Find Nearest features of one layer to another

1739
1
Jump to solution
11-17-2015 08:36 AM
DavidChrest
Occasional Contributor II

Is there some kind of example that essentially mimics the ArcToolbox Near tool? I essentially need to select points of one layer that are closes to points of another layer. Some kind of query by distance would also work (select points within x meters of a layer). I don't want to use the FindNearest Analysis widget since it uses up credits and no examples exist on the API site. Is there some way to make this happen? Near or select by distance would be great! Or do I need to create a geoprocessing service utilizing the ArcToolbox Near tool?

Thanks so much for any help or information. It is much appreciated.

David

0 Kudos
1 Solution

Accepted Solutions
DavidChrest
Occasional Contributor II

Thanks so much to Ryan Sellman and Robert Scheitlin for their HUGE help. Below is my working code. I have the buffer distance hard-coded but plan to use an insert value. Use of the geometryEngine is a wonderful way to create buffers and have them union into a single polygon. The JS code below lets the user select points from FeatureLayer1, those selected points then get buffered (500 feet in this case). That buffer is then used to query and select any intersecting points from FeatureLayer2. Some incredibly handy functionality.

//<<<BUFFER OF SELECTED POINTS THEN SELECTS ANOTHER LAYER'S POINTS>>>


//Draw Day 1 tool initialization function
map.on("load", initDrawToolTest);


function initDrawToolTest(evt) {
tbDrawTest = new Draw(evt.map);
tbDrawTest.on("draw-end", displayPolygonTest);
}


//Draw Freehand Polygon for FeatureLayer1
on(dom.byId("TestSelect"), "click", function () {
tbDrawTest.activate(Draw.FREEHAND_POLYGON);
});


//Get geometry from FeatureLayer1 drawn polygon, symbolize polygon, start FeatureLayer1 query 
function displayPolygonTest(evt) {
// Get the geometry from the event object
var geometryInput = evt.geometry;
// Define symbol for finished polygon
var tbDrawSymbol = new SimpleFillSymbol(SimpleFillSymbol.STYLE_SOLID, new SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID, new Color([53, 119, 221]), 2), new Color([53, 119, 221, 0.3]));
map.graphics.clear();
var graphicPolygon = new Graphic(geometryInput, tbDrawSymbol);
map.graphics.add(graphicPolygon);
selectDay1ActivitiesTest(geometryInput); // Call the next function below...vvv
}


//Symbolize FeatureLayer1, create new Query, select features
function selectDay1ActivitiesTest(geometryInput) {
// Define symbol for selected features (using JSON syntax for improved readability)
var symbolSelectedTest = new SimpleMarkerSymbol({
  "type": "esriSMS",
  "style": "esriSMSCircle",
  "color": [255, 115, 0, 128],
  "size": 6,
  "outline": {
  "color": [255, 0, 0, 214],
  "width": 1
  }
});


//Set the selection symbol to FeatureLayer1
FeatureLayer1.setSelectionSymbol(symbolSelectedTest);
//Initialize the query
var queryDay1ActivitiesTest = new Query();
tbDrawTest.deactivate(); //turns off selection tool so it does not stay on in map.
queryDay1ActivitiesTest.geometry = geometryInput;
//Wire the layer's selection complete event, call function to populate grid with selection results
FeatureLayer1.on("selection-complete", populateGrid1);
//Day 1 Activities selection
FeatureLayer1.selectFeatures(queryDay1ActivitiesTest, FeatureLayer.SELECTION_NEW, function (features, selectionMethod) {


  //Create buffer of selection
  var selectedGeoms = graphicsUtils.getGeometries(features);
  var distance = [500];
  var bufferedGeometries = geometryEngine.geodesicBuffer(selectedGeoms, distance, GeometryService.UNIT_FOOT, true);


  var symbol = new SimpleFillSymbol(SimpleFillSymbol.STYLE_SOLID, SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID,
  new Color([0, 0, 255, 0.65]), 2
  ),
  new Color([0, 0, 255, 0.35])
  );


  array.map(bufferedGeometries, function (geometry) {
  var graphic = new Graphic(geometry, symbol);
  map.graphics.add(graphic);
  });


  //Variable represents Query area to select intersecting FeatureLayer2 points
  var geoBuffer = geometryEngine.union(bufferedGeometries);


  //Symbolize FeatureLayer2 selection
  var symbolSelected = new PictureMarkerSymbol({
  "type": "esriPMS",
  "url": "images/coffeeselect.png",
  "contentType": "image/png",
  "width": 20,
  "height": 22
  });
  symbolSelected.setOffset(-1, 0);


  //Set the selection symbol to FeatureLayer2
  FeatureLayer2.setSelectionSymbol(symbolSelected);
  //Select FeatureLayer2 points that intersect buffer
  var querySBTest = new Query();
  querySBTest.geometry = geoBuffer;
  querySBTest.spatialRelationship = Query.SPATIAL_REL_INTERSECTS;
  //Wire the layer's selection complete event, call function to populate grid with selection results
  FeatureLayer2.on("selection-complete", populateGrid2);
  //FeatureLayer2 selection
  FeatureLayer2.selectFeatures(querySBTest, FeatureLayer.SELECTION_NEW);


});
};

View solution in original post

0 Kudos
1 Reply
DavidChrest
Occasional Contributor II

Thanks so much to Ryan Sellman and Robert Scheitlin for their HUGE help. Below is my working code. I have the buffer distance hard-coded but plan to use an insert value. Use of the geometryEngine is a wonderful way to create buffers and have them union into a single polygon. The JS code below lets the user select points from FeatureLayer1, those selected points then get buffered (500 feet in this case). That buffer is then used to query and select any intersecting points from FeatureLayer2. Some incredibly handy functionality.

//<<<BUFFER OF SELECTED POINTS THEN SELECTS ANOTHER LAYER'S POINTS>>>


//Draw Day 1 tool initialization function
map.on("load", initDrawToolTest);


function initDrawToolTest(evt) {
tbDrawTest = new Draw(evt.map);
tbDrawTest.on("draw-end", displayPolygonTest);
}


//Draw Freehand Polygon for FeatureLayer1
on(dom.byId("TestSelect"), "click", function () {
tbDrawTest.activate(Draw.FREEHAND_POLYGON);
});


//Get geometry from FeatureLayer1 drawn polygon, symbolize polygon, start FeatureLayer1 query 
function displayPolygonTest(evt) {
// Get the geometry from the event object
var geometryInput = evt.geometry;
// Define symbol for finished polygon
var tbDrawSymbol = new SimpleFillSymbol(SimpleFillSymbol.STYLE_SOLID, new SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID, new Color([53, 119, 221]), 2), new Color([53, 119, 221, 0.3]));
map.graphics.clear();
var graphicPolygon = new Graphic(geometryInput, tbDrawSymbol);
map.graphics.add(graphicPolygon);
selectDay1ActivitiesTest(geometryInput); // Call the next function below...vvv
}


//Symbolize FeatureLayer1, create new Query, select features
function selectDay1ActivitiesTest(geometryInput) {
// Define symbol for selected features (using JSON syntax for improved readability)
var symbolSelectedTest = new SimpleMarkerSymbol({
  "type": "esriSMS",
  "style": "esriSMSCircle",
  "color": [255, 115, 0, 128],
  "size": 6,
  "outline": {
  "color": [255, 0, 0, 214],
  "width": 1
  }
});


//Set the selection symbol to FeatureLayer1
FeatureLayer1.setSelectionSymbol(symbolSelectedTest);
//Initialize the query
var queryDay1ActivitiesTest = new Query();
tbDrawTest.deactivate(); //turns off selection tool so it does not stay on in map.
queryDay1ActivitiesTest.geometry = geometryInput;
//Wire the layer's selection complete event, call function to populate grid with selection results
FeatureLayer1.on("selection-complete", populateGrid1);
//Day 1 Activities selection
FeatureLayer1.selectFeatures(queryDay1ActivitiesTest, FeatureLayer.SELECTION_NEW, function (features, selectionMethod) {


  //Create buffer of selection
  var selectedGeoms = graphicsUtils.getGeometries(features);
  var distance = [500];
  var bufferedGeometries = geometryEngine.geodesicBuffer(selectedGeoms, distance, GeometryService.UNIT_FOOT, true);


  var symbol = new SimpleFillSymbol(SimpleFillSymbol.STYLE_SOLID, SimpleLineSymbol(SimpleLineSymbol.STYLE_SOLID,
  new Color([0, 0, 255, 0.65]), 2
  ),
  new Color([0, 0, 255, 0.35])
  );


  array.map(bufferedGeometries, function (geometry) {
  var graphic = new Graphic(geometry, symbol);
  map.graphics.add(graphic);
  });


  //Variable represents Query area to select intersecting FeatureLayer2 points
  var geoBuffer = geometryEngine.union(bufferedGeometries);


  //Symbolize FeatureLayer2 selection
  var symbolSelected = new PictureMarkerSymbol({
  "type": "esriPMS",
  "url": "images/coffeeselect.png",
  "contentType": "image/png",
  "width": 20,
  "height": 22
  });
  symbolSelected.setOffset(-1, 0);


  //Set the selection symbol to FeatureLayer2
  FeatureLayer2.setSelectionSymbol(symbolSelected);
  //Select FeatureLayer2 points that intersect buffer
  var querySBTest = new Query();
  querySBTest.geometry = geoBuffer;
  querySBTest.spatialRelationship = Query.SPATIAL_REL_INTERSECTS;
  //Wire the layer's selection complete event, call function to populate grid with selection results
  FeatureLayer2.on("selection-complete", populateGrid2);
  //FeatureLayer2 selection
  FeatureLayer2.selectFeatures(querySBTest, FeatureLayer.SELECTION_NEW);


});
};
0 Kudos