There have been a lot of questions coming to me lately about the best way to use the StandardGeographyQuery function in the GeoEnrichment REST API if a developer wants to help their end users find features in lower levels of geography. This is done by stringing together a few StandardGeographyQuery requests based on the input that the user provides. The example that I will walk through here is trying to find a random census tract in the state of California. This workflow is similar to the workflow used by Esri developed in applications like the Business Analyst Web Application.
The first thing that we need is to confirm the proper name when querying the levels of geography. A list is provided in response to the “StandardGeographyLevels” request for the US:
This request will return a list that contains the IDs of all levels, as well as branches. While it is possible to query against a single level of geography, census tracts for example, the GeoEnrichment service data contains information which defines a hierarchy in order to help guide application developers and end users to the results they want. This hierarchy is defined in the “branches” section of the response and will be discussed later in this post. Notice that the “levels” section of the response contains a field “isWholeCountry”. Each country will have one record returned which represents the entire country and it will have “‘isWholeCountry’ : true,”. The whole country level will be the first level into which we need to drill in order to get to our final result. In this case, US.WholeUSA is the ID of the level where this attribute is true. To find the most direct path to query census tracts, I need to know the ID for the census tracts level.
If I search for “census tracts” in my browser, I find the following entry:
{ "id" : "US.Tracts", "name" : "Census Tracts", "isWholeCountry" : false, "adminLevel" : "", "singularName" : "Census Tract", "pluralName" : "Census Tracts" },
From this record, I take the ID, which is “US.Tracts” and perform a search for this value in my browser window. This will help me to find if there are any branches that lead me to the census tract level. My search returns:
{ "id" : "USbySTbyCYbyTR", "name" : "US by Tracts", "levels" : [ "US.States", "US.Counties", "US.Tracts" ] }
This lets me know that census tract features each intersect only one feature in the counties level and that counties each intersect only one feature in the States level. The states, being the highest level listed in this branch, are all contained inside of the entire country.
An example of using the branches to drill into the levels of geography to analyze a single feature can be demonstrated with the Business Analyst Web Application using the option of selecting a geography from the full list in the “Define Areas for Reports” > “Select Geography” menu. I’ve provided some screen shots of the Business Analyst Web Application to show this in action. First, I need to navigate through a menu of options where I will ultimately wind up with the option to pick from a list of geography levels. Step 1, I choose to “Define Areas for Reports” and choose “Select Geography”:
Next, I choose to “Select from Full List”:
Being that it is a “full list”, it will need to start with the list of geography levels, then drill into our desired level to get the list of features in that level. When the click for “Select from Full List” is selected, the “StandardGeographyLevels” request, which is described above, is sent. The Business Analyst Web Application then associates each of the levels with an image and the result is here:
Since, I am looking to pick from random census tracts, I click on the “Census Tracts”. The Business Analyst Web Application uses the response from the StandardGeographyLevels request to query the branches which lead me to the “US.Tracts” level. The only entry leading to the census tracts level is listed above. This results in one possible branch and is displayed in the application as a menu to “Select the State > County > Census Tracts”:
When I click on the menu’s drop down a request is executed which will list all states that fall within the entire country. Here is an example of the request:
California is listed in the drop down menu as an option for me to choose. The record for California from the response to the request above is here:
{ "attributes" : { "DatasetID" : "USA_ESRI_2017", "DataLayerID" : "US.States", "AreaID" : "06", "AreaName" : "California", "MajorSubdivisionName" : "California", "MajorSubdivisionAbbr" : "CA", "MajorSubdivisionType" : "State", "CountryAbbr" : "US", "Score" : 100, "ObjectId" : 5 } }
The next request that I send to the server will use some information from this record, like the DataLayerID and AreaID along with the DataLayerID of the counties level from the StandardGeographyLevels request, to ask for a list of all counties in the State of California:
Since there is another level of geography between the US.States level and the census tracts on this branch, this results in another drop-down in the menu where I can choose which county I want to search in:
The drop-down menu is populated with the names of each county in the State of California. I have decided that I am interested in a random area in San Bernardino County, so I search the list for “San Bernardino County”. If looking at the response to my request, I find the following record for San Bernardino County:
{ "attributes" : { "DatasetID" : "USA_ESRI_2017", "DataLayerID" : "US.Counties", "AreaID" : "06071", "AreaName" : "San Bernardino County", "MajorSubdivisionName" : "California", "MajorSubdivisionAbbr" : "CA", "MajorSubdivisionType" : "State", "CountryAbbr" : "US", "Score" : 100, "ObjectId" : 36 } }
From this record, I use the “AreaID” and “DataLayerID” with the help of the “DataLayerID” for Census Tracts from the “StandardGeographyLevels” request in the beginning, I am able to build a request which asks for all of the census tracts in San Bernardino County:
I do not have a specific Census Tract in mind here, so picking a record at random, I am able to use the information in a record to create my enrich and createReport requests to get the demographic information of a random census tract in San Bernardino County, California:
Since I have “returnGeometry=true”, the polygon geometry will be returned along with the variables of the “Health” data collection. This way, I can draw the Census Tract in my application and place it over my map as an area of interest.
To recap, I can get a list of geography levels using the “StandardGeographyLevels” discovery method. From this list, I see possible branches in my data hierarchy and the proper ID for levels of geography in my country of interest. Then, I request a list of all of the features in one of the geography levels in a branch which will lead me to census tracts eventually, like “US.States”. From the list of States, I can pick my state of interest and request a list of all of the features in the next subgeography level specified in that same branch, which is “US.Counties”. I can dig one level further in this branch and get a list of all of the “US.Tracts” contained in a county of my choice. Using the information from the results of my latest query, I can run enrich or create report to obtain demographic statistics for the area.
Article Discussion: