DIAMOND
11 months ago
7 changed files with 897 additions and 1316 deletions
@ -0,0 +1,350 @@ |
|||
<!-- |
|||
|
|||
使用EarthMapModal组件 编辑监控杆功能 |
|||
已被弃用 |
|||
|
|||
--> |
|||
<template> |
|||
<a-spin :spinning="confirmLoading"> |
|||
<a-form ref="formRef" class="antd-modal-form" :labelCol="labelCol" :wrapperCol="wrapperCol"> |
|||
<a-row> |
|||
<a-col :span="24"> |
|||
<a-form-item label="防区" v-bind="validateInfos.lineId"> |
|||
<!-- <j-dict-select-tag v-model:value="formData.lineId" dictCode="" placeholder="" :disabled="disabled"/> --> |
|||
<a-select |
|||
v-model:value="formData.lineId" |
|||
style="width: 300px" |
|||
@change="changeLineValue" |
|||
:disabled="disabled" |
|||
placeholder="请选择所属防区" |
|||
> |
|||
<a-select-option v-for="(item, index) in lineSelect" :value="item.id" :key="item.id"> |
|||
{{ item.name }} |
|||
</a-select-option> |
|||
</a-select> |
|||
</a-form-item> |
|||
</a-col> |
|||
<a-col :span="24"> |
|||
<a-form-item label="点位序号" v-bind="validateInfos.sitecode"> |
|||
<a-input v-model:value="formData.sitecode" placeholder="请输入点位序号" :disabled="disabled"></a-input> |
|||
</a-form-item> |
|||
</a-col> |
|||
<a-col :span="24"> |
|||
<a-form-item label="点位名称" v-bind="validateInfos.sitename"> |
|||
<a-input v-model:value="formData.sitename" placeholder="请输入点位名称" :disabled="disabled"></a-input> |
|||
</a-form-item> |
|||
</a-col> |
|||
<template v-if="disabled == false"> |
|||
<a-col :span="24"> |
|||
<a-form-item label="位置"> |
|||
<a><img :src="locationPng" class="dwImg" @click="mapShow" /></a> |
|||
</a-form-item> |
|||
</a-col> |
|||
|
|||
<!-- <a-modal title="点位设置" :visible="mapVisible" @ok="earthMapOk" @cancel="destroyed" width="60vw" destroyOnClose |
|||
wrapClassName="EarthMap"> |
|||
<a-row style="height: 60vh;"> |
|||
<a-col :span="24"> |
|||
<EarthComp |
|||
ref="earth" |
|||
@customFly="moveChinaPosition" |
|||
:hasMoveMethod="subObject && subObject.id ? true : false" |
|||
:enablePointer="true" |
|||
:listenMouseHandlerSenceOpen="true" |
|||
@checkPosition="checkPositionCache" |
|||
/> |
|||
</a-col> |
|||
</a-row> |
|||
</a-modal> --> |
|||
<EarthMapModal |
|||
ref="earthMapModal" |
|||
:enableTile="false" |
|||
:visible="mapVisible" |
|||
@closeWin=" |
|||
() => { |
|||
mapVisible = false; |
|||
} |
|||
" |
|||
@checkPosition="checkPosition" |
|||
:hasMoveMethod="true" |
|||
@moveChinaPosition="moveChinaPosition" |
|||
:editTileModel="mapModel" |
|||
initModeType="3D" |
|||
:enable-pointer="false" |
|||
> |
|||
</EarthMapModal> |
|||
</template> |
|||
<a-col :span="24"> |
|||
<a-form-item label="经度" v-bind="validateInfos.longitude"> |
|||
<a-input-number v-model:value="formData.longitude" placeholder="请输入经度" style="width: 100%" :disabled="disabled" /> |
|||
</a-form-item> |
|||
</a-col> |
|||
<a-col :span="24"> |
|||
<a-form-item label="纬度" v-bind="validateInfos.latitude"> |
|||
<a-input-number v-model:value="formData.latitude" placeholder="请输入纬度" style="width: 100%" :disabled="disabled" /> |
|||
</a-form-item> |
|||
</a-col> |
|||
<a-col :span="24"> |
|||
<a-form-item label="高度" v-bind="validateInfos.height"> |
|||
<a-input-number v-model:value="formData.height" placeholder="请输入高度" style="width: 100%" :disabled="disabled" /> |
|||
</a-form-item> |
|||
</a-col> |
|||
<a-col :span="24"> |
|||
<a-form-item label="偏航角" v-bind="validateInfos.yaw"> |
|||
<a-input-number v-model:value="formData.yaw" placeholder="请输入偏航角" style="width: 100%" :disabled="disabled" /> |
|||
</a-form-item> |
|||
</a-col> |
|||
<a-col :span="24"> |
|||
<a-form-item label="俯仰角" v-bind="validateInfos.pitch"> |
|||
<a-input-number v-model:value="formData.pitch" placeholder="请输入俯仰角" style="width: 100%" :disabled="disabled" /> |
|||
</a-form-item> |
|||
</a-col> |
|||
<a-col :span="24"> |
|||
<a-form-item label="翻转角" v-bind="validateInfos.roll"> |
|||
<a-input-number v-model:value="formData.roll" placeholder="请输入翻转角" style="width: 100%" :disabled="disabled" /> |
|||
</a-form-item> |
|||
</a-col> |
|||
</a-row> |
|||
</a-form> |
|||
</a-spin> |
|||
</template> |
|||
|
|||
<script lang="ts" setup> |
|||
import { ref, reactive, nextTick, computed, onMounted } from 'vue'; |
|||
import { defHttp } from '/@/utils/http/axios'; |
|||
import { useMessage } from '/@/hooks/web/useMessage'; |
|||
// import JDictSelectTag from '/@/components/Form/src/jeecg/components/JDictSelectTag.vue'; |
|||
import { getValueType } from '/@/utils'; |
|||
import { saveOrUpdate } from '../MsCameraSite.api'; |
|||
import { Form } from 'ant-design-vue'; |
|||
import EarthMapModal from '@/views/military/modules/earthMap/scene/model/mapModel/EarthMapModal.vue'; |
|||
import locationPng from '@/assets/images/getLocation.png'; |
|||
import { useUserStore } from '/@/store/modules/user'; |
|||
import EarthComp from '@/views/earthMap/edit/EarthComp.vue'; |
|||
|
|||
const userStore = useUserStore(); |
|||
const lineSelect: any = ref([]); |
|||
const props = defineProps({ |
|||
formDisabled: { type: Boolean, default: false }, |
|||
formData: { type: Object, default: () => {} }, |
|||
formBpm: { type: Boolean, default: true }, |
|||
}); |
|||
const formRef = ref(); |
|||
const useForm = Form.useForm; |
|||
const emit = defineEmits(['register', 'ok']); |
|||
const formData = reactive<Record<string, any>>({ |
|||
id: undefined, |
|||
lineId: undefined, |
|||
sitecode: '', |
|||
sitename: '', |
|||
longitude: undefined, |
|||
latitude: undefined, |
|||
height: undefined, |
|||
yaw: undefined, |
|||
pitch: undefined, |
|||
roll: undefined, |
|||
}); |
|||
const { createMessage } = useMessage(); |
|||
const labelCol = ref<any>({ xs: { span: 24 }, sm: { span: 5 } }); |
|||
const wrapperCol = ref<any>({ xs: { span: 24 }, sm: { span: 16 } }); |
|||
const confirmLoading = ref<boolean>(false); |
|||
//表单验证 |
|||
const validatorRules = { |
|||
sitecode: [{ required: true, message: '请输入点位序号!' }], |
|||
sitename: [{ required: true, message: '请输入点位名称!' }], |
|||
longitude: [{ required: true, message: '请输入经度!' }], |
|||
latitude: [{ required: true, message: '请输入纬度!' }], |
|||
lineId: [{ required: true, message: '请选择所属防区!' }], |
|||
}; |
|||
const { resetFields, validate, validateInfos } = useForm(formData, validatorRules, { immediate: true }); |
|||
|
|||
// 表单禁用 |
|||
const disabled = computed(() => { |
|||
if (props.formBpm === true) { |
|||
if (props.formData.disabled === false) { |
|||
return false; |
|||
} else { |
|||
return true; |
|||
} |
|||
} |
|||
return props.formDisabled; |
|||
}); |
|||
|
|||
onMounted(() => { |
|||
setSelectList(); |
|||
}); |
|||
//线路选择框 |
|||
function setSelectList() { |
|||
// defHttp |
|||
// .get( |
|||
// { |
|||
// url: '/military/msMapLine/mapLineSelect', |
|||
// }, |
|||
// { isTransformResponse: false } |
|||
// ) |
|||
// // getAction(this.url.querySelectList, {}) |
|||
// .then((res) => { |
|||
// if (res.success) { |
|||
// lineSelect.value = res.result; |
|||
// } |
|||
// }); |
|||
defHttp |
|||
.get( |
|||
{ |
|||
url: '/military/msMapLine/list', |
|||
params: { |
|||
sceneId: userStore.userInfo?.sceneId + "*" |
|||
}, |
|||
},{ isTransformResponse: false }) |
|||
.then((res) => { |
|||
if (res.success) { |
|||
lineSelect.value = res.result.records; |
|||
} |
|||
}); |
|||
|
|||
|
|||
} |
|||
|
|||
/** |
|||
* 新增 |
|||
*/ |
|||
function add() { |
|||
edit({}); |
|||
} |
|||
|
|||
/** |
|||
* 编辑 |
|||
*/ |
|||
function edit(record) { |
|||
nextTick(() => { |
|||
resetFields(); |
|||
//赋值 |
|||
Object.assign(formData, record); |
|||
}); |
|||
} |
|||
|
|||
/** |
|||
* 提交数据 |
|||
*/ |
|||
async function submitForm() { |
|||
// 触发表单验证 |
|||
await validate(); |
|||
confirmLoading.value = true; |
|||
const isUpdate = ref<boolean>(false); |
|||
//时间格式化 |
|||
let model = formData; |
|||
if (model.id) { |
|||
isUpdate.value = true; |
|||
} |
|||
//循环数据 |
|||
for (let data in model) { |
|||
//如果该数据是数组并且是字符串类型 |
|||
if (model[data] instanceof Array) { |
|||
let valueType = getValueType(formRef.value.getProps, data); |
|||
//如果是字符串类型的需要变成以逗号分割的字符串 |
|||
if (valueType === 'string') { |
|||
model[data] = model[data].join(','); |
|||
} |
|||
} |
|||
} |
|||
await saveOrUpdate(model, isUpdate.value) |
|||
.then((res) => { |
|||
if (res.success) { |
|||
createMessage.success(res.message); |
|||
emit('ok'); |
|||
} else { |
|||
createMessage.warning(res.message); |
|||
} |
|||
}) |
|||
.finally(() => { |
|||
confirmLoading.value = false; |
|||
}); |
|||
} |
|||
function changeLineValue(item, option) { |
|||
formData.lineId = option.key; |
|||
} |
|||
|
|||
// 弹窗地图框属性 |
|||
const mapVisible = ref(false); |
|||
const mapModel = ref(); |
|||
const mapShow = function () { |
|||
mapModel.value = { |
|||
custom: { |
|||
id: formData.id, |
|||
}, |
|||
czmObject: { |
|||
name: formData.sitename, |
|||
xbsjType: 'Model', |
|||
url: '/dt/sys/common/static/' + formData.modelUrl, |
|||
// "color": [0.52, 0.6, 0.58, 1], |
|||
minimumPixelSize: formData.minimumPixelSize, |
|||
// maximumScale: 0.02, |
|||
scale: formData.scale, |
|||
xbsjScale: formData.xyzScale ? formData.xyzScale.split(',') : [1, 1, 1], |
|||
xbsjPosition: [window.Cesium.Math.toRadians(formData.longitude), window.Cesium.Math.toRadians(formData.latitude), formData.height], |
|||
xbsjRotation: [ |
|||
window.Cesium.Math.toRadians(formData.yaw), |
|||
window.Cesium.Math.toRadians(formData.pitch), |
|||
window.Cesium.Math.toRadians(formData.roll), |
|||
], |
|||
viewDistance: 150, |
|||
distanceDisplayCondition: [1.0, 30000.0], |
|||
}, |
|||
}; |
|||
|
|||
mapVisible.value = true; |
|||
}; |
|||
|
|||
const checkPosition = function (position, rotation, fov) { |
|||
const CMath = window.Cesium.Math; |
|||
formData.longitude = CMath.toDegrees(position[0]); |
|||
formData.latitude = CMath.toDegrees(position[1]); |
|||
formData.height = CMath.toDegrees(position[2]); |
|||
|
|||
formData.yaw = CMath.toDegrees(rotation[0]); |
|||
formData.pitch = CMath.toDegrees(rotation[1]); |
|||
formData.roll = CMath.toDegrees(rotation[2]); |
|||
|
|||
// subObject.value.viewDistance = fov; |
|||
}; |
|||
const earthMapModal: any = ref(null); |
|||
// 打开地图时飞入到指定位置 |
|||
const moveChinaPosition = function () { |
|||
earthMapModal.value.CModel.czmObject.flyTo(); |
|||
// const CMath = window.Cesium.Math; |
|||
// window.earth.camera.position = [CMath.toRadians(formData.longitude) - 0.000001, CMath.toRadians(formData.latitude) - 0.000001, CMath.toRadians(formData.height) - 0.000001]; |
|||
// window.earth.camera.rotation = [CMath.toRadians(formData.yaw), CMath.toRadians(formData.pitch), CMath.toRadians(formData.roll)] |
|||
}; |
|||
|
|||
|
|||
const earth = ref() |
|||
function destroyed() { |
|||
// console.log("earth", earth.value); |
|||
earth.value.destroy(); |
|||
nextTick(() => { |
|||
mapVisible.value = false |
|||
}) |
|||
|
|||
} |
|||
|
|||
defineExpose({ |
|||
add, |
|||
edit, |
|||
submitForm, |
|||
earth, |
|||
destroyed |
|||
}); |
|||
</script> |
|||
|
|||
<style lang="less" scoped> |
|||
.antd-modal-form { |
|||
min-height: 500px !important; |
|||
overflow-y: auto; |
|||
padding: 24px 24px 24px 24px; |
|||
} |
|||
|
|||
.dwImg { |
|||
width: 32px; |
|||
height: 32px; |
|||
} |
|||
</style> |
@ -1,827 +0,0 @@ |
|||
<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