Locate Button Will Not Find Location

5861
16
Jump to solution
10-30-2013 10:14 AM
NathanSommers
New Contributor III
I'm in the process of creating a web editing application by modifying some of the javascript examples.  I have added LocateButton into the app however when I click on the button it just spins.  It's not my browser because the examples work just fine.  Here is my code:

    <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>


Any help would be much appreciated!

Thank you,
Ian
0 Kudos
16 Replies
NathanSommers
New Contributor III
Unfortunately I was not able to find a work around so I went ahead used the ArcGIS for iOS app.  We were in a time crunch to get a product deployed so I decided that it was better just to use the app then try and reinvent the wheel.  So far it has served our needs perfectly.
0 Kudos
AndyBurns
Occasional Contributor
Hi

Just thought i would add in here. I have not worked with the geolocation service since the old syntax so only have some examples of how i got it to work on a BNG projection (27700)

Once i got the lat lon i then pushed it through our geometry service

// 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);
                })
              }
            };


Hope this helps put you in the right direction.
0 Kudos
OttarViken_Valvåg
New Contributor III
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;
        } 
    });
});
0 Kudos
MattDriscoll
Esri Contributor
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 will add this to the widget for the next update!

Thanks for bringing it to our attention.
0 Kudos
LorinGaertner
New Contributor

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?

0 Kudos
MattDriscoll
Esri Contributor

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");

0 Kudos
OttarViken_Valvåg
New Contributor III
That's great, thank you.
0 Kudos