How do I query records based on actual location using the Python API?

360
3
Jump to solution
08-18-2020 02:53 PM
JudyMak
New Contributor II

Hello,

I've been using the Python API to batch-update records for hosted feature service layers on ArcGIS Online.

To do this, I query the layer according to the API Syntax.

One such example would be like this:

search_item = gis.content.get('<ITEM ID AS A STRING>')  # change this for every layer you run this on

item_layers = search_item.layers

item_layers[0].query(where="<ATTRIBUTE> = '<Example Data>' ")

However, I'm dealing with a layer that has hundreds of thousands of points, and now I want to narrow the results by querying all of the points that are in a certain area. There is no other attribute field that universally describes the points in this area besides their location. There are latitude/longitude fields, but those fields happen to be empty in my case.

How do I query points by location in the Python API syntax, using the point's actual location/the hidden 'Shape'/geometry field?

A non-working example of what I want would be something like filtering out all points below a certain latitude, like 34.1°N, (assuming WGS 1984):

item_layers[0].query(where="geometry.y > 34.1")

I could also run Calculate Geometry on the point layer and then query by those fields, but running Calculate Geometry on all of the points would take as long as returning everything with a raw .query()--that is, not querying at all. I'm trying to avoid operating on all of the points, if possible.

Thanks!

0 Kudos
1 Solution

Accepted Solutions
RandyBurton
MVP Regular Contributor

Have you tried the geometry_filter argument in the FeatureLayer.query.

geometry_filter
Optional from arcgis.geometry.filter. Allows for the information to be filtered on spatial relationship with another geometry.

See the usage example for intersects for a coding example on this help page: arcgis.geometry.filters module

View solution in original post

3 Replies
RandyBurton
MVP Regular Contributor

Have you tried the geometry_filter argument in the FeatureLayer.query.

geometry_filter
Optional from arcgis.geometry.filter. Allows for the information to be filtered on spatial relationship with another geometry.

See the usage example for intersects for a coding example on this help page: arcgis.geometry.filters module

View solution in original post

JudyMak
New Contributor II

That worked for me, thank you. I actually saw that earlier, but didn't want to create a whole new polygon 'filter' layer to have to interface with and maintain--then I forgot about that solution. It doesn't look like there's a way to simply query by a set of coordinates or a specific latitude/longitude/xy threshold, though, so creating a filter layer to intersect with is good enough. I did mine easily using Map Notes in the ArcGIS Online webmap viewer, then saving that polygon layer permanently.

Here's the full code in case anyone else stumbles upon this question:

permanent_item = gis.content.get('<ITEM ID OF ORIGINAL HOSTED FEATURE SERVICE LAYER>')
permanent_layer = permanent_item.layers

filter_item = gis.content.get('<ITEM ID OF HOSTED FEATURE SERVICE BOUNDING AREA POLYGON>')
filter_layer = filter_item.layers

box_fset = filter_layer[0].query()
box_geom_dict = box_fset.features[0].geometry
box_geom = Geometry(box_geom_dict)

box_filter = intersects(box_geom)

permanent_fset = permanent_layer[0].query(geometry_filter=box_filter)

RandyBurton
MVP Regular Contributor

I had also noticed that the API for Python's geometry_filter was a bit more limited than the REST API query which allows you to enter an x-y point and specify a distance.  Perhaps this will be added to the Python API at some future date.