Let's say you have a Hosted Feature Layer named worldEQ which contains data on Earthquakes that have occurred throughout the world for the last 50 years:
You wish to create a view named worldEQView from this Hosted Feature Layer. To do that, you could use the following snippet:
from arcgis import GIS
from arcgis.features import FeatureLayerCollection
gis = GIS("https://www.arcgis.com", "username","password")
source_search = gis.content.search("world_earthquakes")[0]
source_flc = FeatureLayerCollection.fromitem(source_search)
new_view = source_flc.manager.create_view(name="worldEQView")
This works out great and your view is created:
Let's suppose you next want to use the view to show only earthquakes that occurred before the year 1988. Reviewing the Data tab of the view's Item Details, you see that you can filter by a column year_:
When you set a View Definition, that definition is defined at the service level. If you quickly set a test definition in the ArcGIS Online/Portal for ArcGIS user interface and take a look at the view service's Service Definition, you'll see the property that needs to be updated is viewDefinitionQuery:
Click on 'View' in the View's Item Details page
Next, click on the Layer:
Click on 'JSON'
Scroll all the way to the bottom to see the 'viewDefinitionQuery' property:
Note: changing the value of viewDefinitionQuery also updates the related definitionQuery property
To update the viewDefinitionQuery property with the ArcGIS API for Python, you do the following:
view_search = gis.content.search("worldEQView")[0]
view_flc = FeatureLayerCollection.fromitem(view_search)
view_layer = view_flc.layers[0]
view_def = {"viewDefinitionQuery" : "year_ < 1988"}
view_layer.manager.update_definition(view_def)
You should be able to see this update reflected after refreshing the view Item Details page > Visualization
Altogether, the script to create a View from the Hosted Feature Layer and then to set a View Definition is:
from arcgis import GIS
from arcgis.features import FeatureLayerCollection
gis = GIS("https://www.arcgis.com", "username","password")
source_search = gis.content.search("world_earthquakes")[0]
source_flc = FeatureLayerCollection.fromitem(source_search)
new_view = source_flc.manager.create_view(name="worldEQView")
view_search = gis.content.search("worldEQView")[0]
view_flc = FeatureLayerCollection.fromitem(view_search)
view_layer = view_flc.layers[0]
view_def = {"viewDefinitionQuery" : "year_ < 1988"}
view_layer.manager.update_definition(view_def)
This can be generalized into a standalone script like this one:
import sys
from arcgis import GIS
from arcgis.features import FeatureLayerCollection
def search_layer(conn,layer_name):
search_results = conn.content.search(layer_name, item_type="Feature Layer")
proper_index = [i for i, s in enumerate(search_results)
if '"' + layer_name + '"' in str(s)]
found_item = search_results[proper_index[0]]
flc = FeatureLayerCollection.fromitem(found_item)
return flc
def create_view(conn, source_flc, view_name, layer_index, view_def):
new_view = source_flc.manager.create_view(name=view_name)
view_flc = search_layer(conn, view_name)
view_layer = view_flc.layers[layer_index]
view_layer.manager.update_definition(view_def)
print("View created")
def main():
conn = GIS("https://www.arcgis.com",
"username", "password")
layer_index = 0
view_def = {"viewDefinitionQuery" : "year_ < 1988"}
source_flc = search_layer(conn, "world_earthquakes")
create_view(conn, source_flc, "worldEQView", layer_index, view_def)
if __name__ == '__main__':
sys.exit(main())
If you need to define an area of interest, this would be approached like so:
view_def = {"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}}}}}}
view_layer.manager.update_definition(update_dict)