diff --git a/.pnp.cjs b/.pnp.cjs
index 78faf36..41feff0 100755
--- a/.pnp.cjs
+++ b/.pnp.cjs
@@ -30,6 +30,10 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
"packageDependencies": [\
["@ant-design/colors", "npm:7.0.0"],\
["@craco/craco", "virtual:76695216f943c60b10b879e1e542c9b6e80910f801a5dd27c12e0d8f35738fd0876c5aa2a358adcda9729f45063a41698f56ff18e205779bc9465c19ea5a0d5c#npm:7.1.0"],\
+ ["@rematch/core", "virtual:76695216f943c60b10b879e1e542c9b6e80910f801a5dd27c12e0d8f35738fd0876c5aa2a358adcda9729f45063a41698f56ff18e205779bc9465c19ea5a0d5c#npm:2.2.0"],\
+ ["@rematch/loading", "virtual:76695216f943c60b10b879e1e542c9b6e80910f801a5dd27c12e0d8f35738fd0876c5aa2a358adcda9729f45063a41698f56ff18e205779bc9465c19ea5a0d5c#npm:2.1.2"],\
+ ["@rematch/persist", "virtual:76695216f943c60b10b879e1e542c9b6e80910f801a5dd27c12e0d8f35738fd0876c5aa2a358adcda9729f45063a41698f56ff18e205779bc9465c19ea5a0d5c#npm:2.1.2"],\
+ ["@rematch/select", "virtual:76695216f943c60b10b879e1e542c9b6e80910f801a5dd27c12e0d8f35738fd0876c5aa2a358adcda9729f45063a41698f56ff18e205779bc9465c19ea5a0d5c#npm:3.1.2"],\
["@testing-library/jest-dom", "npm:5.17.0"],\
["@testing-library/react", "virtual:76695216f943c60b10b879e1e542c9b6e80910f801a5dd27c12e0d8f35738fd0876c5aa2a358adcda9729f45063a41698f56ff18e205779bc9465c19ea5a0d5c#npm:13.4.0"],\
["@testing-library/user-event", "virtual:76695216f943c60b10b879e1e542c9b6e80910f801a5dd27c12e0d8f35738fd0876c5aa2a358adcda9729f45063a41698f56ff18e205779bc9465c19ea5a0d5c#npm:13.5.0"],\
@@ -43,10 +47,13 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
["lodash-es", "npm:4.17.21"],\
["node-polyfill-webpack-plugin", "virtual:76695216f943c60b10b879e1e542c9b6e80910f801a5dd27c12e0d8f35738fd0876c5aa2a358adcda9729f45063a41698f56ff18e205779bc9465c19ea5a0d5c#npm:2.0.1"],\
["react", "npm:18.2.0"],\
+ ["react-custom-scrollbars-2", "virtual:76695216f943c60b10b879e1e542c9b6e80910f801a5dd27c12e0d8f35738fd0876c5aa2a358adcda9729f45063a41698f56ff18e205779bc9465c19ea5a0d5c#npm:4.5.0"],\
["react-dom", "virtual:76695216f943c60b10b879e1e542c9b6e80910f801a5dd27c12e0d8f35738fd0876c5aa2a358adcda9729f45063a41698f56ff18e205779bc9465c19ea5a0d5c#npm:18.2.0"],\
["react-redux", "virtual:76695216f943c60b10b879e1e542c9b6e80910f801a5dd27c12e0d8f35738fd0876c5aa2a358adcda9729f45063a41698f56ff18e205779bc9465c19ea5a0d5c#npm:8.1.2"],\
["react-router-dom", "virtual:76695216f943c60b10b879e1e542c9b6e80910f801a5dd27c12e0d8f35738fd0876c5aa2a358adcda9729f45063a41698f56ff18e205779bc9465c19ea5a0d5c#npm:6.15.0"],\
["react-scripts", "virtual:76695216f943c60b10b879e1e542c9b6e80910f801a5dd27c12e0d8f35738fd0876c5aa2a358adcda9729f45063a41698f56ff18e205779bc9465c19ea5a0d5c#npm:5.0.1"],\
+ ["redux", "npm:4.2.1"],\
+ ["redux-persist", "virtual:76695216f943c60b10b879e1e542c9b6e80910f801a5dd27c12e0d8f35738fd0876c5aa2a358adcda9729f45063a41698f56ff18e205779bc9465c19ea5a0d5c#npm:6.0.0"],\
["resium", "virtual:76695216f943c60b10b879e1e542c9b6e80910f801a5dd27c12e0d8f35738fd0876c5aa2a358adcda9729f45063a41698f56ff18e205779bc9465c19ea5a0d5c#npm:1.17.1"],\
["tslib", "npm:2.6.2"],\
["web-vitals", "npm:2.1.4"]\
@@ -4606,6 +4613,104 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
"linkType": "HARD"\
}]\
]],\
+ ["@rematch/core", [\
+ ["npm:2.2.0", {\
+ "packageLocation": "./.yarn/cache/@rematch-core-npm-2.2.0-20b02e4f63-c2ae22b9c6.zip/node_modules/@rematch/core/",\
+ "packageDependencies": [\
+ ["@rematch/core", "npm:2.2.0"]\
+ ],\
+ "linkType": "SOFT"\
+ }],\
+ ["virtual:76695216f943c60b10b879e1e542c9b6e80910f801a5dd27c12e0d8f35738fd0876c5aa2a358adcda9729f45063a41698f56ff18e205779bc9465c19ea5a0d5c#npm:2.2.0", {\
+ "packageLocation": "./.yarn/__virtual__/@rematch-core-virtual-a3f06b7f50/0/cache/@rematch-core-npm-2.2.0-20b02e4f63-c2ae22b9c6.zip/node_modules/@rematch/core/",\
+ "packageDependencies": [\
+ ["@rematch/core", "virtual:76695216f943c60b10b879e1e542c9b6e80910f801a5dd27c12e0d8f35738fd0876c5aa2a358adcda9729f45063a41698f56ff18e205779bc9465c19ea5a0d5c#npm:2.2.0"],\
+ ["@types/redux", null],\
+ ["redux", "npm:4.2.1"]\
+ ],\
+ "packagePeers": [\
+ "@types/redux",\
+ "redux"\
+ ],\
+ "linkType": "HARD"\
+ }]\
+ ]],\
+ ["@rematch/loading", [\
+ ["npm:2.1.2", {\
+ "packageLocation": "./.yarn/cache/@rematch-loading-npm-2.1.2-3029b5efe6-142fab3964.zip/node_modules/@rematch/loading/",\
+ "packageDependencies": [\
+ ["@rematch/loading", "npm:2.1.2"]\
+ ],\
+ "linkType": "SOFT"\
+ }],\
+ ["virtual:76695216f943c60b10b879e1e542c9b6e80910f801a5dd27c12e0d8f35738fd0876c5aa2a358adcda9729f45063a41698f56ff18e205779bc9465c19ea5a0d5c#npm:2.1.2", {\
+ "packageLocation": "./.yarn/__virtual__/@rematch-loading-virtual-8240f407e9/0/cache/@rematch-loading-npm-2.1.2-3029b5efe6-142fab3964.zip/node_modules/@rematch/loading/",\
+ "packageDependencies": [\
+ ["@rematch/loading", "virtual:76695216f943c60b10b879e1e542c9b6e80910f801a5dd27c12e0d8f35738fd0876c5aa2a358adcda9729f45063a41698f56ff18e205779bc9465c19ea5a0d5c#npm:2.1.2"],\
+ ["@rematch/core", "virtual:76695216f943c60b10b879e1e542c9b6e80910f801a5dd27c12e0d8f35738fd0876c5aa2a358adcda9729f45063a41698f56ff18e205779bc9465c19ea5a0d5c#npm:2.2.0"],\
+ ["@types/rematch__core", null]\
+ ],\
+ "packagePeers": [\
+ "@rematch/core",\
+ "@types/rematch__core"\
+ ],\
+ "linkType": "HARD"\
+ }]\
+ ]],\
+ ["@rematch/persist", [\
+ ["npm:2.1.2", {\
+ "packageLocation": "./.yarn/cache/@rematch-persist-npm-2.1.2-8250bcade1-341c2a83bf.zip/node_modules/@rematch/persist/",\
+ "packageDependencies": [\
+ ["@rematch/persist", "npm:2.1.2"]\
+ ],\
+ "linkType": "SOFT"\
+ }],\
+ ["virtual:76695216f943c60b10b879e1e542c9b6e80910f801a5dd27c12e0d8f35738fd0876c5aa2a358adcda9729f45063a41698f56ff18e205779bc9465c19ea5a0d5c#npm:2.1.2", {\
+ "packageLocation": "./.yarn/__virtual__/@rematch-persist-virtual-d7ad71acc2/0/cache/@rematch-persist-npm-2.1.2-8250bcade1-341c2a83bf.zip/node_modules/@rematch/persist/",\
+ "packageDependencies": [\
+ ["@rematch/persist", "virtual:76695216f943c60b10b879e1e542c9b6e80910f801a5dd27c12e0d8f35738fd0876c5aa2a358adcda9729f45063a41698f56ff18e205779bc9465c19ea5a0d5c#npm:2.1.2"],\
+ ["@rematch/core", "virtual:76695216f943c60b10b879e1e542c9b6e80910f801a5dd27c12e0d8f35738fd0876c5aa2a358adcda9729f45063a41698f56ff18e205779bc9465c19ea5a0d5c#npm:2.2.0"],\
+ ["@types/redux", null],\
+ ["@types/rematch__core", null],\
+ ["redux", "npm:4.2.1"],\
+ ["redux-persist", "virtual:d7ad71acc2933927428a71390420abc349e46e91b93ce2b96ef764b953c90097d5046872291b9b34e5d9032b48e2796ff5e1afa3c735123f0a0309b6548a4b04#npm:6.0.0"]\
+ ],\
+ "packagePeers": [\
+ "@rematch/core",\
+ "@types/redux",\
+ "@types/rematch__core",\
+ "redux"\
+ ],\
+ "linkType": "HARD"\
+ }]\
+ ]],\
+ ["@rematch/select", [\
+ ["npm:3.1.2", {\
+ "packageLocation": "./.yarn/cache/@rematch-select-npm-3.1.2-07fa98adba-f554e26551.zip/node_modules/@rematch/select/",\
+ "packageDependencies": [\
+ ["@rematch/select", "npm:3.1.2"]\
+ ],\
+ "linkType": "SOFT"\
+ }],\
+ ["virtual:76695216f943c60b10b879e1e542c9b6e80910f801a5dd27c12e0d8f35738fd0876c5aa2a358adcda9729f45063a41698f56ff18e205779bc9465c19ea5a0d5c#npm:3.1.2", {\
+ "packageLocation": "./.yarn/__virtual__/@rematch-select-virtual-ee631dc00e/0/cache/@rematch-select-npm-3.1.2-07fa98adba-f554e26551.zip/node_modules/@rematch/select/",\
+ "packageDependencies": [\
+ ["@rematch/select", "virtual:76695216f943c60b10b879e1e542c9b6e80910f801a5dd27c12e0d8f35738fd0876c5aa2a358adcda9729f45063a41698f56ff18e205779bc9465c19ea5a0d5c#npm:3.1.2"],\
+ ["@rematch/core", "virtual:76695216f943c60b10b879e1e542c9b6e80910f801a5dd27c12e0d8f35738fd0876c5aa2a358adcda9729f45063a41698f56ff18e205779bc9465c19ea5a0d5c#npm:2.2.0"],\
+ ["@types/redux", null],\
+ ["@types/rematch__core", null],\
+ ["redux", "npm:4.2.1"],\
+ ["reselect", "npm:4.1.8"]\
+ ],\
+ "packagePeers": [\
+ "@rematch/core",\
+ "@types/redux",\
+ "@types/rematch__core",\
+ "redux"\
+ ],\
+ "linkType": "HARD"\
+ }]\
+ ]],\
["@remix-run/router", [\
["npm:1.8.0", {\
"packageLocation": "./.yarn/cache/@remix-run-router-npm-1.8.0-a97098c5e8-f754f02d3b.zip/node_modules/@remix-run/router/",\
@@ -6338,6 +6443,15 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
"linkType": "HARD"\
}]\
]],\
+ ["add-px-to-style", [\
+ ["npm:1.0.0", {\
+ "packageLocation": "./.yarn/cache/add-px-to-style-npm-1.0.0-dcfd7231ac-673831d81d.zip/node_modules/add-px-to-style/",\
+ "packageDependencies": [\
+ ["add-px-to-style", "npm:1.0.0"]\
+ ],\
+ "linkType": "HARD"\
+ }]\
+ ]],\
["address", [\
["npm:1.2.2", {\
"packageLocation": "./.yarn/cache/address-npm-1.2.2-b88a43f43a-ace439960c.zip/node_modules/address/",\
@@ -8086,6 +8200,10 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
["cesium-arrow", "workspace:."],\
["@ant-design/colors", "npm:7.0.0"],\
["@craco/craco", "virtual:76695216f943c60b10b879e1e542c9b6e80910f801a5dd27c12e0d8f35738fd0876c5aa2a358adcda9729f45063a41698f56ff18e205779bc9465c19ea5a0d5c#npm:7.1.0"],\
+ ["@rematch/core", "virtual:76695216f943c60b10b879e1e542c9b6e80910f801a5dd27c12e0d8f35738fd0876c5aa2a358adcda9729f45063a41698f56ff18e205779bc9465c19ea5a0d5c#npm:2.2.0"],\
+ ["@rematch/loading", "virtual:76695216f943c60b10b879e1e542c9b6e80910f801a5dd27c12e0d8f35738fd0876c5aa2a358adcda9729f45063a41698f56ff18e205779bc9465c19ea5a0d5c#npm:2.1.2"],\
+ ["@rematch/persist", "virtual:76695216f943c60b10b879e1e542c9b6e80910f801a5dd27c12e0d8f35738fd0876c5aa2a358adcda9729f45063a41698f56ff18e205779bc9465c19ea5a0d5c#npm:2.1.2"],\
+ ["@rematch/select", "virtual:76695216f943c60b10b879e1e542c9b6e80910f801a5dd27c12e0d8f35738fd0876c5aa2a358adcda9729f45063a41698f56ff18e205779bc9465c19ea5a0d5c#npm:3.1.2"],\
["@testing-library/jest-dom", "npm:5.17.0"],\
["@testing-library/react", "virtual:76695216f943c60b10b879e1e542c9b6e80910f801a5dd27c12e0d8f35738fd0876c5aa2a358adcda9729f45063a41698f56ff18e205779bc9465c19ea5a0d5c#npm:13.4.0"],\
["@testing-library/user-event", "virtual:76695216f943c60b10b879e1e542c9b6e80910f801a5dd27c12e0d8f35738fd0876c5aa2a358adcda9729f45063a41698f56ff18e205779bc9465c19ea5a0d5c#npm:13.5.0"],\
@@ -8099,10 +8217,13 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
["lodash-es", "npm:4.17.21"],\
["node-polyfill-webpack-plugin", "virtual:76695216f943c60b10b879e1e542c9b6e80910f801a5dd27c12e0d8f35738fd0876c5aa2a358adcda9729f45063a41698f56ff18e205779bc9465c19ea5a0d5c#npm:2.0.1"],\
["react", "npm:18.2.0"],\
+ ["react-custom-scrollbars-2", "virtual:76695216f943c60b10b879e1e542c9b6e80910f801a5dd27c12e0d8f35738fd0876c5aa2a358adcda9729f45063a41698f56ff18e205779bc9465c19ea5a0d5c#npm:4.5.0"],\
["react-dom", "virtual:76695216f943c60b10b879e1e542c9b6e80910f801a5dd27c12e0d8f35738fd0876c5aa2a358adcda9729f45063a41698f56ff18e205779bc9465c19ea5a0d5c#npm:18.2.0"],\
["react-redux", "virtual:76695216f943c60b10b879e1e542c9b6e80910f801a5dd27c12e0d8f35738fd0876c5aa2a358adcda9729f45063a41698f56ff18e205779bc9465c19ea5a0d5c#npm:8.1.2"],\
["react-router-dom", "virtual:76695216f943c60b10b879e1e542c9b6e80910f801a5dd27c12e0d8f35738fd0876c5aa2a358adcda9729f45063a41698f56ff18e205779bc9465c19ea5a0d5c#npm:6.15.0"],\
["react-scripts", "virtual:76695216f943c60b10b879e1e542c9b6e80910f801a5dd27c12e0d8f35738fd0876c5aa2a358adcda9729f45063a41698f56ff18e205779bc9465c19ea5a0d5c#npm:5.0.1"],\
+ ["redux", "npm:4.2.1"],\
+ ["redux-persist", "virtual:76695216f943c60b10b879e1e542c9b6e80910f801a5dd27c12e0d8f35738fd0876c5aa2a358adcda9729f45063a41698f56ff18e205779bc9465c19ea5a0d5c#npm:6.0.0"],\
["resium", "virtual:76695216f943c60b10b879e1e542c9b6e80910f801a5dd27c12e0d8f35738fd0876c5aa2a358adcda9729f45063a41698f56ff18e205779bc9465c19ea5a0d5c#npm:1.17.1"],\
["tslib", "npm:2.6.2"],\
["web-vitals", "npm:2.1.4"]\
@@ -9827,6 +9948,18 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
"linkType": "HARD"\
}]\
]],\
+ ["dom-css", [\
+ ["npm:2.1.0", {\
+ "packageLocation": "./.yarn/cache/dom-css-npm-2.1.0-386a19033e-f61cc63e88.zip/node_modules/dom-css/",\
+ "packageDependencies": [\
+ ["dom-css", "npm:2.1.0"],\
+ ["add-px-to-style", "npm:1.0.0"],\
+ ["prefix-style", "npm:2.0.1"],\
+ ["to-camel-case", "npm:1.0.0"]\
+ ],\
+ "linkType": "HARD"\
+ }]\
+ ]],\
["dom-serializer", [\
["npm:0.2.2", {\
"packageLocation": "./.yarn/cache/dom-serializer-npm-0.2.2-2e24969c0e-376344893e.zip/node_modules/dom-serializer/",\
@@ -18011,6 +18144,15 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
"linkType": "HARD"\
}]\
]],\
+ ["prefix-style", [\
+ ["npm:2.0.1", {\
+ "packageLocation": "./.yarn/cache/prefix-style-npm-2.0.1-3d7f8fe8cc-79c3559b74.zip/node_modules/prefix-style/",\
+ "packageDependencies": [\
+ ["prefix-style", "npm:2.0.1"]\
+ ],\
+ "linkType": "HARD"\
+ }]\
+ ]],\
["prelude-ls", [\
["npm:1.2.1", {\
"packageLocation": "./.yarn/cache/prelude-ls-npm-1.2.1-3e4d272a55-cd192ec0d0.zip/node_modules/prelude-ls/",\
@@ -19518,6 +19660,35 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
"linkType": "HARD"\
}]\
]],\
+ ["react-custom-scrollbars-2", [\
+ ["npm:4.5.0", {\
+ "packageLocation": "./.yarn/cache/react-custom-scrollbars-2-npm-4.5.0-420f40d266-b264629c0b.zip/node_modules/react-custom-scrollbars-2/",\
+ "packageDependencies": [\
+ ["react-custom-scrollbars-2", "npm:4.5.0"]\
+ ],\
+ "linkType": "SOFT"\
+ }],\
+ ["virtual:76695216f943c60b10b879e1e542c9b6e80910f801a5dd27c12e0d8f35738fd0876c5aa2a358adcda9729f45063a41698f56ff18e205779bc9465c19ea5a0d5c#npm:4.5.0", {\
+ "packageLocation": "./.yarn/__virtual__/react-custom-scrollbars-2-virtual-b3257ba1a6/0/cache/react-custom-scrollbars-2-npm-4.5.0-420f40d266-b264629c0b.zip/node_modules/react-custom-scrollbars-2/",\
+ "packageDependencies": [\
+ ["react-custom-scrollbars-2", "virtual:76695216f943c60b10b879e1e542c9b6e80910f801a5dd27c12e0d8f35738fd0876c5aa2a358adcda9729f45063a41698f56ff18e205779bc9465c19ea5a0d5c#npm:4.5.0"],\
+ ["@types/react", null],\
+ ["@types/react-dom", null],\
+ ["dom-css", "npm:2.1.0"],\
+ ["prop-types", "npm:15.8.1"],\
+ ["raf", "npm:3.4.1"],\
+ ["react", "npm:18.2.0"],\
+ ["react-dom", "virtual:76695216f943c60b10b879e1e542c9b6e80910f801a5dd27c12e0d8f35738fd0876c5aa2a358adcda9729f45063a41698f56ff18e205779bc9465c19ea5a0d5c#npm:18.2.0"]\
+ ],\
+ "packagePeers": [\
+ "@types/react-dom",\
+ "@types/react",\
+ "react-dom",\
+ "react"\
+ ],\
+ "linkType": "HARD"\
+ }]\
+ ]],\
["react-dev-utils", [\
["npm:12.0.1", {\
"packageLocation": "./.yarn/cache/react-dev-utils-npm-12.0.1-83ba06e3ee-2c6917e47f.zip/node_modules/react-dev-utils/",\
@@ -19648,7 +19819,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
["react-dom", "virtual:76695216f943c60b10b879e1e542c9b6e80910f801a5dd27c12e0d8f35738fd0876c5aa2a358adcda9729f45063a41698f56ff18e205779bc9465c19ea5a0d5c#npm:18.2.0"],\
["react-is", "npm:18.2.0"],\
["react-native", null],\
- ["redux", null],\
+ ["redux", "npm:4.2.1"],\
["use-sync-external-store", "virtual:922d1a398d6767acb804cb9eeabcfd32d09be3bad2e7eff68896674bfe84f5d27cb01e73b439dd9c33aca697ae403ee2b7b2433cb6faa4f94719e1d5e62ec50c#npm:1.2.0"]\
],\
"packagePeers": [\
@@ -19889,6 +20060,59 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
"linkType": "HARD"\
}]\
]],\
+ ["redux", [\
+ ["npm:4.2.1", {\
+ "packageLocation": "./.yarn/cache/redux-npm-4.2.1-e7e2cf2e37-f63b9060c3.zip/node_modules/redux/",\
+ "packageDependencies": [\
+ ["redux", "npm:4.2.1"],\
+ ["@babel/runtime", "npm:7.22.11"]\
+ ],\
+ "linkType": "HARD"\
+ }]\
+ ]],\
+ ["redux-persist", [\
+ ["npm:6.0.0", {\
+ "packageLocation": "./.yarn/cache/redux-persist-npm-6.0.0-56dad69feb-edaf10dbf1.zip/node_modules/redux-persist/",\
+ "packageDependencies": [\
+ ["redux-persist", "npm:6.0.0"]\
+ ],\
+ "linkType": "SOFT"\
+ }],\
+ ["virtual:76695216f943c60b10b879e1e542c9b6e80910f801a5dd27c12e0d8f35738fd0876c5aa2a358adcda9729f45063a41698f56ff18e205779bc9465c19ea5a0d5c#npm:6.0.0", {\
+ "packageLocation": "./.yarn/__virtual__/redux-persist-virtual-f95ebe9633/0/cache/redux-persist-npm-6.0.0-56dad69feb-edaf10dbf1.zip/node_modules/redux-persist/",\
+ "packageDependencies": [\
+ ["redux-persist", "virtual:76695216f943c60b10b879e1e542c9b6e80910f801a5dd27c12e0d8f35738fd0876c5aa2a358adcda9729f45063a41698f56ff18e205779bc9465c19ea5a0d5c#npm:6.0.0"],\
+ ["@types/react", null],\
+ ["@types/redux", null],\
+ ["react", "npm:18.2.0"],\
+ ["redux", "npm:4.2.1"]\
+ ],\
+ "packagePeers": [\
+ "@types/react",\
+ "@types/redux",\
+ "react",\
+ "redux"\
+ ],\
+ "linkType": "HARD"\
+ }],\
+ ["virtual:d7ad71acc2933927428a71390420abc349e46e91b93ce2b96ef764b953c90097d5046872291b9b34e5d9032b48e2796ff5e1afa3c735123f0a0309b6548a4b04#npm:6.0.0", {\
+ "packageLocation": "./.yarn/__virtual__/redux-persist-virtual-44e49c1bcc/0/cache/redux-persist-npm-6.0.0-56dad69feb-edaf10dbf1.zip/node_modules/redux-persist/",\
+ "packageDependencies": [\
+ ["redux-persist", "virtual:d7ad71acc2933927428a71390420abc349e46e91b93ce2b96ef764b953c90097d5046872291b9b34e5d9032b48e2796ff5e1afa3c735123f0a0309b6548a4b04#npm:6.0.0"],\
+ ["@types/react", null],\
+ ["@types/redux", null],\
+ ["react", null],\
+ ["redux", "npm:4.2.1"]\
+ ],\
+ "packagePeers": [\
+ "@types/react",\
+ "@types/redux",\
+ "react",\
+ "redux"\
+ ],\
+ "linkType": "HARD"\
+ }]\
+ ]],\
["reflect.getprototypeof", [\
["npm:1.0.3", {\
"packageLocation": "./.yarn/cache/reflect.getprototypeof-npm-1.0.3-6e9c0e2b03-843e2506c0.zip/node_modules/reflect.getprototypeof/",\
@@ -20083,6 +20307,15 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
"linkType": "HARD"\
}]\
]],\
+ ["reselect", [\
+ ["npm:4.1.8", {\
+ "packageLocation": "./.yarn/cache/reselect-npm-4.1.8-cad5f0a3f3-a4ac87ceda.zip/node_modules/reselect/",\
+ "packageDependencies": [\
+ ["reselect", "npm:4.1.8"]\
+ ],\
+ "linkType": "HARD"\
+ }]\
+ ]],\
["resium", [\
["npm:1.17.1", {\
"packageLocation": "./.yarn/cache/resium-npm-1.17.1-7e06356997-07d19321b3.zip/node_modules/resium/",\
@@ -21919,6 +22152,16 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
"linkType": "HARD"\
}]\
]],\
+ ["to-camel-case", [\
+ ["npm:1.0.0", {\
+ "packageLocation": "./.yarn/cache/to-camel-case-npm-1.0.0-2e7e71c9af-2f74cfcffa.zip/node_modules/to-camel-case/",\
+ "packageDependencies": [\
+ ["to-camel-case", "npm:1.0.0"],\
+ ["to-space-case", "npm:1.0.0"]\
+ ],\
+ "linkType": "HARD"\
+ }]\
+ ]],\
["to-fast-properties", [\
["npm:2.0.0", {\
"packageLocation": "./.yarn/cache/to-fast-properties-npm-2.0.0-0dc60cc481-be2de62fe5.zip/node_modules/to-fast-properties/",\
@@ -21928,6 +22171,15 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
"linkType": "HARD"\
}]\
]],\
+ ["to-no-case", [\
+ ["npm:1.0.2", {\
+ "packageLocation": "./.yarn/cache/to-no-case-npm-1.0.2-2d005c2291-1d85326eeb.zip/node_modules/to-no-case/",\
+ "packageDependencies": [\
+ ["to-no-case", "npm:1.0.2"]\
+ ],\
+ "linkType": "HARD"\
+ }]\
+ ]],\
["to-object-path", [\
["npm:0.3.0", {\
"packageLocation": "./.yarn/cache/to-object-path-npm-0.3.0-241b5ffa9c-9425effee5.zip/node_modules/to-object-path/",\
@@ -21970,6 +22222,16 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
"linkType": "HARD"\
}]\
]],\
+ ["to-space-case", [\
+ ["npm:1.0.0", {\
+ "packageLocation": "./.yarn/cache/to-space-case-npm-1.0.0-6bc33e5f5c-157cebe3e9.zip/node_modules/to-space-case/",\
+ "packageDependencies": [\
+ ["to-space-case", "npm:1.0.0"],\
+ ["to-no-case", "npm:1.0.2"]\
+ ],\
+ "linkType": "HARD"\
+ }]\
+ ]],\
["toggle-selection", [\
["npm:1.0.6", {\
"packageLocation": "./.yarn/cache/toggle-selection-npm-1.0.6-c506b73005-a90dc80ed1.zip/node_modules/toggle-selection/",\
diff --git a/package.json b/package.json
index 2997f86..efbecc7 100644
--- a/package.json
+++ b/package.json
@@ -5,6 +5,10 @@
"dependencies": {
"@ant-design/colors": "^7.0.0",
"@craco/craco": "^7.1.0",
+ "@rematch/core": "^2.2.0",
+ "@rematch/loading": "^2.1.2",
+ "@rematch/persist": "^2.1.2",
+ "@rematch/select": "^3.1.2",
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
@@ -18,10 +22,13 @@
"lodash-es": "^4.17.21",
"node-polyfill-webpack-plugin": "^2.0.1",
"react": "^18.2.0",
+ "react-custom-scrollbars-2": "^4.5.0",
"react-dom": "^18.2.0",
"react-redux": "^8.1.2",
"react-router-dom": "^6.15.0",
"react-scripts": "5.0.1",
+ "redux": "^4.2.1",
+ "redux-persist": "^6.0.0",
"resium": "^1.17.1",
"tslib": "^2.6.2",
"web-vitals": "^2.1.4"
diff --git a/src/assets/arrow_round.glb b/src/assets/arrow_round.glb
new file mode 100644
index 0000000..cbf626c
Binary files /dev/null and b/src/assets/arrow_round.glb differ
diff --git a/src/components/HomeLayout/NavBar.jsx b/src/components/HomeLayout/NavBar.jsx
index cc69e71..52e70dc 100644
--- a/src/components/HomeLayout/NavBar.jsx
+++ b/src/components/HomeLayout/NavBar.jsx
@@ -5,17 +5,31 @@ import NavBarButton from "./NavBarButton";
function NavBar() {
const navigate = useNavigate();
- const navigateHandler = useCallback(() => {
- navigate("/polygon", { replace: true });
- }, [navigate]);
+ const navigateHandler = useCallback(
+ (e) => {
+ navigate("/polygon", { replace: true, state: { xx: 1 } });
+ },
+ [navigate]
+ );
return (
-
-
+
+
+
+
+
);
}
diff --git a/src/components/HomeLayout/index.module.less b/src/components/HomeLayout/index.module.less
index dfc73ca..50ea4b0 100644
--- a/src/components/HomeLayout/index.module.less
+++ b/src/components/HomeLayout/index.module.less
@@ -62,7 +62,7 @@
.nav-bar {
width: 100%;
max-width: 1200px;
- margin: 300px auto;
+ margin: 15% auto;
height: 72px;
padding: 0 12px;
color: #fff;
@@ -73,7 +73,7 @@
grid-template-columns: repeat(4, 1fr);
// grid-template-columns: repeat(auto-fit, minmax(25%, 1fr));
grid-auto-flow: row dense;
- gap: 16px 0;
+ gap: 32px 0;
// justify-content: space-between;
.nav-bar-button {
diff --git a/src/components/PolygonLayout/Barotorpic.jsx b/src/components/PolygonLayout/Barotorpic.jsx
index c21d819..52ad3c1 100644
--- a/src/components/PolygonLayout/Barotorpic.jsx
+++ b/src/components/PolygonLayout/Barotorpic.jsx
@@ -1,28 +1,75 @@
+import { useCallback, useState } from "react";
import {
Entity,
- PointGraphics,
- PolylineGraphics,
- useCesium,
- PathGraphics,
+ LabelGraphics,
EllipseGraphics,
+ useCesium,
+ CylinderGraphics,
} from "resium";
-import { Color, Cartesian3 } from "cesium";
+import { Color, Cartesian3, LabelStyle } from "cesium";
+import { useInterval } from "ahooks";
+
+// const material = Cesium.Material.fromType("Custom", {
+// fabric: Cesium.Color.RED.withAlpha(0.5),
+// shader: `
+// czm_material input;
+// czm_material output;
+
+// void main() {
+// output = input;
+// output.alpha = sin(input.st) * 0.5 + 0.5; //给圆柱体添加从上到下的动画效果
+// }`,
+// uniforms: {
+// input: function (czm, frameNumber, time, context) {
+// var u = Cesium.getUniform(context, "u");
+// return Cesium.Color.fromAlpha(czm.color, u);
+// },
+// },
+// });
function Barotropic() {
+ const { viewer } = useCesium();
+
+ const [show, setShow] = useState(false);
+
+ const showAnimate = useCallback(() => {
+ const { currentTime, stopTime } = viewer.clock;
+ const leftTime = Math.floor(
+ stopTime.secondsOfDay - currentTime.secondsOfDay
+ );
+
+ if (leftTime <= 10) {
+ setShow(true);
+ } else if (show) setShow(false);
+ }, [show]);
+
+ useInterval(showAnimate, 1000);
+
return (
+
);
}
diff --git a/src/components/PolygonLayout/CustomFlyTo.jsx b/src/components/PolygonLayout/CustomFlyTo.jsx
index c84678e..c5951fc 100644
--- a/src/components/PolygonLayout/CustomFlyTo.jsx
+++ b/src/components/PolygonLayout/CustomFlyTo.jsx
@@ -8,7 +8,7 @@ function CustomFlyTo() {
// 青藏高原
const plateauOptions = {
destination: Cesium.Cartesian3.fromDegrees(90, 20, 1600000),
- duration: 10,
+ duration: 5,
orientation: {
heading: Cesium.Math.toRadians(-15.0),
pitch: -Cesium.Math.PI_OVER_FOUR,
@@ -16,7 +16,7 @@ function CustomFlyTo() {
},
complete: function () {
setTimeout(function () {
- camera.flyTo(sideViewOptions);
+ camera.flyTo(step1);
}, 1000);
},
};
@@ -37,15 +37,57 @@ function CustomFlyTo() {
},
};
- // 侧边
- const sideViewOptions = {
- destination: Cesium.Cartesian3.fromDegrees(-2.5, 32.5, 20000000),
+ // barotorpic
+ const barotorpic = {
+ destination: Cesium.Cartesian3.fromDegrees(42, 46, 15000000),
+ duration: 30,
+ complete: function () {},
+ };
+
+ // // 侧边
+ // const sideViewOptions = {
+ // destination: Cesium.Cartesian3.fromDegrees(-2.5, 32.5, 20000000),
+ // duration: 5,
+ // complete: () => {
+ // const entity = viewer.entities.getById("point");
+ // viewer.clock.shouldAnimate = true;
+ // setTimeout(function () {
+ // camera.flyTo(step1);
+ // }, 1000);
+ // },
+ // };
+
+ // 俯视看箭头上升
+ const step1 = {
+ destination: Cesium.Cartesian3.fromDegrees(-50, 46, 2000000),
duration: 5,
+ orientation: {
+ heading: Cesium.Math.toRadians(-15.0),
+ pitch: -Cesium.Math.PI_OVER_FOUR,
+ roll: 0.0,
+ },
complete: () => {
viewer.clock.shouldAnimate = true;
+ setTimeout(function () {
+ camera.flyTo(barotorpic);
+ }, 1000);
},
};
+ // 在point后方跟随
+ const step2 = {
+ destination: Cesium.Cartesian3.fromDegrees(88, 60, 2000000),
+ duration: 40,
+ orientation: {
+ heading: Cesium.Math.toRadians(-15.0),
+ pitch: -Cesium.Math.PI_OVER_FOUR,
+ roll: 0.0,
+ },
+ };
+
+ // barotorpic
+ const step3 = {};
+
if (adjustPitch) {
plateauOptions.pitchAdjustHeight = 1000;
sideViewOptions.pitchAdjustHeight = 1000;
diff --git a/src/components/PolygonLayout/CustomToolbar.jsx b/src/components/PolygonLayout/CustomToolbar.jsx
index fe1a8f4..d7a28b7 100644
--- a/src/components/PolygonLayout/CustomToolbar.jsx
+++ b/src/components/PolygonLayout/CustomToolbar.jsx
@@ -1,13 +1,16 @@
-import { useCesium } from "resium";
import { useCallback, useState } from "react";
+import { useDispatch, useSelector } from "react-redux";
import { useNavigate } from "react-router-dom";
+import { useCesium } from "resium";
import { Select } from "antd";
import styles from "./index.module.less";
function CustomToolbar() {
const { viewer } = useCesium();
const navigate = useNavigate();
+ const dispatch = useDispatch();
+ const { toolbar } = useSelector((state) => state.data);
const [value, setValue] = useState("sideview");
const handleChange = (value) => {
@@ -60,12 +63,21 @@ function CustomToolbar() {
navigate("/home", { replace: true });
}, [navigate]);
+ const showPanelHandler = useCallback(
+ (value) => {
+ dispatch.data.updateToolbar({
+ showPanel: value,
+ });
+ },
+ [dispatch]
+ );
+
return (
返回首页
-
*/}
+
);
diff --git a/src/components/PolygonLayout/Cyclone.jsx b/src/components/PolygonLayout/Cyclone.jsx
index e9a4d83..781813d 100644
--- a/src/components/PolygonLayout/Cyclone.jsx
+++ b/src/components/PolygonLayout/Cyclone.jsx
@@ -1,20 +1,139 @@
-import { Entity, PointGraphics, useCesium } from "resium";
+import { Fragment, useCallback, useRef, useState } from "react";
+import { Entity, ModelGraphics, useCesium } from "resium";
+import { useInterval } from "ahooks";
+import arrowRound from "@/assets/arrow_round.glb";
-function Cyclone({ position }) {
+let totalSeconds = 60;
+let numberOfSamples = 120;
+let wheelAngle = 0;
+
+function Cyclone() {
const { viewer } = useCesium();
+ const [show1, setShow1] = useState(false);
+ const [show2, setShow2] = useState(false);
+ const [show3, setShow3] = useState(false);
+ const [show4, setShow4] = useState(false);
+ const [show5, setShow5] = useState(false);
+
+ // const position = new Cesium.SampledPositionProperty();
+
+ // const velocityVectorProperty = new Cesium.VelocityVectorProperty(
+ // position,
+ // false
+ // );
+ // const velocityVector = new Cesium.Cartesian3();
+ // const wheelAngleProperty = new Cesium.SampledProperty(Number);
+
+ // for (let index = 0; index < numberOfSamples; index++) {
+ // const factor = index / numberOfSamples;
+ // const time = Cesium.JulianDate.addSeconds(
+ // startTime,
+ // factor * totalSeconds,
+ // new Cesium.JulianDate()
+ // );
+ // velocityVectorProperty.getValue(time, velocityVector);
+ // wheelAngle -= 3;
+ // wheelAngleProperty.addSample(time, wheelAngle);
+ // }
+ // const rotationProperty = new Cesium.CallbackProperty(function (time, result) {
+ // return Cesium.Quaternion.fromAxisAngle(
+ // Cesium.Cartesian3.UNIT_Z,
+ // wheelAngleProperty.getValue(time) || wheelAngleProperty._values[0],
+ // result
+ // );
+ // }, false);
+
+ const animate = useCallback(() => {
+ const { startTime, currentTime, shouldAnimate } = viewer.clock;
+
+ if (!shouldAnimate) return;
+ const time = Math.floor(currentTime.secondsOfDay - startTime.secondsOfDay);
+ if (time < 10) {
+ if (time === 0) {
+ setShow1(false);
+ setShow2(false);
+ setShow3(false);
+ setShow4(false);
+ setShow5(false);
+ }
+ } else if (10 <= time < 50) {
+ if (time === 10) {
+ setShow1(true);
+ }
+ if (time === 20) {
+ setShow2(true);
+ }
+ if (time === 30) {
+ setShow3(true);
+ }
+ if (time === 40) {
+ setShow4(true);
+ }
+ if (time === 50) {
+ setShow5(true);
+ }
+ } else if (50 <= time < 60) {
+ if (time === 50) {
+ setShow5(true);
+ }
+ }
+ }, [viewer]);
+ useInterval(animate, 1000);
+
return (
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
);
}
diff --git a/src/components/PolygonLayout/InfoLayout/TextInfoPanel/First.jsx b/src/components/PolygonLayout/InfoLayout/TextInfoPanel/First.jsx
index e69de29..83439c8 100644
--- a/src/components/PolygonLayout/InfoLayout/TextInfoPanel/First.jsx
+++ b/src/components/PolygonLayout/InfoLayout/TextInfoPanel/First.jsx
@@ -0,0 +1,14 @@
+import TextPanel from "./TextPanel";
+
+function FirstPanel() {
+ return (
+
+ );
+}
+
+export default FirstPanel;
diff --git a/src/components/PolygonLayout/InfoLayout/TextInfoPanel/Second.jsx b/src/components/PolygonLayout/InfoLayout/TextInfoPanel/Second.jsx
index e69de29..acdd1c8 100644
--- a/src/components/PolygonLayout/InfoLayout/TextInfoPanel/Second.jsx
+++ b/src/components/PolygonLayout/InfoLayout/TextInfoPanel/Second.jsx
@@ -0,0 +1,10 @@
+function SecondPanel() {
+ return (
+
+ );
+}
+
+export default SecondPanel;
diff --git a/src/components/PolygonLayout/InfoLayout/TextInfoPanel/TextPanel.jsx b/src/components/PolygonLayout/InfoLayout/TextInfoPanel/TextPanel.jsx
new file mode 100644
index 0000000..5139381
--- /dev/null
+++ b/src/components/PolygonLayout/InfoLayout/TextInfoPanel/TextPanel.jsx
@@ -0,0 +1,50 @@
+import { useCallback, useEffect, useState } from "react";
+import { useSelector } from "react-redux";
+import { Scrollbars } from "react-custom-scrollbars-2";
+import { useInterval } from "ahooks";
+
+let index = 0;
+function TextPanel({ title, content }) {
+ const showNumberPerTimes = 1;
+ const { toolbar } = useSelector((state) => state.data);
+
+ const [delay, setDelay] = useState(80);
+ const [contentText, setContentText] = useState("");
+
+ useEffect(() => {
+ index = 0;
+ }, [toolbar]);
+
+ const showContent = useCallback(() => {
+ const isFinished = contentText.length >= content.length;
+ if (!isFinished) {
+ setContentText((text) => {
+ index += showNumberPerTimes;
+ return text + content[index - 1];
+ });
+ } else setDelay(undefined);
+ }, [contentText]);
+
+ useInterval(showContent, delay);
+
+ const stopHandler = useCallback(() => {
+ setDelay(undefined);
+ index = 0;
+ setContentText(content);
+ }, []);
+
+ return (
+
+
+ {title}
+
+
+
+ {contentText}
+
+
+
+ );
+}
+
+export default TextPanel;
diff --git a/src/components/PolygonLayout/InfoLayout/TextInfoPanel/Third.jsx b/src/components/PolygonLayout/InfoLayout/TextInfoPanel/Third.jsx
index e69de29..94b0d8a 100644
--- a/src/components/PolygonLayout/InfoLayout/TextInfoPanel/Third.jsx
+++ b/src/components/PolygonLayout/InfoLayout/TextInfoPanel/Third.jsx
@@ -0,0 +1,10 @@
+function ThirdPanel() {
+ return (
+
+ );
+}
+
+export default ThirdPanel;
diff --git a/src/components/PolygonLayout/InfoLayout/TextInfoPanel/index.jsx b/src/components/PolygonLayout/InfoLayout/TextInfoPanel/index.jsx
index 04a26fe..adcf5a4 100644
--- a/src/components/PolygonLayout/InfoLayout/TextInfoPanel/index.jsx
+++ b/src/components/PolygonLayout/InfoLayout/TextInfoPanel/index.jsx
@@ -1,5 +1,19 @@
-function TextInfoPanel() {
- return ;
+import FirstPanel from "./First";
+import SecondPanel from "./Second";
+import ThirdPanel from "./Third";
+
+function TextInfoPanel({ type }) {
+ switch (type) {
+ case 1:
+ return ;
+ case 2:
+ return ;
+ case 3:
+ return ;
+
+ default:
+ break;
+ }
}
export default TextInfoPanel;
diff --git a/src/components/PolygonLayout/InfoLayout/index.jsx b/src/components/PolygonLayout/InfoLayout/index.jsx
index b909c9e..893844b 100644
--- a/src/components/PolygonLayout/InfoLayout/index.jsx
+++ b/src/components/PolygonLayout/InfoLayout/index.jsx
@@ -1,11 +1,18 @@
+import { useLocation } from "react-router-dom";
import ChartInfoPanel from "./ChartInfoPanel";
import TextInfoPanel from "./TextInfoPanel";
import styles from "./index.module.less";
+import { useSelector } from "react-redux";
function InfoLayout() {
+ const location = useLocation();
+ const { toolbar } = useSelector((state) => state.data);
+
+ if (!toolbar.showPanel) return <>>;
+
return (
-
+
);
diff --git a/src/components/PolygonLayout/InfoLayout/index.module.less b/src/components/PolygonLayout/InfoLayout/index.module.less
index 0a8471a..2727332 100644
--- a/src/components/PolygonLayout/InfoLayout/index.module.less
+++ b/src/components/PolygonLayout/InfoLayout/index.module.less
@@ -9,29 +9,30 @@
pointer-events: none;
.textInfoPanel {
- width: 476px;
- height: 426px;
+ width: 450px;
+ height: 400px;
padding: 12px;
border: 1px solid #04fbfd;
color: #02f9ff !important;
background-color: #1f485690;
margin-bottom: 168px;
pointer-events: auto;
+ display: flex;
+ flex-direction: column;
- .ant-descriptions-item {
- padding-bottom: 0;
- .ant-descriptions-item-container {
- font-size: 18px;
+ .title {
+ font-size: 20px;
+ font-weight: 600;
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ margin-bottom: 12px;
+ }
- .ant-descriptions-item-label {
- color: #02f9ff !important;
- // font-size: ;
- }
-
- .ant-descriptions-item-content {
- color: #02f9ff !important;
- }
- }
+ .content {
+ flex: 1;
+ text-indent: 32px;
+ line-height: 1.5;
}
}
diff --git a/src/components/PolygonLayout/Picker.jsx b/src/components/PolygonLayout/Picker.jsx
new file mode 100644
index 0000000..3657c75
--- /dev/null
+++ b/src/components/PolygonLayout/Picker.jsx
@@ -0,0 +1,49 @@
+import { Entity, LabelGraphics, useCesium } from "resium";
+
+let handler;
+
+function Picker() {
+ const { viewer } = useCesium();
+ const { scene } = viewer;
+
+ // Mouse over the globe to see the cartographic position
+ handler = new Cesium.ScreenSpaceEventHandler(scene.canvas);
+ handler.setInputAction(function (movement) {
+ const cartesian = viewer.camera.pickEllipsoid(
+ movement.endPosition,
+ scene.globe.ellipsoid
+ );
+ if (cartesian) {
+ const cartographic = Cesium.Cartographic.fromCartesian(cartesian);
+ const longitudeString = Cesium.Math.toDegrees(
+ cartographic.longitude
+ ).toFixed(2);
+ const latitudeString = Cesium.Math.toDegrees(
+ cartographic.latitude
+ ).toFixed(2);
+ // console.log("longitudeString, :>> ", longitudeString, latitudeString);
+ // entity.position = cartesian;
+ // entity.label.show = true;
+ // entity.label.text =
+ // `Lon: ${` ${longitudeString}`.slice(-7)}\u00B0` +
+ // `\nLat: ${` ${latitudeString}`.slice(-7)}\u00B0`;
+ } else {
+ // entity.label.show = false;
+ }
+ }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
+
+ return (
+
+
+
+ );
+}
+
+export default Picker;
diff --git a/src/components/PolygonLayout/Point copy.jsx b/src/components/PolygonLayout/Point copy.jsx
deleted file mode 100644
index 38c8dac..0000000
--- a/src/components/PolygonLayout/Point copy.jsx
+++ /dev/null
@@ -1,132 +0,0 @@
-import { Entity } from "resium";
-import { useRef } from "react";
-
-// const height = 9000 * 100;
-// // 从南极上升9000m
-// const step1 = [
-// { longitude: -70, latitude: -60, height: 0, time: 0 },
-// { longitude: -70, latitude: -60, height, time: 10 },
-// ];
-// // 从南极上空9km绕地球到青藏高原上空9km
-// const step2 = [
-// { longitude: -30, latitude: -55, height, time: 20 },
-// { longitude: 30, latitude: -40, height, time: 30 },
-// { longitude: 65, latitude: -35, height, time: 40 },
-// ];
-// // 从青藏高原上空9km下降到青藏高原
-// const step3 = [
-// { longitude: 95, latitude: -30, height, time: 50 },
-// { longitude: 95, latitude: -30, height: 0, time: 60 },
-// ];
-// const data = flatten([step1, step2, step3]);
-
-const data = [];
-const height = 2000;
-
-for (let index = 0; index < 120; index++) {
- data.push({
- longitude: 88,
- latitude: 35 - 120 + index * 0.9874, // 由南极到青藏高原
- // latitude: 33 -index, // 由青藏高原到南极
- height:
- index > 59
- ? index === 60
- ? height * 59
- : (119 - index) * height
- : height * index,
- time: index / 2,
- });
-}
-
-function Point({ start, stop }) {
- const entityRef = useRef();
-
- /**
- * 计算飞行路径
- * 数据坐标
- * {SampledPositionProperty|*}
- */
- function createProperty(source) {
- let property = new Cesium.SampledPositionProperty();
- for (let i = 0; i < source.length; i++) {
- let time = Cesium.JulianDate.addSeconds(
- start,
- source[i].time,
- new Cesium.JulianDate()
- );
- let position = Cesium.Cartesian3.fromDegrees(
- source[i].longitude,
- source[i].latitude,
- source[i].height
- );
- // 添加位置,和时间对应
- property.addSample(time, position);
- }
- return property;
- }
-
- const property = createProperty(data);
- // property.setInterpolationOptions({
- // interpolationDegree: 10,
- // interpolationAlgorithm: Cesium.LagrangePolynomialApproximation,
- // });
- property.setInterpolationOptions({
- interpolationDegree: 1,
- interpolationAlgorithm: Cesium.LinearApproximation,
- });
-
- return (
- {
- // setValue("follow");
- // }}
- ref={entityRef}
- availability={
- new Cesium.TimeIntervalCollection([
- new Cesium.TimeInterval({
- start: start,
- stop: stop,
- }),
- ])
- }
- id={"point"}
- position={property}
- // 朝向
- orientation={new Cesium.VelocityOrientationProperty(property)}
- path={{
- resolution: 1,
- material: new Cesium.PolylineDashMaterialProperty({
- dashLength: 20,
- color: new Cesium.Color(4 / 255, 251 / 255, 253 / 255),
- }),
- // leadTime、trailTime 不设置 path全显示
- leadTime: 0, // 设置为0时 模型通过后显示path
- // trailTime: 0, // 设置为0时 模型通过后隐藏path
- width: 2,
- }}
- >
- {/* */}
- {/* */}
-
- );
-}
-
-export default Point;
diff --git a/src/components/PolygonLayout/Point.jsx b/src/components/PolygonLayout/Point.jsx
index 50c4f86..c4351d4 100644
--- a/src/components/PolygonLayout/Point.jsx
+++ b/src/components/PolygonLayout/Point.jsx
@@ -1,36 +1,26 @@
-import {
- Entity,
- PointGraphics,
- PolylineGraphics,
- useCesium,
- PathGraphics,
-} from "resium";
-import { Fragment, useCallback, useRef, useState } from "react";
-import { useInterval } from "ahooks";
+import { Entity, PointGraphics, useCesium } from "resium";
import { flatten } from "lodash-es";
const height = 9000 * 100;
// 从拉布拉多海上升
const step1 = [
- { longitude: -55, latitude: 58, height: 1000000, time: 0 },
- // { longitude: -70, latitude: -60, height, time: 10 },
+ // { longitude: -55, latitude: 58, height: 0, time: 0 },
+ { longitude: -55, latitude: 58, height: 1000000, time: 10 },
];
// 从拉布拉多海上空移动到目的地
const step2 = [
- // { longitude: -30, latitude: -55, height, time: 20 },
- // { longitude: 30, latitude: -40, height, time: 30 },
- // { longitude: 65, latitude: -35, height, time: 40 },
+ { longitude: -32, latitude: 72.2, height, time: 20 },
+ { longitude: 20, latitude: 77, height, time: 30 },
+ { longitude: 63, latitude: 69.9, height, time: 40 },
];
// 从目的地下降
const step3 = [
- // { longitude: 95, latitude: -30, height, time: 50 },
- { longitude: 80, latitude: 60, height: 1000000, time: 60 },
+ { longitude: 88, latitude: 60, height: 1000000, time: 50 },
+ // { longitude: 80, latitude: 60, height: 0, time: 60 },
];
const data = flatten([step1, step2, step3]);
function Point({ start, stop }) {
- const { viewer } = useCesium();
-
/**
* 计算飞行路径
* 数据坐标
@@ -47,8 +37,7 @@ function Point({ start, stop }) {
let position = Cesium.Cartesian3.fromDegrees(
source[i].longitude,
source[i].latitude,
- // source[i].height
- 1000000
+ source[i].height
);
// 添加位置,和时间对应
property.addSample(time, position);
@@ -57,36 +46,15 @@ function Point({ start, stop }) {
}
const property = createProperty(data);
- // property.setInterpolationOptions({
- // interpolationDegree: 10,
- // interpolationAlgorithm: Cesium.LagrangePolynomialApproximation,
- // });
+
property.setInterpolationOptions({
- interpolationDegree: 1,
- interpolationAlgorithm: Cesium.LinearApproximation,
+ interpolationDegree: 10,
+ interpolationAlgorithm: Cesium.LagrangePolynomialApproximation,
});
-
- const animate = useCallback(() => {
- const { currentTime, startTime, shouldAnimate } = viewer.clock;
- if (!shouldAnimate) return;
- const entity = viewer.entities.getById("point");
- const position = entity.position;
- // console.log("entity :>> ", entity, position);
-
- const time = Math.floor(currentTime.secondsOfDay - startTime.secondsOfDay);
- if (time < 10) {
- // entity.position._value.z = position._value.z + 9000 * 10;
- } else if (10 < time < 50) {
- if (time === 20) {
- }
- if (time === 30) {
- }
- if (time === 40) {
- }
- } else if (50 < time < 60) {
- }
- }, [viewer]);
- useInterval(animate, 1000);
+ // property.setInterpolationOptions({
+ // interpolationDegree: 1,
+ // interpolationAlgorithm: Cesium.LinearApproximation,
+ // });
return (
10) {
+ return Cesium.Cartesian3.fromDegreesArrayHeights(
+ [-55, 58, 0, -55, 58, 1000000],
+ Cesium.Ellipsoid.WGS84,
+ result
+ );
+ }
+ }, false)
+ }
+ width={20}
material={new Cesium.PolylineArrowMaterialProperty(Cesium.Color.RED)}
/>
diff --git a/src/components/PolygonLayout/index.jsx b/src/components/PolygonLayout/index.jsx
index c2a1d6c..acff800 100644
--- a/src/components/PolygonLayout/index.jsx
+++ b/src/components/PolygonLayout/index.jsx
@@ -5,13 +5,14 @@ import Point from "./Point";
import CustomClock from "./CustomClock";
import CustomFlyTo from "./CustomFlyTo";
import InfoLayout from "./InfoLayout";
-import styles from "./index.module.less";
import WavePoint from "./WavePoint";
import CustomToolbar from "./CustomToolbar";
import Cyclone from "./Cyclone";
import Barotropic from "./Barotorpic";
import Watervapor from "./Watervapor";
import Updraft from "./Udraft";
+import styles from "./index.module.less";
+import Picker from "./Picker";
// 起始时间
let start = Cesium.JulianDate.fromDate(new Date());
@@ -26,11 +27,11 @@ function PolygonLayout() {
// infoBox={false}
// baseLayerPicker={false}
// timeline={true}
- // homeButton={false}
+ homeButton={false}
// fullscreenButton={false}
- // sceneModePicker={false}
+ sceneModePicker={false}
// navigationInstructionsInitiallyVisible={false}
- // navigationHelpButton={false}
+ navigationHelpButton={false}
// animation={false}
shouldAnimate={true}
>
@@ -43,10 +44,11 @@ function PolygonLayout() {
- {/* */}
+
-
+ {/* */}
+
);
}
diff --git a/src/index.js b/src/index.js
index 7b2f492..bbfbd48 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,16 +1,20 @@
import React from "react";
import ReactDOM from "react-dom/client";
+import { Provider } from "react-redux";
import { BrowserRouter } from "react-router-dom";
-import "./index.css";
+import { store } from "@/store";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
+import "./index.css";
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
//
-
-
-
+
+
+
+
+
//
);
diff --git a/src/models/data.js b/src/models/data.js
new file mode 100644
index 0000000..559675f
--- /dev/null
+++ b/src/models/data.js
@@ -0,0 +1,17 @@
+export const data = {
+ state: {
+ toolbar: {
+ showPanel: true,
+ },
+ },
+ reducers: {
+ update(state, payload) {
+ return { ...state, ...payload };
+ },
+ updateToolbar(state, payload) {
+ const { toolbar } = state;
+ return { ...state, toolbar: { ...toolbar, ...payload } };
+ },
+ },
+ effects: (dispatch) => ({}),
+};
diff --git a/src/models/index.js b/src/models/index.js
new file mode 100644
index 0000000..533b6dc
--- /dev/null
+++ b/src/models/index.js
@@ -0,0 +1 @@
+export { data } from "./data";
diff --git a/src/store.js b/src/store.js
new file mode 100644
index 0000000..d7146fa
--- /dev/null
+++ b/src/store.js
@@ -0,0 +1,17 @@
+import { init } from "@rematch/core";
+import storage from "redux-persist/lib/storage";
+import selectPlugin from "@rematch/select";
+import loadingPlugin from "@rematch/loading";
+import persistPlugin from "@rematch/persist";
+import * as models from "./models";
+
+const persistConfig = {
+ key: "glacier",
+ storage,
+ whitelist: ["user"],
+};
+
+export const store = init({
+ models,
+ plugins: [selectPlugin(), loadingPlugin(), persistPlugin(persistConfig)],
+});
diff --git a/yarn.lock b/yarn.lock
index e19f3e7..1da5828 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2679,6 +2679,48 @@ __metadata:
languageName: node
linkType: hard
+"@rematch/core@npm:^2.2.0":
+ version: 2.2.0
+ resolution: "@rematch/core@npm:2.2.0"
+ peerDependencies:
+ redux: ">=4"
+ checksum: c2ae22b9c6d19b7bd8a4d8679a8c5248733e95314eabdc0e8d85ecb4042432d315e8476fa3ccde6fbc5bde220577d55f3d7d39202136bd4a7b2ad7bc978625d0
+ languageName: node
+ linkType: hard
+
+"@rematch/loading@npm:^2.1.2":
+ version: 2.1.2
+ resolution: "@rematch/loading@npm:2.1.2"
+ peerDependencies:
+ "@rematch/core": ">=2"
+ checksum: 142fab39642472815d42086d3eb94acda99ed2f0aadb773ed7012f9a8c1cbf6f2a04da01b376ed9faa235a5cf6337643d0596e8e277769641f5fc621c6edcd5c
+ languageName: node
+ linkType: hard
+
+"@rematch/persist@npm:^2.1.2":
+ version: 2.1.2
+ resolution: "@rematch/persist@npm:2.1.2"
+ dependencies:
+ redux-persist: ^6.0.0
+ peerDependencies:
+ "@rematch/core": ">=2"
+ redux: ">=4"
+ checksum: 341c2a83bf02df81c1d04beb229c695ffb0ea64deb6a12766534403b41a2f51b32c8cd549b1a1986294e9059ec5ce80f58062a8701f51bf195e679ffa8669222
+ languageName: node
+ linkType: hard
+
+"@rematch/select@npm:^3.1.2":
+ version: 3.1.2
+ resolution: "@rematch/select@npm:3.1.2"
+ dependencies:
+ reselect: ^4.0.0
+ peerDependencies:
+ "@rematch/core": ">=2"
+ redux: ">=4"
+ checksum: f554e26551dd06297375d22cf14e9b2cdb26ead6f4ced47f04979ea2e6158b038b1c9f6e87a6be71db28c81e56e14c81c6927c62e63eae8b416770340a5ed2c2
+ languageName: node
+ linkType: hard
+
"@remix-run/router@npm:1.8.0":
version: 1.8.0
resolution: "@remix-run/router@npm:1.8.0"
@@ -4085,6 +4127,13 @@ __metadata:
languageName: node
linkType: hard
+"add-px-to-style@npm:1.0.0":
+ version: 1.0.0
+ resolution: "add-px-to-style@npm:1.0.0"
+ checksum: 673831d81d86d717e3a9f4f644059476ca74990dd28310d9bffe6cb35fac8007865351d37a885af168a8613f5cdb054db728a3df19e9ee1457b75a668003c729
+ languageName: node
+ linkType: hard
+
"address@npm:^1.0.1, address@npm:^1.1.2":
version: 1.2.2
resolution: "address@npm:1.2.2"
@@ -5466,6 +5515,10 @@ __metadata:
dependencies:
"@ant-design/colors": ^7.0.0
"@craco/craco": ^7.1.0
+ "@rematch/core": ^2.2.0
+ "@rematch/loading": ^2.1.2
+ "@rematch/persist": ^2.1.2
+ "@rematch/select": ^3.1.2
"@testing-library/jest-dom": ^5.17.0
"@testing-library/react": ^13.4.0
"@testing-library/user-event": ^13.5.0
@@ -5479,10 +5532,13 @@ __metadata:
lodash-es: ^4.17.21
node-polyfill-webpack-plugin: ^2.0.1
react: ^18.2.0
+ react-custom-scrollbars-2: ^4.5.0
react-dom: ^18.2.0
react-redux: ^8.1.2
react-router-dom: ^6.15.0
react-scripts: 5.0.1
+ redux: ^4.2.1
+ redux-persist: ^6.0.0
resium: ^1.17.1
tslib: ^2.6.2
web-vitals: ^2.1.4
@@ -6869,6 +6925,17 @@ __metadata:
languageName: node
linkType: hard
+"dom-css@npm:^2.0.0":
+ version: 2.1.0
+ resolution: "dom-css@npm:2.1.0"
+ dependencies:
+ add-px-to-style: 1.0.0
+ prefix-style: 2.0.1
+ to-camel-case: 1.0.0
+ checksum: f61cc63e88771e1800ff4b7d98b17be2b311de984d94c3d3e0be692794502eb021d28c5c40ba08d4370a6d8bd96caf7a56d15c635451c2db1a2233c94ca0fcc0
+ languageName: node
+ linkType: hard
+
"dom-serializer@npm:0":
version: 0.2.2
resolution: "dom-serializer@npm:0.2.2"
@@ -13399,6 +13466,13 @@ __metadata:
languageName: node
linkType: hard
+"prefix-style@npm:2.0.1":
+ version: 2.0.1
+ resolution: "prefix-style@npm:2.0.1"
+ checksum: 79c3559b74417a1552a91d2008d64cc7f326ff4fe8ed2053519663677238f28455bfda0dd935cb1d6690ac7281aff14361e15cfcf83ec263a8183827df7b2a90
+ languageName: node
+ linkType: hard
+
"prelude-ls@npm:^1.2.1":
version: 1.2.1
resolution: "prelude-ls@npm:1.2.1"
@@ -13507,7 +13581,7 @@ __metadata:
languageName: node
linkType: hard
-"prop-types@npm:^15.8.1":
+"prop-types@npm:^15.5.10, prop-types@npm:^15.8.1":
version: 15.8.1
resolution: "prop-types@npm:15.8.1"
dependencies:
@@ -13683,7 +13757,7 @@ __metadata:
languageName: node
linkType: hard
-"raf@npm:^3.4.1":
+"raf@npm:^3.1.0, raf@npm:^3.4.1":
version: 3.4.1
resolution: "raf@npm:3.4.1"
dependencies:
@@ -14300,6 +14374,20 @@ __metadata:
languageName: node
linkType: hard
+"react-custom-scrollbars-2@npm:^4.5.0":
+ version: 4.5.0
+ resolution: "react-custom-scrollbars-2@npm:4.5.0"
+ dependencies:
+ dom-css: ^2.0.0
+ prop-types: ^15.5.10
+ raf: ^3.1.0
+ peerDependencies:
+ react: ^0.14.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0
+ react-dom: ^0.14.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0
+ checksum: b264629c0bfcc292106540f802e4d4281fb4acfab93ab259dcde096b72f135a1be6f2fcf636478f9e9bce6e15a9c6eb624c799184bb478073bb7ace86588a1de
+ languageName: node
+ linkType: hard
+
"react-dev-utils@npm:^12.0.1":
version: 12.0.1
resolution: "react-dev-utils@npm:12.0.1"
@@ -14598,6 +14686,24 @@ __metadata:
languageName: node
linkType: hard
+"redux-persist@npm:^6.0.0":
+ version: 6.0.0
+ resolution: "redux-persist@npm:6.0.0"
+ peerDependencies:
+ redux: ">4.0.0"
+ checksum: edaf10dbf17351ce8058d0802357adae8665b3a1ff39371834e37838ddbe1a79cccbc717b8ba54acb5307651ccf51d0f7dc1cbc8dbae0726ff952d11ef61c6b8
+ languageName: node
+ linkType: hard
+
+"redux@npm:^4.2.1":
+ version: 4.2.1
+ resolution: "redux@npm:4.2.1"
+ dependencies:
+ "@babel/runtime": ^7.9.2
+ checksum: f63b9060c3a1d930ae775252bb6e579b42415aee7a23c4114e21a0b4ba7ec12f0ec76936c00f546893f06e139819f0e2855e0d55ebfce34ca9c026241a6950dd
+ languageName: node
+ linkType: hard
+
"reflect.getprototypeof@npm:^1.0.3":
version: 1.0.3
resolution: "reflect.getprototypeof@npm:1.0.3"
@@ -14766,6 +14872,13 @@ __metadata:
languageName: node
linkType: hard
+"reselect@npm:^4.0.0":
+ version: 4.1.8
+ resolution: "reselect@npm:4.1.8"
+ checksum: a4ac87cedab198769a29be92bc221c32da76cfdad6911eda67b4d3e7136dca86208c3b210e31632eae31ebd2cded18596f0dd230d3ccc9e978df22f233b5583e
+ languageName: node
+ linkType: hard
+
"resium@npm:^1.17.1":
version: 1.17.1
resolution: "resium@npm:1.17.1"
@@ -16383,6 +16496,15 @@ __metadata:
languageName: node
linkType: hard
+"to-camel-case@npm:1.0.0":
+ version: 1.0.0
+ resolution: "to-camel-case@npm:1.0.0"
+ dependencies:
+ to-space-case: ^1.0.0
+ checksum: 2f74cfcffa58e8ddede7e01a03eda2cc3f0ab50efdad1d0f1092d55b4e499be43846d1f9087c458fa9efde4958e407738197d65858272c56c915b649b9ca1e62
+ languageName: node
+ linkType: hard
+
"to-fast-properties@npm:^2.0.0":
version: 2.0.0
resolution: "to-fast-properties@npm:2.0.0"
@@ -16390,6 +16512,13 @@ __metadata:
languageName: node
linkType: hard
+"to-no-case@npm:^1.0.0":
+ version: 1.0.2
+ resolution: "to-no-case@npm:1.0.2"
+ checksum: 1d85326eeb89f9f3a805bf5b395bcabb8556e882350164c1faa10846076732f4cec02ac95b016e7d6bb2f55e448ce5dd227c7699ec43e387c705a5b2b1ee2963
+ languageName: node
+ linkType: hard
+
"to-object-path@npm:^0.3.0":
version: 0.3.0
resolution: "to-object-path@npm:0.3.0"
@@ -16430,6 +16559,15 @@ __metadata:
languageName: node
linkType: hard
+"to-space-case@npm:^1.0.0":
+ version: 1.0.0
+ resolution: "to-space-case@npm:1.0.0"
+ dependencies:
+ to-no-case: ^1.0.0
+ checksum: 157cebe3e98e7cb465fe1978cf26450cc8ea8e637a01039854fac7ed60ad074e5e18b32333cc5f30df81b81ca374d63df768cd4c1fa0fe672605f965376227f4
+ languageName: node
+ linkType: hard
+
"toggle-selection@npm:^1.0.6":
version: 1.0.6
resolution: "toggle-selection@npm:1.0.6"