UNPKG

esri-leaflet

Version:

Leaflet plugins for consuming ArcGIS Online and ArcGIS Server services.

243 lines (211 loc) 7.64 kB
import { point, latLng } from "leaflet"; import { Task } from "./Task.js"; import { warn, responseToFeatureCollection, isArcgisOnline, extentToBounds, _setGeometry, } from "../Util.js"; export const Query = Task.extend({ setters: { offset: "resultOffset", limit: "resultRecordCount", fields: "outFields", precision: "geometryPrecision", featureIds: "objectIds", returnGeometry: "returnGeometry", returnM: "returnM", transform: "datumTransformation", token: "token", }, path: "query", params: { returnGeometry: true, where: "1=1", outSR: 4326, outFields: "*", }, // Returns a feature if its shape is wholly contained within the search geometry. Valid for all shape type combinations. within(geometry) { this._setGeometryParams(geometry); this.params.spatialRel = "esriSpatialRelContains"; // to the REST api this reads geometry **contains** layer return this; }, // Returns a feature if any spatial relationship is found. Applies to all shape type combinations. intersects(geometry) { this._setGeometryParams(geometry); this.params.spatialRel = "esriSpatialRelIntersects"; return this; }, // Returns a feature if its shape wholly contains the search geometry. Valid for all shape type combinations. contains(geometry) { this._setGeometryParams(geometry); this.params.spatialRel = "esriSpatialRelWithin"; // to the REST api this reads geometry **within** layer return this; }, // Returns a feature if the intersection of the interiors of the two shapes is not empty and has a lower dimension than the maximum dimension of the two shapes. Two lines that share an endpoint in common do not cross. Valid for Line/Line, Line/Area, Multi-point/Area, and Multi-point/Line shape type combinations. crosses(geometry) { this._setGeometryParams(geometry); this.params.spatialRel = "esriSpatialRelCrosses"; return this; }, // Returns a feature if the two shapes share a common boundary. However, the intersection of the interiors of the two shapes must be empty. In the Point/Line case, the point may touch an endpoint only of the line. Applies to all combinations except Point/Point. touches(geometry) { this._setGeometryParams(geometry); this.params.spatialRel = "esriSpatialRelTouches"; return this; }, // Returns a feature if the intersection of the two shapes results in an object of the same dimension, but different from both of the shapes. Applies to Area/Area, Line/Line, and Multi-point/Multi-point shape type combinations. overlaps(geometry) { this._setGeometryParams(geometry); this.params.spatialRel = "esriSpatialRelOverlaps"; return this; }, // Returns a feature if the envelope of the two shapes intersects. bboxIntersects(geometry) { this._setGeometryParams(geometry); this.params.spatialRel = "esriSpatialRelEnvelopeIntersects"; return this; }, // if someone can help decipher the ArcObjects explanation and translate to plain speak, we should mention this method in the doc indexIntersects(geometry) { this._setGeometryParams(geometry); this.params.spatialRel = "esriSpatialRelIndexIntersects"; // Returns a feature if the envelope of the query geometry intersects the index entry for the target geometry return this; }, // only valid for Feature Services running on ArcGIS Server 10.3+ or ArcGIS Online nearby(latlng, radius) { latlng = latLng(latlng); this.params.geometry = [latlng.lng, latlng.lat]; this.params.geometryType = "esriGeometryPoint"; this.params.spatialRel = "esriSpatialRelIntersects"; this.params.units = "esriSRUnit_Meter"; this.params.distance = radius; this.params.inSR = 4326; return this; }, where(string) { // instead of converting double-quotes to single quotes, pass as is, and provide a more informative message if a 400 is encountered this.params.where = string; return this; }, between(start, end) { this.params.time = [start.valueOf(), end.valueOf()]; return this; }, simplify(map, factor) { const mapWidth = Math.abs( map.getBounds().getWest() - map.getBounds().getEast(), ); this.params.maxAllowableOffset = (mapWidth / map.getSize().y) * factor; return this; }, orderBy(fieldName, order) { order = order || "ASC"; this.params.orderByFields = this.params.orderByFields ? `${this.params.orderByFields},` : ""; this.params.orderByFields += [fieldName, order].join(" "); return this; }, run(callback, context) { this._cleanParams(); // services hosted on ArcGIS Online and ArcGIS Server 10.3.1+ support requesting geojson directly if ( this.options.isModern || (isArcgisOnline(this.options.url) && this.options.isModern === undefined) ) { this.params.f = "geojson"; return this.request(function (error, response) { this._trapSQLerrors(error); callback.call(context, error, response, response); }, this); // otherwise convert it in the callback then pass it on } return this.request(function (error, response) { this._trapSQLerrors(error); callback.call( context, error, response && responseToFeatureCollection(response), response, ); }, this); }, count(callback, context) { this._cleanParams(); this.params.returnCountOnly = true; return this.request(function (error, response) { callback.call(this, error, response && response.count, response); }, context); }, ids(callback, context) { this._cleanParams(); this.params.returnIdsOnly = true; return this.request(function (error, response) { callback.call(this, error, response && response.objectIds, response); }, context); }, // only valid for Feature Services running on ArcGIS Server 10.3+ or ArcGIS Online bounds(callback, context) { this._cleanParams(); this.params.returnExtentOnly = true; return this.request((error, response) => { if (response && response.extent && extentToBounds(response.extent)) { callback.call( context, error, extentToBounds(response.extent), response, ); } else { error = { message: "Invalid Bounds", }; callback.call(context, error, null, response); } }, context); }, distinct() { // geometry must be omitted for queries requesting distinct values this.params.returnGeometry = false; this.params.returnDistinctValues = true; return this; }, // only valid for image services pixelSize(rawPoint) { const castPoint = point(rawPoint); this.params.pixelSize = [castPoint.x, castPoint.y]; return this; }, // only valid for map services layer(layer) { this.path = `${layer}/query`; return this; }, _trapSQLerrors(error) { if (error) { if (error.code === "400") { warn( "one common syntax error in query requests is encasing string values in double quotes instead of single quotes", ); } } }, _cleanParams() { delete this.params.returnIdsOnly; delete this.params.returnExtentOnly; delete this.params.returnCountOnly; }, _setGeometryParams(geometry) { this.params.inSR = 4326; const converted = _setGeometry(geometry); this.params.geometry = converted.geometry; this.params.geometryType = converted.geometryType; }, }); export function query(options) { return new Query(options); } export default query;