问题描述
当项目需要对接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];
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。