Find service areas

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 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 a free ArcGIS developer account to access your dashboard and API keys. The API key must be scoped to access the services used in this tutorial.

Steps

Create a new pen

  1. To get started, either complete the Display a map tutorial or .

Set the API key

To access ArcGIS location services, you need an API key.

  1. Go to your dashboard to get an API key.

  2. In CodePen, update apiKey to use your key.

    Change line
                                                             
    <!DOCTYPE html>
    <html>
    
    <head>
      <meta charset="utf-8">
      <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
      <title>Esri Leaflet</title>
    
      <!-- Load Leaflet from CDN -->
      <link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css"
        integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A=="
        crossorigin=""/>
      <script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"
        integrity="sha512-XQoYMqMTK8LvdxXYG3nZ448hOEQiglfqkJs1NOQV44cWnUrBc8PkAOcXy20w0vlaXaVUearIOBhiXZ5V3ynxwA=="
        crossorigin=""></script>
    
      <!-- Load Esri Leaflet from CDN -->
      <script src="https://unpkg.com/esri-leaflet@3.0.0/dist/esri-leaflet.js"></script>
      <script src="https://unpkg.com/esri-leaflet-vector@3.0.0/dist/esri-leaflet-vector.js"></script>
    
      <style>
        body { margin:0; padding:0; }
        #map {
            position: absolute;
            top:0;
            bottom:0;
            right:0;
            left:0;
            font-family: Arial, Helvetica, sans-serif;
            font-size: 14px;
            color: #323232;
          }
      </style>
    
    </head>
    
    <body>
      <div id="map"></div>
    
      <script>
    
        const apiKey = "YOUR-API-KEY";
        const basemapEnum = "ArcGIS:Streets";
    
        const map = L.map('map', {
          minZoom: 2
        }).setView([34.02,-118.805], 13);
    
        L.esri.Vector.vectorBasemapLayer(basemapEnum, {
          apiKey: apiKey
        }).addTo(map);
    
      </script>
    
    </body>
    
    </html>

Add references to ArcGIS REST JS

Import the ArcGIS REST JS library from the CDN.

Add line.Add line.Add line.Add line.
                                                                                                                          
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
  <title>Esri Leaflet</title>

  <!-- Load Leaflet from CDN -->
  <link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css"
    integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A=="
    crossorigin=""/>
<script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"
    integrity="sha512-XQoYMqMTK8LvdxXYG3nZ448hOEQiglfqkJs1NOQV44cWnUrBc8PkAOcXy20w0vlaXaVUearIOBhiXZ5V3ynxwA=="
    crossorigin=""></script>

  <!-- Load Esri Leaflet from CDN -->
  <script src="https://unpkg.com/esri-leaflet@3.0.0/dist/esri-leaflet.js"></script>
  <script src="https://unpkg.com/esri-leaflet-vector@3.0.0/dist/esri-leaflet-vector.js"></script>


  <!-- Load ArcGIS REST JS from CDN -->
  <script src="https://unpkg.com/@esri/arcgis-rest-request@3.0.0/dist/umd/request.umd.js"></script>
  <script src="https://unpkg.com/@esri/arcgis-rest-routing@3.0.0/dist/umd/routing.umd.js"></script>
  <script src="https://unpkg.com/@esri/arcgis-rest-auth@3.0.0/dist/umd/auth.umd.js"></script>


  <style>
    body { margin:0; padding:0; }
    #map {
      position: absolute;
      top:0;
      bottom:0;
      right:0;
      left:0;
      font-family: Arial, Helvetica, sans-serif;
      font-size: 14px;
      color: #323232;
    }
  </style>

</head>

<body>

  <div id="map"></div>

  <script>

    const apiKey = "YOUR-API-KEY";

    const basemapEnum = "ArcGIS:Navigation";

    const map = L.map('map', {
      minZoom: 2

    }).setView([13.7367,100.5231], 13); // Bangkok

    L.esri.Vector.vectorBasemapLayer(basemapEnum, {
      apiKey: apiKey
    }).addTo(map);

    // Layer Group for source point
    const startLayerGroup = L.layerGroup().addTo(map);

    // Layer Group for service area results
    const layerGroup = L.layerGroup().addTo(map);

    // Create the arcgis-rest-js authentication object to use later.
    const authentication = new arcgisRest.ApiKey({
      key: apiKey
    });

    // When the map is clicked, call the service area REST service with the
    // clicked point and display the results.
    map.on("click", (e) => {

      // Clear the previous results
      startLayerGroup.clearLayers();
      layerGroup.clearLayers();

      // Add the source point
      L.marker(e.latlng).addTo(startLayerGroup);

      // Make the API request
      arcgisRest
        .serviceArea({
          endpoint: "https://route-api.arcgis.com/arcgis/rest/services/World/ServiceAreas/NAServer/ServiceArea_World/solveServiceArea",
          authentication,
          facilities: [[e.latlng.lng, e.latlng.lat]]
        })
        .then((response) => {
          // Show the result route on the map.
          L.geoJSON(response.saPolygons.geoJson, {
            style: (feature) => {
              const style = {
                fillOpacity: 0.5,
                weight: 1
              }
              if(feature.properties.FromBreak === 0) {
                style.color = 'hsl(210, 80%, 40%)';
              } else if(feature.properties.FromBreak === 5) {
                style.color = "hsl(210, 80%, 60%)";
              } else {
                style.color = "hsl(210, 80%, 80%)";
              }
              return style;
            }
          }).addTo(layerGroup);
        })
        .catch((error) => {
          console.error(error);
          alert("There was a problem using the route service. See the console for details.");
        });
    });


  </script>

</body>

</html>

Add code to create service areas

Add the following code to create 5, 10, and 15 minute drive time polygons:

  • Change the basemap layer to Navigation and set the location to Bangkok.
  • Create layers for each drive time polygon.
  • Use a click handler to get the click point.
  • Call ArcGIS REST JS to get the polygons.
  • Display them on the map.
Change lineChange lineAdd line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.Add line.
                                                                                                                          
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
  <title>Esri Leaflet</title>

  <!-- Load Leaflet from CDN -->
  <link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css"
    integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A=="
    crossorigin=""/>
<script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"
    integrity="sha512-XQoYMqMTK8LvdxXYG3nZ448hOEQiglfqkJs1NOQV44cWnUrBc8PkAOcXy20w0vlaXaVUearIOBhiXZ5V3ynxwA=="
    crossorigin=""></script>

  <!-- Load Esri Leaflet from CDN -->
  <script src="https://unpkg.com/esri-leaflet@3.0.0/dist/esri-leaflet.js"></script>
  <script src="https://unpkg.com/esri-leaflet-vector@3.0.0/dist/esri-leaflet-vector.js"></script>


  <!-- Load ArcGIS REST JS from CDN -->
  <script src="https://unpkg.com/@esri/arcgis-rest-request@3.0.0/dist/umd/request.umd.js"></script>
  <script src="https://unpkg.com/@esri/arcgis-rest-routing@3.0.0/dist/umd/routing.umd.js"></script>
  <script src="https://unpkg.com/@esri/arcgis-rest-auth@3.0.0/dist/umd/auth.umd.js"></script>


  <style>
    body { margin:0; padding:0; }
    #map {
      position: absolute;
      top:0;
      bottom:0;
      right:0;
      left:0;
      font-family: Arial, Helvetica, sans-serif;
      font-size: 14px;
      color: #323232;
    }
  </style>

</head>

<body>

  <div id="map"></div>

  <script>

    const apiKey = "YOUR-API-KEY";

    const basemapEnum = "ArcGIS:Navigation";

    const map = L.map('map', {
      minZoom: 2

    }).setView([13.7367,100.5231], 13); // Bangkok

    L.esri.Vector.vectorBasemapLayer(basemapEnum, {
      apiKey: apiKey
    }).addTo(map);

    // Layer Group for source point
    const startLayerGroup = L.layerGroup().addTo(map);

    // Layer Group for service area results
    const layerGroup = L.layerGroup().addTo(map);

    // Create the arcgis-rest-js authentication object to use later.
    const authentication = new arcgisRest.ApiKey({
      key: apiKey
    });

    // When the map is clicked, call the service area REST service with the
    // clicked point and display the results.
    map.on("click", (e) => {

      // Clear the previous results
      startLayerGroup.clearLayers();
      layerGroup.clearLayers();

      // Add the source point
      L.marker(e.latlng).addTo(startLayerGroup);

      // Make the API request
      arcgisRest
        .serviceArea({
          endpoint: "https://route-api.arcgis.com/arcgis/rest/services/World/ServiceAreas/NAServer/ServiceArea_World/solveServiceArea",
          authentication,
          facilities: [[e.latlng.lng, e.latlng.lat]]
        })
        .then((response) => {
          // Show the result route on the map.
          L.geoJSON(response.saPolygons.geoJson, {
            style: (feature) => {
              const style = {
                fillOpacity: 0.5,
                weight: 1
              }
              if(feature.properties.FromBreak === 0) {
                style.color = 'hsl(210, 80%, 40%)';
              } else if(feature.properties.FromBreak === 5) {
                style.color = "hsl(210, 80%, 60%)";
              } else {
                style.color = "hsl(210, 80%, 80%)";
              }
              return style;
            }
          }).addTo(layerGroup);
        })
        .catch((error) => {
          console.error(error);
          alert("There was a problem using the route service. See the console for details.");
        });
    });


  </script>

</body>

</html>

Run the app

In CodePen, run your code to display the map.

When you click on the map, three service areas are shown as concentric polygons around a marker. 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: