Browse Source
2.earthMapUrl 抽离URL 3. 新增 import { listenMouseHandlerSence } from '@/utils/earthMap/listenMouseHandlerSence'; import getLineInfo from '@/utils/earthMap/getLineInfo'; import getCameraInfo from '@/utils/earthMap/getCameraInfo';master
DIAMOND
12 months ago
9 changed files with 1663 additions and 514 deletions
@ -0,0 +1,55 @@ |
|||||
|
import { defHttp } from '/@/utils/http/axios'; |
||||
|
import { message } from 'ant-design-vue'; |
||||
|
import { useGlobSetting } from '/@/hooks/setting'; |
||||
|
const globSetting = useGlobSetting(); |
||||
|
|
||||
|
export enum earthMapUrl{ |
||||
|
queryLabelList= 'military/msMapLabel/queryLabelAndDeviceList', |
||||
|
queryLineList= 'military/msMapLine/list', |
||||
|
queryCameraInfo= 'military/camera/site/getCameraInfoForEarth', |
||||
|
queryAllModelInfo= 'military/msModelPosition/queryAllModelInfo', |
||||
|
queryPatrolRouteInfo= 'military/msPatrolLine/getLineDetail', |
||||
|
queryBayoneByParam= 'military/msBayonetStatistics/getBayoneByParam', |
||||
|
queryAisInfo= 'military/checkpoint/msAisInfo/list', |
||||
|
keepAlive= 'military/mapInfo/keepAlive', |
||||
|
//雷达扫描列表
|
||||
|
radarList= '/military/RadarConfig/list', |
||||
|
// 删除模型
|
||||
|
// 传感器
|
||||
|
deleteSensor= '/military/msModelPosition/deleteByEventSerialNum', |
||||
|
// 站点
|
||||
|
deleteSite= '/military/camera/site/delete', |
||||
|
// 标志点
|
||||
|
deleteMapLabel= '/military/msMapLabel/delete', |
||||
|
updateMapLine= '/military/msMapLine/edit', |
||||
|
deleteMapLine= '/military/msMapLine/delete', |
||||
|
saveMapLine= '/military/msMapLine/add', |
||||
|
// 编辑 模型
|
||||
|
// 传感器
|
||||
|
updateSensor= '/military/msModelPosition/editByEventSerialNum', |
||||
|
// 站点
|
||||
|
updateSite= '/military/camera/site/edit', |
||||
|
|
||||
|
// 标志点
|
||||
|
updateMapLabel= '/military/msMapLabel/edit', |
||||
|
|
||||
|
// 模型 保存
|
||||
|
// 传感器
|
||||
|
SaveSensorModel= '/military/msModelPosition/add', |
||||
|
// 站点
|
||||
|
saveCameraSiteModel= '/military/camera/site/add', |
||||
|
// 标志点
|
||||
|
saveMapLabel= '/military/msMapLabel/addMapLabel', |
||||
|
|
||||
|
// 通过 线路名称 查询 线路
|
||||
|
queryMapLine= '/military/msMapLine/queryByName', |
||||
|
querySiteById= '/military/camera/site/queryById', |
||||
|
// 查询设备列表
|
||||
|
queryDeviceInfoList= '/military/msDeviceInfo/list', |
||||
|
setDefenseArea= '/military/netty/microwaveDetector/defenceArea', |
||||
|
perimeterRegionList= '/third/api/perimeterRegionList', |
||||
|
perimeterControl= '/third/api/perimeterControl', |
||||
|
// 雷达重新发送报警信息
|
||||
|
sendRadarAlarmByWebSocket= '/military/warn/sendRadarAlarmByWebSocket', |
||||
|
|
||||
|
} |
@ -0,0 +1,186 @@ |
|||||
|
/** |
||||
|
* 加载区域 |
||||
|
* 用于EarthComp.vue |
||||
|
*/ |
||||
|
import { defHttp } from '/@/utils/http/axios'; |
||||
|
import { addPin } from '@/utils/earthMap/earthObj'; |
||||
|
import { useUserStore } from '/@/store/modules/user'; |
||||
|
import { useEarthMapStore } from '/@/store/modules/earthMap'; |
||||
|
import { earthMapUrl } from '@/api/earth/earthMap' |
||||
|
import { nextTick } from 'vue'; |
||||
|
import $ from 'jquery'; |
||||
|
|
||||
|
let userStore = useUserStore(); |
||||
|
let store = useEarthMapStore(); |
||||
|
export default function getCameraInfo(models, type) { |
||||
|
console.log("加载站点"); |
||||
|
return new Promise((resolve, reject) => { |
||||
|
//请求电线杆信息
|
||||
|
defHttp.get({ url: earthMapUrl.queryCameraInfo }, { isTransformResponse: false }).then(async (res) => { |
||||
|
if (res.success) { |
||||
|
// console.log("res",res);
|
||||
|
setCamera(res.result, models, type); |
||||
|
store.cameraData = res.result; |
||||
|
resolve(models); |
||||
|
} |
||||
|
}); |
||||
|
}); |
||||
|
} |
||||
|
async function setCamera(res, models, type) { |
||||
|
//根据经纬度算出该点地形高度
|
||||
|
let posArr: any = [], |
||||
|
updatedPositions: any = []; |
||||
|
//地形是否开启
|
||||
|
if (window.$earth.sceneTree.$refs.terrain.czmObject.show) { |
||||
|
res.forEach((data, index) => { |
||||
|
if (data.msCameraSiteList != null) { |
||||
|
data.msCameraSiteList.forEach((data, index) => { |
||||
|
posArr.push(window.Cesium.Cartographic.fromDegrees(data.longitude, data.latitude)); |
||||
|
}); |
||||
|
} |
||||
|
}); |
||||
|
var promise = window.Cesium.sampleTerrainMostDetailed(this._viewer.terrainProvider, posArr); |
||||
|
updatedPositions = await window.Cesium.when(promise); |
||||
|
} else { |
||||
|
res.forEach((data, index) => { |
||||
|
if (data.msCameraSiteList != null) { |
||||
|
data.msCameraSiteList.forEach((data, index) => { |
||||
|
updatedPositions.push(window.Cesium.Cartographic.fromDegrees(data.longitude, data.latitude, 0)); |
||||
|
}); |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
// console.log("根据经纬度算出该点地形高度",res);
|
||||
|
// console.log("根据经纬度算出该点地形高度",updatedPositions);
|
||||
|
|
||||
|
//设置电线杆
|
||||
|
res.forEach((data, index) => { |
||||
|
// console.log("data",data);
|
||||
|
let siteConfig: any = null; |
||||
|
const lineId = data.id; |
||||
|
let childs: any = null; |
||||
|
if (type == 2) { |
||||
|
childs = models.children; |
||||
|
for (const child of childs) { |
||||
|
if ('node_' + data.id == child.ref) { |
||||
|
siteConfig = child.children[0]; |
||||
|
} |
||||
|
} |
||||
|
} else { |
||||
|
const parentNode = store.nodeConfigByRef.get('node_' + data.id); |
||||
|
if (!parentNode) { |
||||
|
return; |
||||
|
} |
||||
|
childs = parentNode.children; |
||||
|
siteConfig = childs[0]; |
||||
|
// console.log("parentNode",parentNode);
|
||||
|
} |
||||
|
if (!siteConfig) { |
||||
|
return; |
||||
|
} |
||||
|
if (data.msCameraSiteList != null) { |
||||
|
data.msCameraSiteList.forEach((data, index) => { |
||||
|
// 判断电线杆状态
|
||||
|
let num = 0; |
||||
|
if (data.msCameraSettingList != null) { |
||||
|
data.msCameraSettingList.forEach((data, index) => { |
||||
|
if (data.status == '3') { |
||||
|
//1-在线,2-离线,3-异常
|
||||
|
num = num + 1; |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
let gltfStr; |
||||
|
if (!data.modelUrl) { |
||||
|
return; |
||||
|
} |
||||
|
let fileInfos = data.modelUrl.split('.'); |
||||
|
if (num == 0) { |
||||
|
// gltfStr = window._CONFIG['domianURL'] + '/sys/common/static/' + fileInfos[0] + '.' + fileInfos[1];
|
||||
|
gltfStr = '/dt/sys/common/static/' + fileInfos[0] + '.' + fileInfos[1]; |
||||
|
} else if (num < data.msCameraSettingList.length) { |
||||
|
let newName = fileInfos[0].substring(0, fileInfos[0].length - 1) + 'R'; |
||||
|
// gltfStr = window._CONFIG['domianURL'] + '/sys/common/static/' + newName + '.' + fileInfos[1];
|
||||
|
gltfStr = '/dt/sys/common/static/' + newName + '.' + fileInfos[1]; |
||||
|
} else if (num == data.msCameraSettingList.length) { |
||||
|
let newName = fileInfos[0].substring(0, fileInfos[0].length - 1) + 'Y'; |
||||
|
// gltfStr = window._CONFIG['domianURL'] + '/sys/common/static/' + newName + '.' + fileInfos[1];
|
||||
|
gltfStr = '/dt/sys/common/static/' + newName + '.' + fileInfos[1]; |
||||
|
} |
||||
|
const modelConfig = { |
||||
|
ref: data.id, |
||||
|
name: lineId, |
||||
|
czmObject: { |
||||
|
name: data.sitename, |
||||
|
xbsjType: 'Model', |
||||
|
url: gltfStr, |
||||
|
// "color": [0.52, 0.6, 0.58, 1],
|
||||
|
minimumPixelSize: data.minimumPixelSize, |
||||
|
// maximumScale: 0.02,
|
||||
|
scale: data.scale, |
||||
|
xbsjScale: data.xyzScale ? data.xyzScale.split(',') : [1, 1, 1], |
||||
|
xbsjPosition: [window.Cesium.Math.toRadians(data.longitude), window.Cesium.Math.toRadians(data.latitude), data.height], |
||||
|
xbsjRotation: [ |
||||
|
window.Cesium.Math.toRadians(data.yaw), |
||||
|
window.Cesium.Math.toRadians(data.pitch), |
||||
|
window.Cesium.Math.toRadians(data.roll), |
||||
|
], |
||||
|
viewDistance: 150, |
||||
|
distanceDisplayCondition: [1.0, 30000.0], |
||||
|
customProp: data.id, |
||||
|
}, |
||||
|
}; |
||||
|
|
||||
|
window.$earth.sceneTree.root.children.push(modelConfig); |
||||
|
//鼠标事件
|
||||
|
window.$earth.sceneTree.$refs[data.id].czmObject.onmouseover = () => { |
||||
|
window.$viewer._container.style.cursor = 'pointer'; |
||||
|
}; |
||||
|
window.$earth.sceneTree.$refs[data.id].czmObject.onmouseout = () => { |
||||
|
window.$viewer._container.style.cursor = 'default'; |
||||
|
}; |
||||
|
|
||||
|
nextTick(() => { |
||||
|
const divs = $('#earthContainer>div>div>div:nth-child(5)') |
||||
|
.children('div') |
||||
|
.eq(1) |
||||
|
.children() |
||||
|
.eq(0) |
||||
|
.children() |
||||
|
.eq(0) |
||||
|
.children() |
||||
|
.each((index, element) => { |
||||
|
$(element).css('display', 'none'); |
||||
|
}); |
||||
|
}); |
||||
|
//加载相机
|
||||
|
let cameraList: any = []; |
||||
|
if (data.msCameraSettingList) { |
||||
|
for (let camera of data.msCameraSettingList) { |
||||
|
let name = camera.cameraName; |
||||
|
const obj = { |
||||
|
ref: 'camera_' + camera.id, |
||||
|
expand: false, |
||||
|
title: name, |
||||
|
czmObject: { |
||||
|
name: name, |
||||
|
xbsjType: 'Model', |
||||
|
}, |
||||
|
}; |
||||
|
// let id = camera.id
|
||||
|
cameraList.push(obj); |
||||
|
// 默认设置为在线
|
||||
|
} |
||||
|
} |
||||
|
// 杆
|
||||
|
const node = { |
||||
|
ref: 'node_' + data.id, |
||||
|
title: data.sitename, |
||||
|
expand: false, |
||||
|
children: cameraList, |
||||
|
}; |
||||
|
siteConfig.children.push(node); |
||||
|
}); |
||||
|
} |
||||
|
}); |
||||
|
} |
@ -0,0 +1,268 @@ |
|||||
|
/** |
||||
|
* 加载区域 |
||||
|
* 用于EarthComp.vue |
||||
|
*/ |
||||
|
import { defHttp } from '/@/utils/http/axios'; |
||||
|
import { addPin } from '@/utils/earthMap/earthObj'; |
||||
|
import { useUserStore } from '/@/store/modules/user'; |
||||
|
import { useEarthMapStore } from '/@/store/modules/earthMap'; |
||||
|
import { earthMapUrl } from '@/api/earth/earthMap' |
||||
|
import hidePng from '@/assets/earthMap/hide.png'; |
||||
|
import { nextTick } from 'vue'; |
||||
|
import $ from 'jquery'; |
||||
|
|
||||
|
let userStore = useUserStore(); |
||||
|
let store = useEarthMapStore(); |
||||
|
export default function getLineInfo(models, type) { |
||||
|
console.log("请求线路信息"); |
||||
|
|
||||
|
return new Promise((resolve, reject) => { |
||||
|
//请求线路信息
|
||||
|
defHttp |
||||
|
.get( |
||||
|
{ |
||||
|
url: earthMapUrl.queryLineList, |
||||
|
params: { |
||||
|
pageNo: 1, |
||||
|
pageSize: 99999, |
||||
|
sceneId: userStore.userInfo?.sceneId + '*', |
||||
|
}, |
||||
|
}, |
||||
|
{ isTransformResponse: false } |
||||
|
) |
||||
|
.then(async (res) => { |
||||
|
// console.log('加载区域',res);
|
||||
|
if (res.success) { |
||||
|
//一级区域
|
||||
|
let parentArea: any = []; |
||||
|
//二级区域
|
||||
|
let childArea: any = []; |
||||
|
res.result.records.forEach((data) => { |
||||
|
if (data.parentCode) { |
||||
|
childArea.push(data); |
||||
|
} else { |
||||
|
parentArea.push(data); |
||||
|
} |
||||
|
}); |
||||
|
parentArea.forEach((data) => { |
||||
|
// console.log(data);
|
||||
|
|
||||
|
// data.sceneId
|
||||
|
let updatedPositions: any = []; |
||||
|
let positionsData = JSON.parse(data.positions); |
||||
|
if (!positionsData) { |
||||
|
positionsData = []; |
||||
|
} |
||||
|
updatedPositions = positionsData; |
||||
|
|
||||
|
let lineOptions: any = { |
||||
|
maxShowHeight: 30000, |
||||
|
customProp: data.lineCode, |
||||
|
}; |
||||
|
lineOptions.name = data.name; |
||||
|
lineOptions.xbsjType = 'Polyline'; |
||||
|
lineOptions.width = data.width; |
||||
|
lineOptions.positions = updatedPositions; |
||||
|
lineOptions.loop = Boolean(data.isLoop); |
||||
|
lineOptions.depthTest = Boolean(data.isDepthCheck); |
||||
|
lineOptions.arcType = data.interpolation; |
||||
|
let material: any = {}; |
||||
|
switch (data.materialType) { |
||||
|
// 实线
|
||||
|
case 0: |
||||
|
material.type = 'XbsjColorMaterial'; |
||||
|
material.XbsjColorMaterial = {}; |
||||
|
if (!data.color || data.color.length <= 0) { |
||||
|
data.color = '[1,1,1,1]'; |
||||
|
} |
||||
|
material.XbsjColorMaterial.color = JSON.parse(data.color); |
||||
|
break; |
||||
|
// 虚线
|
||||
|
case 1: |
||||
|
material.type = 'XbsjPolylineDashMaterial'; |
||||
|
material.XbsjPolylineDashMaterial = {}; |
||||
|
material.XbsjPolylineDashMaterial.color = JSON.parse(data.color); |
||||
|
material.XbsjPolylineDashMaterial.gapColor = JSON.parse(data.intervalColor); |
||||
|
material.XbsjPolylineDashMaterial.dashLength = data.dashLength; |
||||
|
material.XbsjPolylineDashMaterial.dashPattern = data.dashStyle; |
||||
|
break; |
||||
|
// 箭头线
|
||||
|
case 2: |
||||
|
material.type = 'XbsjPolylineArrowMaterial'; |
||||
|
material.XbsjPolylineArrowMaterial = {}; |
||||
|
material.XbsjPolylineArrowMaterial.color = JSON.parse(data.color); |
||||
|
break; |
||||
|
// 轨迹线
|
||||
|
case 3: |
||||
|
material.type = 'XbsjODLineMaterial'; |
||||
|
material.XbsjODLineMaterial = {}; |
||||
|
material.XbsjODLineMaterial.color = JSON.parse(data.color); |
||||
|
material.XbsjODLineMaterial.totoalFrameCount = data.cycleFrame; |
||||
|
break; |
||||
|
} |
||||
|
lineOptions.material = material; |
||||
|
let currentChildArea: any = []; |
||||
|
if (childArea.length) { |
||||
|
childArea.forEach((element) => { |
||||
|
let obj = {}; |
||||
|
if (data.id == element.parentCode) { |
||||
|
obj = { |
||||
|
expand: false, |
||||
|
title: element.name, |
||||
|
ref: 'nodeSecondary_' + element.id, |
||||
|
children: [], |
||||
|
}; |
||||
|
let updatedPositions: any = []; |
||||
|
let positionsData = JSON.parse(element.positions); |
||||
|
if (!positionsData) { |
||||
|
positionsData = []; |
||||
|
} |
||||
|
updatedPositions = positionsData; |
||||
|
let lineOptions: any = { |
||||
|
maxShowHeight: 30000, |
||||
|
customProp: element.lineCode, |
||||
|
}; |
||||
|
lineOptions.name = element.name; |
||||
|
lineOptions.xbsjType = 'Polyline'; |
||||
|
lineOptions.width = element.width; |
||||
|
lineOptions.positions = updatedPositions; |
||||
|
lineOptions.loop = Boolean(element.isLoop); |
||||
|
lineOptions.depthTest = Boolean(element.isDepthCheck); |
||||
|
lineOptions.arcType = element.interpolation; |
||||
|
let material: any = {}; |
||||
|
switch (element.materialType) { |
||||
|
// 实线
|
||||
|
case 0: |
||||
|
material.type = 'XbsjColorMaterial'; |
||||
|
material.XbsjColorMaterial = {}; |
||||
|
if (!element.color || element.color.length <= 0) { |
||||
|
element.color = '[1,1,1,1]'; |
||||
|
} |
||||
|
material.XbsjColorMaterial.color = JSON.parse(element.color); |
||||
|
break; |
||||
|
// 虚线
|
||||
|
case 1: |
||||
|
material.type = 'XbsjPolylineDashMaterial'; |
||||
|
material.XbsjPolylineDashMaterial = {}; |
||||
|
material.XbsjPolylineDashMaterial.color = JSON.parse(element.color); |
||||
|
material.XbsjPolylineDashMaterial.gapColor = JSON.parse(element.intervalColor); |
||||
|
material.XbsjPolylineDashMaterial.dashLength = element.dashLength; |
||||
|
material.XbsjPolylineDashMaterial.dashPattern = element.dashStyle; |
||||
|
break; |
||||
|
// 箭头线
|
||||
|
case 2: |
||||
|
material.type = 'XbsjPolylineArrowMaterial'; |
||||
|
material.XbsjPolylineArrowMaterial = {}; |
||||
|
material.XbsjPolylineArrowMaterial.color = JSON.parse(element.color); |
||||
|
break; |
||||
|
// 轨迹线
|
||||
|
case 3: |
||||
|
material.type = 'XbsjODLineMaterial'; |
||||
|
material.XbsjODLineMaterial = {}; |
||||
|
material.XbsjODLineMaterial.color = JSON.parse(element.color); |
||||
|
material.XbsjODLineMaterial.totoalFrameCount = element.cycleFrame; |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
let pos = [0, 0, 0]; |
||||
|
positionsData.forEach((element) => { |
||||
|
pos[0] += element[0]; |
||||
|
pos[1] += element[1]; |
||||
|
pos[2] += element[2]; |
||||
|
}); |
||||
|
pos[0] = pos[0] / positionsData.length; |
||||
|
pos[1] = pos[1] / positionsData.length; |
||||
|
pos[2] = pos[2] / positionsData.length; |
||||
|
let pinBuilder = { |
||||
|
extTextFont: '30px 宋体', |
||||
|
extTextPixelOffset: [-40, 10], |
||||
|
fillColor: [0, 0.3450980392156863, 1, 0.9], |
||||
|
outlineColor: [1, 1, 1, 1], |
||||
|
extText: element.name, |
||||
|
}; |
||||
|
let pin = addPin(element.name, hidePng, { position: pos, scale: 0.8, pinBuilder, far: 107374 }); |
||||
|
lineOptions.pinXbsjGuid = pin.xbsjGuid; |
||||
|
lineOptions.material = material; |
||||
|
// that._earth.sceneTree.root.children.push({ czmObject: lineOptions, ref: element.id });
|
||||
|
window.$earth.sceneTree.root.children.push({ czmObject: lineOptions, ref: element.id }); |
||||
|
currentChildArea.push(obj); |
||||
|
// 如果是总部
|
||||
|
if (type == 1) { |
||||
|
store.nodeConfigByRef.set('nodeSecondary_' + element.id, obj); |
||||
|
} |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
//配置信息
|
||||
|
const node = { |
||||
|
ref: 'node_' + data.id, |
||||
|
expand: false, |
||||
|
title: '<防区>' + data.name, |
||||
|
children: [ |
||||
|
{ |
||||
|
expand: false, |
||||
|
title: '监控点位', |
||||
|
ref: 'monitor_' + window.guid(), |
||||
|
children: [], |
||||
|
}, |
||||
|
{ |
||||
|
expand: false, |
||||
|
title: '雷达点位', |
||||
|
ref: 'ldList_' + window.guid(), |
||||
|
children: currentChildArea, |
||||
|
}, |
||||
|
{ |
||||
|
expand: false, |
||||
|
title: '微波点位', |
||||
|
ref: 'wbList_' + window.guid(), |
||||
|
children: [], |
||||
|
}, |
||||
|
], |
||||
|
}; |
||||
|
if (data.sceneId == models.ref) { |
||||
|
// console.log("当前场景下");
|
||||
|
|
||||
|
//该防区为当前场景下
|
||||
|
//压入树
|
||||
|
models.children.push(node); |
||||
|
store.nodeConfigByRef.set(node.ref, node); |
||||
|
store.areaByNodeId.set(node.ref, data.sceneId); |
||||
|
// return
|
||||
|
} else { |
||||
|
const childs = models.children; |
||||
|
for (const child of childs) { |
||||
|
if (child.ref == data.sceneId) { |
||||
|
//该防区为子场景下
|
||||
|
// console.log("子场景下");
|
||||
|
child.children.push(node); |
||||
|
store.nodeConfigByRef.set(node.ref, node); |
||||
|
store.areaByNodeId.set(node.ref, data.sceneId); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
//放进世界场景树
|
||||
|
window.$earth.sceneTree.root.children.push({ czmObject: lineOptions, ref: data.id }); |
||||
|
}); |
||||
|
//加载二级区域模型
|
||||
|
childArea.forEach((data) => {}); |
||||
|
nextTick(() => { |
||||
|
const divs = $('#earthContainer>div>div>div:nth-child(5)') |
||||
|
.children('div') |
||||
|
.eq(1) |
||||
|
.children() |
||||
|
.eq(0) |
||||
|
.children() |
||||
|
.eq(0) |
||||
|
.children() |
||||
|
.each((index, element) => { |
||||
|
// const paddingLeft = $(element).children().eq(0).css('padding-left')
|
||||
|
$(element).css('display', 'none'); |
||||
|
}); |
||||
|
}); |
||||
|
// console.log("models",models);
|
||||
|
resolve(models); |
||||
|
} |
||||
|
}); |
||||
|
}); |
||||
|
} |
@ -0,0 +1,124 @@ |
|||||
|
/** |
||||
|
* 监听鼠标事件(用于场景管理) |
||||
|
* 用于EarthComp.vue |
||||
|
* |
||||
|
*/ |
||||
|
import { toRefs, watch, nextTick, ref, reactive, onMounted } from 'vue'; |
||||
|
import { message } from 'ant-design-vue'; |
||||
|
import dwPng from '@/assets/images/rotationXYZ.png'; |
||||
|
import rotationXYZ from '@/assets/images/rotationXYZ.png'; |
||||
|
|
||||
|
// 添加地图上的鼠标监听事件
|
||||
|
let pin: any = undefined; |
||||
|
let viewer: any = undefined; |
||||
|
// 鼠标样式
|
||||
|
const cursorCss = ref("grab"); |
||||
|
let position: any = null; |
||||
|
let rotation: any = null; |
||||
|
let fov: any = null; |
||||
|
export function listenMouseHandlerSence(enablePointer = false, that) { |
||||
|
viewer = window.$earth.czm.viewer; |
||||
|
window.viewer = viewer; |
||||
|
window.$earth.interaction.picking.enabled = true; |
||||
|
window.$earth.interaction.picking.clickedColor = [1, 0, 0, 1]; |
||||
|
|
||||
|
const handler = new window.Cesium.ScreenSpaceEventHandler( |
||||
|
viewer.scene.canvas |
||||
|
); |
||||
|
window.CesiumGlobalHandler = handler; |
||||
|
// 取消双击旋转事件
|
||||
|
viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction( |
||||
|
window.Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK |
||||
|
); |
||||
|
console.log("enablePointer", enablePointer); |
||||
|
|
||||
|
if (enablePointer) { |
||||
|
viewer.cesiumWidget.screenSpaceEventHandler.setInputAction((event) => { |
||||
|
let cartesian = viewer.scene.globe.pick(viewer.camera.getPickRay(event.position), viewer.scene); |
||||
|
if (!cartesian) { |
||||
|
return; |
||||
|
} |
||||
|
// 世界坐标转换为弧度
|
||||
|
let ellipsoid = viewer.scene.globe.ellipsoid; |
||||
|
let cartographic = ellipsoid.cartesianToCartographic(cartesian); |
||||
|
// 弧度转换为经纬度
|
||||
|
let pointLon = window.Cesium.Math.toDegrees(cartographic.longitude); // 经度
|
||||
|
let pointLat = window.Cesium.Math.toDegrees(cartographic.latitude); // 纬度
|
||||
|
let pointAlt = cartographic.height; // 高度
|
||||
|
console.log("点击的经纬度坐标是:", { |
||||
|
"经度:": pointLon, |
||||
|
"纬度:": pointLat |
||||
|
}); |
||||
|
// debugger
|
||||
|
|
||||
|
//destroy方法有问题无法成功销毁,故选择trycatch
|
||||
|
try { |
||||
|
pin && pin.destroy(); |
||||
|
pin = undefined |
||||
|
} catch (error) { |
||||
|
console.error("销毁失败",error); |
||||
|
pin = undefined |
||||
|
} |
||||
|
pin = new window.XE.Obj.Pin(window.$earth); |
||||
|
pin.position = [cartographic.longitude, cartographic.latitude, pointAlt]; |
||||
|
pin.imageUrl = dwPng; |
||||
|
|
||||
|
let cposition = [window.$earth.camera.position[0], window.$earth.camera.position[1], window.$earth.camera.position[2]]; |
||||
|
if (pin) { |
||||
|
position = [pin.position[0], pin.position[1], pin.position[2]]; |
||||
|
} |
||||
|
rotation = [window.$earth.camera.rotation[0], window.$earth.camera.rotation[1], window.$earth.camera.rotation[2]]; |
||||
|
fov = window.$earth.camera.fov; |
||||
|
that.$emit("checkPosition", position, cposition, rotation, fov); |
||||
|
|
||||
|
}, |
||||
|
window.Cesium.ScreenSpaceEventType.LEFT_CLICK |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
// /* 左键事件 */
|
||||
|
handler.setInputAction((event) => { |
||||
|
handler.removeInputAction(window.Cesium.ScreenSpaceEventType.MOUSE_MOVE) |
||||
|
// modelDw.value = false;
|
||||
|
if (clearId != null) { |
||||
|
clearTimeout(clearId); |
||||
|
clearId = null; |
||||
|
} |
||||
|
cursorCss.value = `grabbing`; |
||||
|
}, window.Cesium.ScreenSpaceEventType.LEFT_DOWN); |
||||
|
handler.setInputAction((event) => { |
||||
|
if (clearId != null) { |
||||
|
clearTimeout(clearId); |
||||
|
clearId = null; |
||||
|
} |
||||
|
cursorCss.value = `grab`; |
||||
|
}, window.Cesium.ScreenSpaceEventType.LEFT_UP); |
||||
|
handler.setInputAction((event) => { |
||||
|
if (clearId != null) { |
||||
|
clearTimeout(clearId); |
||||
|
clearId = null; |
||||
|
} |
||||
|
cursorCss.value = `url(${rotationXYZ}),grab`; |
||||
|
}, window.Cesium.ScreenSpaceEventType.MIDDLE_DOWN); |
||||
|
handler.setInputAction((event) => { |
||||
|
if (clearId != null) { |
||||
|
clearTimeout(clearId); |
||||
|
clearId = null; |
||||
|
} |
||||
|
cursorCss.value = `grab`; |
||||
|
}, window.Cesium.ScreenSpaceEventType.MIDDLE_UP); |
||||
|
let clearId: any = null; |
||||
|
handler.setInputAction((event) => { |
||||
|
if (event > 0) { |
||||
|
cursorCss.value = `zoom-in`; |
||||
|
} else { |
||||
|
cursorCss.value = `zoom-out`; |
||||
|
} |
||||
|
|
||||
|
clearId = setTimeout(() => { |
||||
|
clearTimeout(clearId); |
||||
|
cursorCss.value = `grab` |
||||
|
}, 2000); |
||||
|
}, window.Cesium.ScreenSpaceEventType.WHEEL); |
||||
|
|
||||
|
} |
@ -0,0 +1,827 @@ |
|||||
|
<template> |
||||
|
<a-modal :title="title" :visible="visible" @ok="handleOk" @cancel="handleCancel" width="60vw" :destroyOnClose="true" |
||||
|
wrapClassName="EarthMap"> |
||||
|
<a-row> |
||||
|
<a-col :span="24"> |
||||
|
<div id="earthContainer" :style="{ cursor: cursorCss }"></div> |
||||
|
<!-- <span class="mapManage" @click="() => { mapManageShow = !mapManageShow }"> |
||||
|
<a-icon type="setting" theme="filled" /> |
||||
|
</span> --> |
||||
|
<span :class="['scaleWin', 'iconSpan', scaleWin.status ? 'colorBlue' : '']" title="放大或缩小" @click="scaleWinFunc"> |
||||
|
<ExpandOutlined v-if="!scaleWin.status" /> |
||||
|
<CompressOutlined v-else /> |
||||
|
</span> |
||||
|
<span :class="['mapModel', 'iconSpan']" @click="modelChange" title="地图维度切换"> |
||||
|
{{ modelText == "2D" ? "3D" : "2D" }} |
||||
|
</span> |
||||
|
|
||||
|
<template v-if="editTileModel != undefined && modelText == '3D'"> |
||||
|
<span class="buildManage iconSpan" @click="enableTileChange" title="建筑加载"> |
||||
|
<img src="../../../../../../../assets/images/build_close.png" class="iconSize" v-show="!enableTile" /> |
||||
|
<img src="../../../../../../../assets/images/build_able.png" class="iconSize" v-show="enableTile" /> |
||||
|
</span> |
||||
|
<span class="modelDw iconSpan" @click="modelDwFunc" title="模型跟随鼠标"> |
||||
|
<img src="../../../../../../../assets/images/dw_close.png" class="iconSize" v-show="!modelDw" /> |
||||
|
<img src="../../../../../../../assets/images/dw_able.png" class="iconSize" v-show="modelDw" /> |
||||
|
</span> |
||||
|
<span class="modelMove iconSpan" @click="modelMoveFunc" title="模型移动"> |
||||
|
<img src="../../../../../../../assets/images/move_close.png" class="iconSize" v-show="!modelMove" /> |
||||
|
<img src="../../../../../../../assets/images/move_able.png" class="iconSize" v-show="modelMove" /> |
||||
|
</span> |
||||
|
<span class="modelRotation iconSpan" @click="modelRotationFunc" title="模型旋转"> |
||||
|
<img src="../../../../../../../assets/images/rotation_close.png" class="iconSize" v-show="!modelRotation" /> |
||||
|
<img src="../../../../../../../assets/images/rotation_able.png" class="iconSize" v-show="modelRotation" /> |
||||
|
</span> |
||||
|
<span class="modelScale iconSpan" title="缩放"> |
||||
|
<a-tooltip placement="left" trigger="click" |
||||
|
:getPopupContainer="(triggerNode) => { return triggerNode.parentElement }"> |
||||
|
<img src="../../../../../../../assets/images/scale_close.png" class="iconSize" v-show="!modelScaleStatus" |
||||
|
@click="modelScaleStatusChange" /> |
||||
|
<img src="../../../../../../../assets/images/scale_able.png" class="iconSize" v-show="modelScaleStatus" |
||||
|
@click="modelScaleStatusChange" /> |
||||
|
<template #title> |
||||
|
<div class="sliderContainer"> |
||||
|
<a-row class="sliderRow"> |
||||
|
<a-col :span="4"> |
||||
|
X轴: |
||||
|
</a-col> |
||||
|
<a-col :span="11"> |
||||
|
<a-slider v-model:value="scaleValues[0]" :min="scaleConfig.X.min" :max="scaleConfig.X.max" |
||||
|
:step="scaleConfig.X.step" /> |
||||
|
</a-col> |
||||
|
<a-col :span="6"> |
||||
|
<a-input-number v-model:value="scaleValues[0]" :min="scaleConfig.X.min" :max="scaleConfig.X.max" |
||||
|
:step="scaleConfig.X.step" style="width:100%"></a-input-number> |
||||
|
</a-col> |
||||
|
<a-col :span="2" :offset="1" @click="() => { scaleConfig.X.show = !scaleConfig.X.show }"> |
||||
|
<SettingOutlined :style="{ color: scaleConfig.X.show ? '#1296db' : '#FFF' }" /> |
||||
|
</a-col> |
||||
|
</a-row> |
||||
|
<a-row v-show="scaleConfig.X.show" type="flex" justify="space-around" align="middle" :gutter="[0, 12]"> |
||||
|
<a-col :span="8"> |
||||
|
最小值: |
||||
|
</a-col> |
||||
|
<a-col :span="16"> |
||||
|
<a-input-number v-model:value="scaleConfig.X.min" class="fill-9-row"></a-input-number> |
||||
|
</a-col> |
||||
|
<a-col :span="8"> |
||||
|
最大值: |
||||
|
</a-col> |
||||
|
<a-col :span="16"> |
||||
|
<a-input-number v-model:value="scaleConfig.X.max" class="fill-9-row"></a-input-number> |
||||
|
</a-col> |
||||
|
<a-col :span="8"> |
||||
|
步长: |
||||
|
</a-col> |
||||
|
<a-col :span="16"> |
||||
|
<a-input-number v-model:value="scaleConfig.X.step" class="fill-9-row"></a-input-number> |
||||
|
</a-col> |
||||
|
<a-col :span="24" class="sliderRow"> |
||||
|
<a-button type="primary" class="fill-9-row" @click="() => { allSetting('X') }">应用全部</a-button> |
||||
|
</a-col> |
||||
|
</a-row> |
||||
|
<a-row class="sliderRow"> |
||||
|
<a-col :span="4"> |
||||
|
Y轴: |
||||
|
</a-col> |
||||
|
<a-col :span="11"> |
||||
|
<a-slider v-model:value="scaleValues[1]" :min="scaleConfig.Y.min" :max="scaleConfig.Y.max" |
||||
|
:step="scaleConfig.Y.step" /> |
||||
|
</a-col> |
||||
|
<a-col :span="6"> |
||||
|
<a-input-number v-model:value="scaleValues[1]" :min="scaleConfig.Y.min" :max="scaleConfig.Y.max" |
||||
|
:step="scaleConfig.Y.step" style="width:100%"></a-input-number> |
||||
|
</a-col> |
||||
|
<a-col :span="2" :offset="1" @click="() => { scaleConfig.Y.show = !scaleConfig.Y.show }"> |
||||
|
<SettingOutlined :style="{ color: scaleConfig.X.show ? '#1296db' : '#FFF' }" /> |
||||
|
</a-col> |
||||
|
</a-row> |
||||
|
<a-row v-show="scaleConfig.Y.show" type="flex" justify="space-around" align="middle" :gutter="[0, 12]"> |
||||
|
<a-col :span="8"> |
||||
|
最小值: |
||||
|
</a-col> |
||||
|
<a-col :span="16"> |
||||
|
<a-input-number v-model:value="scaleConfig.Y.min" class="fill-9-row"></a-input-number> |
||||
|
</a-col> |
||||
|
<a-col :span="8"> |
||||
|
最大值: |
||||
|
</a-col> |
||||
|
<a-col :span="16"> |
||||
|
<a-input-number v-model:value="scaleConfig.Y.max" class="fill-9-row"></a-input-number> |
||||
|
</a-col> |
||||
|
<a-col :span="8"> |
||||
|
步长: |
||||
|
</a-col> |
||||
|
<a-col :span="16"> |
||||
|
<a-input-number v-model:value="scaleConfig.Y.step" class="fill-9-row"></a-input-number> |
||||
|
</a-col> |
||||
|
<a-col :span="24" class="sliderRow"> |
||||
|
<a-button type="primary" class="fill-9-row" @click="() => { allSetting('Y') }">应用全部</a-button> |
||||
|
</a-col> |
||||
|
</a-row> |
||||
|
<a-row class="sliderRow"> |
||||
|
<a-col :span="4"> |
||||
|
Z轴: |
||||
|
</a-col> |
||||
|
<a-col :span="11"> |
||||
|
<a-slider v-model:value="scaleValues[2]" :min="scaleConfig.Z.min" :max="scaleConfig.Z.max" |
||||
|
:step="scaleConfig.Z.step" /> |
||||
|
</a-col> |
||||
|
<a-col :span="6"> |
||||
|
<a-input-number v-model:value="scaleValues[2]" :min="scaleConfig.Z.min" :max="scaleConfig.Z.max" |
||||
|
:step="scaleConfig.Z.step" style="width:100%"></a-input-number> |
||||
|
</a-col> |
||||
|
<a-col :span="2" :offset="1" @click="() => { scaleConfig.Z.show = !scaleConfig.Z.show }"> |
||||
|
<SettingOutlined :style="{ color: scaleConfig.X.show ? '#1296db' : '#FFF' }" /> |
||||
|
</a-col> |
||||
|
</a-row> |
||||
|
<a-row v-show="scaleConfig.Z.show" type="flex" justify="space-around" align="middle" :gutter="[0, 12]"> |
||||
|
<a-col :span="8"> |
||||
|
最小值: |
||||
|
</a-col> |
||||
|
<a-col :span="16"> |
||||
|
<a-input-number v-model:value="scaleConfig.Z.min" class="fill-9-row"></a-input-number> |
||||
|
</a-col> |
||||
|
<a-col :span="8"> |
||||
|
最大值: |
||||
|
</a-col> |
||||
|
<a-col :span="16"> |
||||
|
<a-input-number v-model:value="scaleConfig.Z.max" class="fill-9-row"></a-input-number> |
||||
|
</a-col> |
||||
|
<a-col :span="8"> |
||||
|
步长: |
||||
|
</a-col> |
||||
|
<a-col :span="16"> |
||||
|
<a-input-number v-model:value="scaleConfig.Z.step" class="fill-9-row"></a-input-number> |
||||
|
</a-col> |
||||
|
<a-col :span="24" class="sliderRow"> |
||||
|
<a-button type="primary" class="fill-9-row" @click="() => { allSetting('Z') }">应用全部</a-button> |
||||
|
</a-col> |
||||
|
</a-row> |
||||
|
</div> |
||||
|
|
||||
|
</template> |
||||
|
</a-tooltip> |
||||
|
</span> |
||||
|
</template> |
||||
|
</a-col> |
||||
|
</a-row> |
||||
|
|
||||
|
</a-modal> |
||||
|
</template> |
||||
|
<script setup> |
||||
|
import { toRefs, watch, nextTick, ref, reactive, onMounted, getCurrentInstance } from 'vue'; |
||||
|
import { message } from 'ant-design-vue'; |
||||
|
import { useEarthMapStore } from '/@/store/modules/earthMap'; |
||||
|
import rotationXYZ from '@/assets/images/rotationXYZ.png'; |
||||
|
import { defHttp } from '@/utils/http/axios'; |
||||
|
import { FormatPainterOutlined, SettingOutlined, ExpandOutlined, GatewayOutlined, ZoomInOutlined, ZoomOutOutlined, CompressOutlined } from '@ant-design/icons-vue'; |
||||
|
// import dwPng from '/@/assets/images/dwPng.png'; |
||||
|
import dwPng from '@/assets/images/rotationXYZ.png'; |
||||
|
import { drawPolygonSave, drawGeoSmoothPolygon } from "@/utils/earthMap/earthDraw"; |
||||
|
const store = useEarthMapStore(); |
||||
|
const { proxy } = getCurrentInstance(); |
||||
|
// 获取地图 |
||||
|
const getMapPage = (params) => defHttp.get({ url: "/military/msMapManage/list/page", params: params }, { isTransformResponse: false }); |
||||
|
// 鼠标样式 |
||||
|
const cursorCss = ref("grab"); |
||||
|
const props = defineProps(['title', 'visible', 'hasMoveMethod', 'initModeType', 'editTileModel', 'enableTile', 'enablePointer']); |
||||
|
const { title, visible, hasMoveMethod, initModeType, editTileModel, enablePointer } = toRefs(props); |
||||
|
// 禁用切片 |
||||
|
const enableTile = ref(props.enableTile); |
||||
|
const pointerXyz = ref([]); |
||||
|
const defaultPinUrl = "../"; |
||||
|
const emit = defineEmits(["closeWin", "checkPosition", "moveChinaPosition"]) |
||||
|
// 确认事件 |
||||
|
const handleOk = function () { |
||||
|
let position = null; |
||||
|
let rotation = null; |
||||
|
let fov = null; |
||||
|
if (CModel.value) { |
||||
|
position = [...CModel.value.czmObject.xbsjPosition]; |
||||
|
rotation = [...CModel.value.czmObject.xbsjRotation]; |
||||
|
emit("checkPosition", position, rotation, [...scaleValues.value]); |
||||
|
} else { |
||||
|
let cposition = [window.earth.camera.position[0], window.earth.camera.position[1], window.earth.camera.position[2]]; |
||||
|
if (pin) { |
||||
|
position = [pin.position[0], pin.position[1], pin.position[2]]; |
||||
|
} |
||||
|
rotation = [window.earth.camera.rotation[0], window.earth.camera.rotation[1], window.earth.camera.rotation[2]]; |
||||
|
fov = window.earth.camera.fov; |
||||
|
emit("checkPosition", position, cposition, rotation, fov); |
||||
|
} |
||||
|
handleCancel(); |
||||
|
|
||||
|
} |
||||
|
const handleCancel = function () { |
||||
|
emit("closeWin"); |
||||
|
} |
||||
|
// 地球对象 |
||||
|
let earth = undefined; |
||||
|
let _viewer = undefined; |
||||
|
watch( |
||||
|
visible, async (value, oldValue) => { |
||||
|
// 初始化地球和其他 |
||||
|
if (value) { |
||||
|
await nextTick() |
||||
|
// 地图初始化 |
||||
|
window.XE.ready().then(() => { |
||||
|
// 加载标绘插件 |
||||
|
return window.XE.HTML.loadJS('/earthsdk/XbsjEarth-Plugins/plottingSymbol/plottingSymbol.js'); |
||||
|
}).then(async () => { |
||||
|
earth = new window.XE.Earth('earthContainer'); |
||||
|
window.earth = window.$earth = earth |
||||
|
window.$viewer = _viewer = window.earth.czm.viewer; |
||||
|
initMode(); |
||||
|
listenMouseHandler(); |
||||
|
listenMouseHandlerSelect(); |
||||
|
addContainerClickListen(); |
||||
|
await getDataSource(); |
||||
|
moveChinaPosition(); |
||||
|
}); |
||||
|
|
||||
|
} else { |
||||
|
// 销毁缓存 |
||||
|
destroyCache(); |
||||
|
} |
||||
|
} |
||||
|
) |
||||
|
|
||||
|
|
||||
|
const mapManageShow = ref(false); |
||||
|
const modelText = ref('2D'); |
||||
|
const modelChange = function () { |
||||
|
const viewer = window.earth.czm.viewer; |
||||
|
if (modelText.value == '3D') { |
||||
|
// 禁用切片,后切换为2D |
||||
|
// const loyauts = window.earth.sceneTree.$refs["loyauts"].children; |
||||
|
// loyauts.forEach(loyaut => { |
||||
|
// loyaut.enabled = false; |
||||
|
// }); |
||||
|
modelText.value = "2D"; |
||||
|
enableTile.value = false; |
||||
|
if (CModel.value) { |
||||
|
// CModel.value.show = false; |
||||
|
if (modelDw.value) { |
||||
|
modelDwFunc(); |
||||
|
} |
||||
|
if (modelMove.value) { |
||||
|
modelMoveFunc(); |
||||
|
} |
||||
|
if (modelRotation.value) { |
||||
|
modelRotationFunc(); |
||||
|
} |
||||
|
} |
||||
|
viewer.scene.morphTo2D(0) |
||||
|
} else { |
||||
|
viewer.scene.morphTo3D(0) |
||||
|
modelText.value = "3D"; |
||||
|
|
||||
|
} |
||||
|
|
||||
|
|
||||
|
} |
||||
|
const enableTileChange = function () { |
||||
|
if (modelText.value != "3D") { |
||||
|
message.info("2D切片。若要加载切片,请切换至3D模式!") |
||||
|
return; |
||||
|
} |
||||
|
enableTile.value = !enableTile.value; |
||||
|
} |
||||
|
|
||||
|
const initMode = function () { |
||||
|
const viewer = window.earth.czm.viewer; |
||||
|
// 当没有initModeType属性时,默认2D模式展示 |
||||
|
if (!initModeType.value) { |
||||
|
modelText.value = "3D" |
||||
|
viewer.scene.morphTo3D(0) |
||||
|
return; |
||||
|
} |
||||
|
// 2D模式 |
||||
|
if (initModeType.value == "2D") { |
||||
|
modelText.value = "3D" |
||||
|
viewer.scene.morphTo2D(0) |
||||
|
} else if (initModeType.value == "3D") { |
||||
|
// 3D模式 |
||||
|
modelText.value = "3D" |
||||
|
viewer.scene.morphTo3D(0) |
||||
|
} |
||||
|
} |
||||
|
const CModel = ref(null); |
||||
|
// 编辑切片模型 |
||||
|
const editTileModelFunc = function (root) { |
||||
|
// 空值判断 |
||||
|
if (!editTileModel || !editTileModel.value) { |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
// 模型对象 |
||||
|
const modelObj = { |
||||
|
ref: editTileModel.value.custom.id, |
||||
|
czmObject: editTileModel.value.czmObject, |
||||
|
enabled: true, |
||||
|
} |
||||
|
// 创建模型 |
||||
|
root.push(modelObj); |
||||
|
// 拿取创建的模型 |
||||
|
CModel.value = window.earth.sceneTree.$refs[editTileModel.value.custom.id]; |
||||
|
// 启用 |
||||
|
CModel.value.enabled = true; |
||||
|
CModel.value.czmObject.enabled = true; |
||||
|
// 初始大小 |
||||
|
scaleValues.value = [...CModel.value.czmObject.xbsjScale]; |
||||
|
} |
||||
|
const moveChinaPosition = function () { |
||||
|
// 如果外部传入了moveChinaPosition方法则调用外部的 |
||||
|
if (hasMoveMethod.value) { |
||||
|
emit('moveChinaPosition'); |
||||
|
} else { |
||||
|
// 否则则给一个默认位置 |
||||
|
window.earth.camera.fov = 1.0471975511965976; |
||||
|
window.earth.camera.position = [1.8833961240252113, 0.6131398723508994, 8921610.846366767]; |
||||
|
window.earth.camera.rotation = [6.283185307179586, -1.5704896980852325, 0] |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
let viewer = undefined; |
||||
|
// 鼠标样式 |
||||
|
const cssGrab = function (e) { |
||||
|
const buttonNum = e.button; |
||||
|
if (buttonNum == 0) { |
||||
|
cursorCss.value = `grabbing`; |
||||
|
} else if (buttonNum == 1) { |
||||
|
cursorCss.value = `${rotationXYZ}`; |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
// 添加事件监听 |
||||
|
const addContainerClickListen = function () { |
||||
|
const dom = document.getElementById("earthContainer"); |
||||
|
dom.addEventListener("mousedown", cssGrab, true) |
||||
|
// dom.addEventListener("mouseup", cssGrab) |
||||
|
} |
||||
|
// 模型跟随鼠标 |
||||
|
const modelFollowMouse = (event) => { |
||||
|
if (CModel.value && modelText.value == "3D") { |
||||
|
if (CModel.value.enabled == false) { |
||||
|
CModel.value.enabled = true; |
||||
|
} |
||||
|
//地图左键触发 右侧菜单隐藏 |
||||
|
// 屏幕坐标转为世界坐标 |
||||
|
let cartesian = viewer.scene.globe.pick(viewer.camera.getPickRay(event.endPosition), viewer.scene); |
||||
|
if (!cartesian) { |
||||
|
return; |
||||
|
} |
||||
|
// 世界坐标转换为弧度 |
||||
|
let ellipsoid = viewer.scene.globe.ellipsoid; |
||||
|
let cartographic = ellipsoid.cartesianToCartographic(cartesian); |
||||
|
|
||||
|
let lon = cartographic.longitude; // 经度 |
||||
|
let lat = cartographic.latitude; // 纬度 |
||||
|
// let alt = cartographic.height; // 高度 |
||||
|
let alt = 0; // 高度 |
||||
|
CModel.value.czmObject.xbsjPosition = [lon, lat, alt]; |
||||
|
} |
||||
|
} |
||||
|
let pin = undefined; |
||||
|
// 添加地图上的鼠标监听事件 |
||||
|
const listenMouseHandler = function () { |
||||
|
viewer = window.earth.czm.viewer; |
||||
|
window.viewer = viewer; |
||||
|
window.earth.interaction.picking.enabled = true; |
||||
|
window.earth.interaction.picking.clickedColor = [1, 0, 0, 1]; |
||||
|
|
||||
|
const handler = new window.Cesium.ScreenSpaceEventHandler( |
||||
|
viewer.scene.canvas |
||||
|
); |
||||
|
window.CesiumGlobalHandler = handler; |
||||
|
// 取消双击旋转事件 |
||||
|
viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction( |
||||
|
window.Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK |
||||
|
); |
||||
|
// handler.setInputAction(modelFollowMouse, Cesium.ScreenSpaceEventType.MOUSE_MOVE); |
||||
|
|
||||
|
if (enablePointer.value) { |
||||
|
viewer.cesiumWidget.screenSpaceEventHandler.setInputAction((event) => { |
||||
|
let cartesian = viewer.scene.globe.pick(viewer.camera.getPickRay(event.position), viewer.scene); |
||||
|
if (!cartesian) { |
||||
|
return; |
||||
|
} |
||||
|
// 世界坐标转换为弧度 |
||||
|
let ellipsoid = viewer.scene.globe.ellipsoid; |
||||
|
let cartographic = ellipsoid.cartesianToCartographic(cartesian); |
||||
|
// 弧度转换为经纬度 |
||||
|
let pointLon = Cesium.Math.toDegrees(cartographic.longitude); // 经度 |
||||
|
let pointLat = Cesium.Math.toDegrees(cartographic.latitude); // 纬度 |
||||
|
let pointAlt = cartographic.height; // 高度 |
||||
|
|
||||
|
console.log("点击的的经纬度坐标是:", { |
||||
|
"经度:": pointLon, |
||||
|
"纬度:": pointLat |
||||
|
}); |
||||
|
pin && pin.destroy(); |
||||
|
pin = new window.XE.Obj.Pin(window.earth); |
||||
|
pin.position = [cartographic.longitude, cartographic.latitude, pointAlt]; |
||||
|
pin.imageUrl = dwPng; |
||||
|
}, |
||||
|
window.Cesium.ScreenSpaceEventType.LEFT_CLICK |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
// /* 左键事件 */ |
||||
|
handler.setInputAction((event) => { |
||||
|
handler.removeInputAction(window.Cesium.ScreenSpaceEventType.MOUSE_MOVE) |
||||
|
modelDw.value = false; |
||||
|
if (clearId != null) { |
||||
|
clearTimeout(clearId); |
||||
|
clearId = null; |
||||
|
} |
||||
|
cursorCss.value = `grabbing`; |
||||
|
}, window.Cesium.ScreenSpaceEventType.LEFT_DOWN); |
||||
|
handler.setInputAction((event) => { |
||||
|
if (clearId != null) { |
||||
|
clearTimeout(clearId); |
||||
|
clearId = null; |
||||
|
} |
||||
|
cursorCss.value = `grab`; |
||||
|
}, window.Cesium.ScreenSpaceEventType.LEFT_UP); |
||||
|
handler.setInputAction((event) => { |
||||
|
if (clearId != null) { |
||||
|
clearTimeout(clearId); |
||||
|
clearId = null; |
||||
|
} |
||||
|
cursorCss.value = `url(${rotationXYZ}),grab`; |
||||
|
}, window.Cesium.ScreenSpaceEventType.MIDDLE_DOWN); |
||||
|
handler.setInputAction((event) => { |
||||
|
if (clearId != null) { |
||||
|
clearTimeout(clearId); |
||||
|
clearId = null; |
||||
|
} |
||||
|
cursorCss.value = `grab`; |
||||
|
}, window.Cesium.ScreenSpaceEventType.MIDDLE_UP); |
||||
|
let clearId = null; |
||||
|
handler.setInputAction((event) => { |
||||
|
if (event > 0) { |
||||
|
cursorCss.value = `zoom-in`; |
||||
|
} else { |
||||
|
cursorCss.value = `zoom-out`; |
||||
|
} |
||||
|
|
||||
|
clearId = setTimeout(() => { |
||||
|
clearTimeout(clearId); |
||||
|
cursorCss.value = `grab` |
||||
|
}, 2000); |
||||
|
}, window.Cesium.ScreenSpaceEventType.WHEEL); |
||||
|
// window.earth.onclick = function () { |
||||
|
// console.log(1); |
||||
|
// } |
||||
|
} |
||||
|
//添加地图上的监听事件-选取区域 |
||||
|
const listenMouseHandlerSelect = function () { |
||||
|
// window.$earth.interaction.picking.enabled = true; |
||||
|
// window.$earth.interaction.picking.clickedColor = [1, 0, 0, 1]; |
||||
|
const _handler = new window.Cesium.ScreenSpaceEventHandler( |
||||
|
_viewer.scene.canvas |
||||
|
); |
||||
|
// window.CesiumGlobalHandler = handler; |
||||
|
// 取消双击旋转事件 |
||||
|
_viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction( |
||||
|
window.Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK |
||||
|
); |
||||
|
_handler.setInputAction((click) => { |
||||
|
// 判断点击位置是否有实体 |
||||
|
//返回具有 `primitive` 属性的对象,该属性包含场景中特定窗口坐标处的第一个(顶部)图元,如果该位置没有任何内容,则返回未定义的对象。其他属性可能会根据基元的类型进行设置,并可用于进一步识别拾取的对象。 |
||||
|
let pickedFeature = _viewer.scene.pick(click.position); |
||||
|
// console.log("pick", pickedFeature); |
||||
|
|
||||
|
let entity = pickedFeature && pickedFeature.id; |
||||
|
if (entity == undefined) { return; } |
||||
|
//区域选取 |
||||
|
else if (typeof pickedFeature !== 'undefined' && entity.name == '区域选取') { |
||||
|
console.log("entity", entity); |
||||
|
//右键菜单 |
||||
|
entity.showProperty() |
||||
|
} |
||||
|
|
||||
|
}, window.Cesium.ScreenSpaceEventType.RIGHT_CLICK); //右键事件 |
||||
|
|
||||
|
} |
||||
|
// 获取其他切片 |
||||
|
const getDataSource = async function () { |
||||
|
const params = { |
||||
|
pageNo: 1, |
||||
|
pageSize: 9999, |
||||
|
status: 1, |
||||
|
} |
||||
|
return getMapPage(params).then( |
||||
|
(res) => { |
||||
|
if (res.code == 200) { |
||||
|
const loyaut = { |
||||
|
ref: "loyauts", |
||||
|
expand: false, |
||||
|
title: "地图图层", |
||||
|
children: [] |
||||
|
} |
||||
|
const records = res.result.records; |
||||
|
records.forEach(item => { |
||||
|
const czmObject = JSON.parse(item.czmObject); |
||||
|
const child = { |
||||
|
ref: item.id, |
||||
|
czmObject: czmObject, |
||||
|
enabled: true, |
||||
|
} |
||||
|
loyaut.children.push(child); |
||||
|
}); |
||||
|
window.earth.sceneTree.root.children.push(loyaut); |
||||
|
|
||||
|
const loyauts = window.earth.sceneTree.$refs["loyauts"].children; |
||||
|
editTileModelFunc(loyauts); |
||||
|
// 添加监听 |
||||
|
watch([modelText, enableTile], ([newVal, newVal1], [oldValue, oldValue1]) => { |
||||
|
// 在模式为3D,并且启用切片的时候,将其他的切片展示出来 |
||||
|
if (newVal == "3D" && newVal1) { |
||||
|
loyauts.forEach(loyaut => { |
||||
|
if (loyaut.czmObject.xbsjType == "Tileset") { |
||||
|
loyaut.enabled = true; |
||||
|
} |
||||
|
if (CModel.value) { |
||||
|
CModel.value.enabled = true; |
||||
|
} |
||||
|
}); |
||||
|
} else if (newVal == "2D" || !newVal1) { |
||||
|
// 禁用3D切片 |
||||
|
loyauts.forEach(loyaut => { |
||||
|
if (loyaut.czmObject.xbsjType == "Tileset") { |
||||
|
loyaut.enabled = false; |
||||
|
} |
||||
|
if (CModel.value) { |
||||
|
CModel.value.enabled = false; |
||||
|
} |
||||
|
}); |
||||
|
} |
||||
|
}) |
||||
|
} else { |
||||
|
message.error("无法显示数据!"); |
||||
|
} |
||||
|
} |
||||
|
).catch( |
||||
|
(e) => { |
||||
|
message.error("无法显示数据!"); |
||||
|
} |
||||
|
) |
||||
|
} |
||||
|
// 放大缩小弹窗 |
||||
|
const scaleWin = reactive({ |
||||
|
status: false |
||||
|
}) |
||||
|
const scaleWinFunc = function () { |
||||
|
const el = document.getElementsByClassName("EarthMap")[0].querySelector(".ant-modal-content"); |
||||
|
if (!scaleWin.status) { |
||||
|
const width = window.innerWidth; |
||||
|
el.setAttribute("style", `width:${width}px;position:fixed;left:0;top:0;`); |
||||
|
scaleWin.status = true; |
||||
|
} else { |
||||
|
el.removeAttribute("style"); |
||||
|
scaleWin.status = false; |
||||
|
} |
||||
|
} |
||||
|
// 模型定位 |
||||
|
const modelDw = ref(false); |
||||
|
const modelDwFunc = function (e) { |
||||
|
modelScaleStatus.value = false; |
||||
|
if (!modelDw.value) { |
||||
|
window.CesiumGlobalHandler.setInputAction( |
||||
|
modelFollowMouse, window.Cesium.ScreenSpaceEventType.MOUSE_MOVE |
||||
|
); |
||||
|
modelDw.value = true; |
||||
|
} else { |
||||
|
window.CesiumGlobalHandler.removeInputAction(window.Cesium.ScreenSpaceEventType.MOUSE_MOVE) |
||||
|
modelDw.value = false |
||||
|
} |
||||
|
} |
||||
|
// 模型平移 |
||||
|
const modelMove = ref(false); |
||||
|
const modelMoveFunc = function (e) { |
||||
|
if (!CModel.value) { |
||||
|
return; |
||||
|
} |
||||
|
if (!modelMove.value) { |
||||
|
if (CModel.value.enabled == false) { |
||||
|
CModel.value.enabled = true; |
||||
|
} |
||||
|
CModel.value.czmObject.positionEditing = true; |
||||
|
modelRotation.value = false; |
||||
|
modelMove.value = true; |
||||
|
} else { |
||||
|
CModel.value.czmObject.positionEditing = false; |
||||
|
modelMove.value = false |
||||
|
} |
||||
|
} |
||||
|
// 模型旋转 |
||||
|
const modelRotation = ref(false); |
||||
|
const modelRotationFunc = function (e) { |
||||
|
if (!CModel.value) { |
||||
|
return; |
||||
|
} |
||||
|
if (!modelRotation.value) { |
||||
|
if (CModel.value.enabled == false) { |
||||
|
CModel.value.enabled = true; |
||||
|
} |
||||
|
CModel.value.czmObject.rotationEditing = true; |
||||
|
modelMove.value = false; |
||||
|
modelRotation.value = true; |
||||
|
} else { |
||||
|
CModel.value.czmObject.rotationEditing = false; |
||||
|
modelRotation.value = false |
||||
|
} |
||||
|
} |
||||
|
// 模型大小比例 |
||||
|
const scaleValues = ref([1, 1, 1]); |
||||
|
const modelScaleStatus = ref(false); |
||||
|
// 模型放大缩小状态的切换 |
||||
|
const modelScaleStatusChange = function () { |
||||
|
modelScaleStatus.value = !modelScaleStatus.value; |
||||
|
} |
||||
|
// 放大缩小值的配置 |
||||
|
const scaleConfigObj = { |
||||
|
X: { |
||||
|
min: -10, |
||||
|
max: 10, |
||||
|
step: 1, |
||||
|
show: false, |
||||
|
}, |
||||
|
Y: { |
||||
|
min: -10, |
||||
|
max: 10, |
||||
|
step: 1, |
||||
|
show: false, |
||||
|
}, |
||||
|
Z: { |
||||
|
min: -10, |
||||
|
max: 10, |
||||
|
step: 1, |
||||
|
show: false, |
||||
|
}, |
||||
|
}; |
||||
|
const scaleConfig = ref( |
||||
|
{ |
||||
|
...scaleConfigObj |
||||
|
} |
||||
|
) |
||||
|
// xyz所有轴都应用同一设置 |
||||
|
const allSetting = function (propName) { |
||||
|
const keys = Object.keys(scaleConfig.value); |
||||
|
const beCopyObj = scaleConfig.value[propName]; |
||||
|
keys.forEach(key => { |
||||
|
scaleConfig.value[key] = { ...beCopyObj, show: scaleConfig.value[key].show } |
||||
|
}); |
||||
|
} |
||||
|
// 监听放大缩小值的变化 |
||||
|
watch(scaleValues, (new_scale, scale) => { |
||||
|
if (!CModel.value || !CModel.value.czmObject) { |
||||
|
return; |
||||
|
} |
||||
|
CModel.value.czmObject.xbsjScale = new_scale; |
||||
|
}, { |
||||
|
deep: true |
||||
|
}) |
||||
|
// 销毁缓存 |
||||
|
const destroyCache = function () { |
||||
|
scaleConfig.value = { ...scaleConfigObj }; |
||||
|
scaleValues.value = [1, 1, 1]; |
||||
|
modelRotation.value = false; |
||||
|
modelMove.value = false; |
||||
|
scaleWin.value = false; |
||||
|
modelScaleStatus.value = false; |
||||
|
modelDw.value = false; |
||||
|
enableTile.value = false; |
||||
|
|
||||
|
// window.CesiumGlobalHandler.removeInputAction(window.Cesium.ScreenSpaceEventType.MOUSE_MOVE) |
||||
|
// window.CesiumGlobalHandler.removeInputAction(window.Cesium.ScreenSpaceEventType.LEFT_DOWN) |
||||
|
// window.CesiumGlobalHandler.removeInputAction(window.Cesium.ScreenSpaceEventType.LEFT_UP) |
||||
|
// window.CesiumGlobalHandler.removeInputAction(window.Cesium.ScreenSpaceEventType.MIDDLE_DOWN) |
||||
|
// window.CesiumGlobalHandler.removeInputAction(window.Cesium.ScreenSpaceEventType.MIDDLE_UP) |
||||
|
// window.CesiumGlobalHandler.removeInputAction(window.Cesium.ScreenSpaceEventType.WHEEL) |
||||
|
|
||||
|
CModel.value && CModel.value.destroy(); |
||||
|
earth && earth.destroy(); |
||||
|
|
||||
|
modelText.value = "2D"; |
||||
|
scaleWin.status = false; |
||||
|
} |
||||
|
defineExpose( |
||||
|
{ |
||||
|
CModel |
||||
|
} |
||||
|
); |
||||
|
</script> |
||||
|
<style scoped> |
||||
|
|
||||
|
.fill-9-row { |
||||
|
width: 90%; |
||||
|
} |
||||
|
|
||||
|
.sliderRow { |
||||
|
display: flex; |
||||
|
justify-content: center; |
||||
|
align-items: center; |
||||
|
min-height: 50px; |
||||
|
} |
||||
|
|
||||
|
.sliderContainer { |
||||
|
width: 200px; |
||||
|
} |
||||
|
|
||||
|
.iconSize { |
||||
|
width: 16px; |
||||
|
height: 16px; |
||||
|
} |
||||
|
|
||||
|
.colorBlue { |
||||
|
color: #1296db !important; |
||||
|
} |
||||
|
|
||||
|
.iconSpan { |
||||
|
color: #fff; |
||||
|
display: block; |
||||
|
width: 36px; |
||||
|
height: 36px; |
||||
|
font-size: 16px; |
||||
|
font-style: normal; |
||||
|
line-height: 36px; |
||||
|
text-align: center; |
||||
|
text-transform: none; |
||||
|
text-rendering: auto; |
||||
|
background-color: rgba(0, 0, 0, 0.4); |
||||
|
cursor: pointer; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
justify-content: center; |
||||
|
} |
||||
|
|
||||
|
.selectIcon { |
||||
|
position: absolute; |
||||
|
top: 108px; |
||||
|
left: 0; |
||||
|
} |
||||
|
|
||||
|
.clearIcon { |
||||
|
position: absolute; |
||||
|
top: 144px; |
||||
|
left: 0; |
||||
|
} |
||||
|
|
||||
|
.modelScale { |
||||
|
position: absolute; |
||||
|
top: 252px; |
||||
|
left: 0; |
||||
|
} |
||||
|
|
||||
|
.modelRotation { |
||||
|
position: absolute; |
||||
|
top: 216px; |
||||
|
left: 0; |
||||
|
} |
||||
|
|
||||
|
.modelMove { |
||||
|
position: absolute; |
||||
|
top: 180px; |
||||
|
left: 0; |
||||
|
} |
||||
|
|
||||
|
.modelDw { |
||||
|
position: absolute; |
||||
|
top: 144px; |
||||
|
left: 0; |
||||
|
} |
||||
|
|
||||
|
.scaleWin { |
||||
|
position: absolute; |
||||
|
top: 36px; |
||||
|
left: 0; |
||||
|
} |
||||
|
|
||||
|
.mapModel { |
||||
|
position: absolute; |
||||
|
top: 72px; |
||||
|
left: 0; |
||||
|
} |
||||
|
|
||||
|
.buildManage { |
||||
|
position: absolute; |
||||
|
top: 108px; |
||||
|
left: 0; |
||||
|
} |
||||
|
|
||||
|
:deep(.ant-modal-body) { |
||||
|
padding: 0px !important; |
||||
|
} |
||||
|
|
||||
|
:deep(.ant-modal-close-x) { |
||||
|
color: #fff; |
||||
|
background-color: rgba(0, 0, 0, 0.4); |
||||
|
width: 36px; |
||||
|
height: 36px; |
||||
|
line-height: 36px; |
||||
|
} |
||||
|
</style> |
Loading…
Reference in new issue