Learn how to execute a spatial query.
A feature layer
In this tutorial, you use GL Draw to sketch a feature
Prerequisites
You need an ArcGIS Location Platform or ArcGIS Online account.
Steps
Get the starter app
Select a type of authentication and follow the steps to create a new app.
Choose API key authentication if you:
- Want the easiest way to get started.
- Want to build public applications
A public application is an application that allows anonymous access without requiring users to sign in with an ArcGIS account. It supports API key or app authentication. that access ArcGIS Location ServicesArcGIS Location Services, also referred to as Location Services, are services hosted by Esri that provide geospatial functionality for developing mapping applications. They include the ArcGIS Basemap Styles service, ArcGIS Static Basemap Tiles service, ArcGIS Places service, ArcGIS Geocoding service, ArcGIS Routing service, ArcGIS GeoEnrichment service, and ArcGIS Elevation service. An ArcGIS Location Platform or ArcGIS Online account is required to use the services. and secure itemsAn item, also known as a content item, is a resource stored in a portal such as a web map, hosted layer, style, script tool, file, or notebook. . - Have an ArcGIS Location Platform or ArcGIS Online account.
Choose user authentication if you:
- Want to build private applications.
- Require application users to sign in with their own ArcGIS account
An ArcGIS account is an identity with a user type and set of privileges that can access specific ArcGIS products, tools, APIs, services, and resources. The main account types that can be used for development are an ArcGIS Location Platform account, ArcGIS Online account, and ArcGIS Enterprise account. ArcGIS Location Platform and ArcGIS Online accounts are also associated with a subscription. and access resources their behalf. - Have an ArcGIS Online account.
To learn more about both types of authentication, go to Authentication.
Set up authentication
Set developer credentials
Use the API key or OAuth developer credentials
Add script references
This tutorial uses three additional libraries. ArcGIS REST JS is used for querying the feature layer. Mapbox GL Draw provides drawing tools, allowing the user to define a point, line, or polygon of interest. Terraformer is used to convert GeoJSON
-
Add
<scripttags to reference the libraries.> Use dark colors for code blocks <head> <title>MapLibre ArcGIS tutorial: Query a feature layer (spatial)</title> <meta charset="utf-8"> <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no"> <!-- Load MapLibre GL JS from CDN --> <script src="https://unpkg.com/maplibre-gl@5.23.0/dist/maplibre-gl.js"></script> <link href="https://unpkg.com/maplibre-gl@5.23.0/dist/maplibre-gl.css" rel="stylesheet"> <!-- Load MapLibre ArcGIS from CDN --> <script src="https://unpkg.com/@esri/maplibre-arcgis@1.1.0/dist/umd/maplibre-arcgis.min.js"></script> <link rel="stylesheet" href="https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-draw/v1.4.2/mapbox-gl-draw.css" > <script src="https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-draw/v1.4.2/mapbox-gl-draw.js"></script> <script src="https://unpkg.com/@esri/arcgis-rest-request@4/dist/bundled/request.umd.js"></script> <script src="https://unpkg.com/@esri/arcgis-rest-feature-service@4/dist/bundled/feature-service.umd.js"></script> <script src="https://unpkg.com/@terraformer/arcgis@2.1.2/dist/t-arcgis.umd.js"></script> <style> html, body, #map { padding: 0; margin: 0; height: 100%; width: 100%; font-family: Arial, Helvetica, sans-serif; font-size: 14px; color: #323232; } </style> </head>
Add Mapbox GL Draw
To display the Mapbox GL Draw controls, create a Mapbox and call map.add. By default, other tools are included, so you need to specify the three required tools: point, line, and polygon.
-
Create a
Mapboxand add it to theDraw Map.Use dark colors for code blocks const map = new maplibregl.Map({ container: "map", // the id of the div element zoom: 12, // starting zoom center: [-118.80543, 34.03] // starting location [longitude, latitude] }); const basemapStyle = maplibreArcGIS.BasemapStyle.applyStyle(map, { style: "arcgis/outdoor", token: accessToken }); const draw = new MapboxDraw({ displayControlsDefault: false, // Don't add any tools other than those below controls: { point: true, line_string: true, polygon: true } }); map.addControl(draw, "top-left"); -
Edit the
Mapboxglobal constants to allow compatibility with MapLibre GL JS.Draw Use dark colors for code blocks const map = new maplibregl.Map({ container: "map", // the id of the div element zoom: 12, // starting zoom center: [-118.80543, 34.03] // starting location [longitude, latitude] }); const basemapStyle = maplibreArcGIS.BasemapStyle.applyStyle(map, { style: "arcgis/outdoor", token: accessToken }); MapboxDraw.constants.classes.CONTROL_BASE = "maplibregl-ctrl"; MapboxDraw.constants.classes.CONTROL_PREFIX = "maplibregl-ctrl-"; MapboxDraw.constants.classes.CONTROL_GROUP = "maplibregl-ctrl-group"; const draw = new MapboxDraw({ displayControlsDefault: false, // Don't add any tools other than those below controls: { point: true, line_string: true, polygon: true } }); map.addControl(draw, "top-left");
Add query layers
Three layersPoint, Line or Polygon geometry. Create the source with an empty GeoJSON feature collection.
A line layer can display both line features and the border of polygon features.
The circle layer should be filtered to only display point features. Otherwise, a circle will be shown at each vertex of line and polygon features. You can use a filter and the ['geometry-type'] expression. See the MapLibre Style Specification for more details.
Similarly, the fill layer should be filtered to only display polygon features. Otherwise, line features will be treated as polygons and filled inappropriately.
-
Create an
addfunction. Inside, add a GeoJSON source and circle, line, and fill layers.Query Layers Use dark colors for code blocks function addQueryLayers() { map.addSource("query", { type: "geojson", data: { type: "FeatureCollection", features: [] } }); map.addLayer({ id: "query-line", type: "line", source: "query", paint: { "line-color": "hsl(140, 0%, 30%)", "line-width": 2, "line-dasharray": [2, 2] } }); map.addLayer({ id: "query-fill", type: "fill", source: "query", paint: { "fill-color": "hsl(140, 0%, 50%)", "fill-opacity": 0.2 }, filter: ["==", ["geometry-type"], "Polygon"] }); map.addLayer({ id: "query-circle", type: "circle", source: "query", paint: { "circle-color": "hsl(140, 0%, 30%)" }, filter: ["==", ["geometry-type"], "Point"] }); }
Add parcel layers
Parcels returned by the query are simple polygons. You can display them with a GeoJSON
-
Create an
addfunction. Inside, add a GeoJSON source and a fill layer.Parcel Layers Use dark colors for code blocks map.addLayer({ id: "query-circle", type: "circle", source: "query", paint: { "circle-color": "hsl(140, 0%, 30%)" }, filter: ["==", ["geometry-type"], "Point"] }); } function addParcelLayers() { map.addSource("parcels", { type: "geojson", data: { type: "FeatureCollection", features: [] }, }); map.addLayer({ id: "parcels-fill", source: "parcels", type: "fill", paint: { "fill-color": "hsl(200, 80%, 50%)", "fill-opacity": 0.5, "fill-outline-color": "white" } }); } -
Add the data attribution
Data attribution is the requirement to display the names of data source providers in all applications when accessing ArcGIS content, layers, or services. for the feature layer source.- Go to the LA County Parcels item
An item, also known as a content item, is a resource stored in a portal such as a web map, hosted layer, style, script tool, file, or notebook. . - Scroll down to the Acknowledgments section and copy its value.
- Paste the copied value to the
attributionproperty.Use dark colors for code blocks function addParcelLayers() { map.addSource("parcels", { type: "geojson", data: { type: "FeatureCollection", features: [] }, // Attribution text retrieved from https://arcgis.com/home/item.html?id=a6fdf2ee0e454393a53ba32b9838b303 attribution: "LA County Parcels" }); map.addLayer({ id: "parcels-fill", source: "parcels", type: "fill", paint: { "fill-color": "hsl(200, 80%, 50%)", "fill-opacity": 0.5, "fill-outline-color": "white" } }); }
- Go to the LA County Parcels item
Add a load handler
To add layers to the map, use the load event to ensure the map is fully loaded.
-
Add an event handler for the
loadevent. Inside, calladdandQuery Layers add;Parcel Layers Use dark colors for code blocks paint: { "fill-color": "hsl(200, 80%, 50%)", "fill-opacity": 0.5, "fill-outline-color": "white" } }); } map.on("load", () => { addParcelLayers(); addQueryLayers(); });
Get the draw feature
Mapbox GL Draw emits a draw.create event when you have finished drawing a feature. You can listen to this event to respond to the newly created feature.
By default, Mapbox GL Draw keeps all previously drawn features visible in its own layerdelete after copying the feature.
-
Add an event handler for
draw.create. Inside, store the feature in thequerylayer, then delete all features from Mapbox GL Draw.Use dark colors for code blocks map.on("load", () => { addParcelLayers(); addQueryLayers(); }); map.on("draw.create", (e) => { const feature = e.features[0]; map.getSource("query").setData(feature); draw.deleteAll(); }); -
Click Run at the top right to test your code. You should be able to sketch a point, line or polygon feature, and see it turn into a green feature when complete.
Execute the query
Use the ArcGIS REST JS query method to find features in the LA County Parcels feature layerwhere clause. Use Terraformer.geojsonToArcGIS to convert the GeoJSON
When the matching parcels are returned, call set on the parcels source
-
Create a function that calls
arcgis. Specify GeoJSONRest.query Features GeoJSON is an open standard for representing geographic information in a JSON file. It is commonly used for sharing data between web services or manipulating vector data in the browser. as the return type, requestingreturnand specificGeometry out. All of the featuresFields A feature is a single record, also known as a row, that represents a real-world entity. It typically contains a geometry (point, multipoint, polyline, or polygon) and attributes but it can also contain just attributes. within the geometryA geometry is a geometric shape, such as a point, polyline, or polygon, that contains one or more coordinates and a spatial reference. will be returned with attributeAttributes are fields and values for a single feature or non-spatial record. They are typically stored in a database or service such as a feature service. information set by theoutproperty.Fields Use dark colors for code blocks map.on("draw.create", (e) => { const feature = e.features[0]; map.getSource("query").setData(feature); draw.deleteAll(); }); function executeQuery(geometry, geometryType) { arcgisRest .queryFeatures({ url: "https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/LA_County_Parcels/FeatureServer/0", geometry: geometry, geometryType: geometryType, spatialRel: "esriSpatialRelIntersects", f: "geojson", returnGeometry: true, outFields: ["APN", "UseType", "TaxRateCity", " Roll_LandValue"] }) } -
Add a response handler. Inside, set the returned parcels as the data for the parcels source.
Use dark colors for code blocks arcgisRest .queryFeatures({ url: "https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/LA_County_Parcels/FeatureServer/0", geometry: geometry, geometryType: geometryType, spatialRel: "esriSpatialRelIntersects", f: "geojson", returnGeometry: true, outFields: ["APN", "UseType", "TaxRateCity", " Roll_LandValue"] }) .then((response) => { map.getSource("parcels").setData(response); }); } -
In your MapboxDraw event handler, call
execute. UseQuery Terraformer.geojsonto convertTo ArcGIS geometryinto an ArcGIS JSON format.Use dark colors for code blocks map.on("draw.create", (e) => { const feature = e.features[0]; map.getSource("query").setData(feature); draw.deleteAll(); const geometry = Terraformer.geojsonToArcGIS(feature.geometry); let geometryType = "esriGeometry" + feature.geometry.type; if (feature.geometry.type === "LineString") { geometryType = "esriGeometryPolyline"; } executeQuery(geometry, geometryType); }); -
At the top right, click Run. When you create a feature using the toolbox, a spatial query will run against the feature layer
A feature layer (client-side) is a data layer that can access and display features from a feature service that has the same type of geometry and attribute fields. and display all land parcels within the boundary of the feature.
Add a pop-up
You can add a pop-up to view attributes of a parcel when you click on it.
-
Add a
clickevent handler to theparcels-filllayer. Inside, construct the pop-up content from the attributes of the clicked parcel.Use dark colors for code blocks .then((response) => { map.getSource("parcels").setData(response); }); } map.on("click", "parcels-fill", (e) => { const p = e.features[0].properties; const message = `<b>Parcel ${p.APN}</b>` + `Type: ${p.UseType} <br>` + `Land value: $${p.Roll_LandValue.toLocaleString()} <br>` + `Tax Rate City: ${p.TaxRateCity}`; }); -
Create a Popup and add it to the map using
Popup.add.To Use dark colors for code blocks map.on("click", "parcels-fill", (e) => { const p = e.features[0].properties; const message = `<b>Parcel ${p.APN}</b>` + `Type: ${p.UseType} <br>` + `Land value: $${p.Roll_LandValue.toLocaleString()} <br>` + `Tax Rate City: ${p.TaxRateCity}`; new maplibregl.Popup().setHTML(message).setLngLat(e.lngLat).addTo(map); });
Run the app
Run the app.
When you click on the map to draw a polygonWhat's next?
Learn how to use additional location services in these tutorials:

Query a feature layer (SQL)
Execute a SQL query to access polygon features from a feature layer.

Get global data
Query demographic information for locations around the world.

Get local data
Query regional facts and spending trends for a study area in the United States.

Add a feature layer as GeoJSON
Display and style GeoJSON features from a feature service.

Style a feature layer
Use data-driven styling to apply symbol colors and styles to feature layers.