From da67648220f86993fac22b8199165995df3d8563 Mon Sep 17 00:00:00 2001
From: feiyu02 <risaku@163.com>
Date: 星期五, 21 三月 2025 17:35:51 +0800
Subject: [PATCH] 走航融合(待完成)
---
src/model/SatelliteGrid.js | 240 +++++++++++++++++++++++++++++
src/views/underwaymix/UnderwayMixMode.vue | 108 ++++++++++++
src/components/grid/GridSearch.vue | 74 +++++++++
src/components.d.ts | 1
src/views/HomePage.vue | 45 -----
src/stores/grid-info.js | 11 +
6 files changed, 424 insertions(+), 55 deletions(-)
diff --git a/src/components.d.ts b/src/components.d.ts
index 34b6c69..a0257ee 100644
--- a/src/components.d.ts
+++ b/src/components.d.ts
@@ -54,6 +54,7 @@
FactorRadio: typeof import('./components/monitor/FactorRadio.vue')['default']
FactorTrend: typeof import('./components/monitor/FactorTrend.vue')['default']
GaugeChart: typeof import('./components/chart/GaugeChart.vue')['default']
+ GridSearch: typeof import('./components/grid/GridSearch.vue')['default']
HistoricalTrajectory: typeof import('./components/animation/HistoricalTrajectory.vue')['default']
MapLocation: typeof import('./components/map/MapLocation.vue')['default']
MapScene: typeof import('./components/map/MapScene.vue')['default']
diff --git a/src/components/grid/GridSearch.vue b/src/components/grid/GridSearch.vue
new file mode 100644
index 0000000..c9d90a6
--- /dev/null
+++ b/src/components/grid/GridSearch.vue
@@ -0,0 +1,74 @@
+<template>
+ <CardDialog
+ v-model="dialogVisible"
+ title="缃戞牸淇℃伅"
+ draggable
+ :modal="false"
+ width="300px"
+ >
+ <template #default>
+ <el-form
+ :inline="false"
+ ref="formRef"
+ label-position="right"
+ label-width="100px"
+ >
+ <el-form-item label="缃戞牸缂栧彿锛�">
+ <div>
+ {{ data.cellIndex }}
+ </div>
+ </el-form-item>
+ <el-form-item label="缁忕含搴︼細">
+ <div>
+ {{ data.longitude + ', ' + data.latitude }}
+ </div>
+ </el-form-item>
+ <el-form-item label="PM2.5锛�">
+ <div>
+ {{ data.pm25 + ' 渭g/m鲁' }}
+ </div>
+ </el-form-item>
+ <el-form-item label="鍥涜嚦鑼冨洿锛�">
+ <div>/</div>
+ </el-form-item>
+ </el-form>
+ </template>
+ <template #footer> </template>
+ </CardDialog>
+</template>
+<script setup>
+import { ref, watch, computed } from 'vue';
+import { useGridStore } from '@/stores/grid-info';
+
+const gridStore = useGridStore();
+
+const dialogVisible = ref(false);
+
+const data = computed(() => {
+ if (gridStore.selectedGridCellAndDataDetail) {
+ return {
+ cellIndex: gridStore.selectedGridCellAndDataDetail.gridCell.cellIndex,
+ longitude: gridStore.selectedGridCellAndDataDetail.gridCell.longitude,
+ latitude: gridStore.selectedGridCellAndDataDetail.gridCell.latitude,
+ pm25: gridStore.selectedGridCellAndDataDetail.gridDataDetail.pm25
+ };
+ } else {
+ return {
+ cellIndex: '/',
+ longitude: '/',
+ latitude: '/',
+ pm25: '/'
+ };
+ }
+});
+
+watch(
+ () => gridStore.selectedGridCellAndDataDetail,
+ (nv, ov) => {
+ if (nv != ov) {
+ dialogVisible.value = true;
+ }
+ },
+ { deep: true }
+);
+</script>
diff --git a/src/model/SatelliteGrid.js b/src/model/SatelliteGrid.js
index 0067b78..cb547e9 100644
--- a/src/model/SatelliteGrid.js
+++ b/src/model/SatelliteGrid.js
@@ -394,20 +394,35 @@
}
}
- setGridEvent(name, event) {
+ setGridEvent(tags, name, event) {
+ const { _mapViewsList, _gridDataDetailList } = this._getMapViews(...tags);
+
if (!this.events.has(name)) {
this.events.set(name, []);
}
const list = this.events.get(name);
if (list.length > 0) {
const lastEvent = list[list.length - 1];
- this.mapViews.gridViews.forEach((polygon) => {
- polygon.off(name, lastEvent);
+ _mapViewsList.forEach((v) => {
+ v.gridViews.forEach((polygon) => {
+ polygon.off(name, lastEvent);
+ });
});
}
+
this.events.get(name).push(event);
- this.mapViews.gridViews.forEach((polygon) => {
- polygon.on(name, event);
+ _mapViewsList.forEach((v, i) => {
+ const gridDataDetailList = _gridDataDetailList[i];
+ v.gridViews.forEach((polygon) => {
+ const { gridCell } = polygon.getExtData();
+ const cellIndex = gridCell.cellIndex;
+ const gridDataDetail = gridDataDetailList.find(
+ (v) => v.cellId == cellIndex
+ );
+ polygon.on(name, (e) => {
+ event(gridCell, gridDataDetail);
+ });
+ });
});
}
@@ -516,7 +531,220 @@
* @param {string} tag
*/
drawHeatGrid(tag) {
-
+ if (!this.mapViewsMap.has(tag) || !this.gridDataDetailMap.has(tag)) {
+ return;
+ }
+
+ const heatTag = `heat-${tag}`;
+ if (this.mapViewsMap.has(heatTag)) {
+ this.changeVisibility({
+ tags: [heatTag],
+ showGridViews: true
+ });
+ } else {
+ const _mapViews = this.mapViewsMap.get(tag);
+ const _gridDataDetail = this.gridDataDetailMap.get(tag);
+ // const groupId = _gridDataDetail[0].groupId;
+ // const cellId = _gridDataDetail.cellId;
+
+ const originCellIdList = _gridDataDetail.map((v) => v.cellId);
+ let headGridDataDetailList = [];
+
+ const width = 120;
+ const height = 90;
+ const eachwidth = 10;
+ const eachheight = 10;
+
+ const searchLength = 3;
+
+ const _dataMap = new Map();
+
+ _gridDataDetail.forEach((gdd) => {
+ const searchRes = this.search(
+ gdd,
+ width,
+ height,
+ eachwidth,
+ eachheight,
+ searchLength
+ );
+ if (searchRes.find(v=> v.cellId == 1670)) {
+ console.log();
+
+ }
+ searchRes.forEach((e) => {
+ if (originCellIdList.indexOf(e.cellId) == -1) {
+ if (!_dataMap.has(e.cellId)) {
+ _dataMap.set(e.cellId, {
+ source: [],
+ res: {}
+ });
+ }
+ _dataMap.get(e.cellId).source.push(e);
+ }
+ });
+ });
+
+ _dataMap.forEach((v, k) => {
+ let total = 0,
+ count = v.source.length;
+ v.source.forEach((s) => {
+ total += s.pm25;
+ });
+ v.res = {
+ isHeatData: true,
+ groupId: v.source[0].groupId,
+ cellId: v.source[0].cellId,
+ pm25: count == 0 ? null : Math.round((total / count) * 10) / 10,
+ originData: v.source
+ };
+ headGridDataDetailList.push(v.res);
+ });
+ headGridDataDetailList = headGridDataDetailList.concat(_gridDataDetail);
+
+ // 閲嶆柊鎸夌収鐩戞祴鏁版嵁鎺掑簭骞舵爣璁版帓鍚�
+ headGridDataDetailList.sort((a, b) => {
+ return b.pm25 - a.pm25;
+ });
+ headGridDataDetailList.forEach((gdd, i) => {
+ gdd.rank = i + 1;
+ });
+
+ this.drawTagGrid({
+ tag: heatTag,
+ data: headGridDataDetailList,
+ // grid: {
+ // style: {
+ // isMixGridHighlight:
+ // isMixGridHighlight == undefined ? true : isMixGridHighlight
+ // }
+ // },
+ extData: {
+ name: `璧拌埅鐑姏鍥� - ${heatTag}`,
+ type: 2
+ }
+ });
+ }
+
+ return heatTag;
+ }
+
+ search(gdd, width, height, eachwidth, eachheight, searchLength) {
+ function getCellWidthRange(cellId, width, height) {
+ const total = width * height;
+ const x = Math.ceil(cellId / total) - 1;
+ let first = 1 + x * total,
+ last = width + x * total;
+
+ let scale = 0;
+ while (scale < height) {
+ const min = first + scale * width;
+ const max = last + scale * width;
+ if (cellId >= min && cellId <= max) {
+ return [min, max];
+ }
+ scale++;
+ }
+ }
+
+ const cellId = gdd.cellId;
+ // const minData = gdd.pm25 / 2
+ const dataOffset = (gdd.pm25 - gdd.pm25 / 2) / 3;
+
+ const hOffset = eachwidth;
+ const wOffset = 1;
+
+ const cellIdMin = 1;
+ const cellIdMax = width * height;
+
+ let searchWidth = 0 - searchLength,
+ searchHeight = 0 - searchLength;
+
+ const result = [];
+
+ const eachRange = getCellWidthRange(cellId, eachwidth, eachheight);
+ const groupRange = getCellWidthRange(
+ Math.ceil(cellId / (eachwidth * eachheight)),
+ width / eachwidth,
+ height / eachheight
+ );
+
+ for (let w = searchWidth; w <= searchLength; w++) {
+ // 鍏堣繘琛屾í鍚戠殑鍧愭爣鍙樻崲
+ let _cellId = cellId + w * wOffset;
+ if (_cellId < eachRange[0] || _cellId > eachRange[1]) {
+ const cellOffset =
+ _cellId < eachRange[0]
+ ? _cellId - eachRange[0]
+ : _cellId - eachRange[1];
+
+ const groupOffset = Math[cellOffset / eachwidth > 0 ? 'ceil' : 'floor'](
+ cellOffset / eachwidth
+ );
+
+ const newEachRange = eachRange.map(
+ (r) => r + groupOffset * eachwidth * eachheight
+ );
+
+ _cellId =
+ groupOffset > 0
+ ? newEachRange[0] + cellOffset - wOffset
+ : newEachRange[1] + cellOffset + wOffset;
+
+ const _groupId = Math.ceil(_cellId / (eachwidth * eachheight));
+
+ if (_groupId < groupRange[0] || _groupId > groupRange[1]) {
+ continue;
+ }
+ }
+
+ for (let h = searchHeight; h <= searchLength; h++) {
+ if (w == 0 && h == 0) continue;
+
+ const _eachRange = getCellWidthRange(_cellId, eachwidth, eachheight);
+ // if (_eachRange == undefined) {
+ // console.log();
+
+ // }
+ const wOffset = _cellId - _eachRange[0];
+ let _resCellId = _cellId + h * hOffset;
+ if (_resCellId < cellIdMin || _resCellId > cellIdMax) continue;
+
+ const total = eachwidth * eachheight;
+ const x = Math.ceil(_cellId / total) - 1;
+ const eachCellIdMin = 1 + x * total;
+ const eachCellIdMax = total + x * total;
+ const topCell = eachCellIdMin + wOffset;
+ const bottomCell = eachCellIdMax - eachwidth + 1 + wOffset;
+ if (_resCellId < eachCellIdMin || _resCellId > eachCellIdMax) {
+ const cellOffset =
+ _resCellId < eachCellIdMin
+ ? _resCellId - topCell
+ : _resCellId - bottomCell;
+
+ const newTopCell =
+ cellOffset > 0
+ ? topCell + width * eachheight
+ : topCell - width * eachheight;
+ const newBottomCell =
+ cellOffset > 0
+ ? bottomCell + width * eachheight
+ : bottomCell - width * eachheight;
+
+ _resCellId =
+ cellOffset > 0
+ ? newTopCell + cellOffset - hOffset
+ : newBottomCell + cellOffset + hOffset;
+ }
+ result.push({
+ groupId: gdd.groupId,
+ cellId: _resCellId,
+ pm25: gdd.pm25 - Math.max(Math.abs(w), Math.abs(h)) * dataOffset
+ });
+ }
+ }
+
+ return result;
}
_getMapViews(...tags) {
diff --git a/src/stores/grid-info.js b/src/stores/grid-info.js
new file mode 100644
index 0000000..c193329
--- /dev/null
+++ b/src/stores/grid-info.js
@@ -0,0 +1,11 @@
+import { ref } from 'vue';
+import { defineStore } from 'pinia';
+
+// 璧拌埅璁惧
+export const useGridStore = defineStore('grid', () => {
+ const selectedSatelliteProxy = undefined;
+
+ const selectedGridCellAndDataDetail = ref(undefined);
+
+ return { selectedSatelliteProxy, selectedGridCellAndDataDetail };
+});
diff --git a/src/views/HomePage.vue b/src/views/HomePage.vue
index e4cf5d3..b31d689 100644
--- a/src/views/HomePage.vue
+++ b/src/views/HomePage.vue
@@ -10,55 +10,14 @@
<!-- <MapLocation></MapLocation> -->
<SceneSearch></SceneSearch>
<MapScene></MapScene>
+ <GridSearch></GridSearch>
</el-row>
<CoreMenu></CoreMenu>
<router-view></router-view>
</div>
</template>
-<script setup>
-import { map, onMapMounted } from '@/utils/map/index_old';
-
-// let districtPolygon;
-// // 缁樺埗鍖哄幙杈圭晫
-// function drawDistrict(districtName, isNew) {
-// onMapMounted(() => {
-// if (districtPolygon && !isNew) {
-// map.remove(districtPolygon);
-// map.add(districtPolygon);
-// } else {
-// // eslint-disable-next-line no-undef
-// var district = new AMap.DistrictSearch({
-// extensions: 'all', //杩斿洖琛屾斂鍖鸿竟鐣屽潗鏍囩瓑鍏蜂綋淇℃伅
-// level: 'district' //璁剧疆鏌ヨ琛屾斂鍖虹骇鍒负鍖�
-// });
-// district.search(districtName, function (status, result) {
-// var bounds = result.districtList[0].boundaries; //鑾峰彇鏈濋槼鍖虹殑杈圭晫淇℃伅
-// if (bounds) {
-// for (var i = 0; i < bounds.length; i++) {
-// //鐢熸垚琛屾斂鍖哄垝 polygon
-// // eslint-disable-next-line no-undef
-// districtPolygon = new AMap.Polygon({
-// map: map, //鏄剧ず璇ヨ鐩栫墿鐨勫湴鍥惧璞�
-// strokeWeight: 1, //杞粨绾垮搴�
-// path: bounds[i], //澶氳竟褰㈣疆寤撶嚎鐨勮妭鐐瑰潗鏍囨暟缁�
-// fillOpacity: 0.6, //澶氳竟褰㈠~鍏呴�忔槑搴�
-// // fillColor: '#CCF3FF', //澶氳竟褰㈠~鍏呴鑹�
-// fillColor: '#0077ff',
-// // strokeColor: '#ffffff' //绾挎潯棰滆壊
-// strokeColor: 'white', //绾挎潯棰滆壊
-// zIndex: 9
-// });
-// }
-// map.setFitView(); //灏嗚鐩栫墿璋冩暣鍒板悎閫傝閲�
-// }
-// });
-// }
-// });
-// }
-
-// drawDistrict('闀垮畞鍖�');
-</script>
+<script setup></script>
<style scoped>
.overlay-container {
diff --git a/src/views/underwaymix/UnderwayMixMode.vue b/src/views/underwaymix/UnderwayMixMode.vue
index 38a403a..c0dbe9b 100644
--- a/src/views/underwaymix/UnderwayMixMode.vue
+++ b/src/views/underwaymix/UnderwayMixMode.vue
@@ -59,6 +59,13 @@
@change="handleHeatMapClick"
>
</CheckButton>
+ <!-- <CheckButton
+ active-text="鎼滅储缃戞牸"
+ inactive-text="鎼滅储缃戞牸"
+ :default-value="false"
+ @change="handleHeatMapSearchClick"
+ >
+ </CheckButton> -->
</el-row>
<!-- <div class="m-t-8">缃戞牸瑕佺礌</div>
<el-row class="m-t-8">
@@ -147,9 +154,11 @@
import gridApi from '@/api/gridApi';
import { SatelliteGrid } from '@/model/SatelliteGrid';
import GridStyleTool from './component/GridStyleTool.vue';
+import { useGridStore } from '@/stores/grid-info';
+
+const gridStore = useGridStore();
const satelliteGrid = new SatelliteGrid('璧拌埅铻嶅悎');
-
const gridCtrls = ref([satelliteGrid]);
// 鍊熺敤鍗槦閬ユ祴妯″潡涓殑100绫崇綉鏍�
@@ -173,6 +182,7 @@
const gridDataDetailMap = new Map();
const mixActive = ref(false);
+const heatActive = ref(false);
const gridVisible = ref(true);
const underwayVisible = ref(false);
const rankVisible = ref(false);
@@ -216,7 +226,32 @@
}
function prepareGrid(gridInfo) {
- satelliteGrid.gridPrepare(gridInfo);
+ satelliteGrid.gridPrepare(gridInfo, (polygon) => {
+ //榧犳爣绉诲叆浜嬩欢
+ polygon.on('mouseover', () => {
+ polygon.setOptions({
+ //淇敼澶氳竟褰㈠睘鎬х殑鏂规硶
+ strokeWeight: 2,
+ strokeColor: 'red'
+ });
+ });
+ //榧犳爣绉诲嚭浜嬩欢
+ polygon.on('mouseout', () => {
+ polygon.setOptions({
+ strokeWeight: 1,
+ strokeColor: 'white'
+ });
+ });
+ });
+ // satelliteGrid.setGridEvent('click', (gridCell, gridDataDetail) => {
+ // // const polygon = e.target
+ // // const { gridCell } = polygon.getExtData();
+ // // const cellIndex = gridCell.cellIndex;
+ // gridStore.selectedGridCellAndDataDetail = {
+ // gridCell,
+ // gridDataDetail
+ // };
+ // });
}
// watch(mission, (nV, oV) => {
@@ -263,6 +298,16 @@
type: 0
}
});
+ satelliteGrid.setGridEvent(
+ [d.id],
+ 'click',
+ (gridCell, gridDataDetail) => {
+ gridStore.selectedGridCellAndDataDetail = {
+ gridCell,
+ gridDataDetail
+ };
+ }
+ );
gridCtrls.value = [satelliteGrid];
// gridCtrls.value = Array.from(satelliteGrid.mapViewsMap);
// console.log(gridCtrls.value);
@@ -271,6 +316,7 @@
});
}
+let mixTag;
function handleMixClick() {
mixActive.value = !mixActive.value;
const tags = fusionDataList.value
@@ -282,7 +328,17 @@
showRankTxt: false
});
if (mixActive.value) {
- satelliteGrid.mixGrid(tags);
+ mixTag = satelliteGrid.mixGrid(tags);
+ satelliteGrid.setGridEvent(
+ [mixTag],
+ 'click',
+ (gridCell, gridDataDetail) => {
+ gridStore.selectedGridCellAndDataDetail = {
+ gridCell,
+ gridDataDetail
+ };
+ }
+ );
gridCtrls.value = [satelliteGrid];
} else {
satelliteGrid.changeVisibility({
@@ -292,10 +348,50 @@
}
}
+let heatTag;
function handleHeatMapClick() {
- const tags = fusionDataList.value
- .filter((v, i) => selectedfusionData.value.indexOf(i) != -1)
- .map((v) => v.id);
+ heatActive.value = !heatActive.value;
+ satelliteGrid.changeVisibility({
+ showGridViews: false,
+ showDataTxt: false,
+ showRankTxt: false
+ });
+ if (heatActive.value) {
+ heatTag = satelliteGrid.drawHeatGrid(mixTag);
+ satelliteGrid.setGridEvent(
+ [heatTag],
+ 'click',
+ (gridCell, gridDataDetail) => {
+ gridStore.selectedGridCellAndDataDetail = {
+ gridCell,
+ gridDataDetail
+ };
+ }
+ );
+ gridCtrls.value = [satelliteGrid];
+ } else {
+ satelliteGrid.changeVisibility({
+ tags: [mixTag],
+ showGridViews: true
+ });
+ }
+}
+
+function handleHeatMapSearchClick() {
+ const res = satelliteGrid.search(
+ {
+ groupId: 1,
+ cellId: 2893,
+ pm25: 50
+ },
+ 120,
+ 90,
+ 10,
+ 10,
+ 3
+ );
+
+ console.log(res);
}
function handleGridClick() {
--
Gitblit v1.9.3