| | |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { computed, nextTick, ref } from 'vue' |
| | | import { computed, nextTick, ref, watch } from 'vue' |
| | | import { ElMessage } from 'element-plus' |
| | | import { fwPoliceStationDetailApi, fwPoliceStationSubmitApi } from './precinctInfoApi' |
| | | import { fieldRules } from '@ztzf/utils' |
| | | import { contactPhoneRules, fieldRules } from '@ztzf/utils' |
| | | import CommonCesiumMap from '@/components/map-container/common-cesium-map.vue' |
| | | import * as Cesium from 'cesium' |
| | | import axios from 'axios' |
| | | import { saveOperationLog } from '@ztzf/apis' |
| | | import { useRoute } from 'vue-router' |
| | | import positionIcon from '@/assets/images/areaManage/positionIcon.png' |
| | | import { MapTooltip } from '@ztzf/utils' |
| | | |
| | | const initForm = () => ({ |
| | | address: '', // 位置 |
| | |
| | | address: fieldRules(true, 50), |
| | | stationName: fieldRules(true, 50), |
| | | contactPerson: fieldRules(true, 50), |
| | | contactPhone: fieldRules(true, 50), |
| | | contactPhone: contactPhoneRules(true, 50), |
| | | longitude: fieldRules(true), |
| | | } |
| | | |
| | |
| | | let viewer |
| | | let redPointEntity |
| | | let leftClickBound = false |
| | | let mouseMoveBound = false |
| | | let mapTooltip |
| | | let publicCesium |
| | | const tooltipEventKey = 'precinct-info-point-tip' |
| | | const labelParams = { |
| | | font: '16px', |
| | | font: '18px', |
| | | fillColor: Cesium.Color.WHITE, // 文字颜色:白色 |
| | | backgroundColor: Cesium.Color.BLACK, //背景颜色 |
| | | backgroundPadding: new Cesium.Cartesian2(5, 5), // 水平/垂直内边距(像素) |
| | |
| | | } |
| | | |
| | | function LeftClickEvent(click) { |
| | | const pos = click.position // Cartesian2 屏幕坐标 |
| | | // 屏幕坐标 -> 椭球面坐标(不考虑地形/模型) |
| | | const cartesian3 = viewer.camera.pickEllipsoid(pos, viewer.scene.globe.ellipsoid) |
| | | if (!cartesian3) { |
| | | return { longitude: 112, latitude: 23 } |
| | | const pos = click.position |
| | | // 优先使用 pickPosition 获取贴地坐标(包含地形高度) |
| | | let cartesian3 = viewer.scene.pickPosition(pos) |
| | | // 如果 pickPosition 失败,回退到 pickEllipsoid |
| | | if (!cartesian3 || !Cesium.defined(cartesian3)) { |
| | | cartesian3 = viewer.camera.pickEllipsoid(pos, viewer.scene.globe.ellipsoid) |
| | | } |
| | | // 椭球面坐标 -> 经纬度 |
| | | if (!cartesian3) return |
| | | const carto = Cesium.Cartographic.fromCartesian(cartesian3) |
| | | const longitude = Cesium.Math.toDegrees(carto.longitude) |
| | | const latitude = Cesium.Math.toDegrees(carto.latitude) |
| | | // 直接更新 formData |
| | | formData.value.longitude = _.round(longitude, 6) |
| | | formData.value.latitude = _.round(latitude, 6) |
| | | getLocationName(longitude, latitude) |
| | |
| | | if (!redPointEntity) { |
| | | redPointEntity = viewer.entities.add({ |
| | | position: Cesium.Cartesian3.fromDegrees(longitude, latitude), |
| | | point: { |
| | | color: Cesium.Color.RED, |
| | | pixelSize: 10, |
| | | billboard: { |
| | | image: positionIcon, |
| | | width: 20, |
| | | height: 20, |
| | | verticalOrigin: Cesium.VerticalOrigin.CENTER, |
| | | heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, |
| | | }, |
| | | label: { |
| | | text: `${longitude.toFixed(6)}, ${latitude.toFixed(6)}`, |
| | | ...labelParams |
| | | ...labelParams, |
| | | }, |
| | | }) |
| | | } else { |
| | |
| | | if (!redPointEntity) { |
| | | redPointEntity = viewer.entities.add({ |
| | | position: Cesium.Cartesian3.fromDegrees(longitude, latitude), |
| | | point: { |
| | | color: Cesium.Color.RED, |
| | | pixelSize: 10, |
| | | billboard: { |
| | | image: positionIcon, |
| | | width: 20, |
| | | height: 20, |
| | | verticalOrigin: Cesium.VerticalOrigin.CENTER, |
| | | heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, |
| | | }, |
| | | label: { |
| | | text: `${longitude.toFixed(6)}, ${latitude.toFixed(6)}`, |
| | | ...labelParams |
| | | ...labelParams, |
| | | }, |
| | | }) |
| | | } else { |
| | |
| | | await nextTick() |
| | | const map = inlineMapRef.value?.getMap() |
| | | viewer = map?.viewer || null |
| | | publicCesium = map?.publicCesium || null |
| | | if (viewer && !leftClickBound) { |
| | | map.publicCesium?.addLeftClickEvent?.(null, LeftClickEvent) |
| | | leftClickBound = true |
| | | } |
| | | if (viewer && !readonly.value) { |
| | | ensurePointTooltip() |
| | | } |
| | | if (formData.value.longitude != null && formData.value.latitude != null) { |
| | | setMapPoint(formData.value.longitude, formData.value.latitude) |
| | | } |
| | | } |
| | | |
| | | function ensurePointTooltip() { |
| | | if (!viewer || !publicCesium || mouseMoveBound) return |
| | | mapTooltip ||= new MapTooltip(viewer, { offset: { x: 16, y: 24 } }) |
| | | publicCesium.addMouseHandler?.( |
| | | null, |
| | | movement => { |
| | | if (!visible.value || readonly.value) return |
| | | mapTooltip?.show('点击地图选择派出所位置', movement.endPosition) |
| | | }, |
| | | tooltipEventKey |
| | | ) |
| | | mouseMoveBound = true |
| | | } |
| | | |
| | | function clearPointTooltip() { |
| | | mapTooltip?.hide() |
| | | if (publicCesium && mouseMoveBound) { |
| | | publicCesium.removeMouseHandler?.(tooltipEventKey) |
| | | mouseMoveBound = false |
| | | } |
| | | } |
| | | |
| | |
| | | formData.value = dialogMode.value === 'add' ? initForm() : row |
| | | redPointEntity = null |
| | | leftClickBound = false |
| | | clearPointTooltip() |
| | | if (dialogMode.value !== 'add') { |
| | | await loadDetail() |
| | | } |
| | |
| | | }, 500) |
| | | } |
| | | |
| | | watch( |
| | | () => visible.value, |
| | | val => { |
| | | if (!val) { |
| | | clearPointTooltip() |
| | | } |
| | | } |
| | | ) |
| | | |
| | | defineExpose({ open }) |
| | | </script> |
| | | <style scoped lang="scss"> |