EMedina-esristaff

Using the ArcGIS API for Python to create a view from a Hosted Feature Layer and to define a view definition

Blog Post created by EMedina-esristaff Employee on Feb 11, 2019

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:

 

earthquakes

 

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")

# Search for Source Hosted Feature Layer
source_search = gis.content.search("world_earthquakes")[0]
source_flc = FeatureLayerCollection.fromitem(source_search)

# Create View from Source Hosted Feature Layer
new_view = source_flc.manager.create_view(name="worldEQView")

 

This works out great and your view is created:

viewresult

 

 

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_:

tbl

 

 

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

 

servurl

 

Next, click on the Layer:

 

layerrest

 

Click on 'JSON'

 

 

jsonrest

 

 

Scroll all the way to the bottom to see the 'viewDefinitionQuery' property:

defrest
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:

# Search for newly created View
view_search = gis.content.search("worldEQView")[0]
view_flc = FeatureLayerCollection.fromitem(view_search)

# The viewDefinitionQuery property appears under layers
view_layer = view_flc.layers[0]

# Define a SQL query to filter out events past 1988
view_def = {"viewDefinitionQuery" : "year_ < 1988"}

# Update the definition to include the view definition query
view_layer.manager.update_definition(view_def)

 

You should be able to see this update reflected after refreshing the view Item Details page > Visualization

 

def

 

 

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")

# Search for Source Hosted Feature Layer
source_search = gis.content.search("world_earthquakes")[0]
source_flc = FeatureLayerCollection.fromitem(source_search)

# Create View from Source Hosted Feature Layer
new_view = source_flc.manager.create_view(name="worldEQView")

# Search for newly created View
view_search = gis.content.search("worldEQView")[0]
view_flc = FeatureLayerCollection.fromitem(view_search)

# The viewDefinitionQuery property appears under layers
view_layer = view_flc.layers[0]

# Define a SQL query to filter out events past 1988
view_def = {"viewDefinitionQuery" : "year_ < 1988"}

# Update the definition to include the view definition query
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)
    # Search for newly created View
    view_flc = search_layer(conn, view_name)
    # The viewDefinitionQuery property appears under layers
    view_layer = view_flc.layers[layer_index]
    # Update the definition to include the view definition query
    view_layer.manager.update_definition(view_def)
    print("View created")

def main():
    conn = GIS("https://www.arcgis.com",
               "username", "password")
    # Index of the Layer to be filtered
    layer_index = 0
    # Define a SQL query to filter out events past 1988
    view_def = {"viewDefinitionQuery" : "year_ < 1988"}
    # Search for target Hosted Feature Layer
    source_flc = search_layer(conn, "world_earthquakes")
    # Create View from Hosted Feature Layer
    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)

Outcomes