背景:得到一个地图服务,wms,坐标系EPSG是4509,如何加载到cesium和openlayer上呢?
先上图
实现思路:
openlayer中利用proj4对坐标系进行设置,配置整个map的投影
proj4.defs(
'EPSG:4509',
'+proj=tmerc +lat_0=0 +lon_0=117 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs +type=crs'
);
register(proj4);
const projection = new Projection({
code: 'EPSG:4509',
extent: [108195, 1048459, 908195, 9048459],
});
layers.push(
//绿色地形
new TileLayer({
source: new TileWMS({
url: 'http://*******/geoserver/Tiff/wms',
params: {
SERVICE: 'WMS',
VERSION: '1.1.0',
REQUEST: 'GetMap',
FORMAT: 'image/png',
TRANSPARENT: true,
LAYERS: 'Tiff:'+terrainArray[i],
WIDTH: 256,
HEIGHT: 256,
SRS: 'EPSG:4509',
},
ratio: 1,
serverType: 'geoserver',
}),
})
);
const map = new Map({
controls: defaultControls().extend([new ScaleLine()]),
layers: layers,
target: 'map',
view: new View({
projection: projection,
center: fromLonLat([117.0148998624, 36.6688142975], projection),
zoom: 10,
}),
});
cesium中比较特别,虽然本质也是用proj4进行了转换,但是cesium自带的wmsprivder是无法对bbox的每次请求做出修改的,都会发送经纬度。因此采用UrlTemplateImageryProvider自定义了根据xyzoom进行转换成4509坐标的数值。
var imageryProvider = new Cesium.UrlTemplateImageryProvider({
url: '****/geoserver/Tiff/wms?service=WMS&version=1.1.0&request=GetMap&format=image%2Fpng&transparent=true&' +
'layers=Tiff%3A'+terrainArray[i]+'&width=256&height=256&' +
'srs=EPSG%3A4509&bbox={wsen}&styles=',
customTags: {
wsen: function (imageryProvider, x, y, zoom) {
var lon = (x/Math.pow(2,zoom)*360-180);
var n=Math.PI-2*Math.PI*y/Math.pow(2,zoom);
var lat = (180/Math.PI*Math.atan(0.5*(Math.exp(n)-Math.exp(-n))));
var lonMax = ((x+1)/Math.pow(2,zoom)*360-180);
var nMax=Math.PI-2*Math.PI*(y+1)/Math.pow(2,zoom);
var latMax = (180/Math.PI*Math.atan(0.5*(Math.exp(nMax)-Math.exp(-nMax))));
//console.log({ lon: lon, lat: lat, lonMax: lonMax, latMax: latMax });
var epsg4509WSCoords = proj4('WGS84', epsg4509, [lon, lat]);
var epsg4509ENCoords = proj4('WGS84', epsg4509, [lonMax, latMax]);
console.log("" + epsg4509WSCoords[0] + "," + epsg4509WSCoords[1] + "," + epsg4509ENCoords[0] + "," + epsg4509ENCoords[1]);
return "" + epsg4509WSCoords[0] + "," + epsg4509ENCoords[1]+ "," + epsg4509ENCoords[0] + "," +epsg4509WSCoords[1] ;
}
}
});
var imageryLayer = new Cesium.ImageryLayer(imageryProvider);
viewer.imageryLayers.add(imageryLayer);
ps:terrainArray是个图层的数组 不用介意。
cesium中有个问题待解决,就是缩放到全国范围瓦片会有一些偏差,和计算出来的bbox有关,可以尝试设置最小level