/home/desid573/phewl.desidrivers.com.au/v3-utility-library-master/arcgislink/src
NameSizeModeActions
arcgislink.js1451320644editdlrm
arcgislink_code.js1450530644editdlrm
arcgislink_compiled.js350380644editdlrm
arcgislink_externs.js35410644editdlrm
Edit: /home/desid573/phewl.desidrivers.com.au/v3-utility-library-master/arcgislink/src/arcgislink.js (145132B)
(function(){ /* * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ /** * @preserve http://google-maps-utility-library-v3.googlecode.com */ /** * @name ArcGIS Server Link for Google Maps JavaScript API V3 * @version 1.0 * @author: Nianwei Liu (nianwei at gmail dot com) * @fileoverview *

Examples *

*

This library lets you add map resources accessible via * * ESRI ArcGIS Server™ REST API into * Google Maps API V3 and provide some additional support for map tiles created * with different spatial reference and tiling scheme.

*

. * * * * * * *
* {@link TileLayer}
* {@link TileLayerOptions}
* {@link MapType}
* {@link MapTypeOptions}
* {@link MapOverlay}
* {@link MapOverlayOptions}
* {@link Projection}
*
* {@link Catalog}
* {@link MapService}
* {@link Layer}
* {@link GeocodeService}
* {@link GeometryService}
* {@link GPService}
* {@link GPTask}
* {@link RouteTask}
*
* {@link SpatialReference}
* {@link Geographic}
* {@link LambertConformalConic}
* {@link TransverseMercator}
* {@link SphereMercator}
* {@link Albers}
* {@link SpatialRelationship}
*
* {@link Util}
* {@link Config}
* {@link Error}
*
*

There are many objects used in the REST API that do not require * a constructor and can be * used just as object literal in the operation:

* * * * * *
* {@link Field}
* {@link TileInfo}
* {@link LOD}
* {@link ExportMapOptions}
* {@link MapImage}
* {@link IdentifyOptions}
* {@link IdentifyResults}
* {@link IdentifyResult}
*
* {@link QueryOptions}
* {@link ResultSet}
* {@link FindOptions}
* {@link FindResults}
* {@link FindResult}
* {@link Feature}
*
* {@link GeocodeOptions}
* {@link GeocodeResults}
* {@link GeocodeResult}
* {@link ReverseGeocodeOptions}
* {@link ReverseGeocodeResult}
* {@link BufferOptions}
* {@link BufferResults}
* {@link ProjectOptions}
* {@link ProjectResults}
*
* {@link RouteOptions}
* {@link RouteResults}
*
*/ /*jslint evil: true, sub: true */ /*global escape ActiveXObject */ var gmaps = gmaps || {}; /** @const */ var RAD_DEG = Math.PI / 180; var jsonpID_ = 0; window['ags_jsonp'] = window['ags_jsonp'] || {}; var G = google.maps; var WGS84, NAD83, WEB_MERCATOR, WEB_MERCATOR_AUX; /** * @name Config * @class This is an object literal that sets common configuration values used across the lib. * @property {String} [proxyUrl] The URL to the web proxy page used in case the length of the URL request to an ArcGIS Server REST resource exceeds 2000 characters. * @property {Boolean} [alwaysUseProxy] whether to always use proxy page when send request to server. */ var Config = { proxyUrl:null, alwaysUseProxy: false }; /** * an internal collection of Spatial Refeneces supported in the application. * The key of the collection is the wkid/wkt, and value is an instance of * {@link SpatialReference}. */ var spatialReferences_ = {}; /** * A set of utilities ((Util) * for commonly used functions. * @name Util * @namespace */ var Util = {}; /** * Extract the substring from full string, between start string and end string * @param {String} full * @param {String} start * @param {String} end */ function extractString_(full, start, end) { var i = (start === '') ? 0 : full.indexOf(start); var e = end === '' ? full.length : full.indexOf(end, i + start.length); return full.substring(i + start.length, e); } /** * Check if the object is String * @param {Object} o */ function isString_(o) { return o && typeof o === 'string'; } /** * Check if the object is array * @param {Object} o */ function isArray_(o) { return o && o.splice; } function isNumber_(o) { return typeof o === 'number'; } /** * Add the property of the source object to destination object * if not already exists. * @param {Object} dest * @param {Object} src * @param {Boolean} force * @return {Object} */ function augmentObject_(src, dest, force) { if (src && dest) { var p; for (p in src) { if (force || !(p in dest)) { dest[p] = src[p]; } } } return dest; } /** * Wrapper around google.maps.event.trigger * @param {Object} src * @param {String} evtName * @param {Object} args */ function triggerEvent_(src, evtName, args) { G.event.trigger.apply(this, arguments); } /** * handle JSON error * @param {Object} errback * @param {Object} json */ function handleErr_(errback, json) { if (errback && json && json.error) { errback(json.error); } } /** * get REST format for 2 time * @param {Date} time * @param {Date} endTime */ function formatTimeString_(time, endTime) { var ret = ''; if (time) { ret += (time.getTime() - time.getTimezoneOffset() * 60000); } if (endTime) { ret += ', ' + (endTime.getTime() - endTime.getTimezoneOffset() * 60000); } return ret; } /** * Set opacity of a node. * @param {Node} node * @param {Number} 0-1 */ function setNodeOpacity_(node, op) { // closure compiler removed? op = Math.min(Math.max(op, 0), 1); if (node) { var st = node.style; if (typeof st.opacity !== 'undefined') { st.opacity = op; } if (typeof st.filters !== 'undefined') { st.filters.alpha.opacity = Math.floor(100 * op); } if (typeof st.filter !== 'undefined') { st.filter = "alpha(opacity:" + Math.floor(op * 100) + ")"; } } } /** * get the layerdef text string from an object literal * @param {Object} defs */ function getLayerDefsString_(defs) { var strDefs = ''; for (var x in defs) { if (defs.hasOwnProperty(x)) { if (strDefs.length > 0) { strDefs += ';'; } strDefs += (x + ':' + defs[x]); } } return strDefs; } function getXmlHttp_() { if (typeof XMLHttpRequest === "undefined") { try { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); } catch (e) { } try { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); } catch (e1) { } try { return new ActiveXObject("Msxml2.XMLHTTP"); } catch (e2) { } throw new Error("This browser does not support XMLHttpRequest."); } else { return new XMLHttpRequest(); } } /** * @name GeometryType * @enum {String} * @const * @class List of Geometry type supported by ArcGIS server. * @property {String} [POINT] esriGeometryPoint * @property {String} [MULTIPOINT] esriGeometryMultipoint * @property {String} [POLYLINE] esriGeometryPolyline * @property {String} [POLYGON] esriGeometryPolygon * @property {String} [ENVELOPE] esriGeometryEnvelope */ var GeometryType = { POINT: 'esriGeometryPoint', MULTIPOINT: 'esriGeometryMultipoint', POLYLINE: 'esriGeometryPolyline', POLYGON: 'esriGeometryPolygon', ENVELOPE: 'esriGeometryEnvelope' }; function getGeometryType_(obj) { var o = obj; if (isArray_(obj) && obj.length > 0) { o = obj[0]; } if (o instanceof G.LatLng || o instanceof G.Marker) { if (isArray_(obj) && obj.length > 1) { return GeometryType.MULTIPOINT; } else { return GeometryType.POINT; } } else if (o instanceof G.Polyline) { return GeometryType.POLYLINE; } else if (o instanceof G.Polygon) { return GeometryType.POLYGON; } else if (o instanceof G.LatLngBounds) { return GeometryType.ENVELOPE; } else if (o.x !== undefined && o.y !== undefined) { return GeometryType.POINT; } else if (o.points) { return GeometryType.MULTIPOINT; } else if (o.paths) { return GeometryType.POLYLINE; } else if (o.rings) { return GeometryType.POLYGON; } return null; } /** * Is the object an Google Overlay? * @param {Object} obj * @return {Boolean} */ function isOverlay_(obj) { var o = obj; if (isArray_(obj) && obj.length > 0) { o = obj[0]; } if (isArray_(o) && o.length > 0) { o = o[0]; } if (o instanceof G.LatLng || o instanceof G.Marker || o instanceof G.Polyline || o instanceof G.Polygon || o instanceof G.LatLngBounds) { return true; } return false; } function formatSRParam_(sr) { if (!sr) { return null; } // for 9.3 compatibility, return wkid if possible. return isNumber_(sr) ? sr : sr.wkid ? sr.wkid : sr.toJSON(); } /** * @param {MVCArrayOfLatLng} pts */ function fromLatLngsToJSON_(pts, close) { var arr = []; var latlng; for (var i = 0, c = pts.getLength(); i < c; i++) { latlng = pts.getAt(i); arr.push('[' + latlng.lng() + ',' + latlng.lat() + ']'); } if (close && arr.length > 0) { arr.push('[' + pts.getAt(0).lng() + ',' + pts.getAt(0).lat() + ']'); } return arr.join(','); } /** * Convert overlays (Marker, Polyline, Polygons) to JSON string in AGS format. * @param {OverlayView|Array.OverlayView} geom */ function fromOverlaysToJSON_(geom) { var gtype = getGeometryType_(geom); var g, gs, i, pts; var json = '{'; switch (gtype) { case GeometryType.POINT: g = isArray_(geom) ? geom[0] : geom; if (g instanceof G.Marker) { g = g.getPosition(); } json += 'x:' + g.lng() + ',y:' + g.lat(); break; case GeometryType.MULTIPOINT: pts = []; for (i = 0; i < geom.length; i++) { if (geom[i] instanceof G.Marker) { g = geom[i].getPosition(); } else { g = geom[i]; } pts.push('[' + g.lng() + ',' + g.lat() + ']'); } json += 'points: [' + pts.join(',') + ']'; break; case GeometryType.POLYLINE: // V3 does not support multiple paths yet pts = []; gs = isArray_(geom) ? geom : [geom]; for (i = 0; i < gs.length; i++) { pts.push('[' + fromLatLngsToJSON_(gs[i].getPath()) + ']'); } json += 'paths:[' + pts.join(',') + ']'; break; case GeometryType.POLYGON: pts = []; g = isArray_(geom) ? geom[0] : geom; var paths = g.getPaths(); for (i = 0; i < paths.getLength(); i++) { pts.push('[' + fromLatLngsToJSON_(paths.getAt(i), true) + ']'); } json += 'rings:[' + pts.join(',') + ']'; break; case GeometryType.ENVELOPE: g = isArray_(geom) ? geom[0] : geom; json += 'xmin:' + g.getSouthWest().lng() + ',ymin:' + g.getSouthWest().lat() + ',xmax:' + g.getNorthEast().lng() + ',ymax:' + g.getNorthEast().lat(); break; } json += ', spatialReference:{wkid:4326}'; json += '}'; return json; } /** * From ESRI geometry format to JSON String, primarily used in Geometry service * @param {Object} geom */ function fromGeometryToJSON_(geom) { function fromPointsToJSON(pts) { var arr = []; for (var i = 0, c = pts.length; i < c; i++) { arr.push('[' + pts[i][0] + ',' + pts[i][1] + ']'); } return '[' + arr.join(',') + ']'; } function fromLinesToJSON(lines) { var arr = []; for (var i = 0, c = lines.length; i < c; i++) { arr.push(fromPointsToJSON(lines[i])); } return '[' + arr.join(',') + ']'; } var json = '{'; if (geom.x) { json += 'x:' + geom.x + ',y:' + geom.y; } else if (geom.xmin) { json += 'xmin:' + geom.xmin + ',ymin:' + geom.ymin + ',xmax:' + geom.xmax + ',ymax:' + geom.ymax; } else if (geom.points) { json += 'points:' + fromPointsToJSON(geom.points); } else if (geom.paths) { json += 'paths:' + fromLinesToJSON(geom.paths); } else if (geom.rings) { json += 'rings:' + fromLinesToJSON(geom.rings); } json += '}'; return json; } /** * Helper method to convert an Envelope object to google.maps.LatLngBounds * @private * @param {Object} extent * @return {google.maps.LatLngBounds} gLatLngBounds */ function fromEnvelopeToLatLngBounds_(extent) { var sr = spatialReferences_[extent.spatialReference.wkid || extent.spatialReference.wkt]; sr = sr || WGS84; var sw = sr.inverse([extent.xmin, extent.ymin]); var ne = sr.inverse([extent.xmax, extent.ymax]); return new G.LatLngBounds(new G.LatLng(sw[1], sw[0]), new G.LatLng(ne[1], ne[0])); } /** * Convert a ArcGIS Geometry JSON object to core Google Maps API * overlays such as google.maps.Marker, google.maps.Polyline or google.maps.Polygon * Note ArcGIS Geometry may have multiple parts, but the coresponding OverlayView * may (Polygon) or may not (Polyline) support multi-parts, so the result is an array for consistency. * @param {Object} json geometry * @param {OverlayOptions} opts see {@link OverlayOptions} * @return {Array.OverlayView} */ function fromJSONToOverlays_(geom, opts) { var ovs = null; var ov; var i, ic, j, jc, parts, part, lnglat, latlngs; opts = opts || {}; if (geom) { ovs = []; if (geom.x) { ov = new G.Marker(augmentObject_(opts.markerOptions || opts, { 'position': new G.LatLng(geom.y, geom.x) })); ovs.push(ov); } else { //mulpt, line and poly parts = geom.points || geom.paths || geom.rings; if (!parts) { return ovs; } var rings = []; for (i = 0, ic = parts.length; i < ic; i++) { part = parts[i]; if (geom.points) { // multipoint ov = new G.Marker(augmentObject_(opts.markerOptions || opts, { 'position': new G.LatLng(part[1], part[0]) })); ovs.push(ov); } else { latlngs = []; for (j = 0, jc = part.length; j < jc; j++) { lnglat = part[j]; latlngs.push(new G.LatLng(lnglat[1], lnglat[0])); } if (geom.paths) { ov = new G.Polyline(augmentObject_(opts.polylineOptions || opts, { 'path': latlngs })); ovs.push(ov); } else if (geom.rings) { // V3 supports multiple rings rings.push(latlngs); } } } if (geom.rings) { ov = new G.Polygon(augmentObject_(opts.polygonOptions || opts, { 'paths': rings })); ovs.push(ov); } } } return ovs; } function parseFeatures_(features, ovOpts) { if (features) { var i, I, f; for (i = 0, I = features.length; i < I; i++) { f = features[i]; if (f.geometry) { f.geometry = fromJSONToOverlays_(f.geometry, ovOpts); } } } } /** * get string as rest parameter * @param {Object} o */ function formatRequestString_(o) { var ret; if (typeof o === 'object') { if (isArray_(o)) { ret = []; for (var i = 0, I = o.length; i < I; i++) { ret.push(formatRequestString_(o[i])); } return '[' + ret.join(',') + ']'; } else if (isOverlay_(o)) { return fromOverlaysToJSON_(o); } else if (o.toJSON) { return o.toJSON(); } else { ret = ''; for (var x in o) { if (o.hasOwnProperty(x)) { if (ret.length > 0) { ret += ', '; } ret += x + ':' + formatRequestString_(o[x]); } } return '{' + ret + '}'; } } return o.toString(); } function fromLatLngsToFeatureSet_(latlngs) { var i, I, latlng; var features = []; for (i = 0, I = latlngs.length; i < I; i++) { latlng = latlngs[i]; if (latlng instanceof G.Marker) { latlng = latlng.getPosition(); } features.push({ 'geometry': { 'x': latlng.lng(), 'y': latlng.lat(), 'spatialReference': { 'wkid': 4326 } } }); } return { 'type': '"features"', 'features': features, 'doNotLocateOnRestrictedElements': false }; } function prepareGeometryParams_(p) { var params = {}; if (!p) { return null; } var json = []; var g, isOv; if (p.geometries && p.geometries.length > 0) { g = p.geometries[0]; isOv = isOverlay_(g); for (var i = 0, c = p.geometries.length; i < c; i++) { if (isOv) { json.push(fromOverlaysToJSON_(p.geometries[i])); } else { json.push(fromGeometryToJSON_(p.geometries[i])); } } } if (!p.geometryType) { p.geometryType = getGeometryType_(g); } if (isOv) { params.inSR = WGS84.wkid; } else if (p.inSpatialReference) { params.inSR = formatSRParam_(p.inSpatialReference); } if (p.outSpatialReference) { params.outSR = formatSRParam_(p.outSpatialReference); } params.geometries = '{geometryType:"' + p.geometryType + '", geometries:[' + json.join(',') + ']}'; return params; } function log_(msg) { if (window.console) { window.console.log(msg); } else { var l = document.getElementById('_ags_log'); if (l) { l.innerHTML = l.innerHTML + msg + '
'; } } } /** * Format params to URL string * @param {Object} params */ function formatParams_(params) { var query = ''; if (params) { params.f = params.f || 'json'; for (var x in params) { if (params.hasOwnProperty(x) && params[x] !== null && params[x] !== undefined) { // wont sent undefined. //jslint complaint about escape cause NN does not support it. var val = formatRequestString_(params[x]); query += (query.length > 0?'&':'')+(x + '=' + (escape ? escape(val) : encodeURIComponent(val))); } } } return query; } /** create a callback closure * @private * @param {Object} fn * @param {Object} obj */ function callback_(fn, obj) { var args = []; for (var i = 2, c = arguments.length; i < c; i++) { args.push(arguments[i]); } return function() { fn.apply(obj, args); }; } function addCopyrightInfo_(cpArray, mapService, map) { if (mapService.hasLoaded()) { cpArray.push(mapService.copyrightText); } else { G.event.addListenerOnce(mapService, 'load', function() { setCopyrightInfo_(map); }); } } /** * Find copyright control in the map * @param {Object} map */ function setCopyrightInfo_(map) { var div = null; if (map) { var mvc = map.controls[G.ControlPosition.BOTTOM_RIGHT]; if (mvc) { for (var i = 0, c = mvc.getLength(); i < c; i++) { if (mvc.getAt(i).id === 'agsCopyrights') { div = mvc.getAt(i); break; } } } //var callback = callback_(setCopyrightInfo_, null, map); if (!div) { div = document.createElement('div'); div.style.fontFamily = 'Arial,sans-serif'; div.style.fontSize = '10px'; div.style.textAlign = 'right'; div.id = 'agsCopyrights'; map.controls[G.ControlPosition.BOTTOM_RIGHT].push(div); G.event.addListener(map, 'maptypeid_changed', function() { setCopyrightInfo_(map); }); } var ovs = map.agsOverlays; var cp = []; var svc, type; if (ovs) { for (var i = 0, c = ovs.getLength(); i < c; i++) { addCopyrightInfo_(cp, ovs.getAt(i).mapService_, map); } } var ovTypes = map.overlayMapTypes; if (ovTypes) { for (var i = 0, c = ovTypes.getLength(); i < c; i++) { type = ovTypes.getAt(i); if (type instanceof MapType) { for (var j = 0, cj = type.tileLayers_.length; j < cj; j++) { addCopyrightInfo_(cp, type.tileLayers_[j].mapService_, map); } } } } type = map.mapTypes.get(map.getMapTypeId()); if (type instanceof MapType) { for (var i = 0, c = type.tileLayers_.length; i < c; i++) { addCopyrightInfo_(cp, type.tileLayers_[i].mapService_, map); } if (type.negative) { div.style.color = '#ffffff'; } else { div.style.color = '#000000'; } } div.innerHTML = cp.join('
'); } } function getJSON_(url, params, callbackName, callbackFn) { var sid = 'ags_jsonp_' + (jsonpID_++) + '_' + Math.floor(Math.random() * 1000000); var script = null; params = params || {}; // AGS10.1 escapes && so had to take it off. params[callbackName || 'callback'] = 'ags_jsonp.' + sid; var query = formatParams_(params); var head = document.getElementsByTagName("head")[0]; if (!head) { throw new Error("document must have header tag"); } var jsonpcallback = function() { if (window['ags_jsonp'][sid]) { delete window['ags_jsonp'][sid]; //['ags_jsonp'] } if (script) { head.removeChild(script); } script = null; callbackFn.apply(null, arguments); /** * This event is fired after a REST JSONP response was returned by server. * @name Util#jsonpend * @param {String} scriptID * @event */ triggerEvent_(Util, 'jsonpend', sid); }; window['ags_jsonp'][sid] = jsonpcallback; if ((query + url).length < 2000 && !Config.alwaysUseProxy) { script = document.createElement("script"); script.src = url + (url.indexOf('?') === -1 ? '?' : '&') + query; script.id = sid; head.appendChild(script); } else { // check if same host var loc = window.location; var dom = loc.protocol + '//' + loc.hostname + (!loc.port || loc.port === 80 ? '' : ':' + loc.port + '/'); var useProxy = true; if (url.toLowerCase().indexOf(dom.toLowerCase()) !== -1) { useProxy = false; } if (Config.alwaysUseProxy) { useProxy = true; } if (useProxy && !Config.proxyUrl) { throw new Error('No proxyUrl property in Config is defined'); } var xmlhttp = getXmlHttp_(); xmlhttp.onreadystatechange = function() { if (xmlhttp.readyState === 4) { if (xmlhttp.status === 200) { eval(xmlhttp.responseText); } else { throw new Error("Error code " + xmlhttp.status); } } }; xmlhttp.open('POST', useProxy ? Config.proxyUrl + '?' + url : url, true); xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); xmlhttp.send(query); } /** * This event is fired before a REST request sent to server. * @name Util#jsonpstart * @param {String} scriptID * @event */ triggerEvent_(Util, 'jsonpstart', sid); return sid; } /** * Make Cross Domain Calls. This function returns the * script ID which can be used to track the requests. parameters: * * @param {String} url * @param {Object} params * @param {String} callbackName * @param {Function} callbackFn * @return {String} scriptID */ Util.getJSON = function(url, params, callbackName, callbackFn) { getJSON_(url, params, callbackName, callbackFn); }; /** * Add a list of overlays to map * @param {google.maps.Map} map * @param {Array.OverlayView} overlays */ Util.addToMap = function(map, overlays) { if (isArray_(overlays)) { var ov; for (var i = 0, I = overlays.length; i < I; i++) { ov = overlays[i]; if (isArray_(ov)) { Util.addToMap(map, ov); } else if (isOverlay_(ov)) { ov.setMap(map); } } } }; /** * Add a list of overlays to map * @param {Array.OverlayView} overlays * @param {Boolean} clearArray */ Util.removeFromMap = function(overlays, clearArray) { Util.addToMap(null, overlays); if (clearArray) { overlays.length = 0; } }; /** * Create A Generic Spatial Reference Object * The params passed in constructor is a javascript object literal and depends on * the type of Coordinate System to construct. * @name SpatialReference * @class This class (SpatialReference) is for coordinate systems that converts value * between geographic and real-world coordinates. The following classes extend this class: * {@link Geographic}, {@link SphereMercator}, {@link LambertConformalConic}, and {@link TransverseMercator}. * @constructor * @property {Number} [wkid] well-known coodinate system id (EPSG code) * @property {String} [wkt] well-known coodinate system text * @param {Object} params */ function SpatialReference(params) { params = params || {}; this.wkid = params.wkid; this.wkt = params.wkt; } /** * Convert Lat Lng to real-world coordinates. * Note both input and output are array of [x,y], although their values in different units. * @param {Array.number} lnglat * @return {Array.number} */ SpatialReference.prototype.forward = function(lnglat) { return lnglat; }; /** * Convert real-world coordinates to Lat Lng. * Note both input and output are are array of [x,y], although their values are different. * @param {Array.number} coords * @return {Array.number} */ SpatialReference.prototype.inverse = function(coords) { return coords; }; /** * Get the map the periodicity in x-direction, in map units NOT pixels * @return {number} periodicity in x-direction */ SpatialReference.prototype.getCircum = function() { return 360; }; /** * To JSON String * @return String */ SpatialReference.prototype.toJSON = function() { return '{' + (this.wkid ? ' wkid:' + this.wkid : 'wkt: \'' + this.wkt + '\'') + '}'; }; /** * Creates a Geographic Coordinate System. e.g.:
* var g2 = new Geographic({wkid:4326}); * * @name Geographic * @class This class (Geographic) will simply retuns same LatLng as Coordinates. * The param should have wkid property. Any Geographic Coordinate Systems (eg. WGS84(4326)) can * use this class As-Is. *
Note: This class does not support datum transformation. * @constructor * @extends SpatialReference * @param {Object} params */ function Geographic (params) { params = params || {}; SpatialReference.call(this, params); } Geographic.prototype = new SpatialReference(); /** * Create a Lambert Conformal Conic Projection based Spatial Reference. The params passed in construction should * include the following properties: *
-wkid: well-known id *
-semi_major: ellipsoidal semi-major axis in meter *
-unit: meters per unit *
-inverse_flattening: inverse of flattening of the ellipsoid where 1/f = a/(a - b) *
-standard_parallel_1: phi1, latitude of the first standard parallel *
-standard_parallel_2: phi2, latitude of the second standard parallel *
-latitude_of_origin: phi0, latitude of the false origin *
-central_meridian: lamda0, longitude of the false origin (with respect to the prime meridian) *
-false_easting: FE, false easting, the Eastings value assigned to the natural origin *
-false_northing: FN, false northing, the Northings value assigned to the natural origin *
*
e.g. North Carolina State Plane NAD83 Feet:
* var ncsp82 = new LambertConformalConic({wkid:2264, semi_major: 6378137.0,inverse_flattening: 298.257222101, * standard_parallel_1: 34.33333333333334, standard_parallel_2: 36.16666666666666, * central_meridian: -79.0, latitude_of_origin: 33.75,false_easting: 2000000.002616666, * 'false_northing': 0, unit: 0.3048006096012192 }); * @name LambertConformalConic * @class This class (LambertConformalConic) represents a Spatial Reference System based on Lambert Conformal Conic Projection. * @extends SpatialReference * @constructor * @param {Object} params */ function LambertConformalConic(params) { //http://pubs.er.usgs.gov/djvu/PP/PP_1395.pdf //for NCSP83: GLatLng(35.102363,-80.5666)< === > GPoint(1531463.95, 495879.744); params = params || {}; SpatialReference.call(this, params); var f_i = params.inverse_flattening; var phi1 = params.standard_parallel_1 * RAD_DEG; var phi2 = params.standard_parallel_2 * RAD_DEG; var phi0 = params.latitude_of_origin * RAD_DEG; this.a_ = params.semi_major / params.unit; this.lamda0_ = params.central_meridian * RAD_DEG; this.FE_ = params.false_easting; this.FN_ = params.false_northing; var f = 1.0 / f_i; //e: eccentricity of the ellipsoid where e^2 = 2f - f^2 var es = 2 * f - f * f; this.e_ = Math.sqrt(es); var m1 = this.calc_m_(phi1, es); var m2 = this.calc_m_(phi2, es); var tF = this.calc_t_(phi0, this.e_); var t1 = this.calc_t_(phi1, this.e_); var t2 = this.calc_t_(phi2, this.e_); this.n_ = Math.log(m1 / m2) / Math.log(t1 / t2); this.F_ = m1 / (this.n_ * Math.pow(t1, this.n_)); this.rho0_ = this.calc_rho_(this.a_, this.F_, tF, this.n_); } LambertConformalConic.prototype = new SpatialReference(); /** * calc_m_ * @param {number} phi * @param {number} es e square */ LambertConformalConic.prototype.calc_m_ = function(phi, es) { var sinphi = Math.sin(phi); return Math.cos(phi) / Math.sqrt(1 - es * sinphi * sinphi); }; /** * calc_t_ * @param {Object} phi * @param {Object} e */ LambertConformalConic.prototype.calc_t_ = function(phi, e) { var esp = e * Math.sin(phi); return Math.tan(Math.PI / 4 - phi / 2) / Math.pow((1 - esp) / (1 + esp), e / 2); }; /** * calc_rho (15-7)_ * @param {Object} a * @param {Object} F * @param {Object} t * @param {Object} n */ LambertConformalConic.prototype.calc_rho_ = function(a, F, t, n) { return a * F * Math.pow(t, n); }; /** * calc_phi_ * @param {Object} t_i * @param {Object} e * @param {Object} phi */ LambertConformalConic.prototype.calc_phi_ = function(t, e, phi) { var esp = e * Math.sin(phi); return Math.PI / 2 - 2 * Math.atan(t * Math.pow((1 - esp) / (1 + esp), e / 2)); }; /** * solve phi iteratively. * @param {Object} t_i * @param {Object} e * @param {Object} init */ LambertConformalConic.prototype.solve_phi_ = function(t_i, e, init) { // iteration var i = 0; var phi = init; var newphi = this.calc_phi_(t_i, e, phi);//this. while (Math.abs(newphi - phi) > 0.000000001 && i < 10) { i++; phi = newphi; newphi = this.calc_phi_(t_i, e, phi);//this. } return newphi; }; /** * see {@link SpatialReference} * @param {Array.number} lnglat * @return {Array.number} */ LambertConformalConic.prototype.forward = function(lnglat) { var phi = lnglat[1] * RAD_DEG;// (Math.PI / 180); var lamda = lnglat[0] * RAD_DEG; var t = this.calc_t_(phi, this.e_); var rho = this.calc_rho_(this.a_, this.F_, t, this.n_); var theta = this.n_ * (lamda - this.lamda0_); var E = this.FE_ + rho * Math.sin(theta); var N = this.FN_ + this.rho0_ - rho * Math.cos(theta); return [E, N]; }; /** * see {@link SpatialReference} * @param {Array.number} coords * @return {Array.number} */ LambertConformalConic.prototype.inverse = function(coords) { var E = coords[0] - this.FE_; var N = coords[1] - this.FN_; var theta = Math.atan(E / (this.rho0_ - N)); var rho = (this.n_ > 0 ? 1 : -1) * Math.sqrt(E * E + (this.rho0_ - N) * (this.rho0_ - N)); var t = Math.pow((rho / (this.a_ * this.F_)), 1 / this.n_); var init = Math.PI / 2 - 2 * Math.atan(t); var phi = this.solve_phi_(t, this.e_, init); var lamda = theta / this.n_ + this.lamda0_; return [lamda / RAD_DEG, phi / RAD_DEG]; }; /** * see {@link SpatialReference} * @return {number} */ LambertConformalConic.prototype.getCircum = function() { return Math.PI * 2 * this.a_; }; /** * Create a Transverse Mercator Projection. The params passed in constructor should contain the * following properties:
* *
-wkid: well-known id *
-semi_major: ellipsoidal semi-major axis in meters *
-unit: meters per unit *
-inverse_flattening: inverse of flattening of the ellipsoid where 1/f = a/(a - b) *
-Scale Factor: scale factor at origin *
-latitude_of_origin: phi0, latitude of the false origin *
-central_meridian: lamda0, longitude of the false origin (with respect to the prime meridian) *
-false_easting: FE, false easting, the Eastings value assigned to the natural origin *
-false_northing: FN, false northing, the Northings value assigned to the natural origin *
*
e.g. Georgia West State Plane NAD83 Feet: *
var gawsp83 = new TransverseMercator({wkid: 102667, semi_major:6378137.0, * inverse_flattening:298.257222101,central_meridian:-84.16666666666667, latitude_of_origin: 30.0, * scale_factor:0.9999, false_easting:2296583.333333333, false_northing:0, unit: 0.3048006096012192}); * * @param {Object} params * @name TransverseMercator * @constructor * @class This class (TransverseMercator) represents a Spatial Reference System based on * Transverse Mercator Projection * @extends SpatialReference */ function TransverseMercator(params) { params = params || {}; SpatialReference.call(this, params); //GLatLng(33.74561,-84.454308)< === > GPoint(2209149.07977075, 1362617.71496891); this.a_ = params.semi_major / params.unit;//this. var f_i = params.inverse_flattening; this.k0_ = params.scale_factor; var phi0 = params.latitude_of_origin * RAD_DEG;//(Math.PI / 180); this.lamda0_ = params.central_meridian * RAD_DEG; this.FE_ = params.false_easting;//this. this.FN_ = params.false_northing;//this. var f = 1.0 / f_i;//this. /*e: eccentricity of the ellipsoid where e^2 = 2f - f^2 */ this.es_ = 2 * f - f * f; //var _e = Math.sqrt(this.es_); /* e^4 */ this.ep4_ = this.es_ * this.es_; /* e^6 */ this.ep6_ = this.ep4_ * this.es_; /* e' second eccentricity where e'^2 = e^2 / (1-e^2) */ this.eas_ = this.es_ / (1 - this.es_); this.M0_ = this.calc_m_(phi0, this.a_, this.es_, this.ep4_, this.ep6_); } TransverseMercator.prototype = new SpatialReference(); /** * calc_m_ * @param {Object} phi * @param {Object} a * @param {Object} es * @param {Object} ep4 * @param {Object} ep6 */ TransverseMercator.prototype.calc_m_ = function(phi, a, es, ep4, ep6) { return a * ((1 - es / 4 - 3 * ep4 / 64 - 5 * ep6 / 256) * phi - (3 * es / 8 + 3 * ep4 / 32 + 45 * ep6 / 1024) * Math.sin(2 * phi) + (15 * ep4 / 256 + 45 * ep6 / 1024) * Math.sin(4 * phi) - (35 * ep6 / 3072) * Math.sin(6 * phi)); }; /** * see {@link SpatialReference} * @param {Array.number} lnglat * @return {Array.number} */ TransverseMercator.prototype.forward = function(lnglat) { var phi = lnglat[1] * RAD_DEG;// (Math.PI / 180); var lamda = lnglat[0] * RAD_DEG;//(Math.PI / 180); var nu = this.a_ / Math.sqrt(1 - this.es_ * Math.pow(Math.sin(phi), 2)); var T = Math.pow(Math.tan(phi), 2); var C = this.eas_ * Math.pow(Math.cos(phi), 2); var A = (lamda - this.lamda0_) * Math.cos(phi); var M = this.calc_m_(phi, this.a_, this.es_, this.ep4_, this.ep6_); var E = this.FE_ + this.k0_ * nu * (A + (1 - T + C) * Math.pow(A, 3) / 6 + (5 - 18 * T + T * T + 72 * C - 58 * this.eas_) * Math.pow(A, 5) / 120); var N = this.FN_ + this.k0_ * (M - this.M0_) + nu * Math.tan(phi) * (A * A / 2 + (5 - T + 9 * C + 4 * C * C) * Math.pow(A, 4) / 120 + (61 - 58 * T + T * T + 600 * C - 330 * this.eas_) * Math.pow(A, 6) / 720); return [E, N]; }; /** * see {@link SpatialReference} * @param {Array.number} coords * @return {Array.number} */ TransverseMercator.prototype.inverse = function(coords) { var E = coords[0]; var N = coords[1]; var e1 = (1 - Math.sqrt(1 - this.es_)) / (1 + Math.sqrt(1 - this.es_)); var M1 = this.M0_ + (N - this.FN_) / this.k0_; var mu1 = M1 / (this.a_ * (1 - this.es_ / 4 - 3 * this.ep4_ / 64 - 5 * this.ep6_ / 256)); var phi1 = mu1 + (3 * e1 / 2 - 27 * Math.pow(e1, 3) / 32) * Math.sin(2 * mu1) + (21 * e1 * e1 / 16 - 55 * Math.pow(e1, 4) / 32) * Math.sin(4 * mu1) + (151 * Math.pow(e1, 3) / 6) * Math.sin(6 * mu1) + (1097 * Math.pow(e1, 4) / 512) * Math.sin(8 * mu1); var C1 = this.eas_ * Math.pow(Math.cos(phi1), 2); var T1 = Math.pow(Math.tan(phi1), 2); var N1 = this.a_ / Math.sqrt(1 - this.es_ * Math.pow(Math.sin(phi1), 2)); var R1 = this.a_ * (1 - this.es_) / Math.pow((1 - this.es_ * Math.pow(Math.sin(phi1), 2)), 3 / 2); var D = (E - this.FE_) / (N1 * this.k0_); var phi = phi1 - (N1 * Math.tan(phi1) / R1) * (D * D / 2 - (5 + 3 * T1 + 10 * C1 - 4 * C1 * C1 - 9 * this.eas_) * Math.pow(D, 4) / 24 + (61 + 90 * T1 + 28 * C1 + 45 * T1 * T1 - 252 * this.eas_ - 3 * C1 * C1) * Math.pow(D, 6) / 720); var lamda = this.lamda0_ + (D - (1 + 2 * T1 + C1) * Math.pow(D, 3) / 6 + (5 - 2 * C1 + 28 * T1 - 3 * C1 * C1 + 8 * this.eas_ + 24 * T1 * T1) * Math.pow(D, 5) / 120) / Math.cos(phi1); return [lamda / RAD_DEG, phi / RAD_DEG]; }; /** * see {@link SpatialReference} * @return number */ TransverseMercator.prototype.getCircum = function() { return Math.PI * 2 * this.a_; }; /** * Creates a Spatial Reference based on Sphere Mercator Projection. * The params passed in constructor should have the following properties: *
-wkid: wkid *
-semi_major: ellipsoidal semi-major axis *
-unit: meters per unit *
-central_meridian: lamda0, longitude of the false origin (with respect to the prime meridian) *
*
e.g. The "Web Mercator" used in ArcGIS Server:
* var web_mercator = new SphereMercator({wkid: 102113, semi_major:6378137.0, central_meridian:0, unit: 1 }); * * @name SphereMercator * @class This class (SphereMercator) is the Projection Default Google Maps uses. It is a special form of Mercator. * @constructor * @param {Object} params * @extends SpatialReference */ function SphereMercator(params) { /* =========== parameters = ===================== */ params = params || {}; SpatialReference.call(this, params); this.a_ = (params.semi_major || 6378137.0) / (params.unit || 1); this.lamda0_ = (params.central_meridian || 0.0) * RAD_DEG; } SphereMercator.prototype = new SpatialReference(); /** * See {@link SpatialReference} * @param {Array.number} lnglat * @return {Array.number} */ SphereMercator.prototype.forward = function(lnglat) { var phi = lnglat[1] * RAD_DEG; var lamda = lnglat[0] * RAD_DEG; var E = this.a_ * (lamda - this.lamda0_); var N = (this.a_ / 2) * Math.log((1 + Math.sin(phi)) / (1 - Math.sin(phi))); return [E, N]; }; /** * See {@link SpatialReference} * @param {Array.number} coords * @return {Array.number} */ SphereMercator.prototype.inverse = function(coords) { var E = coords[0]; var N = coords[1]; var phi = Math.PI / 2 - 2 * Math.atan(Math.exp(-N / this.a_)); var lamda = E / this.a_ + this.lamda0_; return [lamda / RAD_DEG, phi / RAD_DEG]; }; /** * See {@link SpatialReference} * @return {Number} */ SphereMercator.prototype.getCircum = function () { return Math.PI * 2 * this.a_; }; /** * Create a Albers Equal-Area Conic Projection based Spatial Reference. The params passed in construction should * include the following properties: *
-wkid: well-known id *
-semi_major: ellipsoidal semi-major axis in meter *
-unit: meters per unit *
-inverse_flattening: inverse of flattening of the ellipsoid where 1/f = a/(a - b) *
-standard_parallel_1: phi1, latitude of the first standard parallel *
-standard_parallel_2: phi2, latitude of the second standard parallel *
-latitude_of_origin: phi0, latitude of the false origin *
-central_meridian: lamda0, longitude of the false origin (with respect to the prime meridian) *
-false_easting: FE, false easting, the Eastings value assigned to the natural origin *
-false_northing: FN, false northing, the Northings value assigned to the natural origin *
*
e.g. * var albers = new Albers({wkid:9999, semi_major: 6378206.4,inverse_flattening: 294.9786982, * standard_parallel_1: 29.5, standard_parallel_2: 45.5, * central_meridian: -96.0, latitude_of_origin: 23,false_easting: 0, * 'false_northing': 0, unit: 1 }); * @name Albers * @class This class (Albers) represents a Spatial Reference System based on Albers Projection. * @extends SpatialReference * @constructor * @param {Object} params */ function Albers(params) { //http://pubs.er.usgs.gov/djvu/PP/PP_1395.pdf, page 101 & 292 //for NAD_1983_Alaska_Albers: LatLng()< === > Point(); params = params || {}; SpatialReference.call(this, params); var f_i = params.inverse_flattening; var phi1 = params.standard_parallel_1 * RAD_DEG; var phi2 = params.standard_parallel_2 * RAD_DEG; var phi0 = params.latitude_of_origin * RAD_DEG; this.a_ = params.semi_major / params.unit; this.lamda0_ = params.central_meridian * RAD_DEG; this.FE_ = params.false_easting; this.FN_ = params.false_northing; var f = 1.0 / f_i; //e: eccentricity of the ellipsoid where e^2 = 2f - f^2 var es = 2 * f - f * f; this.e_ = Math.sqrt(es); var m1 = this.calc_m_(phi1, es); var m2 = this.calc_m_(phi2, es); var q1 = this.calc_q_(phi1, this.e_); var q2 = this.calc_q_(phi2, this.e_); var q0 = this.calc_q_(phi0, this.e_); this.n_ = (m1 * m1 - m2 * m2) / (q2 - q1); this.C_ = m1 * m1 + this.n_ * q1; this.rho0_ = this.calc_rho_(this.a_, this.C_, this.n_, q0); }; Albers.prototype = new SpatialReference(); /** * calc_m_ * @param {number} phi * @param {number} es e square */ Albers.prototype.calc_m_ = function(phi, es) { var sinphi = Math.sin(phi); return Math.cos(phi) / Math.sqrt(1 - es * sinphi * sinphi); }; /** * formular (3-12) page 101 * @param {Object} phi * @param {Object} e */ Albers.prototype.calc_q_ = function(phi, e) { var esp = e * Math.sin(phi); return (1 - e * e) * (Math.sin(phi) / (1 - esp * esp) - (1 / (2 * e)) * Math.log((1 - esp) / (1 + esp))); }; Albers.prototype.calc_rho_ = function(a, C, n, q) { return a * Math.sqrt(C - n * q) / n; }; Albers.prototype.calc_phi_ = function(q, e, phi) { var esp = e * Math.sin(phi); return phi + (1 - esp * esp) * (1 - esp * esp) / (2 * Math.cos(phi)) * (q / (1 - e * e) - Math.sin(phi) / (1 - esp * esp) + Math.log((1 - esp) / (1 + esp)) / (2 * e)); }; Albers.prototype.solve_phi_ = function(q, e, init) { // iteration var i = 0; var phi = init; var newphi = this.calc_phi_(q, e, phi); while (Math.abs(newphi - phi) > 0.00000001 && i < 10) { i++; phi = newphi; newphi = this.calc_phi_(q, e, phi); } return newphi; }; /** * see {@link SpatialReference} * @param {Array.number} lnglat * @return {Array.number} */ Albers.prototype.forward = function(lnglat) { var phi = lnglat[1] * RAD_DEG; var lamda = lnglat[0] * RAD_DEG; var q = this.calc_q_(phi, this.e_); var rho = this.calc_rho_(this.a_, this.C_, this.n_, q); var theta = this.n_ * (lamda - this.lamda0_); var E = this.FE_ + rho * Math.sin(theta); var N = this.FN_ + this.rho0_ - rho * Math.cos(theta); return [E, N]; }; /** * see {@link SpatialReference} * @param {Array.number} coords * @return {Array.number} */ Albers.prototype.inverse = function(coords) { var E = coords[0] - this.FE_; var N = coords[1] - this.FN_; var rho = Math.sqrt(E * E + (this.rho0_ - N) * (this.rho0_ - N)); var adj = this.n_ > 0 ? 1 : -1; var theta = Math.atan(adj * E / (adj * this.rho0_ - adj * N)); var q = (this.C_ - rho * rho * this.n_ * this.n_ / (this.a_ * this.a_)) / this.n_; var init = Math.asin(q / 2); var phi = this.solve_phi_(q, this.e_, init); var lamda = theta / this.n_ + this.lamda0_; return [lamda / RAD_DEG, phi / RAD_DEG]; }; /** * see {@link SpatialReference} * @return number */ Albers.prototype.getCircum = function() { return Math.PI * 2 * this.a_; }; /** * See {@link SpatialReference} * @return {number} */ Albers.prototype.getCircum = function() { return Math.PI * 2 * this.a_; }; WGS84 = new Geographic({ wkid: 4326 }); NAD83 = new Geographic({ wkid: 4269 }); WEB_MERCATOR = new SphereMercator({ wkid: 102113, semi_major: 6378137.0, central_meridian: 0, unit: 1 }); WEB_MERCATOR_AUX = new SphereMercator({ wkid: 102100, semi_major: 6378137.0, central_meridian: 0, unit: 1 }); // declared early but assign here to avoid dependency error by jslint spatialReferences_ = { '4326': WGS84, '4269': NAD83, '102113': WEB_MERCATOR, '102100': WEB_MERCATOR_AUX }; SpatialReference.WGS84 = WGS84; SpatialReference.NAD83 = NAD83; //TODO: check advanced compile impact SpatialReference.WEB_MERCATOR = WEB_MERCATOR; SpatialReference.WEB_MERCATOR_AUX = WEB_MERCATOR_AUX; /** * static method. Call with Syntax SpatialReference.register(..). * Add A Spatial Reference to the internal collection of Spatial References. * the wktOrSR parameter can be String format of "well-known text" of the * Spatial Reference, or an instance of {@link SpatialReference}. *
  • If passes in String WKT format, to be consistent, it should use the same format as listed * in * ESRI documentation. For example, add NC State Plane NAD83 as String: *
    * SpatialReference.register(2264,'PROJCS["NAD_1983_StatePlane_North_Carolina_FIPS_3200_Feet", * GEOGCS["GCS_North_American_1983", * DATUM["D_North_American_1983", * SPHEROID["GRS_1980",6378137.0,298.257222101]], * PRIMEM["Greenwich",0.0], * UNIT["Degree",0.0174532925199433]], * PROJECTION["Lambert_Conformal_Conic"], * PARAMETER["False_Easting",2000000.002616666], * PARAMETER["False_Northing",0.0], * PARAMETER["Central_Meridian",-79.0], * PARAMETER["Standard_Parallel_1",34.33333333333334], * PARAMETER["Standard_Parallel_2",36.16666666666666], * PARAMETER["Latitude_Of_Origin",33.75], * UNIT["Foot_US",0.3048006096012192]]'); *
    * Note: only Lambert Conformal Conic and Transverse Mercator Projection * based Spatial References are supported if added via WKT String. *
  • If passes in an instance of {@link SpatialReference}, it can be one of the * built in classes, or a class that extends SpatialReference. For example, add NC State Plane NAD83 as SR: *
    * SpatialReferences.register(2264: new LambertConformalConic({ * wkid: 2264, * semi_major: 6378137.0, * inverse_flattening: 298.257222101, * standard_parallel_1: 34.33333333333334, * standard_parallel_2: 36.16666666666666, * central_meridian: -79.0, * latitude_of_origin: 33.75, * 'false_easting': 2000000.002616666, * 'false_northing': 0, * unit: 0.3048006096012192 * }); *
    * @static * @param {Number|String} wkid/wkt * @param {Object} wktOrSR * @return {SpatialReference} registered SR */ Util.registerSR = function(wkidt, wktOrSR) { var sr = spatialReferences_['' + wkidt]; if (sr) { return sr; } if (wktOrSR instanceof SpatialReference) { spatialReferences_['' + wkidt] = wktOrSR; sr = wktOrSR; } else { var wkt = wktOrSR || wkidt; // only one param is passed in. var params = { 'wkt': wkidt }; if (wkidt === parseInt(wkidt, 10)) { params = { 'wkid': wkidt }; } var prj = extractString_(wkt, "PROJECTION[\"", "\"]"); var spheroid = extractString_(wkt, "SPHEROID[", "]").split(","); if (prj !== "") { params.unit = parseFloat(extractString_(extractString_(wkt, "PROJECTION", ""), "UNIT[", "]").split(",")[1]); params.semi_major = parseFloat(spheroid[1]); params.inverse_flattening = parseFloat(spheroid[2]); params.latitude_of_origin = parseFloat(extractString_(wkt, "\"Latitude_Of_Origin\",", "]")); params.central_meridian = parseFloat(extractString_(wkt, "\"Central_Meridian\",", "]")); params.false_easting = parseFloat(extractString_(wkt, "\"False_Easting\",", "]")); params.false_northing = parseFloat(extractString_(wkt, "\"False_Northing\",", "]")); } switch (prj) { case "": sr = new SpatialReference(params); break; case "Lambert_Conformal_Conic": params.standard_parallel_1 = parseFloat(extractString_(wkt, "\"Standard_Parallel_1\",", "]")); params.standard_parallel_2 = parseFloat(extractString_(wkt, "\"Standard_Parallel_2\",", "]")); sr = new LambertConformalConic(params); break; case "Transverse_Mercator": params.scale_factor = parseFloat(extractString_(wkt, "\"Scale_Factor\",", "]")); sr = new TransverseMercator(params); break; case "Albers": params.standard_parallel_1 = parseFloat(extractString_(wkt, "\"Standard_Parallel_1\",", "]")); params.standard_parallel_2 = parseFloat(extractString_(wkt, "\"Standard_Parallel_2\",", "]")); sr = new Albers(params); break; // more implementations here. default: throw new Error(prj + " not supported"); } if (sr) { spatialReferences_['' + wkidt] = sr; } } return sr; }; //end of projection related code// /** * @name Error * @class Error returned from Server. * Syntax: *
       * {
       "error" : 
      {
        "code" : 500, 
        "message" : "Object reference not set to an instance of an object.", 
        "details" : [
          "'geometry' parameter is invalid"
        ]
      }
      }
      
    */ /** * Create a ArcGIS service catalog instance using it's url: http://<host>/<instance>/rest/services * @name Catalog * @constructor * @class The catalog resource is the root node and initial entry point into an ArcGIS Server host. * This resource represents a catalog of folders and services published on the host. * @param {String} url * @property {String} [currentVersion] currentVersion * @property {Array.string} [folders] folders list * @property {Array.string} [services] list of services. Each has name, type property. */ function Catalog(url) { this.url = url; var me = this; getJSON_(url, {}, '', function(json) { augmentObject_(json, me); /** * This event is fired when the catalog info is loaded. * @name Catalog#load * @event */ triggerEvent_(me, 'load'); }); } /** * @name Field * @class This class represents a field in a {@link Layer}. It is accessed from * the fields property. There is no constructor for this class, * use Object Literal. * @property {String} [name] field Name * @property {String} [type] field type (esriFieldTypeOID|esriFieldTypeString|esriFieldTypeInteger|esriFieldTypeGeometry}. * @property {String} [alias] field alias. * @property {Domain} [domain] domain * @property {Int} [length] length. */ /** * Create a ArcGIS map Layer using it's url (http://[mapservice-url]/[layerId]) * @name Layer * @class This class (Layer) The layer / table(v10+) * resource represents a single layer / table in a map of a map service * published by ArcGIS Server. * @constructor * @param {String} url * @property {Number} [id] layer ID * @property {String} [name] layer Name * @property {String} [type] Feature Layer|Image Layer * @property {String} [description] description * @property {String} [definitionExpression] Layer definition. * @property {String} [geometryType] geometryType type(esriGeometryPoint|..), only available after load. * @property {String} [copyrightText] copyrightText, only available after load. * @property {Layer} [parentLayer] parent Layer {@link Layer} * @property {Boolean} [defaultVisibility] defaultVisibility * @property {Array.Layer} [subLayers] sub Layers. {@link Layer}. * @property {Boolean} [visibility] Visibility of this layer * @property {Number} [minScale] minScale * @property {Number} [maxScale] maxScale * @property {TimeInfo} [timeInfo] timeInfo * @property {DrawingInfo} [drawingInfo] rendering info See {@link DrawingInfo} * @property {Boolean} [hasAttachments] hasAttachments * @property {String} [typeIdField] typeIdField * @property {Array.Field} [fields] fields, only available after load. See {@link Field} * @property {Array.String} [types] subtypes: id, name, domains. * @property {Array.String} [relationships] relationships (id, name, relatedTableId) */ function Layer(url) { this.url = url; this.definition = null; } /** * Load extra information such as it's fields from layer resource. * If opt_callback function will be called after it is loaded */ Layer.prototype.load = function() { var me = this; if (this.loaded_) { return; } getJSON_(this.url, {}, '', function (json) { augmentObject_(json, me); me.loaded_ = true; /** * This event is fired when layer's service info is loaded. * @name Layer#load * @event */ triggerEvent_(me, 'load'); }); }; /** * Whether the layer is viewable at given scale * @param {Number} scale * @return {Boolean} */ Layer.prototype.isInScale = function(scale) { // note if the layer's extra info is not loaded, it will return true if (this.maxScale && this.maxScale > scale) { return false; } if (this.minScale && this.minScale < scale) { return false; } return true; }; /** * @name SpatialRelationship * @enum * @class This is actually a list of constants that represent spatial * relationship types. * @property {String} [INTERSECTS] esriSpatialRelIntersects * @property {String} [CONTAINS] esriSpatialRelContains * @property {String} [CROSSES] esriSpatialRelCrosses * @property {String} [ENVELOPE_INTERSECTS] esriSpatialRelEnvelopeIntersects * @property {String} [INDEX_INTERSECTS] esriSpatialRelIndexIntersects * @property {String} [OVERLAPS] esriSpatialRelOverlaps * @property {String} [TOUCHES] esriSpatialRelTouches * @property {String} [WITHIN] esriSpatialRelWithin */ var SpatialRelationship = { INTERSECTS: 'esriSpatialRelIntersects', CONTAINS: 'esriSpatialRelContains', CROSSES: 'esriSpatialRelCrosses', ENVELOPE_INTERSECTS: 'esriSpatialRelEnvelopeIntersects', INDEX_INTERSECTS: 'esriSpatialRelIndexIntersects', OVERLAPS: 'esriSpatialRelOverlaps', TOUCHES: 'esriSpatialRelTouches', WITHIN: 'esriSpatialRelWithin' }; /** * @name QueryOptions * @class This class represent the parameters needed in an query operation for a {@link Layer}. * There is no constructor, use JavaScript object literal. *
    For more info see Query Operation. * @property {String} [text] A literal search text. If the layer has a display field * associated with it, the server searches for this text in this field. * This parameter is a short hand for a where clause of: * where [displayField]like '%[text]%'. The text is case sensitive. * This parameter is ignored if the where parameter is specified. * @property {OverlayView|Array.OverlayView} [geometry] The geometry to apply as the spatial filter. * @property {SpatialRelationship} [spatialRelationship] The spatial relationship to be applied on the * input geometry while performing the query. The supported spatial relationships * include intersects, contains, envelope intersects, within, etc. * The default spatial relationship is intersects. See {@link SpatialRelationship} * @property {String} [where] A where clause for the query filter. Any legal SQL where clause operating on the fields in the layer is allowed. * @property {Array.string} [outFields] The list of fields to be included in the returned resultset. * @property {Boolean} [returnGeometry] If true, If true, the resultset will include the geometries associated with each result. * @property {Array.number} [objectIds] The object IDs of this layer / table to be queried * @property {Number} [maxAllowableOffset] This option can be used to specify the maximum allowable offset to be used for generalizing geometries returned by the query operation * @property {Boolean} [returnIdsOnly] If true, the response only includes an array of object IDs. Otherwise the response is a feature set. The default is false. * @property {OverlayOptions} [overlayOptions] See {@link OverlayOptions} */ /** * @name ResultSet * @class This class represent the results of an query operation for a {@link Layer}. * There is no constructor, use JavaScript object literal. *
    For more info see Query Operation. * @property {String} [displayFieldName] display Field Name for layer * @property {Object} [fieldAliases] Field Name's Aliases. key is field name, value is alias. * @property {GemetryType} [geometryType] esriGeometryPoint | esriGeometryMultipoint | esriGeometryPolygon | esriGeometryPolyline * @property {Array.feature} [features] result as array of {@link Feature} * @property {String} [objectIdFieldName] objectIdFieldName when returnIdsOnly=true * @property {Array.int} [objectIds] objectIds when returnIdsOnly=true */ /** * The query operation is performed on a layer resource. The result of this operation is a resultset resource that will be * passed in the callback function. param is an instance of {@link QueryOptions} *
    For more info see Query Operation. * @param {QueryOptions} params * @param {Function} callback * @param {Function} errback */ Layer.prototype.query = function(p, callback, errback) { if (!p) { return; } // handle text, where, relationParam, objectIds, maxAllowableOffset var params = augmentObject_(p, {}); if (p.geometry && !isString_(p.geometry)) { params.geometry = fromOverlaysToJSON_(p.geometry); params.geometryType = getGeometryType_(p.geometry); params.inSR = 4326; } if (p.spatialRelationship) { params.spatialRel = p.spatialRelationship; delete params.spatialRelationship; } if (p.outFields && isArray_(p.outFields)) { params.outFields = p.outFields.join(','); } if (p.objectIds) { params.objectIds = p.objectIds.join(','); } if (p.time) { params.time = formatTimeString_(p.time, p.endTime); } params.outSR = 4326; params.returnGeometry = p.returnGeometry === false ? false : true; params.returnIdsOnly = p.returnIdsOnly === true ? true : false; delete params.overlayOptions; getJSON_(this.url + '/query', params, '', function(json) { parseFeatures_(json.features, p.overlayOptions); callback(json, json.error); handleErr_(errback, json); }); }; /** * @name QueryRelatedRecordsOptions * @class This class represent the parameters needed in an query related records operation for a {@link Layer}. *
    For more info see Query Related Records Operation. * @property {Array.number} [objectIds] The object IDs of this layer / table to be queried * @property {Int} [relatioshipId] The ID of the relationship to be queried * @property {Array.string} [outFields] The list of fields to be included in the returned resultset. This list is a comma delimited list of field names. * @property {String} [definitionExpression] The definition expression to be applied to the related table / layer. From the list of objectIds, only those records that conform to this expression will be returned. * @property {Boolean} [returnGeometry = true] If true, the resultset will include the geometries associated with each result. * @property [Number] [maxAllowableOffset] This option can be used to specify the maximum allowable offset to be used for generalizing geometries returned by the query operation * @property {Number} [outSR] The well-known ID of or the {@link SpatialReference} of the output geometries */ /** * @name RelatedRecords * @class This class represent the results of an query related records operation for a {@link Layer}. *
    For more info see Query Operation. * @property {String} [geometryType] esriGeometryPoint | esriGeometryMultipoint | esriGeometryPolygon | esriGeometryPolyline * @property {Object} [spatialReference] {@link SpatialReference} * @property {String} [displayFieldName] display Field Name for layer * @property {Array.object} [relatedRecordGroups] list of related records */ /** * @name RelatedRecord * @class This class represent the result of an query related records operation for a {@link Layer}. * There is no constructor, use JavaScript object literal. *
    For more info see Query Operation. * @property {int} [objectId] objectid of original record * @property {Array.feature} [relatedRecords] list of {@link Feature}s. */ /** * The query related records operation is performed on a layer / table resource. * The result of this operation are featuresets grouped by source layer / table * object IDs. Each featureset contains Feature objects including the values for * the fields requested by the user. For related layers, if you request geometry * information, the geometry of each feature is also returned in the featureset. * For related tables, the featureset does not include geometries. * @param {QueryRelatedRecordsParameters} params * @param {Function} callback * @param {Function} errback */ Layer.prototype.queryRelatedRecords = function(qparams, callback, errback) { if (!qparams) { return; } var params = augmentObject_(qparams, {}); params.f = params.f || 'json'; if (params.outFields && !isString_(params.outFields)) { params.outFields = params.outFields.join(','); } params.returnGeometry = params.returnGeometry === false ? false : true; getJSON_(this.url + '/query', params, '', function (json) { handleErr_(errback, json); callback(json); }); }; /** * @name MapSerivceOptions * @class provides options to construct a {@link MapService} * @property {Number} delayLoad number of seconds to delay loading meta data on construction. */ /** * Creates a MapService objects that can be used by UI components. *