前言
项目近期有个全省的降雨等值面展示任务交到我手上,功能实现使用的是基于超图的openlayer表面分析服务,功能实现后自觉全省的数据量较大,对性能有些要求而且要调用超图iserver发布的服务,有些情况下不便实现,联想到三年前实践过的克里金(Kriging)插值,便想着把了解到的实现方法做个总结,于是就有了这篇文章。
主要使用vue3、supermap、openlayer、leaflet、kriging、proj等,对应版本信息如下:
"@supermapgis/iclient-leaflet": "^11.2.1",
"@supermapgis/iclient-ol": "^11.2.0",
"proj4": "^2.12.1",
"proj4leaflet": "^1.0.2",
"vue": "^3.5.4",
二维地图的实现是用的超图发布的openlayer和leaflet,这两者也是目前较为流行的二维地图框架:openlayer地图功能丰富全面;leaflet则较为轻量,上手简单。这里不做过多介绍,本文介绍openlayer和leaflet,如何分别使用超图服务和克里金自行计算来实现等值线、面的展示。
1.openlayer
以下是地图初始化代码,对应天地图的token,可以去超图官网的案例中获取,也可以去天地图官网自行申请。不做过多描述:
let map = new Map({
target: "dzmdiv",
controls: defaultControls({ attribution: false, zoom: true, rotate: true }),
view: new View({
center: [117,37],
zoom: 6,
minZoom: 2,
maxZoom: 18,
projection:"EPSG:4326",
multiWorld: true
})
});
let tiandituChina_vec = new TileLayer({
zIndex: 2,
source: new Tianditu({
url: "http://t0.tianditu.gov.cn/vec_c/wmts?tk=你的token",
layerType: 'img',
projection: "EPSG:4326"
}),
visible: true
});
map.addLayer(tiandituChina_vec);
引入对应的ol.css运行之后,得到一份初始的影像地图,具体地图样式可以自行调整css进行设置:
1.1 openlayer+超图iserver
下面进行等值面的处理,图层颜色区间可以根据时间业务需求进行调整修改:
// 格式 [{
// "DRP" : 7.4,
// "LGTD" : 119.11,
// "LTTD" : 37.43
// },
// {}]
let newData = 需要进行等值面分析的数据;
let points = [];
let zValues = [];
let interval= [0, 10, 25, 50, 100, 250];//等值面的区间,这里使用的的降雨值数据
//设置图层样式,后面用到zvalue
let layer = new VectorLayer({
style: function (feature: any) {
let cl = feature.get('zvalue');
let clor = 'rgba(255, 255, 255, 0)';
if (cl == '0') {
clor = 'rgba(112,128,144, 1)';
}
if (cl == '1') {
clor = '#88F693'
}
if (cl == '2') {
clor = '#00BA47'
}
if (cl == '3') {
clor = '#00B6F9'
}
if (cl == '4') {
clor = '#0007F8'
}
if (cl == '5') {
clor = '#FF00F3'
}
if (cl == '6') {
clor = '#91003A'
}
return new Style({
stroke: new Stroke({
color: clor,
width: 1
}),
fill: new Fill({
color: clor,
// color: "white"
}),
})
},
opacity: 0.6
});
//推荐使用forof newData中[{
// "DRP" : 7.4,
// "LGTD" : 119.11,
// "LTTD" : 37.43
// },]
for (let i = 0; i < newData.length; i++) {
let obj = newData[i];
let drp = obj.DRP;
if (drp == '') {
drp = 0;
}
if (drp != null && obj.LGTD != null && obj.LTTD != null) {
zValues.push(drp * 1);
//经纬度转至xy
let m_center = transform([obj.LGTD, obj.LTTD], 'EPSG:4326', 'EPSG:3857');
let geometry = new Point(m_center);
points.push(geometry)
}
}
//设置裁剪面格式如下
// [[[114.73, 38.02],[114.73, 34.59],[122.64,