esri-leaflet
Version:
Leaflet plugins for consuming ArcGIS Online and ArcGIS Server services.
232 lines (194 loc) • 7.12 kB
JavaScript
import L from 'leaflet';
import { Task } from './Task';
import Util from '../Util';
export var Query = Task.extend({
setters: {
'offset': 'resultOffset',
'limit': 'resultRecordCount',
'fields': 'outFields',
'precision': 'geometryPrecision',
'featureIds': 'objectIds',
'returnGeometry': 'returnGeometry',
'token': 'token'
},
path: 'query',
params: {
returnGeometry: true,
where: '1=1',
outSr: 4326,
outFields: '*'
},
within: function (geometry) {
this._setGeometry(geometry);
this.params.spatialRel = 'esriSpatialRelContains'; // will make code read layer within geometry, to the api this will reads geometry contains layer
return this;
},
intersects: function (geometry) {
this._setGeometry(geometry);
this.params.spatialRel = 'esriSpatialRelIntersects';
return this;
},
contains: function (geometry) {
this._setGeometry(geometry);
this.params.spatialRel = 'esriSpatialRelWithin'; // will make code read layer contains geometry, to the api this will reads geometry within layer
return this;
},
crosses: function (geometry) {
this._setGeometry(geometry);
this.params.spatialRel = 'esriSpatialRelCrosses';
return this;
},
touches: function (geometry) {
this._setGeometry(geometry);
this.params.spatialRel = 'esriSpatialRelTouches';
return this;
},
overlaps: function (geometry) {
this._setGeometry(geometry);
this.params.spatialRel = 'esriSpatialRelOverlaps';
return this;
},
// only valid for Feature Services running on ArcGIS Server 10.3 or ArcGIS Online
nearby: function (latlng, radius) {
latlng = L.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: function (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: function (start, end) {
this.params.time = [start.valueOf(), end.valueOf()];
return this;
},
simplify: function (map, factor) {
var mapWidth = Math.abs(map.getBounds().getWest() - map.getBounds().getEast());
this.params.maxAllowableOffset = (mapWidth / map.getSize().y) * factor;
return this;
},
orderBy: function (fieldName, order) {
order = order || 'ASC';
this.params.orderByFields = (this.params.orderByFields) ? this.params.orderByFields + ',' : '';
this.params.orderByFields += ([fieldName, order]).join(' ');
return this;
},
run: function (callback, context) {
this._cleanParams();
// services hosted on ArcGIS Online also support requesting geojson directly
if (this.options.isModern || Util.isArcgisOnline(this.options.url)) {
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
} else {
return this.request(function (error, response) {
this._trapSQLerrors(error);
callback.call(context, error, (response && Util.responseToFeatureCollection(response)), response);
}, this);
}
},
count: function (callback, context) {
this._cleanParams();
this.params.returnCountOnly = true;
return this.request(function (error, response) {
callback.call(this, error, (response && response.count), response);
}, context);
},
ids: function (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: function (callback, context) {
this._cleanParams();
this.params.returnExtentOnly = true;
return this.request(function (error, response) {
callback.call(context, error, (response && response.extent && Util.extentToBounds(response.extent)), response);
}, context);
},
// only valid for image services
pixelSize: function (point) {
point = L.point(point);
this.params.pixelSize = [point.x, point.y];
return this;
},
// only valid for map services
layer: function (layer) {
this.path = layer + '/query';
return this;
},
_trapSQLerrors: function (error) {
if (error) {
if (error.code === '400') {
Util.warn('one common syntax error in query requests is encasing string values in double quotes instead of single quotes');
}
}
},
_cleanParams: function () {
delete this.params.returnIdsOnly;
delete this.params.returnExtentOnly;
delete this.params.returnCountOnly;
},
_setGeometry: function (geometry) {
this.params.inSr = 4326;
// convert bounds to extent and finish
if (geometry instanceof L.LatLngBounds) {
// set geometry + geometryType
this.params.geometry = Util.boundsToExtent(geometry);
this.params.geometryType = 'esriGeometryEnvelope';
return;
}
// convert L.Marker > L.LatLng
if (geometry.getLatLng) {
geometry = geometry.getLatLng();
}
// convert L.LatLng to a geojson point and continue;
if (geometry instanceof L.LatLng) {
geometry = {
type: 'Point',
coordinates: [geometry.lng, geometry.lat]
};
}
// handle L.GeoJSON, pull out the first geometry
if (geometry instanceof L.GeoJSON) {
// reassign geometry to the GeoJSON value (we are assuming that only one feature is present)
geometry = geometry.getLayers()[0].feature.geometry;
this.params.geometry = Util.geojsonToArcGIS(geometry);
this.params.geometryType = Util.geojsonTypeToArcGIS(geometry.type);
}
// Handle L.Polyline and L.Polygon
if (geometry.toGeoJSON) {
geometry = geometry.toGeoJSON();
}
// handle GeoJSON feature by pulling out the geometry
if (geometry.type === 'Feature') {
// get the geometry of the geojson feature
geometry = geometry.geometry;
}
// confirm that our GeoJSON is a point, line or polygon
if (geometry.type === 'Point' || geometry.type === 'LineString' || geometry.type === 'Polygon' || geometry.type === 'MultiPolygon') {
this.params.geometry = Util.geojsonToArcGIS(geometry);
this.params.geometryType = Util.geojsonTypeToArcGIS(geometry.type);
return;
}
// warn the user if we havn't found an appropriate object
Util.warn('invalid geometry passed to spatial query. Should be L.LatLng, L.LatLngBounds, L.Marker or a GeoJSON Point, Line, Polygon or MultiPolygon object');
return;
}
});
export function query (options) {
return new Query(options);
}
export default query;