<!--
|
* @Author: shuishen 1109946754@qq.com
|
* @Date: 2023-10-11 16:01:58
|
* @LastEditors: shuishen 1109946754@qq.com
|
* @LastEditTime: 2023-11-29 14:17:09
|
* @FilePath: \web\business\src\components\OlMapBox\index.vue
|
* @Description:
|
*
|
* Copyright (c) 2023 by shuishen, All Rights Reserved.
|
-->
|
<template>
|
<div class="w100 h100">
|
<div id="OlMapBoxElement" class="w100 h100">
|
</div>
|
</div>
|
</template>
|
|
<script>
|
// import OLCesium from "ol-cesium"
|
import "ol/ol.css"
|
import OlView from "ol/View.js"
|
import {
|
// eslint-disable-next-line no-unused-vars
|
defaults as OlControlDefaults,
|
defaults,
|
// 全屏控件
|
FullScreen,
|
// 比例尺控件
|
ScaleLine,
|
// 缩放滚动条控件
|
// eslint-disable-next-line no-unused-vars
|
ZoomSlider,
|
// 鼠标位置控件
|
// eslint-disable-next-line no-unused-vars
|
MousePosition,
|
// -地图属性控件
|
Attribution,
|
// 鹰眼控件
|
// eslint-disable-next-line no-unused-vars
|
OverviewMap,
|
// 缩放到范围控件
|
// eslint-disable-next-line no-unused-vars
|
ZoomToExtent,
|
Rotate,
|
} from "ol/control.js"
|
import OlSourceOSM from "ol/source/OSM.js"
|
import OlLayerTile from "ol/layer/Tile.js"
|
|
import { Image as ImageLayer } from 'ol/layer'
|
import ImageStatic from 'ol/source/ImageStatic.js'
|
|
import OlLayerVectorTile from "ol/layer/VectorTile.js"
|
import OlMap from "ol/Map.js"
|
import OlProjection from "ol/proj/Projection.js"
|
import OlMVT from "ol/format/MVT.js"
|
import OlUnits from "ol/proj/Units.js"
|
import OlFeature from "ol/Feature"
|
|
import { get as projGet } from "ol/proj.js"
|
// c
|
|
import XYZ from "ol/source/XYZ"
|
|
import Cluster from "ol/source/Cluster"
|
|
import VectorLayer from "ol/layer/Vector"
|
import VectorSource from "ol/source/Vector"
|
|
import TileArcGISRest from "ol/source/TileArcGISRest"
|
import TilegridTileGrid from "ol/tilegrid/TileGrid"
|
|
import GeoJSON from "ol/format/GeoJSON"
|
|
import Feature from 'ol/Feature.js'
|
import Point from 'ol/geom/Point.js'
|
import { Icon, Style, Fill, Text, Stroke, Circle } from 'ol/style.js'
|
|
|
let mapView = null
|
let layersObjcect = {}
|
|
let baseMapLayer = {
|
yx: [],
|
sl: []
|
}
|
let options,
|
epsgcode,
|
isMvt = false
|
|
let isMapResource = true
|
export default {
|
name: 'OlMapBox',
|
|
props: {
|
mapType: {
|
type: String,
|
default: 'sl'
|
},
|
|
mapContrast: {
|
type: String,
|
default: 'custom'
|
}
|
},
|
|
data () {
|
return {
|
publicPath: process.env.BASE_URL,
|
}
|
},
|
|
|
mounted () {
|
const that = this
|
|
this.$nextTick(() => {
|
mapView = new OlMap({
|
target: 'OlMapBoxElement',
|
layers: [],
|
view: new OlView({
|
// 初始化中心点坐标,经纬度一会自己换一下
|
center: [113, 24],
|
zoom: 18,
|
projection: "EPSG:4326"
|
}),
|
})
|
|
mapView.on("singleclick", function (event) {
|
mapView.forEachFeatureAtPixel(
|
event.pixel,
|
(feature) => {
|
feature.dispatchEvent && feature.dispatchEvent({ type: 'click', event: event })
|
}
|
)
|
})
|
|
that.baseInitLayer(that.mapType)
|
|
|
this.mapAddClusterLayer(
|
'livePersonLocationLayer',
|
'/public/img/map/location',
|
[{lng: 113, lat: 24}, {lng: 115, lat:24 }],
|
(e) => { },
|
)
|
})
|
},
|
|
methods: {
|
/**
|
* @description: 底图加载
|
* @param {*} type
|
* @return {*}
|
*/
|
baseInitLayer (type) {
|
if (baseMapLayer.yx.length) {
|
baseMapLayer.yx.forEach(item => {
|
mapView.removeLayer(item)
|
})
|
baseMapLayer.yx = []
|
}
|
|
if (baseMapLayer.sl.length) {
|
baseMapLayer.sl.forEach(item => {
|
mapView.removeLayer(item)
|
})
|
baseMapLayer.sl = []
|
}
|
|
if (type == 'yx') {
|
let yxImgW = new OlLayerTile({
|
zIndex: 1,
|
title: '影像',
|
source: new XYZ({
|
url: 'https://t0.tianditu.gov.cn/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=e45274b0235bb913eceb393aabbf9c9c',
|
})
|
})
|
|
mapView.addLayer(yxImgW)
|
|
baseMapLayer.yx.push(yxImgW)
|
|
let yxCvaW = new OlLayerTile({
|
zIndex: 2,
|
title: '影像标注',
|
source: new XYZ({
|
url: 'https://t0.tianditu.gov.cn/DataServer?T=cva_w&x={x}&y={y}&l={z}&tk=e45274b0235bb913eceb393aabbf9c9c',
|
})
|
})
|
|
mapView.addLayer(yxCvaW)
|
|
baseMapLayer.yx.push(yxCvaW)
|
} else if (type == 'sl') {
|
let slVecW = new OlLayerTile({
|
zIndex: 2,
|
title: '矢量',
|
source: new XYZ({
|
url: 'https://t0.tianditu.gov.cn/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=e45274b0235bb913eceb393aabbf9c9c',
|
})
|
})
|
|
mapView.addLayer(slVecW)
|
|
baseMapLayer.sl.push(slVecW)
|
|
let slCvaW = new OlLayerTile({
|
zIndex: 2,
|
title: '矢量标注',
|
source: new XYZ({
|
url: 'https://t0.tianditu.gov.cn/DataServer?T=cva_w&x={x}&y={y}&l={z}&tk=e45274b0235bb913eceb393aabbf9c9c',
|
})
|
})
|
|
mapView.addLayer(slCvaW)
|
|
baseMapLayer.sl.push(slVecW)
|
}
|
},
|
|
// javascript 转换
|
lonLat2Mercator (lonlat) {
|
var mercator = {
|
x: 0,
|
y: 0
|
}
|
var earthRad = 6378137.0
|
mercator.x = lonlat.lng * Math.PI / 180 * earthRad
|
var a = lonlat.lat * Math.PI / 180
|
mercator.y = earthRad / 2 * Math.log((1.0 + Math.sin(a)) / (1.0 - Math.sin(a)))
|
return mercator
|
},
|
|
getCurItemFeature (params) {
|
const iconFeature = new Feature({
|
geometry: new Point([Number(params.lng), Number(params.lat)]),
|
attributes: params.item
|
})
|
|
let styleOptions = {
|
cursor: 'pointer',
|
}
|
|
if (params.url) {
|
styleOptions.image = new Icon({
|
scale: params.scale || 1,
|
imgSize: params.imgSize || [160, 221],
|
src: params.url,
|
})
|
}
|
|
if (params.text) {
|
let textElement = document.createElement('span')
|
textElement.innerHTML = params.text
|
|
let color = '#0000FF'
|
|
styleOptions.text = new Text({
|
// 对齐方式
|
textAlign: 'center',
|
// 文本基线
|
textBaseline: 'middle',
|
text: textElement.innerHTML,
|
font: '14px Arial',
|
fill: new Fill({
|
color: 'white'
|
}),
|
// 填充背景
|
backgroundFill: new Fill({
|
color: color
|
}),
|
padding: [2, 5, 2, 5],
|
stroke: new Stroke({ color: '#00000000', width: 1 })
|
})
|
}
|
|
iconFeature.setStyle(new Style(styleOptions))
|
|
iconFeature.on('click', (e) => {
|
if (params.event) {
|
params.event(e.target.values_.attributes.attr)
|
}
|
})
|
|
return iconFeature
|
},
|
|
/**
|
* 删除图层
|
* @param {*} layerName 图层名称
|
*/
|
mapRemoveLayer (layerNames) {
|
layerNames.forEach(item => {
|
if (layersObjcect[item] && layersObjcect[item] != null) {
|
mapView.removeLayer(layersObjcect[item])
|
delete layersObjcect[item]
|
}
|
|
if (layersObjcect[item + 'ONE'] && layersObjcect[item + 'ONE'] != null) {
|
mapView.removeLayer(layersObjcect[item + 'ONE'])
|
delete layersObjcect[item + 'ONE']
|
}
|
|
if (layersObjcect[item + 'TWO'] && layersObjcect[item + 'TWO'] != null) {
|
mapView.removeLayer(layersObjcect[item + 'TWO'])
|
delete layersObjcect[item + 'TWO']
|
}
|
})
|
},
|
|
// 添加聚合图层的新模式,水库点分布
|
mapAddClusterLayer (layerName, imgUrl, positionData, incident = (e) => { }, type = '') {
|
const that = this
|
|
if (!layersObjcect[layerName]) {
|
if (type == 'cluster') {
|
let source = new VectorSource()
|
|
positionData.forEach(item => {
|
source.addFeature(that.getCurItemFeature({
|
item,
|
lng: item.lng,
|
lat: item.lat,
|
url: imgUrl,
|
event: incident
|
}))
|
})
|
|
let layer = new Cluster({
|
source: source,
|
distance: 100
|
})
|
|
layersObjcect[layerName] = new VectorLayer({
|
source: layer,
|
zIndex: 24,
|
style: (feature, resolution) => {
|
let size = feature.get('features').length
|
|
let radius = 10
|
|
if (size > 900) {
|
radius = 19
|
} else if (size > 600) {
|
radius = 16
|
} else if (size > 400) {
|
radius = 13
|
}
|
|
let style = new Style({
|
image: new Circle({
|
radius: radius,
|
stroke: new Stroke({
|
color: 'blue',
|
width: 1
|
}),
|
fill: new Fill({
|
color: 'blue'
|
})
|
}),
|
text: new Text({
|
text: size.toString(),
|
fill: new Fill({
|
color: 'white'
|
})
|
})
|
})
|
|
return style
|
}
|
})
|
|
mapView.addLayer(layersObjcect[layerName])
|
|
return
|
} else {
|
layersObjcect[layerName] = new VectorLayer({
|
// 图标图层
|
zIndex: 24,
|
minZoom: 12,
|
source: new VectorSource(),
|
})
|
}
|
|
mapView.addLayer(layersObjcect[layerName])
|
}
|
|
positionData.forEach(item => {
|
layersObjcect[layerName].getSource().addFeature(that.getCurItemFeature({
|
item,
|
lng: item.lng,
|
lat: item.lat,
|
url: imgUrl,
|
event: incident
|
}))
|
})
|
},
|
},
|
}
|
</script>
|
|
<style lang='scss' scope>
|
|
.w100 {
|
width: 100%;
|
}
|
|
.h100 {
|
height: 100%;
|
}
|
</style>
|