使用技术:vue3.2+openlayers8.2.0
<template>
<div style="width: 100%;height: 100%">
<div class="map" id="mymap"></div>
<div class="tools shadow-md rounded flex">
<el-button class="btn-search" @click="layerChange" :type="isHeatLayer ? 'primary' : 'success'">{{
isHeatLayer ? '点位图' : '热力图' }}</el-button>
</div>
<el-card id="popup" class="popup">
<div class="popupContainer"></div>
</el-card>
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue';
import 'ol/css';
import Map from 'ol/Map';
import ZoomToExtent from 'ol/control/ZoomToExtent';
import { defaults } from 'ol/control';
import Feature from 'ol/Feature';
import Overlay from 'ol/Overlay';
import VectorSource from 'ol/source/Vector';
import { Tile as TileLayer, Vector as VectorLayer, Heatmap as HeatmapLayer } from 'ol/layer';
import View from 'ol/View';
import XYZ from 'ol/source/XYZ'
import Point from 'ol/geom/Point';
import { Icon, Style, Fill, Text, Stroke } from 'ol/style';
import markerImg from '@/assets/img/marker.png'; // 静态图片资源
const mapDom = ref(null)
const mapObj = ref(null)
const mapPointList = ref([]) //
const pointLayer = ref(null) // 点图层
const heatLayer = ref(null) // 热力图图层
const pointLayerSource = ref(null) // 点图层数据源
// 清除地图 某些情况 地图容器会存在两个 导致地图无法正常显示
const mapClear = () => {
if (mapDom.value) {
mapDom.value.innerHTML = ''
mapDom.value = null
}
}
mapClear()
// 初始化地图
const initMap = () => {
// 获取地图容器
mapDom.value = document.getElementById('mymap')
// 初始化地图配置
mapObj.value = new Map({
target: mapDom.value, // 地图容器
view: new View({
center: [120.990969, 31.635013], // 地图中心点
zoom: 10, // 缩放
minZoom: 3, // 最小缩放
maxZoom: 17, // 最大缩放
projection: 'EPSG:4326', // 坐标系
// extent: [116.67, 31.05, 116.67, 34.51], // 地图显示范围
}),
layers: [
// new TileLayer({
// source: new OSM(),
// }),
new TileLayer({
source: new XYZ({
// url: 'http://192.168.10.179:9527/roadmap/roadmap' + '/{z}/{x}/{y}.png' // 设置本地离线瓦片所在路径
url: 'https://wprd0{1-4}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&style=7&x={x}&y={y}&z={z}' //在线高德地图
})
})
],
controls: defaults().extend([
new ZoomToExtent({
extent: [119.67, 31.05, 119.67, 34.81], // 地图显示范围
})
])
})
// 地图点击事件
mapOnClick()
// 加载点位
addPoint()
}
// 地图点击事件
const mapOnClick = () => {
// popupDom
const popupDom = document.getElementById('popup')
// 创建 popup
const popup = new Overlay({
element: popupDom,
positioning: 'bottom-center',
stopEvent: false
})
// 加载到地图
mapObj.value.addOverlay(popup)
// 地图点击事件
mapObj.value.on('click', function (evt) {
if (isHeatLayer.value) return
// 获取点击位置的数据
const feature = mapObj.value.forEachFeatureAtPixel(evt.pixel, function (feature) {
return feature;
})
const popupContainer = document.getElementsByClassName('popupContainer')[0]
// 判断数据
if (feature) {
// feature.values_.data ,data字段是在 addPoint 函数创建point时添加 可以自定义
if (feature.values_.data) {
const pointData = feature.values_.data
popup.setPosition(evt.coordinate)
popupContainer.innerHTML = `<div>${pointData}</div>`
popupDom.style.display = 'block'
// 设置地图中心点
// mapObj.value.getView().setCenter(evt.coordinate)
// 设置地图层级
// mapObj.value.getView().setZoom(15)
}
} else {
popupDom.style.display = 'none'
}
})
}
// 添加地理坐标
const addPoint = () => {
// 清除所有点
delPointAll()
// 地理坐标数组
// const pointData = [
// { longitude: 120.29, latitude: 31.93 }
// ]
makers.map(item => {
// 创建点
const point = new Feature({
geometry: new Point([item.longitude, item.latitude]),
data: item.title
})
// 点的样式
const iconStyle = new Style({
image: new Icon({
// color: 'red',
crossOrigin: 'anonymous',
// 设置图标
src: markerImg,
// 设置图标缩放
// scale: 0.02,
scale: 0.2,
// 设置图标偏移
anchor: [0.6, 1],
}),
text: new Text({
text: item.title,
cursor: 'pointer',
fill: new Fill({
color: '#000'
}),
backgroundFill: new Fill({
color: '#00E400'
}),
offsetX: 0,
offsetY: -35,
font: 'normal 14px 微软雅黑',
stroke: new Stroke({
color: '#00E400',
width: 2
})
})
})
// 设置样式
point.setStyle(iconStyle)
// 保存到数据 方便删除
mapPointList.value.push(point)
})
// 创建geojson数据源
pointLayerSource.value = new VectorSource({ features: mapPointList.value })
// 创建图层 并加载数据
pointLayer.value = new VectorLayer({ source: pointLayerSource.value })
heatLayer.value = new HeatmapLayer({
source: pointLayerSource.value,
blur: 15,
radius: 15,
})
// 将图层添加地图上
mapObj.value.addLayer(pointLayer.value)
mapObj.value.addLayer(heatLayer.value)
heatLayer.value.setVisible(false)
}
// 点位图和热力图切换
let isHeatLayer = ref(false)
const layerChange = () => {
isHeatLayer.value = !isHeatLayer.value
if (isHeatLayer.value) {
pointLayer.value.setVisible(false)
heatLayer.value.setVisible(true)
} else {
heatLayer.value.setVisible(false)
pointLayer.value.setVisible(true)
}
}
// 地理点位删除
const delPointAll = () => {
// 判断 删除的数据源是否存在
if (pointLayerSource.value) {
// 删除图层 重置数据
mapObj.value.removeLayer(pointLayer.value)
pointLayerSource.value = null
pointLayer.value = null
mapPointList.value = []
}
}
onMounted(() => {
initMap()
// 获取水印元素然后隐藏
const waterMarker = document.getElementsByClassName('ol-attribution')
waterMarker[0].style.display = 'none'
})
</script>
<style scoped>
.map {
width: 100vw;
height: 98vh;
background: transparent;
}
.ol-attribution {
display: none !important;
}
.tools {
position: fixed;
z-index: 999;
top: 60px;
right: 30px;
width: 32%;
background: rgba(255, 255, 255, 0.5);
border: 1px solid #3782b4 !important;
backdrop-filter: blur(4px);
-webkit-backdrop-filter: blur(4px);
}
</style>
4 条评论
故事线完整,伏笔巧妙,结局耐人寻味。
《吸毒者国语》剧情片高清在线免费观看:https://www.jgz518.com/xingkong/28264.html
《原始生活40天第一季》记录片高清在线免费观看:https://www.jgz518.com/xingkong/107708.html
怎么收藏这篇文章?