关于mapbox:mapbox地图对接gis图层时坐标系不一致

64次阅读

共计 1814 个字符,预计需要花费 5 分钟才能阅读完成。

问题形容

当我的项目须要对接 GIS 图层时,发现它的坐标系为 EPSG:4490,而 mapbox 反对的坐标系是 EPSG:3857。mapbox 对接 wms 时 bbox 截取的地图块的经纬度范畴,在对接时可将其 EPSG:3857 通过拦挡申请转换为 EPSG:4490 的坐标系,获取失去 GIS 对应的图层瓦片。

  • EPSG:4326
    大地坐标系,WGS84
  • EPSG:4490
    大地坐标系,cgcs2000
  • EPSG:3857
    投影坐标系,墨卡托投影

形式 1: 通过全局拦挡 fetch 申请的形式

function injectFetch() {const newFetch = Object.getOwnPropertyDescriptor(window, 'fetch');
  Object.defineProperty(window, 'fetch', {value(a, b) {if (a instanceof Request && a.url.includes('/GISServices/')) {const u = new URL(a.url);
        // 解析 bbox 参数
        const bbox = u.searchParams.get('bbox') ?? '';
        const [lon1, lat1, lon2, lat2] = bbox.split(',');
        // 坐标系转换:墨卡托 ->GPS
        const p1 = mercator2LonLat([Number(lon1), Number(lat1)]);
        const p2 = mercator2LonLat([Number(lon2), Number(lat2)]);
        const newBBOX = p1.concat(p2).join(',');
        u.searchParams.set('bbox', newBBOX);
        Object.defineProperty(a, 'url', {value: decodeURIComponent(u.toString()),
        });
      }
      return newFetch.value.apply(this, [a, b]);
    },
  });
}

代理拦挡申请的形式

  • 可通过 node 写一个代理服务,拦挡瓦片申请服务。参考 webpack 的配置代理服务的形式,通过 http-proxy-middleware 来实现,而后可通过把 node 服务打包为 exe 后部署服务器来实现。

坐标系简介

通常有两种坐标系 天文坐标系(geographic coordinate systems)和 投影坐标系(projected coordinate systems)

天文坐标系

坐标系 简介
WGS-84 坐标系 地心坐标系,GPS 原始坐标体系
GCJ-02 坐标系 国测局坐标,火星坐标系,应用:高德、腾讯、Google 中国地图
CGCS2000 坐标系 国家大地坐标系
BD-09 坐标系 百度地图所采纳的坐标系,由 GCJ-02 进行进一步的偏移算法失去

投影坐标系(Projected coordinate systems)

天文坐标系是三维的,咱们要在地图或者屏幕上显示就须要转化为二维,这被称为投影(Map projection)。不言而喻的是,从三维到二维的转化,必然会导致变形和失真,失真是不可避免的,然而不同投影下会有不同的失真,这让咱们能够有得抉择。罕用的投影有等矩矩形投影(Platte Carre)和墨卡托投影(Mercator)

  • 墨卡托投影: 投影后依然是圆形,然而在高纬度时物体被重大放大了
  • 等距投影: 物体的大小变动不是那么显著,然而图像被拉长了

墨卡托坐标系与 GPS 坐标系转换工具办法

// 墨卡托坐标转 GPS 坐标
function mercator2LonLat(mercator) {const x = (mercator[0] / 20037508.34) * 180;
  let y = (mercator[1] / 20037508.34) * 180;
  y = (180 / Math.PI) * (2 * Math.atan(Math.exp((y * Math.PI) / 180)) - Math.PI / 2);
  return [x, y];
}

// GPS 坐标转墨卡托坐标
function lonLat2Mercator(lonlat) {const x = (lonlat[0] * 20037508.34) / 180;
  let y = Math.log(Math.tan(((90 + lonlat[1]) * Math.PI) / 360)) / (Math.PI / 180);
  y = (y * 20037508.34) / 180;
  return [x, y];
}

正文完
 0