Learn how to execute a spatial query to access polygon features from a feature service.
A feature layer can contain a large number of features stored in ArcGIS. To access a subset of these features, you can execute an SQL or spatial query, either together or individually. The results can contain the attributes, geometry, or both for each record. SQL and spatial queries are useful when a feature layer is very large and you want to access only a subset of its data.
In this tutorial, you sketch a feature on the map and use ArcGIS REST JS to perform a spatial query against the LA County Parcels hosted feature layer. The layer contains ±2.4 million features. The spatial query returns all of the parcels that intersect the sketched feature. A pop-up is also used to display feature attributes.
Prerequisites
You need a free ArcGIS developer account to access your dashboard and API keys. The API key must be scoped to access the services used in this tutorial.
<!DOCTYPE html><html><head><metacharset="utf-8"><metaname="viewport"content="initial-scale=1,maximum-scale=1,user-scalable=no" /><title>Esri Leaflet</title><!-- Load Leaflet from CDN --><linkrel="stylesheet"href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css"integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A=="crossorigin=""/><scriptsrc="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"integrity="sha512-XQoYMqMTK8LvdxXYG3nZ448hOEQiglfqkJs1NOQV44cWnUrBc8PkAOcXy20w0vlaXaVUearIOBhiXZ5V3ynxwA=="crossorigin=""></script><!-- Load Esri Leaflet from CDN --><scriptsrc="https://unpkg.com/esri-leaflet@3.0.0/dist/esri-leaflet.js"></script><scriptsrc="https://unpkg.com/esri-leaflet-vector@3.0.0/dist/esri-leaflet-vector.js"></script><scriptsrc="https://unpkg.com/leaflet-editable@1.2.0/src/Leaflet.Editable.js"></script><style>body { margin:0; padding:0; }
#map {
position: absolute;
top:0;
bottom:0;
right:0;
left:0;
font-family: Arial, Helvetica, sans-serif;
font-size: 14px;
color: #323232;
}
</style></head><body><divid="map"></div><script>const apiKey = "YOUR-API-KEY";
const basemapEnum = "ArcGIS:Streets";
const map = L.map('map', {
minZoom: 2,
editable: true }).setView([34.02,-118.805], 13);
L.esri.Vector.vectorBasemapLayer(basemapEnum, {
apiKey: apiKey
}).addTo(map);
// Add the Feature Layer to the mapvar parcels = L.esri.featureLayer({
url: 'https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/LA_County_Parcels/FeatureServer/0',
simplifyFactor: 0.5,
precision: 4,
where: '1 = 0',
style: function(feature){
// https://leafletjs.com/reference-1.7.1.html#path-optionreturn {
opacity: 1.0,
weight: 0.5,
color: 'white',
fillColor: '#19A1E6',
fillOpacity: 0.5 };
}
}).addTo(map);
// Setup the Popup parcels.bindPopup(function(layer){
return L.Util.template('<b>Parcel {APN}</b>' +
'Type: {UseType} <br>' +
'Tax Rate City: {TaxRateCity}', layer.feature.properties);
});
// create a generic control to invoke editing L.EditControl = L.Control.extend({
options: {
position: 'topleft',
callback: null,
kind: '',
html: '' },
// when the control is added to the map, wire up its DOM dynamically and add a click listener onAdd: function(map){
var container = L.DomUtil.create('div', 'leaflet-control leaflet-bar');
var link = L.DomUtil.create('a', '', container);
link.href = '#';
link.title = 'Create a new ' + this.options.kind;
link.innerHTML = this.options.html;
L.DomEvent
.on(link, 'click', L.DomEvent.stop)
.on(link, 'click', function(){
this.options.callback.call(map.editTools);
}, this);
return container;
}
});
// extend the control to draw points L.NewMarkerControl = L.EditControl.extend({
options: {
position: 'topleft',
callback: map.editTools.startMarker,
kind: 'marker',
html: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" style="margin: 3px;"><path d="M6 5.619v11.93l6 6.04 6-6.04V5.619C18 2.283 15.313 1 12 1S6 2.283 6 5.619zM12 2c2.28 0 5 .628 5 3.619v11.518l-5 5.032-5-5.032V5.619C7 2.628 9.72 2 12 2zm0 9a3 3 0 1 0-3-3 3 3 0 0 0 3 3zm0-5a2 2 0 1 1-2 2 2.003 2.003 0 0 1 2-2z"/><path fill="none" d="M0 0h24v24H0z"/></svg>' }
});
// extend the control to draw lines L.NewLineControl = L.EditControl.extend({
options: {
position: 'topleft',
callback: map.editTools.startPolyline,
kind: 'line',
html: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" style="margin: 3px;"><path d="M21 6h.046l-5.25 9h-.944L10 9.455V7H7v2.926L1.862 18H0v3h3v-2.926L8.138 10h1.01L14 15.545V18h3v-3h-.046l5.25-9H24V3h-3zM8 8h1v1H8zM2 20H1v-1h1zm14-3h-1v-1h1zm7-13v1h-1V4z"/><path fill="none" d="M0 0h24v24H0z"/></svg>' }
});
// extend the control to draw polygons L.NewPolygonControl = L.EditControl.extend({
options: {
position: 'topleft',
callback: map.editTools.startPolygon,
kind: 'polygon',
html: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" style="margin: 3px;"><path d="M20 3.456L12 9.28V9H9v.433l-5-3.31V4H1v3h1v13H1v3h3v-1h16v1h3v-3h-1V4h1V1h-3zM10 10h1v1h-1zM2 5h1v1H2zm0 17v-1h1v1zm20 0h-1v-1h1zm-1-2h-1v1H4v-1H3V7h.512L9 10.632V12h3v-1.483L20.952 4H21zm1-18v1h-1V2z"/><path fill="none" d="M0 0h24v24H0z"/></svg>' }
});
// add the two new controls to the map map.addControl(new L.NewMarkerControl());
map.addControl(new L.NewLineControl());
map.addControl(new L.NewPolygonControl());
var previousLayer;
map.on('editable:drawing:end', function(e){
// If this is a subsequent query, delete the previous layerif(previousLayer) {
map.removeLayer(previousLayer);
}
previousLayer = e.layer;
// Turn the shape's edit mode off e.layer.disableEdit();
// Query the geometry, get back the OBJECTIDs of the matching features,// and filter the layer based on the resultant OBJECTIDsvar feature = e.layer.toGeoJSON();
parcels.query().intersects(feature.geometry).ids(function(error, queryResult){
parcels.setWhere('OBJECTID IN (' + queryResult.join(',') + ')');
});
});
</script></body></html>
Run the app
In CodePen, run your code to display the map.
When you click on the map to draw a polygon, a spatial query will run against the feature layer and display all land parcels that intersect the boundary of the feature. You can click on a parcel to see a pop-up with information about the parcel.