Select to view content in your preferred language

Features within 300 feet of selected feature

884
1
Jump to solution
02-19-2021 10:30 AM
khanley
Emerging Contributor

I see a lot of examples of queries using a circle to find features within a given distance of a center point, but I have yet to be able to find an example of a query done using a feature to find all features within a given distance.

Can someone point me in the right direction? I'm sure it's very similar to a circle but something just isn't clicking in my head.

Thank you.

0 Kudos
1 Solution

Accepted Solutions
RobertScheitlin__GISP
MVP Emeritus

Here is a mashup of the Select with Feature Layer and Geometry Service - Buffer samples. It querys the census block layer and buffers the results and uses that buffer to query census block points that intersect the buffer.

<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    
    <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">
    <title>Select with feature layer</title>
    <link rel="stylesheet" href="https://js.arcgis.com/3.35/dijit/themes/tundra/tundra.css">
    <link rel="stylesheet" href="https://js.arcgis.com/3.35/esri/css/esri.css">
    <style>
      html, body, #mapDiv {
        padding: 0;
        margin: 0;
        height: 100%;
      }
      #messages{
        background-color: #fff;
        box-shadow: 0 0 5px #888;
        font-size: 1.1em;
        max-width: 15em;
        padding: 0.5em;
        position: absolute;
        right: 20px;
        top: 20px;
        z-index: 40;
      }
    </style>
    <script src="https://js.arcgis.com/3.35/"></script>
    <script>
      var map;
      require([
        "esri/map", "esri/layers/FeatureLayer", 
        "esri/tasks/query", "esri/tasks/GeometryService",
        "esri/tasks/BufferParameters",
        "esri/graphic", "esri/symbols/SimpleMarkerSymbol",
        "esri/symbols/SimpleLineSymbol", "esri/symbols/SimpleFillSymbol", "esri/renderers/SimpleRenderer",
        "esri/config", "esri/Color", "dojo/dom", "dojo/domReady!"
      ], function(
        Map, FeatureLayer,
        Query, GeometryService, BufferParameters,
        Graphic, SimpleMarkerSymbol,
        SimpleLineSymbol, SimpleFillSymbol, SimpleRenderer,
        esriConfig, Color, dom
      ) {
        esriConfig.defaults.geometryService = new GeometryService("https://utility.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer");

        map = new Map("mapDiv", { 
          basemap: "streets",
          center: [-95.249, 38.954],
          zoom: 14,
          slider: false
        });
        
        // Add the census block points in on demand mode. An outfield is specified since it is used when calculating   the total population falling within the one mile radius.
        var featureLayer = new FeatureLayer("https://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer/0",{
          outFields: ["POP2000"]
        });

        // census block polygon layer
        var featureLayer2 = new FeatureLayer("https://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer/1",{
          outFields: ["FIPS"]
        });

        // Selection symbol used to draw the selected census block points within the buffer polygon
        var symbol = new SimpleMarkerSymbol(
          SimpleMarkerSymbol.STYLE_CIRCLE, 
          12, 
          new SimpleLineSymbol(
            SimpleLineSymbol.STYLE_NULL, 
            new Color([247, 34, 101, 0.9]), 
            1
          ),
          new Color([207, 34, 171, 0.5])
        );
        featureLayer.setSelectionSymbol(symbol); 
        
        // Make unselected features invisible
        var nullSymbol = new SimpleMarkerSymbol().setSize(0);
        featureLayer.setRenderer(new SimpleRenderer(nullSymbol));
        
        map.addLayer(featureLayer);
        
        var blockSymb = new SimpleFillSymbol(
          SimpleFillSymbol.STYLE_NULL,
          new SimpleLineSymbol(
            SimpleLineSymbol.STYLE_SHORTDASHDOTDOT,
            new Color([105, 105, 105]),
            2
          ), new Color([255, 255, 0, 0.25])
        );
        var block, buffer;

        //setup the buffer parameters
        var params = new BufferParameters();
        params.distances = [0.5];
        params.outSpatialReference = map.spatialReference;
        params.unit = GeometryService["UNIT_STATUTE_MILE"];
        
        setTimeout(function(){
          var query2 = new Query();
          query2.where = "FIPS = '200450004001'";
          query2.returnGeometry = true;
          query2.outSpatialReference = map.spatialReference;
          featureLayer2.queryFeatures(query2, function(response){
            map.graphics.clear();
            block = response.features[0].geometry;
            var graphic = new Graphic(block, blockSymb);
            map.graphics.add(graphic);

            params.geometries = [block];
            esriConfig.defaults.geometryService.buffer(params, showBuffer);
          });
        }, 2000);

        function showBuffer(bufferedGeometries){
            var symbol = new SimpleFillSymbol(
                SimpleFillSymbol.STYLE_NULL,
                new SimpleLineSymbol(
                SimpleLineSymbol.STYLE_SOLID,
                new Color([255,0,0,0.65]), 2
                ),
                new Color([255,0,0,0.35])
            );
            buffer = bufferedGeometries[0];
            var graphic = new Graphic(buffer, symbol);
            map.graphics.add(graphic);
            var query = new Query();
            query.geometry = buffer.getExtent();
            featureLayer.queryFeatures(query, selectInBuffer);
        }

        function selectInBuffer(response){
          var feature;
          var features = response.features;
          var inBuffer = [];
          // Filter out features that are not actually in buffer, since we got all points in the buffer's bounding box
          for (var i = 0; i < features.length; i++) {
            feature = features[i];
            if(buffer.contains(feature.geometry)){
              inBuffer.push(feature.attributes[featureLayer.objectIdField]);
            }
          }
          var query = new Query();
          query.objectIds = inBuffer;
          // Use an objectIds selection query (should not need to go to the server)
          featureLayer.selectFeatures(query, FeatureLayer.SELECTION_NEW, function(results){
            var totalPopulation = sumPopulation(results);
            var r = "";
            r = "<b>The total Census Block population within the Census Block buffered by .5 mi is <i>" + totalPopulation + "</i>.</b>";
            dom.byId("messages").innerHTML = r;
          });
        }
        
        function sumPopulation(features) {
          var popTotal = 0;
          for (var x = 0; x < features.length; x++) {
            popTotal = popTotal + features[x].attributes["POP2000"];
          }
          return popTotal;
        }
      });
    </script>
  </head>

  <body>
    <span id="messages">Wait for FIPS = '200450004001' Query to execute...</span>
    <div id="mapDiv"></div>
  </body>
</html>

 

View solution in original post

1 Reply
RobertScheitlin__GISP
MVP Emeritus

Here is a mashup of the Select with Feature Layer and Geometry Service - Buffer samples. It querys the census block layer and buffers the results and uses that buffer to query census block points that intersect the buffer.

<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    
    <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">
    <title>Select with feature layer</title>
    <link rel="stylesheet" href="https://js.arcgis.com/3.35/dijit/themes/tundra/tundra.css">
    <link rel="stylesheet" href="https://js.arcgis.com/3.35/esri/css/esri.css">
    <style>
      html, body, #mapDiv {
        padding: 0;
        margin: 0;
        height: 100%;
      }
      #messages{
        background-color: #fff;
        box-shadow: 0 0 5px #888;
        font-size: 1.1em;
        max-width: 15em;
        padding: 0.5em;
        position: absolute;
        right: 20px;
        top: 20px;
        z-index: 40;
      }
    </style>
    <script src="https://js.arcgis.com/3.35/"></script>
    <script>
      var map;
      require([
        "esri/map", "esri/layers/FeatureLayer", 
        "esri/tasks/query", "esri/tasks/GeometryService",
        "esri/tasks/BufferParameters",
        "esri/graphic", "esri/symbols/SimpleMarkerSymbol",
        "esri/symbols/SimpleLineSymbol", "esri/symbols/SimpleFillSymbol", "esri/renderers/SimpleRenderer",
        "esri/config", "esri/Color", "dojo/dom", "dojo/domReady!"
      ], function(
        Map, FeatureLayer,
        Query, GeometryService, BufferParameters,
        Graphic, SimpleMarkerSymbol,
        SimpleLineSymbol, SimpleFillSymbol, SimpleRenderer,
        esriConfig, Color, dom
      ) {
        esriConfig.defaults.geometryService = new GeometryService("https://utility.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer");

        map = new Map("mapDiv", { 
          basemap: "streets",
          center: [-95.249, 38.954],
          zoom: 14,
          slider: false
        });
        
        // Add the census block points in on demand mode. An outfield is specified since it is used when calculating   the total population falling within the one mile radius.
        var featureLayer = new FeatureLayer("https://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer/0",{
          outFields: ["POP2000"]
        });

        // census block polygon layer
        var featureLayer2 = new FeatureLayer("https://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer/1",{
          outFields: ["FIPS"]
        });

        // Selection symbol used to draw the selected census block points within the buffer polygon
        var symbol = new SimpleMarkerSymbol(
          SimpleMarkerSymbol.STYLE_CIRCLE, 
          12, 
          new SimpleLineSymbol(
            SimpleLineSymbol.STYLE_NULL, 
            new Color([247, 34, 101, 0.9]), 
            1
          ),
          new Color([207, 34, 171, 0.5])
        );
        featureLayer.setSelectionSymbol(symbol); 
        
        // Make unselected features invisible
        var nullSymbol = new SimpleMarkerSymbol().setSize(0);
        featureLayer.setRenderer(new SimpleRenderer(nullSymbol));
        
        map.addLayer(featureLayer);
        
        var blockSymb = new SimpleFillSymbol(
          SimpleFillSymbol.STYLE_NULL,
          new SimpleLineSymbol(
            SimpleLineSymbol.STYLE_SHORTDASHDOTDOT,
            new Color([105, 105, 105]),
            2
          ), new Color([255, 255, 0, 0.25])
        );
        var block, buffer;

        //setup the buffer parameters
        var params = new BufferParameters();
        params.distances = [0.5];
        params.outSpatialReference = map.spatialReference;
        params.unit = GeometryService["UNIT_STATUTE_MILE"];
        
        setTimeout(function(){
          var query2 = new Query();
          query2.where = "FIPS = '200450004001'";
          query2.returnGeometry = true;
          query2.outSpatialReference = map.spatialReference;
          featureLayer2.queryFeatures(query2, function(response){
            map.graphics.clear();
            block = response.features[0].geometry;
            var graphic = new Graphic(block, blockSymb);
            map.graphics.add(graphic);

            params.geometries = [block];
            esriConfig.defaults.geometryService.buffer(params, showBuffer);
          });
        }, 2000);

        function showBuffer(bufferedGeometries){
            var symbol = new SimpleFillSymbol(
                SimpleFillSymbol.STYLE_NULL,
                new SimpleLineSymbol(
                SimpleLineSymbol.STYLE_SOLID,
                new Color([255,0,0,0.65]), 2
                ),
                new Color([255,0,0,0.35])
            );
            buffer = bufferedGeometries[0];
            var graphic = new Graphic(buffer, symbol);
            map.graphics.add(graphic);
            var query = new Query();
            query.geometry = buffer.getExtent();
            featureLayer.queryFeatures(query, selectInBuffer);
        }

        function selectInBuffer(response){
          var feature;
          var features = response.features;
          var inBuffer = [];
          // Filter out features that are not actually in buffer, since we got all points in the buffer's bounding box
          for (var i = 0; i < features.length; i++) {
            feature = features[i];
            if(buffer.contains(feature.geometry)){
              inBuffer.push(feature.attributes[featureLayer.objectIdField]);
            }
          }
          var query = new Query();
          query.objectIds = inBuffer;
          // Use an objectIds selection query (should not need to go to the server)
          featureLayer.selectFeatures(query, FeatureLayer.SELECTION_NEW, function(results){
            var totalPopulation = sumPopulation(results);
            var r = "";
            r = "<b>The total Census Block population within the Census Block buffered by .5 mi is <i>" + totalPopulation + "</i>.</b>";
            dom.byId("messages").innerHTML = r;
          });
        }
        
        function sumPopulation(features) {
          var popTotal = 0;
          for (var x = 0; x < features.length; x++) {
            popTotal = popTotal + features[x].attributes["POP2000"];
          }
          return popTotal;
        }
      });
    </script>
  </head>

  <body>
    <span id="messages">Wait for FIPS = '200450004001' Query to execute...</span>
    <div id="mapDiv"></div>
  </body>
</html>