Hi,
Is it possible to set an Area of Interest on a Hosted Feature Layer View using the ArcGIS API for Python?
I know how to create a view on a Hosted Feature Layer and to set a View Definition by defining which features to show. (This procedure is also clearly explained in this blog: https://community.esri.com/groups/arcgis-python-api/blog/2019/02/11/using-the-arcgis-api-for-python-...)
But you can also set a View Definition on a Hosted Feature Layer View by defining an Area of Interest. (This was new in ArcGIS Online in December 2017: What’s new with hosted feature layer views (December 2017))
So, my question is: is it possible to somehow set this Area of Interest using the ArcGIS API for Python?
So far, my research (Google, etc.) did not result in a positive answer, so any hint would be appreciated.
Thanks in advance,
Egge-Jan
Solved! Go to Solution.
Hi Egge-Jan,
Thank you for sharing that blog spot here and I hope it was useful to you!
Essentially, when you set an area of interest the updateDefinition operation is executed on the view layer (https://whatever.domain.com/arcgis/rest/admin/services/worldEQView/FeatureServer/0/updateDefinition)
That request looks something like this, with the viewLayerDefintion property being updated:
{"viewLayerDefinition":{"filter":{"operator":"esriSpatialRelIntersects","value":{"geometryType":"esriGeometryEnvelope","geometry":{"xmin":4485937.7074932605,"ymin":1543545.165101517,"xmax":9417043.276225261,"ymax":6239836.182941515,"spatialReference":{"wkid":102100,"latestWkid":3857}}}}}}
Here you see that the Area of Interest is really just an envelope which intersects the view. So, the trickiest part is probably knowing the geometry to supply.
To accomplish this with the Python API, you use FeatureLayerManager's update_definition: arcgis.features.managers module — arcgis 1.6.0 documentation
Something like this will accomplish the desired result:
from arcgis import GIS
gis = GIS("https://machine.domain.com/portal", "user", "pass")
url = 'https://machine.domain.com/arcgis/rest/services/viewLayer/FeatureServer/0'
fs = arcgis.features.FeatureLayer(url, gis)
update_dict = {"viewLayerDefinition":{"filter":
{"operator":"esriSpatialRelIntersects","value":
{"geometryType":"esriGeometryEnvelope","geometry":
{"xmin":4485937.7074932605,"ymin":1543545.165101517,
"xmax":9417043.276225261,"ymax":6239836.182941515,
"spatialReference":{"wkid":102100,"latestWkid":3857}}}}}}
fs.manager.update_definition(update_dict)
Kind regards,
Earl
Hi Egge-Jan,
Thank you for sharing that blog spot here and I hope it was useful to you!
Essentially, when you set an area of interest the updateDefinition operation is executed on the view layer (https://whatever.domain.com/arcgis/rest/admin/services/worldEQView/FeatureServer/0/updateDefinition)
That request looks something like this, with the viewLayerDefintion property being updated:
{"viewLayerDefinition":{"filter":{"operator":"esriSpatialRelIntersects","value":{"geometryType":"esriGeometryEnvelope","geometry":{"xmin":4485937.7074932605,"ymin":1543545.165101517,"xmax":9417043.276225261,"ymax":6239836.182941515,"spatialReference":{"wkid":102100,"latestWkid":3857}}}}}}
Here you see that the Area of Interest is really just an envelope which intersects the view. So, the trickiest part is probably knowing the geometry to supply.
To accomplish this with the Python API, you use FeatureLayerManager's update_definition: arcgis.features.managers module — arcgis 1.6.0 documentation
Something like this will accomplish the desired result:
from arcgis import GIS
gis = GIS("https://machine.domain.com/portal", "user", "pass")
url = 'https://machine.domain.com/arcgis/rest/services/viewLayer/FeatureServer/0'
fs = arcgis.features.FeatureLayer(url, gis)
update_dict = {"viewLayerDefinition":{"filter":
{"operator":"esriSpatialRelIntersects","value":
{"geometryType":"esriGeometryEnvelope","geometry":
{"xmin":4485937.7074932605,"ymin":1543545.165101517,
"xmax":9417043.276225261,"ymax":6239836.182941515,
"spatialReference":{"wkid":102100,"latestWkid":3857}}}}}}
fs.manager.update_definition(update_dict)
Kind regards,
Earl
Hi Earl,
Thanks for your prompt reply. Very useful 🙂 Now I know I was on the right track, but it was your sample code that really helped me out.
I did extent your example a little bit to apply the Area of Interest to each and every layer in the Hosted Feature Layer View. And yes, it works - see the red rectangle in the screendump below.
Now I can go and test with more complex geometries for the Area of Interest, and with another spatial operator.
(There is already one test result I can share: the Spatial Reference system of my dataset is 28992 (not 102100/3857). And yes it is posssible to define the Area of Interest in another Spatial Reference system. But if you do so, this area will not be visualized on the Visualization tab. So, if this visualization is important to you, you should stick to 102100/3857.)
Thanks again,
Egge-Jan
## ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
## ArcGIS Online Tools
## Script: agol_create_view_area_of_interest.py
## Goal: to create a Hosted Feature Layer View (i.e. a View on a Hosted Feature Layer) with an Area of Interest
## Author: Egge-Jan Polle - Tensing GIS Consultancy
## Date: March 14, 2019
## ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
# This script should be run within a specific ArcGIS/Python environment using the batch file below
# (This batch file comes with the installation of ArcGIS Pro)
# "C:\Program Files\ArcGIS\Pro\bin\Python\scripts\propy.bat" agol_create_view_area_of_interest.py
from arcgis.gis import GIS
from arcgis.features import FeatureLayerCollection
from provide_credentials import provide_credentials
print('===================')
print('The script that is running: ' + __file__)
print('First you have to log in to ArcGIS Online')
# Log in
username, password = provide_credentials()
my_agol = GIS("https://www.arcgis.com", username, password)
print ("Start: "+datetime.datetime.today().strftime('%c'))
service = my_agol.content.get("<serviceItemId_of_your_Hosted_Feature_Layer>")
flc = FeatureLayerCollection.fromitem(service)
xmin = 599538.1
ymin = 6828068
xmax = 599863.4
ymax = 6828394
update_dict = {"viewLayerDefinition":{"filter":
{"operator":"esriSpatialRelIntersects","value":
{"geometryType":"esriGeometryEnvelope","geometry":
{"xmin":xmin,"ymin":ymin,
"xmax":xmax,"ymax":ymax,
"spatialReference":{"wkid":102100,"latestWkid":3857}}}}}}
view_name = service.name + "_view"
print(view_name)
view = flc.manager.create_view(name=view_name, spatial_reference=None, extent=None,
allow_schema_changes=True, updateable=True, capabilities='Query, Update', view_layers=None)
for lyr in view.layers:
lyr.manager.update_definition(update_dict)
print ("End: "+datetime.datetime.today().strftime('%c'))
Hi Egge-Jan,
It was my pleasure to help out and thank you for sharing the end product. Please go ahead and mark this one answered for anyone who might be interested in the workflow.
Kind regards,
Earl
Extending the example above with some other parameters in the update_dict:
update_dict = {"viewLayerDefinition":{"filter":
{"operator":"esriSpatialRelContains","value":
{"geometryType":"esriGeometryPolygon","geometry":
{"rings": [ [ [ 599538.094340413692407, 6828149.832508580759168 ],
[ 599619.427406286238693, 6828068.295202748849988 ],
[ 599782.09063097089529, 6828068.294832927174866 ],
[ 599863.424065723433159, 6828149.831768924370408 ],
[ 599863.42953326983843, 6828394.4517279881984 ],
[ 599538.091433217399754, 6828312.911664362065494 ],
[ 599538.094340413692407, 6828149.832508580759168 ] ] ],
"spatialReference":{"wkid":102100,"latestWkid":3857}}}}}}