Vue.js2+OpenLayers6 八、聚合

Vue.js2+OpenLayers6 八、聚合

Demo

Github

示例

<template>
	<div id="map-container" style="width:100%;height:100%;">
		<div style="position:absolute;right:50px;top:50px;z-index:999;">
			<button @click="addClusterLayer(clusterData)">聚合</button>
			<button @click="removeLayerByName('聚合图层')">清除</button>
		</div>
	</div>
</template>
<script>
import 'ol/ol.css'
import Map from 'ol/Map'
import View from 'ol/View'
import TileLayer from 'ol/layer/Tile'
import OSM from 'ol/source/OSM'
import { defaults as defaultControls } from 'ol/control'
import ZoomSlider from 'ol/control/ZoomSlider'
import OlFeature from 'ol/Feature'
import OlGeomPoint from 'ol/geom/Point'
import OlSourceVector from 'ol/source/Vector'
import OlLayerVector from 'ol/layer/Vector'
import OlStyleStyle from 'ol/style/Style'
import OlStyleFill from 'ol/style/Fill'
import OlStyleStroke from 'ol/style/Stroke'
import OlStyleCircle from 'ol/style/Circle'
import OlStyleText from 'ol/style/Text'
import { Cluster } from 'ol/source'

export default {
	name: '',
	data() {
		return {
			// 聚合数据
			clusterData: [
				{
					name: '1',
					coordinates: [116.40182752977934, 39.92476619935702],
				},
				{
					name: '2',
					coordinates: [116.42764915596571, 39.949683921105375],
				},
				{
					name: '3',
					coordinates: [116.48107607733336, 39.88376327014636],
				},
				{
					name: '4',
					coordinates: [116.43154238235083, 39.94546346522044],
				},
				{
					name: '5',
					coordinates: [116.40311901342001, 39.92316223836612],
				},
				{
					name: '6',
					coordinates: [116.40436524149327, 39.92102890235143],
				},
			],
			map: null,
		}
	},
	mounted() {
		this.initMap()
	},
	methods: {
		/**
		 * @name: 鼠标悬浮改变聚合图标样式
		 */
		pointerMove() {
			const _this = this
			_this.map.on('pointermove', evt => {
				_this.map.getTargetElement().style.cursor = _this.map.hasFeatureAtPixel(evt.pixel)
					? 'pointer'
					: ''
			})
		},

		/**
		 * @name: 设置聚合图标样式
		 */
		setClusterStyle() {
			return feature => {
				const size = feature.get('features').length
				let color = ''
				if (size === 1) {
					color = 'green'
				} else if (size === 2) {
					color = 'yellow'
				} else {
					color = 'red'
				}
				const style = new OlStyleStyle({
					image: new OlStyleCircle({
						radius: 15,
						stroke: new OlStyleStroke({
							color: '#fff',
						}),
						fill: new OlStyleFill({
							color: color,
						}),
					}),
					text: new OlStyleText({
						text: size.toString(),
						fill: new OlStyleFill({
							color: '#000',
						}),
						stroke: new OlStyleStroke({
							color: '#fff',
							width: 5,
						}),
					}),
				})
				return style
			}
		},

		/**
		 * @name: 添加聚合图层
		 * @param {data} Array 聚合数据
		 * @return {type}
		 */
		addClusterLayer(data) {
			const _this = this
			const source = new OlSourceVector()
			const clusterSource = new Cluster({
				distance: parseInt(20, 10),
				source: source,
			})
			const layer = new OlLayerVector({
				source: clusterSource,
				style: _this.setClusterStyle.call(_this),
				name: '聚合图层',
				zIndex: 9,
			})
			_this.map.addLayer(layer)
			for (let i = 0; i < data.length; i++) {
				const coordinates = data[i].coordinates
				const feature = new OlFeature({
					geometry: new OlGeomPoint(coordinates),
				})
				feature.set('name', data[i].name)
				feature.set('value', data[i].value)
				feature.set('type', 'cluster')
				source.addFeature(feature)
				layer.getSource().addFeatures(feature)
			}
			_this.pointerMove()
		},

		/**
		 * @name: 根据图层名移除图层
		 * @param {layername} 图层名称
		 */
		removeLayerByName(layerName) {
			this.getLayerByName(layerName)
			const layer = this.getLayerByName(layerName)
			layer.forEach(item => {
				this.map.removeLayer(item)
			})
		},

		/**
		 * @name: 根据图层名获取图层
		 * @param {layerName} 图层名称
		 */
		getLayerByName(layerName) {
			const allLayers = this.getAllLayers()
			const layer = allLayers.filter(item => {
				return item.get('name') === layerName
			})
			return layer
		},

		/**
		 * @name: 获取所有图层
		 */
		getAllLayers() {
			const layers = this.map.getLayers().getArray()
			return layers
		},

		/**
		 * @name: 地图单击事件
		 */
		singleClickFun() {
			this.map.on('singleclick', event => {
				console.log(event)
			})
		},

		/**
		 * @name: 初始化地图
		 */
		initMap() {
			const view = new View({
				projection: 'EPSG:4326',
				center: [116.395645038, 39.9299857781],
				zoom: 12,
			})
			const layer = new TileLayer({
				source: new OSM(),
				visible: true,
				zIndex: 1,
				name: 'OSM',
			})
			this.map = new Map({
				layers: [],
				target: 'map-container',
				view: view,
				controls: defaultControls().extend([new ZoomSlider()]),
			})
			this.map.addLayer(layer)
			this.singleClickFun()
		},
	},
}
</script>
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值