<template>
<div>
<div ref="emap" id="map"></div>
<div id="popup" class="ol-popup">
<a href="#" id="popup-closer" class="ol-popup-closer"></a>
<div id="popup-content"></div>
</div>
</div>
</template>
<script>
import 'ol/ol.css'
import Map from 'ol/Map'
import Stamen from 'ol/source/Stamen'
import VectorSource from 'ol/source/Vector'
import View from 'ol/View'
import { Heatmap as HeatmapLayer, Tile as TileLayer, Vector as LayerVec } from 'ol/layer'
import GeoJSON from 'ol/format/GeoJSON'
import olsourceOSM from 'ol/source/OSM'
import { get as getProjection, transform, fromLonLat } from 'ol/proj'
import { Vector as SourceVec, Cluster } from 'ol/source'
import { Feature, Overlay } from 'ol'
import { Point } from 'ol/geom'
import { Style, Icon, Stroke, Fill, Text, Circle } from 'ol/style'
export default {
name: 'heatmap',
data() {
return {
maps: null,
center: [113.0521, 34.6006],
heatData: {
type: 'FeatureCollection',
features: [
{ type: 'Point', coordinates: [104.4, 31.19], count: 100 },
{ type: 'Point', coordinates: [113.3, 30.6], count: 19 },
{ type: 'Point', coordinates: [123.3, 30.6], count: 419 },
{ type: 'Point', coordinates: [105.3, 30.6], count: 319 },
{ type: 'Point', coordinates: [106.3, 30.6], count: 719 },
{ type: 'Point', coordinates: [109.3, 31.6], count: 519 },
{ type: 'Point', coordinates: [109.3, 30.6], count: 319 },
{ type: 'Point', coordinates: [108.3, 32.6], count: 139 },
{ type: 'Point', coordinates: [118.3, 31.6], count: 129 },
{ type: 'Point', coordinates: [108.3, 33.6], count: 190 },
{ type: 'Point', coordinates: [108.3, 32.6], count: 189 },
{ type: 'Point', coordinates: [100.3, 30.6], count: 1 },
{ type: 'Point', coordinates: [109.3, 30.6], count: 119 },
{ type: 'Point', coordinates: [108.3, 31.6], count: 200 },
{ type: 'Point', coordinates: [118.3, 30.6], count: 300 },
],
},
view: null,
}
},
methods: {
initMap() {
let projection = getProjection('EPSG:4326')
// 热力图层
let vector = new HeatmapLayer({
source: new VectorSource({
features: new GeoJSON().readFeatures(this.heatData, {
dataProjection: 'EPSG:4326',
featureProjection: 'EPSG:3857',
}),
}),
blur: 20,
radius: 10,
})
// 底图1
let tile = new TileLayer({
source: new olsourceOSM(),
})
// 地图中心
let view = new View({
center: transform(this.center, 'EPSG:4326', 'EPSG:3857'),
zoom: 5,
})
// 实例化底图
this.maps = new Map({
layers: [tile, vector],
target: 'map',
view,
})
// 点标记
let point = [
[113.28, 34.54],
[114.28, 35.54],
[114.28, 34.54],
[114.28, 36.54],
[114.28, 37.54],
[110.28, 36.54],
]
let pointss = []
// 创建矢量容器
let vectorSource = new SourceVec({})
for (let i = 0; i < point.length; i++) {
let points = fromLonLat(point[i])
//创建图标特性
let iconFeature = new Feature({
geometry: new Point(points),
})
//将图标特性添加进矢量中
vectorSource.addFeature(iconFeature)
//创建图标样式
let iconStyle = new Style({
image: new Icon({
opacity: 1,
scale: 0.75,
src: '/static/warning_icon/normal_green.png', //图标的URL
}),
})
//创建矢量层
let vectorLayer = new LayerVec({
source: vectorSource,
style: iconStyle,
})
pointss.push(vectorLayer)
//添加进map
this.maps.addLayer(vectorLayer)
}
/*********************显示弹出层**************************/
let container = document.getElementById('popup')
let content = document.getElementById('popup-content')
let popupCloser = document.getElementById('popup-closer')
let overlay = new Overlay({
element: container,
autoPan: true,
})
let _this = this
_this.maps.on('pointermove', function(e) {
let pixel = _this.maps.getEventPixel(e.originalEvent)
let hit = _this.maps.hasFeatureAtPixel(pixel)
if (!hit) {
_this.maps.getTargetElement().style.cursor = 'auto'
} else {
_this.maps.getTargetElement().style.cursor = 'pointer'
}
})
this.maps.on('click', function(e) {
let pixel = _this.maps.getEventPixel(e.originalEvent)
_this.maps.forEachFeatureAtPixel(pixel, function(feature) {
let coodinate = e.coordinate
content.innerHTML = 'dddddd' + 'ddddd'
overlay.setPosition(coodinate)
_this.maps.addOverlay(overlay)
})
})
popupCloser.addEventListener('click', function() {
overlay.setPosition(undefined)
})
},
},
mounted() {
this.initMap()
},
}
</script>
<style scoped>
.label {
font-size: 20px;
}
#map {
width: 100%;
height: 99vh;
}
.ol-popup {
position: absolute;
background-color: #eeeeee;
-webkit-filter: drop-shadow(0 1px 4px rgba(0, 0, 0, 0.2));
filter: drop-shadow(0 1px 4px rgba(0, 0, 0, 0.2));
padding: 15px;
border-radius: 10px;
border: 1px solid #cccccc;
bottom: 12px;
left: -100px;
width: 180px;
}
.ol-popup:after,
.ol-popup:before {
top: 100%;
border: solid transparent;
content: '';
height: 0;
width: 0;
position: absolute;
pointer-events: none;
}
.ol-popup:after {
border-top-color: #eeeeee;
border-width: 10px;
left: 48px;
margin-left: 40px;
}
.ol-popup:before {
border-top-color: #cccccc;
border-width: 10px;
left: 48px;
margin-left: 40px;
}
.ol-popup-closer {
text-decoration: none;
position: absolute;
top: 2px;
right: 8px;
}
.ol-popup-closer:after {
content: '✖';
}
</style>