Feature Layer query for multiple coordinates

824
4
01-28-2020 06:43 AM
GillesJacobs
New Contributor

Hi,

I have a FeatureLayer that I'm trying to query for a bunch of coordinates. Is there any way to query the FeatureLayer once (from the WWW to my local machine) and then query it once per coordinate, instead of doing an HTTP request per coordinate?

Thanks,

Gilles

0 Kudos
4 Replies
AnttiKajanus
New Contributor III

If i understood your need correctly, you can use query with multipoint to get all the points in one go and then query the returned result set further. The api is a bit confusing for the query but you should get the idea from this. 

from arcgis.gis import GIS
from arcgis.features import FeatureLayer
from arcgis.geometry import *
import getpass

password = getpass.getpass("Enter password: ")
gis = GIS('org', 'me', password)

feature_layer_item = gis.content.get('bfb34d920bda46388e95a9d4e71e036b')
feature_layer = feature_layer_item.layers[0]

json = {"points":[
            [-9816005.5426,5126478.4306999967],
            [-9814244.3355,5126472.3226],
            [-9813815.49,5126409.5697999969]
        ],
        "spatialReference":{"wkid":102100 }};

multi_point = MultiPoint(json)
print(multi_point.is_valid())
for point in multi_point.coordinates():
    print(point)

query_result = feature_layer.query(geometry_filter = filters.contains(multi_point))
len(query_result.features)‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
0 Kudos
GillesJacobs
New Contributor
Hi,
I tested it and it doesn't seem to do what I want it to do.

Maybe to explain my use-case better: I have this feature layer (https://gis.wri.org/server/rest/services/LandMark/comm_ind_Documented/MapServer/1) that you can visualize graphically here.
I would like to query these layer for multiple locations; for example (LAT 36.357824, LNG-109.271351) and (LAT -14.681117, LNG 127.484020). Querying the points one by one I get the results I want, but the MultiPoint approach doesn't get me any results (seemingly because both points need to be  in a the same shape).

My code below:

MultiPoint:
feature_layer = arcgis.features.FeatureLayer(FEATURE_LAYER_comm_ind_Documented)
result = feature_layer.query(geometry_filter=arcgis.geometry.filters.contains(multi_point))

Point by point:
feature_layer = arcgis.features.FeatureLayer(FEATURE_LAYER_comm_ind_Documented)
point = arcgis.geometry.Point({'x': location.lng, 'y': location.lat, 'spatialReference': {'wkid': 4326}})
result = feature_layer.query(return_geometry='false', sr={'wkid': 4326}, geometry_filter=geom_filter).to_dict()
The reason why I would like to avoind the point-by-point approach is because I have thousands of locations, and I want to save round-trips to the MapServer.
I also tried downloading the layer to a GeoAccessor or DataFrame, but that takes forever.
Maybe what I want to do is not possible
Best,
Gilles
0 Kudos
AnttiKajanus
New Contributor III

I totally get that you want to do all in one query to avoid the ridiculous amount of HTTP calls when doing these kind of queries one by one. I think that what you are looking here is to use a correct spatial relationship.

Feature Service supports following spatial relationships on the query

  • esriSpatialRelIntersects —Part of an input feature is contained in the query geometry
  • esriSpatialRelContains —Part or all of an input feature is contained within the query geometry
  • esriSpatialRelCrosses —An input feature crosses the query geometry
  • esriSpatialRelEnvelopeIntersects —The envelope of an input feature intersects the envelope of the query geometry
  • esriSpatialRelOverlaps —An input feature overlaps the query geometry
  • esriSpatialRelTouches —An input feature touches the border of the query geometry
  • esriSpatialRelWithin—An input feature is completely enclosed by the query geometry

So instead of using contains you should use intersects instead. That should/could/maybe do the trick. 

from arcgis.gis import GIS
from arcgis.features import FeatureLayerCollection
from arcgis.geometry import *

feature_service_url = 'https://gis.wri.org/server/rest/services/LandMark/comm_ind_Documented/MapServer'
feature_service_root = FeatureLayerCollection(feature_service_url)
feature_layer = feature_service_root.layers[1]
feature_layer

# <FeatureLayer url:"https://gis.wri.org/server/rest/services/LandMark/comm_ind_Documented/MapServer/1">

multipoint_json = {"points":[
            [-109.271351,36.357824],
            [127.484020,-14.681117]
        ],
        "spatialReference":{"wkid":4326 }};

multipoint = MultiPoint(multipoint_json)
print(multipoint.is_valid())

# True

query_result = feature_layer.query(
                geometry_filter = filters.intersects(multipoint), 
                return_geometry='false',
                out_fields = 'NAME')
print("Found {} results.".format(len(query_result.features)))
for feature in query_result.features:
    print(feature)
    
# Found 3 results.
# {"attributes": {"OBJECTID": 30989, "Name": "Navajo Nation Reservation"}}
# {"attributes": {"OBJECTID": 106183, "Name": "FORREST RIVER"}}
# {"attributes": {"OBJECTID": 107290, "Name": "Balanggarra (Combined)"}}
OSINT_ENGINEER
New Contributor III

Whenever we try to use Multipoint directly against the query operation of a hosted feature service endpoint, it seems the feature service always returns the first matching feature, not all matching features. Would you be so kind and validate that maybe our Multipoint geometry is malformed?

0 Kudos