Learn how to calculate the area that can be reached in a given driving time from a location.
A service area, also known as an isochrone, is a polygon that represents the area that can be reached when driving or walking on a street network. The area that can be reached is restricted by either time or distance.
To calculate service areas, you can use the routing service. You provide a start location (facilities), one or more time or distance values, and a spatial reference. Once processed, the service returns the service areas that can be reached.
In this tutorial, you use ArcGIS REST JS to access the routing service to create and display five, ten, and fifteen minute drive time service areas when the map is clicked. You use data-driven styling to give each polygon a different shade of blue.
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 > Routing
- 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 basemapEnum = "arcgis/outdoor"; const map = new maplibregl.Map({ container: "map", // the id of the div element style: `https://basemapstyles-api.arcgis.com/arcgis/rest/services/styles/v2/styles/${basemapEnum}?token=${accessToken}`, zoom: 12, // starting zoom center: [-118.805, 34.027] // starting location [longitude, latitude] });
-
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.
Reference the ArcGIS REST JS
-
Add links to the ArcGIS REST JS libraries in the
<script
section.> Use dark colors for code blocks <head> <meta charset="utf-8" /> <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" /> <script src=https://unpkg.com/maplibre-gl@4/dist/maplibre-gl.js></script> <link href=https://unpkg.com/maplibre-gl@4/dist/maplibre-gl.css rel="stylesheet" /> <script src="https://unpkg.com/@esri/arcgis-rest-request@4/dist/bundled/request.umd.js"></script> <script src="https://unpkg.com/@esri/arcgis-rest-routing@4/dist/bundled/routing.umd.js"></script> <style> html, body, #map { padding: 0; margin: 0; height: 100%; width: 100%; font-family: Arial, Helvetica, sans-serif; font-size: 14px; color: #323232; } </style> </head>
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
[100.5231,13.7367]
, Bangkok.Use dark colors for code blocks const accessToken = "YOUR_ACCESS_TOKEN"; const basemapEnum = "arcgis/navigation"; const map = new maplibregl.Map({ container: "map", // the id of the div element style: `https://basemapstyles-api.arcgis.com/arcgis/rest/services/styles/v2/styles/${basemapEnum}?token=${accessToken}`, zoom: 12, // starting zoom center: [100.5231, 13.7367] // Bangkok });
Add a starting point layer
Add a source and a layer to show a white circle for the starting point of the calculation. This will show the user where they clicked.
-
Start a new function called
add
Starting Point Layer() Use dark colors for code blocks center: [100.5231, 13.7367] // Bangkok }); function addStartingPointLayer() { }
-
Add a GeoJSON source with id
start
. Set thedata
attribute to an empty FeatureCollection.This source will later contain the geometry information of the start or end point that the user has selected. For now, you can simply provide it with an empty piece of GeoJSON: a feature collection that contains no features.
Use dark colors for code blocks function addStartingPointLayer() { map.addSource("start", { type: "geojson", data: { type: "FeatureCollection", features: [] } }
-
Add a circle layer with id
start-circle
, connected to thestart
source. Set the paint properties to make it white with a black outline.Use dark colors for code blocks function addStartingPointLayer() { map.addSource("start", { type: "geojson", data: { type: "FeatureCollection", features: [] } }); map.addLayer({ id: "start-circle", type: "circle", source: "start", paint: { "circle-radius": 6, "circle-color": "white", "circle-stroke-color": "black", "circle-stroke-width": 2 } }); }
Add service area layer
To show the service area, you will use a fill layer to display a GeoJSON source. Each polygon has a property called From
which contains the lower bound of the number of minutes of travel: 0, 5 and 10 minutes. You can use an expression for the fill-color
to display each polygon in a different shade of blue.
-
Start a new function called
add
.Service Area Layer() Use dark colors for code blocks center: [100.5231, 13.7367] // Bangkok }); function addServiceAreaLayer() { }
-
Add a GeoJSON source for the service area, with id
servicearea
. Set thedata
attribute of each source to be an empty FeatureCollection.This source will later contain the geometry information of the service area. For now, you can simply provide it with an empty piece of GeoJSON: a feature collection that contains no features.
Use dark colors for code blocks function addServiceAreaLayer() { map.addSource("servicearea", { type: "geojson", data: { type: "FeatureCollection", features: [] } }); }
-
Add a layer of type
fill
to display the service area polygons, connected to theservicearea
source. Use amatch
expression for thefill-color
to show each polygon in a different shade of blue: darkest for shortest time, and lightest for longest time.The
match
expression is like aswitch
statement: it compares the value of theFrom
property of each polygon feature, and compares it against the values 0, 5 or 10. If it matches, the corresponding color becomes theBreak fill-color
. Otherwise, the last value,transparent
is used.Use dark colors for code blocks function addServiceAreaLayer() { map.addSource("servicearea", { type: "geojson", data: { type: "FeatureCollection", features: [] } }); map.addLayer({ id: "servicearea-fill", type: "fill", source: "servicearea", paint: { "fill-color": [ "match", ["get", "FromBreak"], 0, "hsl(210, 80%, 40%)", 5, "hsl(210, 80%, 60%)", 10, "hsl(210, 80%, 80%)", "transparent" ], "fill-outline-color": "black", "fill-opacity": 0.5 } }); }
Add a load event handler
You need to use the load
event to ensure the map is fully loaded, before adding your layers.
-
Add an event handler to the map
load
event. Call theadd
andService Area Layer() add
functions here.Starting Point Layer() The order in which layers are added to the map is the order in which they will be displayed: layers added later are displayed over the top. Therefore, to have the starting point layer remain visible, you should add it after the service area layer.
Use dark colors for code blocks paint: { "circle-radius": 6, "circle-color": "white", "circle-stroke-color": "black", "circle-stroke-width": 2 } }); } map.on("load", () => { addServiceAreaLayer(); addStartingPointLayer(); });
Add a click handler
When you click on the map, you will update the location of the startingpoint
source data to show the starting point location.
-
Add a click handler to the map.
Use dark colors for code blocks map.on("load", () => { addServiceAreaLayer(); addStartingPointLayer(); }); map.on("click", (e) => { });
-
Use the
lng
property of the event parameter to construct a GeoJSON point. Update the geometry information of theLat start
source with it.The object passed to the
click
event contains several useful properties, including:lng
: the map location where the click took place.Lat point
: the screen location in pixels where the click took place.original
: the DOM event, which contains information about modifier keys.Event
For more information, see the MapLibre GL JS documentation.
Use dark colors for code blocks map.on("click", (e) => { const coordinates = e.lngLat.toArray(); const point = { type: "Point", coordinates }; map.getSource("start").setData(point); });
-
At the top right, click Run.
When you click on the map, the white circle should move to each location that you click.
Get the service area
With the coordinates of the click event, you can now call the service
function in the route service to get the service area.
-
Inside the click handler, create a new
arcgis
to access the route service. Call theRest. Api Key Manager service
method. Set theArea facilities
parameter with the clicked coordinates to calculate the service area.The
facilities
parameter lets you pass in multiple locations around which the service area is calculated. In this case, you are only passing one.By default, the three drive times that are requested are 5, 10 and 15 minutes. You can change these by passing the
default
parameter.Breaks Use dark colors for code blocks const authentication = arcgisRest.ApiKeyManager.fromKey(accessToken); arcgisRest .serviceArea({ authentication, facilities: [coordinates] })
Display the service area on the map
The response to the request contains the geographic information of the service areas. Use the sa
property to update the servicearea
source.
-
Use
Map.get
to access theSource servicearea
source. Callset
to update the data with the GeoJSON returned from the API.Data Use dark colors for code blocks arcgisRest .serviceArea({ authentication, facilities: [coordinates] }) .then((response) => { map.getSource("servicearea").setData(response.saPolygons.geoJson); });
-
At the top right, click Run.
When you click on the map, three service areas are shown as concentric polygons around a white circle. These indicate the areas that can be reached by driving for 5, 10 or 15 minutes.
What's next?
Learn how to use additional ArcGIS location services in these tutorials: