将周边分析的配置文件放在hook下
This commit is contained in:
@@ -1,37 +0,0 @@
|
|||||||
import { LoadingResource } from '@/types/common/LoadingResourceType';
|
|
||||||
import type { ResourceConfig } from '@/types/common/useAroundAnalysisType';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 周边分析资源配置(统一管理)
|
|
||||||
*/
|
|
||||||
export const RESOURCE_CONFIGS: ResourceConfig[] = [
|
|
||||||
{ key: LoadingResource.SCHOOL, category: 'school' },
|
|
||||||
{ key: LoadingResource.HOSPITAL, category: 'hospital' },
|
|
||||||
{ key: LoadingResource.DANGEROUS_SOURCE, category: 'danger' },
|
|
||||||
{ key: LoadingResource.EMERGENCY_SHELTER, category: 'shelter' },
|
|
||||||
{ key: LoadingResource.FIRE_STATION, category: 'fire' },
|
|
||||||
{ key: LoadingResource.STORE_POINTS, category: 'store' },
|
|
||||||
{ key: LoadingResource.SUBWAY_STATION, category: 'subway' },
|
|
||||||
{ key: LoadingResource.LANDSLIDE_HIDDEN_POINT, category: 'hidden-danger', forcedType: 'landslide' },
|
|
||||||
{ key: LoadingResource.DEBRIS_FLOW_HIDDEN_POINT, category: 'hidden-danger', forcedType: 'debris_flow' },
|
|
||||||
{ key: LoadingResource.WATER_LOGGING_HIDDEN_POINT, category: 'hidden-danger', forcedType: 'water_logging' },
|
|
||||||
{ key: LoadingResource.FLASH_FLOOD_HIDDEN_POINT, category: 'hidden-danger', forcedType: 'flash_flood' },
|
|
||||||
{ key: LoadingResource.COLLAPSE_HIDDEN_POINT, category: 'hidden-danger', forcedType: 'collapse' },
|
|
||||||
{ key: LoadingResource.RISK_POINT, category: 'risk-point' },
|
|
||||||
{ key: LoadingResource.BRIDGE, category: 'bridge' },
|
|
||||||
{ key: LoadingResource.RESERVOIR, category: 'reservoir' },
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 常量配置
|
|
||||||
*/
|
|
||||||
export const AROUND_ANALYSIS_CONSTANTS = {
|
|
||||||
DIALOG_WIDTH: 280,
|
|
||||||
DIALOG_HEIGHT: 150,
|
|
||||||
DIALOG_PADDING: 10,
|
|
||||||
DIALOG_OFFSET: 20,
|
|
||||||
EARTH_RADIUS: 6371000,
|
|
||||||
MIN_FLY_HEIGHT: 10000,
|
|
||||||
FLY_HEIGHT_MULTIPLIER: 6000,
|
|
||||||
FLY_DURATION: 2,
|
|
||||||
} as const;
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import { ref, reactive, onUnmounted, watch, computed } from 'vue';
|
import { ref, reactive, onUnmounted, watch, computed } from 'vue';
|
||||||
import { useStatusStore } from '@/stores/useStatusStore';
|
import { useStatusStore } from '@/stores/useStatusStore';
|
||||||
import { useLoadingResourceStore } from '@/stores/useLoadingResourceStore';
|
import { useLoadingResourceStore } from '@/stores/useLoadingResourceStore';
|
||||||
import { RESOURCE_CONFIGS, AROUND_ANALYSIS_CONSTANTS } from '@/config/aroundAnalysisConfig';
|
import { useAroundAnalysisConfig } from './useAroundAnalysisConfig';
|
||||||
import type { PointResource, PointResourceCategory, AnalysisButtonConfig, AroundAnalysisState } from '@/types/common/useAroundAnalysisType';
|
import type { PointResource, PointResourceCategory, AnalysisButtonConfig, AroundAnalysisState } from '@/types/common/useAroundAnalysisType';
|
||||||
import { CesiumUtilsSingleton } from '@/utils/cesium/CesiumUtils';
|
import { CesiumUtilsSingleton } from '@/utils/cesium/CesiumUtils';
|
||||||
import { isCategoryVisible, loadAllPointData, calculateDistance } from '@/utils/aroundAnalysisUtils';
|
import { isCategoryVisible, loadAllPointData, calculateDistance } from '@/utils/aroundAnalysisUtils';
|
||||||
@@ -21,6 +21,7 @@ import { useMarkerManager } from './useMarkerManager';
|
|||||||
*/
|
*/
|
||||||
export const useAroundAnalysis = (): AroundAnalysisState => {
|
export const useAroundAnalysis = (): AroundAnalysisState => {
|
||||||
const statusStore = useStatusStore();
|
const statusStore = useStatusStore();
|
||||||
|
const { resourceConfigs, MIN_FLY_HEIGHT, FLY_HEIGHT_MULTIPLIER, FLY_DURATION } = useAroundAnalysisConfig();
|
||||||
|
|
||||||
// ==================== 响应式状态 ====================
|
// ==================== 响应式状态 ====================
|
||||||
const selectedButtonIndex = ref<number>(-1);
|
const selectedButtonIndex = ref<number>(-1);
|
||||||
@@ -31,7 +32,7 @@ export const useAroundAnalysis = (): AroundAnalysisState => {
|
|||||||
const showPulsePointList = ref(false);
|
const showPulsePointList = ref(false);
|
||||||
const searchState = ref('');
|
const searchState = ref('');
|
||||||
const canSearch = computed(() => {
|
const canSearch = computed(() => {
|
||||||
return RESOURCE_CONFIGS.some(config => isCategoryVisible(config.category, config.forcedType));
|
return resourceConfigs.value.some(config => isCategoryVisible(config.category, config.forcedType));
|
||||||
});
|
});
|
||||||
|
|
||||||
let clickHandler: ScreenSpaceEventHandler | null = null;
|
let clickHandler: ScreenSpaceEventHandler | null = null;
|
||||||
@@ -48,7 +49,7 @@ export const useAroundAnalysis = (): AroundAnalysisState => {
|
|||||||
const centerLon = cartographic.longitude * (180 / Math.PI);
|
const centerLon = cartographic.longitude * (180 / Math.PI);
|
||||||
const centerLat = cartographic.latitude * (180 / Math.PI);
|
const centerLat = cartographic.latitude * (180 / Math.PI);
|
||||||
|
|
||||||
const allPoints = loadAllPointData(RESOURCE_CONFIGS);
|
const allPoints = loadAllPointData(resourceConfigs.value);
|
||||||
const radiusMeters = radiusKm * 1000;
|
const radiusMeters = radiusKm * 1000;
|
||||||
|
|
||||||
const filteredPoints = allPoints.filter(point => {
|
const filteredPoints = allPoints.filter(point => {
|
||||||
@@ -125,20 +126,20 @@ export const useAroundAnalysis = (): AroundAnalysisState => {
|
|||||||
|
|
||||||
const calculateDialogPosition = (clickPosition: Cartesian2) => {
|
const calculateDialogPosition = (clickPosition: Cartesian2) => {
|
||||||
const { innerWidth: screenWidth, innerHeight: screenHeight } = window;
|
const { innerWidth: screenWidth, innerHeight: screenHeight } = window;
|
||||||
const { DIALOG_WIDTH, DIALOG_HEIGHT, DIALOG_PADDING, DIALOG_OFFSET } = AROUND_ANALYSIS_CONSTANTS;
|
const { DIALOG_WIDTH: dialogWidth, DIALOG_HEIGHT: dialogHeight, DIALOG_PADDING: dialogPadding, DIALOG_OFFSET: dialogOffset } = useAroundAnalysisConfig().getConstants();
|
||||||
|
|
||||||
let x = clickPosition.x + DIALOG_OFFSET;
|
let x = clickPosition.x + dialogOffset;
|
||||||
let y = clickPosition.y + DIALOG_OFFSET;
|
let y = clickPosition.y + dialogOffset;
|
||||||
|
|
||||||
if (x + DIALOG_WIDTH > screenWidth - DIALOG_PADDING) {
|
if (x + dialogWidth > screenWidth - dialogPadding) {
|
||||||
x = clickPosition.x - DIALOG_WIDTH - DIALOG_OFFSET;
|
x = clickPosition.x - dialogWidth - dialogOffset;
|
||||||
}
|
}
|
||||||
if (y + DIALOG_HEIGHT > screenHeight - DIALOG_PADDING) {
|
if (y + dialogHeight > screenHeight - dialogPadding) {
|
||||||
y = clickPosition.y - DIALOG_HEIGHT - DIALOG_OFFSET;
|
y = clickPosition.y - dialogHeight - dialogOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
dialogPosition.x = Math.max(DIALOG_PADDING, Math.min(x, screenWidth - DIALOG_WIDTH - DIALOG_PADDING));
|
dialogPosition.x = Math.max(dialogPadding, Math.min(x, screenWidth - dialogWidth - dialogPadding));
|
||||||
dialogPosition.y = Math.max(DIALOG_PADDING, Math.min(y, screenHeight - DIALOG_HEIGHT - DIALOG_PADDING));
|
dialogPosition.y = Math.max(dialogPadding, Math.min(y, screenHeight - dialogHeight - dialogPadding));
|
||||||
};
|
};
|
||||||
|
|
||||||
// ==================== 事件处理 ====================
|
// ==================== 事件处理 ====================
|
||||||
@@ -160,8 +161,8 @@ export const useAroundAnalysis = (): AroundAnalysisState => {
|
|||||||
const longitude = cartographic.longitude * (180 / Math.PI);
|
const longitude = cartographic.longitude * (180 / Math.PI);
|
||||||
const latitude = cartographic.latitude * (180 / Math.PI);
|
const latitude = cartographic.latitude * (180 / Math.PI);
|
||||||
|
|
||||||
const flyHeight = Math.max(radius.value * AROUND_ANALYSIS_CONSTANTS.FLY_HEIGHT_MULTIPLIER, AROUND_ANALYSIS_CONSTANTS.MIN_FLY_HEIGHT);
|
const flyHeight = Math.max(radius.value * FLY_HEIGHT_MULTIPLIER, MIN_FLY_HEIGHT);
|
||||||
CesiumUtilsSingleton.flyToTarget([longitude, latitude, flyHeight], AROUND_ANALYSIS_CONSTANTS.FLY_DURATION);
|
CesiumUtilsSingleton.flyToTarget([longitude, latitude, flyHeight], FLY_DURATION);
|
||||||
|
|
||||||
showAreaDialog.value = false;
|
showAreaDialog.value = false;
|
||||||
removeMapClickHandler();
|
removeMapClickHandler();
|
||||||
@@ -212,10 +213,10 @@ export const useAroundAnalysis = (): AroundAnalysisState => {
|
|||||||
|
|
||||||
const centerX = window.innerWidth / 2;
|
const centerX = window.innerWidth / 2;
|
||||||
const centerY = window.innerHeight / 2;
|
const centerY = window.innerHeight / 2;
|
||||||
const { DIALOG_WIDTH, DIALOG_HEIGHT, DIALOG_PADDING, DIALOG_OFFSET } = AROUND_ANALYSIS_CONSTANTS;
|
const { DIALOG_WIDTH: dialogWidth, DIALOG_HEIGHT: dialogHeight, DIALOG_PADDING: dialogPadding, DIALOG_OFFSET: dialogOffset } = useAroundAnalysisConfig().getConstants();
|
||||||
|
|
||||||
dialogPosition.x = Math.max(DIALOG_PADDING, Math.min(centerX + DIALOG_OFFSET, window.innerWidth - DIALOG_WIDTH - DIALOG_PADDING));
|
dialogPosition.x = Math.max(dialogPadding, Math.min(centerX + dialogOffset, window.innerWidth - dialogWidth - dialogPadding));
|
||||||
dialogPosition.y = Math.max(DIALOG_PADDING, Math.min(centerY + DIALOG_OFFSET, window.innerHeight - DIALOG_HEIGHT - DIALOG_PADDING));
|
dialogPosition.y = Math.max(dialogPadding, Math.min(centerY + dialogOffset, window.innerHeight - dialogHeight - dialogPadding));
|
||||||
};
|
};
|
||||||
|
|
||||||
// ==================== 搜索功能 ====================
|
// ==================== 搜索功能 ====================
|
||||||
@@ -226,10 +227,10 @@ export const useAroundAnalysis = (): AroundAnalysisState => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const lowerQuery = queryString.toLowerCase();
|
const lowerQuery = queryString.toLowerCase();
|
||||||
const allResources = loadAllPointData(RESOURCE_CONFIGS);
|
const allResources = loadAllPointData(resourceConfigs.value);
|
||||||
|
|
||||||
const filteredResults = allResources.filter(item => {
|
const filteredResults = allResources.filter(item => {
|
||||||
const config = RESOURCE_CONFIGS.find(c => c.category === item.category);
|
const config = resourceConfigs.value.find(c => c.category === item.category);
|
||||||
let isVisible = false;
|
let isVisible = false;
|
||||||
|
|
||||||
if (config) {
|
if (config) {
|
||||||
|
|||||||
@@ -0,0 +1,146 @@
|
|||||||
|
import { ref, computed } from 'vue';
|
||||||
|
import { LoadingResource } from '@/types/common/LoadingResourceType';
|
||||||
|
import type { ResourceConfig, PointResourceCategory } from '@/types/common/useAroundAnalysisType';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 周边分析配置 Hook
|
||||||
|
* 将配置文件改为 hook 形式,提供响应式配置管理
|
||||||
|
*/
|
||||||
|
export const useAroundAnalysisConfig = () => {
|
||||||
|
// ==================== 资源配置 ====================
|
||||||
|
|
||||||
|
/** 周边分析资源配置列表 */
|
||||||
|
const resourceConfigs = ref<ResourceConfig[]>([
|
||||||
|
{ key: LoadingResource.SCHOOL, category: 'school' },
|
||||||
|
{ key: LoadingResource.HOSPITAL, category: 'hospital' },
|
||||||
|
{ key: LoadingResource.DANGEROUS_SOURCE, category: 'danger' },
|
||||||
|
{ key: LoadingResource.EMERGENCY_SHELTER, category: 'shelter' },
|
||||||
|
{ key: LoadingResource.FIRE_STATION, category: 'fire' },
|
||||||
|
{ key: LoadingResource.STORE_POINTS, category: 'store' },
|
||||||
|
{ key: LoadingResource.SUBWAY_STATION, category: 'subway' },
|
||||||
|
{ key: LoadingResource.LANDSLIDE_HIDDEN_POINT, category: 'hidden-danger', forcedType: 'landslide' },
|
||||||
|
{ key: LoadingResource.DEBRIS_FLOW_HIDDEN_POINT, category: 'hidden-danger', forcedType: 'debris_flow' },
|
||||||
|
{ key: LoadingResource.WATER_LOGGING_HIDDEN_POINT, category: 'hidden-danger', forcedType: 'water_logging' },
|
||||||
|
{ key: LoadingResource.FLASH_FLOOD_HIDDEN_POINT, category: 'hidden-danger', forcedType: 'flash_flood' },
|
||||||
|
{ key: LoadingResource.COLLAPSE_HIDDEN_POINT, category: 'hidden-danger', forcedType: 'collapse' },
|
||||||
|
{ key: LoadingResource.RISK_POINT, category: 'risk-point' },
|
||||||
|
{ key: LoadingResource.BRIDGE, category: 'bridge' },
|
||||||
|
{ key: LoadingResource.RESERVOIR, category: 'reservoir' },
|
||||||
|
]);
|
||||||
|
|
||||||
|
// ==================== 常量配置 ====================
|
||||||
|
|
||||||
|
/** 对话框宽度(像素) */
|
||||||
|
const DIALOG_WIDTH = 280;
|
||||||
|
|
||||||
|
/** 对话框高度(像素) */
|
||||||
|
const DIALOG_HEIGHT = 150;
|
||||||
|
|
||||||
|
/** 对话框内边距(像素) */
|
||||||
|
const DIALOG_PADDING = 10;
|
||||||
|
|
||||||
|
/** 对话框偏移量(像素) */
|
||||||
|
const DIALOG_OFFSET = 20;
|
||||||
|
|
||||||
|
/** 地球半径(米) */
|
||||||
|
const EARTH_RADIUS = 6371000;
|
||||||
|
|
||||||
|
/** 最小飞行高度(米) */
|
||||||
|
const MIN_FLY_HEIGHT = 10000;
|
||||||
|
|
||||||
|
/** 飞行高度倍数 */
|
||||||
|
const FLY_HEIGHT_MULTIPLIER = 6000;
|
||||||
|
|
||||||
|
/** 飞行持续时间(秒) */
|
||||||
|
const FLY_DURATION = 2;
|
||||||
|
|
||||||
|
// ==================== 计算属性 ====================
|
||||||
|
|
||||||
|
/** 根据分类获取资源配置 */
|
||||||
|
const getConfigByCategory = (category: PointResourceCategory) => {
|
||||||
|
return resourceConfigs.value.find(config => config.category === category);
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 根据 key 获取资源配置 */
|
||||||
|
const getConfigByKey = (key: LoadingResource) => {
|
||||||
|
return resourceConfigs.value.find(config => config.key === key);
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 获取所有隐患点配置 */
|
||||||
|
const hiddenDangerConfigs = computed(() => {
|
||||||
|
return resourceConfigs.value.filter(config => config.category === 'hidden-danger');
|
||||||
|
});
|
||||||
|
|
||||||
|
/** 获取所有资源配置的 key 列表 */
|
||||||
|
const resourceKeys = computed(() => {
|
||||||
|
return resourceConfigs.value.map(config => config.key);
|
||||||
|
});
|
||||||
|
|
||||||
|
/** 获取所有资源配置的 category 列表 */
|
||||||
|
const resourceCategories = computed(() => {
|
||||||
|
return resourceConfigs.value.map(config => config.category);
|
||||||
|
});
|
||||||
|
|
||||||
|
// ==================== 方法 ====================
|
||||||
|
|
||||||
|
/** 添加资源配置 */
|
||||||
|
const addResourceConfig = (config: ResourceConfig) => {
|
||||||
|
resourceConfigs.value.push(config);
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 移除资源配置 */
|
||||||
|
const removeResourceConfig = (key: LoadingResource) => {
|
||||||
|
const index = resourceConfigs.value.findIndex(config => config.key === key);
|
||||||
|
if (index !== -1) {
|
||||||
|
resourceConfigs.value.splice(index, 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 更新资源配置 */
|
||||||
|
const updateResourceConfig = (key: LoadingResource, updates: Partial<ResourceConfig>) => {
|
||||||
|
const config = resourceConfigs.value.find(c => c.key === key);
|
||||||
|
if (config) {
|
||||||
|
Object.assign(config, updates);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 获取常量配置对象 */
|
||||||
|
const getConstants = () => ({
|
||||||
|
DIALOG_WIDTH,
|
||||||
|
DIALOG_HEIGHT,
|
||||||
|
DIALOG_PADDING,
|
||||||
|
DIALOG_OFFSET,
|
||||||
|
EARTH_RADIUS,
|
||||||
|
MIN_FLY_HEIGHT,
|
||||||
|
FLY_HEIGHT_MULTIPLIER,
|
||||||
|
FLY_DURATION,
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
// 状态
|
||||||
|
resourceConfigs,
|
||||||
|
|
||||||
|
// 常量
|
||||||
|
DIALOG_WIDTH,
|
||||||
|
DIALOG_HEIGHT,
|
||||||
|
DIALOG_PADDING,
|
||||||
|
DIALOG_OFFSET,
|
||||||
|
EARTH_RADIUS,
|
||||||
|
MIN_FLY_HEIGHT,
|
||||||
|
FLY_HEIGHT_MULTIPLIER,
|
||||||
|
FLY_DURATION,
|
||||||
|
|
||||||
|
// 计算属性
|
||||||
|
hiddenDangerConfigs,
|
||||||
|
resourceKeys,
|
||||||
|
resourceCategories,
|
||||||
|
|
||||||
|
// 方法
|
||||||
|
getConfigByCategory,
|
||||||
|
getConfigByKey,
|
||||||
|
addResourceConfig,
|
||||||
|
removeResourceConfig,
|
||||||
|
updateResourceConfig,
|
||||||
|
getConstants,
|
||||||
|
};
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user