<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>