Angular + Leaflet: step by step tutorial to add a map

This tutorial helps you to create an Angular-based application and add a Leaflet map as a component. In our tutorial, we provide a way to use the Leaflet library without additional components. Moreover, we prepared an Angular-project for you that contains already a component skeleton for the map component.

We use Geoapify map tiles for the tutorial. You can choose between different map styles and colors there. Check the Geoapify Maps Playground that contains Live demo and code samples.

We use Mapbox style specification, which describes how the map is rendered, tile server locations, and provides values for map settings. For example, minimum, and maximal zoom levels.

Before you start

Step 1. Create an Angular project

You can use the Angular project template we’ve prepared for you or create a new one with Angular CLI. The project template contains already a component for a map:

  • Download or clone the GitHub repository
  • Switch to the project folder: cd angular-based-project
  • Run npm install to install libraries and dependencies
  • Run ng serve for a dev server
  • Navigate to http://localhost:4200/. The app will automatically reload if you change any of the source files.

Step 2. Display a map with Leaflet

Install Leaflet + Mapbox GL plugin

By default, Leaflet doesn’t support vector tiles and Mapbox Style specifications. Therefore you need to install the Mapbox GL Leaflet plugin together with Leaflet to generate a map from style.json:

npm i leaflet mapbox-gl mapbox-gl-leaflet
Install Leaflet + Mapbox GL types

Type definitions will allow you to utilize Leaflet and Mapbox types in your code. Moreover, some IDEs provide code completion when the types are available:

npm i @types/leaflet @types/mapbox-gl-leaflet -dev
Add Leaflet and Mapbox styles

Leaflet and Mapbox styles are required to render a map and it’s elements correctly. We recommend you to add styles to the angular.json:

"projects": {
    "angular-project": {
      ...
      "architect": {
        "build": {
          "options": {
            ...
            "styles": [
              "src/styles.scss",
              "node_modules/mapbox-gl/dist/mapbox-gl.css",
              "node_modules/leaflet/dist/leaflet.css"
            ],
            "scripts": []
          },
          ...
        }
      }
    }
}

You will need to restart the dev server to apply changes from angular.json.

Add a Leaflet map to an Angular-component

Open MyMapComponent if you use our template or create a new component.

  • Remove placeholder and create ViewChild for the div element. Add ngAfterViewInit() lifecycle hook that is called after Angular has fully initialized a component’s view:
<div class="map-container" #map></div>
import { Component, OnInit, ViewChild, ElementRef, AfterViewInit } from '@angular/core';

@Component({
  selector: 'app-my-map',
  templateUrl: './my-map.component.html',
  styleUrls: ['./my-map.component.scss']
})
export class MyMapComponent implements OnInit, AfterViewInit {

  @ViewChild('map')
  private mapContainer: ElementRef<HTMLElement>;

  constructor() { }

  ngOnInit() {
  }

  ngAfterViewInit() {
  }
}
  • Add a Leaflet map to the component:
import { Component, OnInit, ViewChild, ElementRef, AfterViewInit } from '@angular/core';
import  * as L from 'leaflet';
import 'mapbox-gl-leaflet';

@Component({
  selector: 'app-my-map',
  templateUrl: './my-map.component.html',
  styleUrls: ['./my-map.component.scss']
})
export class MyMapComponent implements OnInit, AfterViewInit {

  private map: L.Map;

  @ViewChild('map')
  private mapContainer: ElementRef<HTMLElement>;

  constructor() { }

  ngOnInit() {
  }

  ngAfterViewInit() {
    const myAPIKey = "YOUR_API_KEY_HERE";
    const mapStyle = "https://maps.geoapify.com/v1/styles/osm-carto/style.json";

    const initialState = {
      lng: 11,
      lat: 49,
      zoom: 4
    };

    const map = new L.Map(this.mapContainer.nativeElement).setView(
      [initialState.lat, initialState.lng],
      initialState.zoom
    );

    // the attribution is required for the Geoapify Free tariff plan
    map.attributionControl
      .setPrefix("")
      .addAttribution(
        'Powered by <a href="https://www.geoapify.com/" target="_blank">Geoapify</a> | © OpenStreetMap <a href="https://www.openstreetmap.org/copyright" target="_blank">contributors</a>'
      );

    L.mapboxGL({
      style: `${mapStyle}?apiKey=${myAPIKey}`,
      accessToken: "no-token"
    }).addTo(map);
  }
}

Build the application

Run ng build to build the project. The build artifacts will be stored in the dist/ directory. Use the --prod flag for a production build.

More code sample

Find more Live demos, JSFiddle samples and Code samples on the Geoapify API Documentation page.

React + Leaflet: project template and step by step tutorial

This tutorial helps you to create a React-based application with a Leaflet map. We’ve prepared for you a project template and instructions to develop a Map app from scratch.

We use Geoapify map tiles and Mapbox Style specification to create a map. So at the end of the tutorial, your application will be able to render both vector and raster maps with the Leaflet library.

Before you start

Step 1. Create a React project

We’ve prepared a React-based project template for you. The project already contains a component to visualize a map and uses for Sass3 CSS pre-processor:

  • Download or clone the GitHub repository
  • Switch to the project folder: cd react-based-project
  • Run npm install to install libraries and dependencies
  • Run npm start to start the server
  • Open http://localhost:3000 to view the page in the browser

As the second option, you can generate a React project by yourself with Create React App.

Step 2. Display a map with Leaflet

Install Leaflet + Mapbox GL plugin

By default, Leaflet doesn’t support vector tiles and Mapbox Style specifications. You need to install the Mapbox GL Leaflet plugin together with Leaflet to generate a map from style.json:

npm i leaflet mapbox-gl mapbox-gl-leaflet
Add Leaflet and Mapbox styles

You need to import styles to display a map and it’s elements correctly. You can add the styles to the index.scss file:

@import '~mapbox-gl/dist/mapbox-gl.css';
@import '~leaflet/dist/leaflet.css';
Add a map to a React-component

We already prepared a React-component for you – “src/components/my-map.jsx”:

 
import React, { useEffect } from 'react'; 
import './my-map.scss';

function MyMap() {

  useEffect(() => {
    console.log('This is called when the component is mounted!');
  }, []);

  return (
    <div className="map-container">
      <div className="placeholder">
        <span className="placeholder-text">The map will be displayed here</span>
      </div>
    </div>
  )
}

export default MyMap;

Create one if you’ve generated a project with Create React App. Use can use the MyMap component as an example.

  • Remove the placeholder and add the element reference
  • Make the useEffect() function to be called when the element is ready:
import React, { useEffect } from 'react';
import './my-map.scss';

function MyMap() {
  let mapContainer;

  useEffect(() => {

  }, [mapContainer]);

  return (
    <div className="map-container" ref={el => mapContainer = el}>
    </div>
  )
}

export default MyMap;
  • Add a Leaflet map to the component:
import React, { useEffect } from 'react';
import './my-map.scss';
import L from 'leaflet';
import {} from 'mapbox-gl-leaflet';

function MyMap() {
  let mapContainer;

  useEffect(() => {
    const initialState = {
      lng: 11,
      lat: 49,
      zoom: 4
    };

    const map = L.map(mapContainer).setView([initialState.lat, initialState.lng], initialState.zoom);

    // the attribution is required for the Geoapify Free tariff plan
    map.attributionControl.setPrefix('').addAttribution('Powered by <a href="https://www.geoapify.com/" target="_blank">Geoapify</a> | © OpenStreetMap <a href="https://www.openstreetmap.org/copyright" target="_blank">contributors</a>');

    var myAPIKey = 'YOUR_API_KEY_HERE';
    const mapStyle = 'https://maps.geoapify.com/v1/styles/osm-carto/style.json';

    const gl = L.mapboxGL({
      style: `${mapStyle}?apiKey=${myAPIKey}`,
      accessToken: 'no-token'
    }).addTo(map);
  }, [mapContainer]);

  return (
    <div className="map-container" ref={el => mapContainer = el}>
    </div>
  )
}

export default MyMap;

Note! You may require to restart the development server to apply all changes.

Build the application

Run npm run build from the application directory. This builds the app for production to the build folder.

More code sample

Find more Live demos, JSFiddle samples and Code samples on the Geoapify API Documentation page.

Visualizing time series data on the map

In this article, I’ll show how to create a map-based visualization of multi-dimensional data – time, location and value. As an example, I’m going to use the public daily statistics for nCoV-2019 “coronavirus” outbreak.

By the end of January 2020, the “coronavirus” outbreak started to become one of the top world concerns. Despite the high amount of information that authorities and news agencies provide every day, it is surprisingly hard to see the big picture behind all those numbers.

As most situational data, virus outbreak numbers have a clear location component. Therefore map-based visualization can be extremely helpful.

We’re going to take the raw data and create a simple web-based dashboard that looks like this:

Coronavirus outbreak visualization
Coronavirus outbreak visualization

Preparing data

As the first step, I took the daily statistics data kindly made available here by the Center for Systems Science and Engineering at John Hopkins University.

Raw data were normalized, aggregated by date and geocoded with Geoapify Geocoding API. For convenience, the resulting data for each day were represented in the GeoJSON format, that looks like this:

{
        "type": "FeatureCollection",
        "features": [{
          "type": "Feature",
          "geometry": {
            "type": "Point",
            "coordinates": [121.4554, 31.20327]
          },
          "properties": {
            "Place": "Shanghai",
            "Confirmed": 9
          }
        },
        ...
}

Configuring map

As the next step, I created a simple webpage with Mapbox GL data visualization library, “dark” basemap and two layers – “case-circles” and “case-labels”. Both layers configured to use the GeoJSON data source and dynamically take the number of confirmed cases from each GeoJSON Feature “properties.Confirmed” field.

// please get your own free ApiKey at https://myprojects.geoapify.com
var geoapifyApiKey = '7e99a2fb2e9b41ae9e40742f24c33d75';

var map = new mapboxgl.Map({
  container: 'map',
  style: `https://maps.geoapify.com/v1/styles/dark-matter/style.json?apiKey=${geoapifyApiKey}`,
  center: [15, 21],
  refreshExpiredTiles: false,
  zoom: 1.1
});

map.on('load', function() {
  map.addSource('cases', {
    'type': 'geojson',
    data: null
  });

  map.addLayer({
    'id': 'case-circles',
    'type': 'circle',
    'source': 'cases',
    'paint': {
      'circle-color': '#FF0000',
      'circle-opacity': 0.5,
      'circle-radius': [
        'interpolate',
        ["exponential", 0.9],
        ['get', 'Confirmed'],
        1,
        5,
        5000,
        15
      ]
    }
  });

  map.addLayer({
    'id': 'case-labels',
    'type': 'symbol',
    'source': 'cases',
    'layout': {
      'text-field': [
        'to-string', ['get', 'Confirmed']
      ],
      'text-font': [
        'Open Sans Bold',
        'Arial Unicode MS Bold'
      ],
      'text-size': 12
    },
    'paint': {
      'text-color': 'rgba(0,0,0,0.5)'
    }
  });
});

Due to the significant difference in the number of confirmed cases per location, the “case-circles” layer was configured to use an exponential scale, to emphasize new locations as they appear on the map.

Adding interactivity

Additionally, I’ve added the date slide that triggers map update accordingly to the selected date and allows to see outbreak dynamics.

<div class="map-overlay top">
    <div class="map-overlay-inner">
        <h2 id="date"></h2>
        <input id="slider" type="range" min="0" max="1" step="1" value="0" />
        <h2 id="count">Confirmed cases</h2>
    </div>
</div>

<script>
var casesHistory = getCasesHistory()
var dates = Object.keys(casesHistory)

document.getElementById('slider').max = dates.length - 1

function updateMap(dateId) {
  var date = dates[dateId]
  var casesForDate = casesHistory[date]
  document.getElementById('date').textContent = `Date: ${date}`;
  document.getElementById('count').textContent = `Confirmed cases: ${casesForDate.total}`;
  map.getSource('cases').setData(casesForDate.geojson);
}

document
  .getElementById('slider')
  .addEventListener('input', function(e) {
    var dateId = parseInt(e.target.value, 10);
    updateMap(dateId);
});

updateMap(0);
</script>

Going further

I hope that you now have the general idea of how to create similar visualizations. To make it easier, I’ve prepared a free JSFiddle example to help you get started.

Still too complicated? Don’t worry, and get in touch with us. We’ll be happy to help you with your project.

Nominatim geocoder

Nominatim geocoder is a free, open-source address search engine that you can run on your own computer, even without an Internet connection! And this is one of few solutions which allows you to do high volume, batch geocoding for any address on our planet on budget.

Nominatim can do both forward and reverse geocoding and supports all countries, languages and address formats in the world. It is developed and maintained by the OpenStreetMap community and used as a default geocoding service for OSM data.

Nominatim pros and cons

Sounds good so far? Great!

But before you invest hours and days into getting Nominatim up and running, let’s have a quick overview of its strong and weak sides, and make sure it can be a good fit for your needs.

PROSCONS
Free! No license fees, and very few limitations (you need to adhere to ODBL license)You need to invest your time and resources to get it up and running
Based on rich OSM and Wikipedia data, collected and updated by millions of volunteers, companies, and organizations around the worldMost address records are not authoritative, coverage can be spotty and some data can be obsolete or even incorrect
Community project – good activity and number of articles and configuration instructions in InternetNo guarantees, no support, no SLA; incomplete and often outdated instructions
Open source, you can extend or fix any part of itSometimes code is your only documentation
Works on your servers, also offlineYou need (powerful) servers and somebody who can maintain them
Very configurable queriesYou need to know which options to use to get results you want

To be fair, all Nominatim weaknesses are common for any big, community-driven, open-source project. And we at Geoapify have extensive experience with Nominatim and will be happy to support you.

Geocoding addresses with Nominatim

Nominatim accepts geocoding requests on the /search endpoint, in one of two exclusive modes – free-form and structured search.

Free-form address search

Free-form address query requires “q” parameter, like

Nominatim free-form search results for "Chicago"
Nominatim free-form search results for /search?q=chicago

In that mode, Nominatim supports special phrases like “in”, “near”

Nominatim search with special phrase "restaurant in Chicago"
Nominatim search with special phrase /search?q=restaurant+in+chicago

Structured address search

Alternatively, you can use a structured search, where address defined by a combination of:

street=<number> <name>
city=<city>
county=<county>
state=<state>
postalcode=<code>
Nominatim structured country search
Nominatim structured country search with /search?country=us

Nominatim structured geocoding is not as useful as it could be, because it doesn’t guarantee that search will be performed with requested granularity and prevents Nominatim from applying some internal geocoding heuristics. It also less flexible and does not support Nominatim’s special phrases.

We can only recommend to use it as a workaround for scenarios where Nominatim cannot correctly parse the address.

Filtering by location

If you know that results should belong to a specific country or area, it is highly recommended to narrow down search results with “countrycodes=<comma-separated list of country codes>” and “viewbox=<lon1>,<lat1>,<lon2>,<lat2>” parameters.

Nominatim search with location filter
Nominatim search with location filter
/search?q=berlin&countrycodes=us&viewbox=-89.8,39.7,-90,39.8

By default “viewbox” parameter works as location bias and includes results both inside and outside of provided bounding box.

Adding “bounded=1” parameter instructs Nominatim to return only results included in viewbox.

Search by type and amenity

Nominatim has only very limited support for places search. In most cases, you will get better and more reliable results with other services, for instance, Geoapify Places API or Overpass. But for simple cases, Nominatim can be good enough.

There are three ways to perform a search by type and amenity in Nominatim:

  • Using special phrases like “in” or “near”,
    for example
    /search?q=pub+in+new+york
  • Using search bounded by the “viewbox” together with “amenity” parameter,
    for example, searching for pubs in Manhattan area
    /search?viewbox=-74.02631,40.73022,-73.96202,40.69769&bounded=1&amenity=pub
  • Using search bounded by the “viewbox” together with place type in square brackets,
    for example /search?q=[pub]&viewbox=-74.02631,40.73022,-73.96202,40.69769&bounded=1
Searching pubs in New York with Nominatim
Searching pubs in New York with Nominatim

You can find an extensive list of supported place types and amenities on OpenStreetMap wiki.

Reverse geocoding with Nominatim

Nominatim can find and return addresses corresponding to a given latitude and longitude coordinate. For that, you need to use /reverse endpoint together with “lat” and “lon” parameters.

Finding Statue of Liberty by its GPS coordinate with Nominatim
Finding Statue of Liberty by its GPS coordinate with Nominatim
/reverse?lon=-74.044548&lat=40.6892532&format=html

Results granularity

Nominatim currently does not support filtering by object type nor specific geocoding granularity like “city”, “administrative area” or “street”. But there are several workarounds.

First, Nominatim /search endpoint accepts the (undocumented) “featuretype” parameter with one of the following values: “country”, “state”, “city”, and “settlement” (anything below country and above the street level).

Then, reverse geocoding supports “zoom” parameter and returns the results of different granularity depending on its value:

ZOOMRESULT GRANULARITY
3country
5state
8county
10city
14suburb
16major streets
17major and minor streets
18building

In the case of forward geocoding, you will need to do the second call to reverse geocoding with previously looked up coordinates and desired zoom level.

Another alternative requires a call to /details endpoint together with addressdetails=1 parameter and “place_id” matching the id of the previously geocoded result. This way you get full hierarchy from given the place up to country level, including administrative and postal code boundaries.

Output formats

By default Nominatim returns a formatted HTML page, that is ready to be displayed in the browser. If you need a machine-readable response format, you will need to add the “format” parameter and set it to one of “xml”, “json”, “geojson” and “geocodejson” output formats.

We recommend using “geojson” as the only standard and widely supported format. The second favorite format is “geocodejson”, which is generally compatible with GeoJSON specification and in the case of Nominatim includes the most complete and standartized address structure.

Example geocoding output for “/search?q=berlin&format=geojson&limit=1”

{
    "type": "FeatureCollection",
    "licence": "Data © OpenStreetMap contributors, ODbL 1.0. https://osm.org/copyright",
    "features": [
        {
            "type": "Feature",
            "properties": {
                "place_id": 595794,
                "osm_type": "node",
                "osm_id": 240109189,
                "display_name": "Berlin, 10117, Deutschland",
                "place_rank": 15,
                "category": "place",
                "type": "city",
                "importance": 0.887539028249136,
                "icon": "https://nominatim.openstreetmap.org/images/mapicons/poi_place_city.p.20.png"
            },
            "bbox": [
                13.2288599,
                52.3570365,
                13.5488599,
                52.6770365
            ],
            "geometry": {
                "type": "Point",
                "coordinates": [
                    13.3888599,
                    52.5170365
                ]
            }
        }
    ]
}

Geometry and additional details

Nominatim can lookup and return some additional information

addressdetails=1
extratags=1
namedetails=1

Geocoding example with additional fields
“/search?q=berlin&format=geojson&limit=1&addressdetails=1&extratags=1&namedetails=1”

{
    "type": "FeatureCollection",
    "licence": "Data © OpenStreetMap contributors, ODbL 1.0. https://osm.org/copyright",
    "features": [
        {
            "type": "Feature",
            "properties": {
                "place_id": 595794,
                "osm_type": "node",
                "osm_id": 240109189,
                "display_name": "Berlin, 10117, Deutschland",
                "place_rank": 15,
                "category": "place",
                "type": "city",
                "importance": 0.887539028249136,
                "icon": "https://nominatim.openstreetmap.org/images/mapicons/poi_place_city.p.20.png",
                "address": {
                    "city": "Berlin",
                    "state": "Berlin",
                    "postcode": "10117",
                    "country": "Deutschland",
                    "country_code": "de"
                },
                "extratags": {
                    "email": "[email protected]",
                    "capital": "yes",
                    "website": "https://www.berlin.de/",
                    "wikidata": "Q64",
                    "wikipedia": "de:Berlin",
                    "population": "3531201",
                    "name:prefix": "Land und Kreisfreie Stadt"
                },
                "namedetails": {
                    "name": "Berlin",
                    "name:ab": "Берлин",
                    "name:af": "Berlyn",
                    "name:am": "በርሊን",
                    "name:an": "Berlín",
                    "name:ar": "برلين",
                    "name:short": "BE",
                    "name:nds-nl": "Berlien",
                    "old_name:vi": "Bá Linh",
                    "name:bat-smg": "Berlīns",
                    "name:cbk-zam": "Berlín",
                    "name:fiu-vro": "Berliin",
                    "name:roa-rup": "Berlin",
                    "name:roa-tara": "Berline",
                    "name:be-tarask": "Бэрлін"
                }
            },
            "bbox": [
                13.2288599,
                52.3570365,
                13.5488599,
                52.6770365
            ],
            "geometry": {
                "type": "Point",
                "coordinates": [
                    13.3888599,
                    52.5170365
                ]
            }
        }
    ]
}

It is also possible to return the original geometry of the results instead of the coordinate and bounding box. For that you need to specify one of the following parameters:

polygon_geojson=1
polygon_kml=1
polygon_svg=1
polygon_text=1

Multilanguage support

By default, Nominatim uses “Accept-Language” HTTP header to choose the preferred language of the result. This can be changed by “accept-language” parameter, which can be set to one or multiple (comma-separated) language codes – in order of preference. If both the HTTP header and parameter are missing, Nominatim will return each geocoding result using the native language of the place.

Installation and hardware requirements

General installation instructions are very well documented in Nominatim Administration Guide, and there is no point in repeating the same information here.

You should plan that initial production-ready setup and configuration will take at least 2 days and up to several weeks of effort, depending on your situation, requirements, and level of expertise. You also need to have some level of confidence with Linux, Apache web server, PHP and PostgreSQL database to follow the instructions.

Hardware requirements depend on desired coverage (full planet, country, region or city) and if you plan to apply daily or hourly updates to the Nominatim database. For planet import, we recommend a server with at least 8 cores, 32 GB RAM and 700 GB of fast SSD/NVMe storage. With that, you can expect initial data import to take approximately 2-3 days. For smaller regional datasets your hardware requirements will be proportionally lower, but as a bare minimum, you need at least 2 CPUs, 4 GB memory and 50 GB of fast storage.

A possible alternative for testing and small non-profit projects you can use the free community-supported Nominatim instance. It is funded by the OpenStreetMap foundation and normally has the most up to date Nominatim version and data. As a downside, there are no up-time or performance guarantees, and your requests may be blocked without any further notice if you generate than 1 request per second, or send repetitive, systematic or batch queries.

Again, it is normally acceptable for testing and very small projects, but and serious business usage is discouraged. Please check the OSM Nominatim Acceptable Use Policy for more details.

As an alternative, we at Geoapify can offer you a full range of Nominatim support – from business-friendly, managed Nominatim instances, to dedicated installations, as well as consultation and assistance if you need help with configuration.

So, should I use Nominatim for geocoding?

You should definitely consider Nominatim if you need to do high-volume or batch geocoding with thousands and millions of addresses. It also can be very useful for scenarios when you need to do geocoding in secure environments or offline.

Another benefit comes from the open data that Nominatim uses. If something is missing or wrong in underlying OSM or Wikipedia data, you or anyone else can easily add or correct that information. It is normally much more challenging to do that with any alternative services.

Another benefit comes from the open data that Nominatim uses. If something is missing or wrong in underlying OSM or Wikipedia data, you or anyone else can easily add or correct that information. It is normally much more challenging to do that with any alternative services.

But do not expect Nominatim to be as smart as e.g. Google Maps API, especially if you deal with manually entered addresses. On average Nominatim does great job and correctly geocodes around 70% of addresses, while best commercial services can geocode around 90%.

Also, full-text-search in Nominatim is somewhat limited. Elasticsearch based alternatives like Photon or Pelias can give better results if you need to lookup places by name instead of addresses.

And don’t forget about time and resources that need to be invested into configuring, running and maintaining Nominatim installations.

If that is too much for you and you just need smart geocoding that works well, we can recommend giving our Geocoding API a try. It has very liberal pricing, generous free tier that is eligible for business usage and combines a number of technologies and know-how to deliver the best results as fast as possible.

Nominatim vs Photon geocoder

Looking up a location given free-form address is one of the most frequent operations on geospatial data. Almost every business needs to recognize and locate customer addresses. At the same time, differences in languages, country-specific address and postcode formats, typos and ambiguous names make it very hard to do it right.

This is why one normally uses a geocoder – a specialized search engine that is designed to return the most relevant location for a given address string.

Feature comparison

Nominatim geocoder is a “de-facto” standard in the world of open source geocoding engines. It is developed and maintained by the OpenStreetMap community.

Photon is another popular open-source geocoder with the focus on search-as-you-type suggestions and typos correction. It is developed and maintained by Komoot.

Both geocoders are fine pieces of software, supporting both forward and reverse geocoding and primarily use the OpenStreetMap dataset for address lookups.

FeatureNominatimPhoton
Structured searchyesno
Search-as-you-typenoyes
Hardware requirementshighmedium
Typo toleranceaveragegood
Full-text searchnoyes
Filtering resultsbounding box
county code
bounding box
OSM tag name and value
Special phrases (in, near)yesno
Configurable results rangingnolocation bias
DatabasePostGISElasticsearch
Data sourcesOpenStreetMap
Wikipedia
US Tiger & Postcodes
UK Postcodes
OpenStreetMap
Response formatsGeoJSON
JSON
HTML
XML
GeoJSON
Returned datafull, including geometrybasic
User interfaceyesno

Conclusion

So, which geocoder is the best, Nominatim or Photon? As usual, the answer is – it depends.

Photon excels in search-as-you-type scenarios. It tolerates typos and spelling mistakes. Photon is good for a general, free-form text geocoding. It is relatively lightweight and not very difficult to maintain – setting up your own instance takes from few hours to few days.

Nominatim on another hand has superior structured address search and filtering capabilities. It supports a number of output formats and advanced filters. Nominatim works best in scenarios when you at least roughly know what you’re looking for and where. Nominatim comes with significant complexity, hardware requirements, and maintenance overhead. It may take days and weeks to configure your own functional Nominatim instance.

In both cases, you’ll need to have expertise and time to set up your own geocoder instance. Alternatively, you can use our managed Photon and Nominatim geocoder instances. We take care of all aspects – configuration, updates, maintenance, availability, and security. We also provide consulting and custom software development. In case you’re looking for high-volume batch geocoding or cannot use 3rd party services due to security or privacy regulations, we can also set up a dedicated geocoder instance for you.

Travel time map: TOP 10 use cases for businesses and individuals

Travel time is one of the most important criteria when you choose a location. That’s why a travel time map or isochrone is often used as the main analytics tool to answer spatial questions. In this article, we would like to show you some scenarios of how travel time maps can help to make a location decision.

Travel time map use cases for businesses

While Location Intelligence becomes one of the key tools of Business Intelligence travel time maps become more and more popular in the business world. Here are a few examples of the isochrones application which could solve business tasks.

Operations on travel time maps
Union and intersection of travel time maps

Choose a new office location

Relocation is always a big step for a company. It’s important not only to satisfy the needs of the existing employees but also choose an attractive location for the new employees.

You can build reachability maps with desired time for each of your current employees and check if there is an intersection between them. Moreover, with isochrones, you can filter statistics and check how many potential workers are living in the bounded area of a new office.

Check coverage of your network

You can build isochrones for each of your selling points and check their union to see the coverage of your network. Different transportation modes, for example, “by public transport”, “driving”, or “walking”, help you to see if there are empty spots on your coverage map.

Choose the best place for a new retail shop

Not only vacant spots but also potentially profitable locations could be found with Location Intelligence tools and isochrones. For example, you can see if your target auditory can reach a new location easily. Moreover, you can filter properties by isoline and check exact numbers for the location.

Estimate a place reachability

It’s always good to rank locations by reachability. How good is the public transport connection for a place? How big reachability area by car? Better connectivity will always provide more potential and perspectives for a location. In short, travel time maps are designed to solve this task as well.

Study opportunities and potential of a location

When you have statistical data, for example, demographic data, you can bound the data by travel time maps and get statistics by isochrones. So you can study opportunities and potential clients, who can reach the location within the desired amount of time.

Travel time map use cases for individuals

Not only businesses but also individuals can benefit using isochrones. Thus if you provide the service on your website, the website becomes more valuable and attractive for your customers.

Transit isochrone
30 min isochrone for public transport

Optimize commute time by choosing the right place to live

It’s know fact, that fewer time people spend commuting, happier they are. Isochrones can help you to optimize commute time for each family member to their working or study place. If you build the travel time maps and then calculate the intersection of them, you can see locations reachable from each point of interests.

Optimize commute time by choosing the right place to work

Moreover, the inverse problem also could be solved with isochrones. If you plan to change your working place, the travel time map could show you all the possible areas where a new working place could be.

Study amenities you can reach

Would you like to see on the map only amenities you can reach within the desired time? Sure, it would be great! Filtering amenities by an isochrone provides you the answer.

Amenities filtered by the travel time map
All dentists within 30 min by public transport

Choose the best place to stay in a new city

When you plan a trip to a city you’ve never visited before it always a challenge to book accommodation in a good location. Often you need a good transport connection to multiple points of interest. For example, to the airport and conference place. Intersection on travel time maps of each of the locations will show you the perfect place for accommodation.

Book a hotel within desired travel time from seaside or ski resort

Isolines will also help you to book a hotel within walking or driving distance from seaside or ski resort. By calculating union of beach entries or ski lifts reachability maps, you can see on a map where hotels with an acceptable walking or drive time are.

Geoapify provides Isoline API to build travel time maps

Isolines API allows you to build travel time maps for different traveling modes and all over the world. Our APIs work via HTTP Get requests and return GeoJSON object as a result. Moreover, we provide Geometry API which calculates intersections and unions of isochrones. So you can quickly and with ease create your own Location Intelligence solution or extend an existing one. Register and start building isochrones for free.