openLayer基本使用

本文介绍了如何使用openLayers4.6.5在Web上创建地图,包括地图元素的设定、各种图层(点位、线、WMS、WFS聚合)的添加、数据刷新、地图事件监听以及解决地图空白和性能问题的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

概述

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()方法手动对地图进行缩放

地图中心设置为某经纬度后,地图空白

检查该经纬度数据是否正常

在控制筛选图层内部分点位显隐时加载慢

将点位以显隐条件进行区分,分开几个图层,只针对图层的显隐进行控制而不是重新筛选数据

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值