How do I get an array of Graphics, in a given radius?

1276
5
Jump to solution
08-10-2017 09:52 AM
RobertTaracha
New Contributor

Hello,

   I am trying to make a function where I can locate near by points. The idea is that I click on a point in the map and a hitTest would return the graphic. This graphic would be the center point and I would find all points within a given radius. Ideally I would want to know the point and the distance and in a array.

I am lost at the moment, I am working with multiple Feature Layers. If possible to point me to an example that would be perfect.

Here is a sample of what I am doing at the moment. 

""""""""""""""""""""""" This point gives me the graphics objec I clicked on """"""""""""""""""""""""""""""""'

bd4sp.view.hitTest(event)
.then(bd4sp.getGraphics) //gets the graphics
.then(bd4sp.createDistanceLayer); // creates the lines for distance

""""""""""""""""""""""""""""""""""""""

***********************************************************************************************************************************

// This function takes the response and tries

getGraphics: function (response) { 
//clearPolyline(); //clear old lines
var graphic = response.results[0].graphic; //the top most graphic from the click location

console.log("Graphic Object", graphic['geometry']);
var close_points = bd4sp.geo_engine.nearestVertices(graphic['geometry'],graphic['geometry'], 300, 20);
console.log("Close Points", close_points);
//Obtain lat and long form graphic information
var p_o_i = bd4sp.point_of_intrest[0].geogrpraphic_proximity; // point of intrests
var lat_long_arry = [];


var polyarry = [];

for (var make in p_o_i) {
   for (var i = 0; i < p_o_i[make].length; i++) {
      var x = p_o_i[make].x;
      var y = p_o_i[make].y;
      lat_long_arry.push({x,y});

   }
}

polyarry = bd4sp.getAllClosePoints(graphic.geometry['latitude'], graphic.geometry['longitude'], lat_long_arry); //array of graphic lines
console.log("LINES TO DRAW ->", polyarry);
return polyarry;
}

***********************************************************************************************************************************

This 

var close_points = bd4sp.geo_engine.nearestVertices(graphic['geometry'],graphic['geometry'], 300, 20);

returns an array but I always get 0 because its the same point, is there a way to have one argument only?

Tags (1)
0 Kudos
1 Solution

Accepted Solutions
ThomasSolow
Occasional Contributor III

What probably want to do here is:

  1. User clicks map: do a hitTest, if a graphic is a found, take that graphic's geometry and continue
  2. Using the geometry obtained in step 1, create a circle geometry with the center as the geometry from step 1 and a radius of whatever you like (note, circles can be geodesic if you're using wgs84 or web mercator, default unit for setting radius is meters)
  3. Take the extent of the circle you just created (circles, like polygons automatically compute their extent when created.  Access this via circle.extent).
  4. Test the extent of the circle against all the graphics on each featureLayer you want to search.  This can be done manually or with featureLayerView.queryFeatures or with featureLayer.queryFeatures
  5. Take the array of graphics that results from step 4 and filter them against the original circle.  Use geometryEngine.intersects(circle, graphic.geometry) for each graphic that passed the previous test.
  6. The result is an array of graphics that fit inside the circle for each feature layer you tested.
  7. You can now compute distance using the geometry Engine, or Point.distance(point) and display the results however you like.

It's preferable (in my opinion) to do the extent search first because it's cheap compared to the circle search, and the majority of graphics will likely be eliminated.  The geometryEngine.intersects method is more expensive when using a circle or polygon, so this should only be tested against graphics you know are inside the circle's extent.

Edit - this is the client-side method.  You can also pass in the circle to featureLayer.queryFeatures to do this on the server.  If you do this, you'll want to send one featureLayer.queryFeatures request for each featureLayer.  You'll wrap these requests in Promise.all(), wait for all of them to return, and then display your results with polylines or however you like.  If you use the server, you don't need to worry about the intersects method being expensive so forget the circle.extent stuff for that.

View solution in original post

5 Replies
KenBuja
MVP Esteemed Contributor

Isn't the first parameter of the nearestVertices method supposed to be the geometry of the points you're trying to locate instead of the point you clicked?

0 Kudos
RobertTaracha
New Contributor

It might be but i am wondering if there is a way to find those points in a radius and get there information, without knowing where it is exactly. 

0 Kudos
KenBuja
MVP Esteemed Contributor

My approach on this would be to create a buffer and use that geometry in a query of your point layer.

0 Kudos
ThomasSolow
Occasional Contributor III

What probably want to do here is:

  1. User clicks map: do a hitTest, if a graphic is a found, take that graphic's geometry and continue
  2. Using the geometry obtained in step 1, create a circle geometry with the center as the geometry from step 1 and a radius of whatever you like (note, circles can be geodesic if you're using wgs84 or web mercator, default unit for setting radius is meters)
  3. Take the extent of the circle you just created (circles, like polygons automatically compute their extent when created.  Access this via circle.extent).
  4. Test the extent of the circle against all the graphics on each featureLayer you want to search.  This can be done manually or with featureLayerView.queryFeatures or with featureLayer.queryFeatures
  5. Take the array of graphics that results from step 4 and filter them against the original circle.  Use geometryEngine.intersects(circle, graphic.geometry) for each graphic that passed the previous test.
  6. The result is an array of graphics that fit inside the circle for each feature layer you tested.
  7. You can now compute distance using the geometry Engine, or Point.distance(point) and display the results however you like.

It's preferable (in my opinion) to do the extent search first because it's cheap compared to the circle search, and the majority of graphics will likely be eliminated.  The geometryEngine.intersects method is more expensive when using a circle or polygon, so this should only be tested against graphics you know are inside the circle's extent.

Edit - this is the client-side method.  You can also pass in the circle to featureLayer.queryFeatures to do this on the server.  If you do this, you'll want to send one featureLayer.queryFeatures request for each featureLayer.  You'll wrap these requests in Promise.all(), wait for all of them to return, and then display your results with polylines or however you like.  If you use the server, you don't need to worry about the intersects method being expensive so forget the circle.extent stuff for that.

RobertTaracha
New Contributor

thank you sounds great

This makes a lot of sense to me.

0 Kudos