Learn how to find demographic information for places around the world with GeoEnrichment service.
Prerequisites
Steps
Create a new pen
- To get started, either complete the Display a map tutorial or .
Import ArcGIS REST JS
Import the ArcGIS REST JS modules to get access to some ArcGIS location services, like access to demographic data from the GeoEnrichment service.
<!-- require ArcGIS REST JS libraries from https://unpkg.com -->
<script src="https://unpkg.com/@esri/arcgis-rest-request@4.0.0/dist/bundled/request.umd.js"></script>
<script src="https://unpkg.com/@esri/arcgis-rest-demographics@4.0.0/dist/bundled/demographics.umd.js"></script>
<link rel="stylesheet" href="https://js.arcgis.com/4.31/esri/themes/light/main.css" />
<script src="https://js.arcgis.com/4.31/"></script>
Get an access token
You need an access token with the correct privileges to access the location services used in this tutorial.
- Go to the Create an API key tutorial and create an API key with the following privileges:
- Privileges
- Location services > Basemaps
- Location services > Data enrichment
- Location services > Geocoding
- Privileges
- In CodePen, set the
esri
to your API key.Config.api Key - You will also need to use your API key to access ArcGIS REST JS.
Use dark colors for code blocks const authentication = arcgisRest.ApiKeyManager.fromKey("YOUR API KEY"); esriConfig.apiKey = "YOUR API KEY";
Add modules
-
In the
require
statement, add the Graphic, geometryEngine, Search, locator, and reactiveUtils modules.The ArcGIS Maps SDK for JavaScript is available as AMD modules and ES modules, but this tutorial is based on AMD. The AMD
require
function uses references to determine which modules will be loaded – for example, you can specify"esri/layers/
for loading the FeatureLayer module. After the modules are loaded, they are passed as parameters (e.g.Feature Layer" Feature
) to the callback function where they can be used in your application. It is important to keep the module references and callback parameters in the same order. To learn more about the API's different modules visit the Overview Guide page.Layer Use dark colors for code blocks require([ "esri/config", "esri/Map", "esri/views/MapView", "esri/Graphic", "esri/geometry/geometryEngine", "esri/widgets/Search", "esri/rest/locator", "esri/core/reactiveUtils" ], function (esriConfig, Map, MapView, Graphic, geometryEngine, Search, locator, reactiveUtils) {
Update the map
A streets basemap layer is typically used in geocoding applications. Update the basemap
property to use the arcgis/navigation
basemap layer and change the position of the map to center on Milan, Italy.
-
Update the
basemap
property fromarcgis/topographic
toarcgis/navigation
.Use dark colors for code blocks const map = new Map({ basemap: "arcgis/navigation" });
-
Update the
center
property to[9.1900, 45.4642]
, and set thezoom
property to4
.Use dark colors for code blocks const view = new MapView({ map: map, center: [9.19, 45.4642], // Milan, Italy zoom: 4, container: "viewDiv" });
Add the Search widget
Next, we are going to add the Search widget so that the user can search for locations where they want to see the demographics.
-
Create the Search widget and define the view. Then, add the widget to the top right.
Use dark colors for code blocks const search = new Search({ view: view }); view.ui.add(search, "top-right");
-
When the user selects a search result, we want to query for the demographics of that location. To do this, we will listen for the
select-result
event on the Search widget, then call theget
function, which we will define in the Get demographic data section.Demographic Data() Use dark colors for code blocks search.on("select-result", (event) => { if (!event.result) { });
Add click event on the view
We also want to allow the user to search for demographics by clicking anywhere in the map. To do this, we will watch for a click event on the MapView.
- Use the
click
event to watch for when the MapView is clicked.Use dark colors for code blocks view.on("click", (e) => { });
- When the event is returned, use the resulting
map
to set your parameters, then execute thePoint location
method on the locator. This will return the city that we want to find the demographics for.To Address() Use dark colors for code blocks view.on("click", (e) => { const params = { location: e.mapPoint, outFields: "*" }; const locatorUrl = "https://geocode-api.arcgis.com/arcgis/rest/services/World/GeocodeServer"; locator .locationToAddress(locatorUrl, params) });
- Once the
location
method has resolved, we can use the results to get the name of the city closest to the click point. We can use this city and the point that was clicked on the map to call theTo Address() get
method that is defined in the next step.Demographic Data() Use dark colors for code blocks view.on("click", (e) => { const params = { location: e.mapPoint, outFields: "*" }; const locatorUrl = "https://geocode-api.arcgis.com/arcgis/rest/services/World/GeocodeServer"; locator .locationToAddress(locatorUrl, params) .then( function (response) { // Show the address found function (err) { // Show no address found view.graphics.removeAll(); console.log("No address found."); } ); });
Get demographic data
To get the demographic data for an area on the map, we will use the ArcGIS REST JS query
method.
-
Create a function,
get
, to get the demographic data from the ArcGIS REST JS and handle the results. We will add the city and point we want to get the demographics for as the function parameters.Demographic Data() Use dark colors for code blocks function getDemographicData(city, point) { }
-
Query for the demographic data using the
query
method from ArcGIS REST JS. We will set theDemographic Data() study
to the longitude and latitude of our point parameter. We use theAreas authentication
variable we set from our apiKey earlier to authenticate this request.Use dark colors for code blocks function getDemographicData(city, point) { // Request demographic data arcgisRest .queryDemographicData({ studyAreas: [ { geometry: { x: point.longitude, y: point.latitude } } ], authentication: authentication }) }
-
The method above returns a promise with the response. We can handle this promise by using
.then()
to wait until the promise has resolved, then handle the response.Use dark colors for code blocks function getDemographicData(city, point) { // Request demographic data arcgisRest .queryDemographicData({ studyAreas: [ { geometry: { x: point.longitude, if ( response.results[0].value.FeatureSet.length > 0 && response.results[0].value.FeatureSet[0].features.length > 0 ) { const attributes = response.results[0].value.FeatureSet[0].features[0].attributes; showData(city, attributes, point); } else { console.log("No data found."); } }); }
-
Within the
.then()
, we can check that results were returned, and process those results by adding them to an attributes variable. Then, we can call theshow
function to show the results in a popup.Data() Use dark colors for code blocks function getDemographicData(city, point) { // Request demographic data arcgisRest .queryDemographicData({ studyAreas: [ { geometry: { x: point.longitude, y: point.latitude } } ], authentication: authentication if ( response.results[0].value.FeatureSet.length > 0 && response.results[0].value.FeatureSet[0].features.length > 0 ) { const attributes = response.results[0].value.FeatureSet[0].features[0].attributes; showData(city, attributes, point); } else { console.log("No data found."); } }); }
Display data in a Popup
Once we have the results from the demographic query, we want to show those results in a popup to display to the user.
-
Create the
show
function we mentioned in the last step.Data Use dark colors for code blocks color: [0, 0, 0, 0.25], width: 0.5 } } }); view.graphics.removeAll(); view.graphics.add(graphicBuffer); }
-
Define the
title
andcontent
of the Popup. In the title, we will state the name of the city. In the content, we will display the demographics for that city.Use dark colors for code blocks const title = `Global facts near ${city}`; const content = `Population: ${attributes.TOTPOP}<br>Males: ${attributes.TOTMALES} <br>Females: ${attributes.TOTFEMALES}<br>Average Household Size: ${attributes.AVGHHSZ}`; view.openPopup({ location: point, title: title, content: content }); }
-
Open the popup at the given point, with the title and content displayed.
Use dark colors for code blocks function showData(city, attributes, point) { if (!city || !attributes || !point) { return; } const title = `Global facts near ${city}`; const content = `Population: ${attributes.TOTPOP}<br>Males: ${attributes.TOTMALES} <br>Females: ${attributes.TOTFEMALES}<br>Average Household Size: ${attributes.AVGHHSZ}`; view.openPopup({ location: point, title: title, content: content }); }
-
Next, we want to display a buffer around the area we got the demographics for, so the user knows what is included in the query. We will create 1 mile buffer and add it to the view.
Use dark colors for code blocks function showData(city, attributes, point) { if (!city || !attributes || !point) { return; } const title = `Global facts near ${city}`; const content = `Population: ${attributes.TOTPOP}<br>Males: ${attributes.TOTMALES} <br>Females: ${attributes.TOTFEMALES}<br>Average Household Size: ${attributes.AVGHHSZ}`; view.openPopup({ location: point, title: title, content: content }); const buffer = geometryEngine.geodesicBuffer(point, 1, "miles"); const graphicBuffer = new Graphic({ geometry: buffer, symbol: { type: "simple-fill", color: [50, 50, 50, 0.1], outline: { color: [0, 0, 0, 0.25], width: 0.5 } } }); view.graphics.removeAll(); view.graphics.add(graphicBuffer); }
Show the Popup on app load
To give users an idea of how the app works, we can show the popup on initial load of the app. Once the view
loads, we can call get
for the center of the view.
-
Wait for the view to be created by using
view.when
.Use dark colors for code blocks view.when(() => { reactiveUtils.watch(
-
Inside the callback, use
reactive
to watch once theUtils.watch active
property ofSource Search
has changed. Then, we can disable the default popup for Search, set a placeholder within the Search widget, and callget
for the city of Milan, which is located in the center of the view.Demographic Data() Use dark colors for code blocks view.when(() => { reactiveUtils.watch( () => search.activeSource, (loaded) => { if (loaded) { search.popupEnabled = false; search.activeSource.placeholder = "Find facts for cities or places"; } getDemographicData("Milan", view.center); }, { once: true } ); });
Run the App
In CodePen, run your code to display the map.
Click on the map or perform a search to get the demographics for a given city.
What's next?
Learn how to use additional API features and ArcGIS services in these tutorials: