Select to view content in your preferred language

Converting between coordinate-systems

4522
9
06-19-2012 08:53 AM
GísliFreyr
Emerging Contributor
Hi

I recently started at the National Landsurvey of Iceland and I'm having a problem with programming a JS-mapviewer (don't really know how to describe it better).

So my problem is that I have a map where if you click it an alert box pops up (better for small mobile-screens than an infowindow) which contains the ISN93 and LatLong coordinates. I've been trying to code "around" an example on the JS API samples-site but the problem is that I'm not an experienced JS-programmer so I'm not figuring out how to project the point from ISN93 to LatLong coordinates.
I hope you can help, been trying this for some 4-5 hours now but not getting anything. I'll just paste the whole code here but my problem is with the "coordinates"-function.


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> 

<html> 
 <head> 
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=7,IE=9" />
  <!--The viewport meta tag is used to improve the presentation and behavior of the samples 
  on iOS devices-->
  <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no"/>
  <title> Map with scalebar</title> 
  <link rel="stylesheet" type="text/css" href="http://serverapi.arcgisonline.com/jsapi/arcgis/3.0/js/dojo/dijit/themes/claro/claro.css"> 
  <style> html, body { height: 100%; width: 100%; margin: 0; padding: 0; }#map{padding:0;}</style>
 
  <script type="text/javascript"> 
   var djConfig = {
    parseOnLoad: true
   };
   </script> 

   <script type="text/javascript" src="http://serverapi.arcgisonline.com/jsapi/arcgis/?v=2.8"></script> 
   
   <script type="text/javascript"> 
    dojo.require("dojo.parser");
    dojo.require("dijit.layout.BorderContainer");
    dojo.require("dijit.layout.ContentPane");
    dojo.require("esri.map");
    dojo.require("esri.dijit.Scalebar");
    dojo.require("esri.tasks.geometry");

    var map;
    var gsvc = null;
    var pt = null;

    function init() {
     var initExtent = new esri.geometry.Extent({
      "xmin": 210000,
      "ymin": 275000,
      "xmax": 810000,
      "ymax": 705000,
      "spatialReference": {
       "wkid": 3057
      }
     });

     map = new esri.Map("map", {
      extent: initExtent
     });

     var basemap = new esri.layers.ArcGISTiledMapServiceLayer("http://a1arc.lmi.is/arcgis/rest/services/kort-isn93/kort-medornefnum-isn93/MapServer");
     map.addLayer(basemap);

     gsvc = new esri.tasks.GeometryService("http://a1arc.lmi.is/arcgis/rest/services/Geometry/GeometryServer");

     dojo.connect(map, 'onLoad', function(scale) {
      var scalebar = new esri.dijit.Scalebar({
       map: map,
       scalebarUnit:'metric'
      });
      //resize the map when the browser resizes
      dojo.connect(dijit.byId('map'), 'resize', map,map.resize);
     });

     console.log(gsvc); 
     dojo.connect(map, "onClick", coordinates);
    }

    function coordinates(evt) {
     map.graphics.clear();
     var point = evt.mapPoint;
     console.log(point); //works
     var symbol = new esri.symbol.SimpleMarkerSymbol().setStyle(esri.symbol.SimpleMarkerSymbol.STYLE_CIRCLE);
     var outSR = new esri.SpatialReference({wkid: 4326});
     var graphic = new esri.Graphic(point, symbol);
     
     map.graphics.add(graphic);

     function projectToLatLong(point, outSR) {
      gsvc.project([point], outSR, function(projectedPoints) {
       pt = projectedPoints[0];
       console.log(pt); //doesn't work
      });
     }

     console.log(pt) //outputs null
     console.log("ISN93: " + point.x.toFixed(2) + " ; " + point.y.toFixed(2));

    }

    dojo.addOnLoad(init);
   </script> 

 </head> 
 <body class="claro"> 
  <div dojotype="dijit.layout.BorderContainer" design="headline" gutters="false"
  style="width: 100%; height: 100%; margin: 0;"> 
   <div id="map" dojotype="dijit.layout.ContentPane" region="center" style="overflow:hidden;"></div> 
  </div> 
 </body> 

</html>
0 Kudos
9 Replies
KellyHutchins
Esri Frequent Contributor
Your code was close. Looks like you just needed to call the projectToLatLong function. Here's  a modified version of your code that should work:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> 

<html> 
 <head> 
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=7,IE=9" />
  <!--The viewport meta tag is used to improve the presentation and behavior of the samples 
  on iOS devices-->
  <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no"/>
  <title> Map with scalebar</title> 
  <link rel="stylesheet" type="text/css" href="http://serverapi.arcgisonline.com/jsapi/arcgis/3.0/js/dojo/dijit/themes/claro/claro.css"> 
  <style> html, body { height: 100%; width: 100%; margin: 0; padding: 0; }#map{padding:0;}</style>
 
  <script type="text/javascript"> 
   var djConfig = {
    parseOnLoad: true
   };
   </script> 

   <script type="text/javascript" src="http://serverapi.arcgisonline.com/jsapi/arcgis/?v=2.8"></script> 
   
   <script type="text/javascript"> 
    dojo.require("dojo.parser");
    dojo.require("dijit.layout.BorderContainer");
    dojo.require("dijit.layout.ContentPane");
    dojo.require("esri.map");
    dojo.require("esri.dijit.Scalebar");
    dojo.require("esri.tasks.geometry");

    var map;
    var gsvc = null;
    var pt = null;

    function init() {
     var initExtent = new esri.geometry.Extent({
      "xmin": 210000,
      "ymin": 275000,
      "xmax": 810000,
      "ymax": 705000,
      "spatialReference": {
       "wkid": 3057
      }
     });

     map = new esri.Map("map", {
      extent: initExtent
     });

     var basemap = new esri.layers.ArcGISTiledMapServiceLayer("http://atlas.lmi.is/lmigis/rest/services/kort/grunnkort/MapServer");
     map.addLayer(basemap);

     gsvc = new esri.tasks.GeometryService("http://servicesbeta2.esri.com/arcgis/rest/services/Geometry/GeometryServer");

     dojo.connect(map, 'onLoad', function(scale) {
      var scalebar = new esri.dijit.Scalebar({
       map: map,
       scalebarUnit:'metric'
      });
      //resize the map when the browser resizes
      dojo.connect(dijit.byId('map'), 'resize', map,map.resize);
     });

     console.log(gsvc); 
     dojo.connect(map, "onClick", coordinates);
    }

    function coordinates(evt) {
     map.graphics.clear();
     var point = evt.mapPoint;
     console.log(point); //works
     var symbol = new esri.symbol.SimpleMarkerSymbol().setStyle(esri.symbol.SimpleMarkerSymbol.STYLE_CIRCLE);
     var outSR = new esri.SpatialReference({wkid: 4326});
     var graphic = new esri.Graphic(point, symbol);
     
     map.graphics.add(graphic);
                    projectToLatLong(point,outSR);

    }
     function projectToLatLong(point, outSR) {
      gsvc.project([point], outSR, function(projectedPoints) {
       pt = projectedPoints[0];
       console.log(pt.x + ' '  + pt.y ); //doesn't work
      });
     }
    dojo.addOnLoad(init);
   </script> 

 </head> 
 <body class="claro"> 
  <div dojotype="dijit.layout.BorderContainer" design="headline" gutters="false"
  style="width: 100%; height: 100%; margin: 0;"> 
   <div id="map" dojotype="dijit.layout.ContentPane" region="center" style="overflow:hidden;"></div> 
  </div> 
 </body> 

</html>

0 Kudos
JohnnyPenet
Emerging Contributor
Hi Kelly,

The code you showed is pre 3.0. As from 3.0 the project method now has a ProjectParameters as input where You can specify the datum transformation. However I tried using the new method, but I still have an offset of around 100meters. I am a bit confused with the properties as transformationForward. In the transformation list I find several same transformations :

1609 Belge_1972_To_WGS_1984_1
1610 Belge_1972_To_WGS_1984_2
15749 Belge_1972_To_WGS_1984_3

For me it looks confused. I don't now what the real transform is.

Johnny
0 Kudos
KellyHutchins
Esri Frequent Contributor
Johnny,

Can you post a snippet of your code? What coordinate system are you trying to project from and to?

Hi Kelly,

The code you showed is pre 3.0. As from 3.0 the project method now has a ProjectParameters as input where You can specify the datum transformation. However I tried using the new method, but I still have an offset of around 100meters. I am a bit confused with the properties as transformationForward. In the transformation list I find several same transformations :

1609 Belge_1972_To_WGS_1984_1
1610 Belge_1972_To_WGS_1984_2
15749 Belge_1972_To_WGS_1984_3

For me it looks confused. I don't now what the real transform is.

Johnny
0 Kudos
JohnnyPenet
Emerging Contributor
Hi Kelly,

The code I show you is part of an application framework I build for consuming the JavaScript ArcGis API (see blog jpenet.blogspot.com). The code is an illustration of using Google streetview with the ArcGis API's. It looks as if there is no datum correction. I had the same result with the version 2.8 without transform. If I use a base layer with spatial reference 102100, all is ok, but probably there is nog convertion happening.

The function for the projection change is part of a JavaScript class and looks like this :

        convertProjection: function (points, toSpacialReference, transformation, callback) {
            var params = new esri.tasks.ProjectParameters();
            params.geometries = points;
            params.outSR = toSpacialReference;
            params.transformation = transformation;
            params.transformationForward = false;
            GisOperation.getGeometryService().project(params,
                function (projectedPoints) {
                    callback(projectedPoints);
                }, function errorprojected(err) {
                    logging.logMessage("E", "projection convertion failed -->" + err.message, "GisGeoProcessing");
                    callBack(null);
                });
        }

The function is called by the code below, where the value of  viewModel.wmsTransformWgs84 has the value of  31370 (Belgium Lambert 1972):

            // Interface to google streetview use 4326 (wgs 84)
            var tranform = {
                wkid: viewModel.wmsTransformWgs84
            };
            GisGeoProcessing.convertProjection([wmsPoint], new esri.SpatialReference({ wkid: 4326 }), tranform, function (point) {
                if (point[0] != null) {
                    if (dojo.byId("streetviewId") == null) {
                        var contentPosition = "<div id='streetviewId' style='width: 360px; height: 360px'></div>";
                        require(["dojo/dom-construct"], function (domConstruct) {
                            domConstruct.place(contentPosition, "extraContents", "last")
                        });
                    }
                    GisExtra.initStreetView(point[0], dojo.byId("streetviewId"), 20);
                }
            });
0 Kudos
JohnnyPenet
Emerging Contributor
Kelly,

I think I found an explanation of the offset. I use a wms layer for doing the query of a point. However I now see that for the WMS layer, I have an offset Apparently when loading an WMS layer, projection is not done correctly when I use as base layer the streetlayer of ArcGis online with a spatial reference of 102100, probably this is the same for 31370 but  I can not verify this.

The wms layers  are http://wms.agiv.be/inspire/wms/adressen and  http://grb.agiv.be/geodiensten/raadpleegdiensten/GRB-basiskaart/wms

Johnny
0 Kudos
JohnnyPenet
Emerging Contributor
Kelly,

The offset problem is solved. You have to use a geometry service on an ArcGis server 10.1 in order to have the transformation working.
For the transformation of 102100 to wgs 84, I wrote a custom transformation in JavaScript, I could not find it in the list of transformations.

I only have two problems when loading layers dynamically :

1. When you load a ArcGISTiledMapServiceLayer which has a spatial reference defined with wkt and no wkid, you can run into problems when you need a wkid, you can solve it by set the spatial reference on the map. Example of such a service :

http://gisservices.inbo.be/ArcGIS/rest/services/Orthofoto/MapServer

2. I had a wms service which was not displayed at all having a local spatial reference and a base layer with a spatial reference of 102100. I did not find a work around for that.
Example of such a service :

http://grb.agiv.be/geodiensten/raadpleegdiensten/GRB-basiskaart/wms

I hope this give you an idea what I was trying to do.

Johnny
0 Kudos
GísliFreyr
Emerging Contributor
Kelly

Thanks for trying to help but this solution still doesn't work for me. When I click on the map the original point is still okay but the latlong coordinates (wkid:4326) prints out this error
Resource interpreted as Script but transferred with MIME type text/plain: "http://a1arc.lmi.is/arcgis/rest/services/Geometry/GeometryServer/project?f=json&outSR=4326&inSR=3057&geometries=%7B%22geometryType%22%3A%22esriGeometryPoint%22%2C%22geometries%22%3A%5B%7B%22x%22%3A521112.52222504455%2C%22y%22%3A596627.2965879266%2C%22spatialReference%22%3A%7B%22wkid%22%3A3057%7D%7D%5D%7D&callback=dojo.io.script.jsonp_dojoIoScript2._jsonpCallback". 


and when I visit that site in the browser I get:
dojo.io.script.jsonp_dojoIoScript2._jsonpCallback({"error":{"code":400,"message":"Unable to complete Project operation.","details":["Service 'Geometry' of type 'GeometryServer' does not exist or is inaccessible."]}});


As I said I'm no expert on JavaScript but I hope I figure it out soon. I would welcome if you had time to help me with this and possibly enlighten me.
0 Kudos
KellyHutchins
Esri Frequent Contributor
It sounds like your geometry service may not be running? If you navigate to your geometry service url in a browser it should take you to the rest services directory. You can test the project method there and see if it works.

http://a1arc.lmi.is/arcgis/rest/services/Geometry/GeometryServer

You may also want to test your code with this geometry service to see if your code is working correctly:
http://tasks.arcgisonline.com/arcgis/rest/services/Geometry/GeometryServer


Kelly

Thanks for trying to help but this solution still doesn't work for me. When I click on the map the original point is still okay but the latlong coordinates (wkid:4326) prints out this error
Resource interpreted as Script but transferred with MIME type text/plain: "http://a1arc.lmi.is/arcgis/rest/services/Geometry/GeometryServer/project?f=json&outSR=4326&inSR=3057&geometries=%7B%22geometryType%22%3A%22esriGeometryPoint%22%2C%22geometries%22%3A%5B%7B%22x%22%3A521112.52222504455%2C%22y%22%3A596627.2965879266%2C%22spatialReference%22%3A%7B%22wkid%22%3A3057%7D%7D%5D%7D&callback=dojo.io.script.jsonp_dojoIoScript2._jsonpCallback". 


and when I visit that site in the browser I get:
dojo.io.script.jsonp_dojoIoScript2._jsonpCallback({"error":{"code":400,"message":"Unable to complete Project operation.","details":["Service 'Geometry' of type 'GeometryServer' does not exist or is inaccessible."]}});


As I said I'm no expert on JavaScript but I hope I figure it out soon. I would welcome if you had time to help me with this and possibly enlighten me.
0 Kudos
GísliFreyr
Emerging Contributor
Thank you very much Kelly!

The problem was that the senior developer (who is now on vacation) told me to try and use that a1arc-service because something wouldn't work an now that I have fixed that the service couldn't handle this problem. So I just switched it to our "main"server and it works! Thanks again.
0 Kudos