Esri Leaflet

Use Turf and Esri Leaflet together

Esri Leaflet pairs nicely with clientside libraries that can perform spatial analysis in the browser like Turf.js. This demo shows how the output from a spatial query can be augmented to isolate features that have a spatial relationship with another arbitrary geometry.

<html>
<head>
  <meta charset=utf-8 />
  <title>Use Turf and Esri Leaflet together</title>
  <meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />

    <!-- Load Leaflet from CDN -->
    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.2.0/dist/leaflet.css"
    integrity="sha512-M2wvCLH6DSRazYeZRIm1JnYyh22purTM+FDB5CsyxtQJYeKq83arPe5wgbNmcFXGqiSH2XR8dT/fJISVA1r/zQ=="
    crossorigin=""/>
    <script src="https://unpkg.com/leaflet@1.2.0/dist/leaflet.js"
    integrity="sha512-lInM/apFSqyy1o6s89K4iQUKg6ppXEgsVxT35HbzUupEVRh2Eu9Wdl4tHj7dZO0s1uvplcYGmt3498TtHq+log=="
    crossorigin=""></script>


    <!-- Load Esri Leaflet from CDN -->
    <script src="https://unpkg.com/esri-leaflet@2.1.1/dist/esri-leaflet.js"
    integrity="sha512-ECQqaYZke9cSdqlFG08zSkudgrdF6I1d8ViSa7I3VIszJyVqw4ng1G8sehEXlumdMnFYfzY0tMgdQa4WCs9IUw=="
    crossorigin=""></script>


  <style>
    body { margin:0; padding:0; }
    #map { position: absolute; top:0; bottom:0; right:0; left:0; }
  </style>
</head>
<body>

<script src="https://unpkg.com/@turf/turf@3.5.1/turf.min.js"></script>

<style>
  #info-pane {
    position: absolute;
    top: 10px;
    right: 10px;
    z-index: 1000;
    padding: 1em;
    background: white;
    max-width: 150px;
  }
</style>

<div id="map"></div>
<div id="info-pane" class="leaflet-bar">
  <label>
  Census block points that intersect both bounding boxes and are shown in red.
  </label>
</div>

<script type='text/javascript'>
  // two GeoJSON bounding boxes.  the first smaller than the second.
    var boundingBoxes = {
      "type": "FeatureCollection",
      "features": [
        {
          "type": "Feature",
          "properties": {
            "color": "orange"
          },
          "geometry": {
            "type": "Polygon",
            "coordinates": [
              [
                [ -84.39010620117188, 33.747965492070236 ],
                [ -84.39010620117188, 33.75431694675655 ],
                [ -84.37311172485352, 33.75431694675655 ],
                [ -84.37311172485352, 33.747965492070236 ],
                [ -84.39010620117188, 33.747965492070236 ]
              ]
            ]
          }
        },
        {
          "type": "Feature",
          "properties": {
            "color": "#0ceb70"
          },
          "geometry": {
            "type": "Polygon",
            "coordinates": [
              [
                [ -84.39963340759277, 33.744254312044156 ],
                [ -84.39963340759277,  33.75817040902938 ],
                [ -84.38444137573242, 33.75817040902938 ],
                [ -84.38444137573242, 33.744254312044156 ],
                [ -84.39963340759277, 33.744254312044156 ]
              ]
            ]
          }
        }
      ]
    }

    // draw a map of atlanta
    var map = L.map('map').setView([33.752, -84.385], 14.5);
    L.esri.basemapLayer('Topographic').addTo(map);

    // display the bounding boxes on the map
    L.geoJSON(boundingBoxes, {
      style: function (feature) {
        return {color: feature.properties.color};
      }
    }).addTo(map);

    // query for census block points that intersect the smaller box
    var query = L.esri.query({
      url: 'http://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer/0'
    })
    query.intersects(boundingBoxes.features[0])
    query.run(function (err, censusCollection, raw) {
      var features = censusCollection.features;
      // loop through the collection of census block points
      for (i=0; i<features.length; i++) {
        // if the point is inside (or contained by, the bigger box) draw it in red
        if (turf.inside(features[i], boundingBoxes.features[1])) {
          L.geoJSON(features[i], {
            pointToLayer: function(geoJsonPoint, latlng) {
              return L.circleMarker(latlng, {
                color: '#ff0066'
              });
            }
          }).addTo(map);
        } else {
          // if its outside (or not contained) by the bigger box, make it less opaque.
          L.geoJSON(features[i], {
            pointToLayer: function(geoJsonPoint, latlng) {
              return L.circleMarker(latlng, {
                radius: 10,
                color: 'gray',
                opacity: 0.2
              });
            }
          }).addTo(map);
        }
      }
    });
</script>

</body>
</html>