pmckinneyccpa

Esri Leaflet Geocoder Crash Course

Blog Post created by pmckinneyccpa on Jan 25, 2017

I thought I’d introduce the Esri Leaflet Geocoder plugin in this post. It is one of many plugins Esri has developed to support integration with the Leaflet.js web mapping library. Although Esri states that they “provide no guarantee of individual features, nor a traditional product lifecycle to support planning,” they have integrated their technology with Leaflet pretty well. And they are also very active in fixing bugs.

 

The Geocoder plugin allows you to search from the Esri World Geocoding service, a custom geocoding service, as well as within map/feature services. They also provide a user interface for performing the searches. And while the default placement is below the zoom controls, the Calcite Maps project has a code sample to move the search control into a Bootstrap navigation bar.

 

esri leaflet geocoder standard placement

 

esri leaflet calcite geocoder placement

 

 

I’d like to share some code snippets of how I implement this plugin. As the majority of my map applications use the same type of search (custom geocode service), I’ve developed a module for geocoding. For the samples, I’ll provide an example of the Esri World Geocoding service, a custom geocoding service, and searching within a feature layer.

 

Setting up the Geocoder

 

To start with, we need to create a few variables to to create the geocode search and store results. The searchControl variable is the the L.esri.Geocoding.geosearch object, which we add to the map. There are many options for this object, including search providers, search bounds, and placeholder text.

 

The providers are separately constructed objects that can be the Esri World Geocoding service, a custom geocoding service, or a feature layer search. The search bounds are a L.latLngBounds object that allows you to limit the searching within latitude/longitude bounds. This can be especially nice when using a service with features outside of your map's focust area to exclude those results (i.e, not returning California addresses for a map of Pennsylvania).

 

The searchResults variable is a L.layerGroup object that will hold the results of your search. I have only used this plugin to return a single result, so I’m not very familiar with using multiple results.

 

// previous code …
var searchControl;
var searchResults;
var searchBounds = L.latLngBounds([39.803052, -77.820029],[40.453170, -76.799358]);

searchControl = L.esri.Geocoding.geosearch({
     useMapBounds: false,
     providers: [agolProvider, ccpaProvider, schoolsLayer],
     placeholder: 'Search for an address',
     title: 'Address Search',
     searchBounds: searchBounds,
     zoomToResult: true
}).addTo(map);

searchResults = L.layerGroup().addTo(map);

 

Setting up the Search Providers

 

Next, I’ll share some sample code for creating three search providers.

 

Esri World Geocoding Service

 

This is by far the easiest to set-up. There are some options for limiting results to certain countries or categories, although I haven't used them.

 

// ArcGIS Online
var agolProvider = L.esri.Geocoding.arcgisOnlineProvider({
     label: 'ArcGIS Online World Geocoding Service',
     maxResults: 6
});


Custom Geocoding Service

 

For a custom geocoding service, you need to provide the URL of the service, and you can also provide options available to all search providers. The label option is the text used to group suggestions when more than one provider is used.

 

// CCPA Composite Locator
var ccpaProvider = L.esri.Geocoding.geocodeServiceProvider({
   label: 'Cumberland County Composite Locator',
   maxResults: 6,
   attribution: 'Cumberland County',
   url: '//gis.ccpa.net/arcgiswebadaptor/rest/services/CompositeLocator/GeocodeServer'
});


Feature Layer Provider

 

This may be the coolest search provider. With a Feature Layer Provider, you can search for records within the service. In addition to providing the service’s URL, you provide the fields you want to search within. You can also format how the suggestion text will look.

 

// CCPA Schools
var schoolsLayer = L.esri.Geocoding.featureLayerProvider({
   url: '//gis.ccpa.net/arcgiswebadaptor/rest/services/911/MapServer/7',
   searchFields: ['Name', 'Address1', 'City'],
   formatSuggestion: function(feature) {
      return feature.properties.Name + ', ' + feature.properties.Address1 + ', ' + feature.properties.City;
   },
   label: 'Schools'
});


Handling Results

 

The final step in using the Esri Leaflet Geocoder plugin is to configure the results event of the search. All of the results are stored in array, where each result is a Result Object. Each Result Object will contain the text that was passed to the provider, the latitude/longitude bounds (L.latLngBounds) for the result, and the latitude/longitude (L.latLng) for the result. It will also contain additional properties from the provider.

 

In my implementation of this plugin, I have only been interested in returning a single result. I start by clearing the previous result, then center the map view with the latitude/longitude of the result and a specific zoom level. Finally, I open a popup at the result’s location with the text passed to the search. Finally, I wrap all of this in a conditional statement to ensure there are actually results.

 

 

searchControl.on('results', function(data) {
   searchResults.clearLayers();

    if (data.results.length > 0) {
      // set map view
      map.setView(data.results[0].latlng, 18);
     
      // open pop-up for location
      var popup = L.popup({closeOnClick: true}).setLatLng(data.results[0].latlng).setContent(data.results[0].text).openOn(map);
   }
});


Hopefully you have found this crash course for the Esri Leaflet Geocoder plugin useful. If you’d like to learn more, please visit the plugin’s API reference or the examples page.

Outcomes