Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

I want to know if I'm approaching this incorrectly. We are attempting to create an esri-based map where we add graphics to a map thru the javascript API. The points that we're adding are lat/lng coords(wkid:4326). Part of our requirements are to be able to show these items regardless of the spatialreference of the map. So we tried to use the geometry service that esri provides to project the 4326 coords to the map spatialreference.

That all works fine, unless we have a lot of points to project. If the geometry service is fed too many points at a time it returns Error:"timeout exceeded". We've split out the amount we give the service and called it iteratively, but it also errors out if we call it too many times too quickly. So we've tried to spread the interval between calls to limit that. The more I do this, the more I feel like I'm digging myself into a deep hole.

  1. Should we be approaching this problem in another way? If so, any suggestions?
  2. Should we homebrew our own geometry projection service to bypass the limitations we notice with the esri implementation?
    1. If so, any resources that would help with the required algorithms?
share|improve this question
1  
Where are the points coming from? If you're fetching via the REST query, you can request them to be returned in the map's spatial reference. All the SDK's should expose this, including the javascript SDK. –  Kirk Kuykendall Dec 5 '11 at 16:59
    
The points are coming from our database, we need them converted, but as I mentioned the geometry service has limitations that I'm trying to work with –  Jose Dec 5 '11 at 17:04
    
How many points cause the service to time out? –  Derek Swingley Dec 5 '11 at 17:06
    
@Derek: 15+ points and if a request is < 30ms between each other it also errors out –  Jose Dec 5 '11 at 17:07
    
Assuming the points are coming from a web service, would a server-side solution be acceptable? If so, what is the DBMS you're running? –  Kirk Kuykendall Dec 5 '11 at 17:08
show 1 more comment

2 Answers

up vote 0 down vote accepted

It shouldn't be a problem to send 15 or so points to a geometry service to be projected in a single call.

Below is an example that generates 50 "random" lat, lon points (if you run this locally, provide a URL for a proxy page) and sends them to a geometry service hosted by Esri to be projected to web mercator:

<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=7,IE=9" />
    <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no"/>
    <title></title>

    <link rel="stylesheet" type="text/css" href="http://serverapi.arcgisonline.com/jsapi/arcgis/2.5/js/dojo/dijit/themes/tundra/tundra.css">
    <script src="http://serverapi.arcgisonline.com/jsapi/arcgis/?v=2.5" type="text/javascript"></script>

    <script type="text/javascript">
      dojo.require("esri.map");
      dojo.require("esri.tasks.geometry");

      esri.config.defaults.io.proxyUrl = "URL TO YOUR PROXY PAGE";

      var map, gsvc, pt;

      function init() {
        var ext, layer;

        ext = esri.geometry.geographicToWebMercator(new esri.geometry.Extent(-144.13, 7.98, -52.76, 68.89, new esri.SpatialReference({wkid: 4326})));
        map = new esri.Map("map", { "extent": ext });

        layer = new esri.layers.ArcGISTiledMapServiceLayer("http://services.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Base/MapServer");
        map.addLayer(layer);

        gsvc = new esri.tasks.GeometryService("http://tasks.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer");
        dojo.connect(map, "onClick", projectPoints);
      }

      function projectPoints(evt) {
        var pts, symbol, graphic, outSR, coordsTable;

        map.graphics.clear();
        pts = createPoints(evt.mapPoint);

        symbol = new esri.symbol.SimpleMarkerSymbol().setStyle(esri.symbol.SimpleMarkerSymbol.STYLE_DIAMOND);
        graphic = new esri.Graphic(evt.mapPoint, symbol);
        outSR = new esri.SpatialReference({ wkid: 102100 });

        map.graphics.add(graphic);

        gsvc.project(pts, outSR, function(projected) {
          console.log("gsvc returned: ", projected);
          coordsTable = "<table><thead><th>x</th><th>y</th></thead><tbody>";
          dojo.forEach(projected, function(p) {
            coordsTable += "<tr><td>" + p.x.toFixed() + "</td><td>" + p.y.toFixed() + "</td></tr>";
          });
          coordsTable += "</tbody></table>";
          dojo.byId("outCoords").innerHTML = coordsTable;
        });
      }

      function createPoints(mp) {
        var ext, width, height, numGraphics, latLonPts, i, randx, randy, pt;

        ext = map.extent;
        width = ext.xmax - ext.xmin;
        height = ext.ymax - ext.ymin;
        numGraphics = 50;
        latLonPts = [];
        for ( i=0; i<numGraphics; i++ ) {
          randx = (Math.random() * width) + ext.xmin;
          randy = (Math.random() * height) + ext.ymin,
          pt = esri.geometry.webMercatorToGeographic(new esri.geometry.Point(randx, randy, map.spatialReference));
          latLonPts.push(pt);
        }
        return latLonPts;
      }
      dojo.ready(init);
    </script>
  </head>
  <body class="tundra">
    <b>Click a location on the map to Project from LatLng -> Web Mercator:</b>
    <div id="map" style="width:600px; height:400px; border:1px solid #000;"></div>
    <div id="outCoords"></div>
  </body>
</html>

Can you post the code showing how you're talking to the geometry service?

Additionally, there are built-in client side methods to do geographic --> web mercator and web mercator --> geographic conversions. No geometry service necessary.

share|improve this answer
    
All i can say is I tried to send more than 15 and it would error out. The esri.geometry.geographicToWebMercator function is what got me where I needed to be. Thanks! –  Jose Dec 6 '11 at 16:07
    
Glad you got it sorted. If you're interested in pursuing this further, please email me: dswingley at esri dot com. –  Derek Swingley Dec 6 '11 at 16:53
add comment

You can do the reprojection on the client side (in javascript) rather than relying on a Geometry server.

The PROJ4JS library will let you do that. If you know ahead of time which projections your maps will be in, so much the better- you can prune down PROJ4JS to only include what you need. Otherwise, you can just use the whole thing.

share|improve this answer
    
how do I create a projection from wkid:4326 to wkid:102100? I don't know what spatialreference.org considers it? –  Jose Dec 5 '11 at 23:16
    
I think they use the "GOOGLE" code, EPSG:900913. They may also use the new EPSG code, EPSG:3857. See gis.stackexchange.com/questions/253/… –  mwalker Dec 6 '11 at 16:55
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.