最近遇到一个项目,需要将将近2w条围栏数据,快速的绘制到地图上,而且客户的电脑内存只有4g。用传统的svg绘制上地图上,同时渲染页面一下就崩溃了。因此需要以canvas的形式绘制到地图内。接下来我就叙述一下实现的过程。
由于需要一次性加载2w条数据,无法通过接口查询数据库,这会消耗大量的时间请求接口查询数据。因此,最好的方案是直接读取文件的geojson资源。这里用的项目资源是shp2的压缩包。
将文件打包成zip文件,再将资源放到自己的服务器上。
js// url为文件服务器资源
import * as shpUtil from 'shp-geojson';
const geojson = await shpUtil.toGeoJSON(url, undefined, 'gkb', options.crs);
这里可以看官方示例http://mars2d.cn/editor-vue.html?id=layer-graphic/file/geojson-canvas 这里贴出我这里的关键代码(项目不同需要看文档)
js// geojsonData为服务端来的数据,map为mars2d的地图实例
const showData = (geojsonData: any, map: any) => {
const canvasLayer = new L.CanvasGeojsonLayer({
style: {},
onClick: function (features: any, latlng: any) {
if (features.length === 0) {
return
}
let inhtml = "<table>"
const attr = features[0].geojson.properties
for (const col in attr) {
const showval = mars2d.Util.trim(String(attr[col]))
if (showval === null || showval?.toString() === "NaN" || showval === "" || showval === "Null" || showval === "Unknown" || showval === "0" || showval?.length === 0) {
continue
}
inhtml += '<tr> <td style="text-align: right;min-width: 80px;">' + col + ":</td> <td>" + showval + "</td> </tr>"
}
inhtml += "</table>"
const popup = L.popup().setLatLng(latlng).setContent(inhtml).openOn(map)
},
onMouseOver: function (features: any, latlng: any) {
// handle mouseover events
if (features.length === 0) {
return
}
for (let i = 0; i < features.length; i++) {
const properties = features[i].geojson.properties
if (!properties.Color_Old) {
properties.Color_Old = properties.Color
}
properties.Color = "rgba(90, 131, 245, 1)"
}
canvasLayer.render()
},
onMouseOut: function (features: any, latlng: any) {
if (features.length === 0) {
return
}
for (let i = 0; i < features.length; i++) {
const properties = features[i].geojson.properties
properties.Color = properties.Color_Old
}
canvasLayer.render()
}
})
canvasLayer.addTo(map)
canvasLayer.addCanvasFeatures(L.CanvasFeatureFactory(geojsonData))
canvasLayer.render()
return canvasLayer
}
const geojson = await shpUtil.toGeoJSON(url, undefined, 'gkb', options.crs);
for (let i = 0; i < geojson.features.length; i++) {
const feature = geojson.features[i];
// 设置围栏颜色
feature.properties.Color = item.color
}
showData({ ...geojson, type: "FeatureCollection" }, map)
这样就能以canvas的形式绘制到地图内。(数据保密部分打码处理)实现效果:
最终总结
使用其它地图api,也可使用类似的思路,将地图数据改为本地数据,将围栏绘制到地图canvas内部,这种方式是内存消耗小,数据加载快的最有效方案。领导再也不嫌地图资源加载慢了。
本文作者:lsq_137
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!