文章目录
概述
openLayers是一个高性能、功能丰富的库,用于在 Web 上创建交互式地图。本篇基于openlayers@4.6.5编写,主要介绍几种常见图层的创建方法,便于快速上手,如需了解更复杂的地图操作,可查阅官方文档:https://openlayers.org/en/v4.6.5/apidoc/
开发
创建地图元素,需指定宽高
<div id="emap" class="map"></div>
绑定ol地图
initOLMapGD() {
return new Promise(resolve => {
let layer = new ol.layer.Tile({
name: 'defaultMap', // 图层名
source: new ol.source.XYZ({
url: 'https://webrd01.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=7&x={x}&y={y}&z={z}' // 在线地图地址,此处为高德
})
})
resolve(layer)
})
},
this.initOLMap().then(res => {
let layers = [res]; // 图层 Array
let projection = new ol.proj.Projection({
code: 'EPSG:4326', // 地图投影
units: 'degrees' // 单位,度
});
this.map = new ol.Map({
layers: layers, // 图层 Array
target: 'emap', // 地图元素的id
view: new ol.View({
center: [118.05640564941875, 24.591312216796875], // 地图初始中心
projection: projection, // 地图投影及单位配置
zoom: 18, // 地图初始层级
maxZoom: 24, // 地图最大层级
minZoom: 12 // 地图最小层级
})
});
// 之后再用 this.map.addLayer(layer) 挂其他图层
})
添加图层
普通的点位图层
// 站点图层
initSiteLayer(data) {
return new Promise(resolve => {
let features = [] // 点位数据
if(data) {
// 从data中构建点位数组
for(let i=0; i<data.length; i++) {
if(data[i].lat && data[i].lng) {
let coordinates = [data[i].lng, data[i].lat] // 点位经纬度
let feature = new ol.Feature(new ol.geom.Point(coordinates) // 创建点位
// 设置点位详细数据
feature.setProperties({
name: 'site',
id: data[i].id,
})
features.push(feature)
}
}
// 数据源
let source = new ol.source.Vector({
features: features,
})
// 图层
let layer = new ol.layer.Vector({
name: 'siteLayer',
source: source,
style: function () { // 点位样式
let style = new ol.style.Style({
image: new ol.style.Icon({
src: require('@/assets/images/emap/site.png')
})
})
return style;
}
})
resolve(layer)
}
})
}
点线图层(轨迹)
// points 轨迹点位
initTrackLayer(points) {
return new Promise(resolve => {
let route = new ol.geom.LineString(points) // 将点位连接起来
let features = []
for(let i=1; i<points.length-1; i++) {
features.push(new ol.Feature({
type: 'feature',
geometry: new ol.geom.Point(points[i])
}))
}
let source = new ol.source.Vector({
features: [
new ol.Feature({
type: 'route',
geometry: route // 路径连线
}),
...features, // 点位
new ol.Feature({
type: 'feature',
geometry: new ol.geom.Point(route.getFirstCoordinate()), // 起点
}),
new ol.Feature({
type: 'feature',
geometry: new ol.geom.Point(route.getLastCoordinate()), // 终点
})
],
})
let layer = new ol.layer.Vector({
name: 'customLayer',
source: source,
style: function (feature) {
let style = null
switch (feature.get("type")) {
case 'route':
style = new ol.style.Style({
stroke: new ol.style.Stroke({
width: 12,
color: '#466ee2',
// lineDash: [8, 10],
// linedash:数组中下标是奇数的元素是虚线小段的尺寸,下标是偶数的元素则是虚线小段之间的间距
}),
})
break;
default:
break;
}
return style;
}
})
resolve(layer)
})
}
wms图层,获取GEOServer服务数据
initWMSLayer() {
return new Promise(resolve => {
let params = {
'LAYERS': 'ebike:electric_fence_geoinfo', // 服务发布的图层名
'VERSION': '1.1.0', // 服务发布的图层版本
// 'CQL_FILTER': `fence_code=${id}` // 图层数据筛选
}
this.wmsSource = new ol.source.TileWMS({
url: location.origin + '/geoserver/ebike/wms', // 服务地址
params: params,
serverType: 'geoserver'
})
let layer = new ol.layer.Tile({
name: 'fenceLayer', // 图层名
source: this.wmsSource // 数据源
});
resolve(layer)
})
},
wfs聚合图层
url字段说明:
request:GetFeature,请求数据类型
typeName:ebike:share_cycle_current,图层名称
outputFormat:application/json,输出格式
srsname:EPSG:4326,地图投影
CQL_FILTER:bike_status=1,筛选条件(不能与bbox一起使用,需要可使用filter)
initOLWFSLayer() {
return new Promise(resolve => {
// 设置wfs数据源
let vectorSource = new ol.source.Vector({
format: new ol.format.GeoJSON(), // 数据源格式
url: function (extent, resolution, projection) {
let proj = projection.getCode(); // 地图投影类型
return location.origin + `/geoserver/ebike/ows?service=WFS&version=1.1.0&request=GetFeature&typeName=ebike%3Ashare_cycle_current&outputFormat=application%2Fjson&srsname=${proj}&bbox=${extent.join(',') + ',' + proj}` // 图层数据链接
},
strategy: ol.loadingstrategy.bbox, // 根据当前展示的地图范围加载
});
// 将点位数据源汇聚成聚合的数据源
let source = new ol.source.Cluster({
source: vectorSource,
geometryFunction: function(feature) {
return feature.getGeometry();
},
distance: 100 // 聚合距离
})
let cluser = new ol.layer.Vector({
name: 'carLayer',
source: source,
style: function (feature) {
// 可以根据点位详细信息设置不同样式
let size = feature.get('features').length;
let style = new ol.style.Style({
image: new ol.style.Circle({
radius: 18,
stroke: new ol.style.Stroke({
color: 'white',
width: 2
}),
fill: new ol.style.Fill({
color: '#466ee2'
})
}),
text: new ol.style.Text({
// 当聚合的点位超过99个,展示99+
text: size > 99 ? '99+' : size.toString(),
fill: new ol.style.Fill({
color: '#fff'
})
})
})
return style;
}
})
resolve(cluser)
// 点位结束
})
}
WKT点位(POI)
// item.position = POINT(118.24 24.05)
let feature = new ol.format.WKT().readFeature(item.position)
feature.setProperties({
...item,
id: item.bikeId,
type: 'forbid-car',
})
操作图层
wms数据刷新
layer.getSource().updateParams({"time": Date.now()})
wfs聚合数据刷新
拿到最底层的数据源进行刷新
// 清除缓存
layer.getSource().getSource().clear()
// 重新加载
layer.getSource().getSource().refresh()
监听地图缩放和移动事件
this.map.on('moveend', () => {
// 获取当前地图的缩放级别
let zoom = this.map.getView().getZoom()
// 进行操作
})
只监听层级缩放
this.map.getView().on("change:resolution", () => {
// 获取当前地图的缩放级别
let zoom = this.map.getView().getZoom()
// 进行操作
});
地图弹窗
this.popup = new ol.Overlay({
element: document.getElementById('popup'),
positioning: 'bottom-center', // 相对于其位置属性的实际位置
stopEvent: true, // 事件冒泡,设为true时在弹窗内点击不会触发地图事件
});
this.map.addOverlay(this.popup);
F&Q
当页面进行缩放时地图盒子大小发生变化,但地图内容没有进行相应的变化或者空白
使用map.updateSize()
方法手动对地图进行缩放
地图中心设置为某经纬度后,地图空白
检查该经纬度数据是否正常
在控制筛选图层内部分点位显隐时加载慢
将点位以显隐条件进行区分,分开几个图层,只针对图层的显隐进行控制而不是重新筛选数据