Learn how to search for coffee shops, gas stations, restaurants and other nearby places with the geocoding service.
Place addresses for businesses by category with the geocoding service.
Place finding is the process of searching for a place name or POI to find its address and location. You can use the geocoding service to find places such as coffee shops, gas stations, or restaurants for any geographic location around the world. You can search for places by name or by using categories. You can search near a location or you can search globally.
In this tutorial, you use ArcGIS REST JS to access the geocoding service and find places by place category.
Prerequisites
You need an ArcGIS Location Platform or ArcGIS Online account.
Steps
Create a new pen
- To get started, you can complete the Display a map tutorial or use the .
Get an access token
You need an access token with the correct privileges to access the resources used in this tutorial.
-
Go to the Create an API key tutorial and create an API key with the following privilege(s):
- Privileges
- Location services > Basemaps
- Location services > Geocoding
- Privileges
-
Copy the API key access token to your clipboard when prompted.
-
In CodePen, update the
access
variable to use your access token.Token Use dark colors for code blocks const accessToken = "YOUR_ACCESS_TOKEN"; const basemapId = "arcgis/outdoor"; const basemapURL = `https://basemapstyles-api.arcgis.com/arcgis/rest/services/styles/v2/styles/${basemapId}?token=${accessToken}`; olms.apply(map, basemapURL);
-
Run the code to ensure the basemap is displayed in the map.
To learn about the other types of authentication available, go to Types of authentication.
Add references to ArcGIS REST JS
This tutorial uses ArcGIS REST JS for place finding.
-
In the
<head
element, add references to the ArcGIS REST JS library.> Use dark colors for code blocks <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/ol@v10.1.0/ol.css" type="text/css" /> <script src="https://cdn.jsdelivr.net/npm/ol@v10.1.0/dist/ol.js"></script> <script src="https://cdn.jsdelivr.net/npm/ol-mapbox-style@12.3.5/dist/olms.js" type="text/javascript"></script> <script src="https://unpkg.com/@esri/arcgis-rest-request@4.0.0/dist/bundled/request.umd.js"></script> <script src="https://unpkg.com/@esri/arcgis-rest-geocoding@4.0.0/dist/bundled/geocoding.umd.js"></script>
Update the map
A navigation basemap layer is typically used in geocoding and routing applications. Update the basemap layer to use arcgis/navigation
.
-
Update the basemap and the map initialization to center on location
[-122.4194,37.7749]
, San Francisco.Use dark colors for code blocks const view = new ol.View({ center: ol.proj.fromLonLat([-122.4194, 37.7749]), // San Francisco zoom: 14 }); map.setView(view); const basemapId = "arcgis/navigation";
Add controls
Use a select
element to create the drop-down element. Each category is an option
element inside it. The select
element needs to have absolute
positioning in order to appear in front of the map element.
-
Add a
select
control, with options for "Coffee shop", "Gas station", "Food", "Hotel", "Parks and outdoors". Use inline styling to position the control.The option values have special meaning to the geocoding service so ensure the spelling is correct. To learn more, go to Category filtering in the ArcGIS services reference.
Use dark colors for code blocks <body> <div id="map"></div> <select id="places-select" style="right: 20px; top: 20px; position: absolute; font-size: 16px; padding: 4px 8px"> <option value="">Choose a place type...</option> <option value="Coffee shop">Coffee shops</option> <option value="Gas station">Gas stations</option> <option value="Food">Food</option> <option value="Hotel">Hotels</option> <option value="Parks and Outdoors">Parks and Outdoors</option> </select>
-
At the top right, click Run to verify that the
select
control is created and contains the different categories.
Add a places layer
To display places from the geocoding service on the map, you will add a vector layer, containing a vector source. Small blue circles is the default styling used.
-
Inside
olms
load handler, create a new vector layer containing a vector source. Store it in aplaces
, and add it to the map withLayer map.add
;Layer Use dark colors for code blocks olms.apply(map, basemapURL).then(function (map) { const placesLayer = new ol.layer.Vector({ source: new ol.source.Vector(), }); map.addLayer(placesLayer);
Call the geocoding service
To find places near a location, you can use the arcgis
. Use the center of the map view.get
with proj.to
to get the point in longitude and latitude. Provide the category selected by the user using document.get
to get the control, then use its value
property.
-
Create a function called
show
. Inside, create a newPlaces arcgis
to access the geocoding service. CallRest. Api Key Manager arcgis
to set the API key and to call the service endpoint. PassRest.geocode() location
andcategory
, and specifyPlace
and_addr Place
as the fields to be returned. Request a maximum of 25 places.Name Use dark colors for code blocks map.addLayer(placesLayer); function showPlaces() { const authentication = arcgisRest.ApiKeyManager.fromKey(accessToken); const category = document.getElementById("places-select").value; arcgisRest .geocode({ authentication, outFields: "Place_addr,PlaceName", // attributes to be returned params: { category, location: ol.proj.toLonLat(view.getCenter()), maxLocations: 25 } }) }
Display results
When the query completes, the geo
property of the response object contains a GeoJSON feature collection of points. You can use this to update the data of your places
source. You will need to use a Geo
feature format to read the data, and also reproject it to the map's projection. Use an exception handler to detect problems accessing the service. This could happen due to network disruption or a problem with your API key, for instance.
-
Add a response handler. Inside, use a new GeoJSON feature format to read the
geo
property and reproject the data. Clear the places source withJson clear
and add the new features withadd
Features Use dark colors for code blocks params: { category, location: ol.proj.toLonLat(view.getCenter()), maxLocations: 25 } }) .then((response) => { const features = new ol.format.GeoJSON({ featureProjection: view.getProjection() }).readFeatures(response.geoJson); placesLayer.getSource().clear(); placesLayer.getSource().addFeatures(features); })
-
If there is an exception accessing the geocoding service, alert the user and log the error.
Use dark colors for code blocks .then((response) => { const features = new ol.format.GeoJSON({ featureProjection: view.getProjection() }).readFeatures(response.geoJson); placesLayer.getSource().clear(); placesLayer.getSource().addFeatures(features); }) .catch((error) => { alert("There was a problem using the geocoder. See the console for details."); console.error(error); });
Add a change event handler
To update the map when the user chooses a category, you must add an event handler for the change
event on the <select
control.
-
After the map initialization code, add
show
as thePlaces change
event handler to the<select
control.> Use dark colors for code blocks .catch((error) => { alert("There was a problem using the geocoder. See the console for details."); console.error(error); }); } document.getElementById("places-select").addEventListener("change", showPlaces);
-
At the top right, click Run. When you choose a place category, circles should be shown for places.
Display labels
In order to show the name of each place on the map, you will modify the layer definition to include a style
property. You provide a function that takes a feature and returns a Style
. It will include a Text
style to display the labels, using the text
property to determine which is text is displayed. Use the Place
property of the feature for this. You will also set properties such as text
and font
to control the appearance of the labels. The style will also include a Circle
style to draw a circle at the place location.
By default, the labels would overlap each other and be hard to read. You use the declutter
property on the Vector
layer to prevent this.
-
Add a
style
property to theplaces
definition. Make this function return a newLayer Style
which includes aCircle
style and aText
style for theimage
andtext
properties. Enable thedeclutter
setting.Use dark colors for code blocks const placesLayer = new ol.layer.Vector({ source: new ol.source.Vector(), style: (feature) => new ol.style.Style({ image: new ol.style.Circle({ radius: 5, fill: new ol.style.Fill({ color: "white" }), stroke: new ol.style.Stroke({ color: "hsl(220, 80%, 40%)", width: 2 }) }), text: new ol.style.Text({ font: "14px sans-serif", textAlign: "left", text: feature.get("PlaceName"), offsetX: 8, // move text to the right to avoid overlapping circle offsetY: 2, // move down to align with circle's center fill: new ol.style.Fill({ color: "hsl(220, 80%, 40%)" }), stroke: new ol.style.Stroke({ color: "white" }) }) }), declutter: true
Run the app
In CodePen, run your code to display the map.
When you choose a place category, you should see the name of each place shown as a label, next to a white circle with a blue outline.
What's next?
Learn how to use additional ArcGIS location services in these tutorials: