WMSTileLayer
WMSTileLayer是TileLayer的子类,本质就是通过用户配置一些WMS请求的一些参数,来构造瓦片请求地址
其比较简单,故在这里就不多细说了
WMSTileLayer怎样强制刷新?
由于业务的需要WMSTileLayer的数据可能是动态,业务里期望隔一段时间就去更新WMSTileLayerr的内容,这时就需要去强制刷新WMSTileLayer
js
wmsLayer.forceReload();
WARNING
这个方法会清空图层里缓存的所有图片资源,从新加载的,所以要慎用
怎样避免浏览器的缓存策略
瓦片请求是简单的image get请求,因为浏览器缓存策略的问题,如果瓦片地址一样,会触发浏览器缓存策略, 导致前端并没有真实的再次去请求后台的瓦片,导致显示的瓦片还是上一次的请求的结果,这时就需要我们手动的绕过 浏览器缓存策略
通过给瓦片请求携带个随机参数以此使瓦片的每次请求地址不一样从而绕过浏览器缓存策略
js
const wmsTileLayer = new maptalks.WMSTileLayer("wms", {
tileSystem: [1, -1, -180, 90],
urlTemplate: "https://ahocevar.com/geoserver/wms",
crs: "EPSG:4326",
layers: "topp:states",
styles: "",
version: "1.3.0",
format: "image/png",
transparent: true,
uppercase: true,
});
//generate tile url
wmsTileLayer.getTileUrl = function (x, y, z) {
//replace with your own
//e.g. return a url pointing to your sqlite database
let url = maptalks.WMSTileLayer.prototype.getTileUrl.call(this, x, y, z);
url += `&t=${new Date().getTime()}`;
// console.log(url);
return url;
};
WARNING
该方法无法利用浏览器的缓存策略的,每次都是重新加载同样的资源,用户体验会下降的,业务要要根据自己的图层是否需要 实时刷新来决定是否使用,不可滥用
加载非常用的WMS服务
业务里我们的wms服务可能并不一定是常用的 EPSG:4326
,EPSG:3857
啥的,这时我们怎么加载呢?
- 地图我们还是使用常用的投影(
EPSG:4326
,EPSG:3857
),因为这样是我们使用地图的最佳的方式,方便对接适量切片,3dtile图层啥的 - WMS图层我们也保持和地图的投影一样,在wms瓦片请求时我们 利用proj4动态的将瓦片坐标转换为wms的坐标投影即可
这里以WMS的坐标投影为ESPG:4547
,地图的投影为EPSG:3857
为例子:
TIP
其他的投影可以照葫芦画瓢,比如地图是 EPSG:4326
啊,WMS服务时其他的投影等
js
//define EPSG3857=> EPSG4547
const proj4547 = proj4(
"EPSG:3857",
"+proj=tmerc +lat_0=0 +lon_0=114 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs +type=cr",
);
let wmsTileInstance = new maptalks.WMSTileLayer("base", {
// debug: true,
version: "1.1.1",
request: "GetMap",
format: "image/jpeg",
transparent: true,
exceptions: "application/vnd.ogc.se_inimage",
crs: "EPSG:4547",
uppercase: true,
urlTemplate: "http://121.46.30.137:55030/geoserver/maiwa_yinyingtu/wms",
layers: `maiwa_yinyingtu:59_55`,
// spatialReference: {
// projection: getProjection({
// fromProjection: "EPSG:4326",
// toProjection: "EPSG:4547"
// }),
// resolutions: [
// 156543.03392804097, 78271.51696402048, 9135.75848201024,
// 19567.87924100512, 9783.93962050256, 4891.96981025128,
// 2445.98490512564, 1222.99245256282, 611.49622628141,
// 305.748113140705, 152.8740565703525, 76.43702828517625,
// 38.21851414258813, 19.109257071294063, 9.554628535647032,
// 4.777314267823516, 2.388657133911758, 1.194328566955879,
// 0.5971642834779395, 0.29858214173896974
// ],
// fullExtent: {
// top: 6378137 * Math.PI,
// left: -6378137 * Math.PI,
// bottom: -6378137 * Math.PI,
// right: 6378137 * Math.PI
// }
// },
// bufferPixel: 0
});
function getParamString(obj, existingUrl, uppercase) {
const params = [];
for (const i in obj) {
params.push(
encodeURIComponent(uppercase ? i.toUpperCase() : i) +
"=" +
encodeURIComponent(obj[i]),
);
}
return (
(!existingUrl || existingUrl.indexOf("?") === -1 ? "?" : "&") +
params.join("&")
);
}
//重写wms瓦片请求
wmsTileInstance.getTileUrl = function (x, y, z) {
const res = this.getSpatialReference().getResolution(z),
tileConfig = this._getTileConfig(),
tileExtent = tileConfig.getTilePrjExtent(x, y, res);
const max = tileExtent.getMax(),
min = tileExtent.getMin();
const min1 = proj4547.forward(min.toArray());
min.x = min1[0];
min.y = min1[1];
const max1 = proj4547.forward(max.toArray());
max.x = max1[0];
max.y = max1[1];
const bbox = (
this._wmsVersion >= 1.3 &&
(this.wmsParams.crs === "EPSG:4326" ||
this.wmsParams.crs === "EPSG:4490")
? [min.y, min.x, max.y, max.x]
: [min.x, min.y, max.x, max.y]
).join(",");
const url = this.options.urlTemplate;
return (
url +
// @ts-ignore
getParamString(this.wmsParams, url, this.options.uppercase) +
// @ts-ignore
(this.options.uppercase ? "&BBOX=" : "&bbox=") +
bbox
);
};
const map = new maptalks.Map("map", {
center: [114.51181548, 40.07208582],
zoom: 14,
// spatialReference: {
// projection: 'EPSG:4326'
// }
});
wmsTileInstance.addTo(map);