首页 > 解决方案 > 开放层 3 中的坐标基于什么以及它们如何工作?

问题描述

我是打开第 3 层的新手,我发现了一个绘制多边形的示例

我在示例中看到您创建了一个矢量图层,并在该层中给它一个 geoJSON 作为源,geoJSON 具有如下特征:

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

现在这可行,我得到了一个漂亮的多边形,我不知道这些坐标是什么?我的意思是什么是-5e6?!,如果我有这样的长和纬度:

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

如何将其转换为这些坐标?,
实际上我进行了一些搜索,并找到了一些链接:
打开第 3 层如何以编程方式绘制多边形?
但使用后:

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

transform我的坐标(我仍然不知道我要转换成什么,因为我不知道类似的东西是什么-5e6意思),我仍然没有得到任何结果
有人可以说明这些坐标是基于什么的吗他们是如何工作的?
谢谢。

更新 01:
这是我运行的代码,导致cannot read property length of undefined内部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}
        />
    )
}  

最困扰我的是转换后的控制台日志显示结果如下:

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

更新 02:
根据 answer 的建议cabesuon,我现在正在使用以下代码:

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,
    });  

但是地图上什么也没画,在控制台记录多边形后,我可以看到一个问题:

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

我不知道为什么,但我的代码中似乎有些不正确,导致不正确extent_ends_

标签: javascriptreactjsopenlayersopenlayers-3

解决方案


要使地图应用程序正常工作,它提供的所有信息都需要位于相同的空间参考系统 (SR) 中,通常由底图确定,例如 OSM 地图、必应地图等。Web 地图的实际 SR 是 Web Mercator每股收益:3857。

现在,您要询问的坐标位于 Web Mercator 中。您看到的值是科学计数法。例如 1e6=1000000,换句话说就是 1x10^6。

如果您的坐标是地理坐标 (EPSG:4326),则需要将其转换为地图使用的 SR。polygon.transform('EPSG:4326', 'EPSG:3857')正在将地理坐标转换为网络墨卡托,如果您的地图使用网络墨卡托(如果您有网络底图,它可能会这样做)它应该可以工作。

问题更新

您的代码有几个问题,

  1. 你有一个坐标数组而不是几何,你需要创建一个几何
  2. 在对几何体应用变换后,现在您正在使用一种变换坐标而不是数组的方法
  3. 您不需要为特征集合创建geojson,只需创建一个特征并将其添加到源中

像这样的东西应该工作,

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);

更新2:我在你的坐标数组中错过了一些东西,问题是要创建一个Polygon带有坐标的坐标,你必须将一个环数组作为参数传递,而一个环是一个坐标数组,修复它可以正常工作。

这里我给你做了一个例子,

<!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>


推荐阅读