3.17 Measurement Widget Location Conversion Incorrect

1650
3
07-28-2016 08:13 AM
JoelBennett
MVP Regular Contributor

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

Description:

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

Conditions:

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 https://developers.arcgis.com/javascript/3/sandbox/sandbox.html?sample=widget_measurement 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.

Diagnosis:

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:

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

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}, 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.

Prescription:

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

0 Kudos
3 Replies
JoelBennett
MVP Regular Contributor

There is another subtle bug in the measure tool related to the advanced location measurements.  In some cases, which could be very common in our setup, The "measure-end" will fire once on the first mouse move if one of the advanced units is selected.  This was also noticed in 3.17.

The perceived intent of the advanced tools is that they shouldn't update on mouse move.  The code is set up to detect that and turn the move handler off, but not until after the first time it fires.

You can reproduce this in the sandbox (see above) by adding the advancedLocationUnits parameter to the constructor and running it.  Then, expand the measure tool, click the Location tool, switch to MGRS, click a different tool (Distance or Area) and then click back on Location.  Then move the mouse over the map...you will see the tool calculates the location of where the mouse cursor first intersected the map.

The problem occurs in the _calculateLocation function

You can fix the problem by changing the line:

A&&this._mouseMoveMapHandler&&(c.disconnect(this._mouseMoveMapHandler),this._mouseMoveMapHandler=null);

to

if((A)&&(this._mouseMoveMapHandler)){c.disconnect(this._mouseMoveMapHandler);this._mouseMoveMapHandler=null;if(!a)return;}

0 Kudos
JonathanUihlein
Esri Regular Contributor

Hi Joel!

Thank you for taking the time to report these issues.

Both workflows described in this thread have been fixed internally and will be available in the next release (3.18).

Please don't hesitate to let us know if you discover any other issues.

0 Kudos
JeffPace
MVP Alum

I have noticed alot of items fixed in 3.18, and references that people are using it.  However it is not available for download

0 Kudos