作者:yangjl
前言
最近还是有很多小伙伴们,一遇到非wgs84坐标的ugcv5或mvt切图瓦片发布的地图服务,便不能对接出图了,或者是出了图但是看着地图边界比较模糊。今天我在这里讲干货,让小伙伴们能快速的对接出图,让小伙伴不用为不会填写origin,resolution,scales,tilegrid等等参数而苦恼了。对于非epsg3857,4326的坐标系的地图服务,是需要利用proj4插件的,因为前文已有同事做个详细的说明,本章就不再赘述,感兴趣的同学可参考
https://blog.csdn.net/supermapsupport/article/details/88967390
此次我用epsg:4525坐标系的地图切ugcv5和mvt缓存,发布成地图服务,进行iClient for OpenLayers产品的对接,过程中讲述如何快速对接出图的方法。
使用proj4
完整包中已带有在线的proj4库,直接在代码第一行粘贴上面复制即可。
对接ugcv5
ugcv5的对接方式,其实非常的简单。当然你需要拿到地图服务的extent,center,origin,tilegrid,zoom等参数。很多小伙伴明白其含义但是往往不知道如何去获取参数,其实我们的iClient For OpenLayer提供了相关获取map信息以及瓦片信息的接口,但是往往被不太熟悉我们的产品的小伙伴所忽略。接口名称:ol.supermap.MapService,感兴趣的同学可以查看,此接口提供了getMapInfo以及getTilesets方法。话不多说,直接上代码,直接把需要的参数给拿出来。
function getMapInfo(url){
var needInfo={};
return new Promise(function(resolve){
new ol.supermap.MapService(url).getMapInfo(function (serviceResult) {
var mapJSONObj=serviceResult.result;
var tileInfo=ol.source.TileSuperMapRest.optionsFromMapJSON(url, serviceResult.result);
console.log(tileInfo)
var bounds=mapJSONObj.bounds;
needInfo.center=[mapJSONObj.center.x,mapJSONObj.center.y];
needInfo.extent=[bounds.left,bounds.bottom,bounds.right,bounds.top];
needInfo.origin=tileInfo.tileGrid.g;
needInfo.tileGrid=tileInfo.tileGrid;
resolve(needInfo);
})
})
};
是不是很简单的就获取出参数了,只要有地图的url不管在哪直接复制代码直接拿出对接ugcv5的参数信息。拿到了这些个参数,剩下的实现就更加简单了,更具官网例子对接出图即可,如下文所示:
async function loadLayer(){
proj4.defs("EPSG:4525","+proj=tmerc +lat_0=0 +lon_0=111 +k=1 +x_0=37500000 +y_0=0 +ellps=GRS80 +units=m +no_defs");
var infoone=await getMapInfo(url);
var projection = new ol.proj.Projection({
code:"EPSG:4525",
extent: infoone.extent,
});
var map = new ol.Map({
target: 'map',
view: new ol.View({
center: infoone.center,
zoom: infoone.minZoom,
projection: projection,
origin:infoone.origin
})
});
var layer = new ol.layer.Tile({
source: new ol.source.TileSuperMapRest({
url:url,
tileGrid:infoone.tileGrid,
})
});
map.addLayer(layer);
}
loadLayer()
对接mvt矢量瓦片
一般我们对接矢量瓦片时后是参考这个官网的例子的。
https://iclient.supermap.io/examples/openlayers/editor.html#mvtvectorlayer_mbstyle_landuse
如果我们仔细看下该示例,相比对接ugcv5瓦片的时候,无非是多了resolutions,tileType,以及format这三个参数。官网的例子中给出了一个如何解算resolution的函数,其原理就是以dpi96为准,通过某一级zoom以及相应的比例尺(可通过sci文件查看)得到出每个层级的分辨率。感兴趣的同学可以再网上搜索下根据分辨率与比例尺之间的相互转换。但今天的主题既然是快速的对接,那肯定是用最简单的方法来获取剩下需要的resolutions,tileType,以及format这三个参数。其方法如下,打开iserver预览mvt的页面,用谷歌浏览器,打开console控制台,再其中复制以下代码,因map为全局量,便可直接获取加载其中的layer的source属性,其中便有我们需要的全部参数。
map.values_.layergroup.values_.layers.array_[+""+0+""].state_.layer.values_.source
如果resolution过长不好复制,可以
右击该量,然后点击红框,存为全局量
即可拿到,然后复制到你的代码中即可。比起对接ugcv5,不过多用了一个接口ol.supermap.MapboxStyles和上述三个参数,其他使用方式都一致。附上代码:
var url ="http://localhost:8090/iserver/services/map-mvt-4525mvt/rest/maps/4525mvt";
function getMapInfo(url){
var needInfo={};
return new Promise(function(resolve){
new ol.supermap.MapService(url).getMapInfo(function (serviceResult) {
var mapJSONObj=serviceResult.result;
var tileInfo=ol.source.TileSuperMapRest.optionsFromMapJSON(url, serviceResult.result);
var bounds=mapJSONObj.bounds;
needInfo.center=[mapJSONObj.center.x,mapJSONObj.center.y];
needInfo.extent=[bounds.left,bounds.bottom,bounds.right,bounds.top];
needInfo.origin=tileInfo.tileGrid.g;
needInfo.tileGrid=tileInfo.tileGrid;
needInfo.minZoom=tileInfo.tileGrid.minZoom;
needInfo.maxZoom=tileInfo.tileGrid.maxZoom;
resolve(needInfo);
})
})
};
async function loadLayer(){
var res=[39070.17862981005, 19535.089314905024, 9767.544657452512, 4883.772328726256, 2441.886164363128, 1220.943082181564, 610.471541090782, 305.235770545391, 152.6178852726955, 76.30894263634775, 38.154471318173876, 19.077235659086938, 9.538617829543469, 4.7693089147717345, 2.3846544573858672, 1.1923272286929336, 0.5961636143464668, 0.2980818071732334, 0.1490409035866167, 0.07452045179330835, 0.037260225896654176, 0.018630112948327088];
proj4.defs("EPSG:4525","+proj=tmerc +lat_0=0 +lon_0=111 +k=1 +x_0=37500000 +y_0=0 +ellps=GRS80 +units=m +no_defs");
var infoone=await getMapInfo(url);
console.log(infoone,"infoone")
var projection = new ol.proj.Projection({
code:"EPSG:4525",
extent: infoone.extent,
});
console.log(projection,"projection")
var map = new ol.Map({
target: 'map',
view: new ol.View({
center: infoone.center,
zoom: infoone.minZoom,
projection: projection,
origin:infoone.origin,
resolutions:res
})
});
var style = new ol.supermap.MapboxStyles({
map: map,
url: url,
// source: 'landuse',
resolutions: res
})
style.on('styleloaded', function () {
var vectorLayer = new ol.layer.VectorTile({
//设置避让参数
declutter: true,
source: new ol.source.VectorTileSuperMapRest({
url: url,
projection: projection,
tileGrid: infoone.tileGrid,
tileType: 'ScaleXY',
format: new ol.format.MVT()
}),
style: style.getStyleFunction()
});
map.addLayer(vectorLayer);
})
}
loadLayer()
结语
本次文章主要目的是让小伙伴能学会快速拿到对接ugcv5,mvt的一系列相关参数,主要通过两种方式。1.通过ol.supermap.MapService接口拿到extent,center,origin,tilegrid,zoom等参数2.在iserver可以预览出mvt的情况下,直接在谷歌console拿到加载到map中的mvtlayer的属性,从而拿到resolutions,tileType,以及format这三个参数。