OpenLayers 百万点位撒点
文章目录
- OpenLayers 百万点位撒点
- 一、解决方案
- 二、使用步骤
- 1.引入库
- 2.html代码
- 3.js代码
提示:下面案例可供参考
一、解决方案
设置网格,把地图切分成不同网格,在zoon 视图放大到一定程度,进行视图大小获取点位撒点
二、使用步骤
1.引入库
代码如下(示例):
import 'ol/ol.css'
import { Map, View } from 'ol'
import Tile from 'ol/layer/Tile'
// import OSM from "ol/source/OSM";
import { Style, Circle, Stroke, Fill, Text, Icon } from 'ol/style'
import layerVector from 'ol/layer/Vector'
import sourceVector from 'ol/source/Vector'
import Cluster from 'ol/source/Cluster'
import XYZ from 'ol/source/XYZ'
import { get as getProjection } from 'ol/proj'
import { getWidth } from 'ol/extent'
import Point from 'ol/geom/Point'
import Feature from 'ol/Feature'
import { defaults } from 'ol/interaction'
import Overlay from 'ol/Overlay'
import { getbmapData, getsmapData, getpointData } from '@/api/api.js'
2.html代码
代码如下(示例):
<template>
<div class="vm">
<div id="map" class="map-x"></div>
</div>
</div>
</template>
3.js代码
代码如下(示例):
data() {
return {
map: null,
popup: null,
isPopup: false,
clusterSource: null,
points: [],
clusterData: [],
list:[],
mixzoom: true,
maxzoom: true,
zoomfont: true,
ismovezoom: 0,
ismovezoomend: 0,
systemId: '',
openhx: true,
fullAddr: '',
dycxsxmc: '',
orgName: '',
qu: '',
}
},
mounted() {
// 初始化 地图
this.initMap()
// this.addFeatures()
this.getbmapData()
// 初始化 新增聚合点
this.addCluster(this.clusterData, this.points)
},
methods: {
//节流
debounce (func, delay = 1000, immediate = false) {
//闭包
let timer = null
//不能用箭头函数
return function () {
if (timer) {
clearTimeout(timer)
}
if (immediate && !timer) {
func.apply(this,arguments)
}
timer = setTimeout(() => {
func.apply(this,arguments)
}, delay)
}
},
openhxbox() {
this.$emit('openhxfun', { systemId: this.systemId, openhx: this.openhx, fullAddr: this.fullAddr })
},
// 不同值,返回不同颜色
getColor(val) {
if (val < 10) return 'mix'
else if (val >= 10 && val < 200) return 'mid'
else if (val >= 200) return 'max'
},
initMap() {
var projection = getProjection('EPSG:4326')
var projectionExtent = projection.getExtent()
var size = getWidth(projectionExtent) / 256
var resolutions = []
var matrixIds = []
for (var z = 0; z < 21; ++z) {
resolutions[z] = size / Math.pow(2, z)
matrixIds[z] = z
}
// 地图地址
var dzdt_xyz_Url = window._CONFIG['bigMapURL'] // 在 index.html 文件中设置
//电子地图图层XYZ方式
var dzdtXYZlayer = new Tile({
source: new XYZ({
url: dzdt_xyz_Url,
//crossOrigin: 'anonymous',
projection: 'EPSG:4326',
}),
visible: true,
})
this.map = new Map({
target: 'map',
layers: [dzdtXYZlayer],
view: new View({
// center: [0, 0],
center: [120.440239, 36.103322], // 中心点位置 全国地市
projection: projection,
zoom: 10, // 显示的缩放大小
maxZoom: 20, // 最大缩放
minZoom: 6, // 最小缩放
}),
interactions: defaults({
doubleClickZoom: false, // 取消双击放大功能交互
}),
})
// 监听放大缩小
this.map.getView().on('change:resolution', this.checkZoom)
this.map.getView().on('change:center', this.checkcenter)
// 点击地图展示弹窗
this.popup = new Overlay({
element: document.getElementById('popup'),
positioning: 'center-left', //相对于其位置属性的实际位置
stopEvent: true, //事件冒泡
})
// this.map.addOverlay(this.popup) // 新增元素
this.map.on('singleclick', (evt) => {
// 增加点击事件
// this.clickMap(evt)
})
},
clusterlouStyle() {
return (feature) => {
var total = 0
feature.get('features').forEach((value) => {
total += value.get('value') // 获取显示的值 用来聚合
})
var src = ''
var offsetY = 0
var style = new Style({
image: new Icon({
anchor: [0.5, 46],
anchorOrigin: 'top-lefttop-right',
anchorXUnits: 'fraction',
anchorYUnits: 'pixels',
src: `${window.location.origin}/lou.png`,
}),
})
return style
}
},
//设置聚合样式
clusterStyle() {
return (feature) => {
var total = 0
feature.get('features').forEach((value) => {
total += value.get('value') // 获取显示的值 用来聚合
})
var src = ''
var offsetY = 0
if (total < 2) {
src = `${window.location.origin}/mix.png`
offsetY = 23
} else if (total >= 2 && total < 3) {
src = `${window.location.origin}/mid.png`
offsetY = 48
} else if (total >= 3) {
src = `${window.location.origin}/max.png`
offsetY = 53
}
var style = new Style({
image: new Icon({
anchor: [0.5, 46],
anchorOrigin: 'top-lefttop-right',
anchorXUnits: 'fraction',
anchorYUnits: 'pixels',
src: src,
}),
text: new Text({
text: total.toString(), // 中心点显示的内容
offsetY: offsetY,
fill: new Fill({
// 文字内的颜色
color: '#FFF',
}),
textAlign: 'center',
font: '32px Calibri,sans-serif',
stroke: new Stroke({
// 文字得到边框的颜色
color: 'red',
width: 5,
}),
}),
})
return style
}
},
//移除聚合标注
removeFeatures() {
this.clusterSource.getSource().clear() //移除聚合标注数据源中的所有要素
this.map.removeLayer(this.layer) //移除标注图层
},
//添加聚合标注
addFeatures() {
// console.log(this.clusterSource)
var currentFeatures = this.clusterSource.getSource().getFeatures()
// //如果聚合标注数据源中没有要素,则重新添加要素
if (currentFeatures.length == 0) {
this.addCluster(this.clusterData, this.points)
}
// } else {
// alert("要素已经存在");
// }
},
addCluster(clusterData, points) {
let source = new sourceVector()
this.clusterSource = new Cluster({
distance: parseInt(20, 10),
source: source,
})
this.layer = new layerVector({
source: this.clusterSource,
style: this.clusterStyle.call(this),
})
this.map.addLayer(this.layer)
let count = clusterData.length // 点的数量
let features = clusterData //存放点要素的数组
// 初始化每个点的坐标位置
for (let i = 0; i < count; ++i) {
let pit = [features[i].lng, features[i].lat]
let mm = new Feature({
geometry: new Point(pit),
})
mm.set('name', features[i].orgName) // 给点位增加参数 name 名称
mm.set('value', 1) // 给点位增加参数 value 值
mm.set('lat', features[i].lat) // 给点位增加参数 lan 坐标
mm.set('lon', features[i].lng) // 给点位增加经度参数 lot 坐标
features[i] = mm
}
console.log(features)
// 把点都添加到 地图中去
source.addFeatures(features)
},
checkcenter(e) {
// 监听返回的视图大小
// var max = true;
let zoom = Math.round(this.map.getView().getZoom() * 10000) / 10000
// console.log(e, this.map.getView().calculateExtent(this.map.getSize())); // 视图大小
this.points = this.map.getView().calculateExtent(this.map.getSize())
// console.log(this.points);
if (zoom > 14 && this.maxzoom) {
if (this.ismovezoomend === zoom) {
this.removeFeatures()
this.getsmapData()
}
this.zoomfont = false
setTimeout(() => {
this.maxzoom = true
}, 1000)
}
},
getsmapData() {
let data = {
// mplx: '1',
trlng: this.points[2],
trlat: this.points[3],
bllng: this.points[0],
bllat: this.points[1],
}
this.maxzoom = false
getsmapData(data).then((res) => {
if (res.success) {
this.map.removeLayer(this.layer)
let clusterData = res.result //存放点要素的数组
// 新增聚合点
let source = new sourceVector()
this.clusterSource = new Cluster({
distance: parseInt(20, 10),
source: source,
})
this.layer = new layerVector({
source: this.clusterSource,
style: this.clusterlouStyle.call(this),
})
this.map.addLayer(this.layer)
let count = clusterData.length // 点的数量
let features = clusterData //存放点要素的数组
// // 初始化每个点的坐标位置
for (let i = 0; i < count; ++i) {
let pit = [features[i].mapy, features[i].mapx]
let mm = new Feature({
geometry: new Point(pit),
})
// mm.set('name', features[i].orgName); // 给点位增加参数 name 名称
mm.set('value', 1) // 给点位增加参数 value 值
mm.set('systemId', features[i].systemId) // 给点位增systemId
mm.set('lat', features[i].mapx) // 给点位增加纬度参数 lat 坐标
mm.set('lon', features[i].mapy) // 给点位增加经度参数 lon 120 坐标
features[i] = mm
}
// console.log(features);
// // 把点都添加到 地图中去
source.addFeatures(features)
}
})
},
getbmapData() {
console.log("getbmapData()")
getbmapData().then((res) => {
if (res.success) {
sessionStorage.setItem('getbmapData',JSON.stringify(res.result[2].list));
this.list = res.result[2].list
this.clusterData = res.result[2].list //存放点要素的数组
this.addCluster(res.result[2].list)
}
})
},
checkZoom(e) {
if (this.isPopup) {
this.isPopup = false
this.popup.setPosition(undefined)
}
// 监听返回的当前地图的缩放,取值为 正整数
let zoom = Math.round(this.map.getView().getZoom() * 10000) / 10000
if ((zoom < 14 && !this.zoomfont) || (zoom <= 14 && !this.zoomfont)) {
// 移除 聚合点
this.removeFeatures()
this.getbmapData()
this.zoomfont = true
}
if (zoom > 14) {
this.ismovezoomend = this.ismovezoom
this.ismovezoom = zoom
// console.log(this.ismovezoomend);
// console.log(this.ismovezoom);
// // 监听移动
// this.map.getView().on('moveend', function(ent){
// console.log(ent);
// this.ismove = !this.ismove;
// });
}
},
},