identify all graphics within an area

807
7
03-03-2020 10:20 AM
TravisYordi
New Contributor II

I would like to be able to draw/sketch a polygon on the map and then identify all graphics within that polygon area. The 'identify' functions appear to only take in a single point.  Is there a way to identify graphics within a geometry?

0 Kudos
7 Replies
Nicholas-Furness
Esri Regular Contributor

If you want to take a set of AGSGraphics and see if they are within a polygon, you can use AGSGeometryEngine and the polygon and filter them out with something like this…

func filterGraphics(graphics: [AGSGraphic], within polygon: AGSPolygon) -> [AGSGraphic] {
    return graphics.filter {
        if let geom = $0.geometry {
            return AGSGeometryEngine.geometry(geom, within: polygon)
        } else {
            return false
        }
    }
}

I'm pretty sure that's what you're after.

I'm checking because we use Identify to mean a very specific thing in ArcGIS: respond to a user interaction with the map (usually a tap or click) looking to get more information about a feature the user can see in the map. But I don't think that's what you're looking for. If it is, let me know.

0 Kudos
TravisYordi
New Contributor II

it's not super fast because I have to give it all of the graphics that are currently on that layer to sift through, but it does work.

0 Kudos
TravisYordi
New Contributor II

Nick, I un-marked this as correct because I'm not sure this answers my question (unless the answer is no).  In your example your function takes a set of graphics to sort through, but this is what I'm looking for a map function to give me if possible.  I don't want to have to sort through ALL graphics on the map, I'm looking for a quicker way I guess.

0 Kudos
Nicholas-Furness
Esri Regular Contributor

Are they graphics in graphics overlays, or are they features in feature layers? Are their geometries points, lines, or polygons? And how many do you have?

I've used the above approach on a few thousand (animated) AGSPoints stored as AGSGraphics testing against an AGSPolygon and it's pretty real-time whether the graphic is in or not on modern hardware.

0 Kudos
TravisYordi
New Contributor II

They are point graphics in graphics overlays.  There could be a few or many (20k +).

0 Kudos
Nicholas-Furness
Esri Regular Contributor

Is the process too slow to be useful to you, or is it impacting the UI? Are you dispatching the work off the main thread?

If you can provide a repro case (feel free to DM me) we can look into it. It should be pretty fast.

One thought is that if you have, say, 20,000 graphics globally but are just searching a small polygon that might include only 20 points, that's a lot of point-in-polygon tests that are unnecessary. You could try first filtering against the polygon's extent (using geometryengine.intersect rather than within might be a bit quicker) and then filtering further to see what's actually in the polygon. But it's hard to know what to suggest without knowing more about the nature of the data so a repro case would really help.

0 Kudos
Nicholas-Furness
Esri Regular Contributor

Travis Yordi wrote:

Nick, I un-marked this as correct because I'm not sure this answers my question (unless the answer is no).  In your example your function takes a set of graphics to sort through, but this is what I'm looking for a map function to give me if possible.  I don't want to have to sort through ALL graphics on the map, I'm looking for a quicker way I guess.

Also, no, there is no single call against a AGSGraphicsOverlay.

What you could consider is using a AGSFeatureCollectionLayer and AGSFeatureCollectionTable instead of an AGSGraphicsOverlay, and then calling queryFeatures on the AGSeatureCollectionTable. In the AGSQueryParameters you pass to queryFeatures, set the geometry to your polygon and set the spatialRelationship to .intersects.

0 Kudos