Select to view content in your preferred language

FeatureLayer wkid transformation/reproject

2417
7
Jump to solution
09-15-2017 05:21 AM
MichaelLodes2
Occasional Contributor

Hi,

I want to reproject my FeatureLayer with client side Point features (wkid: 31468) into my streets basemap (default wkid: 4326).

How can I do this. See me code below, there is one point in "features". There will be several thousand points in future to be displayed.

var map = new Map({
      basemap: "streets"

    });

var view = new MapView({
      center: [10.757158, 48.181567],
      container: "viewDiv",
      map: map,
      zoom: 15
    });

var features = [      
          {

     geometry: new Point({
        x: 4408681.069,
        y: 5338984.143
        

      })
  }
                
];



var lyr = new FeatureLayer({
    fields: [
        {
        name: "ObjectID",
        alias: "ObjectID",
        type: "oid"
        }
    ],
    objectIdField: "ObjectID",
    geometryType: "point",
    spatialReference: { wkid: 31468 },
    source: features,  
    renderer: baumRenderer //custom renderer
  
});

map.add(lyr);

Thank you very much for your help.

Michael

0 Kudos
1 Solution

Accepted Solutions
ThomasSolow
Regular Contributor

To go a little further, the only projection that is included in the JS API is WGS84 to web mercator and web mercator to WGS84.  Everything else is done on the backend.

There is a public geometry service that you can use located at https://utility.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer (only supports json, no html)

View solution in original post

7 Replies
RobertScheitlin__GISP
MVP Emeritus

Michael,

  First thing is the esri default base maps are 102100 not 4326. To reproject your data you need to use the GeometryService project method.

https://developers.arcgis.com/javascript/latest/api-reference/esri-tasks-GeometryService.html#projec... 

ThomasSolow
Regular Contributor

To go a little further, the only projection that is included in the JS API is WGS84 to web mercator and web mercator to WGS84.  Everything else is done on the backend.

There is a public geometry service that you can use located at https://utility.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer (only supports json, no html)

MichaelLodes2
Occasional Contributor

Tank you for your fast answers.

@Thomas Solow, does this mean I have to outsource my javascript code from html/php file to .json and do there the projection? Could I do that also offline?

0 Kudos
ThomasSolow
Regular Contributor

You'll need an internet connection to use the geometry service.  You can do this from JS normally, I just meant that most esri services have an HTML UI but the geometry service I linked doesn't.

Here's a sample showing how to project a list of geometries (only one in the example) and then add each one to a layer as a new graphic: JS Bin - Collaborative JavaScript Debugging 

MichaelLodes2
Occasional Contributor

Thank you very much for the example code. That worked for me perfectly.

To come back to the offline issue - Is there another possibility to transform/project features? The success of my application depends amongst others on the possibility to use it offline. Could I do that for example with python in background?

0 Kudos
MichaelLodes2
Occasional Contributor

Hi Thomas,

what is happening now - when I execute my code (token from your sample), no objects are displayed in browser. When I refresh website, sometimes all objects are displayed, sometimes just a handful of objects. In your code you are using the then()-function. So what can be the problem? I think it's the GeometryService. It seems to be arbitrary hhow many objects are displayed. Is there no possibility to project whole FeatureLayers? Isn't loading each point into the project()-function very expensive?

You can see my code below.


<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no">
  <title>Test</title>
  <style>
    html,
    body,
    #viewDiv {
      padding: 0;
      margin: 0;
      height: 100%;
      width: 100%;
    }
  </style>

  <link rel="stylesheet" href="https://js.arcgis.com/4.4/esri/css/main.css">
  <script src="https://js.arcgis.com/4.4/"></script>

  <script>
    require([
      "esri/Map",
      "esri/views/MapView",
      "esri/layers/FeatureLayer",
      "esri/Graphic",
      "esri/geometry/Point",
      "esri/symbols/SimpleMarkerSymbol",
      "esri/tasks/GeometryService",
      "esri/tasks/support/ProjectParameters",
      "esri/geometry/SpatialReference",
      "esri/widgets/Compass",
      "esri/widgets/BasemapToggle",
      "esri/widgets/Track",
      "esri/renderers/SimpleRenderer",
      "esri/geometry/SpatialReference",
      "dojo/domReady!"
    ], function (Map, MapView, FeatureLayer, Graphic, Point, SimpleMarkerSymbol, GeometryService, ProjectParameters, SpatialReference, Compass, BasemapToggle, Track, SimpleRenderer, SpatialReference
) {
      var mapCenter = [10.734112, 48.174298];

      var map = new Map({
        basemap: "streets"

      });
      
      var geoSvc = new GeometryService({
      url: 'https://utility.arcgisonline.com/ArcGIS/rest/services/Geometry/GeometryServer'
    });
      
      var view = new MapView({
        center: mapCenter,
        container: "viewDiv",
        map: map,
        zoom: 15
      });


       // renderer
   var sr = new SimpleRenderer({
     symbol: new SimpleMarkerSymbol({
        style: "square",
        color: "blue",
        size: "8px",  // pixels
        outline: {  // autocasts as esri/symbols/SimpleLineSymbol
          color: [ 255, 255, 0 ],
          width: 3  // points
        }
      })
   });

      // create new layer, starts emtpty
   var lyr = new FeatureLayer({
     fields: [
       {
         name: "ObjectID",
         alias: "ObjectID",
         type: "oid"
       }
    ],
    objectIdField: "ObjectID",
    geometryType: "point",
    spatialReference: { wkid: 102100 },
    source: [],
    renderer: sr //custom renderer
  });
      
        
 
    
               
            
    var feature = [ 
        new Point({
          x: "4408069.551",
          y: "5338730.568",
          spatialReference: { wkid: 31468 }
        })


    ]; 
    projectPoints (geoSvc, feature, lyr);   
    
    var feature1 = [ 
        new Point({
          x: "4408681.069",
          y: "5338984.143",
          spatialReference: { wkid: 31468 }
        })


    ]; 
    projectPoints (geoSvc, feature1, lyr); 


    var feature2 = [ 
        new Point({
          x: "4408132.398",
          y: "5339858.609",
          spatialReference: { wkid: 31468 }
        })


    ]; 
    projectPoints (geoSvc, feature2, lyr); 
    

    var feature3 = [ 
        new Point({
          x: "4407338.453",
          y: "5340594.881",
          spatialReference: { wkid: 31468 }
        })


    ]; 
    projectPoints (geoSvc, feature3, lyr);
    
             var feature4 = [ 
        new Point({
          x: "4407532.633",
          y: "5340506.362",
          spatialReference: { wkid: 31468 }
        })


    ]; 
    projectPoints (geoSvc, feature4, lyr);
    
            var feature5 = [ 
        new Point({
          x: "4403489.605",
          y: "5340682.593",
          spatialReference: { wkid: 31468 }
        })


    ]; 
    projectPoints (geoSvc, feature5, lyr);
            
    
    var feature6 = [ 
        new Point({
          x: "4402731.486",
          y: "5342881.800",
          spatialReference: { wkid: 31468 }
        })


    ]; 
    projectPoints (geoSvc, feature6, lyr);
                
    
    var feature7 = [ 
        new Point({
          x: "4402384.333",
          y: "5339734.656",
          spatialReference: { wkid: 31468 }
        })


    ]; 
    projectPoints (geoSvc, feature7, lyr);                     
    var feature8 = [ 
        new Point({
          x: "4401578.794",
          y: "5342314.299",
          spatialReference: { wkid: 31468 }
        })


    ]; 
    projectPoints (geoSvc, feature8, lyr);
                    
    
    var feature9 = [ 
        new Point({
          x: "4402966.449",
          y: "5339372.039",
          spatialReference: { wkid: 31468 }
        })


    ]; 
    projectPoints (geoSvc, feature9, lyr);
                    
    
    var feature10 = [ 
        new Point({
          x: "4407610.834",
          y: "5338804.822",
          spatialReference: { wkid: 31468 }
        })


    ]; 
    projectPoints (geoSvc, feature10, lyr);


      // add layer to map
    map.add(lyr);

    
       // project each geomtry, then add to layer's source
   function projectPoints(geoSvc, geometries, lyr){
        geoSvc.project({
          geometries: geometries,
          outSpatialReference: SpatialReference.WebMercator
        }).then(geometries => {
          let features = geometries.map((geometry, idx) => {
            return new Graphic({
              geometry: geometry,
              attributes: {
                objectID: idx - 1
              }
            });
          });

          lyr.source = lyr.source.concat(features);
          
        });
    }
    
    
    
    });
  </script>
</head>

<body>
  <div id="viewDiv"></div>
</body>
</html>

Best Regards,

Michael

0 Kudos
ThomasSolow
Regular Contributor

Looks like the problem is with concat.

Try changing this line: 

lyr.source = lyr.source.concat(features);

to this:

features.forEach(f => lyr.source.push(f));

As far as doing the projections locally, I'm sure it's possible, it's just a question of finding the right code.  You might want to look at some open source tools for this kind of thing, like proj4.  There also may be some way to interface with Esri software with python, which would allow you to set up a local web server and use that to feed projections to the browser.

0 Kudos