问题形容

当我的项目须要对接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];}