Hello World

这个是标题,但是为什么要有标题

这个是子标题,但是为什么要有子标题

openlayers解决坐标经过本初子午线后横跨整个地图的异常问题

在使用 OpenLayers 处理坐标系统和地图投影时,确保地图上的线条平滑过渡过本初子午线是一个常见的问题。本博客提供了一个针对 EPSG:3857 和 EPSG:4326 投影的坐标调整方法,以避免线条异常横跨整个地图的情况。

针对3857投影

当使用 EPSG:3857 投影时,坐标系统使用的是米为单位,而绘图时涉及的经度可能跨越180度。以下的 adjustCoordinates 函数通过检测并调整跨越本初子午线的坐标来处理这个问题:

function adjustCoordinates(coords) {
  return coords.reduce((acc, coord, index, array) => {
    if (index === 0) {
      acc.push(coord);
      return acc;
    }
    const previous = acc[acc.length - 1];
    let [prevX, prevY] = previous;
    let [x, y] = coord;

    // 将米转换回经度
    const prevLon = prevX / 20037508.34 * 180;
    const lon = x / 20037508.34 * 180;

    // 检查是否跨越180度经线
    const lonDifference = lon - prevLon;
    if (Math.abs(lonDifference) > 180) {
      // 如果跨越,找到合适的方向进行调整
      const adjustment = Math.sign(lonDifference) * 360;
      x -= adjustment / 180 * 20037508.34;
    }
    acc.push([x, y]);
    return acc;
  }, []);
}

 

针对4326投影

对于使用地理坐标系的 EPSG:4326 投影,处理方式类似,但是坐标直接是经纬度值:

function adjustCoordinates(coords) {
  return coords.reduce((acc, coord, index, array) => {
    if (index === 0) {
      acc.push(coord);
      return acc;
    }
    const previous = acc[acc.length - 1];
    let [prevLon, prevLat] = previous;
    let [lon, lat] = coord;

    // 检查是否跨越本初子午线
    const lonDifference = lon - prevLon;
    if (lonDifference > 180 || lonDifference < -180) {
      // 调整经度
      lon -= Math.sign(lonDifference) * 360;
    }
    acc.push([lon, lat]);
    return acc;
  }, []);
}

 

实现在界面上:

使用 OpenLayers 创建和显示路线的代码示例如下:

      var coordinates = row.track.map(coord => olProj.fromLonLat(coord, 'EPSG:3857'));
      coordinates = adjustCoordinates(coordinates);
      const routeFeature = new Feature({
        geometry: new LineString(coordinates),
        row
      });
      routeFeature.setStyle(selectedRouteStyle);
      const routeLayer = new VectorLayer({
        name: "routeLayer",
        source: new VectorSource({
          features: [routeFeature]
        })
      });
      this.openMap.addLayer(routeLayer);

这些代码块提供了在处理全球范围内坐标时如何优雅地管理横跨本初子午线的情况,确保地图的视觉连贯性。

posted on 2024-06-11 20:23  swuxyj  阅读(12)  评论(0编辑  收藏  举报

导航

Hello World