Learn how to execute a SQL query to access polygon features in a feature service.
A feature service hosted in ArcGIS can contain a large number of features. To access a subset of the features, you can execute a SQL or spatial query, or both at the same time. Your query can return the attributes, geometry, or both attributes and geometry for each record. SQL and spatial queries are useful when a feature layer is very large and you just want to access a subset of the data.
In this tutorial, you perform server-side SQL queries to return a subset of the features from the LA County Parcels feature service. The feature service contains over 2.4 million features. The resulting features are displayed as a Geo
using CesiumJS.
Prerequisites
You need an ArcGIS Developer or ArcGIS Online account to access the developer dashboard and create an API key.
Steps
Create a new pen
- To get started, either complete the Display a scene tutorial or .
Set the API key
To access location services, you need an API key or OAuth 2.0 access token. To learn how to create and scope your key, visit the Create an API key tutorial.
-
Go to your dashboard to get an API key. The API key must be scoped to access the services used in this tutorial.
-
In CodePen, update
api
to use your key. UpdateKey cesium
to use your Cesium ion access token.Access Token Use dark colors for code blocks const apiKey = "YOUR_API_KEY"; Cesium.ArcGisMapService.defaultAccessToken = apiKey; const cesiumAccessToken = "YOUR_CESIUM_ACCESS_TOKEN"; Cesium.Ion.defaultAccessToken = cesiumAccessToken; const arcGisImagery = Cesium.ArcGisMapServerImageryProvider.fromBasemapType(Cesium.ArcGisBaseMapType.SATELLITE); const viewer = new Cesium.Viewer("cesiumContainer", { baseLayer: Cesium.ImageryLayer.fromProviderAsync(arcGisImagery), });
Add references to ArcGIS REST JS
-
In the
<head>
element, reference thefeature-service
andrequest
packages from ArcGIS REST JS.Use dark colors for code blocks <script src="https://cesium.com/downloads/cesiumjs/releases/1.114/Build/Cesium/Cesium.js"></script> <link href="https://cesium.com/downloads/cesiumjs/releases/1.114/Build/Cesium/Widgets/widgets.css" rel="stylesheet"> <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-feature-service@4.0.0/dist/bundled/feature-service.umd.js"></script>
-
In the
<body>
, create anarcgis
using your API key to authenticate requests to the feature service.Rest.Api K e y Manager Use dark colors for code blocks const apiKey = "YOUR_API_KEY"; Cesium.ArcGisMapService.defaultAccessToken = apiKey; const authentication = arcgisRest.ApiKeyManager.fromKey(apiKey);
Create a query selector
ArcGIS feature layers support a standard SQL query where clause. Use a drop-down <select>
element to provide a list of SQL queries for the LA County Parcels feature layer.
-
Create a
<select>
HTML element that allows the user to select different SQL queries. Construct each SQL query based on the values of attributes in the LA County Parcels layer, such asUse
andType Tax
.Rate Area Use dark colors for code blocks <body> <div id="cesiumContainer"></div> <select id="query-select"> <option value="">Choose a WHERE clause...</option> <option value="UseType = 'Residential'">UseType = 'Residential'</option> <option value="UseType = 'Government'">UseType = 'Government'</option> <option value="UseType = 'Irrigated Farm'">UseType = 'Irrigated Farm'</option> <option value="TaxRateArea = 10853">TaxRateArea = 10853</option> <option value="TaxRateArea = 10860" selected>TaxRateArea = 10860</option> <option value="TaxRateArea = 08637">TaxRateArea = 08637</option> <option value="Roll_LandValue > 1000000">Roll_LandValue > 1000000</option> <option value="Roll_LandValue < 1000000">Roll_LandValue < 1000000</option> </select> <script>
-
Style the
<select>
element so that it displays properly in your application.Use dark colors for code blocks <style> html, body, #cesiumContainer { width:100%; height:100%; padding:0px; margin:0px; } #query-select { position: absolute; top: 8px; left: 8px; padding: 4px 8px; font-size: 16px; border-radius: 0; } </style>
Query the parcel layer
When the user selects a SQL query, use the ArcGIS REST JS query
operation to query the LA County Parcels feature layer.
-
Copy the URL of the LA County Parcels feature layer. Define a new
perform
function that takes a SQL query string as input.Query Use dark colors for code blocks const layerName = "LA_County_Parcels"; const layerURL = "https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/"+layerName+"/FeatureServer/0"; function performQuery(whereClause) { }
-
Query the feature layer using the
query
operation. Pass theFeatures where
paramater as well as yourClause authentication
object. Format results asgeojson
.Use dark colors for code blocks const layerName = "LA_County_Parcels"; const layerURL = "https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/"+layerName+"/FeatureServer/0"; function performQuery(whereClause) { arcgisRest.queryFeatures({ url: layerURL, authentication, f:"geojson", returnGeometry:true, where: whereClause, }) }
-
Add an event listener to your
<select>
HTML element. When the selected value changes, call theperform
function.Query Use dark colors for code blocks const layerName = "LA_County_Parcels"; const layerURL = "https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/"+layerName+"/FeatureServer/0"; function performQuery(whereClause) { arcgisRest.queryFeatures({ url: layerURL, authentication, f:"geojson", returnGeometry:true, where: whereClause, }) } const select = document.getElementById("query-select"); select.addEventListener("change", () => { if (select.value !== "") { const whereClause = select.value; performQuery(whereClause); } });
Set the query extent
The set of features returned by ArcGIS REST JS may not be visible from the current camera position. Add the camera position to the REST request as a geometry
object to only return features that intersect the current viewable extent.
The maximum number of features returned by a query for hosted feature layers is 2000. To return more, you need to check if the request exceeded the maximum feature amount with exceeded
, then use the result
parameter to make multiple requests with the appropriate offset values. To learn more, visit the REST API documentation.
-
Calculate the current viewable extent using the
compute
function. Convert the result from radians to latitude and longitude in degrees.View Rectangle() Use dark colors for code blocks function performQuery(whereClause) { const rect = viewer.camera.computeViewRectangle(); const boundsRadian = [rect.east,rect.south,rect.west,rect.north]; const boundsDegree = []; for (coordinate of boundsRadian) { boundsDegree.push(Cesium.Math.toDegrees(coordinate)); } arcgisRest.queryFeatures({ url: layerURL, authentication, f:"geojson", returnGeometry:true, where: whereClause, }) }
-
Set the
geometry
parameter of your query to the extent, and specify the geometry type asesri
. Perform a spatial intersection to only return features that overlap with the extent.Geometry Envelope Use dark colors for code blocks arcgisRest.queryFeatures({ url: layerURL, authentication, f:"geojson", returnGeometry:true, where: whereClause, geometry: boundsDegree, geometryType: "esriGeometryEnvelope", spatialRel: "esriSpatialRelIntersects", inSR:4326, })
Display results
After you perform a SQL query, add the resulting features to the scene as GeoJSON.
-
Add the service response service to the scene as a
Geo
.Json Data Source Use dark colors for code blocks arcgisRest.queryFeatures({ url: layerURL, authentication, f:"geojson", returnGeometry:true, where: whereClause, geometry: boundsDegree, geometryType: "esriGeometryEnvelope", spatialRel: "esriSpatialRelIntersects", inSR:4326, }) .then((response) => { console.log(response) Cesium.GeoJsonDataSource.load(response,{ outline:true, }).then((data)=>{ viewer.dataSources.add(data); }) })
-
In the event listener, remove all previous query results by calling
data
.Sources.remove All Use dark colors for code blocks const select = document.getElementById("query-select"); select.addEventListener("change", () => { viewer.dataSources.removeAll(); if (select.value !== "") { const whereClause = select.value; performQuery(whereClause); } });
Run the app
In CodePen, run your code to display the map.
When the scene loads, you should be able to use the query selector to display parcels. Click on a parcel to show a pop-up with the feature's attributes.
What's next?
Learn how to use additional ArcGIS location services in these tutorials: