This sample demonstrates how to search and filter the data available in the urban database. The sample covers three different search examples:
- Find the public projects with a start date set to summer 2019.
- Find the global IDs of all public projects created by a user.
- Fetch all publicly available urban models using variables and pagination.
The first two instances work with an urban model of the city of Hardeeville, created specifically for the sample code. The urban
is "8d199b9a69664aac9b2c3a69573600a6"
.
Import relevant libraries and the Urban API schema stored as a Python module. See the Python sgqlc client library section to get instructions on how to export the schema to a Python module.
from sgqlc.operation import Operation
from sgqlc.endpoint.http import HTTPEndpoint
from sgqlc.types import Variable
import sgqlc.types
from urban_api_schema import urban_api_schema as schema
from datetime import date, datetime
Find the public projects with a start date set to summer 2019
Implement a helper function that returns the season of a given date.
Y = 2000 # dummy leap year to allow input X-02-29 (leap day)
seasons = [('winter', (date(Y, 1, 1), date(Y, 3, 20))),
('spring', (date(Y, 3, 21), date(Y, 6, 20))),
('summer', (date(Y, 6, 21), date(Y, 9, 22))),
('autumn', (date(Y, 9, 23), date(Y, 12, 20))),
('winter', (date(Y, 12, 21), date(Y, 12, 31)))]
def get_season(my_time):
if isinstance(my_time, datetime):
my_time = my_time.date()
my_time = my_time.replace(year=Y)
return next(season for season, (start, end) in seasons
if start <= my_time <= end)
Provide the endpoint
and urban
variables.
endpoint_url = 'https://urban-api.arcgis.com/graphql'
endpoint = HTTPEndpoint(endpoint_url)
urban_model_id = "8d199b9a69664aac9b2c3a69573600a6"
Create an Operation
instance of schema.
type, which allows you to generate and interpret GraphQL queries. In the next step, ask for specific fields on selected objects. More specifically, select a few project attributes stored in the urban database of the urban model with the identifier specified in the urban
argument.
Intermediate results can be stored in a variable, such as for projects
and attributes
, and reused later.
# initialize the query
op = Operation(schema.Query)
# set the body of the query
projects = op.urban_model(urban_model_id=urban_model_id).urban_database.projects(
# complex argument types, such as paging are passed as JSON objects
paging={'limit':100}
)
attributes = projects.attributes()
# select relevant return fields
attributes.event_name()
attributes.global_id()
attributes.start_date()
attributes.description()
Call the endpoint to retrieve all projects in the urban model. The return
variable stores the output of the query in JSON format.
return_projects = endpoint(op)
errors = return_projects.get('errors')
if errors:
print(errors)
To parse the returned JSON data into more convenient native objects, add the query operation to the results variable. Loop through the returned projects and find the relevant ones with a start date set to summer 2019.
obj = op + return_projects
# loop through the projects
for project in obj.urban_model.urban_database.projects:
start_date_timestamp = project.attributes.start_date
start_date_dt_object = datetime.fromtimestamp(start_date_timestamp/1000)
# find and return projects with a start date set to summer 2019
if (get_season(start_date_dt_object)=='summer') and (start_date_dt_object.year==2019):
print("Start date: {}, \t Global ID: {}, \t Project name: {}"
.format(start_date_dt_object.strftime('%Y-%m-%d'),
project.attributes.global_id,
project.attributes.event_name)
)
The output should look something like this:
Start date: 2019-07-19, Global ID: ce68ea4c-7ade-464f-ba59-616d0212e958, Project name: DLP Fire Warehouse
Start date: 2019-07-26, Global ID: def80619-f087-4436-b9f9-92fc4bc01b34, Project name: Hearthstone Lakes Phase 3
Start date: 2019-08-01, Global ID: d30bf160-5081-45a6-a915-20a010deb1dd, Project name: Latitude Phase 3B
Start date: 2019-08-28, Global ID: d451e5c6-0a2a-4443-8f24-c9a31e22bc1c, Project name: Ramirez Landscaping
Find the global IDs of all public projects created by a user
Get the global IDs of all the projects created by a given user.
The endpoint
and the urban
variables are the same as in the first example.
Create a new instance of Operation
and select relevant objects and fields.
# initialize the query
op = Operation(schema.Query)
# set the body of the query
urban_database = op.urban_model(urban_model_id=urban_model_id).urban_database()
# add projects to the query
projects = urban_database.projects(paging={'limit':100})
project_attributes = projects.attributes()
# select relevant return fields considering projects
project_attributes.event_name()
project_attributes.global_id()
project_attributes.owner_name()
Call the endpoint to retrieve all projects in the urban model.
projects = endpoint(op)
errors = projects.get('errors')
if errors:
print(errors)
To parse the returned JSON data into more convenient native objects, add the query operation to the results variable. Provide the ArcGIS account username of the user, which you want to use to filter the projects. Loop through the returned projects and find the ones created by the provided user.
obj = op + projects
user_filter = "urban_till_dev"
# go through returned projects
print('Global IDs of projects created by {} \n'.format(user_filter))
for project in obj.urban_model.urban_database.projects:
if project.attributes.owner_name==user_filter:
print(project.attributes.global_id)
The output should look something like this:
Global IDs of projects created by urban_till_dev
48c52224-1dd1-4055-a342-b334695f340f
c3b18289-7012-4ef4-a4dc-2b2e39cb4e3e
def80619-f087-4436-b9f9-92fc4bc01b34
ce68ea4c-7ade-464f-ba59-616d0212e958
d451e5c6-0a2a-4443-8f24-c9a31e22bc1c
Fetch all publicly available urban models using variables and pagination
It is possible that the number of publicly available urban models exceeds the maximum number of objects which can be retrieved in a single API call. If you want to fetch more objects than defined by the maximum limits, you must use pagination. You are going to implement it in this example.
Urban API provides offset-based pagination, in which a client requests a page based on an absolute index in the list (offset) and the maximum number of elements to return (limit).
Create a new instance of Operation
and set two arguments (variables), limit
and offset
. The variables must be named and have a defined type. Next, select relevant objects and return fields for the query operation.
op = Operation(schema.Query, limit=int, offset=int)
# set the body of the query
urban_models = op.urban_models(limit=Variable('limit'), offset=Variable('offset'))
# select relevant return fields
urban_models.title()
urban_models.access()
urban_models.owner()
Create a list to store all relevant models and initialize var
and var
variables.
Set the var
to 100 to fetch the data in batches of 100 objects.
The value of the var
variable is going to change in the while loop until all data is retrieved.
Note, that the code snippet below invoke multiple API calls.
all_models = []
var_limit = 100
var_offset = 0
while True:
json_data = endpoint(op, variables={'limit':var_limit, 'offset': var_offset})
errors = json_data.get('errors')
if errors:
print(errors)
obj = op + json_data
if len(obj.urban_models)==0:
break
else:
for urban_model in obj.urban_models:
all_models.append(urban_model)
var_offset+=100
The urban models are stored in the all
variable. You can get the total number of the retrieved models from the length of the list.
Print all the retrieved urban models.
print('There are {} publicly available urban models.'
.format(len(all_models)))
for model in all_models:
print(model)
The output should look something like this:
There are 345 publicly available urban models.
UrbanModel(title=Sample Urban Project, access=public, owner=EsriTrainingSvc)
UrbanModel(title=River Forest Urban Model, access=public, owner=devlavigne)
UrbanModel(title=Fullerton, access=public, owner=Learn_ArcGIS)
UrbanModel(title=Modelo Curso ArcGIS Urban 2.0, access=public, owner=ricardocuberos_esriven)
UrbanModel(title=Housing Analysis with ArcGIS Urban, access=public, owner=bsims_hlplanning)
...