leaflet 移动端h5地图开发(一) 点聚合&矢量瓦片(附项目代码和数据)
leaflet是一个轻量级的GIS前端框架,支持多种GIS服务(wfs,wms,wmts,arcgis mapserver,mvt矢量切片)。但是leaflet不支持三维,如果不考虑三维的话,leaflet是做移动端h5地图很好的选择。
技术栈
前端 : vue (uniapp) +leaflet
GIS服务器:geoserver
案例项目界面效果(仿高德):
在线预览地址:http://magic1412.gitee.io/h5_leaflet/#/
一、加载点marker,并添加点击事件
运用到markercluster插件实现点的聚合效果
插件地址:https://github.com/Leaflet/Leaflet.markercluster
封装请求wfs服务的函数
requestWFSData = (opts) => {
return new Promise(
(resolve, reject) => {
var urlString = opts.root + '/wfs'
var param = {
service: 'WFS',
version: '1.0.0',
request: 'GetFeature',
typeName: opts.layerId,
outputFormat: 'application/json',
maxFeatures: 3200,
srsName: 'EPSG:4326',
}
if (opts.cql_filter) param.CQL_FILTER = opts.cql_filter
axios.get(urlString + L.Util.getParamString(param, urlString)).then(
res => {
if (res.data) {
resolve(res)
} else {
reject('请求wfs错误')
}
}
)
}
)
}
将返回的点json,遍历实例化成marker,添加点击事件后,添加至markerClusterGroup中
addMakerLayer = (opts) => {
this.requestWFSData(opts).then(
res => {
if (res.data.features.length > 0) {
this._layerDict[opts.layerId] = L.markerClusterGroup({
spiderfyOnMaxZoom: false,
showCoverageOnHover: false,
zoomToBoundsOnClick: false
}).addTo(this._map)
res.data.features.forEach(
f => {
var c = f.geometry.coordinates
var title = f.properties[opts.idField]
var marker = L.marker(new L.LatLng(c[0][1], c[0][0]))
marker.on('click', evt => {
this._map.flyTo(evt.latlng, 16)
})
marker.bindPopup(title.toString())
this._layerDict[opts.layerId].addLayer(marker)
}
)
}
}
)
}
二、加载矢量瓦片
使用Leaflet.VectorGrid插件加载geoserver矢量瓦片
插件地址:https://github.com/Leaflet/Leaflet.VectorGrid
addVectorTileLayer = (opts) => {
this._layerDict[opts.layerId] = L.vectorGrid.protobuf(opts.url, {
rendererFactory: L.canvas.tile,
tms: true,
interactive: true,
vectorTileLayerStyles: opts.vectorTileLayerStyles
}).addTo(this._map)
}
实现点击矢量瓦片跳转页面
定义个list,初始化图层时,存储图层信息。
addToClickSearchList = (opts) => {
this._clickSearchList.push({
root: opts.root, //wfs服务根地址
layerId: opts.layerId, //图层id
idField: opts.idField, //id字段
crs: opts.crs,//坐标系
added: true //是否
})
}
遍历list,构造crs(坐标系) 和 cql_filter (筛选条件) 参数
getClickFeatrue = (pt) => {
if (this._clickSearchList.length === 0) return
if (document.getElementById("popup")) document.getElementById("popup").remove()
var content = '<a id="popup" style="text-decoration: underline;cursor: pointer;">'
this._clickSearchList.forEach(
l => {
if (l.added) {
var cpt
if (l.crs === 'EPSG:4326') cpt = L.CRS.EPSG4326.project(pt)
if (l.crs === 'EPSG:3857') cpt = L.CRS.EPSG3857.project(pt)
l.cql_filter = 'INTERSECTS(geom,POINT(' + cpt.x + ' ' + cpt.y + '))'
this.requestWFSData(l).then(
res => {
if (res.data.features.length !== 0) {
var geoObj = L.geoJSON(res.data)
content += res.data.features[0].properties[l.idField] + '</a>'
this._clickResLayer = geoObj.addTo(this._map)
geoObj.bindPopup(content).openPopup()
}
}
)
}
}
)
}
三、案例数据
疫情数据:
来源于腾讯疫情小区地图,原接口已不能用,现在的地址是
https://map.wap.qq.com/app/mp/online/h5-epidemic-20200203/OutMapDetail.html?hideBrowserTitle=1
上海小区边界和学校边界(国测局/高德坐标)
扫描关注 “GIS攻城狮” 公众号,回复”上海小区学校边界“,获取数据数据百度云链接
四、案例项目代码
https://gitee.com/magic1412/h5_leaflet