<script> require([ "dojo/ready", "dojo/parser", "dijit/layout/BorderContainer", "dijit/layout/ContentPane", "esri/map", "esri/dijit/LocateButton", "esri/config", "esri/tasks/GeometryService", "esri/urlUtils", "esri/arcgis/utils", "dojo/dom", "dojo/_base/array", "esri/dijit/editing/Editor", "dojo/domReady!" ], function( ready, parser, BorderContainer, ContentPane, Map, LocateButton, config, GeometryService, urlUtils, arcgisUtils, dom, array, Editor ) { ready(function(){ parser.parse(); config.defaults.io.proxyUrl = "/proxy"; config.defaults.geometryService = new GeometryService("http://maps.ci.perrysburg.oh.us/arcgis/rest/services/Utilities/Geometry/GeometryServer"); //check to see if a webmap was specified using URL params. If not use the //hardcoded webmap id var urlObject = urlUtils.urlToObject(document.location.href); var webmap = "90d7e213fb014d31ac623d233511fcf9"; if(urlObject.query && urlObject.query.webmap){ webmap = urlObject.query.webmap; } //create the map arcgisUtils.createMap(webmap, "map", { mapOptions: { sliderStyle: "large" }, ignorePopups: true }).then(function(response){ var map = response.map; dom.byId("title").innerHTML = response.itemInfo.item.title; dom.byId("snippet").innerHTML = response.itemInfo.item.snippet; geoLocate = new LocateButton({ map: map, geolocationOptions: { maximumAge: 0, timeout: 15000, enableHighAccuracy: true } }, "LocateButton"); //create the editor widget var layerInfo = []; var layers = response.itemInfo.itemData.operationalLayers; array.forEach(layers, function (layer){ layerInfo.push({ "featureLayer": layer.layerObject }); }); var settings = { map: map, layerInfos: layerInfo }; var editorWidget = new Editor({ settings: settings },"editorDiv"); editorWidget.startup(); }); }); }); </script>
Solved! Go to Solution.
// use this if basemap is WGS84 --- var pt = esri.geometry.geographicToWebMercator(new esri.geometry.Point(location.coords.longitude, location.coords.latitude)); //otherwise, use this stuff below - basically we make a new point with the geolocated coordinates and reproject it, but to do so, you make the point //first and specify it's originating spatial reference so then you can reproject it to your own wkid function zoomToLocation(location) { var pt = new esri.geometry.Point(location.coords.longitude, location.coords.latitude, new esri.SpatialReference({ wkid: 4236 } )); //don't forget to specify the originating wkid (in this case from the GPS/Geolocation) var outSR = new esri.SpatialReference({ wkid: 27700 }); gsvc.project([pt], outSR, function (projectedPoints) { pt = projectedPoints[0]; map.centerAndZoom(pt, 2); //add graphic at current location - if graphic exists just move it if (!graphic) { addGraphic(pt); } else { //move the graphic if it already exists graphic.setGeometry(pt); } map.centerAt(pt); //console.log(pt); }) } };
require([ "dojo/_base/lang", "esri/dijit/LocateButton", "dojo/Deferred", "esri/config", "esri/geometry/Point", "esri/SpatialReference" ], function ( lang, LocateButton, Deferred, esriConfig, Point, SpatialReference ) { lang.extend(LocateButton, { _setPosition: function (location) { var deferred = new Deferred; if (location && location.coords) { var point = null; var scale = this.get("scale") || location.coords.accuracy || 5E4; if (point = new Point([location.coords.longitude, location.coords.latitude], new SpatialReference({ wkid: 4326 }))) { esriConfig.defaults.geometryService.project([point], this.map.spatialReference).then(lang.hitch(this, function (projectedPoints) { point = projectedPoints[0]; var event = this._createEvent(point, scale, location); if (this.get("setScale")) this.get("map").setScale(scale); if (this.get("centerAt")) { this.get("map").centerAt(point).then(lang.hitch(this, function () { deferred.resolve(event); }), lang.hitch(this, function (err) { if (!err) err = Error("LocateButton::Could not center map."); deferred.reject(err); })); } else { deferred.resolve(event); } }), lang.hitch(this, function (err) { if (!err) err = Error("LocateButton::Could not project point to map's spatial reference."); deferred.reject(err); })); } else { var err = Error("LocateButton::Invalid point"); deferred.reject(err) } } else { var err = Error("LocateButton::Invalid position"); deferred.reject(err); } return deferred.promise; } }); });
I've also found that the Locate Button does not work with non-mercator projections.
The fairly obvious requirement of projecting the lat/long coordinate to the map's spatial reference doesn't seem to be implemented.
I added the functionality to the LocateButton by overriding the private _setPosition method using version 3.8 of the API. Since it's a private method the fix could break with updates of the API though. Hopefully ESRI can incorporate this functionality in future versions of the API, it's literally 3 extra lines of code.require([ "dojo/_base/lang", "esri/dijit/LocateButton", "dojo/Deferred", "esri/config", "esri/geometry/Point", "esri/SpatialReference" ], function ( lang, LocateButton, Deferred, esriConfig, Point, SpatialReference ) { lang.extend(LocateButton, { _setPosition: function (location) { var deferred = new Deferred; if (location && location.coords) { var point = null; var scale = this.get("scale") || location.coords.accuracy || 5E4; if (point = new Point([location.coords.longitude, location.coords.latitude], new SpatialReference({ wkid: 4326 }))) { esriConfig.defaults.geometryService.project([point], this.map.spatialReference).then(lang.hitch(this, function (projectedPoints) { point = projectedPoints[0]; var event = this._createEvent(point, scale, location); if (this.get("setScale")) this.get("map").setScale(scale); if (this.get("centerAt")) { this.get("map").centerAt(point).then(lang.hitch(this, function () { deferred.resolve(event); }), lang.hitch(this, function (err) { if (!err) err = Error("LocateButton::Could not center map."); deferred.reject(err); })); } else { deferred.resolve(event); } }), lang.hitch(this, function (err) { if (!err) err = Error("LocateButton::Could not project point to map's spatial reference."); deferred.reject(err); })); } else { var err = Error("LocateButton::Invalid point"); deferred.reject(err) } } else { var err = Error("LocateButton::Invalid position"); deferred.reject(err); } return deferred.promise; } }); });
I'm using API 3.10 and as far as I can tell this still hasn't been fixed. Or has it and I'm missing something?
It will project the geometry if you've set a geometry service for your app.
Default API Configurations | Guide | ArcGIS API for JavaScript
esriConfig.defaults.geometryService = new GeometryService("http://yourdomain.com/geometryService");