3.17 Measurement Widget Location Conversion Incorrect

Discussion created by bennetjo on Jul 28, 2016
Latest reply on Sep 15, 2016 by jeff.pace

A bug exists in the Measurement dijit of version 3.17 of the API.  This could also exist is previous versions as well.



After obtaining a location value, you get nothing or a garbage value when switching the units to UTM, MGRS, or USNG.




1) Your map's spatial reference is web mercator (may happen for other spatial references besides WGS 84 as well).

2) You create the measurement dijit with "advancedLocationUnits" set to true



Steps to reproduce:

(Note, you can reproduce this is in the measurement widget sample at if you also add the "advancedLocationUnits" parameter and set it to true in the constructor and then run the sample)

1) Click the "Location" tool of the widget

2) Click a point on the map so you see the output for the point

3) Switch the units to UTM, USNG, OR MGRS


Note: This bug is not manifested if you select UTM, USNG, or MGRS and then click the point on the map.  It is only where there is an existing point and you switch units.


Example: If your original units are UTM, and you click a point, you get a good value.  If you then re-select UTM in the units list, you get a garbage value for the same location.




There are different code paths taken when clicking on a point, or switching the dropdown list.  The problem occurs in the _switchLocationUnit function, particularly in this line of code:




Since that's difficult to comprehend, I've translated it (more or less) here:


if ((b == "esriDegreeMinuteSeconds")  || (b == "esriDecimalDegrees")) {
 this._mouseMoveMapHandler = c.connect(this._map, "onMouseMove", this, "_locationMoveHandler");
 this._toggleLocationResultsTable(true, false);
 if (this._locationGraphic)
  this._calculateLocation(this._locationGraphic.geometry, true);
} else {
 this._toggleLocationResultsTable(false, false);
 if ((this.resultValue !== null) && (this.markerLocationX !== null) && (this.markerLocationY !== null)) {
  a = this.markerLocationX;
  d = this.markerLocationY;
  if (this._locationGraphic)
   this._updateGeocoordinateStringLocation({coordinates:[[a,d]], sr:{wkid: 4326}, conversionType:this._unitStrings[b]}, this._locationGraphic.geometry);


Notice the call at the end to _updateGeocoordinateStringLocation...notice in particular the hard-coded value of the "sr" parameter {wkid:4326}.  This is the problem...explanation below:


When just clicking a point on the map, the workflow goes from _measureCustomPoint to _calculateLocation.  This results in call to _updateMarkerLocation, where markerLocationX and markerLocationY are set to wm values of _userGeometry (the point the user clicked).  In _calculateLocation, a copy of the geometry projected to wgs 84 is obtained, which then makes its way to _updateGeocoordinateStringLocation.  This works because the coordinate values passed are in wgs 84.


However, when changing the unit drop-down, the flow is a little different.  This starts with a call to _switchLocationUnit, which, as you can see in the code, grabs the markerLocationX and markerLocationY values, which are in web mercator, but slaps a hard coded wkid of 4326 on them, saying they're wgs 84 instead.  You can probably see where this is a problem.  This is why you get nothing/garbage when switching to UTM, MGRS, or USNG.






You can do this yourself if you have a locally hosted copy of the API.  The cause of the bug lies in the hard-coded value for sr (sr:{wkid: 4326}).  I instead recommend changing it to sr:this._locationGraphic.geometry.spatialReference


This is because the values of the _locationGraphic geometry are actually copied into markerLocationX and markerLocationY, which are the coordinates passed in the same call.  See flow of _locationClickHandler -> _calculateLocation -> this._updateMarkerLocation