此篇博客主要介绍openlayers自定义坐标系及过程中的一些坑.功能开发的过程比预计复杂的多,主要是要彻底弄明白GIS相关开发图层分辨率 矩阵集原理,图层加载行列号 缩放等级其实都是由此计算出来的.自己也是因此走了许多弯路.写一下博客总结一下,以下加载WMTS为例
目前坐标系基本都是有EPSG来维护的,点击epsg.io进入官网,查找需要定的坐标系,以下以EPSG:3395(极地坐标系-南极)为例
进入链接: epsg.io,输入查询的坐标系,如图所示
进入详情页,找到坐标系Projected bounds、Proj4js、WGS84 bounds选项对应的信息(推荐 turf.js 地图操作的类库,相交 包含等操作)
已经拿到坐标系数据,下面创建坐标系实例,代码如下:
// 自定义坐标系
var projection_3031 = new ol.proj.Projection({
code: 'EPSG:3031',
extent:[-948.75 -543592.47,5817.41 -3333128.95],
units: 'm',
axisOrientation: 'neu'
});
proj4.defs("EPSG:3031","+proj=stere +lat_0=-90 +lat_ts=-71 +lon_0=0 +k=1 +x_0=0 +y_0=0 +datum=WGS84 +units=m +no_defs");
添加proj4 转换方法
//结合proj4在ol3中自定义坐标系,以4326为例(3857同理)
ol.proj.addProjection(projection_3031);
ol.proj.addCoordinateTransforms("EPSG:4326", "EPSG:3031",
function(coordinate) {
return proj4("EPSG:4326","EPSG:3031",coordinate);
},
function(coordinate) {
return proj4("EPSG:3031","EPSG:4326",coordinate);;
}
);
验证转换一个坐标,如果输出正常,祝贺你自定义坐标系成功
ol.proj.transform([118,32],'EPSG:4326','EPSG:3031');
因为ol默认是3857坐标系,分辨率 矩阵默认.加载自定义坐标系图层如下:
//转换地图实例坐标系 地图实例的坐标系要与图层自定义的坐标系保持一致
var new_view = new ol.View({
center: [0, 0],
zoom: 1,
projection: projection_3031
});
map.setView(new_view);
获取原点 计算分辨率 矩阵等
var projection = ol.proj.get('EPSG:3031');
var projectionExtent = projection.getExtent();
var resolutions = [x,x,x,x,...] //不同等级下,每像素代表的比例
var resolutions_len = resolutions.length;
var matrixIds = new Array(resolutions_len);
for (var z = 0; z < resolutions_len; ++z) {
matrixIds[z] = z;
}
var WMTS_layer = new ol.layer.Tile({
source: new ol.source.WMTS({
url: url,
projection: projection,
tileGrid: new ol.tilegrid.WMTS({
origin: ol.extent.getTopLeft(projectionExtent),
resolutions: resolutions, //分辨率
matrixIds: matrixIds //矩阵集
}),
format: "image/png",
wrapX: true,
crossOrigin: "anonymous",
matrixSet: "GoogleMapsCompatible"
})
});
map.addLayer(WMTS_layer); // 添加图层
完善一下,根据图层范围,自动适应中心及缩放等级
var extent = [
layer.rect_minx,
layer.rect_miny,
layer.rect_maxx,
layer.rect_maxy
];
if (proj) {
extent = ol.proj.transformExtent(extent, "EPSG:4326", proj);
}
map.getView().fit(extent, map.getSize());
1.因为我做的是多坐标系预览,每次坐标系时,地图实例要设定对应的坐标系,就是setView的那步操作;
2.map实例设定对应的坐标系后,moveend 返回的coordinate做了转换,不必进行二次转换;
参考了此篇 博客.,讲的挺明白,获益匪浅.
到此结束,转载请注明出处,有错误欢迎指教!