<template>
<div class="cont_Main">
<div id="map"></div>
<div id="popup" ref="popup" class="ol-popup" v-show="devicesPointInfo">
<div id="popup-closer" class="ol-popup-closer" @click="closePopup()"></div>
<div id="popup-content">
{{devicesPointInfo.name}}@@@@@@@@@@@
</div>
</div>
</div>
</template>
<script>
import 'ol/ol.css'
import { Tile as TileLayer, Vector as VectorLayer } from 'ol/layer'
import XYZ from 'ol/source/XYZ'
import View from 'ol/View'
import Map from 'ol/Map'
import { Vector as SourceVector } from 'ol/source'
import { Icon, Style } from 'ol/style'
import Feature from 'ol/Feature'
import Point from 'ol/geom/Point'
import Overlay from 'ol/Overlay'
import { fromLonLat } from 'ol/proj'
import iconImg from '../../assets/images/icons/icon-1.png'
export default {
name: 'OpenLayerMap',
data () {
return {
map: null,
sourceVector: new SourceVector({}),
markerList: [],
devicesPointInfo: {},
infoWindow: undefined,
data: [
{ 'longitude': 107.04229069683836, 'latitude': 28.02818011403752236, 'name': 'icon1' },
{ 'longitude': 107.04445343, 'latitude': 28.02999934343, 'name': 'icon2' },
{ 'longitude': 107.04398343, 'latitude': 28.02831494343, 'name': 'icon3' },
{ 'longitude': 107.043895343, 'latitude': 28.02601234343, 'name': 'icon4' }
]
}
},
mounted () {
this.initMap()
this.creatIcon(this.data)
},
methods: {
initMap () {
// let center = proj.transformExtent([103.3, 35.5], 'EPSG:4326', 'EPSG:3857')
this.map = new Map({
target: 'map',
layers: [
new TileLayer({
source: new XYZ({
url: 'http://t{0-7}.tianditu.com/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=c0849fd047dcba41681950b4df63bf01'
})
}),
new TileLayer({
source: new XYZ({
url: 'http://t{0-7}.tianditu.com/DataServer?T=cia_w&x={x}&y={y}&l={z}&tk=c0849fd047dcba41681950b4df63bf01'
}),
isGroup: true,
name: '天地图文字标注'
}),
new VectorLayer({
source: this.sourceVector
})
],
view: new View({
center: fromLonLat([107.04229069683836, 27.97599999999999]),
zoom: 15,
minZoom: 5,
maxZoom: 18
})
})
const popup = document.getElementById('popup')
if (!this.infoWindow) {
this.infoWindow = new Overlay({
id: 'infoWindow',
element: popup,
stopEvent: true,
insertFirst: true,
offset: [0, 0], // 气泡离icon标点的位置
autoPan: false,
className: 'overlay-popup'
})
}
},
creatIcon (deviceList) {
const markFeatures = []
const markerList = []
deviceList.forEach(device => {
// 地图标点
let imageSrc = iconImg
const marker = this.createOverlay(device)
const iconStyle = new Style({
image: new Icon({
src: imageSrc,
scale: 1.4
})
})
// vector
const iconFeature = new Feature({
geometry: new Point(fromLonLat([device.longitude, device.latitude]), 'XY'),
info: device,
tooltip: marker
})
iconFeature.setStyle(iconStyle)
markFeatures.push(iconFeature)
markerList.push(marker)
})
this.sourceVector.addFeatures(markFeatures)
markerList.forEach(tooltip => {
this.map.addOverlay(tooltip)
})
this.markerList = markerList
},
createOverlay (device) {
const element = document.createElement('div')
element.innerHTML = device.name
element.className = 'tooltip-Unline'
const that = this
this.devicesPointInfo = device
// that.map.getView().setCenter(fromLonLat([device.longitude, Number(device.latitude) - 0.006]))
element.addEventListener('click', function () {
// 获取当前icon弹框详情
that.devicesPointInfo = device
that.map.removeOverlay(that.infoWindow)
that.map.addOverlay(that.infoWindow)
that.infoWindow.setPosition(fromLonLat([device.longitude, device.latitude]))
})
return new Overlay({
id: device.name,
insertFirst: false,
element: element,
offset: [8, -12],
positioning: 'right-top',
position: fromLonLat([device.longitude, device.latitude])
})
},
closePopup () {
this.infoWindow.setPosition(undefined)
this.map.removeOverlay(this.infoWindow)
this.$emit('closePopup', this.devicesPointInfo)
}
},
// 销毁组件前清除定时器
beforeDestroy () { }
}
</script>
<style scoped>
.cont_Main{
100%;
height: 100%;
}
#map {
100%;
height: 400%;
}
/deep/ .tooltip-Unline {
background: #72da29;
padding: 0 8px;
color: #fff;
border-radius: 2px;
cursor: pointer;
margin-left: 2px;
}
/deep/ .overlay-popup {
z-index: 1000;
}
.ol-popup {
position: absolute;
z-index: 1000;
color: #001656;
background-color: #e8e8f7;
opacity: 1;
-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: 24px;
left: -50px;
min- 320px;
}
.ol-popup:after,
.ol-popup:before {
top: 100%;
border: solid transparent;
content: " ";
height: 0;
0;
position: absolute;
pointer-events: none;
}
.ol-popup:after {
border-top-color: #eeeeee;
border- 10px;
left: 48px;
margin-left: -10px;
}
.ol-popup:before {
border-top-color: #cccccc;
border- 11px;
left: 48px;
margin-left: -11px;
}
.ol-popup-closer {
text-decoration: none;
position: absolute;
top: 2px;
right: 8px;
}
.ol-popup-closer:after {
content: "✖";
}
</style>