From 824c980dbc31b63b1ceee42cefa10286a3761dc8 Mon Sep 17 00:00:00 2001 From: wzy-warehouse <18135009705@163.com> Date: Sat, 11 Apr 2026 18:58:43 +0800 Subject: [PATCH] =?UTF-8?q?=E9=87=8D=E6=9E=84=E9=A3=8E=E9=99=A9=E7=82=B9?= =?UTF-8?q?=E9=9A=90=E6=82=A3=E7=82=B9=E6=98=BE=E7=A4=BA=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/api.ts | 17 +++- src/api/hidden-danger-spots.ts | 4 +- src/api/risk-spots.ts | 20 ++++ src/assets/images/icon/risk-area.png | Bin 0 -> 4043 bytes src/component/map/Map.vue | 39 +++++++- .../rain-earthquake/BasicComponent.vue | 6 +- .../rain-earthquake/HiddenPointComponent.vue | 92 ++++++++---------- .../rain-earthquake/LoadingPoints.vue | 7 +- .../rain-earthquake/RiskPointComponent.vue | 90 +++++++++++++++++ src/hooks/usePointsHandle.ts | 18 ++-- src/stores/useLoadingInformation.ts | 52 ++++++++++ src/types/base/XianRiskSpots.ts | 42 ++++++++ src/utils/cesium/CesiumUtils.ts | 1 - src/views/home/earthquake/Earthquake.vue | 6 +- src/views/home/rainstorm/Rainstorm.vue | 5 +- 15 files changed, 320 insertions(+), 79 deletions(-) create mode 100644 src/api/risk-spots.ts create mode 100644 src/assets/images/icon/risk-area.png create mode 100644 src/component/rain-earthquake/RiskPointComponent.vue create mode 100644 src/stores/useLoadingInformation.ts create mode 100644 src/types/base/XianRiskSpots.ts diff --git a/src/api/api.ts b/src/api/api.ts index 6f8840d..097075c 100644 --- a/src/api/api.ts +++ b/src/api/api.ts @@ -1,8 +1,10 @@ import type { DisasterType } from '@/types/common/DisasterType' import { getSm2PublicKey } from './crypto' -import { getBasePoins, getPointDetailById } from './hidden-danger-spots' +import { getBasePoins as getHiddenDangerBasePoints, getPointDetailById as getHiddenDangerPointDetailById} from './hidden-danger-spots' +import { getBasePoins as getRiskBasePoints, getPointDetailById as getRiskPointDetailById} from './risk-spots' import type { ApiResponse } from '@/types/ApiResponse' import type { XianHiddenDangerSpots } from '@/types/base/XianHiddenDangerSpots' +import type { XianRiskSpots } from '@/types/base/XianRiskSpots' export const $api = { @@ -15,9 +17,18 @@ export const $api = { // 隐患点信息 hiddenDangerSpots: { // 获取所有基础隐患点 - getBasePoins: (disasterType: DisasterType): Promise> => getBasePoins(disasterType), + getBasePoins: (disasterType: DisasterType): Promise> => getHiddenDangerBasePoints(disasterType), // 根据id获取隐患点详情 - getPointDetailById: (id: number): Promise> => getPointDetailById(id), + getPointDetailById: (id: number): Promise> => getHiddenDangerPointDetailById(id), + }, + + // 风险点信息 + riskSpots: { + // 获取所有基础风险点 + getBasePoins: (): Promise> => getRiskBasePoints(), + + // 根据id获取风险点详情 + getPointDetailById: (id: number): Promise> => getRiskPointDetailById(id), }, } diff --git a/src/api/hidden-danger-spots.ts b/src/api/hidden-danger-spots.ts index 0723bf2..95514cb 100644 --- a/src/api/hidden-danger-spots.ts +++ b/src/api/hidden-danger-spots.ts @@ -4,7 +4,7 @@ import type { DisasterType } from "@/types/common/DisasterType" import httpInstance from "@/utils/request/http" /** - * 获取隐藏危险点数据 + * 获取隐患点数据 * @param disasterType 灾害类型 * @returns 隐患点数据 */ @@ -18,7 +18,7 @@ export const getBasePoins = (disasterType: DisasterType): Promise> => { diff --git a/src/api/risk-spots.ts b/src/api/risk-spots.ts new file mode 100644 index 0000000..7d09944 --- /dev/null +++ b/src/api/risk-spots.ts @@ -0,0 +1,20 @@ +import type { ApiResponse } from "@/types/ApiResponse" +import type { XianRiskSpots } from "@/types/base/XianRiskSpots" +import httpInstance from "@/utils/request/http" + +/** + * 获取风险点数据 + * @returns 风险点数据 + */ +export const getBasePoins = (): Promise> => { + return httpInstance.get('/risk-spots/base-points') +} + +/** + * 根据id获取风险点详情 + * @param id 风险点id + * @returns 风险点详情 + */ +export const getPointDetailById = (id: number): Promise> => { + return httpInstance.get(`/risk-spots/point-detail/${id}`) +} \ No newline at end of file diff --git a/src/assets/images/icon/risk-area.png b/src/assets/images/icon/risk-area.png new file mode 100644 index 0000000000000000000000000000000000000000..22ee97eff1bfaeba895c5b55184d679b12a21158 GIT binary patch literal 4043 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 literal 0 HcmV?d00001 diff --git a/src/component/map/Map.vue b/src/component/map/Map.vue index 932dbdf..aa773cb 100644 --- a/src/component/map/Map.vue +++ b/src/component/map/Map.vue @@ -11,15 +11,14 @@ import config from '@/config/config.json'; import { CesiumUtilsSingleton } from '@/utils/cesium/CesiumUtils'; import AdministrativeDivision from './AdministrativeDivision.vue'; import { useViewerStore } from '@/stores/useViewerStore'; +import { useLoadingInformationStore } from '@/stores/useLoadingInformation'; onBeforeMount(() => { // 初始化为false useViewerStore().setViewerLoadingCompleted(false) - // 清除viewer相关资源 - if (CesiumUtilsSingleton.getViewer()) { - CesiumUtilsSingleton.clearAllResources('all') - } + // 重置状态 + useLoadingInformationStore().resetStatue() }) onMounted(() => { @@ -27,6 +26,38 @@ onMounted(() => { containerId: 'map-container' }) + // 注册全局点击监听器 + CesiumUtilsSingleton.clickLayer((pickedObject: any) => { + if (pickedObject && pickedObject.id && (typeof pickedObject.id === 'string')) { + const matchResult = pickedObject.id.match(/\d+$/) + const id = matchResult ? parseInt(matchResult[0]) : -1 + + // 当id改变时候,重置状态 + if (useLoadingInformationStore().getHiddenPointId() !== id && useLoadingInformationStore().getRiskPointId() !== id) { + useLoadingInformationStore().resetStatue() + } + + // 点击对象 + useLoadingInformationStore().setClickObject(pickedObject) + + // 隐患点 + if (pickedObject.id.startsWith(config.prefix.hiddenDangerPointId)) { + useLoadingInformationStore().setHiddenPointId(id) + } + + // 风险点 + else if (pickedObject.id.startsWith(config.prefix.riskPointId)) { + useLoadingInformationStore().setRiskPointId(id) + }else { + // 重置状态 + useLoadingInformationStore().resetStatue() + } + } else { + // 重置状态 + useLoadingInformationStore().resetStatue() + } + }) + // 更新完成状态 useViewerStore().setViewerLoadingCompleted(true) CesiumUtilsSingleton.viewToTarget(config.defaultPosition as [number, number, number]); diff --git a/src/component/rain-earthquake/BasicComponent.vue b/src/component/rain-earthquake/BasicComponent.vue index bde6f40..72c8fcf 100644 --- a/src/component/rain-earthquake/BasicComponent.vue +++ b/src/component/rain-earthquake/BasicComponent.vue @@ -5,10 +5,10 @@ - + - + @@ -16,6 +16,8 @@ import MapComponent from "@/component/map/Map.vue" import type { DisasterType } from "@/types/common/DisasterType"; import HiddenPointComponent from "./HiddenPointComponent.vue"; +import RiskPointComponent from "./RiskPointComponent.vue"; +import { useViewerStore } from "@/stores/useViewerStore"; // 获取父组件传递德数据 const props = defineProps<{ diff --git a/src/component/rain-earthquake/HiddenPointComponent.vue b/src/component/rain-earthquake/HiddenPointComponent.vue index ce3d734..7796a45 100644 --- a/src/component/rain-earthquake/HiddenPointComponent.vue +++ b/src/component/rain-earthquake/HiddenPointComponent.vue @@ -2,24 +2,20 @@ diff --git a/src/component/rain-earthquake/RiskPointComponent.vue b/src/component/rain-earthquake/RiskPointComponent.vue new file mode 100644 index 0000000..f36f77e --- /dev/null +++ b/src/component/rain-earthquake/RiskPointComponent.vue @@ -0,0 +1,90 @@ + + + + + + + + diff --git a/src/hooks/usePointsHandle.ts b/src/hooks/usePointsHandle.ts index 3375f77..7cfd1e9 100644 --- a/src/hooks/usePointsHandle.ts +++ b/src/hooks/usePointsHandle.ts @@ -2,7 +2,6 @@ import type { Point } from "@/types/base/Point"; import type { PrimitiveOptions } from "@/types/cesium/PrimitiveOptions"; import { CesiumUtilsSingleton } from "@/utils/cesium/CesiumUtils"; import { Cartesian3, HorizontalOrigin, NearFarScalar, VerticalOrigin } from "cesium"; -import config from '@/config/config.json' /** * 公共批量处理点钩子函数 @@ -14,9 +13,10 @@ export const usePointsHandle = () => { * 添加点 * @param points - 点数据 * @param getDisasterIcon - 获取灾害图标的函数 + * @param prefix - 前缀 * @returns 点的ID列表 */ - function addPoints(points: Point[], getDisasterIcon: (disasterType: string) => string): string[] { + function addPoints(points: Point[], getDisasterIcon: (disasterType?: string) => string, prefix: string): string[] { // 设置加载配置 const options: PrimitiveOptions[] = []; @@ -26,15 +26,14 @@ export const usePointsHandle = () => { points.forEach(point => { try { - if (point.lon === undefined || point.lat === undefined || point.disasterType === undefined) { - throw new Error(`点位数据缺少经纬度或者灾害类型:${point.id}`); + if (point.lon === undefined || point.lat === undefined) { + throw new Error(`点位数据缺少经纬度:${point.id}`); } - // 将经纬度转换为笛卡尔坐标 - const position = Cartesian3.fromDegrees(point.lon, point.lat, 0); + // 将经纬度转换为笛卡尔坐标,太高一点高度,方便点击 + const position = Cartesian3.fromDegrees(point.lon, point.lat, 10); - const id = `${config.prefix.hiddenDangerPointId}${point.id}` + const id = `${prefix}${point.id}` ids.push(id) - options.push({ id: id, type: 'billboard', @@ -51,10 +50,9 @@ export const usePointsHandle = () => { }, }); } catch (error) { - throw new Error(`处理点位失败:${point.id}`); + throw new Error(`处理点位失败:${error}`); } }) - // 批量创建图层 CesiumUtilsSingleton.addPrimitivesBatch(options); diff --git a/src/stores/useLoadingInformation.ts b/src/stores/useLoadingInformation.ts new file mode 100644 index 0000000..cfbe97b --- /dev/null +++ b/src/stores/useLoadingInformation.ts @@ -0,0 +1,52 @@ +import { Billboard } from 'cesium' +import { defineStore } from 'pinia' +import { type Ref, ref } from 'vue' + +/** + * 加载信息弹窗相关参数 + */ +export const useLoadingInformationStore = defineStore('loadingInformation', () => { + + // 点击的对象 + const clickObject: Ref<{ primitive: Billboard | null }> = ref({ primitive: null }) + + // 隐患点 + const loadingHiddenPointInformationStatus: Ref = ref(false) + const hiddenPointId: Ref = ref(-1) + + // 风险点 + const loadingRiskPointInformationStatus: Ref = ref(false) + const riskPointId: Ref = ref(-1) + + // 重置状态 + const resetStatue = () => { + loadingHiddenPointInformationStatus.value = false + hiddenPointId.value = -1 + loadingRiskPointInformationStatus.value = false + riskPointId.value = -1 + } + + // get/set方法 + const getClickObject = () => clickObject.value + const setClickObject = (value: {primitive: Billboard}) => { + clickObject.value = value + } + const getLoadingHiddenPointInformationStatus = () => loadingHiddenPointInformationStatus.value + const setLoadingHiddenPointInformationStatus = (value: boolean) => { + loadingHiddenPointInformationStatus.value = value + } + const getLoadingRiskPointInformationStatus = () => loadingRiskPointInformationStatus.value + const setLoadingRiskPointInformationStatus = (value: boolean) => { + loadingRiskPointInformationStatus.value = value + } + const getHiddenPointId = () => hiddenPointId.value + const setHiddenPointId = (value: number) => { + hiddenPointId.value = value + } + const getRiskPointId = () => riskPointId.value + const setRiskPointId = (value: number) => { + riskPointId.value = value + } + + return { resetStatue, getClickObject, setClickObject, getLoadingHiddenPointInformationStatus, setLoadingHiddenPointInformationStatus, getLoadingRiskPointInformationStatus, setLoadingRiskPointInformationStatus, getHiddenPointId, setHiddenPointId, getRiskPointId, setRiskPointId } +}) diff --git a/src/types/base/XianRiskSpots.ts b/src/types/base/XianRiskSpots.ts new file mode 100644 index 0000000..8756101 --- /dev/null +++ b/src/types/base/XianRiskSpots.ts @@ -0,0 +1,42 @@ +import type { Point } from "./Point"; + +export interface XianRiskSpots extends Point { + /** 风险区名称 */ + riskName?: string; + /** 统一编号 */ + unitCode?: string; + /** 风险区等级 */ + riskLevel?: string; + /** 面积 */ + area?: number; + /** 省 */ + province?: string; + /** 市 */ + city?: string; + /** 县 */ + county?: string; + /** 乡 */ + country?: string; + /** 村 */ + village?: string; + /** 位置 */ + position?: string; + /** 居民户数(户) */ + residentCounts?: number; + /** 居民人口(人) */ + addressPopulation?: number; + /** 威胁财产(万元) */ + riskProperty?: number; + /** 常住人口(人) */ + permanentPopulation?: number; + /** 住房(间) */ + housing?: number; + /** 巡查员姓名 */ + inspectorName?: string; + /** 巡查员电话 */ + inspectorTele?: string; + /** 空间 */ + geom?: any; + /** 逻辑删除标识,0未删除,1已删除 */ + isDelete?: number; +} \ No newline at end of file diff --git a/src/utils/cesium/CesiumUtils.ts b/src/utils/cesium/CesiumUtils.ts index f7e371c..5e1bd5a 100644 --- a/src/utils/cesium/CesiumUtils.ts +++ b/src/utils/cesium/CesiumUtils.ts @@ -410,7 +410,6 @@ export class CesiumUtils { handler.setInputAction((clickEvent: {position: Cartesian2}) => { // 在点击位置进行拾取 const pickedObject = CesiumUtilsSingleton.getViewer()?.scene.pick(clickEvent.position); - callback(pickedObject); }, ScreenSpaceEventType.LEFT_CLICK); } diff --git a/src/views/home/earthquake/Earthquake.vue b/src/views/home/earthquake/Earthquake.vue index c006cab..26b92a5 100644 --- a/src/views/home/earthquake/Earthquake.vue +++ b/src/views/home/earthquake/Earthquake.vue @@ -1,12 +1,16 @@ diff --git a/src/views/home/rainstorm/Rainstorm.vue b/src/views/home/rainstorm/Rainstorm.vue index 5a3d38a..63d9458 100644 --- a/src/views/home/rainstorm/Rainstorm.vue +++ b/src/views/home/rainstorm/Rainstorm.vue @@ -1,12 +1,15 @@