<!--
|
* @Author: shuishen 1109946754@qq.com
|
* @Date: 2022-08-18 17:00:30
|
* @LastEditors: shuishen 1109946754@qq.com
|
* @LastEditTime: 2022-11-08 14:25:31
|
* @FilePath: \srs-police-affairs\src\components\map\index.vue
|
* @Description: 公用地图组件
|
*
|
* Copyright (c) 2022 by shuishen 1109946754@qq.com, All Rights Reserved.
|
-->
|
<template>
|
<div class="viewer-box" id="viewer-container">
|
<!-- 全屏控制按钮 -->
|
<div class="screen-full-btn">
|
<el-tooltip v-if="isFullscreen" content="缩放" placement="bottom" effect="dark">
|
<i
|
class="fa fa-compress"
|
style="vertical-align: middle; cursor: pointer"
|
@click="fullscreenchange"
|
></i>
|
</el-tooltip>
|
<el-tooltip v-if="!isFullscreen" content="全屏" placement="bottom" effect="dark">
|
<i
|
class="fa fa-expand"
|
style="vertical-align: middle; cursor: pointer"
|
@click="fullscreenchange"
|
></i>
|
</el-tooltip>
|
</div>
|
<!-- 切换矢量图按钮 -->
|
<div
|
class="image-switch-icon-btn"
|
title="切换影像"
|
@mouseover="showImgBtn = true"
|
@mouseleave="showImgBtn = false"
|
>
|
<img src="/img/base_map.png" alt />
|
</div>
|
<div
|
class="image-switch-img-btn"
|
v-show="showImgBtn"
|
@mouseover="showImgBtn = true"
|
@mouseleave="showImgBtn = false"
|
>
|
<div class="img" @click="switchImg">
|
<span :class="{on:imgtype == 0}">影像</span>
|
</div>
|
<div class="elec" @click="switchElec">
|
<span :class="{on:imgtype == 1}">矢量</span>
|
</div>
|
</div>
|
</div>
|
</template>
|
|
<script>
|
|
var siteEntitylayers = null
|
|
let layersObjcect = {
|
housingEstateLayer: null,
|
patrolWagonLayer: null,
|
handMachineLayer: null,
|
monitoringLayer: null,
|
panoramaLayer: null
|
}
|
|
let tilesetLayer = null
|
|
let baseLayers = null
|
|
let tilesetObject = {
|
sdTilesetLayer: null
|
}
|
|
export default {
|
name: 'mapBox',
|
|
data () {
|
return {
|
fullscreen: false,
|
isFullscreen: false,
|
dialogVisible: false,
|
dialogTitle: "",
|
searchInput: '',
|
loading: false,
|
searchDetailsShow: false,
|
videoExist: true,
|
videoTotal: 0,
|
carTotal: 0,
|
showImgBtn: false,
|
imgtype: 0,
|
}
|
},
|
|
computed: {
|
|
},
|
mounted () {
|
if (global.viewer != null) {
|
global.viewer = null
|
}
|
|
const that = this
|
|
// 初始化地图
|
function initViewer () {
|
// new Viewer(new 地图)
|
global.viewer = new global.DC.Viewer('viewer-container', {
|
contextOptions: {
|
webgl: {
|
alpha: true,
|
stencil: true,
|
preserveDrawingBuffer: true
|
}
|
}
|
})
|
|
// global.viewer.scene.globe.depthTestAgainstTerrain = false
|
|
// 去除logo
|
let primitiveArr = global.viewer.scene.primitives._primitives
|
global.viewer.scene.primitives.remove(primitiveArr[0])
|
|
|
// 已声明的图层添加到地图上
|
siteEntitylayers = new global.DC.VectorLayer('siteEntitylayers')
|
global.viewer.addLayer(siteEntitylayers)
|
|
// 图层加入地图
|
layersObjcect.housingEstateLayer = new global.DC.VectorLayer('housingEstateLayer')
|
global.viewer.addLayer(layersObjcect.housingEstateLayer)
|
layersObjcect.patrolWagonLayer = new global.DC.VectorLayer('patrolWagonLayer')
|
global.viewer.addLayer(layersObjcect.patrolWagonLayer)
|
layersObjcect.handMachineLayer = new global.DC.VectorLayer('handMachineLayer')
|
global.viewer.addLayer(layersObjcect.handMachineLayer)
|
layersObjcect.monitoringLayer = new global.DC.VectorLayer('monitoringLayer')
|
global.viewer.addLayer(layersObjcect.monitoringLayer)
|
layersObjcect.panoramaLayer = new global.DC.VectorLayer('panoramaLayer')
|
global.viewer.addLayer(layersObjcect.panoramaLayer)
|
|
// 模型图层添加
|
tilesetLayer = new global.DC.TilesetLayer('tilesetLayer')
|
global.viewer.addLayer(tilesetLayer)
|
|
// 加载围栏
|
let layer = new global.DC.VectorLayer('layer')
|
global.viewer.addLayer(layer)
|
|
let wall = new global.DC.Wall(
|
'116.018142,28.688089,100.0; 116.017756,28.684648,100.0; 116.019507,28.677570,100.0; 116.033653,28.675634,100.0; 116.034223,28.681389,100.0; 116.033483,28.687265,100.0; 116.018142,28.688089,100.0'
|
)
|
|
wall.setStyle({
|
material: new global.DC.WallTrailMaterialProperty({
|
color: global.DC.Namespace.Cesium.Color.fromBytes(
|
33, 150, 243,
|
200
|
),
|
speed: 8
|
})
|
})
|
layer.addOverlay(wall)
|
|
|
|
// 判断是否支持图像渲染像素化处理
|
if (global.DC.Namespace.Cesium.FeatureDetection.supportsImageRenderingPixelated()) {
|
global.viewer.setOptions({
|
resolutionScale: window.devicePixelRatio
|
})
|
}
|
|
// 天地图 影像
|
global.viewer.imageryLayers.addImageryProvider(
|
new global.DC.Namespace.Cesium.UrlTemplateImageryProvider({
|
url: 'http://t{s}.tianditu.gov.cn/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=e45274b0235bb913eceb393aabbf9c9c',
|
subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'],
|
format: 'image/jpeg',
|
show: true,
|
maximumLevel: 18
|
})
|
)
|
|
|
// 上饶部署,内网使用的
|
// global.viewer.imageryLayers.addImageryProvider(
|
// new global.DC.Namespace.Cesium.WebMapTileServiceImageryProvider({
|
// url: "http://36.14.131.101:8090/MapTileService/wmts?STORETYPE=merged-dat&PROJECTION=4326",
|
// layer: "wmts_4326_361100",
|
// style: "default",
|
// format: "image/png",
|
// tileMatrixSetID: "c",
|
// tileMatrixLabels: new Array(18).fill(0).map((v, i) => i + 1),
|
// tilingScheme: new global.DC.Namespace.Cesium.GeographicTilingScheme(),
|
// })
|
// )
|
|
// 加载顺丰底图
|
// global.viewer.imageryLayers.addImageryProvider(
|
// new global.DC.Namespace.Cesium.UrlTemplateImageryProvider({
|
// url: "http://36.14.131.102:8899/tile?x={x}&y={y}&z={z}&mid=basemap&p=0&f=pbf"
|
// // url: "https://webmap-tile.sf-express.com/MapTileService/rt?x={x}&y={y}&z={z}"
|
// })
|
// )
|
|
// 设置地图初始位置,角度等
|
global.viewer.camera.setView({
|
// Cesium的坐标是以地心为原点,一向指向南美洲,一向指向亚洲,一向指向北极州
|
// fromDegrees()方法,将经纬度和高程转换为世界坐标
|
destination: global.DC.Namespace.Cesium.Cartesian3.fromDegrees(
|
116.112550, 28.196631, 50000
|
),
|
orientation: {
|
// 指向
|
heading: global.DC.Namespace.Cesium.Math.toRadians(0, 0),
|
// 视角
|
pitch: global.DC.Namespace.Cesium.Math.toRadians(-45),
|
roll: 0.0
|
}
|
})
|
|
|
|
global.viewer.use(new global.DC.Measure())
|
|
global.viewer.locationBar.enable = true
|
// 缩放
|
global.viewer.zoomController.enable = true
|
// 比例尺
|
// global.viewer.distanceLegend.enable = true
|
|
}
|
|
global.DC.ready(initViewer)
|
|
// global.viewer.scene.morphTo2D(1)
|
|
// 清除控制台
|
console.clear()
|
|
function isEleFullScreen () {
|
const fullScreenEle =
|
document.fullscreenElement ||
|
document.msFullscreenElement ||
|
document.mozFullScreenElement ||
|
document.webkitFullscreenElement
|
if (fullScreenEle === null) {
|
|
that.isFullscreen = false
|
return false
|
} else {
|
return true
|
}
|
}
|
|
window.onresize = function () {
|
console.log(isEleFullScreen())
|
}
|
|
// 注册事件
|
|
// 使用示例
|
// this.$EventBus.$emit('mapAddLayer', {
|
// layerName: 'housingEstateLayer',
|
// type: 'VectorLayer'
|
// })
|
|
|
this.$EventBus.$on('mapAddLayer', (params) => {
|
that.mapAddLayer(params.layerName, params.type)
|
})
|
|
this.$EventBus.$on('mapRemoveLayer', (params) => {
|
that.mapRemoveLayer(params.layerName, params.type)
|
})
|
|
this.$EventBus.$on('mapClearLayer', (params) => {
|
that.mapClearLayer(params.layerName, params.type)
|
})
|
|
this.$EventBus.$on('layerPointAdd', (params) => {
|
// eslint-disable-next-line no-unused-vars
|
that.layerPointAdd(params.layerName, params.type, params.layerType, params.params, params.distanceDisplayCondition, params.incident)
|
})
|
|
this.$EventBus.$on('layerPolygonAdd', (params) => {
|
that.layerPolygonAdd(params.layerName, params.positions, params.material, params.distanceDisplayCondition)
|
})
|
|
this.$EventBus.$on('layerPolylineAdd', (params) => {
|
that.layerPolylineAdd(params.layerName, params.positions, params.material, params.width)
|
})
|
|
this.$EventBus.$on('layerShow', (params) => {
|
that.layerShow(params.layerName, params.flag)
|
})
|
|
this.$EventBus.$on('toPosition', (params) => {
|
that.toPosition(params.siteJd, params.siteWd, params.siteGd, params.siteHeading, params.sitePitch, params.siteRoll, params.time)
|
})
|
|
this.$EventBus.$on('addMxTileset', (params) => {
|
// eslint-disable-next-line no-unused-vars
|
that.addMxTileset(params.titlesetName, params.titlesetUrl, params.incident)
|
})
|
|
this.$EventBus.$on('removeMxTileset', (params) => {
|
// eslint-disable-next-line no-unused-vars
|
that.removeMxTileset(params.titlesetName, params.incident)
|
})
|
|
},
|
|
methods: {
|
// 模型的点击事件
|
tilesetClick (e) {
|
if (this.$route.path != "/lyout/house") {
|
this.$router.push({ path: '/lyout/house', query: { searchName: 'xxx小区' } })
|
}
|
},
|
switchImg () {
|
// 天地图 影像
|
this.imgtype = 0
|
global.viewer.imageryLayers.remove(baseLayers)
|
baseLayers = global.viewer.imageryLayers.addImageryProvider(
|
new global.DC.Namespace.Cesium.UrlTemplateImageryProvider({
|
url: 'http://t{s}.tianditu.gov.cn/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=e45274b0235bb913eceb393aabbf9c9c',
|
subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'],
|
format: 'image/jpeg',
|
show: true,
|
maximumLevel: 18
|
})
|
)
|
this.showImgBtn = false
|
},
|
switchElec () {
|
// 天地图 矢量
|
this.imgtype = 1
|
global.viewer.imageryLayers.remove(baseLayers)
|
baseLayers = global.viewer.imageryLayers.addImageryProvider(
|
new global.DC.Namespace.Cesium.UrlTemplateImageryProvider({
|
url: 'http://t{s}.tianditu.gov.cn/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=e45274b0235bb913eceb393aabbf9c9c',
|
subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'],
|
format: 'image/jpeg',
|
show: true,
|
maximumLevel: 18
|
})
|
)
|
this.showImgBtn = false
|
},
|
/**
|
* @description: 全屏控制
|
* @return {*} 无返回值
|
*/
|
fullscreenchange () {
|
// 最新写法
|
const isFullScreen = document.fullscreenElement
|
if (isFullScreen) {
|
if (document.exitFullscreen) {
|
document.exitFullscreen()
|
} else if (document.msExitFullscreen) {
|
document.msExitFullscreen()
|
} else if (document.mozCancelFullScreen) {
|
document.mozCancelFullScreen()
|
} else if (document.webkitCancelFullScreen) {
|
document.webkitCancelFullScreen()
|
}
|
this.isFullscreen = false
|
} else {
|
var fullscreen = document.body // 需要全屏的元素
|
if (fullscreen.requestFullscreen) {
|
fullscreen.requestFullscreen()
|
} else if (fullscreen.mozRequestFullScreen) {
|
fullscreen.mozRequestFullScreen()
|
} else if (fullscreen.webkitRequestFullscreen) {
|
fullscreen.webkitRequestFullscreen()
|
} else if (fullscreen.msRequestFullscreen) {
|
fullscreen.msRequestFullscreen()
|
}
|
this.isFullscreen = true
|
}
|
},
|
/**
|
* 在图层中添加实体(点)
|
* @param {*} item 图标
|
* @param {*} url 图标地址
|
*/
|
addSiteEntity (item, url) {
|
const billboard = new global.DC.Billboard(new global.DC.Position(Number(item.lng), Number(item.lat)), url)
|
billboard.size = [20, 28]
|
billboard.attrParams = item
|
siteEntitylayers.addOverlay(billboard)
|
},
|
|
/**
|
* 添加图层
|
* @param {*} layerName 图层名称
|
* @param {*} type 图层类型
|
*/
|
mapAddLayer (layerName, type) {
|
if (type == 'VectorLayer') {
|
if (!layersObjcect[layerName]) layersObjcect[layerName] = null
|
|
layersObjcect[layerName] = new global.DC.VectorLayer(layerName)
|
|
layersObjcect[layerName].addTo(global.viewer)
|
} else if (type == 'ClusterLayer') {
|
if (!layersObjcect[layerName]) layersObjcect[layerName] = null
|
|
layersObjcect[layerName] = new global.DC.ClusterLayer(layerName)
|
|
layersObjcect[layerName].addTo(global.viewer)
|
} else if (type == 'HeatLayer') {
|
if (!layersObjcect[layerName]) layersObjcect[layerName] = null
|
|
layersObjcect[layerName] = new global.DC.HeatLayer(layerName)
|
|
layersObjcect[layerName].addTo(global.viewer)
|
}
|
},
|
|
/**
|
* 删除图层
|
* @param {*} layerName 图层名称
|
* @param {*} type 图层类型
|
*/
|
mapRemoveLayer (layerName, type) {
|
if (type == 'VectorLayer' || type == 'ClusterLayer' || type == 'HeatLayer') {
|
if (layersObjcect[layerName] && layersObjcect[layerName] != null) {
|
layersObjcect[layerName].remove()
|
layersObjcect[layerName] = null
|
}
|
}
|
},
|
|
/**
|
* 清空图层
|
* @param {*} layerName 图层名称
|
* @param {*} type 图层类型
|
*/
|
mapClearLayer (layerName, type) {
|
if (type == 'VectorLayer' || type == 'ClusterLayer' || type == 'HeatLayer') {
|
if (layersObjcect[layerName] && layersObjcect[layerName] != null)
|
layersObjcect[layerName].clear()
|
}
|
},
|
|
/**
|
* 图层点添加
|
* @param {*} layerName 图层名称
|
* @param {*} type 添加的点位类型
|
* @param {*} params 添加的点位参数(内容、详情)
|
* @param {*} incident 添加的点位事件
|
*/
|
|
layerPointAdd (layerName, type, layerType = 'VectorLayer', params, distanceDisplayCondition = {
|
near: 0, //最近距离
|
far: Number.MAX_VALUE //最远距离
|
}, incident = (e) => { }) {
|
if (!layersObjcect[layerName] || layersObjcect[layerName] == null) {
|
this.mapAddLayer(layerName, layerType)
|
}
|
|
let pointElement
|
|
if (type == "billboard") {
|
pointElement = new global.DC.Billboard(new global.DC.Position(Number(params.lng), Number(params.lat), Number(params.alt)), params.url)
|
pointElement.size = [32, 32]
|
pointElement.attrParams = params
|
layersObjcect[layerName].addOverlay(pointElement)
|
pointElement.on(global.DC.MouseEventType.CLICK, incident)
|
} else if (type == "label") {
|
pointElement = new global.DC.Label(new global.DC.Position(Number(params.lng), Number(params.lat), Number(params.alt)), params.text)
|
pointElement.setStyle({
|
fillColor: global.DC.Color.CRIMSON,
|
style: global.DC.Namespace.Cesium.LabelStyle.FILL_AND_OUTLINE,
|
outlineColor: global.DC.Color.WHITE, // 边框颜色
|
outlineWidth: 4, // 边框大小,
|
font: '16px sans-serif',
|
pixelOffset: { x: 0, y: -24 },
|
distanceDisplayCondition: distanceDisplayCondition
|
})
|
pointElement.attrParams = params
|
layersObjcect[layerName].addOverlay(pointElement)
|
pointElement.on(global.DC.MouseEventType.CLICK, incident)
|
} else if (type == 'HeatPoint') {
|
layersObjcect[layerName].setPositions(params.positions)
|
}
|
|
|
},
|
|
/**
|
* 图层面添加
|
* @param {*} layerName 图层名称
|
* @param {*} positions 图层位置数据
|
* @param {*} material 颜色
|
* @param {*} distanceDisplayCondition 可见距离
|
*/
|
layerPolygonAdd (layerName, positions, material, distanceDisplayCondition) {
|
if (!layersObjcect[layerName] || layersObjcect[layerName] == null) {
|
this.mapAddLayer(layerName, 'VectorLayer')
|
|
layersObjcect[layerName].allowDrillPicking = true
|
}
|
|
let polygon = new global.DC.Polygon(positions)
|
|
polygon.setStyle({
|
material: material,
|
distanceDisplayCondition: distanceDisplayCondition,
|
perPositionHeight: true,
|
})
|
|
layersObjcect[layerName].addOverlay(polygon)
|
},
|
|
/**
|
* 图层线添加
|
* @param {*} layerName 图层名称
|
* @param {*} positions 图层位置数据
|
* @param {*} material 颜色
|
* @param {*} width 宽度
|
*/
|
layerPolylineAdd (layerName, positions, material, width) {
|
if (!layersObjcect[layerName] || layersObjcect[layerName] == null) {
|
this.mapAddLayer(layerName, 'VectorLayer')
|
|
layersObjcect[layerName].allowDrillPicking = true
|
}
|
|
let polyline = new global.DC.Polyline(positions)
|
|
polyline.setStyle({
|
width: width,
|
material: material,
|
clampToGround: false
|
})
|
layersObjcect[layerName].addOverlay(polyline)
|
},
|
|
/**
|
* 图层显示隐藏
|
* @param {*} layerName 图层名称
|
* @param {*} flag 显示隐藏
|
*/
|
layerShow (layerName, flag) {
|
layersObjcect[layerName].show = flag
|
},
|
|
/**
|
* 飞到指定位置
|
* @param {*} siteJd 经度
|
* @param {*} siteWd 纬度
|
* @param {*} siteGd 高度,默认0
|
* @param {*} siteHeading 偏航角度,默认0
|
* @param {*} sitePitch 俯仰角度,默认0
|
* @param {*} siteRoll 翻转角度,默认0
|
* @param {*} time 飞行时间,默认3秒
|
*/
|
toPosition (siteJd, siteWd, siteGd = 2000, siteHeading = 0, sitePitch = -90, siteRoll = 0, time = 3) {
|
global.viewer.flyToPosition(
|
new global.DC.Position(
|
Number(siteJd),
|
Number(siteWd),
|
Number(siteGd),
|
Number(siteHeading),
|
Number(sitePitch),
|
Number(siteRoll)
|
),
|
function () { },
|
time
|
)
|
},
|
// sdTilesetLayer
|
|
/**
|
* 添加模型
|
* @param {*} titlesetName 图层名称
|
* @param {*} titlesetUrl 模型地址
|
* @param {*} incident 模型点击事件
|
*/
|
addMxTileset (titlesetName, titlesetUrl, incident = (e) => { }) {
|
if (!tilesetObject[titlesetName]) tilesetObject[titlesetName] = null
|
|
tilesetObject[titlesetName] = new global.DC.Tileset(titlesetUrl, {
|
luminanceAtZenith: 0.4,
|
// cullWithChildrenBounds: false,
|
// cullRequestsWhileMoving: false,
|
// skipLevelOfDetail: false,
|
shadows: global.DC.Namespace.Cesium.ShadowMode.DISABLED
|
})
|
|
tilesetObject[titlesetName].setHeight(5)
|
|
|
tilesetLayer.addOverlay(tilesetObject[titlesetName])
|
|
// global.viewer.flyTo(tilesetObject[titlesetName])
|
tilesetObject[titlesetName].on(global.DC.MouseEventType.CLICK, incident)
|
},
|
|
/**
|
* 删除模型
|
* @param {*} titlesetName 图层名称
|
* @param {*} incident 模型点击事件
|
*/
|
removeMxTileset (titlesetName, incident = (e) => { }) {
|
if (tilesetObject[titlesetName] && tilesetObject[titlesetName] != null) {
|
tilesetObject[titlesetName].off(global.DC.MouseEventType.CLICK, incident)
|
tilesetLayer.removeOverlay(tilesetObject[titlesetName])
|
tilesetObject[titlesetName] = null
|
}
|
},
|
},
|
|
}
|
</script>
|
|
<style lang="scss" scope>
|
.viewer-box {
|
position: relative;
|
width: 100%;
|
height: 100%;
|
}
|
</style>
|