diff --git a/.vscode/settings.json b/.vscode/settings.json
index 33c89a8..58b2816 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -20,6 +20,5 @@
"typescript.tsdk": "node_modules/typescript/lib",
"typescript.preferences.autoImportFileExcludePatterns": ["vue-router/auto$"],
"i18n-ally.localesPaths": ["src/locales"],
- "i18n-ally.keystyle": "nested",
- "oxc.enable": true
+ "i18n-ally.keystyle": "nested"
}
diff --git a/eslint.config.ts b/eslint.config.ts
index fb99d32..2496aca 100644
--- a/eslint.config.ts
+++ b/eslint.config.ts
@@ -4,6 +4,7 @@ import { defineConfigWithVueTs, vueTsConfigs } from '@vue/eslint-config-typescri
import pluginImport from 'eslint-plugin-import-x';
import oxlint from 'eslint-plugin-oxlint';
import perfectionist from 'eslint-plugin-perfectionist';
+import perfectionistPlugin from 'eslint-plugin-perfectionist';
import pluginVue from 'eslint-plugin-vue';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
@@ -68,6 +69,7 @@ export default defineConfigWithVueTs(
},
// https://perfectionist.dev/guide/getting-started
+ perfectionistPlugin.configs['recommended-natural'],
{
plugins: {
perfectionist,
diff --git a/package.json b/package.json
index 02e215a..1be1384 100644
--- a/package.json
+++ b/package.json
@@ -49,6 +49,7 @@
"alova": "^3.2.8",
"ant-design-vue": "~4.2.6",
"axios": "^1.7.9",
+ "cesium": "^1.127.0",
"consola": "^3.4.0",
"dayjs": "^1.11.13",
"deep-freeze-es6": "^4.0.0",
@@ -63,6 +64,7 @@
"primelocale": "^2.0.0",
"primevue": "^4.3.1",
"radash": "^12.1.0",
+ "satellite.js": "^5.0.0",
"tdesign-icons-vue-next": "^0.3.4",
"ts-enum-util": "^4.1.0",
"utils4u": "^4.0.0",
@@ -124,6 +126,7 @@
"vite": "^6.1.0",
"vite-plugin-cdn-import": "^1.0.1",
"vite-plugin-fake-server": "^2.2.0",
+ "vite-plugin-static-copy": "^2.3.0",
"vite-plugin-vue-devtools": "^7.7.1",
"vite-plugin-vue-layouts": "^0.11.0",
"vite-plugin-vue-meta-layouts": "^0.5.1",
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index ac7fc20..93c911c 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -46,6 +46,9 @@ importers:
axios:
specifier: ^1.7.9
version: 1.7.9
+ cesium:
+ specifier: ^1.127.0
+ version: 1.127.0
consola:
specifier: ^3.4.0
version: 3.4.0
@@ -88,6 +91,9 @@ importers:
radash:
specifier: ^12.1.0
version: 12.1.0
+ satellite.js:
+ specifier: ^5.0.0
+ version: 5.0.0
tdesign-icons-vue-next:
specifier: ^0.3.4
version: 0.3.4(vue@3.5.13(typescript@5.7.3))
@@ -266,6 +272,9 @@ importers:
vite-plugin-fake-server:
specifier: ^2.2.0
version: 2.2.0
+ vite-plugin-static-copy:
+ specifier: ^2.3.0
+ version: 2.3.0(vite@6.1.0(@types/node@22.13.1)(jiti@2.4.2)(less@4.2.2)(sass-embedded@1.83.4)(terser@5.38.2)(tsx@4.19.2)(yaml@2.7.0))
vite-plugin-vue-devtools:
specifier: ^7.7.1
version: 7.7.1(@nuxt/kit@3.15.1(rollup@4.30.1))(rollup@4.30.1)(vite@6.1.0(@types/node@22.13.1)(jiti@2.4.2)(less@4.2.2)(sass-embedded@1.83.4)(terser@5.38.2)(tsx@4.19.2)(yaml@2.7.0))(vue@3.5.13(typescript@5.7.3))
@@ -480,6 +489,14 @@ packages:
'@bufbuild/protobuf@2.2.3':
resolution: {integrity: sha512-tFQoXHJdkEOSwj5tRIZSPNUuXK3RaR7T1nUrPgbYX1pUbvqqaaZAsfo+NXBPsz5rZMSKVFrgK1WL8Q/MSLvprg==}
+ '@cesium/engine@15.0.0':
+ resolution: {integrity: sha512-jimj7khIf/mBkejsMZ+n6Y9PPvXh4QmWKkz2ekFz59icDCeGj8ZJrzl5p0caqiK/372mnHOwmYFWYEwThEw2ew==}
+ engines: {node: '>=14.0.0'}
+
+ '@cesium/widgets@11.0.0':
+ resolution: {integrity: sha512-4ELgFuU2uwkvD6NI9MHIWNFKjmyI9wlDzZ9NuoPFSnUhf9XfVBI8sJekGx5dijxjK2S3aCuxB3dtUkdDZEsQmA==}
+ engines: {node: '>=14.0.0'}
+
'@commitlint/config-validator@19.5.0':
resolution: {integrity: sha512-CHtj92H5rdhKt17RmgALhfQt95VayrUo2tSqY9g2w+laAXyk7K/Ef6uPm9tn5qSIwSmrLjKaXK9eiNuxmQrDBw==}
engines: {node: '>=v18'}
@@ -1210,6 +1227,36 @@ packages:
resolution: {integrity: sha512-AOnbzzYr0Y7w7M1jTypNQQyDtEbrzjCmjnFf8tQ72fAHpTU2+W7O7aw0oO17VCh5TLyZkCftwWG9N6SfCv3o+Q==}
engines: {node: '>=12.11.0'}
+ '@protobufjs/aspromise@1.1.2':
+ resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==}
+
+ '@protobufjs/base64@1.1.2':
+ resolution: {integrity: sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==}
+
+ '@protobufjs/codegen@2.0.4':
+ resolution: {integrity: sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==}
+
+ '@protobufjs/eventemitter@1.1.0':
+ resolution: {integrity: sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==}
+
+ '@protobufjs/fetch@1.1.0':
+ resolution: {integrity: sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==}
+
+ '@protobufjs/float@1.0.2':
+ resolution: {integrity: sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==}
+
+ '@protobufjs/inquire@1.1.0':
+ resolution: {integrity: sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==}
+
+ '@protobufjs/path@1.1.2':
+ resolution: {integrity: sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==}
+
+ '@protobufjs/pool@1.1.0':
+ resolution: {integrity: sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==}
+
+ '@protobufjs/utf8@1.1.0':
+ resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==}
+
'@rollup/pluginutils@5.1.4':
resolution: {integrity: sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==}
engines: {node: '>=14.0.0'}
@@ -1353,6 +1400,9 @@ packages:
'@tsconfig/node22@22.0.0':
resolution: {integrity: sha512-twLQ77zevtxobBOD4ToAtVmuYrpeYUh3qh+TEp+08IWhpsrIflVHqQ1F1CiPxQGL7doCdBIOOCF+1Tm833faNg==}
+ '@tweenjs/tween.js@25.0.0':
+ resolution: {integrity: sha512-XKLA6syeBUaPzx4j3qwMqzzq+V4uo72BnlbOjmuljLrRqdsd3qnzvZZoxvMHZ23ndsRS4aufU6JOZYpCbU6T1A==}
+
'@tybys/wasm-util@0.9.0':
resolution: {integrity: sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==}
@@ -1395,6 +1445,9 @@ packages:
'@types/parse-json@4.0.2':
resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==}
+ '@types/trusted-types@2.0.7':
+ resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==}
+
'@types/web-bluetooth@0.0.20':
resolution: {integrity: sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==}
@@ -1979,6 +2032,10 @@ packages:
'@vueuse/shared@12.5.0':
resolution: {integrity: sha512-vMpcL1lStUU6O+kdj6YdHDixh0odjPAUM15uJ9f7MY781jcYkIwFA4iv2EfoIPO6vBmvutI1HxxAwmf0cx5ISQ==}
+ '@zip.js/zip.js@2.7.57':
+ resolution: {integrity: sha512-BtonQ1/jDnGiMed6OkV6rZYW78gLmLswkHOzyMrMb+CAR7CZO8phOHO6c2qw6qb1g1betN7kwEHhhZk30dv+NA==}
+ engines: {bun: '>=0.7.0', deno: '>=1.0.0', node: '>=16.5.0'}
+
abbrev@2.0.0:
resolution: {integrity: sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==}
engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
@@ -2132,6 +2189,9 @@ packages:
resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==}
engines: {node: '>= 4.0.0'}
+ autolinker@4.1.0:
+ resolution: {integrity: sha512-mYzdZMei1zIXcHVS/LjnuCJG+C/hNi8O+5m0R8YWtrIBWGrjL8CVzEZXxOfH0l1kioEXHNpUJRkgZdyL4GgIHQ==}
+
aws-sign2@0.7.0:
resolution: {integrity: sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==}
@@ -2166,6 +2226,9 @@ packages:
birpc@0.2.19:
resolution: {integrity: sha512-5WeXXAvTmitV1RqJFppT5QtUiz2p1mRSYU000Jkft5ZUCLJIk4uQriYNO50HknxKwM6jd8utNc66K1qGIwwWBQ==}
+ bitmap-sdf@1.0.4:
+ resolution: {integrity: sha512-1G3U4n5JE6RAiALMxu0p1XmeZkTeCwGKykzsLTCqVzfSDaN6S7fKnkIkfejogz+iwqBWc0UYAIKnKHNN7pSfDg==}
+
bl@4.1.0:
resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==}
@@ -2259,6 +2322,10 @@ packages:
caseless@0.12.0:
resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==}
+ cesium@1.127.0:
+ resolution: {integrity: sha512-MRGkPb3ClEkAI9viZxxdD3LCu7ydOzOKdJ6/iPtBx1GUsPCZNbgB0IH7wmhwgbxA5sjv4/a90+mvR9CoLP1PWQ==}
+ engines: {node: '>=18.18.0'}
+
chalk@2.4.2:
resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==}
engines: {node: '>=4'}
@@ -2597,13 +2664,22 @@ packages:
dom-scroll-into-view@2.0.1:
resolution: {integrity: sha512-bvVTQe1lfaUr1oFzZX80ce9KLDlZ3iU+XGNE/bz9HnGdklTieqsbmsLHe+rT2XWqopvL0PckkYqN7ksmm5pe3w==}
+ dompurify@3.2.4:
+ resolution: {integrity: sha512-ysFSFEDVduQpyhzAob/kkuJjf5zWkZD8/A9ywSp1byueyuCfHamrCBa14/Oc2iiB0e51B+NpxSl5gmzn+Ms/mg==}
+
dotenv@16.4.7:
resolution: {integrity: sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==}
engines: {node: '>=12'}
+ draco3d@1.5.7:
+ resolution: {integrity: sha512-m6WCKt/erDXcw+70IJXnG7M3awwQPAsZvJGX5zY7beBqpELw6RDGkYVU0W43AFxye4pDZ5i2Lbyc/NNGqwjUVQ==}
+
duplexer@0.1.2:
resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==}
+ earcut@3.0.1:
+ resolution: {integrity: sha512-0l1/0gOjESMeQyYaK5IDiPNvFeu93Z/cO0TjZh9eZ1vyCtZnA7KMZ8rQggpsJHIbGSdrqYq9OhuveadOVHCshw==}
+
eastasianwidth@0.2.0:
resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
@@ -3201,6 +3277,9 @@ packages:
graceful-fs@4.2.11:
resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
+ grapheme-splitter@1.0.4:
+ resolution: {integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==}
+
graphemer@1.4.0:
resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==}
@@ -3501,6 +3580,10 @@ packages:
jsencrypt@3.3.2:
resolution: {integrity: sha512-arQR1R1ESGdAxY7ZheWr12wCaF2yF47v5qpB76TtV64H1pyGudk9Hvw8Y9tb/FiTIaaTRUyaSnm5T/Y53Ghm/A==}
+ jsep@1.4.0:
+ resolution: {integrity: sha512-B7qPcEVE3NVkmSJbaYxvv4cHkVW7DQsZz13pUMrfS8z8Q/BuShN+gcTXrUlPiGqM2/t/EEaI030bpxMqY8gMlw==}
+ engines: {node: '>= 10.16.0'}
+
jsesc@3.1.0:
resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==}
engines: {node: '>=6'}
@@ -3553,6 +3636,9 @@ packages:
resolution: {integrity: sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==}
engines: {node: '>=0.6.0'}
+ kdbush@4.0.2:
+ resolution: {integrity: sha512-WbCVYJ27Sz8zi9Q7Q0xHC+05iwkm3Znipc2XTlrnJbsHMYktW4hPhXUE8Ys1engBrvffoSCqbil1JQAa7clRpA==}
+
keyv@4.5.4:
resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==}
@@ -3577,6 +3663,12 @@ packages:
kolorist@1.8.0:
resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==}
+ ktx-parse@1.0.0:
+ resolution: {integrity: sha512-Z31kVizz4DF/6vo9YiSYVBhuXAfyQy9bGxlW3+mB5OELoZjfXVZQpRoctsx8IEDKxBd6SagXKo7qRvu38i8Jfg==}
+
+ lerc@2.0.0:
+ resolution: {integrity: sha512-7qo1Mq8ZNmaR4USHHm615nEW2lPeeWJ3bTyoqFbd35DLx0LUH7C6ptt5FDCTAlbIzs3+WKrk5SkJvw8AFDE2hg==}
+
less@4.2.2:
resolution: {integrity: sha512-tkuLHQlvWUTeQ3doAqnHbNn8T6WX1KA8yvbKG9x4VtKtIjHsVKQZCH11zRgAfbDAXC2UNIg/K9BYAAcEzUIrNg==}
engines: {node: '>=6'}
@@ -3650,6 +3742,9 @@ packages:
resolution: {integrity: sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==}
engines: {node: '>=18'}
+ long@5.3.1:
+ resolution: {integrity: sha512-ka87Jz3gcx/I7Hal94xaN2tZEOPoUOEVftkQqZx2EeQRN7LGdfLlI3FvZ+7WDplm+vK2Urx9ULrvSowtdCieng==}
+
longest@2.0.1:
resolution: {integrity: sha512-Ajzxb8CM6WAnFjgiloPsI3bF+WCxcvhdIG3KNA2KN962+tdBsHcuQ4k4qX/EcS/2CRkcc0iAkR956Nib6aXU/Q==}
engines: {node: '>=0.10.0'}
@@ -3715,6 +3810,12 @@ packages:
merge@2.1.1:
resolution: {integrity: sha512-jz+Cfrg9GWOZbQAnDQ4hlVnQky+341Yk5ru8bZSe6sIDTCIg8n9i/u7hSQGSVOF3C7lH6mGtqjkiT9G4wFLL0w==}
+ mersenne-twister@1.1.0:
+ resolution: {integrity: sha512-mUYWsMKNrm4lfygPkL3OfGzOPTR2DBlTkBNHM//F6hGp8cLThY897crAlk3/Jo17LEOOjQUrNAx6DvgO77QJkA==}
+
+ meshoptimizer@0.22.0:
+ resolution: {integrity: sha512-IebiK79sqIy+E4EgOr+CAw+Ke8hAspXKzBd0JdgEmPHiAwmvEj2S4h1rfvo+o/BnfEYd/jAOg5IeeIjzlzSnDg==}
+
micro@9.3.5-canary.3:
resolution: {integrity: sha512-viYIo9PefV+w9dvoIBh1gI44Mvx1BOk67B4BpC2QK77qdY0xZF0Q+vWLt/BII6cLkIc8rLmSIcJaB/OrXXKe1g==}
engines: {node: '>= 8.0.0'}
@@ -3935,6 +4036,9 @@ packages:
resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
engines: {node: '>=0.10.0'}
+ nosleep.js@0.12.0:
+ resolution: {integrity: sha512-9d1HbpKLh3sdWlhXMhU6MMH+wQzKkrgfRkYV0EBdvt99YJfj0ilCJrWRDYG2130Tm4GXbEoTCx5b34JSaP+HhA==}
+
npm-normalize-package-bin@4.0.0:
resolution: {integrity: sha512-TZKxPvItzai9kN9H/TkmCtx/ZN/hvr3vUycjlfmH0ootY9yFBzNOpiXAdIn1Iteqsvk4lQn6B5PTrt+n6h8k/w==}
engines: {node: ^18.17.0 || >=20.5.0}
@@ -4030,6 +4134,10 @@ packages:
resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==}
engines: {node: '>=10'}
+ p-map@7.0.3:
+ resolution: {integrity: sha512-VkndIv2fIB99swvQoA65bm+fsmt6UNdGeIB0oxBs+WhAhdh08QA04JXpI7rbB9r08/nkbysKoya9rtDERYOYMA==}
+ engines: {node: '>=18'}
+
package-json-from-dist@1.0.1:
resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==}
@@ -4048,6 +4156,9 @@ packages:
vue: ^3.0.0
vue-router: ^4.0.0
+ pako@2.1.0:
+ resolution: {integrity: sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==}
+
parent-module@1.0.1:
resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
engines: {node: '>=6'}
@@ -4260,6 +4371,10 @@ packages:
proto-list@1.2.4:
resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==}
+ protobufjs@7.4.0:
+ resolution: {integrity: sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw==}
+ engines: {node: '>=12.0.0'}
+
proxy-from-env@1.1.0:
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
@@ -4284,6 +4399,9 @@ packages:
queue-microtask@1.2.3:
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
+ quickselect@2.0.0:
+ resolution: {integrity: sha512-RKJ22hX8mHe3Y6wH/N3wCM6BWtjaxIyyUIkpHOvfFnxdI4yD4tBXEBKSbriGujF6jnSVkJrffuo6vxACiSSxIw==}
+
radash@12.1.0:
resolution: {integrity: sha512-b0Zcf09AhqKS83btmUeYBS8tFK7XL2e3RvLmZcm0sTdF1/UUlHSsjXdCcWNxe7yfmAlPve5ym0DmKGtTzP6kVQ==}
engines: {node: '>=14.18.0'}
@@ -4295,6 +4413,9 @@ packages:
resolution: {integrity: sha512-9WmIKF6mkvA0SLmA2Knm9+qj89e+j1zqgyn8aXGd7+nAduPoqgI9lO57SAZNn/Byzo5P7JhXTyg9PzaJbH73bA==}
engines: {node: '>= 0.8'}
+ rbush@3.0.1:
+ resolution: {integrity: sha512-XRaVO0YecOpEuIvbhbpTrZgoiI6xBlz6hnlr6EHhd+0x9ase6EmeN+hdwwUaJvLcsFFQ8iWVF1GAK1yB0BWi0w==}
+
rc9@2.1.2:
resolution: {integrity: sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg==}
@@ -4539,6 +4660,9 @@ packages:
engines: {node: '>=16.0.0'}
hasBin: true
+ satellite.js@5.0.0:
+ resolution: {integrity: sha512-ie3yiJ2LJAJIhVUKdYhgp7V0btXKAMImDjRnuaNfJGl8rjwP2HwVIh4HLFcpiXYEiYwXc5fqh5+yZqCe6KIwWw==}
+
sax@1.4.1:
resolution: {integrity: sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==}
@@ -4840,6 +4964,10 @@ packages:
resolution: {integrity: sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==}
engines: {node: '>=0.6'}
+ topojson-client@3.1.0:
+ resolution: {integrity: sha512-605uxS6bcYxGXw9qi62XyrV6Q3xwbndjachmNxu8HWTtVPxZfEJN9fd/SZS1Q54Sn2y0TMyMxFj/cJINqGHrKw==}
+ hasBin: true
+
totalist@3.0.1:
resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==}
engines: {node: '>=6'}
@@ -5133,6 +5261,9 @@ packages:
uri-js@4.4.1:
resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
+ urijs@1.19.11:
+ resolution: {integrity: sha512-HXgFDgDommxn5/bIv0cnQZsPhHDA90NPHD6+c/v21U5+Sx5hoP8+dP9IZXBU1gIfvdRfhG8cel9QNPeionfcCQ==}
+
url-parse-as-address@1.0.0:
resolution: {integrity: sha512-1WJ8YX1Kcec9wgxy8d/ATzGP1ayO6BRnd3iB6NlM+7cOnn6U8p5PKppRTCPLobh3CSdJ4d0TdPjopzyU2KcVFw==}
@@ -5225,6 +5356,12 @@ packages:
'@nuxt/kit':
optional: true
+ vite-plugin-static-copy@2.3.0:
+ resolution: {integrity: sha512-LLKwhhHetGaCnWz4mas4qqjjguDka6/6b4+SeIohRroj8aCE7QTfiZECfPecslFQkWZ3HdQuq5kOPmWZjNYlKA==}
+ engines: {node: ^18.0.0 || >=20.0.0}
+ peerDependencies:
+ vite: ^6.1.0
+
vite-plugin-vue-devtools@7.7.1:
resolution: {integrity: sha512-f1Fnda4CJYH7t7K1WaTEjFTLdF4oUkmlZTVwBGG5UhJ+Oa5KPX0Ue32c+YWRMOpCtFbCDl1iXGgQVzg8Ew5JnQ==}
engines: {node: '>=v14.21.3'}
@@ -5733,6 +5870,33 @@ snapshots:
'@bufbuild/protobuf@2.2.3': {}
+ '@cesium/engine@15.0.0':
+ dependencies:
+ '@tweenjs/tween.js': 25.0.0
+ '@zip.js/zip.js': 2.7.57
+ autolinker: 4.1.0
+ bitmap-sdf: 1.0.4
+ dompurify: 3.2.4
+ draco3d: 1.5.7
+ earcut: 3.0.1
+ grapheme-splitter: 1.0.4
+ jsep: 1.4.0
+ kdbush: 4.0.2
+ ktx-parse: 1.0.0
+ lerc: 2.0.0
+ mersenne-twister: 1.1.0
+ meshoptimizer: 0.22.0
+ pako: 2.1.0
+ protobufjs: 7.4.0
+ rbush: 3.0.1
+ topojson-client: 3.1.0
+ urijs: 1.19.11
+
+ '@cesium/widgets@11.0.0':
+ dependencies:
+ '@cesium/engine': 15.0.0
+ nosleep.js: 0.12.0
+
'@commitlint/config-validator@19.5.0':
dependencies:
'@commitlint/types': 19.5.0
@@ -6350,6 +6514,29 @@ snapshots:
'@primevue/metadata@4.3.1': {}
+ '@protobufjs/aspromise@1.1.2': {}
+
+ '@protobufjs/base64@1.1.2': {}
+
+ '@protobufjs/codegen@2.0.4': {}
+
+ '@protobufjs/eventemitter@1.1.0': {}
+
+ '@protobufjs/fetch@1.1.0':
+ dependencies:
+ '@protobufjs/aspromise': 1.1.2
+ '@protobufjs/inquire': 1.1.0
+
+ '@protobufjs/float@1.0.2': {}
+
+ '@protobufjs/inquire@1.1.0': {}
+
+ '@protobufjs/path@1.1.2': {}
+
+ '@protobufjs/pool@1.1.0': {}
+
+ '@protobufjs/utf8@1.1.0': {}
+
'@rollup/pluginutils@5.1.4(rollup@4.30.1)':
dependencies:
'@types/estree': 1.0.6
@@ -6447,6 +6634,8 @@ snapshots:
'@tsconfig/node22@22.0.0': {}
+ '@tweenjs/tween.js@25.0.0': {}
+
'@tybys/wasm-util@0.9.0':
dependencies:
tslib: 2.8.1
@@ -6486,6 +6675,9 @@ snapshots:
'@types/parse-json@4.0.2': {}
+ '@types/trusted-types@2.0.7':
+ optional: true
+
'@types/web-bluetooth@0.0.20': {}
'@typescript-eslint/eslint-plugin@8.20.0(@typescript-eslint/parser@8.20.0(eslint@9.20.1(jiti@2.4.2))(typescript@5.7.3))(eslint@9.20.1(jiti@2.4.2))(typescript@5.7.3)':
@@ -7446,6 +7638,8 @@ snapshots:
transitivePeerDependencies:
- typescript
+ '@zip.js/zip.js@2.7.57': {}
+
abbrev@2.0.0: {}
acorn-import-attributes@1.9.5(acorn@8.14.0):
@@ -7598,6 +7792,10 @@ snapshots:
at-least-node@1.0.0: {}
+ autolinker@4.1.0:
+ dependencies:
+ tslib: 2.8.1
+
aws-sign2@0.7.0: {}
aws4@1.13.2: {}
@@ -7638,6 +7836,8 @@ snapshots:
birpc@0.2.19: {}
+ bitmap-sdf@1.0.4: {}
+
bl@4.1.0:
dependencies:
buffer: 5.7.1
@@ -7736,6 +7936,11 @@ snapshots:
caseless@0.12.0: {}
+ cesium@1.127.0:
+ dependencies:
+ '@cesium/engine': 15.0.0
+ '@cesium/widgets': 11.0.0
+
chalk@2.4.2:
dependencies:
ansi-styles: 3.2.1
@@ -8066,10 +8271,18 @@ snapshots:
dom-scroll-into-view@2.0.1: {}
+ dompurify@3.2.4:
+ optionalDependencies:
+ '@types/trusted-types': 2.0.7
+
dotenv@16.4.7: {}
+ draco3d@1.5.7: {}
+
duplexer@0.1.2: {}
+ earcut@3.0.1: {}
+
eastasianwidth@0.2.0: {}
ecc-jsbn@0.1.2:
@@ -8757,6 +8970,8 @@ snapshots:
graceful-fs@4.2.11: {}
+ grapheme-splitter@1.0.4: {}
+
graphemer@1.4.0: {}
gray-matter@4.0.3:
@@ -9019,6 +9234,8 @@ snapshots:
jsencrypt@3.3.2: {}
+ jsep@1.4.0: {}
+
jsesc@3.1.0: {}
json-buffer@3.0.1: {}
@@ -9066,6 +9283,8 @@ snapshots:
json-schema: 0.4.0
verror: 1.10.0
+ kdbush@4.0.2: {}
+
keyv@4.5.4:
dependencies:
json-buffer: 3.0.1
@@ -9084,6 +9303,10 @@ snapshots:
kolorist@1.8.0: {}
+ ktx-parse@1.0.0: {}
+
+ lerc@2.0.0: {}
+
less@4.2.2:
dependencies:
copy-anything: 2.0.6
@@ -9181,6 +9404,8 @@ snapshots:
strip-ansi: 7.1.0
wrap-ansi: 9.0.0
+ long@5.3.1: {}
+
longest@2.0.1: {}
loose-envify@1.4.0:
@@ -9245,6 +9470,10 @@ snapshots:
merge@2.1.1: {}
+ mersenne-twister@1.1.0: {}
+
+ meshoptimizer@0.22.0: {}
+
micro@9.3.5-canary.3:
dependencies:
arg: 4.1.0
@@ -9418,6 +9647,8 @@ snapshots:
normalize-path@3.0.0: {}
+ nosleep.js@0.12.0: {}
+
npm-normalize-package-bin@4.0.0: {}
npm-run-all2@7.0.2:
@@ -9552,6 +9783,8 @@ snapshots:
dependencies:
p-limit: 3.1.0
+ p-map@7.0.3: {}
+
package-json-from-dist@1.0.1: {}
package-manager-detector@0.2.8: {}
@@ -9565,6 +9798,8 @@ snapshots:
vue: 3.5.13(typescript@5.7.3)
vue-router: 4.5.0(vue@3.5.13(typescript@5.7.3))
+ pako@2.1.0: {}
+
parent-module@1.0.1:
dependencies:
callsites: 3.1.0
@@ -9743,6 +9978,21 @@ snapshots:
proto-list@1.2.4: {}
+ protobufjs@7.4.0:
+ dependencies:
+ '@protobufjs/aspromise': 1.1.2
+ '@protobufjs/base64': 1.1.2
+ '@protobufjs/codegen': 2.0.4
+ '@protobufjs/eventemitter': 1.1.0
+ '@protobufjs/fetch': 1.1.0
+ '@protobufjs/float': 1.0.2
+ '@protobufjs/inquire': 1.1.0
+ '@protobufjs/path': 1.1.2
+ '@protobufjs/pool': 1.1.0
+ '@protobufjs/utf8': 1.1.0
+ '@types/node': 22.13.1
+ long: 5.3.1
+
proxy-from-env@1.1.0: {}
prr@1.0.1:
@@ -9760,6 +10010,8 @@ snapshots:
queue-microtask@1.2.3: {}
+ quickselect@2.0.0: {}
+
radash@12.1.0: {}
rate-limiter-flexible@5.0.4: {}
@@ -9771,6 +10023,10 @@ snapshots:
iconv-lite: 0.4.24
unpipe: 1.0.0
+ rbush@3.0.1:
+ dependencies:
+ quickselect: 2.0.0
+
rc9@2.1.2:
dependencies:
defu: 6.1.4
@@ -10010,6 +10266,8 @@ snapshots:
sass-embedded-win32-ia32: 1.83.4
sass-embedded-win32-x64: 1.83.4
+ satellite.js@5.0.0: {}
+
sax@1.4.1:
optional: true
@@ -10337,6 +10595,10 @@ snapshots:
toidentifier@1.0.0: {}
+ topojson-client@3.1.0:
+ dependencies:
+ commander: 2.20.3
+
totalist@3.0.1: {}
tough-cookie@2.5.0:
@@ -10721,6 +10983,8 @@ snapshots:
dependencies:
punycode: 2.3.1
+ urijs@1.19.11: {}
+
url-parse-as-address@1.0.0: {}
util-deprecate@1.0.2: {}
@@ -10823,6 +11087,15 @@ snapshots:
- rollup
- supports-color
+ vite-plugin-static-copy@2.3.0(vite@6.1.0(@types/node@22.13.1)(jiti@2.4.2)(less@4.2.2)(sass-embedded@1.83.4)(terser@5.38.2)(tsx@4.19.2)(yaml@2.7.0)):
+ dependencies:
+ chokidar: 3.6.0
+ fast-glob: 3.3.3
+ fs-extra: 11.2.0
+ p-map: 7.0.3
+ picocolors: 1.1.1
+ vite: 6.1.0(@types/node@22.13.1)(jiti@2.4.2)(less@4.2.2)(sass-embedded@1.83.4)(terser@5.38.2)(tsx@4.19.2)(yaml@2.7.0)
+
vite-plugin-vue-devtools@7.7.1(@nuxt/kit@3.15.1(rollup@4.30.1))(rollup@4.30.1)(vite@6.1.0(@types/node@22.13.1)(jiti@2.4.2)(less@4.2.2)(sass-embedded@1.83.4)(terser@5.38.2)(tsx@4.19.2)(yaml@2.7.0))(vue@3.5.13(typescript@5.7.3)):
dependencies:
'@vue/devtools-core': 7.7.1(vite@6.1.0(@types/node@22.13.1)(jiti@2.4.2)(less@4.2.2)(sass-embedded@1.83.4)(terser@5.38.2)(tsx@4.19.2)(yaml@2.7.0))(vue@3.5.13(typescript@5.7.3))
diff --git a/src/layouts/sakai-vue/styles/_main.scss b/src/layouts/sakai-vue/styles/_main.scss
index e85dcb2..2fdbe06 100644
--- a/src/layouts/sakai-vue/styles/_main.scss
+++ b/src/layouts/sakai-vue/styles/_main.scss
@@ -13,4 +13,5 @@
.layout-main {
flex: 1 1 auto;
padding-bottom: 2rem;
+ position: relative;
}
diff --git a/src/pages/cesium/README.md b/src/pages/cesium/README.md
new file mode 100644
index 0000000..aa2ffa9
--- /dev/null
+++ b/src/pages/cesium/README.md
@@ -0,0 +1,10 @@
+## 配置项目
+- https://github.dev/CesiumGS/cesium-vite-example
+- https://cesium.com/blog/2024/02/13/configuring-vite-or-webpack-for-cesiumjs/
+- https://cesium.com/learn/cesiumjs-learn/cesiumjs-quickstart/
+- vite-plugin-cesium
+
+## 参考
+- https://www.npmjs.com/package/vue-cesium
+- https://zouyaoji.top/vue-cesium/#/zh-CN/component/controls/vc-navigation
+- https://cesium.pages.dev/
diff --git a/src/pages/cesium/cesium-helper/00.cesium-init.ts b/src/pages/cesium/cesium-helper/00.cesium-init.ts
new file mode 100644
index 0000000..0eb2885
--- /dev/null
+++ b/src/pages/cesium/cesium-helper/00.cesium-init.ts
@@ -0,0 +1,83 @@
+import * as Cesium from 'cesium';
+import 'cesium/Build/Cesium/Widgets/widgets.css';
+
+// Cesium.Ion.defaultAccessToken =
+// 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJiYjZmMWM4Ny01YzQ4LTQ3MzUtYTI5Mi1hNTgyNjdhMmFiMmMiLCJpZCI6NjIwMjgsImlhdCI6MTYyNjY3MTMxNX0.5SelYUyzXWRoMyjjFvmFIAoPtWlJPQMjsVl2e_jQe-c';
+
+export function cesium_init() {
+ // 复写原型方法 用于timeline组件日期格式化;
+ // @ts-expect-error node_modules/@cesium/widgets/Source/Timeline/Timeline.js
+ Cesium.Timeline.prototype.makeLabel = function (time) {
+ let minutes = 0 - new Date().getTimezoneOffset();
+ let dataZone8 = Cesium.JulianDate.addMinutes(time, minutes, new Cesium.JulianDate());
+ return Cesium.JulianDate.toIso8601(dataZone8).slice(0, 19);
+ };
+
+ // cesium-viewer-bottom
+
+ const viewer = new Cesium.Viewer('cesiumContainer', {
+ /* animationContainer: !true, */
+ /* timelineContainer: true, */
+ /* bottomContainer: document.createElement('p'), // The DOM element or ID that will contain the bottomContainer. If not specified, the bottomContainer is added to the widget itself. */
+ shouldAnimate: true,
+ // globe: false, // 地球
+ baseLayerPicker: true,
+ homeButton: true, // Home按钮
+ fullscreenButton: !true, // 全屏按钮
+ geocoder: true, // = IonGeocodeProviderType.DEFAULT] - 在使用Geocoder小部件进行搜索时使用的地理编码服务或服务。如果设置为false,则不会创建Geocoder小部件。
+ infoBox: true, // InfoBox小部件。
+ navigationHelpButton: !true, // 是否显示导航帮助按钮
+ projectionPicker: !true, // 投影选择器
+ sceneModePicker: true, // 是否显示场景模式选择器(2D/3D切换)
+ animation: true, // 是否创建动画小部件
+ timeline: true, // If set to false, the Timeline widget will not be created.
+ selectionIndicator: true,
+ requestRenderMode: !true, // 如果为真,渲染帧将仅在场景内部发生变化时需要时发生。启用此功能可以减少应用程序的CPU/GPU使用率,并在移动设备上节省更多电量,但在此模式下需要使用{@link Scene#requestRender}显式渲染新帧。在API的其他部分对场景进行更改后,在许多情况下都需要这样做。请参阅{@link https://cesium.com/blog/2018/01/24/cesium-scene-rendering-performance/|使用显式渲染提高性能}。
+ showRenderLoopErrors: true, // 如果为真,当发生渲染循环错误时,此小部件将自动向用户显示包含错误的HTML面板。
+ orderIndependentTranslucency: false, // 顺序无关透明度
+ shadows: true, // Determines if shadows are cast by light sources.
+ });
+ /* if ($__DEV__) */ viewer.scene.debugShowFramesPerSecond = true;
+
+ // 时间格式化
+ let minutes = 0 - new Date().getTimezoneOffset(); // 0 - (-480);
+ viewer.animation.viewModel.timeFormatter = function (date, _viewModel) {
+ let dataZone8 = Cesium.JulianDate.addMinutes(date, minutes, new Cesium.JulianDate());
+ return Cesium.JulianDate.toIso8601(dataZone8).slice(11, 19);
+ };
+ viewer.animation.viewModel.dateFormatter = function (date, _viewModel) {
+ let dataZone8 = Cesium.JulianDate.addMinutes(date, minutes, new Cesium.JulianDate());
+ return Cesium.JulianDate.toIso8601(dataZone8).slice(0, 10);
+ };
+
+ //高德卫星地图
+ let gaoDeSatelliteImgLayer = new Cesium.UrlTemplateImageryProvider({
+ url: 'https://webst02.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}',
+ minimumLevel: 3,
+ maximumLevel: 18,
+ tilingScheme: new Cesium.WebMercatorTilingScheme(),
+ });
+
+ const customLayerViewModel = new Cesium.ProviderViewModel({
+ name: '高德地图',
+ iconUrl: 'gaodeImage.png',
+ tooltip: '高德地图',
+ category: 'Cesium ion', // 或 'Other 、Cesium ion'、'Bing Maps' 等
+ creationFunction: function () {
+ return gaoDeSatelliteImgLayer;
+ },
+ });
+ // 设置高德地图为默认图层
+ viewer.baseLayerPicker.viewModel.imageryProviderViewModels.unshift(customLayerViewModel);
+ const selectedViewModel = viewer.baseLayerPicker.viewModel.imageryProviderViewModels[0];
+ viewer.baseLayerPicker.viewModel.selectedImagery = selectedViewModel;
+
+ Cesium.Camera.DEFAULT_VIEW_RECTANGLE = Cesium.Rectangle.fromDegrees(
+ 75.0, // 西经
+ 10.0, // 南纬
+ 140.0, // 东经
+ 60.0, // 北纬
+ );
+
+ return viewer;
+}
diff --git a/src/pages/cesium/cesium-helper/01.x.ts b/src/pages/cesium/cesium-helper/01.x.ts
new file mode 100644
index 0000000..5f0a1ae
--- /dev/null
+++ b/src/pages/cesium/cesium-helper/01.x.ts
@@ -0,0 +1,118 @@
+import type { Viewer } from 'cesium';
+import * as Cesium from 'cesium';
+import { twoline2satrec, propagate, gstime, eciToEcf } from 'satellite.js';
+
+export async function demoOrbitGeneration(viewer: Viewer) {
+ const tle = `STARLINK-11371 [DTC]
+1 62879U 25024A 25062.93300820 .00003305 00000+0 21841-4 0 9995
+2 62879 42.9977 257.3937 0001725 269.2925 90.7748 15.77864921 5143`;
+
+ // 解析TLE数据
+ const lines = tle.split('\n');
+ const satelliteName = lines[0].trim();
+ const tleLine1 = lines[1];
+ const tleLine2 = lines[2];
+
+ // 创建卫星记录
+ const satrec = twoline2satrec(tleLine1, tleLine2);
+
+ // 创建轨道点
+ const pointsArray = [];
+ const totalMinutes = 1440; // 一天的分钟数
+ const timeStepInMinutes = 10;
+
+ // 当前时间
+ const now = new Date();
+
+ // 计算一条完整的轨道
+ for (let i = 0; i < totalMinutes; i += timeStepInMinutes) {
+ // 创建时间点
+ const time = new Date(now.getTime() + i * 60000);
+
+ // 获取卫星位置
+ const positionAndVelocity = propagate(satrec, time);
+
+ // 有时可能返回false
+ const position = positionAndVelocity.position;
+ if (typeof position === 'boolean') {
+ console.error('Error calculating satellite position');
+ return;
+ }
+ // 转换为千米
+ const gmst = gstime(time);
+ const p = eciToEcf(position, gmst);
+
+ // 添加到点数组
+ pointsArray.push(
+ Cesium.Cartesian3.fromDegrees(
+ Cesium.Math.toDegrees(Math.atan2(p.y, p.x)),
+ Cesium.Math.toDegrees(Math.atan2(p.z, Math.sqrt(p.x * p.x + p.y * p.y))),
+ Math.sqrt(p.x * p.x + p.y * p.y + p.z * p.z) * 1000, // 转换为米
+ ),
+ );
+ }
+
+ // 获取当前位置用于放置卫星模型
+ const time = new Date();
+ const positionAndVelocity = propagate(satrec, time);
+ const position = positionAndVelocity.position;
+ const gmst = gstime(time);
+ if (typeof position === 'boolean') {
+ console.error('Error calculating satellite position');
+ return;
+ }
+ const p = eciToEcf(position, gmst);
+
+ const currentPosition = Cesium.Cartesian3.fromDegrees(
+ Cesium.Math.toDegrees(Math.atan2(p.y, p.x)),
+ Cesium.Math.toDegrees(Math.atan2(p.z, Math.sqrt(p.x * p.x + p.y * p.y))),
+ Math.sqrt(p.x * p.x + p.y * p.y + p.z * p.z) * 1000, // 转换为米
+ );
+
+ // 创建轨道线
+ const orbitPath = viewer.entities.add({
+ name: `${satelliteName} Orbit`,
+ polyline: {
+ positions: pointsArray,
+ width: 2,
+ material: new Cesium.PolylineGlowMaterialProperty({
+ glowPower: 0.2,
+ color: Cesium.Color.BLUE,
+ }),
+ },
+ });
+
+ // 添加卫星实体
+ const satellite = viewer.entities.add({
+ name: satelliteName,
+ position: currentPosition,
+ point: {
+ pixelSize: 10,
+ color: Cesium.Color.YELLOW,
+ outlineColor: Cesium.Color.WHITE,
+ outlineWidth: 2,
+ },
+ label: {
+ text: satelliteName,
+ font: '14pt sans-serif',
+ style: Cesium.LabelStyle.FILL_AND_OUTLINE,
+ fillColor: Cesium.Color.WHITE,
+ outlineColor: Cesium.Color.BLACK,
+ outlineWidth: 2,
+ verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
+ pixelOffset: new Cesium.Cartesian2(0, -10),
+ },
+ // billboard: {
+ // image: '/assets/satellite.png', // 您需要添加一个卫星图标
+ // scale: 0.5,
+ // },
+ });
+
+ // 将相机定位到卫星
+ viewer.flyTo(satellite, { duration: 3 });
+
+ return {
+ orbitPath,
+ satellite,
+ };
+}
diff --git a/src/pages/cesium/index.page.vue b/src/pages/cesium/index.page.vue
new file mode 100644
index 0000000..4300628
--- /dev/null
+++ b/src/pages/cesium/index.page.vue
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
diff --git a/typed-router.d.ts b/typed-router.d.ts
index 7d0bfa9..830cded 100644
--- a/typed-router.d.ts
+++ b/typed-router.d.ts
@@ -22,6 +22,7 @@ declare module 'vue-router/auto-routes' {
'$Path': RouteRecordInfo<'$Path', '/:path(.*)', { path: ParamValue }, { path: ParamValue }>,
'AntdV': RouteRecordInfo<'AntdV', '/AntdV', Record, Record>,
'API': RouteRecordInfo<'API', '/API', Record, Record>,
+ 'Cesium': RouteRecordInfo<'Cesium', '/cesium', Record, Record>,
'DataLoadersId': RouteRecordInfo<'DataLoadersId', '/data-loaders/:id', { id: ParamValue }, { id: ParamValue }>,
'DataLoadersIdSub1UserId': RouteRecordInfo<'DataLoadersIdSub1UserId', '/data-loaders/:id/sub-1/:userId', { id: ParamValue, userId: ParamValue }, { id: ParamValue, userId: ParamValue }>,
'Fonts': RouteRecordInfo<'Fonts', '/fonts', Record, Record>,
diff --git a/vite.config.plugins.ts b/vite.config.plugins.ts
index 0388cbd..07f3eea 100644
--- a/vite.config.plugins.ts
+++ b/vite.config.plugins.ts
@@ -2,6 +2,8 @@
* https://github.com/antfu-collective/vitesse/blob/47618e72dfba76c77b9b85b94784d739e35c492b/vite.config.ts
* https://github.com/vue-macros/vue-macros/blob/main/playground/vue3/vite.config.ts
*/
+
+import { viteStaticCopy } from 'vite-plugin-static-copy';
import VueI18n from '@intlify/unplugin-vue-i18n/vite';
import { PrimeVueResolver } from '@primevue/auto-import-resolver';
import { unheadVueComposablesImports } from '@unhead/vue';
@@ -29,6 +31,11 @@ import Layouts from 'vite-plugin-vue-layouts';
import MetaLayouts from 'vite-plugin-vue-meta-layouts';
import { ViteWebfontDownload as WebfontDownload } from 'vite-plugin-webfont-dl';
+const cesiumSource = 'node_modules/cesium/Build/Cesium';
+// This is the base url for static files that CesiumJS needs to load.
+// Set to an empty string to place the files at the site's root path
+export const cesiumBaseUrl = 'cesiumStatic';
+
export function Plugins() {
const plugins: PluginOption[] = [];
@@ -163,6 +170,15 @@ export function Plugins() {
basename: 'fake-api',
enableProd: true,
}),
+
+ viteStaticCopy({
+ targets: [
+ { dest: cesiumBaseUrl, src: `${cesiumSource}/ThirdParty` },
+ { dest: cesiumBaseUrl, src: `${cesiumSource}/Workers` },
+ { dest: cesiumBaseUrl, src: `${cesiumSource}/Assets` },
+ { dest: cesiumBaseUrl, src: `${cesiumSource}/Widgets` },
+ ],
+ }),
);
const _unused = () => {
diff --git a/vite.config.ts b/vite.config.ts
index 6d3dfd8..0c27c46 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -4,7 +4,7 @@ import { fileURLToPath, URL } from 'node:url';
import { createViteProxy } from 'utils4u/vite';
import { defineConfig, loadEnv } from 'vite';
-import { Plugins } from './vite.config.plugins';
+import { cesiumBaseUrl, Plugins } from './vite.config.plugins';
// https://vitejs.dev/config/
export default defineConfig(({ mode, command }) => {
@@ -16,6 +16,7 @@ export default defineConfig(({ mode, command }) => {
plugins: Plugins(),
define: {
$__DEV__: JSON.stringify(!isBuild),
+ CESIUM_BASE_URL: JSON.stringify(`/${cesiumBaseUrl}`),
},
resolve: {
alias: {