Select to view content in your preferred language

Client side reprojection?

2453
5
09-29-2010 07:34 AM
KevinGooss
Regular Contributor
My map is in Web Mercator projection but I want for my measurement values to be in UTM when the user does a measurement on the map with my measure tool. Is there any way to do this without having to go back to the server with every click of the mouse as a vertex is added?
0 Kudos
5 Replies
GlenRhea
Emerging Contributor
That's the only way that I know how to do it, thats also why my x,y values are displayed in UTM when the user moves their mouse, it would require a call to the server to reproject EVERY TIME. I did create a "my location" widget that displays UTM and WGS lat/long for the user which seems to satisfy that need for them.
0 Kudos
JianHuang
Deactivated User
It's not necessary to reproject it to UTM. You can use the code below to calculate geodesic length and area for geometries under GCS. Since JavaScript API has client side method to convert from Web Mercator to GCS, so there is no client-server transaction needed. But please note, the result is not as accurate as geometry service returns since the client solution is a simple calculation based on spherical model.

    geodesicLengths: function (polylines, lengthUnit) {
      var radius = 6371.009 / 1.609344; // miles
      var lengths = [];
      dojo.forEach(polylines, function (polyline, idx) {
        var length = 0;
        dojo.forEach(polyline.paths, function (path, idx) {
          var subLength = 0;
          for (var i = 1; i < path.length; i++) {
            var lon1 = path[i - 1][0] * Math.PI / 180;
            var lon2 = path[0] * Math.PI / 180;
            var lat1 = path[i - 1][1] * Math.PI / 180;
            var lat2 = path[1] * Math.PI / 180;
            var dLat = (lat2 - lat1);
            var dLon = (lon2 - lon1);
            var tempValue = Math.sin(dLat / 2) * Math.sin(dLat / 2) + Math.cos(lat1) * Math.cos(lat2) * Math.sin(dLon / 2) * Math.sin(dLon / 2);
            var coefficient = 2 * Math.atan2(Math.sqrt(tempValue), Math.sqrt(1 - tempValue));
            var distance = radius * coefficient;
            subLength += distance;
          }
          length += subLength;
        });
        length *= esri.geometry.unitsDictionary[lengthUnit];
        lengths.push(length);
      });
      return lengths;
    },

    geographicAreas: function (polygons, areaUnit) {
      var radius = 6371009; //meters
      var areas = [];
      dojo.forEach(polygons, function (polygon, idx) {
        var area = 0;
        dojo.forEach(polygon.rings, function (ring, idx) {
          var subArea = 0;
          for (var i = 1; i < ring.length; i++) {
            if (i < ring.length - 1) {
              subArea += ((ring[i + 1][0] - ring[i - 1][0]) * Math.PI / 180) * Math.sin(ring[1] * Math.PI / 180);
            }
            else {
              subArea += ((ring[1][0] - ring[i - 1][0]) * Math.PI / 180) * Math.sin(ring[1] * Math.PI / 180);
            }
          }
          subArea *= radius * radius / 2 / 4046.87; //acres
          area += subArea;
        });
        area *= esri.geometry.unitsDictionary[areaUnit];
        areas.push(area);
      });
      return areas;
    },
0 Kudos
KevinGooss
Regular Contributor
Interesting. I'm trying to get this to work for testing but I'm having trouble with the:
esri.geometry.unitsDictionary
what is that construct? I searched for it in the 9.3 and 10 js api documentation with no results and the only google reference to that term is in your post.
How can i achieve similar at the 9.3 level?
0 Kudos
JianHuang
Deactivated User
unitsDictionary is an object of the conversion number between different units. You can replace the line of code:
length *= esri.geometry.unitsDictionary[lengthUnit];
as:
length *= 1.609344; //because 1mile=1.609344 km, if you are looking for the result in the unit of kilometer
Just for your reference, here is the object:
    unitsDictionary: {
    //length unit conversion from miles
      "esriMiles": 1,
      "esriKilometers": 1.609344,
      "esriFeet": 5280,
      "esriMeters": 1609.34,
      "esriYards": 1760,
      "esriNauticalMiles": 0.869,
      //area unit conversion from acres
      "esriAcres": 1,
      "esriSqKilometers": 0.004047,
      "esriSqMiles": 0.0015625,
      "esriSqFeet": 43560,
      "esriSqMeters": 4046.87,
      "esriHectares": 0.4047,
      "esriSqYards": 4840
    },
0 Kudos
KevinGooss
Regular Contributor
Cool. Thank you very much that is helpful. I'm guessing then that sr 4326 is default of miles and acres for length and area respectively?
One other thing and i won't bother any longer. How can i calculate the perimeter of a polygon using the formulas you have provided?
0 Kudos