地图轨迹图案绘制软件
|
@ -4,7 +4,7 @@
|
|||
<meta charset="UTF-8" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>数字地球</title>
|
||||
<title>地图轨迹绘制</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"name": "digital-earth",
|
||||
"name": "map-trajectory-draw",
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"scripts": {
|
||||
|
@ -9,12 +9,16 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"cesium": "^1.92.0",
|
||||
"echarts": "^5.4.0",
|
||||
"naive-ui": "^2.34.3",
|
||||
"pinia": "^2.0.13",
|
||||
"vue": "^3.2.25",
|
||||
"vue-cesium": "^3.0.11"
|
||||
"vue-cesium": "^3.0.11",
|
||||
"vue-echarts": "^6.2.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vitejs/plugin-vue": "^2.3.0",
|
||||
"less": "^4.1.3",
|
||||
"vite": "^2.9.0"
|
||||
}
|
||||
}
|
||||
|
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 72 KiB |
48
src/App.vue
|
@ -1,36 +1,46 @@
|
|||
<template>
|
||||
<div class="w-h-full flex">
|
||||
<div style="width: 80%; height: 100%;">
|
||||
<vc-config-provider :cesium-path="CESIUM_PATH">
|
||||
<Earth>
|
||||
<LocatingPoint />
|
||||
<MarkPoints />
|
||||
<LandMarkPoints />
|
||||
</Earth>
|
||||
<LandMarkWindow />
|
||||
<LandMarkShow />
|
||||
</vc-config-provider>
|
||||
|
||||
<LonlatForm id="lonlat-form"></LonlatForm>
|
||||
<LonlatTable id="lonlat-table"></LonlatTable>
|
||||
<HotLandmark id="hotlandmark"></HotLandmark>
|
||||
<LonlatForm id="lonlat-form" ref="clear"></LonlatForm>
|
||||
</div>
|
||||
<div style="width: 20%; height: 100%;">
|
||||
<Application>
|
||||
<CalculationArea @clear="handleClear" />
|
||||
</Application>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { VcConfigProvider } from 'vue-cesium'
|
||||
import Earth from '/@/components/Earth.vue'
|
||||
import LonlatForm from '/@/components/LonlatForm.vue'
|
||||
import LonlatTable from '/@/components/LonlatTable.vue'
|
||||
import MarkPoints from "/@/components/MarkPoints.vue"
|
||||
import { ref } from "vue";
|
||||
import { VcConfigProvider } from "vue-cesium";
|
||||
import Earth from "/@/components/Earth.vue";
|
||||
import LonlatForm from '/@/components/LonlatForm.vue';
|
||||
import LocatingPoint from '/@/components/LocatingPoint.vue'
|
||||
import HotLandmark from '/@/components/HotLandmark.vue'
|
||||
import LandMarkPoints from "/@/components/LandMarkPoints.vue"
|
||||
import LandMarkWindow from '/@/components/LandMarkWindow.vue'
|
||||
import LandMarkShow from '/@/components/LandMarkShow.vue'
|
||||
import Application from "/@/components/Application.vue";
|
||||
import CalculationArea from "/@/components/CalculationArea.vue";
|
||||
|
||||
const CESIUM_PATH = (process.env.NODE_ENV === 'development' ? './node_modules/cesium/Build/Cesium/Cesium.js': './Cesium/Cesium.js')
|
||||
const CESIUM_PATH =
|
||||
process.env.NODE_ENV === "development"
|
||||
? "./node_modules/cesium/Build/Cesium/Cesium.js"
|
||||
: "./Cesium/Cesium.js";
|
||||
|
||||
const clear = ref();
|
||||
|
||||
const handleClear = () => {
|
||||
clear.value.onClearBtnClick();
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
html, body, #app {
|
||||
html,
|
||||
body,
|
||||
#app {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
|
|
Before Width: | Height: | Size: 61 KiB |
Before Width: | Height: | Size: 8.1 KiB |
Before Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 6.7 KiB After Width: | Height: | Size: 72 KiB |
Before Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.2 KiB |
|
@ -1,12 +0,0 @@
|
|||
import poi1 from '/@/assets/poi/1.png'
|
||||
import poi2 from '/@/assets/poi/2.png'
|
||||
import poi3 from '/@/assets/poi/3.png'
|
||||
import poi4 from '/@/assets/poi/4.png'
|
||||
import poi5 from '/@/assets/poi/5.png'
|
||||
import poi6 from '/@/assets/poi/6.png'
|
||||
import poi7 from '/@/assets/poi/7.png'
|
||||
import poi8 from '/@/assets/poi/8.png'
|
||||
import poi9 from '/@/assets/poi/9.png'
|
||||
import poi10 from '/@/assets/poi/10.png'
|
||||
|
||||
export default [ poi1, poi2, poi3, poi4, poi5, poi6, poi7, poi8, poi9, poi10 ]
|
Before Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 5.4 KiB |
Before Width: | Height: | Size: 5.5 KiB |
Before Width: | Height: | Size: 15 KiB |
|
@ -0,0 +1,59 @@
|
|||
|
||||
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
li {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
div::-webkit-scrollbar {
|
||||
width: 0;
|
||||
}
|
||||
|
||||
.w-full {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.h-full {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.w-h-full {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.text-center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
|
||||
.flex {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.flex-col {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.flex-1 {
|
||||
flex: 1 1 0%;
|
||||
}
|
||||
|
||||
.mx-auto {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.text-right {
|
||||
text-align: right;
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
<template>
|
||||
<n-config-provider
|
||||
:locale="zhCN"
|
||||
:date-locale="dateZhCN"
|
||||
:theme-overrides="themeOverrides"
|
||||
>
|
||||
<n-loading-bar-provider>
|
||||
<n-message-provider>
|
||||
<n-notification-provider>
|
||||
<n-dialog-provider>
|
||||
<slot name="default"></slot>
|
||||
</n-dialog-provider>
|
||||
</n-notification-provider>
|
||||
</n-message-provider>
|
||||
</n-loading-bar-provider>
|
||||
</n-config-provider>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
zhCN,
|
||||
dateZhCN,
|
||||
NConfigProvider,
|
||||
NDialogProvider,
|
||||
NMessageProvider,
|
||||
NLoadingBarProvider,
|
||||
NNotificationProvider,
|
||||
} from "naive-ui";
|
||||
|
||||
const themeOverrides = {};
|
||||
</script>
|
|
@ -0,0 +1,258 @@
|
|||
<template>
|
||||
<n-flex vertical>
|
||||
<div style="height:100vh">
|
||||
<n-scrollbar style="max-height: 100vh; border: 1px solid #ddd;padding-top:10vh;padding-bottom:10vh;">
|
||||
<n-dynamic-input
|
||||
v-model:value="geodata"
|
||||
:on-create="onCreate"
|
||||
:on-remove="onRemove"
|
||||
>
|
||||
<template #default="{ value }">
|
||||
<div style="display: flex; align-items: flex-start; width: 100%">
|
||||
<div style="width: 50%">
|
||||
<n-input
|
||||
maxlength="13"
|
||||
clearable
|
||||
v-model:value="value.lat"
|
||||
type="text"
|
||||
placeholder="经度"
|
||||
@input="handleInput"
|
||||
:status="value.latStatus"
|
||||
/>
|
||||
<n-gradient-text :size="12" type="error" v-show="value.latCheck">
|
||||
<div v-html="value.latErrMsg"></div>
|
||||
</n-gradient-text>
|
||||
</div>
|
||||
<div style="width: 50%">
|
||||
<n-input
|
||||
maxlength="12"
|
||||
clearable
|
||||
v-model:value="value.lng"
|
||||
type="text"
|
||||
placeholder="纬度"
|
||||
@input="handleInput"
|
||||
:status="value.lngStatus"
|
||||
/>
|
||||
<n-gradient-text :size="12" type="error" v-show="value.lngCheck">
|
||||
<div v-html="value.lngErrMsg"></div>
|
||||
</n-gradient-text>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</n-dynamic-input>
|
||||
<div class="w-full flex flex-1" style="border: 1px solid #ddd;position:absolute;bottom:5vh;left:0;">
|
||||
<n-button
|
||||
class="mx-auto"
|
||||
:disabled="geodata.length == 0 ? true : false"
|
||||
size="large"
|
||||
type="primary"
|
||||
@click="drawTrajectory"
|
||||
>生成轨迹</n-button
|
||||
>
|
||||
<n-button
|
||||
class="mx-auto"
|
||||
:disabled="geodata.length == 0 ? true : false"
|
||||
size="large"
|
||||
type="info"
|
||||
@click="drawArea"
|
||||
>生成图案</n-button
|
||||
>
|
||||
<n-button
|
||||
class="mx-auto"
|
||||
:disabled="geodata.length == 0 ? true : false"
|
||||
size="large"
|
||||
type="error"
|
||||
@click="delgeo"
|
||||
>清空输入</n-button
|
||||
>
|
||||
</div>
|
||||
</n-scrollbar>
|
||||
</div>
|
||||
</n-flex>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, defineEmits } from "vue";
|
||||
import {
|
||||
NFlex,
|
||||
NButton,
|
||||
NDynamicInput,
|
||||
NScrollbar,
|
||||
NInput,
|
||||
NGradientText,
|
||||
useMessage,
|
||||
useDialog,
|
||||
} from "naive-ui";
|
||||
import { usePositionArrStore } from "/@/stores/positionArr";
|
||||
|
||||
const message = useMessage();
|
||||
|
||||
const dialog = useDialog();
|
||||
|
||||
const emit = defineEmits(['clear']);
|
||||
|
||||
const positionArr = usePositionArrStore();
|
||||
|
||||
const geodata = ref([
|
||||
{
|
||||
lat: "",
|
||||
latStatus: "",
|
||||
latCheck: "",
|
||||
latErrMsg: "",
|
||||
lng: "",
|
||||
lngStatus: "",
|
||||
lngCheck: "",
|
||||
lngErrMsg: "",
|
||||
},
|
||||
]);
|
||||
|
||||
const onCreate = () => {
|
||||
return {
|
||||
lat: "",
|
||||
latStatus: "",
|
||||
latCheck: "",
|
||||
latErrMsg: "",
|
||||
lng: "",
|
||||
lngStatus: "",
|
||||
lngCheck: "",
|
||||
lngErrMsg: "",
|
||||
};
|
||||
};
|
||||
|
||||
const inputFilter = (inputData) => {
|
||||
let infilter = [];
|
||||
let beffilter = [...inputData];
|
||||
beffilter.forEach((item) => {
|
||||
if (item !== "\u00A0" && item !== "\u0020" && item !== "\u3000") {
|
||||
if (!isNaN(Number(item))) {
|
||||
infilter.push(item);
|
||||
} else if (item == ".") {
|
||||
if (infilter.indexOf(".") == "-1") {
|
||||
infilter.push(item);
|
||||
}
|
||||
} else if (item == "-") {
|
||||
if (infilter.indexOf("-") == "-1") {
|
||||
infilter.push(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
return infilter.join("");
|
||||
};
|
||||
|
||||
const stuck = (dataObj, dataItem, Status, Check, ErrMsg, throwMsg) => {
|
||||
dataObj[dataItem + "Status"] = Status;
|
||||
dataObj[dataItem + "Check"] = Check;
|
||||
dataObj[dataItem + "ErrMsg"] = ErrMsg;
|
||||
if (throwMsg) {
|
||||
message.error(ErrMsg);
|
||||
throw new Error(ErrMsg);
|
||||
}
|
||||
};
|
||||
|
||||
const judgment = (dataObj, dataItem, ErrMsg, throwMsg) => {
|
||||
let toJudgment;
|
||||
if (dataItem == "lat") {
|
||||
toJudgment =
|
||||
Number(dataObj[dataItem]).toFixed(8) > 180 ||
|
||||
Number(dataObj[dataItem]).toFixed(8) < -180;
|
||||
} else if (dataItem == "lng") {
|
||||
toJudgment =
|
||||
Number(dataObj[dataItem]).toFixed(8) > 90 ||
|
||||
Number(dataObj[dataItem]).toFixed(8) < -90;
|
||||
}
|
||||
if (dataObj[dataItem] == "") {
|
||||
stuck(dataObj, dataItem, "error", true, ErrMsg + "不能为空", throwMsg);
|
||||
} else if (
|
||||
(dataObj[dataItem].indexOf("-") !== -1 && dataObj[dataItem].indexOf("-") !== 0) ||
|
||||
dataObj[dataItem].indexOf(".") == dataObj[dataItem].length - 1 ||
|
||||
dataObj[dataItem].indexOf("-") + 1 == dataObj[dataItem].indexOf(".")
|
||||
) {
|
||||
stuck(dataObj, dataItem, "error", true, ErrMsg + "数据格式错误", throwMsg);
|
||||
} else if (toJudgment) {
|
||||
stuck(dataObj, dataItem, "error", true, "非法的" + ErrMsg + "数据", throwMsg);
|
||||
} else {
|
||||
stuck(dataObj, dataItem, "success", false, "", false);
|
||||
if (throwMsg) {
|
||||
dataObj[dataItem] = Number(dataObj[dataItem]).toString();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleInput = () => {
|
||||
geodata.value.forEach((element, index) => {
|
||||
element.lat = inputFilter(element.lat);
|
||||
element.lng = inputFilter(element.lng);
|
||||
judgment(element, "lat", "经度", false);
|
||||
judgment(element, "lng", "纬度", false);
|
||||
});
|
||||
};
|
||||
|
||||
const calculation = () => {
|
||||
let pointArr = [];
|
||||
geodata.value.forEach((element, index) => {
|
||||
judgment(element, "lat", "经度", true);
|
||||
judgment(element, "lng", "纬度", true);
|
||||
pointArr.push({
|
||||
longitude: element.lat.length > 8 ? Number(element.lat).toFixed(8) : Number(element.lat),
|
||||
latitude: element.lng.length > 8 ? Number(element.lng).toFixed(8) : Number(element.lng),
|
||||
});
|
||||
});
|
||||
return pointArr;
|
||||
};
|
||||
|
||||
const delgeo = () => {
|
||||
dialog.warning({
|
||||
title: "警告",
|
||||
content: "确定要清除全部输入吗?",
|
||||
positiveText: "确定",
|
||||
negativeText: "返回",
|
||||
onPositiveClick: () => {
|
||||
emit('clear');
|
||||
positionArr.$reset();
|
||||
geodata.value = [
|
||||
{
|
||||
lat: "",
|
||||
latStatus: "",
|
||||
latCheck: "",
|
||||
lng: "",
|
||||
lngStatus: "",
|
||||
lngCheck: "",
|
||||
},
|
||||
];
|
||||
},
|
||||
onNegativeClick: () => {
|
||||
message.error("已返回");
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const drawTrajectory = () => {
|
||||
if (geodata.value.length <= 1) {
|
||||
message.error("经纬度数据对的数量不能满足运算");
|
||||
return;
|
||||
}
|
||||
positionArr.add('trajectory', calculation());
|
||||
};
|
||||
|
||||
const drawArea = () => {
|
||||
if (geodata.value.length <= 2) {
|
||||
message.error("经纬度数据对的数量不能满足运算");
|
||||
return;
|
||||
}
|
||||
positionArr.add('area', calculation());
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.n-grid {
|
||||
place-items: center;
|
||||
}
|
||||
.p {
|
||||
padding: 1%;
|
||||
padding-top: 2%;
|
||||
}
|
||||
.mt {
|
||||
margin-top: 2%;
|
||||
}
|
||||
</style>
|
|
@ -1,5 +1,10 @@
|
|||
<template>
|
||||
<vc-viewer :showCredit="false" @ready="ready" @leftDoubleClick="leftDoubleClick" :info-box="false">
|
||||
<vc-viewer
|
||||
:showCredit="false"
|
||||
@ready="ready"
|
||||
@leftDoubleClick="leftDoubleClick"
|
||||
:info-box="false"
|
||||
>
|
||||
<vc-layer-imagery>
|
||||
<vc-imagery-provider-urltemplate
|
||||
:projectionTransforms="projectionTransforms"
|
||||
|
@ -32,10 +37,9 @@
|
|||
</template>
|
||||
|
||||
<script setup>
|
||||
import Compass from '/@/components/Compass.vue'
|
||||
import { usePointStore } from "/@/stores/point";
|
||||
import Compass from "/@/components/Compass.vue";
|
||||
import { usePositionStore } from "/@/stores/position";
|
||||
import { useFlytoStore } from "/@/stores/flyto";
|
||||
import { usePositionArrStore } from "/@/stores/positionArr";
|
||||
import {
|
||||
VcViewer,
|
||||
VcStatusBar,
|
||||
|
@ -55,51 +59,76 @@ const ready = (readyObj) => {
|
|||
|
||||
viewer._selectionIndicator = false;
|
||||
//不显示选中指示器
|
||||
viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
|
||||
viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(
|
||||
Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK
|
||||
);
|
||||
//屏蔽Cesium的默认双击追踪选中entity行为
|
||||
};
|
||||
|
||||
const point = usePointStore();
|
||||
const leftDoubleClick = ({ position }) => {
|
||||
if (!viewer) return;
|
||||
const positionArr = usePositionArrStore();
|
||||
|
||||
if (point.index >= point.length) {
|
||||
alert(`最多只能够添加 ${point.length} 个点`);
|
||||
return;
|
||||
const drawTrack = (points) => {
|
||||
// 创建路径实体
|
||||
const pathEntity = viewer.entities.add({
|
||||
id: "pathEntity",
|
||||
name: "My pathEntity",
|
||||
polyline: {
|
||||
positions: [], // 初始为空,后续会添加位置点
|
||||
width: 3,
|
||||
material: Cesium.Color.RED,
|
||||
},
|
||||
});
|
||||
|
||||
// 将经纬度点转换为Cartesian3并添加到路径中
|
||||
points.forEach((point) => {
|
||||
const position = Cesium.Cartesian3.fromDegrees(point.longitude, point.latitude);
|
||||
pathEntity.polyline.positions._value.push(position);
|
||||
});
|
||||
};
|
||||
|
||||
const drawPolygon = (positionsArray) => {
|
||||
// 将经纬度数组转换为Cesium.Cartesian3数组
|
||||
const cartesianPositions = positionsArray.map((pos) => {
|
||||
return Cesium.Cartesian3.fromDegrees(pos.longitude, pos.latitude);
|
||||
});
|
||||
|
||||
// 创建多边形实体并添加到viewer.entities中
|
||||
const polygonEntity = viewer.entities.add({
|
||||
id: "polygonEntity",
|
||||
name: "My polygonEntity",
|
||||
polygon: {
|
||||
// 多边形的位置数组
|
||||
hierarchy: cartesianPositions,
|
||||
// 多边形的外观
|
||||
material: Cesium.Color.BLUE.withAlpha(0.5), // 半透明蓝色
|
||||
height: 0, // 多边形的高度,可以根据需要调整
|
||||
// 可选:多边形的边界线
|
||||
outline: true, // 是否显示边界线
|
||||
outlineColor: Cesium.Color.WHITE, // 边界线颜色
|
||||
outlineWidth: 2, // 边界线宽度
|
||||
},
|
||||
});
|
||||
|
||||
return polygonEntity;
|
||||
};
|
||||
|
||||
positionArr.$subscribe((_, state) => {
|
||||
if (state.mode == "trajectory") {
|
||||
drawTrack(state.positionArr);
|
||||
}
|
||||
|
||||
const cartesian = viewer.camera.pickEllipsoid(position, viewer.scene.globe.ellipsoid);
|
||||
|
||||
if (!cartesian) return;
|
||||
|
||||
const lnglat = cartesian2Lonlat(cartesian);
|
||||
|
||||
point.addItem(lnglat);
|
||||
};
|
||||
|
||||
const cartesian2Lonlat = (cartesian) => {
|
||||
if (!Cesium) return;
|
||||
|
||||
const cartographic = Cesium.Cartographic.fromCartesian(cartesian);
|
||||
const lng = Cesium.Math.toDegrees(cartographic.longitude).toFixed(8);
|
||||
const lat = Cesium.Math.toDegrees(cartographic.latitude).toFixed(8);
|
||||
|
||||
return { lng, lat };
|
||||
};
|
||||
if (state.mode == "area") {
|
||||
drawPolygon(state.positionArr);
|
||||
}
|
||||
if (state.mode == "") {
|
||||
let pathEntity = viewer.entities.getById('pathEntity');
|
||||
viewer.entities.remove(pathEntity);
|
||||
let polygonEntity = viewer.entities.getById('polygonEntity');
|
||||
viewer.entities.remove(polygonEntity);
|
||||
}
|
||||
});
|
||||
|
||||
const position = usePositionStore();
|
||||
position.$subscribe((_, state) => {
|
||||
// 侦听到state变化时,把state存在localStorage中
|
||||
// localStorage.setItem('cart', JSON.stringify(state))
|
||||
if (!isLnglat(state)) return;
|
||||
|
||||
viewer.camera.flyTo({
|
||||
destination: Cesium.Cartesian3.fromDegrees(state.lng, state.lat, 2000.0),
|
||||
});
|
||||
});
|
||||
|
||||
const flyto = useFlytoStore();
|
||||
flyto.$subscribe((_, state) => {
|
||||
if (!isLnglat(state)) return;
|
||||
|
||||
viewer.camera.flyTo({
|
||||
|
@ -109,12 +138,16 @@ flyto.$subscribe((_, state) => {
|
|||
|
||||
// 默认值 天安门广场经纬度 116.39140105, 39.90452844 高度 2000.0
|
||||
const pointTo = () => {
|
||||
let initialPosition = Cesium.Cartesian3.fromDegrees(position.lng?position.lng:116.39140105, position.lat?position.lat:39.90452844, 2000.0);
|
||||
let initialPosition = Cesium.Cartesian3.fromDegrees(
|
||||
position.lng ? position.lng : 116.39140105,
|
||||
position.lat ? position.lat : 39.90452844,
|
||||
2000.0
|
||||
);
|
||||
let initialOrientation = Cesium.HeadingPitchRoll.fromDegrees(0.0, -90.0, 0.0);
|
||||
viewer.camera.flyTo({
|
||||
destination: initialPosition,
|
||||
orientation: initialOrientation,
|
||||
endtransform: Cesium.Matrix4.IDENTITY,
|
||||
});
|
||||
}
|
||||
};
|
||||
</script>
|
|
@ -1,112 +0,0 @@
|
|||
<template>
|
||||
<div>
|
||||
<div
|
||||
v-show="!showit"
|
||||
class="switch"
|
||||
style="position: absolute; top: -40px; right: 0; z-index: 99; cursor: pointer"
|
||||
@click="showLandmark"
|
||||
>
|
||||
<img class="icon" src="../assets/up.png" />
|
||||
</div>
|
||||
<div
|
||||
v-show="showit"
|
||||
class="switch"
|
||||
style="position: absolute; top: -50px; right: 0; z-index: 99; cursor: pointer"
|
||||
@click="showLandmark"
|
||||
>
|
||||
<img class="icon" src="../assets/down.png" />
|
||||
</div>
|
||||
<div class="landmark">
|
||||
<table v-if="showit">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>景点名称</th>
|
||||
<th>经度</th>
|
||||
<th>纬度</th>
|
||||
<th>访问景点</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="(item, index) in landmarkArr" :key="index">
|
||||
<td>{{ item ? item.landmark : index + 1 }}</td>
|
||||
<td>{{ item ? item.position.lng : "" }}</td>
|
||||
<td>{{ item ? item.position.lat : "" }}</td>
|
||||
<td>
|
||||
<button style="cursor: pointer" @click="write(item.position)">访问</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { useFlytoStore } from "/@/stores/flyto";
|
||||
import { landmarkArr } from "/@/information/landmark";
|
||||
|
||||
let showit = ref(false);
|
||||
|
||||
const showLandmark = () => {
|
||||
showit.value = !showit.value;
|
||||
};
|
||||
|
||||
const flyto = useFlytoStore();
|
||||
|
||||
const write = (flytoLand) => {
|
||||
flyto.set(flytoLand);
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.landmark {
|
||||
max-height: 360px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.switch {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.icon {
|
||||
width: 50px;
|
||||
}
|
||||
|
||||
table {
|
||||
color: #ffffff;
|
||||
background-color: #242424;
|
||||
padding: 10px;
|
||||
border-radius: 7px;
|
||||
border-collapse: separate;
|
||||
border-spacing: 2px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
table th:first-child {
|
||||
width: 120px;
|
||||
}
|
||||
|
||||
table th:not(:first-child) {
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
table thead tr {
|
||||
background-color: rgba(84, 84, 84, 0.8);
|
||||
}
|
||||
|
||||
table tbody tr:nth-child(even) {
|
||||
background-color: rgba(84, 84, 84, 0.8);
|
||||
}
|
||||
|
||||
table tbody tr:nth-child(odd) {
|
||||
background-color: rgba(84, 84, 84, 0.25);
|
||||
}
|
||||
|
||||
table th,
|
||||
table td {
|
||||
padding: 3px 5px;
|
||||
}
|
||||
</style>
|
|
@ -1,16 +0,0 @@
|
|||
<template>
|
||||
<Pin
|
||||
v-for="item, index in landmarkArr"
|
||||
:key="index"
|
||||
:position="item.position"
|
||||
:image="showpin"
|
||||
:pintype="landmark"/>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { landmarkArr } from '/@/information/landmark'
|
||||
import Pin from '/@/components/Pin.vue'
|
||||
import showpin from '/@/assets/showpin.png'
|
||||
|
||||
const landmark = "landmark"
|
||||
</script>
|
|
@ -1,221 +0,0 @@
|
|||
<template>
|
||||
<div class="lightbox" :style="judgmentShow">
|
||||
<div class="boxImg">
|
||||
<img :id="nowId" style="height:100%;display:block;margin:auto;" :src="nowImg" />
|
||||
<div id="describesBox" class="describesBox" :style="describesShow">
|
||||
<div class="textBox">
|
||||
<br />
|
||||
<h1 class="describesTitle">{{LandMarkShow.information.landTitle}}</h1>
|
||||
<br />
|
||||
<div class="paragraphBox">
|
||||
<p class="describesParagraph">{{LandMarkShow.information.landDescribes}}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="brieflyBox" class="brieflyBox" :style="brieflyShow">
|
||||
<div class="textBox">
|
||||
<h3 class="brieflyTitle">{{LandMarkShow.information.landTitle}}</h3>
|
||||
<div class="paragraphBox">
|
||||
<p class="brieflyParagraph">{{LandMarkShow.information.landBriefly}}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="share showBtn">
|
||||
<img class="imgBase" :style="judgmentUp" src="../../src/assets/up.png" @click="up" />
|
||||
<img class="imgBase" :style="judgmentDown" src="../../src/assets/down.png" @click="down" />
|
||||
</div>
|
||||
<div class="share leftBtn">
|
||||
<img class="imgBase" src="../../src/assets/left.png" @click="left" />
|
||||
</div>
|
||||
<div class="share rightBtn">
|
||||
<img class="imgBase" src="../../src/assets/right.png" @click="right" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="share boxClose">
|
||||
<img class="imgBase" src="../../src/assets/close.png" @click="close" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { LandMarkShowStore } from '/@/stores/LandMarkShow';
|
||||
import { ref, watch } from 'vue';
|
||||
|
||||
const LandMarkShow = LandMarkShowStore();
|
||||
|
||||
const judgmentShow = ref();
|
||||
const describesShow = ref();
|
||||
const brieflyShow = ref();
|
||||
const nowId = ref(1);
|
||||
const nowImg = ref();
|
||||
const judgmentUp = ref("dispaly:block;");
|
||||
const judgmentDown = ref("dispaly:none;");
|
||||
|
||||
//文本内容自适应照片宽度
|
||||
const adaptive = (imgId) => {
|
||||
let newImg;
|
||||
setTimeout(() => {
|
||||
newImg = document.getElementById(imgId);
|
||||
}, 10);
|
||||
//程序执行需要时间
|
||||
setTimeout(() => {
|
||||
let newWidth = window.getComputedStyle(newImg, null)["width"];
|
||||
let newMargin = window.getComputedStyle(newImg, null).marginLeft;
|
||||
describesShow.value = `width:${newWidth};left:${newMargin};${judgmentDown.value}`;
|
||||
brieflyShow.value = `width:${newWidth};left:${newMargin};${judgmentUp.value}`;
|
||||
}, 20);
|
||||
}
|
||||
|
||||
watch(() => LandMarkShow.boxShow, (newValue, oldValue) => {
|
||||
judgmentShow.value = `display:${LandMarkShow.boxShow?'block':'none'};`;
|
||||
adaptive(nowId.value);
|
||||
})
|
||||
|
||||
watch(() => LandMarkShow.information.landImgUrl, (newValue, oldValue) => {
|
||||
nowId.value = 1;
|
||||
nowImg.value = `${LandMarkShow.information.landImgUrl}${nowId.value}.webp`;
|
||||
judgmentUp.value = "display:block;";
|
||||
judgmentDown.value = "display:none;";
|
||||
adaptive(nowId.value);
|
||||
})
|
||||
|
||||
const up = () => {
|
||||
judgmentUp.value = "display:none;";
|
||||
judgmentDown.value = "display:block;";
|
||||
adaptive(nowId.value);
|
||||
}
|
||||
|
||||
const down = () => {
|
||||
judgmentUp.value = "display:block;";
|
||||
judgmentDown.value = "display:none;";
|
||||
adaptive(nowId.value);
|
||||
}
|
||||
|
||||
const left = () => {
|
||||
nowId.value = nowId.value - 1;
|
||||
if (nowId.value == 0) {
|
||||
nowId.value = LandMarkShow.information.landImgCount;
|
||||
}
|
||||
nowImg.value = `${LandMarkShow.information.landImgUrl}${nowId.value}.webp`;
|
||||
adaptive(nowId.value);
|
||||
}
|
||||
|
||||
const right = () => {
|
||||
nowId.value = nowId.value + 1;
|
||||
if (nowId.value > LandMarkShow.information.landImgCount) {
|
||||
nowId.value = 1;
|
||||
}
|
||||
nowImg.value = `${LandMarkShow.information.landImgUrl}${nowId.value}.webp`;
|
||||
adaptive(nowId.value);
|
||||
}
|
||||
|
||||
const close = () => {
|
||||
LandMarkShow.boxShow = false;
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.lightbox {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
background: rgba(0, 0, 0, 0.4);
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
user-select: none;
|
||||
display:none;
|
||||
}
|
||||
.boxImg {
|
||||
width: 70%;
|
||||
height: 50%;
|
||||
position: absolute;
|
||||
top: 20%;
|
||||
left: 15%;
|
||||
}
|
||||
.imgBase {
|
||||
width: 100%;
|
||||
}
|
||||
.share {
|
||||
min-width: 32px;
|
||||
min-height: 32px;
|
||||
width: 3vw;
|
||||
height: 3vw;
|
||||
position: absolute;
|
||||
bottom: -15%;
|
||||
z-index: 1;
|
||||
border-radius: 50%;
|
||||
overflow: hidden;
|
||||
cursor: pointer;
|
||||
box-shadow:inset 0px 0px 6px white;
|
||||
}
|
||||
.describesBox {
|
||||
width: 60%;
|
||||
height: 100%;
|
||||
background: rgba(255, 255, 255, 0.5);
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 20%;
|
||||
display: none;
|
||||
text-shadow: 0 0 6px white;
|
||||
}
|
||||
.brieflyBox {
|
||||
width: 60%;
|
||||
height: 24%;
|
||||
background: linear-gradient(rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.8));
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 20%;
|
||||
text-shadow: 0 0 6px black;
|
||||
}
|
||||
.textBox {
|
||||
width: 80%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
margin: auto;
|
||||
}
|
||||
.paragraphBox{
|
||||
height:80%;
|
||||
overflow-x:hidden;
|
||||
overflow-y:auto;
|
||||
}
|
||||
.describesTitle {
|
||||
text-align: center;
|
||||
margin: 0;
|
||||
font-size: clamp(0.8rem, 0.489rem + 1.05vw, 2rem);
|
||||
}
|
||||
.describesParagraph {
|
||||
text-align: left;
|
||||
text-indent: 2em;
|
||||
margin: 0;
|
||||
font-weight:bolder;
|
||||
font-size: clamp(0.5rem, 0.489rem + 1.05vw, 1rem);
|
||||
}
|
||||
.brieflyTitle {
|
||||
color: #fff;
|
||||
text-align: left;
|
||||
margin-top: 4%;
|
||||
margin-bottom: 1%;
|
||||
font-size: clamp(0.6rem, 0.489rem + 1.05vw, 1.2rem);
|
||||
}
|
||||
.brieflyParagraph {
|
||||
color: #fff;
|
||||
text-align: left;
|
||||
text-indent: 2em;
|
||||
margin-top: 0;
|
||||
font-weight:bolder;
|
||||
font-size: clamp(0.4rem, 0.489rem + 1.05vw, 0.8rem);
|
||||
}
|
||||
.boxClose {
|
||||
bottom: 15%;
|
||||
left: 48.5%;
|
||||
}
|
||||
.showBtn {
|
||||
left: 47.8%;
|
||||
}
|
||||
.leftBtn {
|
||||
left: 40%;
|
||||
}
|
||||
.rightBtn {
|
||||
right: 40%;
|
||||
}
|
||||
</style>
|
|
@ -1,132 +0,0 @@
|
|||
<template>
|
||||
<div class="window" :style="nowPosition">
|
||||
<div class="base">
|
||||
<div>{{LandMarkWindow.information.landTitle}}</div>
|
||||
<div class="triangle"></div>
|
||||
<div class="backimg" :style="nowImg">{{LandMarkWindow.information.landTitle}}</div>
|
||||
</div>
|
||||
<div class="closeBtn" @click="closeWindow">
|
||||
<svg
|
||||
t="1603334792546"
|
||||
class="icon"
|
||||
viewBox="0 0 1024 1024"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="1328"
|
||||
width="20"
|
||||
height="20"
|
||||
>
|
||||
<path
|
||||
d="M568.922 508.232L868.29 208.807a39.139 39.139 0 0 0 0-55.145l-1.64-1.64a39.139 39.139 0 0 0-55.09 0l-299.367 299.82-299.425-299.934a39.139 39.139 0 0 0-55.088 0l-1.697 1.64a38.46 38.46 0 0 0 0 55.09l299.48 299.594-299.424 299.48a39.139 39.139 0 0 0 0 55.09l1.64 1.696a39.139 39.139 0 0 0 55.09 0l299.424-299.48L811.56 864.441a39.139 39.139 0 0 0 55.089 0l1.696-1.64a39.139 39.139 0 0 0 0-55.09l-299.48-299.537z"
|
||||
p-id="1329"
|
||||
></path>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="changeButton" @click="judgment">{{LandMarkWindow.buttonText?'地点信息':'探索'}}</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { LandMarkWindowStore } from '/@/stores/LandMarkWindow';
|
||||
import { LandMarkShowStore } from '/@/stores/LandMarkShow';
|
||||
import { ref, watch } from 'vue';
|
||||
|
||||
const LandMarkWindow = LandMarkWindowStore();
|
||||
const LandMarkShow = LandMarkShowStore();
|
||||
|
||||
const nowPosition = ref();
|
||||
const nowImg = ref();
|
||||
|
||||
watch(() => LandMarkWindow.windowShow, (newValue, oldValue) => {
|
||||
nowPosition.value = `bottom:${LandMarkWindow.windowPosition.bottom};left:${LandMarkWindow.windowPosition.left};display:${LandMarkWindow.windowShow?'block':'none'};`;
|
||||
})
|
||||
|
||||
watch(() => LandMarkWindow.information.landImgUrl, (newValue, oldValue) => {
|
||||
nowImg.value = `background-image: url('${LandMarkWindow.information.landImgUrl}1.webp');`;
|
||||
})
|
||||
|
||||
watch(() => LandMarkWindow.windowPosition.left, (newValue, oldValue) => {
|
||||
nowPosition.value = `bottom:${LandMarkWindow.windowPosition.bottom};left:${LandMarkWindow.windowPosition.left};display:${LandMarkWindow.windowShow?'block':'none'};`;
|
||||
})
|
||||
|
||||
const closeWindow = () => {
|
||||
LandMarkWindow.windowShow = false;
|
||||
LandMarkWindow.hiddenWindow = true;
|
||||
}
|
||||
const flyToLandmark = () => {
|
||||
LandMarkWindow.flyToLand = true;
|
||||
}
|
||||
const watchImg = () => {
|
||||
LandMarkShow.boxShow = true;
|
||||
LandMarkShow.information = LandMarkWindow.information;
|
||||
}
|
||||
const judgment = () => {
|
||||
if(LandMarkWindow.buttonText){
|
||||
watchImg()
|
||||
}else{
|
||||
flyToLandmark()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.window {
|
||||
width: 300px;
|
||||
height: 30px;
|
||||
position: absolute;
|
||||
display:none;
|
||||
}
|
||||
.base {
|
||||
background: #FFFFA0;
|
||||
height: 200px;
|
||||
text-align: center;
|
||||
}
|
||||
.triangle {
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-top: 10px solid red;
|
||||
border-right: 10px solid transparent;
|
||||
border-left: 10px solid transparent;
|
||||
position: absolute;
|
||||
left: 140px;
|
||||
bottom: -200px;
|
||||
}
|
||||
.backimg {
|
||||
color: red;
|
||||
text-shadow: 0px 0px 8px rgba(255, 255, 255, 0.5);
|
||||
padding-top: 4px;
|
||||
font-size: 32px;
|
||||
background-size: cover;
|
||||
height: 200px;
|
||||
line-height:100px;
|
||||
border-radius: 0px 0px 10px 10px;
|
||||
}
|
||||
.closeBtn {
|
||||
width:20px;
|
||||
height:21px;
|
||||
position:absolute;
|
||||
top:0;
|
||||
right:0;
|
||||
background-color:#fff;
|
||||
cursor:pointer;
|
||||
}
|
||||
.closeBtn:hover {
|
||||
background-color: red;
|
||||
}
|
||||
.changeButton {
|
||||
width:110px;
|
||||
height:40px;
|
||||
position:absolute;
|
||||
top:100px;
|
||||
right:95px;
|
||||
background-image:url('../../src/assets/button.png');
|
||||
background-size:cover;
|
||||
color:#fff;
|
||||
border:1px solid skyblue;
|
||||
border-radius:16px;
|
||||
box-shadow:0px 0px 8px skyblue;
|
||||
text-align:center;
|
||||
line-height:36px;
|
||||
cursor:pointer;
|
||||
}
|
||||
</style>
|
|
@ -23,34 +23,23 @@
|
|||
|
||||
<script setup>
|
||||
import { ref } from "vue";
|
||||
import { usePointStore } from "/@/stores/point";
|
||||
import { usePositionStore } from "/@/stores/position";
|
||||
import { useFlytoStore } from "/@/stores/flyto";
|
||||
import { isLnglat } from "/@/api/util";
|
||||
|
||||
const lng = ref(NaN);
|
||||
const lat = ref(NaN);
|
||||
const position = usePositionStore();
|
||||
const flyto = useFlytoStore();
|
||||
|
||||
flyto.$subscribe((_, state) => {
|
||||
if (!isLnglat(state)) return;
|
||||
|
||||
lng.value = flyto.lng;
|
||||
lat.value = flyto.lat;
|
||||
});
|
||||
|
||||
const onFlyBtnClick = () => {
|
||||
if (!position.set({ lng: lng.value, lat: lat.value })) alert("请输入正确的经纬度信息");
|
||||
};
|
||||
|
||||
const point = usePointStore();
|
||||
const onClearBtnClick = () => {
|
||||
lng.value = NaN;
|
||||
lat.value = NaN;
|
||||
position.$reset();
|
||||
point.$reset();
|
||||
};
|
||||
|
||||
defineExpose({ onClearBtnClick });
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
|
|
@ -1,62 +0,0 @@
|
|||
<template>
|
||||
<table v-if="show">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>序号</th>
|
||||
<th>经度</th>
|
||||
<th>纬度</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="point-list">
|
||||
<tr v-for="item, index in point.items" :key="index">
|
||||
<td>{{ index + 1 }}</td>
|
||||
<td>{{ item ? item.lng : ''}}</td>
|
||||
<td>{{ item ? item.lat : ''}}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
import { usePointStore } from '/@/stores/point'
|
||||
|
||||
const point = usePointStore()
|
||||
const show = computed(() => point.index)
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
table {
|
||||
color: #FFFFFF;
|
||||
background-color: #242424;
|
||||
padding: 10px;
|
||||
border-radius: 7px;
|
||||
border-collapse: separate;
|
||||
border-spacing: 2px;
|
||||
text-align:center;
|
||||
}
|
||||
|
||||
table th:first-child {
|
||||
width: 60px;
|
||||
}
|
||||
|
||||
table th:not(:first-child) {
|
||||
width: 120px;
|
||||
}
|
||||
|
||||
table thead tr {
|
||||
background-color: rgba(84, 84, 84, 0.8);
|
||||
}
|
||||
|
||||
table tbody tr:nth-child(even) {
|
||||
background-color: rgba(84, 84, 84, 0.8);
|
||||
}
|
||||
|
||||
table tbody tr:nth-child(odd) {
|
||||
background-color: rgba(84, 84, 84, 0.25);
|
||||
}
|
||||
|
||||
table th, table td {
|
||||
padding: 3px 5px;
|
||||
}
|
||||
</style>
|
|
@ -1,15 +0,0 @@
|
|||
<template>
|
||||
<Pin
|
||||
v-for="item, index in point.items"
|
||||
:key="index"
|
||||
:position="item"
|
||||
:image="pois[index]"/>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { usePointStore } from '/@/stores/point'
|
||||
import Pin from '/@/components/Pin.vue'
|
||||
import pois from '/@/assets/poi'
|
||||
|
||||
const point = usePointStore()
|
||||
</script>
|
|
@ -1,199 +1,29 @@
|
|||
<template>
|
||||
<vc-entity
|
||||
:show="pintype == 'landmark' ? landshow : show"
|
||||
:show="show"
|
||||
:position="position"
|
||||
@click="clickPin"
|
||||
@ready="ready"
|
||||
>
|
||||
<vc-graphics-billboard
|
||||
:image="image"
|
||||
:image="pin"
|
||||
:verticalOrigin="1"
|
||||
:scale="pintype == 'landmark' ? jump : 1"
|
||||
:color="pintype == 'landmark' ? jumpColor : 'none'"
|
||||
:scale="1"
|
||||
:color="'none'"
|
||||
/>
|
||||
</vc-entity>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { LandMarkWindowStore } from '/@/stores/LandMarkWindow';
|
||||
import { LandMarkShowStore } from '/@/stores/LandMarkShow';
|
||||
import { ref, computed, watch } from "vue";
|
||||
import { computed } from "vue";
|
||||
import { VcEntity, VcGraphicsBillboard } from "vue-cesium";
|
||||
import { isLnglat } from "/@/api/util";
|
||||
import { landmarkArr } from "/@/information/landmark";
|
||||
import pin from "/@/assets/pin.png";
|
||||
|
||||
const LandMarkWindow = LandMarkWindowStore();
|
||||
const LandMarkShow = LandMarkShowStore();
|
||||
|
||||
const props = defineProps({
|
||||
position: {
|
||||
type: Object,
|
||||
default: { lng: NaN, lat: NaN },
|
||||
},
|
||||
image: {
|
||||
type: String,
|
||||
default: pin,
|
||||
},
|
||||
pintype: {
|
||||
type: String,
|
||||
default: "ordinary",
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
const show = computed(() => isLnglat(props.position));
|
||||
|
||||
const landshow = ref(false);
|
||||
|
||||
const jump = ref(1);
|
||||
const jumpSwitch = ref(true);
|
||||
const jumpColor = ref("none");
|
||||
|
||||
let handler = null,
|
||||
computTime = null;
|
||||
|
||||
//标点动画
|
||||
const animetion = (clearit) => {
|
||||
if(!clearit){
|
||||
clearInterval(computTime);
|
||||
}else{
|
||||
computTime = setInterval(() => {
|
||||
if (0.5 <= jump.value < 1.1 && jumpSwitch.value) {
|
||||
jump.value = Math.round(jump.value * 100) / 100 + 0.05;
|
||||
jumpColor.value = "none";
|
||||
if (jump.value == 1.1) {
|
||||
jumpSwitch.value = false;
|
||||
jumpColor.value = "rgba(0,255,255,0.5)";
|
||||
}
|
||||
} else if (0.5 < jump.value <= 1.1) {
|
||||
jump.value = Math.round(jump.value * 100) / 100 - 0.05;
|
||||
jumpColor.value = "none";
|
||||
if (jump.value == 0.5) {
|
||||
jumpSwitch.value = true;
|
||||
jumpColor.value = "rgba(0,255,255,0.5)";
|
||||
}
|
||||
}
|
||||
}, 100);
|
||||
};
|
||||
};
|
||||
|
||||
const ready = (readyObj) => {
|
||||
handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
|
||||
if (props.pintype == "landmark") {
|
||||
viewer.scene.postRender.addEventListener(() => {
|
||||
if (viewer.camera.positionCartographic.height < 100000) {
|
||||
landshow.value = true;
|
||||
} else {
|
||||
landshow.value = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
watch(landshow,() => {
|
||||
animetion(landshow.value);
|
||||
})
|
||||
|
||||
let landArr = {};
|
||||
|
||||
const insetLand = () => {
|
||||
landmarkArr.forEach((element) => {
|
||||
if (
|
||||
element.position.lng == props.position.lng &&
|
||||
element.position.lat == props.position.lat
|
||||
) {
|
||||
landArr.landTitle = element.landmark;
|
||||
landArr.landDescribes = element.describes;
|
||||
landArr.landBriefly = element.briefly;
|
||||
landArr.landImgUrl = element.imgUrl;
|
||||
landArr.landPosition = element.position;
|
||||
landArr.landImgCount = element.imgCount;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
//清除事件监听
|
||||
const clearDiv = (id) => {
|
||||
viewer.scene.postRender.removeEventListener(addDynamicLabel);
|
||||
handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
|
||||
};
|
||||
|
||||
const addDynamicLabel = (data) => {
|
||||
insetLand();
|
||||
LandMarkWindow.information = landArr;
|
||||
LandMarkWindow.windowShow = true;
|
||||
LandMarkWindow.hiddenWindow = false;
|
||||
let gisPosition = data.position._value;
|
||||
//cesium 渲染事件监听
|
||||
viewer.scene.postRender.addEventListener(() => {
|
||||
const canvasHeight = viewer.scene.canvas.height;
|
||||
const windowPosition = new Cesium.Cartesian2();
|
||||
Cesium.SceneTransforms.wgs84ToWindowCoordinates(
|
||||
viewer.scene,
|
||||
gisPosition,
|
||||
windowPosition
|
||||
);
|
||||
//组件 LandMarkWindow 宽度
|
||||
const elWidth = 300;
|
||||
let showBottom = canvasHeight - windowPosition.y + 240 + "px";
|
||||
let showLeft = windowPosition.x - elWidth / 2 + "px";
|
||||
//使弹窗跟随标点移动
|
||||
LandMarkWindow.windowPosition.bottom = showBottom;
|
||||
LandMarkWindow.windowPosition.left = showLeft;
|
||||
const camerPosition = viewer.camera.position;
|
||||
let height = viewer.scene.globe.ellipsoid.cartesianToCartographic(camerPosition).height;
|
||||
height += viewer.scene.globe.ellipsoid.maximumRadius;
|
||||
if (viewer.camera.positionCartographic.height < 2400) {
|
||||
LandMarkWindow.buttonText = true;
|
||||
} else {
|
||||
LandMarkWindow.buttonText = false;
|
||||
}
|
||||
if (viewer.camera.positionCartographic.height > 100000) {
|
||||
LandMarkWindow.windowShow = false;
|
||||
}else{
|
||||
if(!LandMarkWindow.hiddenWindow){
|
||||
LandMarkWindow.windowShow = true;
|
||||
}
|
||||
}
|
||||
if (viewer.camera.positionCartographic.height > 2400) {
|
||||
LandMarkShow.boxShow = false;
|
||||
}
|
||||
});
|
||||
handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
|
||||
handler.setInputAction(function (movement) {
|
||||
//点击空白处触发
|
||||
LandMarkWindow.windowShow = false;
|
||||
LandMarkWindow.hiddenWindow = true;
|
||||
clearDiv();
|
||||
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
|
||||
};
|
||||
|
||||
watch(() => LandMarkWindow.flyToLand, (newValue, oldValue) => {
|
||||
if(LandMarkWindow.flyToLand){
|
||||
viewer.camera.flyTo({
|
||||
destination: Cesium.Cartesian3.fromDegrees(
|
||||
LandMarkWindow.information.landPosition.lng,
|
||||
LandMarkWindow.information.landPosition.lat,
|
||||
2000.0
|
||||
),
|
||||
});
|
||||
LandMarkWindow.flyToLand = false;
|
||||
}
|
||||
})
|
||||
|
||||
const clickPin = () => {
|
||||
if (props.pintype == "landmark") {
|
||||
handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
|
||||
//cesium 监听鼠标事件
|
||||
handler.setInputAction(function (movement) {
|
||||
let pick = viewer.scene.pick(movement.position);
|
||||
//点击标点时触发
|
||||
if (Cesium.defined(pick) && pick.id.id) {
|
||||
let id = pick.id.id;
|
||||
let entiy = viewer.entities.getById(id);
|
||||
addDynamicLabel(entiy);
|
||||
}
|
||||
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
|
||||
}
|
||||
};
|
||||
</script>
|
|
@ -1,74 +0,0 @@
|
|||
export const landmarkArr = [
|
||||
{
|
||||
landmark:'北京天安门',
|
||||
position:{
|
||||
lng:116.391243,
|
||||
lat:39.907202
|
||||
},
|
||||
briefly:`天安门(Tian'anmen),始建于明朝永乐十五年(1417年),设计者为明代御用建筑匠师蒯祥。`,
|
||||
describes:`天安门(Tian'anmen),坐落在中华人民共和国首都北京市的中心、故宫的南端,与天安门广场以及人民英雄纪念碑、毛主席纪念堂、人民大会堂、中国国家博物馆隔长安街相望,占地面积4800平方米,以杰出的建筑艺术和特殊的政治地位为世人所瞩目。
|
||||
天安门是明清两代北京皇城的正门,始建于明朝永乐十五年(1417年),最初名“承天门”,寓“承天启运、受命于天”之意。设计者为明代御用建筑匠师蒯祥。清朝顺治八年(1651年)更名为天安门。由城台和城楼两部分组成,有汉白玉石的须弥座,总高34.7米。天安门城楼长66米、宽37米。城台下有券门五阙,中间的券门最大,位于北京市皇城中轴线上,过去只有皇帝才可以由此出入。正中门洞上方悬挂着毛泽东画像,两边分别是“中华人民共和国万岁”和“世界人民大团结万岁”的大幅标语。
|
||||
1925年10月10日,故宫博物院成立,天安门开始对民众开放。1949年10月1日,在这里举行了中华人民共和国开国大典,由此被设计入国徽,并成为中华人民共和国的象征。1961年,中华人民共和国国务院公布为第一批全国重点文物保护单位之一。`,
|
||||
imgUrl:'/landmarkImg/TianAnmen/',
|
||||
imgCount:8
|
||||
},
|
||||
{
|
||||
landmark:'国家体育场',
|
||||
position:{
|
||||
lng:116.390502,
|
||||
lat:39.991396
|
||||
},
|
||||
briefly:`国家体育场(National Stadium),又名“鸟巢”(Bird's Nest),位于北京奥林匹克公园中心区南部,为2008年北京奥运会的主体育场。`,
|
||||
describes:`国家体育场(National Stadium),又名“鸟巢”(Bird's Nest),位于北京奥林匹克公园中心区南部,为2008年北京奥运会的主体育场,举行了2008年夏季奥运会、残奥会开闭幕式、田径比赛及足球比赛决赛,以及2022年冬季奥运会、冬残奥会开闭幕式。
|
||||
体育场占地20.4万平方米,建筑面积25.8万平方米,可容纳观众9.1万人,其中正式座位8万个,临时座位1.1万个;由雅克·赫尔佐格、德梅隆、艾未未以及李兴钢等设计,由北京城建集团负责施工。体育场的形态如同孕育生命的“巢”和摇篮,寄托着人类对未来的希望。设计者们对这个场馆没有做任何多余的处理,把结构暴露在外,因而自然形成了建筑的外观。
|
||||
2003年12月24日开工建设,2008年3月完工,总造价22.67亿元。作为国家标志性建筑,2008年奥运会主体育场,国家体育场结构特点十分显著。体育场为特级体育建筑,大型体育场馆。主体结构设计使用年限100年,耐火等级为一级,抗震设防烈度8度,地下工程防水等级1级。2008年奥运会后,国家体育场成为北京市民参与体育活动及享受体育娱乐的大型专业场所,并成为地标性的体育建筑和奥运遗产。`,
|
||||
imgUrl:'/landmarkImg/BirdsNest/',
|
||||
imgCount:8
|
||||
},
|
||||
{
|
||||
landmark:'上海东方明珠',
|
||||
position:{
|
||||
lng:121.495263,
|
||||
lat:31.241829
|
||||
},
|
||||
briefly:`东方明珠广播电视塔,简称“东方明珠”(Oriental Pearl),位于上海市浦东新区陆家嘴世纪大道1号,地处黄浦江畔,为亚洲第六高塔、世界第九高塔。`,
|
||||
describes:`东方明珠广播电视塔,简称“东方明珠”(Oriental Pearl),位于上海市浦东新区陆家嘴世纪大道1号,地处黄浦江畔,背拥陆家嘴地区现代化建筑楼群,与隔江的外滩万国建筑博览群交相辉映,1991年7月30日动工建造,1994年10月1日建成投入使用,是集都市观光、时尚餐饮、购物娱乐、历史陈列、浦江游览、会展演出、广播电视发射等多功能于一体的上海市标志性建筑之一。截至2019年,为亚洲第六高塔、世界第九高塔。东方明珠广播电视塔主体为多筒结构,由3根斜撑、3根立柱及广场、塔座、下球体、5个小球体、上球体、太空舱、发射天线桅杆等构成,总高468米,总建筑面积达10万平方米。1995年,东方明珠广播电视塔被评为上海十大新景观之一。1999年,东方明珠广播电视塔获上海市优秀勘察设计一等奖、中国土木工程詹天佑奖。2007年5月8日,东方明珠广播电视塔被中华人民共和国国家旅游局批准为国家AAAAA级旅游景区。`,
|
||||
imgUrl:'/landmarkImg/OrientalPearl/',
|
||||
imgCount:8
|
||||
},
|
||||
{
|
||||
landmark:'香港迪士尼',
|
||||
position:{
|
||||
lng:114.042287,
|
||||
lat:22.313002
|
||||
},
|
||||
briefly:`香港迪士尼乐园(Hong Kong Disneyland)位于中华人民共和国香港特别行政区新界大屿山,占地126公顷,在2005年9月12日正式开幕。`,
|
||||
describes:`香港迪士尼乐园(Hong Kong Disneyland)位于中华人民共和国香港特别行政区新界大屿山,占地126公顷,在2005年9月12日正式开幕,由香港特别行政区政府以及华特迪士尼公司联合经营的香港国际主题乐园有限公司建设及营运,是全球第五座、亚洲第二座、中国第一座迪士尼乐园。乐园分为9个主题园区,分别为美国小镇大街、探险世界、幻想世界、明日世界、灰熊山谷、铁甲奇侠总部、反斗奇兵大本营、迷离庄园、魔雪奇缘世界,其中灰熊山谷和迷离庄园为全球独有。园区内设有主题游乐设施、娱乐表演、互动体验、餐饮服务、商品店铺及小食亭。此外,乐园每天晚上会呈献巡游表演节目及烟花汇演。2022年10月,基建咨询服务企业AECOM联合主题娱乐协会TEA发布了《2021全球主题公园和博物馆报告》,香港迪士尼乐园入选全球主题公园Top25排行榜第21名,亚太地区Top 20主题乐园排行榜第10名。`,
|
||||
imgUrl:'/landmarkImg/HongKongDisneyland/',
|
||||
imgCount:8
|
||||
},
|
||||
{
|
||||
landmark:'布达拉宫',
|
||||
position:{
|
||||
lng:91.117684,
|
||||
lat:29.656959
|
||||
},
|
||||
briefly:`布达拉宫(Potala Palace)位于中国西藏自治区首府拉萨市区西北的玛布日山上,中华人民共和国国务院第一批全国重点文物保护单位之一。是世界文化遗产。`,
|
||||
describes:`布达拉宫(Potala Palace)位于中国西藏自治区首府拉萨市区西北的玛布日山上,是一座宫堡式建筑群,一说为吐蕃王朝赞普松赞干布为迎娶尺尊公主和文成公主而兴建;另一说为,作为松赞干布迁都拉萨后的王宫而建。于17世纪重建后,成为历代达赖喇嘛的冬宫居所,为西藏政教合一的统治中心。
|
||||
布达拉宫的主体建筑为白宫和红宫两部分。整座宫殿具有藏式风格,外观13层,实际只有9层。由于它起建于山腰,大面积的石壁又屹立如峭壁,使建筑仿佛与山岗融为一体,气势雄伟。布达拉宫海拔3700米,占地总面积36万平方米,建筑总面积13万平方米,由东部的白宫、中部的红宫组成,主楼高117米。布达拉宫主体建筑的东西两侧分别向下延伸,与高大的宫墙相接。宫墙高6米,底宽4.4米,顶宽2.8米,用夯土砌筑,外包砖石。墙的东、南、西侧各有一座三层的门楼,在东南和西北角还各有一座角楼。宫墙所包围的范围全都属于布达拉宫。
|
||||
布达拉宫的壁画、木雕及建筑过程中使用的金属冶炼技术均闻名于世,体现了以藏族为主,汉、蒙、满各族能工巧匠高超的技艺。1961年,布达拉宫成为了中华人民共和国国务院第一批全国重点文物保护单位之一。1994年,布达拉宫被列为世界文化遗产。`,
|
||||
imgUrl:'/landmarkImg/PotalaPalace/',
|
||||
imgCount:8
|
||||
},
|
||||
{
|
||||
landmark:'西昌卫星发射中心',
|
||||
position:{
|
||||
lng:102.026661,
|
||||
lat:28.245627
|
||||
},
|
||||
briefly:`西昌卫星发射中心(英文:Xichang Satellite Launch Center,简称:XSLC,又称“西昌卫星城”),是中国卫星发射基地之一。`,
|
||||
describes:`西昌卫星发射中心(英文:Xichang Satellite Launch Center,简称:XSLC,又称“西昌卫星城”),是中国卫星发射基地之一。组建于1970年,是中国三大航天发射中心之一,管理使用西昌、文昌两个航天发射场。西昌发射场1982年交付使用,位于四川省凉山彝族自治州冕宁县。西昌发射场地处山区,是全球十大发射场中气候条件最为复杂的发射场之一。`,
|
||||
imgUrl:'/landmarkImg/XichangSatelliteLaunchCenter/',
|
||||
imgCount:9
|
||||
}
|
||||
]
|
|
@ -2,6 +2,8 @@ import { createPinia } from 'pinia'
|
|||
import { createApp } from 'vue'
|
||||
import App from './App.vue'
|
||||
|
||||
import './common.less'
|
||||
|
||||
import 'vue-cesium/dist/index.css';
|
||||
|
||||
createApp(App).use(createPinia()).mount('#app')
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
import { defineStore } from 'pinia'
|
||||
|
||||
|
||||
export const LandMarkShowStore = defineStore({
|
||||
id: 'LandMarkShow',
|
||||
state: () => ({
|
||||
information: {
|
||||
landTitle: NaN,
|
||||
landDescribes: NaN,
|
||||
landBriefly: NaN,
|
||||
landImgUrl: NaN,
|
||||
landPosition: NaN,
|
||||
landImgCount: NaN
|
||||
},
|
||||
boxShow: false,
|
||||
})
|
||||
})
|
|
@ -1,24 +0,0 @@
|
|||
import { defineStore } from 'pinia'
|
||||
|
||||
|
||||
export const LandMarkWindowStore = defineStore({
|
||||
id: 'LandMarkWindow',
|
||||
state: () => ({
|
||||
information: {
|
||||
landTitle: NaN,
|
||||
landDescribes: NaN,
|
||||
landBriefly: NaN,
|
||||
landImgUrl: NaN,
|
||||
landPosition: NaN,
|
||||
landImgCount: NaN
|
||||
},
|
||||
windowPosition: {
|
||||
bottom: NaN,
|
||||
left: NaN
|
||||
},
|
||||
buttonText: false,
|
||||
windowShow: false,
|
||||
hiddenWindow: false,
|
||||
flyToLand: false,
|
||||
})
|
||||
})
|
|
@ -1,28 +0,0 @@
|
|||
import { defineStore } from 'pinia'
|
||||
|
||||
|
||||
export const usePointStore = defineStore({
|
||||
id: 'point',
|
||||
state: () => ({
|
||||
index: 0,
|
||||
length: 10,
|
||||
rawItems: [],
|
||||
}),
|
||||
getters: {
|
||||
items: (state) => {
|
||||
const items = state.rawItems
|
||||
items.length = state.length
|
||||
|
||||
return items
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
addItem(item) {
|
||||
if (this.index >= this.length) {
|
||||
return
|
||||
}
|
||||
this.rawItems[this.index] = item
|
||||
this.index++
|
||||
},
|
||||
},
|
||||
})
|
|
@ -1,26 +0,0 @@
|
|||
import { defineStore } from 'pinia'
|
||||
import { isLnglat } from '/@/api/util'
|
||||
|
||||
|
||||
export const useFlytoStore = defineStore({
|
||||
id: 'flyto',
|
||||
state: () => ({
|
||||
lng: NaN,
|
||||
lat: NaN,
|
||||
change:true,
|
||||
}),
|
||||
getters: {
|
||||
value: (state) => { state.lng, state.lat }
|
||||
},
|
||||
actions: {
|
||||
set(flyto) {
|
||||
if ( !isLnglat(flyto) ) return false
|
||||
|
||||
this.lng = flyto.lng
|
||||
this.lat = flyto.lat
|
||||
this.change = !this.change
|
||||
|
||||
return true
|
||||
},
|
||||
},
|
||||
})
|
|
@ -0,0 +1,15 @@
|
|||
import { defineStore } from 'pinia'
|
||||
|
||||
export const usePositionArrStore = defineStore({
|
||||
id: 'positionArr',
|
||||
state: () => ({
|
||||
mode:'',
|
||||
positionArr:[]
|
||||
}),
|
||||
actions: {
|
||||
add(inputMode, inputArr) {
|
||||
this.mode = inputMode;
|
||||
this.positionArr = inputArr;
|
||||
}
|
||||
},
|
||||
})
|
|
@ -9,6 +9,7 @@ function pathResolve(dir) {
|
|||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
base: './',
|
||||
resolve: {
|
||||
alias: [
|
||||
// /@/xxxx => src/xxxx
|
||||
|
|
174
yarn.lock
|
@ -12,6 +12,50 @@
|
|||
resolved "https://registry.npmmirror.com/@babel/parser/-/parser-7.17.8.tgz#2817fb9d885dd8132ea0f8eb615a6388cca1c240"
|
||||
integrity sha512-BoHhDJrJXqcg+ZL16Xv39H9n+AqJ4pcDrQBGZN+wHxIysrLZ3/ECwCBUch/1zUNhnsXULcONU3Ei5Hmkfk6kiQ==
|
||||
|
||||
"@babel/runtime@^7.21.0":
|
||||
version "7.24.6"
|
||||
resolved "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.24.6.tgz#5b76eb89ad45e2e4a0a8db54c456251469a3358e"
|
||||
integrity sha512-Ja18XcETdEl5mzzACGd+DKgaGJzPTCow7EglgwTmHdwokzDFYh/MHua6lU6DV/hjF2IaOJ4oX2nqnjG7RElKOw==
|
||||
dependencies:
|
||||
regenerator-runtime "^0.14.0"
|
||||
|
||||
"@css-render/plugin-bem@^0.15.12":
|
||||
version "0.15.14"
|
||||
resolved "https://registry.npmmirror.com/@css-render/plugin-bem/-/plugin-bem-0.15.14.tgz#de13fc9f59299c2b646119851763dfa08929b3c1"
|
||||
integrity sha512-QK513CJ7yEQxm/P3EwsI+d+ha8kSOcjGvD6SevM41neEMxdULE+18iuQK6tEChAWMOQNQPLG/Rw3Khb69r5neg==
|
||||
|
||||
"@css-render/vue3-ssr@^0.15.10", "@css-render/vue3-ssr@^0.15.12":
|
||||
version "0.15.14"
|
||||
resolved "https://registry.npmmirror.com/@css-render/vue3-ssr/-/vue3-ssr-0.15.14.tgz#a2f4dedc3e86211a3ce1445555265095b7736491"
|
||||
integrity sha512-//8027GSbxE9n3QlD73xFY6z4ZbHbvrOVB7AO6hsmrEzGbg+h2A09HboUyDgu+xsmj7JnvJD39Irt+2D0+iV8g==
|
||||
|
||||
"@emotion/hash@~0.8.0":
|
||||
version "0.8.0"
|
||||
resolved "https://registry.npmmirror.com/@emotion/hash/-/hash-0.8.0.tgz#bbbff68978fefdbe68ccb533bc8cbe1d1afb5413"
|
||||
integrity sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==
|
||||
|
||||
"@juggle/resize-observer@^3.3.1":
|
||||
version "3.4.0"
|
||||
resolved "https://registry.npmmirror.com/@juggle/resize-observer/-/resize-observer-3.4.0.tgz#08d6c5e20cf7e4cc02fd181c4b0c225cd31dbb60"
|
||||
integrity sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA==
|
||||
|
||||
"@types/katex@^0.16.2":
|
||||
version "0.16.7"
|
||||
resolved "https://registry.npmmirror.com/@types/katex/-/katex-0.16.7.tgz#03ab680ab4fa4fbc6cb46ecf987ecad5d8019868"
|
||||
integrity sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ==
|
||||
|
||||
"@types/lodash-es@^4.17.9":
|
||||
version "4.17.12"
|
||||
resolved "https://registry.npmmirror.com/@types/lodash-es/-/lodash-es-4.17.12.tgz#65f6d1e5f80539aa7cfbfc962de5def0cf4f341b"
|
||||
integrity sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==
|
||||
dependencies:
|
||||
"@types/lodash" "*"
|
||||
|
||||
"@types/lodash@*", "@types/lodash@^4.14.198":
|
||||
version "4.17.4"
|
||||
resolved "https://registry.npmmirror.com/@types/lodash/-/lodash-4.17.4.tgz#0303b64958ee070059e3a7184048a55159fe20b7"
|
||||
integrity sha512-wYCP26ZLxaT3R39kiN2+HcJ4kTd3U1waI/cY7ivWYqFP6pW3ZNpvi6Wd6PHZx7T/t8z0vlkXMg3QYLa7DZ/IJQ==
|
||||
|
||||
"@vitejs/plugin-vue@^2.3.0":
|
||||
version "2.3.1"
|
||||
resolved "https://registry.npmmirror.com/@vitejs/plugin-vue/-/plugin-vue-2.3.1.tgz#5f286b8d3515381c6d5c8fa8eee5e6335f727e14"
|
||||
|
@ -117,16 +161,51 @@
|
|||
resolved "https://registry.npmmirror.com/@zouyaoji/heatmap.js/-/heatmap.js-2.0.8.tgz#5f6b285e7635ca07f2ecdb3d83a9dc1d240433d7"
|
||||
integrity sha512-kBQny/zOUFH2OFoVyu6IdGJEcQMENIAASUsaZhk+OuJ9WexsYf6EU2lCyGURcsFly1kTMZKODlV7nBTCgfvJqg==
|
||||
|
||||
async-validator@^4.2.5:
|
||||
version "4.2.5"
|
||||
resolved "https://registry.npmmirror.com/async-validator/-/async-validator-4.2.5.tgz#c96ea3332a521699d0afaaceed510a54656c6339"
|
||||
integrity sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==
|
||||
|
||||
cesium@^1.92.0:
|
||||
version "1.92.0"
|
||||
resolved "https://registry.npmmirror.com/cesium/-/cesium-1.92.0.tgz#d4a736be7f3516830a814c4c99780a385c12a258"
|
||||
integrity sha512-qU2EIV3M+ru6uF5UQUjUWXeq9UVieMBeq+Q8fzzNbFgeSbLrvnJ7jSJq0vvgaVDPe0PnmN72FZKMDiJdTFpMnQ==
|
||||
|
||||
css-render@^0.15.10, css-render@^0.15.12:
|
||||
version "0.15.14"
|
||||
resolved "https://registry.npmmirror.com/css-render/-/css-render-0.15.14.tgz#c23d8c8b9c0b44cd20b426f5e9de7ef7bade69b8"
|
||||
integrity sha512-9nF4PdUle+5ta4W5SyZdLCCmFd37uVimSjg1evcTqKJCyvCEEj12WKzOSBNak6r4im4J4iYXKH1OWpUV5LBYFg==
|
||||
dependencies:
|
||||
"@emotion/hash" "~0.8.0"
|
||||
csstype "~3.0.5"
|
||||
|
||||
csstype@^2.6.8:
|
||||
version "2.6.20"
|
||||
resolved "https://registry.npmmirror.com/csstype/-/csstype-2.6.20.tgz#9229c65ea0b260cf4d3d997cb06288e36a8d6dda"
|
||||
integrity sha512-/WwNkdXfckNgw6S5R125rrW8ez139lBHWouiBvX8dfMFtcn6V81REDqnH7+CRpRipfYlyU1CmOnOxrmGcFOjeA==
|
||||
|
||||
csstype@^3.1.3:
|
||||
version "3.1.3"
|
||||
resolved "https://registry.npmmirror.com/csstype/-/csstype-3.1.3.tgz#d80ff294d114fb0e6ac500fbf85b60137d7eff81"
|
||||
integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==
|
||||
|
||||
csstype@~3.0.5:
|
||||
version "3.0.11"
|
||||
resolved "https://registry.npmmirror.com/csstype/-/csstype-3.0.11.tgz#d66700c5eacfac1940deb4e3ee5642792d85cd33"
|
||||
integrity sha512-sa6P2wJ+CAbgyy4KFssIb/JNMLxFvKF1pCYCSXS8ZMuqZnMsrxqI2E5sPyoTpxoPU/gVZMzr2zjOfg8GIZOMsw==
|
||||
|
||||
date-fns-tz@^2.0.0:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.npmmirror.com/date-fns-tz/-/date-fns-tz-2.0.1.tgz#0a9b2099031c0d74120b45de9fd23192e48ea495"
|
||||
integrity sha512-fJCG3Pwx8HUoLhkepdsP7Z5RsucUi+ZBOxyM5d0ZZ6c4SdYustq0VMmOu6Wf7bli+yS/Jwp91TOCqn9jMcVrUA==
|
||||
|
||||
date-fns@^2.30.0:
|
||||
version "2.30.0"
|
||||
resolved "https://registry.npmmirror.com/date-fns/-/date-fns-2.30.0.tgz#f367e644839ff57894ec6ac480de40cae4b0f4d0"
|
||||
integrity sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.21.0"
|
||||
|
||||
echarts@^5.2.1:
|
||||
version "5.3.2"
|
||||
resolved "https://registry.npmmirror.com/echarts/-/echarts-5.3.2.tgz#0a7b3be8c48a48b2e7cb1b82121df0c208d42d2c"
|
||||
|
@ -266,6 +345,11 @@ estree-walker@^2.0.2:
|
|||
resolved "https://registry.npmmirror.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac"
|
||||
integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==
|
||||
|
||||
evtd@^0.2.2, evtd@^0.2.4:
|
||||
version "0.2.4"
|
||||
resolved "https://registry.npmmirror.com/evtd/-/evtd-0.2.4.tgz#0aac39ba44d6926e6668948ac27618e0795b9d07"
|
||||
integrity sha512-qaeGN5bx63s/AXgQo8gj6fBkxge+OoLddLniox5qtLAEY5HSnuSlISXVPxnSae1dWblvTh4/HoMIB+mbMsvZzw==
|
||||
|
||||
fsevents@~2.3.2:
|
||||
version "2.3.2"
|
||||
resolved "https://registry.npmmirror.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a"
|
||||
|
@ -283,6 +367,11 @@ has@^1.0.3:
|
|||
dependencies:
|
||||
function-bind "^1.1.1"
|
||||
|
||||
highlight.js@^11.8.0:
|
||||
version "11.9.0"
|
||||
resolved "https://registry.npmmirror.com/highlight.js/-/highlight.js-11.9.0.tgz#04ab9ee43b52a41a047432c8103e2158a1b8b5b0"
|
||||
integrity sha512-fJ7cW7fQGCYAkgv4CPfwFHrfd/cLS4Hau96JuJ+ZTOWhjnhoeN1ub1tFmALm/+lW5z4WCAuAV9bm05AP0mS6Gw==
|
||||
|
||||
is-core-module@^2.8.1:
|
||||
version "2.8.1"
|
||||
resolved "https://registry.npmmirror.com/is-core-module/-/is-core-module-2.8.1.tgz#f59fdfca701d5879d0a6b100a40aa1560ce27211"
|
||||
|
@ -322,6 +411,31 @@ mitt@^3.0.0:
|
|||
resolved "https://registry.npmmirror.com/mitt/-/mitt-3.0.0.tgz#69ef9bd5c80ff6f57473e8d89326d01c414be0bd"
|
||||
integrity sha512-7dX2/10ITVyqh4aOSVI9gdape+t9l2/8QxHrFmUXu4EEUpdlxl6RudZUPZoc+zuY2hk1j7XxVroIVIan/pD/SQ==
|
||||
|
||||
naive-ui@^2.34.3:
|
||||
version "2.38.2"
|
||||
resolved "https://registry.npmmirror.com/naive-ui/-/naive-ui-2.38.2.tgz#d7c8bdbe9319ea3dd2c24c4f6741090650eae24a"
|
||||
integrity sha512-WhZ+6DW61aYSmFyfH7evcSGFmd2xR68Yq1mNRrVdJwBhZsnNdAUsMN9IeNCVEPMCND/jzYZghkStoNoR5Xa09g==
|
||||
dependencies:
|
||||
"@css-render/plugin-bem" "^0.15.12"
|
||||
"@css-render/vue3-ssr" "^0.15.12"
|
||||
"@types/katex" "^0.16.2"
|
||||
"@types/lodash" "^4.14.198"
|
||||
"@types/lodash-es" "^4.17.9"
|
||||
async-validator "^4.2.5"
|
||||
css-render "^0.15.12"
|
||||
csstype "^3.1.3"
|
||||
date-fns "^2.30.0"
|
||||
date-fns-tz "^2.0.0"
|
||||
evtd "^0.2.4"
|
||||
highlight.js "^11.8.0"
|
||||
lodash "^4.17.21"
|
||||
lodash-es "^4.17.21"
|
||||
seemly "^0.3.8"
|
||||
treemate "^0.3.11"
|
||||
vdirs "^0.1.8"
|
||||
vooks "^0.2.12"
|
||||
vueuc "^0.4.58"
|
||||
|
||||
nanoid@^3.3.1:
|
||||
version "3.3.2"
|
||||
resolved "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.2.tgz#c89622fafb4381cd221421c69ec58547a1eec557"
|
||||
|
@ -362,6 +476,16 @@ proj4@^2.7.5:
|
|||
mgrs "1.0.0"
|
||||
wkt-parser "^1.3.1"
|
||||
|
||||
regenerator-runtime@^0.14.0:
|
||||
version "0.14.1"
|
||||
resolved "https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f"
|
||||
integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==
|
||||
|
||||
resize-detector@^0.3.0:
|
||||
version "0.3.0"
|
||||
resolved "https://registry.npmmirror.com/resize-detector/-/resize-detector-0.3.0.tgz#fe495112e184695500a8f51e0389f15774cb1cfc"
|
||||
integrity sha512-R/tCuvuOHQ8o2boRP6vgx8hXCCy87H1eY9V5imBYeVNyNVpuL9ciReSccLj2gDcax9+2weXy3bc8Vv+NRXeEvQ==
|
||||
|
||||
resolve@^1.22.0:
|
||||
version "1.22.0"
|
||||
resolved "https://registry.npmmirror.com/resolve/-/resolve-1.22.0.tgz#5e0b8c67c15df57a89bdbabe603a002f21731198"
|
||||
|
@ -378,6 +502,11 @@ rollup@^2.59.0:
|
|||
optionalDependencies:
|
||||
fsevents "~2.3.2"
|
||||
|
||||
seemly@^0.3.6, seemly@^0.3.8:
|
||||
version "0.3.8"
|
||||
resolved "https://registry.npmmirror.com/seemly/-/seemly-0.3.8.tgz#42879d8375d73126a04dc16b1bf92a773d2e5974"
|
||||
integrity sha512-MW8Qs6vbzo0pHmDpFSYPna+lwpZ6Zk1ancbajw/7E8TKtHdV+1DfZZD+kKJEhG/cAoB/i+LiT+5msZOqj0DwRA==
|
||||
|
||||
source-map-js@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.npmmirror.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c"
|
||||
|
@ -398,11 +527,23 @@ supports-preserve-symlinks-flag@^1.0.0:
|
|||
resolved "https://registry.npmmirror.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09"
|
||||
integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
|
||||
|
||||
treemate@^0.3.11:
|
||||
version "0.3.11"
|
||||
resolved "https://registry.npmmirror.com/treemate/-/treemate-0.3.11.tgz#7d52f8f69ab9ce326f8d139e0a3d1ffb25e48222"
|
||||
integrity sha512-M8RGFoKtZ8dF+iwJfAJTOH/SM4KluKOKRJpjCMhI8bG3qB74zrFoArKZ62ll0Fr3mqkMJiQOmWYkdYgDeITYQg==
|
||||
|
||||
tslib@2.3.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.npmmirror.com/tslib/-/tslib-2.3.0.tgz#803b8cdab3e12ba581a4ca41c8839bbb0dacb09e"
|
||||
integrity sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==
|
||||
|
||||
vdirs@^0.1.4, vdirs@^0.1.8:
|
||||
version "0.1.8"
|
||||
resolved "https://registry.npmmirror.com/vdirs/-/vdirs-0.1.8.tgz#a103bc43baca738f8dea912a7e9737154a19dbc2"
|
||||
integrity sha512-H9V1zGRLQZg9b+GdMk8MXDN2Lva0zx72MPahDKc30v+DtwKjfyOSXWRIX4t2mhDubM1H09gPhWeth/BJWPHGUw==
|
||||
dependencies:
|
||||
evtd "^0.2.2"
|
||||
|
||||
vite@^2.9.0:
|
||||
version "2.9.1"
|
||||
resolved "https://registry.npmmirror.com/vite/-/vite-2.9.1.tgz#84bce95fae210a7beb566a0af06246748066b48f"
|
||||
|
@ -415,6 +556,13 @@ vite@^2.9.0:
|
|||
optionalDependencies:
|
||||
fsevents "~2.3.2"
|
||||
|
||||
vooks@^0.2.12, vooks@^0.2.4:
|
||||
version "0.2.12"
|
||||
resolved "https://registry.npmmirror.com/vooks/-/vooks-0.2.12.tgz#2b6e23330b77bac81c7f7a344c4ca3e9f4f6c373"
|
||||
integrity sha512-iox0I3RZzxtKlcgYaStQYKEzWWGAduMmq+jS7OrNdQo1FgGfPMubGL3uGHOU9n97NIvfFDBGnpSvkWyb/NSn/Q==
|
||||
dependencies:
|
||||
evtd "^0.2.2"
|
||||
|
||||
vue-cesium@^3.0.11:
|
||||
version "3.0.11"
|
||||
resolved "https://registry.npmmirror.com/vue-cesium/-/vue-cesium-3.0.11.tgz#442e45fd85c8bc7e1b095ae66fbeea8f9e141cca"
|
||||
|
@ -435,6 +583,19 @@ vue-demi@*:
|
|||
resolved "https://registry.npmmirror.com/vue-demi/-/vue-demi-0.12.5.tgz#8eeed566a7d86eb090209a11723f887d28aeb2d1"
|
||||
integrity sha512-BREuTgTYlUr0zw0EZn3hnhC3I6gPWv+Kwh4MCih6QcAeaTlaIX0DwOVN0wHej7hSvDPecz4jygy/idsgKfW58Q==
|
||||
|
||||
vue-demi@^0.13.11:
|
||||
version "0.13.11"
|
||||
resolved "https://registry.npmmirror.com/vue-demi/-/vue-demi-0.13.11.tgz#7d90369bdae8974d87b1973564ad390182410d99"
|
||||
integrity sha512-IR8HoEEGM65YY3ZJYAjMlKygDQn25D5ajNFNoKh9RSDMQtlzCxtfQjdQgv9jjK+m3377SsJXY8ysq8kLCZL25A==
|
||||
|
||||
vue-echarts@^6.2.3:
|
||||
version "6.7.2"
|
||||
resolved "https://registry.npmmirror.com/vue-echarts/-/vue-echarts-6.7.2.tgz#66f3d9dcd9535f1d39a20f890b870a3e5c6598a8"
|
||||
integrity sha512-SG8Vmszhx24KjtySsk361DogZLRkPCyLhgoyh7iN1eH3WGJ0kyl3k0g4QiSJqK0+F1Ej0HDopq4A5OGcBlAwzw==
|
||||
dependencies:
|
||||
resize-detector "^0.3.0"
|
||||
vue-demi "^0.13.11"
|
||||
|
||||
vue@^3.2.25:
|
||||
version "3.2.31"
|
||||
resolved "https://registry.npmmirror.com/vue/-/vue-3.2.31.tgz#e0c49924335e9f188352816788a4cca10f817ce6"
|
||||
|
@ -446,6 +607,19 @@ vue@^3.2.25:
|
|||
"@vue/server-renderer" "3.2.31"
|
||||
"@vue/shared" "3.2.31"
|
||||
|
||||
vueuc@^0.4.58:
|
||||
version "0.4.58"
|
||||
resolved "https://registry.npmmirror.com/vueuc/-/vueuc-0.4.58.tgz#03ee2ea6febf360ca9cbe490841fce91742eea12"
|
||||
integrity sha512-Wnj/N8WbPRSxSt+9ji1jtDHPzda5h2OH/0sFBhvdxDRuyCZbjGg3/cKMaKqEoe+dErTexG2R+i6Q8S/Toq1MYg==
|
||||
dependencies:
|
||||
"@css-render/vue3-ssr" "^0.15.10"
|
||||
"@juggle/resize-observer" "^3.3.1"
|
||||
css-render "^0.15.10"
|
||||
evtd "^0.2.4"
|
||||
seemly "^0.3.6"
|
||||
vdirs "^0.1.4"
|
||||
vooks "^0.2.4"
|
||||
|
||||
wkt-parser@^1.3.1:
|
||||
version "1.3.2"
|
||||
resolved "https://registry.npmmirror.com/wkt-parser/-/wkt-parser-1.3.2.tgz#deeff04a21edc5b170a60da418e9ed1d1ab0e219"
|
||||
|
|