0

I'm new to open layer 3 and i found an example of drawing a polygon :

I saw in the example that you create a vector layer and in that layer you give it a geoJSON as a source, the geoJSON has features which are something like this:

{
    'type': 'Feature',
    'geometry': {
      'type': 'Polygon',
      'coordinates': [[[-5e6, -1e6], [-4e6, 1e6], [-3e6, -1e6]]]
}

Now this works and i get a nice polygon, what i don't know is what are these coordinates? i mean what is a -5e6 ?!, if i have a long and lat such as this:

 [[36.301744, 50.010456], [36.302180, 50.019864], [36.301025, 50.021730], [36.293856, 50.016215], [66.293682, 56.009240], [66.301744, 56.010456]]

How can i convert it to these coordinates?,
Actually i did some search and i found some links :
open layers 3 how to draw a polygon programmatically?
But after using:

polygon.transform('EPSG:4326', 'EPSG:3857');  

To transform my coordinates (which i still don't know what i'm transforming to as i don't know what something like a -5e6 means), i still didn't get any result
Can someone please shine a light on what are these coordinates based on and how do they work ?
Thanks.

Update 01:
Here is the code i run which results in cannot read property length of undefined inside geon/SimpleGeomerty:

const GeographicalMap = ({ onClick }) => {

    const myCoord = [[36.301744, 50.010456], [36.302180, 50.019864], [36.301025, 50.021730], [36.293856, 50.016215], [36.293682, 50.009240], [36.301744, 50.010456]]
    const newCoord = transform(myCoord, 'EPSG:4326', 'EPSG:3857')
    console.log('newCoord', newCoord)

    const geojsonObject = {
        'type': 'FeatureCollection',
        'crs': {
            'type': 'name',
            'properties': {
                'name': 'EPSG:4326'
            }
        },
        'features': [
            {
                'type': 'Feature',
                'geometry': {
                    'type': 'Polygon',
                    'coordinates': newCoord
                }
            },
        ]
    };


    var source = new VectorSource({
        features: (new GeoJSON()).readFeatures(geojsonObject)
    })

    var layer = new VectorLayer({
        source: source,
    });

    const layers = [layer]

    return (
        <Map
            onClick={onClick}
            layers={layers}
        />
    )
}  

What bothers me the most is the the console log after transformation shows this as a result:

[
  null,
  null,
  [
    36.301025,
    50.02173
  ],
  [
    36.293856,
    50.016215
  ],
  [
    36.293682,
    50.00924
  ],
  [
    36.301744,
    50.010456
  ]
]

Update 02:
As suggest by answer cabesuon, i am now using the code below:

const myCoord = [[36.301744, 50.010456], [36.302180, 50.019864], [36.301025, 50.021730], [36.293856, 50.016215], [36.293682, 50.009240], [36.301744, 50.010456]]

    const polygon = new Polygon(myCoord);    
    polygon.transform('EPSG:4326', 'EPSG:3857');
    console.log('polygon', polygon)
    const feature = new Feature({
        geometry: polygon
    });

    const source = new VectorSource();
    source.addFeature(feature);

    const layer = new VectorLayer({
        source: source,
    });  

But nothing is drawn on the map, after console logging the polygon, i can see a problem :

extent_: (4) [Infinity, Infinity, -Infinity, -Infinity]
ends_: (6) [0, 0, 0, 0, 0, 0]  

I don't know why, but something seems to be incorrect in my code which results in incorrect extent_ and ends_

Ali Ahmadi
  • 701
  • 6
  • 27
  • If your code still does not wok, add it to the question so we can take a look. – cabesuon Mar 03 '20 at 13:33
  • @cabesuon I added an update with the code that i run and results in a error, the error happens when i assign `newCoord` to `coordinates` – Ali Ahmadi Mar 03 '20 at 15:00
  • @cabesuon Please read `update 02`, there seems to be a problem with transforming the coordinates, thanks. – Ali Ahmadi Mar 03 '20 at 15:58

1 Answers1

1

For a map application to work all the information that it presents need to be in the same spatial reference system (SR), usually determined by the basemap, for example OSM maps, Bing maps, etc. The defacto SR for web maps is Web Mercator EPSG:3857.

Now, the coordinates that you are asking are in Web Mercator. The values you are seeing are in scientific notation. As an example 1e6=1000000, in other words it means 1x10^6.

If your coordinates are in geographic (EPSG:4326), you need to transform it to the SR that the map is using. polygon.transform('EPSG:4326', 'EPSG:3857') is transforming geographic coordinates to Web mercator, if your map is using Web mercator (it probably does if you have a web basemap) it should work.

Question Update

Your code has several issues,

  1. you have an array of coordinates not a geometry, you need to create a geometry
  2. after you apply a transform on the geometry, right now you are using a method that transform a coordinate not an array
  3. you don't need to create the geojson for a feature collection, just create a feature and add it to the source

Something like this should work,

const coords = [[
  [36.301744, 50.010456], [36.302180, 50.019864], [36.301025, 50.021730],
  [36.293856, 50.016215], [36.293682, 50.009240], [36.301744, 50.010456]
]]; // edited on update 2
const polygon = new Polygon(coords);
polygon.transform('EPSG:4326', 'EPSG:3857');
const feature = new Feature({
  geometry: polygon
});
const source = new VectorSource();
source.addFeature(feature);

Update 2: There something I miss in your array of coordinates, the thing is that to create a Polygon with coords you have to pass as a parameter an array of rings, ans a ring is an array of coordinates, fixing that works fine.

Here I made an example for you,

<!doctype html>
<html lang="en">
  <head>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.1.1/css/ol.css" type="text/css">
    <style>
      .map {
        height: 400px;
        width: 100%;
      }
   #a { display: none; }
    </style>
    <script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.1.1/build/ol.js"></script>
    <title>OL - Feature From Coords</title>
  </head>
  <body>
    <h2>Feature From Coords</h2>
    <div id="map" class="map"></div>
    <script type="text/javascript">
      // tile layer
      var tile = new ol.layer.Tile({
        source: new ol.source.OSM()
      });
      // vector layer
      const coords = [
        [
          [36.301744, 50.010456],
          [36.302180, 50.019864],
          [36.301025, 50.021730],
          [36.293856, 50.016215],
          [36.293682, 50.009240],
          [36.301744, 50.010456]
        ]
      ];
      const polygon = new ol.geom.Polygon(coords);
      polygon.transform('EPSG:4326', 'EPSG:3857');
      const feature = new ol.Feature({
        geometry: polygon
      });
      const source = new ol.source.Vector();
      source.addFeature(feature);
      var vector = new ol.layer.Vector({
        source,
        style: new ol.style.Style({
          stroke: new ol.style.Stroke({
            color: 'red',
            width: 3
          }),
          fill: new ol.style.Fill({
            color: 'rgba(255, 0, 0, 0.1)'
          })
        })
      })
      var map = new ol.Map({
        layers: [
          tile,
          //image,
          vector
        ],
        target: 'map',
        view: new ol.View({
          center: ol.proj.fromLonLat([36.301025, 50.021730]),
          zoom: 12
        })
      });
    </script>
  </body>
</html>
cabesuon
  • 4,860
  • 2
  • 15
  • 24
  • i imported feature from `import Feature from 'ol/source/Vector'` and then copy pasted your code, i get the error : `TypeError: feature.getId is not a function`, the error seems to happen when `addFeature` is called. – Ali Ahmadi Mar 03 '20 at 15:33
  • Adding from `import Feature from 'ol/Feature'` solved the error – Ali Ahmadi Mar 03 '20 at 15:37
  • Thanks for the help so far, I no longer have any error but i see nothing on map!, i even tried `const myCoord = [[0, 0], [100, 100], [200, 200], [300, 300]]` so i get some thing big, bot no use, what could be the cause? – Ali Ahmadi Mar 03 '20 at 15:42
  • 1
    Yes, it seems my main problem which stopped me from getting results was the `rings`, meaning my coordinates had to be inside an extra array for it to work and show something, thanks for all the help!. – Ali Ahmadi Mar 03 '20 at 17:23
  • Exactly, glad It help you! – cabesuon Mar 03 '20 at 17:59