代码迁移
This commit is contained in:
18
.babelrc
Normal file
18
.babelrc
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"presets": [
|
||||||
|
[
|
||||||
|
"@babel/preset-env",
|
||||||
|
{
|
||||||
|
"modules": false,
|
||||||
|
"targets": {
|
||||||
|
"browsers": ["> 1%", "last 2 versions", "ie >= 10"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"plugins": [
|
||||||
|
["@babel/plugin-proposal-decorators", { "legacy": true }],
|
||||||
|
["@babel/plugin-proposal-class-properties", { "loose": false }],
|
||||||
|
"@babel/plugin-syntax-dynamic-import"
|
||||||
|
]
|
||||||
|
}
|
||||||
2
.browserslistrc
Normal file
2
.browserslistrc
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
> 1%
|
||||||
|
last 2 versions
|
||||||
12
.editorconfig
Normal file
12
.editorconfig
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
end_of_line = lf
|
||||||
|
charset = utf-8
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
insert_final_newline = true
|
||||||
|
|
||||||
|
[*.md]
|
||||||
|
trim_trailing_whitespace = false
|
||||||
4
.eslintignore
Normal file
4
.eslintignore
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
/lib/
|
||||||
|
/web/
|
||||||
|
/pack/
|
||||||
|
|
||||||
29
.eslintrc
Normal file
29
.eslintrc
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
{
|
||||||
|
"root": true,
|
||||||
|
"parser": "babel-eslint",
|
||||||
|
"parserOptions": {
|
||||||
|
"sourceType": "module"
|
||||||
|
},
|
||||||
|
"env": {
|
||||||
|
"es6": true,
|
||||||
|
"node": true,
|
||||||
|
"browser": true
|
||||||
|
},
|
||||||
|
"plugins": ["prettier"],
|
||||||
|
"extends": ["eslint:recommended", "plugin:prettier/recommended"],
|
||||||
|
"globals": {
|
||||||
|
"Cesium": false
|
||||||
|
},
|
||||||
|
"rules": {
|
||||||
|
"global-require": 0,
|
||||||
|
"indent": 0,
|
||||||
|
"no-new": 0,
|
||||||
|
"camelcase": 0,
|
||||||
|
"padded-blocks": 0,
|
||||||
|
"no-unused-vars": 0,
|
||||||
|
"no-trailing-spaces": 0,
|
||||||
|
"no-mixed-spaces-and-tabs": 0,
|
||||||
|
"space-before-function-paren": [0, "always"],
|
||||||
|
"no-multiple-empty-lines": 0
|
||||||
|
}
|
||||||
|
}
|
||||||
131
.gitignore
vendored
131
.gitignore
vendored
@ -1,14 +1,123 @@
|
|||||||
# ---> VisualStudioCode
|
# Logs
|
||||||
.vscode/*
|
logs
|
||||||
!.vscode/settings.json
|
*.log
|
||||||
!.vscode/tasks.json
|
npm-debug.log*
|
||||||
!.vscode/launch.json
|
yarn-debug.log*
|
||||||
!.vscode/extensions.json
|
yarn-error.log*
|
||||||
!.vscode/*.code-snippets
|
lerna-debug.log*
|
||||||
|
|
||||||
# Local History for Visual Studio Code
|
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||||
.history/
|
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||||
|
|
||||||
# Built Visual Studio Code Extensions
|
# Runtime data
|
||||||
*.vsix
|
pids
|
||||||
|
*.pid
|
||||||
|
*.seed
|
||||||
|
*.pid.lock
|
||||||
|
*.idea
|
||||||
|
|
||||||
|
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||||
|
lib-cov
|
||||||
|
|
||||||
|
# Coverage directory used by tools like istanbul
|
||||||
|
coverage
|
||||||
|
*.lcov
|
||||||
|
|
||||||
|
# nyc test coverage
|
||||||
|
.nyc_output
|
||||||
|
|
||||||
|
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
||||||
|
.grunt
|
||||||
|
|
||||||
|
# Bower dependency directory (https://bower.io/)
|
||||||
|
bower_components
|
||||||
|
|
||||||
|
# node-waf configuration
|
||||||
|
.lock-wscript
|
||||||
|
|
||||||
|
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||||
|
build/Release
|
||||||
|
|
||||||
|
# Dependency directories
|
||||||
|
node_modules/
|
||||||
|
jspm_packages/
|
||||||
|
|
||||||
|
#static
|
||||||
|
|
||||||
|
# Snowpack dependency directory (https://snowpack.dev/)
|
||||||
|
web_modules/
|
||||||
|
|
||||||
|
# TypeScript cache
|
||||||
|
*.tsbuildinfo
|
||||||
|
|
||||||
|
# Optional npm cache directory
|
||||||
|
.npm
|
||||||
|
|
||||||
|
# Optional eslint cache
|
||||||
|
.eslintcache
|
||||||
|
|
||||||
|
# Microbundle cache
|
||||||
|
.rpt2_cache/
|
||||||
|
.rts2_cache_cjs/
|
||||||
|
.rts2_cache_es/
|
||||||
|
.rts2_cache_umd/
|
||||||
|
|
||||||
|
# Optional REPL history
|
||||||
|
.node_repl_history
|
||||||
|
|
||||||
|
# Output of 'npm pack'
|
||||||
|
*.tgz
|
||||||
|
|
||||||
|
# Yarn Integrity file
|
||||||
|
.yarn-integrity
|
||||||
|
|
||||||
|
# dotenv environment variables file
|
||||||
|
.env
|
||||||
|
.env.test
|
||||||
|
|
||||||
|
# parcel-bundler cache (https://parceljs.org/)
|
||||||
|
.cache
|
||||||
|
.parcel-cache
|
||||||
|
|
||||||
|
# Next.js build output
|
||||||
|
.next
|
||||||
|
out
|
||||||
|
|
||||||
|
# Nuxt.js build / generate output
|
||||||
|
.nuxt
|
||||||
|
dist
|
||||||
|
|
||||||
|
# Gatsby files
|
||||||
|
.cache/
|
||||||
|
# Comment in the public line in if your project uses Gatsby and not Next.js
|
||||||
|
# https://nextjs.org/blog/next-9-1#public-directory-support
|
||||||
|
# public
|
||||||
|
|
||||||
|
# vuepress build output
|
||||||
|
.vuepress/dist
|
||||||
|
|
||||||
|
# Serverless directories
|
||||||
|
.serverless/
|
||||||
|
|
||||||
|
# FuseBox cache
|
||||||
|
.fusebox/
|
||||||
|
|
||||||
|
# DynamoDB Local files
|
||||||
|
.dynamodb/
|
||||||
|
|
||||||
|
# TernJS port file
|
||||||
|
.tern-port
|
||||||
|
|
||||||
|
# Stores VSCode versions used for testing VSCode extensions
|
||||||
|
.vscode-test
|
||||||
|
|
||||||
|
# yarn v2
|
||||||
|
.yarn/cache
|
||||||
|
.yarn/unplugged
|
||||||
|
.yarn/build-state.yml
|
||||||
|
.yarn/install-state.gz
|
||||||
|
.pnp.*
|
||||||
|
docs
|
||||||
|
|
||||||
|
# history
|
||||||
|
.history
|
||||||
|
|||||||
11
.markdownlintrc
Normal file
11
.markdownlintrc
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"default": true,
|
||||||
|
"colors": true,
|
||||||
|
"header-increment": false,
|
||||||
|
"line-length": false,
|
||||||
|
"no-trailing-punctuation": { "punctuation": ".,;:" },
|
||||||
|
"no-duplicate-header": false,
|
||||||
|
"no-inline-html": false,
|
||||||
|
"no-hard-tabs": false,
|
||||||
|
"whitespace": false
|
||||||
|
}
|
||||||
5
.prettierrc
Normal file
5
.prettierrc
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"eslintIntegration": true,
|
||||||
|
"singleQuote": true,
|
||||||
|
"semi": false
|
||||||
|
}
|
||||||
201
LICENSE
Normal file
201
LICENSE
Normal file
@ -0,0 +1,201 @@
|
|||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright [yyyy] [name of copyright owner]
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
203
LICENSE.MD
Normal file
203
LICENSE.MD
Normal file
@ -0,0 +1,203 @@
|
|||||||
|
Copyright (c) 2019-present Caven Chen
|
||||||
|
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright (c) 2019-present Caven Chen
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
26
README.en.md
Normal file
26
README.en.md
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
# sdk4
|
||||||
|
|
||||||
|
#### Description
|
||||||
|
4.0的sdk,兼容3.0,取消earthsdk的引用
|
||||||
|
|
||||||
|
#### Software Architecture
|
||||||
|
Software architecture description
|
||||||
|
|
||||||
|
#### Installation
|
||||||
|
|
||||||
|
1. xxxx
|
||||||
|
2. xxxx
|
||||||
|
3. xxxx
|
||||||
|
|
||||||
|
#### Instructions
|
||||||
|
|
||||||
|
1. xxxx
|
||||||
|
2. xxxx
|
||||||
|
3. xxxx
|
||||||
|
|
||||||
|
#### Contribution
|
||||||
|
|
||||||
|
1. Fork the repository
|
||||||
|
2. Create Feat_xxx branch
|
||||||
|
3. Commit your code
|
||||||
|
4. Create Pull Request
|
||||||
28
README.md
28
README.md
@ -1,3 +1,27 @@
|
|||||||
# sdk4.0
|
# sdk4
|
||||||
|
|
||||||
sdk4.0
|
#### 介绍
|
||||||
|
4.0的sdk,兼容3.0,取消earthsdk的引用
|
||||||
|
|
||||||
|
#### 软件架构
|
||||||
|
软件架构说明
|
||||||
|
|
||||||
|
|
||||||
|
#### 安装教程
|
||||||
|
|
||||||
|
1. xxxx
|
||||||
|
2. xxxx
|
||||||
|
3. xxxx
|
||||||
|
|
||||||
|
#### 使用说明
|
||||||
|
|
||||||
|
1. xxxx
|
||||||
|
2. xxxx
|
||||||
|
3. xxxx
|
||||||
|
|
||||||
|
#### 参与贡献
|
||||||
|
|
||||||
|
1. Fork 本仓库
|
||||||
|
2. 新建 Feat_xxx 分支
|
||||||
|
3. 提交代码
|
||||||
|
4. 新建 Pull Request
|
||||||
|
|||||||
40
ink-docstrap.json
Normal file
40
ink-docstrap.json
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
{
|
||||||
|
"tags": {
|
||||||
|
"allowUnknownTags": true,
|
||||||
|
"dictionaries": [
|
||||||
|
"jsdoc"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"source": {
|
||||||
|
"include": [
|
||||||
|
"./src"
|
||||||
|
],
|
||||||
|
"includePattern": ".+\\.js(doc|x)?$",
|
||||||
|
"excludePattern": "(^|\\/|\\\\)_"
|
||||||
|
},
|
||||||
|
"templates": {
|
||||||
|
"cleverLinks": false,
|
||||||
|
"monospaceLinks": false,
|
||||||
|
"default": {
|
||||||
|
"outputSourceFiles": true
|
||||||
|
},
|
||||||
|
"systemName": "接口文档",
|
||||||
|
"footer": "",
|
||||||
|
"copyright": "",
|
||||||
|
"navType": "vertical",
|
||||||
|
"theme": "Cerulean",
|
||||||
|
"linenums": true,
|
||||||
|
"collapseSymbols": true,
|
||||||
|
"inverseNav": true,
|
||||||
|
"protocol": "html://",
|
||||||
|
"methodHeadingReturns": true
|
||||||
|
},
|
||||||
|
"opts": {
|
||||||
|
"destination": "./docs/docs/",
|
||||||
|
"encoding": "utf8",
|
||||||
|
"private": true,
|
||||||
|
"recurse": true,
|
||||||
|
"sort": false,
|
||||||
|
"template": "./node_modules/ink-docstrap/template"
|
||||||
|
}
|
||||||
|
}
|
||||||
17084
package-lock.json
generated
Normal file
17084
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
51
package.json
Normal file
51
package.json
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
{
|
||||||
|
"name": "YJEarth-JSSDK",
|
||||||
|
"version": "2.5.0",
|
||||||
|
"main": "build/YJEarth.min.js",
|
||||||
|
"author": "",
|
||||||
|
"license": "",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1",
|
||||||
|
"dev": "yarn run clean && cross-env DZ=xj webpack --mode development ",
|
||||||
|
"build": "yarn run clean && cross-env DZ=xj webpack --mode production --env.production ",
|
||||||
|
"minami-3Ddoc": "jsdoc -c ink-docstrap.json ",
|
||||||
|
"clean": "rimraf build/"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@babel/core": "^7.4.0",
|
||||||
|
"@babel/plugin-proposal-class-properties": "^7.18.6",
|
||||||
|
"@babel/plugin-proposal-decorators": "^7.25.9",
|
||||||
|
"@babel/plugin-proposal-export-namespace-from": "^7.0.0",
|
||||||
|
"@babel/plugin-proposal-function-sent": "^7.0.0",
|
||||||
|
"@babel/plugin-proposal-json-strings": "^7.0.0",
|
||||||
|
"@babel/plugin-proposal-numeric-separator": "^7.0.0",
|
||||||
|
"@babel/plugin-proposal-throw-expressions": "^7.0.0",
|
||||||
|
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
|
||||||
|
"@babel/plugin-syntax-import-meta": "^7.0.0",
|
||||||
|
"@babel/plugin-transform-runtime": "^7.4.0",
|
||||||
|
"@babel/polyfill": "^7.4.0",
|
||||||
|
"@babel/preset-env": "^7.4.2",
|
||||||
|
"babel-eslint": "^10.0.1",
|
||||||
|
"babel-loader": "^8.0.5",
|
||||||
|
"copy-webpack-plugin": "^5.0.0",
|
||||||
|
"cross-env": "^7.0.3",
|
||||||
|
"eslint": "^5.15.3",
|
||||||
|
"eslint-config-prettier": "^4.1.0",
|
||||||
|
"eslint-plugin-import": "^2.16.0",
|
||||||
|
"eslint-plugin-node": "^8.0.1",
|
||||||
|
"eslint-plugin-prettier": "^3.0.1",
|
||||||
|
"eslint-plugin-promise": "^4.0.1",
|
||||||
|
"ink-docstrap": "^1.3.2",
|
||||||
|
"jsdoc": "^3.6.7",
|
||||||
|
"prettier": "^1.16.4",
|
||||||
|
"rimraf": "^2.6.3",
|
||||||
|
"webpack": "^4.29.6",
|
||||||
|
"webpack-cli": "^3.3.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"caniuse-lite": "^1.0.30001663",
|
||||||
|
"child_process": "^1.0.2",
|
||||||
|
"js-md5": "^0.7.3",
|
||||||
|
"url-loader": "^4.1.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
204
src/BaseDialog/index.js
Normal file
204
src/BaseDialog/index.js
Normal file
@ -0,0 +1,204 @@
|
|||||||
|
class BaseDialog {
|
||||||
|
constructor(container, options = {}) {
|
||||||
|
this.container = container
|
||||||
|
this.options = { ...options }
|
||||||
|
this.options.ismove = true
|
||||||
|
if(options.ismove === false) {
|
||||||
|
this.options.ismove = options.ismove
|
||||||
|
}
|
||||||
|
this.closeCallBack = options.closeCallBack
|
||||||
|
this._element = {}
|
||||||
|
this._element_style = undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
async init() {
|
||||||
|
|
||||||
|
this.closeAll()
|
||||||
|
DialogAll.push(this)
|
||||||
|
this.isDestroy = false
|
||||||
|
// body
|
||||||
|
this._element.body = document.createElement('div');
|
||||||
|
this._element.body.className = 'YJ-custom-base-dialog';
|
||||||
|
this._element.body.style.top = this.options.top
|
||||||
|
this._element.body.style.bottom = this.options.bottom
|
||||||
|
this._element.body.style.left = this.options.left
|
||||||
|
this._element.body.style.right = this.options.right
|
||||||
|
this.container.appendChild(this._element.body)
|
||||||
|
|
||||||
|
//title
|
||||||
|
this._element.title = document.createElement('div');
|
||||||
|
this._element.title.className = 'title-box';
|
||||||
|
this._element.title.innerHTML = `<span class="title">${(this.options.title || '')}</span>` + `<span class="close-box"><span class="close"></span><i>✕</i></span>`
|
||||||
|
this._element.body.appendChild(this._element.title)
|
||||||
|
|
||||||
|
//content
|
||||||
|
this._element.content = await document.createElement('div');
|
||||||
|
this._element.content.className = 'content';
|
||||||
|
this._element.body.appendChild(this._element.content)
|
||||||
|
|
||||||
|
// foot
|
||||||
|
this._element.foot = await document.createElement('div');
|
||||||
|
this._element.foot.className = 'foot';
|
||||||
|
// this._element.foot.innerHTML = `
|
||||||
|
// <button class="translational">平移</button>
|
||||||
|
// <button class="resetting">重置</button>
|
||||||
|
// <button class="delete">删除</button>
|
||||||
|
// <button class="close">关闭</button>
|
||||||
|
// `
|
||||||
|
this._element.foot.innerHTML = `
|
||||||
|
<button class="close">关闭</button>
|
||||||
|
`
|
||||||
|
this._element.body.appendChild(this._element.foot)
|
||||||
|
|
||||||
|
// 关闭
|
||||||
|
let closeBtnsBox = this._element.body.getElementsByClassName('close-box')[0];
|
||||||
|
closeBtnsBox.addEventListener('click', () => {
|
||||||
|
this.close()
|
||||||
|
});
|
||||||
|
let closeBtns = this._element.body.getElementsByClassName('close');
|
||||||
|
for (let i = 0; i < closeBtns.length; i++) {
|
||||||
|
closeBtns[i].addEventListener('click', () => {
|
||||||
|
this.close()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this.options.ismove) {
|
||||||
|
this.moveDiv()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
close() {
|
||||||
|
let styles = document.getElementsByTagName("style")
|
||||||
|
for (let i = styles.length - 1; i >= 0; i--) {
|
||||||
|
if (styles[i].dataset) {
|
||||||
|
if (styles[i].dataset.name === 'YJ_style_dialog') {
|
||||||
|
document.getElementsByTagName('head')[0].removeChild(styles[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this._element.body && this._element.body.parentNode) {
|
||||||
|
this.container.removeChild(this._element.body)
|
||||||
|
}
|
||||||
|
this._element.body = null
|
||||||
|
this._element.title = null
|
||||||
|
this._element.content = null
|
||||||
|
this._element.foot = null
|
||||||
|
this._element_style = null
|
||||||
|
this.isDestroy = true
|
||||||
|
if (this.closeCallBack) {
|
||||||
|
this.closeCallBack()
|
||||||
|
this.closeCallBack = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
closeAll() {
|
||||||
|
for(let i=DialogAll.length-1;i>=0;i--) {
|
||||||
|
DialogAll[i].close()
|
||||||
|
DialogAll.splice(i, 1)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
let styles = document.getElementsByTagName("style")
|
||||||
|
for (let i = styles.length - 1; i >= 0; i--) {
|
||||||
|
if (styles[i].dataset) {
|
||||||
|
if (styles[i].dataset.name === 'YJ_style_dialog') {
|
||||||
|
document.getElementsByTagName('head')[0].removeChild(styles[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this._element_style) {
|
||||||
|
this._element_style = null
|
||||||
|
}
|
||||||
|
let elms = this.container.getElementsByClassName('YJ-custom-base-dialog')
|
||||||
|
for (let i = elms.length - 1; i >= 0; i--) {
|
||||||
|
this.container.removeChild(elms[i])
|
||||||
|
}
|
||||||
|
this._element.body = null
|
||||||
|
this._element.title = null
|
||||||
|
this._element.content = null
|
||||||
|
this._element.foot = null
|
||||||
|
}
|
||||||
|
|
||||||
|
titleAppChild(node) {
|
||||||
|
this._element.title.appendChild(node)
|
||||||
|
}
|
||||||
|
contentAppChild(node) {
|
||||||
|
this._element.content.appendChild(node)
|
||||||
|
}
|
||||||
|
footAppChild(node, target) {
|
||||||
|
if (target) {
|
||||||
|
this._element.foot.insertBefore(node, target);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this._element.foot.prepend(node)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
moveDiv() {
|
||||||
|
let x = 0
|
||||||
|
let y = 0
|
||||||
|
let l = 0
|
||||||
|
let t = 0
|
||||||
|
let oClickDiv = this._element.body
|
||||||
|
let _this = this
|
||||||
|
oClickDiv.onmousedown = (e) => {
|
||||||
|
if (e.toElement.className !== 'title-box') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// dialog的宽度、高度
|
||||||
|
// let oMoveDivHeight = that.oMoveDiv.offsetHeight
|
||||||
|
let oMoveDivHeight = this._element.body.offsetHeight
|
||||||
|
// let oMoveDivWidth = that.oMoveDiv.offsetWidth
|
||||||
|
let oMoveDivWidth = this._element.body.offsetWidth
|
||||||
|
|
||||||
|
x = e.clientX
|
||||||
|
y = e.clientY
|
||||||
|
|
||||||
|
let leftPx = window.getComputedStyle(this._element.body).left
|
||||||
|
let topPx = window.getComputedStyle(this._element.body).top
|
||||||
|
|
||||||
|
l = leftPx.substr(0, leftPx.indexOf('px')) * 1
|
||||||
|
t = topPx.substr(0, topPx.indexOf('px')) * 1
|
||||||
|
// 视口大小
|
||||||
|
let windowHeight = document.documentElement.clientHeight
|
||||||
|
let windowWidth = document.documentElement.clientWidth
|
||||||
|
|
||||||
|
//鼠标移动
|
||||||
|
window.onmousemove = function (e) {
|
||||||
|
e.preventDefault()
|
||||||
|
//获取x和y
|
||||||
|
let nx = e.clientX
|
||||||
|
let ny = e.clientY
|
||||||
|
//计算移动后的左偏移量和顶部的偏移量
|
||||||
|
let leftPx = nx - (x - l)
|
||||||
|
let topPx = ny - (y - t)
|
||||||
|
if (leftPx < 0) {
|
||||||
|
leftPx = 0
|
||||||
|
} else if (leftPx + oMoveDivWidth > windowWidth) {
|
||||||
|
leftPx = windowWidth - oMoveDivWidth
|
||||||
|
}
|
||||||
|
|
||||||
|
if (topPx <= 0) {
|
||||||
|
topPx = 0
|
||||||
|
} else if (topPx + oMoveDivHeight > windowHeight) {
|
||||||
|
topPx = windowHeight - oMoveDivHeight
|
||||||
|
}
|
||||||
|
_this._element.body.style.left = leftPx + 'px'
|
||||||
|
_this._element.body.style.top = topPx + 'px'
|
||||||
|
_this._element.body.style.bottom = 'unset'
|
||||||
|
_this._element.body.style.right = 'unset'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//鼠标抬起事件
|
||||||
|
document.onmouseup = function (e) {
|
||||||
|
window.onmousemove = null
|
||||||
|
}
|
||||||
|
window.ondragend = function (e) {
|
||||||
|
window.onmousemove = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let DialogAll = []
|
||||||
|
|
||||||
|
export default BaseDialog
|
||||||
35
src/BaseDialog/rule.js
Normal file
35
src/BaseDialog/rule.js
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
function check(elm, rule) {
|
||||||
|
let input = elm.getElementsByTagName('input')[0]
|
||||||
|
rules[rule.validator](input, rule.trigger, (s, error) => {
|
||||||
|
if (s) {
|
||||||
|
elm.className = 'input-box'
|
||||||
|
let eElm = elm.getElementsByClassName('input-error-text')[0]
|
||||||
|
if(eElm) {
|
||||||
|
elm.removeChild(eElm)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
elm.className = 'input-box error'
|
||||||
|
let e = rule.message || error
|
||||||
|
let eElm = document.createElement('span');
|
||||||
|
eElm.className = 'input-error-text'
|
||||||
|
eElm.innerHTML = e
|
||||||
|
elm.appendChild(eElm)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const rules = {
|
||||||
|
notEmpty: (input, trigger, cd) => {
|
||||||
|
input.addEventListener(trigger, ()=>{
|
||||||
|
if (input.value) {
|
||||||
|
cd(true)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
cd(false, '不能为空!')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export { check }
|
||||||
905
src/Controller/index.js
Normal file
905
src/Controller/index.js
Normal file
@ -0,0 +1,905 @@
|
|||||||
|
/**
|
||||||
|
* @description 平移旋转-改
|
||||||
|
*/
|
||||||
|
import MouseEvent from '../Event'
|
||||||
|
class ControllerObject {
|
||||||
|
constructor(sdk, options = {}) {
|
||||||
|
this.sdk = sdk
|
||||||
|
this.viwer = this.sdk.viewer
|
||||||
|
this.options = options
|
||||||
|
this.options.position = options.position || {}
|
||||||
|
this.options.rotate = options.rotate || {}
|
||||||
|
this.options.position.lng = this.options.position.lng || 0
|
||||||
|
this.options.position.lat = this.options.position.lat || 0
|
||||||
|
this.options.position.alt = this.options.position.alt || 0
|
||||||
|
this.options.rotate.x = this.options.rotate.x || 0
|
||||||
|
this.options.rotate.y = this.options.rotate.y || 0
|
||||||
|
this.options.rotate.z = this.options.rotate.z || 0
|
||||||
|
this.activeAxis
|
||||||
|
this.activeCircle
|
||||||
|
this.activeModelParam
|
||||||
|
this.origin
|
||||||
|
this.rayX
|
||||||
|
this.rayY
|
||||||
|
this.rayZ
|
||||||
|
this.arrow = {}
|
||||||
|
this.activeState
|
||||||
|
this.coordArrows = []
|
||||||
|
this.coordCircles = []
|
||||||
|
|
||||||
|
this.MapEvent = new MouseEvent(this.sdk)
|
||||||
|
}
|
||||||
|
|
||||||
|
get position() {
|
||||||
|
return this.options.position
|
||||||
|
}
|
||||||
|
set position(v) {
|
||||||
|
this.options.position = v
|
||||||
|
this.againArrow()
|
||||||
|
this.againCircle()
|
||||||
|
}
|
||||||
|
|
||||||
|
get rotate() {
|
||||||
|
return this.options.rotate
|
||||||
|
}
|
||||||
|
set rotate(v) {
|
||||||
|
this.options.rotate = v
|
||||||
|
}
|
||||||
|
|
||||||
|
initParam() {
|
||||||
|
this._params = {
|
||||||
|
tx: this.options.position.lng, //模型中心X轴坐标(经度,单位:十进制度)
|
||||||
|
ty: this.options.position.lat, //模型中心Y轴坐标(纬度,单位:十进制度)
|
||||||
|
tz: this.options.position.alt, //模型中心Z轴坐标(高程,单位:米)
|
||||||
|
rx: this.options.rotate.x, //X轴(经度)方向旋转角度(单位:度)
|
||||||
|
ry: this.options.rotate.y, //Y轴(纬度)方向旋转角度(单位:度)
|
||||||
|
rz: this.options.rotate.z //Z轴(高程)方向旋转角度(单位:度)
|
||||||
|
}
|
||||||
|
return { ...this.options.position, ...this.options.rotate }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开始编辑平移
|
||||||
|
*/
|
||||||
|
async editTranslational() {
|
||||||
|
this.destroy()
|
||||||
|
this.activeState = 'translational'
|
||||||
|
this.MapEvent = new MouseEvent(this.sdk)
|
||||||
|
// this.viwer.scene.camera.flyTo({
|
||||||
|
// destination: new Cesium.Cartesian3.fromDegrees(104.17401, 30.63593, 1000),
|
||||||
|
// orientation: {
|
||||||
|
// pitch: Cesium.Math.toRadians(-35.0)
|
||||||
|
// },
|
||||||
|
// duration: 1
|
||||||
|
// })
|
||||||
|
/**
|
||||||
|
* 创建一条射线
|
||||||
|
*/
|
||||||
|
let _this = this
|
||||||
|
let param = this.initParam()
|
||||||
|
let lng = param.lng
|
||||||
|
let lat = param.lat
|
||||||
|
let h = param.alt
|
||||||
|
let viewer = this.viwer
|
||||||
|
// let lon = 104.17401
|
||||||
|
// let lat = 30.64593
|
||||||
|
// let h = 0
|
||||||
|
// 原点
|
||||||
|
this.origin = Cesium.Cartesian3.fromDegrees(lng, lat, h)
|
||||||
|
// 计算xyz轴方向
|
||||||
|
const directionVectorX = Cesium.Cartesian3.normalize(Cesium.Cartesian3.subtract(this.origin, Cesium.Cartesian3.fromDegrees(lng - 0.001, lat, h), new Cesium.Cartesian3()), new Cesium.Cartesian3());
|
||||||
|
const directionVectorY = Cesium.Cartesian3.normalize(Cesium.Cartesian3.subtract(this.origin, Cesium.Cartesian3.fromDegrees(lng, lat - 0.001, h), new Cesium.Cartesian3()), new Cesium.Cartesian3());
|
||||||
|
const directionVectorZ = Cesium.Cartesian3.normalize(Cesium.Cartesian3.subtract(this.origin, Cesium.Cartesian3.fromDegrees(lng, lat, h - 1), new Cesium.Cartesian3()), new Cesium.Cartesian3());
|
||||||
|
this.rayX = new Cesium.Ray(this.origin, directionVectorX)
|
||||||
|
this.rayY = new Cesium.Ray(this.origin, directionVectorY)
|
||||||
|
this.rayZ = new Cesium.Ray(this.origin, directionVectorZ)
|
||||||
|
this.arrow.positionX = Cesium.Ray.getPoint(this.rayX, 0)
|
||||||
|
this.arrow.positionY = Cesium.Ray.getPoint(this.rayY, 0)
|
||||||
|
this.arrow.positionZ = Cesium.Ray.getPoint(this.rayZ, 0)
|
||||||
|
|
||||||
|
const matrix = Cesium.Transforms.eastNorthUpToFixedFrame(
|
||||||
|
new Cesium.Cartesian3.fromDegrees(lng, lat, h)
|
||||||
|
)
|
||||||
|
// 获取相机的位置
|
||||||
|
var cameraPosition = viewer.camera.position;
|
||||||
|
// 计算相机与目标坐标之间的距离
|
||||||
|
var distance = Cesium.Cartesian3.distance(cameraPosition, this.origin);
|
||||||
|
let newRadius = distance / 15
|
||||||
|
let scale = newRadius
|
||||||
|
Cesium.Matrix4.multiplyByScale(matrix, new Cesium.Cartesian3(scale, scale, scale), matrix)
|
||||||
|
let axisArrowX = this.createAxisArrow('model_edit_xAxis', [new Cesium.Cartesian3(0, 0.001, 0), new Cesium.Cartesian3(1, 0, 0)], matrix, Cesium.Color.RED)
|
||||||
|
let axisArrowY = this.createAxisArrow('model_edit_yAxis', [new Cesium.Cartesian3(0, 0.001, 0), new Cesium.Cartesian3(0, 1, 0)], matrix, Cesium.Color.LIME)
|
||||||
|
let axisArrowZ = this.createAxisArrow('model_edit_zAxis', [new Cesium.Cartesian3(0, 0.001, 0), new Cesium.Cartesian3(0, 0, 1)], matrix, Cesium.Color.BLUE)
|
||||||
|
let positions = []
|
||||||
|
let radius = 1
|
||||||
|
// for (let i = 0; i <= 360; i += 3) {
|
||||||
|
// const sin = Math.sin(Cesium.Math.toRadians(i))
|
||||||
|
// const cos = Math.cos(Cesium.Math.toRadians(i))
|
||||||
|
// const x = radius * cos
|
||||||
|
// const y = radius * sin
|
||||||
|
// positions.push(new Cesium.Cartesian3(x, y, 0))
|
||||||
|
// }
|
||||||
|
// console.log('positions', positions)
|
||||||
|
// let axisCircular = this.createAxisCircular('model_edit_circular', positions, matrix)
|
||||||
|
this.viwer.scene.primitives.add(axisArrowX)
|
||||||
|
this.viwer.scene.primitives.add(axisArrowY)
|
||||||
|
this.viwer.scene.primitives.add(axisArrowZ)
|
||||||
|
// this.viwer.scene.primitives.add(axisCircular)
|
||||||
|
|
||||||
|
this.againArrow()
|
||||||
|
|
||||||
|
// this.viwer.entities.add({
|
||||||
|
// id: "tool-position_plane_xy",
|
||||||
|
// rectangle: {
|
||||||
|
// coordinates: new Cesium.CallbackProperty(function () {
|
||||||
|
// return Cesium.Rectangle.fromCartesianArray([positionX, positionY])
|
||||||
|
// }, false),
|
||||||
|
// material: Cesium.Color.YELLOW.withAlpha(0),
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
|
||||||
|
// 监听相机移动
|
||||||
|
this.viwer.camera.percentageChanged = 0.001
|
||||||
|
this.viwer.camera.changed.addEventListener(this.againArrow, { _that: this });
|
||||||
|
|
||||||
|
let coordinatesDiffer = { x: 0, y: 0 }
|
||||||
|
let lastPickTime = 0;
|
||||||
|
let timeoutEvent
|
||||||
|
this.MapEvent.mouse_move((e, cartesian) => {
|
||||||
|
moveEvent(e)
|
||||||
|
})
|
||||||
|
function moveEvent(movement) {
|
||||||
|
if (!_this.activeAxis) {
|
||||||
|
const now = Date.now();
|
||||||
|
if (now - lastPickTime < 100) {
|
||||||
|
clearTimeout(timeoutEvent)
|
||||||
|
timeoutEvent = setTimeout(() => {
|
||||||
|
moveEvent(movement)
|
||||||
|
}, 100);
|
||||||
|
return
|
||||||
|
}
|
||||||
|
clearTimeout(timeoutEvent)
|
||||||
|
lastPickTime = now;
|
||||||
|
let primitives = _this.coordArrows
|
||||||
|
for (let i = 0; i < primitives.length; i++) {
|
||||||
|
if (primitives[i].getGeometryInstanceAttributes) {
|
||||||
|
switch (primitives[i]._name) {
|
||||||
|
case 'model_edit_xAxis':
|
||||||
|
primitives[i].appearance = new Cesium.PolylineMaterialAppearance({
|
||||||
|
material: Cesium.Material.fromType(Cesium.Material.PolylineArrowType, {
|
||||||
|
color: Cesium.Color.RED,
|
||||||
|
}),
|
||||||
|
translucent: true,
|
||||||
|
renderState: {
|
||||||
|
depthTest: {
|
||||||
|
enabled: false,
|
||||||
|
},
|
||||||
|
depthMask: false,
|
||||||
|
depthFunction: Cesium.DepthFunction.ALWAYS,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
break;
|
||||||
|
case 'model_edit_yAxis':
|
||||||
|
primitives[i].appearance = new Cesium.PolylineMaterialAppearance({
|
||||||
|
material: Cesium.Material.fromType(Cesium.Material.PolylineArrowType, {
|
||||||
|
color: Cesium.Color.LIME,
|
||||||
|
}),
|
||||||
|
translucent: true,
|
||||||
|
renderState: {
|
||||||
|
depthTest: {
|
||||||
|
enabled: false,
|
||||||
|
},
|
||||||
|
depthMask: false,
|
||||||
|
depthFunction: Cesium.DepthFunction.ALWAYS,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
break;
|
||||||
|
case 'model_edit_zAxis':
|
||||||
|
primitives[i].appearance = new Cesium.PolylineMaterialAppearance({
|
||||||
|
material: Cesium.Material.fromType(Cesium.Material.PolylineArrowType, {
|
||||||
|
color: Cesium.Color.BLUE,
|
||||||
|
}),
|
||||||
|
translucent: true,
|
||||||
|
renderState: {
|
||||||
|
depthTest: {
|
||||||
|
enabled: false,
|
||||||
|
},
|
||||||
|
depthMask: false,
|
||||||
|
depthFunction: Cesium.DepthFunction.ALWAYS,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let pickedObjectArray = _this.viwer.scene.drillPick(movement.endPosition, 10);
|
||||||
|
for (let i = pickedObjectArray.length - 1; i >= 0; i--) {
|
||||||
|
let pick = pickedObjectArray[i]
|
||||||
|
if (pick && pick.primitive && pick.id) {
|
||||||
|
switch (pick.primitive._name) {
|
||||||
|
case 'model_edit_xAxis':
|
||||||
|
case 'model_edit_yAxis':
|
||||||
|
case 'model_edit_zAxis':
|
||||||
|
pick.primitive.appearance = new Cesium.PolylineMaterialAppearance({
|
||||||
|
material: Cesium.Material.fromType(Cesium.Material.PolylineArrowType, {
|
||||||
|
color: Cesium.Color.YELLOW,
|
||||||
|
}),
|
||||||
|
translucent: true,
|
||||||
|
renderState: {
|
||||||
|
depthTest: {
|
||||||
|
enabled: false,
|
||||||
|
},
|
||||||
|
depthMask: false,
|
||||||
|
depthFunction: Cesium.DepthFunction.ALWAYS,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
return
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
let y = movement.startPosition.y - movement.endPosition.y //负数往下
|
||||||
|
|
||||||
|
let endPosition = { x: movement.endPosition.x - coordinatesDiffer.x, y: movement.endPosition.y - coordinatesDiffer.y }
|
||||||
|
let ray = viewer.camera.getPickRay(endPosition);//获取一条射线
|
||||||
|
let position = viewer.scene.globe.pick(ray, viewer.scene);
|
||||||
|
let finalPosition = new Cesium.Cartesian3();
|
||||||
|
let matrix4 = Cesium.Transforms.eastNorthUpToFixedFrame(viewer.camera.position);
|
||||||
|
Cesium.Matrix4.inverse(matrix4, matrix4);
|
||||||
|
Cesium.Matrix4.multiplyByPoint(matrix4, position, finalPosition);
|
||||||
|
Cesium.Cartesian3.normalize(finalPosition, finalPosition);
|
||||||
|
let param = _this.initParam()
|
||||||
|
let pitch = 90 + Cesium.Math.toDegrees(Math.asin(finalPosition.z))
|
||||||
|
let camera_cartographic = Cesium.Cartographic.fromCartesian(viewer.camera.position);
|
||||||
|
let a = camera_cartographic.height
|
||||||
|
let b = _this.activeModelParam.alt
|
||||||
|
// let d = Cesium.Cartesian3.distance(viewer.camera.position, position);
|
||||||
|
let d = a / Math.cos(Cesium.Math.toRadians(pitch))
|
||||||
|
let geodesic = new Cesium.EllipsoidGeodesic(Cesium.Cartographic.fromCartesian(position), Cesium.Cartographic.fromCartesian(viewer.camera.position))
|
||||||
|
|
||||||
|
position = Cesium.Ray.getPoint(ray, d * (1 - (b / a)))
|
||||||
|
let cartographic = Cesium.Cartographic.fromCartesian(position);
|
||||||
|
let lng = Cesium.Math.toDegrees(cartographic.longitude); // 经度
|
||||||
|
let lat = Cesium.Math.toDegrees(cartographic.latitude); // 纬度
|
||||||
|
let m
|
||||||
|
switch (_this.activeAxis._name) {
|
||||||
|
case 'model_edit_xAxis':
|
||||||
|
_this._params.tx = lng
|
||||||
|
_this._params.ty = _this.activeModelParam.lat
|
||||||
|
_this._params.tz = b
|
||||||
|
|
||||||
|
_this.origin = Cesium.Cartesian3.fromDegrees(param.lng, param.lat, param.alt)
|
||||||
|
// 计算xyz轴方向
|
||||||
|
const directionVectorX = Cesium.Cartesian3.normalize(Cesium.Cartesian3.subtract(_this.origin, Cesium.Cartesian3.fromDegrees(param.lng - 0.001, param.lat, param.alt), new Cesium.Cartesian3()), new Cesium.Cartesian3());
|
||||||
|
const directionVectorY = Cesium.Cartesian3.normalize(Cesium.Cartesian3.subtract(_this.origin, Cesium.Cartesian3.fromDegrees(param.lng, param.lat - 0.001, param.alt), new Cesium.Cartesian3()), new Cesium.Cartesian3());
|
||||||
|
const directionVectorZ = Cesium.Cartesian3.normalize(Cesium.Cartesian3.subtract(_this.origin, Cesium.Cartesian3.fromDegrees(param.lng, param.lat, param.alt - 1), new Cesium.Cartesian3()), new Cesium.Cartesian3());
|
||||||
|
_this.rayX = new Cesium.Ray(_this.origin, directionVectorX)
|
||||||
|
_this.rayY = new Cesium.Ray(_this.origin, directionVectorY)
|
||||||
|
_this.rayZ = new Cesium.Ray(_this.origin, directionVectorZ)
|
||||||
|
break
|
||||||
|
case 'model_edit_yAxis':
|
||||||
|
_this._params.tx = _this.activeModelParam.lng
|
||||||
|
_this._params.ty = lat
|
||||||
|
_this._params.tz = b
|
||||||
|
_this.origin = Cesium.Cartesian3.fromDegrees(param.lng, param.lat, param.alt)
|
||||||
|
// 计算xyz轴方向
|
||||||
|
const directionVectorX2 = Cesium.Cartesian3.normalize(Cesium.Cartesian3.subtract(_this.origin, Cesium.Cartesian3.fromDegrees(param.lng - 0.001, param.lat, param.alt), new Cesium.Cartesian3()), new Cesium.Cartesian3());
|
||||||
|
const directionVectorY2 = Cesium.Cartesian3.normalize(Cesium.Cartesian3.subtract(_this.origin, Cesium.Cartesian3.fromDegrees(param.lng, param.lat - 0.001, param.alt), new Cesium.Cartesian3()), new Cesium.Cartesian3());
|
||||||
|
const directionVectorZ2 = Cesium.Cartesian3.normalize(Cesium.Cartesian3.subtract(_this.origin, Cesium.Cartesian3.fromDegrees(param.lng, param.lat, param.alt - 1), new Cesium.Cartesian3()), new Cesium.Cartesian3());
|
||||||
|
_this.rayX = new Cesium.Ray(_this.origin, directionVectorX2)
|
||||||
|
_this.rayY = new Cesium.Ray(_this.origin, directionVectorY2)
|
||||||
|
_this.rayZ = new Cesium.Ray(_this.origin, directionVectorZ2)
|
||||||
|
break
|
||||||
|
case 'model_edit_zAxis':
|
||||||
|
_this.activeModelParam.alt += (Cesium.Cartesian3.distance(viewer.camera.position, Cesium.Cartesian3.fromDegrees(_this.options.position.lng, _this.options.position.lat, _this.options.position.alt)) / 4300) * y * 3
|
||||||
|
_this._params.tx = _this.activeModelParam.lng
|
||||||
|
_this._params.ty = _this.activeModelParam.lat
|
||||||
|
_this._params.tz = _this.activeModelParam.alt
|
||||||
|
_this.origin = Cesium.Cartesian3.fromDegrees(param.lng, param.lat, _this.activeModelParam.alt)
|
||||||
|
// 计算xyz轴方向
|
||||||
|
const directionVectorX3 = Cesium.Cartesian3.normalize(Cesium.Cartesian3.subtract(_this.origin, Cesium.Cartesian3.fromDegrees(param.lng - 0.001, param.lat, _this.activeModelParam.alt), new Cesium.Cartesian3()), new Cesium.Cartesian3());
|
||||||
|
const directionVectorY3 = Cesium.Cartesian3.normalize(Cesium.Cartesian3.subtract(_this.origin, Cesium.Cartesian3.fromDegrees(param.lng, param.lat - 0.001, _this.activeModelParam.alt), new Cesium.Cartesian3()), new Cesium.Cartesian3());
|
||||||
|
const directionVectorZ3 = Cesium.Cartesian3.normalize(Cesium.Cartesian3.subtract(_this.origin, Cesium.Cartesian3.fromDegrees(param.lng, param.lat, _this.activeModelParam.alt - 1), new Cesium.Cartesian3()), new Cesium.Cartesian3());
|
||||||
|
_this.rayX = new Cesium.Ray(_this.origin, directionVectorX3)
|
||||||
|
_this.rayY = new Cesium.Ray(_this.origin, directionVectorY3)
|
||||||
|
_this.rayZ = new Cesium.Ray(_this.origin, directionVectorZ3)
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
_this.updateModel(_this._params.tx, _this._params.ty, _this._params.tz, _this._params.rx, _this._params.ry, _this._params.rz)
|
||||||
|
_this.againArrow()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.MapEvent.mouse_left_down((event, cartesian) => {
|
||||||
|
let canvasCoordinates = viewer.scene.cartesianToCanvasCoordinates(this.origin)
|
||||||
|
coordinatesDiffer.x = event.position.x - Math.floor(canvasCoordinates.x)
|
||||||
|
coordinatesDiffer.y = event.position.y - Math.floor(canvasCoordinates.y)
|
||||||
|
let pickedObjectArray = viewer.scene.drillPick(event.position, 10);
|
||||||
|
for (let i = pickedObjectArray.length - 1; i >= 0; i--) {
|
||||||
|
let pickedObject = pickedObjectArray[i]
|
||||||
|
if (pickedObject && pickedObject.primitive && pickedObject.primitive._name) {
|
||||||
|
if (_this.activeAxis) {
|
||||||
|
_this.activeAxis = null
|
||||||
|
_this.activeModelParam = null
|
||||||
|
_this.controllerCallBack
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
switch (pickedObject.primitive._name) {
|
||||||
|
case 'model_edit_xAxis':
|
||||||
|
case 'model_edit_yAxis':
|
||||||
|
case 'model_edit_zAxis':
|
||||||
|
viewer.scene.screenSpaceCameraController.enableRotate = false;
|
||||||
|
_this.activeAxis = pickedObject.primitive
|
||||||
|
_this.activeModelParam = _this.initParam()
|
||||||
|
pickedObject.primitive.appearance = new Cesium.PolylineMaterialAppearance({
|
||||||
|
material: Cesium.Material.fromType(Cesium.Material.PolylineArrowType, {
|
||||||
|
color: Cesium.Color.YELLOW,
|
||||||
|
}),
|
||||||
|
translucent: true,
|
||||||
|
renderState: {
|
||||||
|
depthTest: {
|
||||||
|
enabled: false,
|
||||||
|
},
|
||||||
|
depthMask: false,
|
||||||
|
depthFunction: Cesium.DepthFunction.ALWAYS,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.MapEvent.mouse_left_up((event) => {
|
||||||
|
viewer.scene.screenSpaceCameraController.enableRotate = true;
|
||||||
|
for (let i = 0; i < _this.coordArrows.length; i++) {
|
||||||
|
switch (_this.coordArrows[i]._name) {
|
||||||
|
case 'model_edit_xAxis':
|
||||||
|
_this.coordArrows[i].appearance = new Cesium.PolylineMaterialAppearance({
|
||||||
|
material: Cesium.Material.fromType(Cesium.Material.PolylineArrowType, {
|
||||||
|
color: Cesium.Color.RED,
|
||||||
|
}),
|
||||||
|
translucent: true,
|
||||||
|
renderState: {
|
||||||
|
depthTest: {
|
||||||
|
enabled: false,
|
||||||
|
},
|
||||||
|
depthMask: false,
|
||||||
|
depthFunction: Cesium.DepthFunction.ALWAYS,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
break;
|
||||||
|
case 'model_edit_yAxis':
|
||||||
|
_this.coordArrows[i].appearance = new Cesium.PolylineMaterialAppearance({
|
||||||
|
material: Cesium.Material.fromType(Cesium.Material.PolylineArrowType, {
|
||||||
|
color: Cesium.Color.LIME,
|
||||||
|
}),
|
||||||
|
translucent: true,
|
||||||
|
renderState: {
|
||||||
|
depthTest: {
|
||||||
|
enabled: false,
|
||||||
|
},
|
||||||
|
depthMask: false,
|
||||||
|
depthFunction: Cesium.DepthFunction.ALWAYS,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
break;
|
||||||
|
case 'model_edit_zAxis':
|
||||||
|
_this.coordArrows[i].appearance = new Cesium.PolylineMaterialAppearance({
|
||||||
|
material: Cesium.Material.fromType(Cesium.Material.PolylineArrowType, {
|
||||||
|
color: Cesium.Color.BLUE,
|
||||||
|
}),
|
||||||
|
translucent: true,
|
||||||
|
renderState: {
|
||||||
|
depthTest: {
|
||||||
|
enabled: false,
|
||||||
|
},
|
||||||
|
depthMask: false,
|
||||||
|
depthFunction: Cesium.DepthFunction.ALWAYS,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (_this.activeAxis) {
|
||||||
|
_this.activeAxis = null
|
||||||
|
_this.activeModelParam = null
|
||||||
|
_this.controllerCallBack
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重新计算箭头位置
|
||||||
|
againArrow() {
|
||||||
|
let _that = (this._that || this)
|
||||||
|
if (!_that.origin) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_that.initParam()
|
||||||
|
_that.origin = new Cesium.Cartesian3.fromDegrees(_that._params.tx, _that._params.ty, _that._params.tz)
|
||||||
|
let viewer = _that.viwer
|
||||||
|
// 获取相机的位置
|
||||||
|
var cameraPosition = viewer.camera.position;
|
||||||
|
// 计算相机与目标坐标之间的距离
|
||||||
|
var distance = Cesium.Cartesian3.distance(cameraPosition, _that.origin);
|
||||||
|
let scale = distance / 15
|
||||||
|
const matrix = Cesium.Transforms.eastNorthUpToFixedFrame(_that.origin)
|
||||||
|
|
||||||
|
let primitives = _that.coordArrows
|
||||||
|
for (let i = 0; i < primitives.length; i++) {
|
||||||
|
switch (primitives[i]._name) {
|
||||||
|
case 'model_edit_xAxis':
|
||||||
|
case 'model_edit_yAxis':
|
||||||
|
case 'model_edit_zAxis':
|
||||||
|
Cesium.Matrix4.multiplyByScale(matrix, new Cesium.Cartesian3(scale, scale, scale), primitives[i].modelMatrix)
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//重新计算圆
|
||||||
|
againCircle() {
|
||||||
|
let _that = (this._that || this)
|
||||||
|
if (!_that.origin) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_that.initParam()
|
||||||
|
_that.origin = new Cesium.Cartesian3.fromDegrees(_that._params.tx, _that._params.ty, _that._params.tz)
|
||||||
|
let viewer = _that.viwer
|
||||||
|
// 获取相机的位置
|
||||||
|
var cameraPosition = viewer.camera.position;
|
||||||
|
// 计算相机与目标坐标之间的距离
|
||||||
|
var distance = Cesium.Cartesian3.distance(cameraPosition, _that.origin);
|
||||||
|
let radius = distance / 15
|
||||||
|
const matrix = Cesium.Transforms.eastNorthUpToFixedFrame(_that.origin)
|
||||||
|
let primitives = _that.coordCircles
|
||||||
|
for (let i = 0; i < primitives.length; i++) {
|
||||||
|
// _that.viwer.scene.primitives.lowerToBottom(primitives[i])
|
||||||
|
switch (primitives[i]._name) {
|
||||||
|
case 'model_edit_zCircle':
|
||||||
|
case 'model_edit_yCircle':
|
||||||
|
case 'model_edit_xCircle':
|
||||||
|
let scale = radius / 20
|
||||||
|
Cesium.Matrix4.multiplyByScale(matrix, new Cesium.Cartesian3(scale, scale, scale), primitives[i].modelMatrix)
|
||||||
|
primitives[i]._radius = radius
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开始旋转编辑
|
||||||
|
*/
|
||||||
|
async editRtation() {
|
||||||
|
this.destroy()
|
||||||
|
this.activeState = 'rtation'
|
||||||
|
this.MapEvent = new MouseEvent(this.sdk)
|
||||||
|
const param = this.initParam()
|
||||||
|
this.origin = Cesium.Cartesian3.fromDegrees(param.lng, param.lat, param.alt)
|
||||||
|
this.createCircle(
|
||||||
|
param.lng,
|
||||||
|
param.lat,
|
||||||
|
param.alt,
|
||||||
|
20
|
||||||
|
)
|
||||||
|
// 监听相机移动
|
||||||
|
this.viwer.camera.percentageChanged = 0.001
|
||||||
|
this.viwer.camera.changed.addEventListener(this.againCircle, { _that: this });
|
||||||
|
}
|
||||||
|
|
||||||
|
async createCircle(lng, lat, height, radius) {
|
||||||
|
let _that = (this._that || this)
|
||||||
|
let _this = this
|
||||||
|
let viewer = this.viwer
|
||||||
|
const position = []
|
||||||
|
for (let i = 0; i <= 360; i += 3) {
|
||||||
|
const sin = Math.sin(Cesium.Math.toRadians(i))
|
||||||
|
const cos = Math.cos(Cesium.Math.toRadians(i))
|
||||||
|
const x = radius * cos
|
||||||
|
const y = radius * sin
|
||||||
|
position.push(new Cesium.Cartesian3(x, y, 0))
|
||||||
|
}
|
||||||
|
const matrix = Cesium.Transforms.eastNorthUpToFixedFrame(
|
||||||
|
new Cesium.Cartesian3.fromDegrees(lng, lat, height)
|
||||||
|
)
|
||||||
|
// 获取相机的位置
|
||||||
|
var cameraPosition = viewer.camera.position;
|
||||||
|
// 计算相机与目标坐标之间的距离
|
||||||
|
var distance = Cesium.Cartesian3.distance(cameraPosition, this.origin);
|
||||||
|
let newRadius = distance / 15
|
||||||
|
let scale = newRadius / radius
|
||||||
|
Cesium.Matrix4.multiplyByScale(matrix, new Cesium.Cartesian3(scale, scale, scale), matrix)
|
||||||
|
// Cesium.Matrix4.multiply(
|
||||||
|
// matrix,
|
||||||
|
// x,
|
||||||
|
// matrix
|
||||||
|
// )
|
||||||
|
//绕Z轴
|
||||||
|
const axisSphereZ = await this.createAxisSphere(
|
||||||
|
'model_edit_zCircle',
|
||||||
|
position,
|
||||||
|
matrix,
|
||||||
|
Cesium.Color.RED,
|
||||||
|
newRadius
|
||||||
|
)
|
||||||
|
viewer.scene.primitives.add(axisSphereZ)
|
||||||
|
|
||||||
|
//绕Y周
|
||||||
|
const axisSphereY = await this.createAxisSphere(
|
||||||
|
'model_edit_yCircle',
|
||||||
|
position,
|
||||||
|
matrix,
|
||||||
|
Cesium.Color.BLUE,
|
||||||
|
newRadius
|
||||||
|
)
|
||||||
|
viewer.scene.primitives.add(axisSphereY)
|
||||||
|
let my = Cesium.Matrix3.fromRotationY(Cesium.Math.toRadians(90))
|
||||||
|
let rotationY = Cesium.Matrix4.fromRotationTranslation(my)
|
||||||
|
Cesium.Matrix4.multiply(
|
||||||
|
axisSphereY.geometryInstances.modelMatrix,
|
||||||
|
rotationY,
|
||||||
|
axisSphereY.geometryInstances.modelMatrix
|
||||||
|
)
|
||||||
|
|
||||||
|
//绕X周
|
||||||
|
const axisSphereX = await this.createAxisSphere(
|
||||||
|
'model_edit_xCircle',
|
||||||
|
position,
|
||||||
|
matrix,
|
||||||
|
Cesium.Color.LIME,
|
||||||
|
newRadius
|
||||||
|
)
|
||||||
|
viewer.scene.primitives.add(axisSphereX)
|
||||||
|
let mx = Cesium.Matrix3.fromRotationX(Cesium.Math.toRadians(90))
|
||||||
|
let rotationX = Cesium.Matrix4.fromRotationTranslation(mx)
|
||||||
|
Cesium.Matrix4.multiply(
|
||||||
|
axisSphereX.geometryInstances.modelMatrix,
|
||||||
|
rotationX,
|
||||||
|
axisSphereX.geometryInstances.modelMatrix
|
||||||
|
)
|
||||||
|
|
||||||
|
let lastPickTime = 0;
|
||||||
|
let timeoutEvent
|
||||||
|
this.MapEvent.mouse_move((movement) => {
|
||||||
|
moveEvent(movement)
|
||||||
|
})
|
||||||
|
|
||||||
|
function moveEvent(movement) {
|
||||||
|
if (!_this.activeCircle) {
|
||||||
|
const now = Date.now();
|
||||||
|
if (now - lastPickTime < 100) {
|
||||||
|
clearTimeout(timeoutEvent)
|
||||||
|
timeoutEvent = setTimeout(() => {
|
||||||
|
moveEvent(movement)
|
||||||
|
}, 100);
|
||||||
|
return
|
||||||
|
}
|
||||||
|
clearTimeout(timeoutEvent)
|
||||||
|
lastPickTime = now;
|
||||||
|
let primitives = _that.coordCircles
|
||||||
|
for (let i = 0; i < primitives.length; i++) {
|
||||||
|
if (primitives[i].getGeometryInstanceAttributes) {
|
||||||
|
let attributes = primitives[i].getGeometryInstanceAttributes(primitives[i]._name);
|
||||||
|
switch (primitives[i]._name) {
|
||||||
|
case 'model_edit_zCircle':
|
||||||
|
attributes.color = Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.RED).value
|
||||||
|
break;
|
||||||
|
case 'model_edit_yCircle':
|
||||||
|
attributes.color = Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.BLUE).value
|
||||||
|
break;
|
||||||
|
case 'model_edit_xCircle':
|
||||||
|
attributes.color = Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.LIME).value
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let pickedObjectArray = viewer.scene.drillPick(movement.endPosition, 10);
|
||||||
|
for (let i = 0; i < pickedObjectArray.length; i++) {
|
||||||
|
let pick = pickedObjectArray[i]
|
||||||
|
if (pick && pick.primitive && pick.id) {
|
||||||
|
let attributes = pick.primitive.getGeometryInstanceAttributes(pick.id);
|
||||||
|
switch (pick.primitive._name) {
|
||||||
|
case 'model_edit_zCircle':
|
||||||
|
attributes.color = Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.YELLOW).value
|
||||||
|
return;
|
||||||
|
case 'model_edit_yCircle':
|
||||||
|
attributes.color = Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.YELLOW).value
|
||||||
|
return;
|
||||||
|
case 'model_edit_xCircle':
|
||||||
|
attributes.color = Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.YELLOW).value
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
let position1 = Cesium.SceneTransforms.wgs84ToWindowCoordinates(viewer.scene, _that.ciclkPosition);
|
||||||
|
|
||||||
|
let _rx = 0,
|
||||||
|
_ry = 0,
|
||||||
|
_rz = 0 //xyz方向的旋转量(度)
|
||||||
|
if (!position1) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const _yPix = movement.startPosition.y - movement.endPosition.y
|
||||||
|
const _xPix = movement.startPosition.x - movement.endPosition.x
|
||||||
|
switch (_this.activeCircle._name) {
|
||||||
|
case 'model_edit_xCircle':
|
||||||
|
_ry = 1 * _xPix
|
||||||
|
break;
|
||||||
|
case 'model_edit_yCircle':
|
||||||
|
_rx = 1 * _yPix
|
||||||
|
break;
|
||||||
|
case 'model_edit_zCircle':
|
||||||
|
_rz = 1 * _xPix
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
_this._params.rx -= _rx
|
||||||
|
if (_this._params.rx > 360) {
|
||||||
|
_this._params.rx = 1
|
||||||
|
}
|
||||||
|
if (_this._params.rx < 0) {
|
||||||
|
_this._params.rx = 360
|
||||||
|
}
|
||||||
|
let mx = Cesium.Matrix3.fromRotationX(
|
||||||
|
Cesium.Math.toRadians(_this._params.rx)
|
||||||
|
)
|
||||||
|
_this._params.ry -= _ry
|
||||||
|
if (_this._params.ry > 360) {
|
||||||
|
_this._params.ry = 1
|
||||||
|
}
|
||||||
|
if (_this._params.ry < 0) {
|
||||||
|
_this._params.ry = 360
|
||||||
|
}
|
||||||
|
_this._params.rz -= _rz
|
||||||
|
if (_this._params.rz > 360) {
|
||||||
|
_this._params.rz = 1
|
||||||
|
}
|
||||||
|
if (_this._params.rz < 0) {
|
||||||
|
_this._params.rz = 360
|
||||||
|
}
|
||||||
|
_this.updateModel(_this._params.tx, _this._params.ty, _this._params.tz, _this._params.rx, _this._params.ry, _this._params.rz)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.MapEvent.mouse_left_down((event) => {
|
||||||
|
let cartesian = viewer.scene.pickPosition(event.position);
|
||||||
|
_that.ciclkPosition = cartesian
|
||||||
|
let pickedObjectArray = viewer.scene.drillPick(event.position, 10);
|
||||||
|
for (let i = 0; i < pickedObjectArray.length; i++) {
|
||||||
|
let pickedObject = pickedObjectArray[i]
|
||||||
|
if (pickedObject && pickedObject.primitive && pickedObject.id) {
|
||||||
|
switch (pickedObject.primitive._name) {
|
||||||
|
case 'model_edit_xCircle':
|
||||||
|
case 'model_edit_yCircle':
|
||||||
|
case 'model_edit_zCircle':
|
||||||
|
viewer.scene.screenSpaceCameraController.enableRotate = false;
|
||||||
|
let attributes = pickedObject.primitive.getGeometryInstanceAttributes(pickedObject.primitive._name);
|
||||||
|
attributes.color = Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.YELLOW).value
|
||||||
|
_this.activeCircle = pickedObject.primitive
|
||||||
|
_this.activeModelParam = _this.initParam()
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_this.activeCircle = null
|
||||||
|
_this.activeModelParam = null
|
||||||
|
viewer.scene.screenSpaceCameraController.enableRotate = true
|
||||||
|
})
|
||||||
|
this.MapEvent.mouse_left_up((event) => {
|
||||||
|
viewer.scene.screenSpaceCameraController.enableRotate = true;
|
||||||
|
let primitives = _this.coordCircles
|
||||||
|
_this.activeCircle = null
|
||||||
|
_this.activeModelParam = null
|
||||||
|
for (let i = 0; i < primitives.length; i++) {
|
||||||
|
if (primitives[i].getGeometryInstanceAttributes) {
|
||||||
|
let attributes = primitives[i].getGeometryInstanceAttributes(primitives[i]._name);
|
||||||
|
switch (primitives[i]._name) {
|
||||||
|
case 'model_edit_zCircle':
|
||||||
|
attributes.color = Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.RED).value
|
||||||
|
break;
|
||||||
|
case 'model_edit_yCircle':
|
||||||
|
attributes.color = Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.BLUE).value
|
||||||
|
break;
|
||||||
|
case 'model_edit_xCircle':
|
||||||
|
attributes.color = Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.LIME).value
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//更新模型位置
|
||||||
|
updateModel(_tx, _ty, _tz, _rx = 0, _ry = 0, _rz = 0) {
|
||||||
|
this._params.tx = _tx = parseFloat(parseFloat(_tx).toFixed(8))
|
||||||
|
this._params.ty = _ty = parseFloat(parseFloat(_ty).toFixed(8))
|
||||||
|
this._params.tz = _tz = parseFloat(parseFloat(_tz).toFixed(2))
|
||||||
|
this._params.rx = _rx = parseFloat(_rx)
|
||||||
|
this._params.ry = _ry = parseFloat(_ry)
|
||||||
|
this._params.rz = _rz = parseFloat(_rz)
|
||||||
|
this.options.position.lng = _tx
|
||||||
|
this.options.position.lat = _ty
|
||||||
|
this.options.position.alt = _tz
|
||||||
|
this.options.rotate = { x: _rx, y: _ry, z: _rz }
|
||||||
|
// this.model.position = new Cesium.Cartesian3.fromDegrees(_tx, _ty, _tz)
|
||||||
|
// this.model.rotate = { x: _rx, y: _ry, z: _rz }
|
||||||
|
// let mx = Cesium.Matrix3.fromRotationX(
|
||||||
|
// Cesium.Math.toRadians(_rx)
|
||||||
|
// )
|
||||||
|
// let my = Cesium.Matrix3.fromRotationY(
|
||||||
|
// Cesium.Math.toRadians(_ry)
|
||||||
|
// )
|
||||||
|
// let mz = Cesium.Matrix3.fromRotationZ(
|
||||||
|
// Cesium.Math.toRadians(_rz)
|
||||||
|
// )
|
||||||
|
// // 平移
|
||||||
|
// let m = Cesium.Transforms.eastNorthUpToFixedFrame(new Cesium.Cartesian3.fromDegrees(_tx, _ty, _tz))
|
||||||
|
// // 旋转
|
||||||
|
// let rotationX = Cesium.Matrix4.fromRotationTranslation(mx)
|
||||||
|
// let rotationY = Cesium.Matrix4.fromRotationTranslation(my)
|
||||||
|
// let rotationZ = Cesium.Matrix4.fromRotationTranslation(mz)
|
||||||
|
// let originalMatrix = new Cesium.Matrix4()
|
||||||
|
// Cesium.Matrix4.multiply(m, rotationX, originalMatrix)
|
||||||
|
// Cesium.Matrix4.multiply(originalMatrix, rotationY, originalMatrix)
|
||||||
|
// Cesium.Matrix4.multiply(originalMatrix, rotationZ, this.model.modelMatrix)
|
||||||
|
this.controllerCallBack
|
||||||
|
}
|
||||||
|
|
||||||
|
set controllerCallBack(callback) {
|
||||||
|
this._controllerCallBack = callback
|
||||||
|
}
|
||||||
|
get controllerCallBack() {
|
||||||
|
this._controllerCallBack && this._controllerCallBack(this.options, this.activeAxis ? false : true)
|
||||||
|
}
|
||||||
|
|
||||||
|
createAxisArrow(name, position, matrix, color) {
|
||||||
|
let result = new Cesium.Primitive({
|
||||||
|
geometryInstances: new Cesium.GeometryInstance({
|
||||||
|
id: name,
|
||||||
|
geometry: new Cesium.PolylineGeometry({
|
||||||
|
positions: position,
|
||||||
|
width: 20
|
||||||
|
}),
|
||||||
|
attributes: {
|
||||||
|
color: Cesium.ColorGeometryInstanceAttribute.fromColor(color)
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
releaseGeometryInstances: false,
|
||||||
|
appearance: new Cesium.PolylineMaterialAppearance({
|
||||||
|
material: Cesium.Material.fromType(Cesium.Material.PolylineArrowType, {
|
||||||
|
color: color,
|
||||||
|
}),
|
||||||
|
translucent: true,
|
||||||
|
renderState: {
|
||||||
|
depthTest: {
|
||||||
|
enabled: false,
|
||||||
|
},
|
||||||
|
depthMask: false,
|
||||||
|
depthFunction: Cesium.DepthFunction.ALWAYS,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
modelMatrix: matrix
|
||||||
|
})
|
||||||
|
result._name = name
|
||||||
|
this.coordArrows.push(result)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
createAxisCircular(name, position, matrix, color) {
|
||||||
|
let result = new Cesium.Primitive({
|
||||||
|
geometryInstances: new Cesium.GeometryInstance({
|
||||||
|
geometry: new Cesium.EllipseGeometry(
|
||||||
|
{
|
||||||
|
center: { x: 1, y: 1, z: 1 },
|
||||||
|
semiMinorAxis: 500000.0,
|
||||||
|
semiMajorAxis: 1000000.0,
|
||||||
|
rotation: Cesium.Math.PI_OVER_FOUR,
|
||||||
|
vertexFormat: Cesium.VertexFormat.POSITION_AND_ST
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}),
|
||||||
|
releaseGeometryInstances: false,
|
||||||
|
appearance: new Cesium.EllipsoidSurfaceAppearance({
|
||||||
|
material: new Cesium.Material({
|
||||||
|
fabric: {
|
||||||
|
type: 'Color',
|
||||||
|
uniforms: {
|
||||||
|
color: Cesium.Color.YELLOW
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}),
|
||||||
|
modelMatrix: matrix
|
||||||
|
})
|
||||||
|
result._name = name
|
||||||
|
this.coordArrows.push(result)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
createAxisSphere(name, position, matrix, color, radius) {
|
||||||
|
let result = new Cesium.Primitive({
|
||||||
|
geometryInstances: new Cesium.GeometryInstance({
|
||||||
|
id: name,
|
||||||
|
geometry: new Cesium.PolylineGeometry({
|
||||||
|
positions: position,
|
||||||
|
width: 5
|
||||||
|
}),
|
||||||
|
attributes: {
|
||||||
|
color: Cesium.ColorGeometryInstanceAttribute.fromColor(color)
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
releaseGeometryInstances: false,
|
||||||
|
appearance: new Cesium.PolylineColorAppearance({
|
||||||
|
translucent: true,
|
||||||
|
renderState: {
|
||||||
|
depthTest: {
|
||||||
|
enabled: false,
|
||||||
|
},
|
||||||
|
depthMask: false,
|
||||||
|
depthFunction: Cesium.DepthFunction.ALWAYS,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
modelMatrix: matrix
|
||||||
|
})
|
||||||
|
result._radius = radius
|
||||||
|
result._name = name
|
||||||
|
this.coordCircles.push(result)
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
removeCoordArrows() {
|
||||||
|
for (let i = 0; i < this.coordArrows.length; i++) {
|
||||||
|
this.viwer.scene.primitives.remove(this.coordArrows[i])
|
||||||
|
}
|
||||||
|
this.coordArrows = []
|
||||||
|
}
|
||||||
|
|
||||||
|
removeCoordCircle() {
|
||||||
|
for (let i = 0; i < this.coordCircles.length; i++) {
|
||||||
|
this.viwer.scene.primitives.remove(this.coordCircles[i])
|
||||||
|
}
|
||||||
|
this.coordCircles = []
|
||||||
|
}
|
||||||
|
|
||||||
|
removeAllTools() {
|
||||||
|
this.removeCoordArrows()
|
||||||
|
this.removeCoordCircle()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 关闭/注销
|
||||||
|
*/
|
||||||
|
destroy() {
|
||||||
|
this.removeAllTools()
|
||||||
|
this.activeAxis = undefined
|
||||||
|
this.activeState = undefined
|
||||||
|
this.MapEvent && this.MapEvent.destroy()
|
||||||
|
this.viwer.camera.changed.removeEventListener(this.againArrow)
|
||||||
|
this.viwer.camera.changed.removeEventListener(this.againCircle)
|
||||||
|
}
|
||||||
|
|
||||||
|
getActiveState() {
|
||||||
|
return this.activeState
|
||||||
|
}
|
||||||
|
|
||||||
|
update() {
|
||||||
|
this.againArrow()
|
||||||
|
this.againCircle()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export default ControllerObject
|
||||||
88
src/DZ/XJ/BatchLoadObjModel/index.js
Normal file
88
src/DZ/XJ/BatchLoadObjModel/index.js
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
import { getHost, getToken } from "../../../on";
|
||||||
|
import BaseLoadObjModel from '../../../Obj/Base/LoadObjModel'
|
||||||
|
import LoadObjModel from '../LoadObjModel'
|
||||||
|
export default class BatchLoadObjModel {
|
||||||
|
constructor(sdk, options = {}) {
|
||||||
|
this.sdk = sdk
|
||||||
|
this.options = { ...options }
|
||||||
|
this.options.show = (options.show || options.show === false) ? options.show : true
|
||||||
|
this.options.host = this.options.host || getHost()
|
||||||
|
this.objModelObject = []
|
||||||
|
this._loaded = false
|
||||||
|
this._loadEvent = void 0
|
||||||
|
this.on()
|
||||||
|
}
|
||||||
|
|
||||||
|
get show() {
|
||||||
|
return this.options.show
|
||||||
|
}
|
||||||
|
|
||||||
|
set show(v) {
|
||||||
|
if (typeof v === "boolean") {
|
||||||
|
this.options.show = v
|
||||||
|
for (let i = 0; i < this.objModelObject.length; i++) {
|
||||||
|
this.objModelObject[i].load(() => {
|
||||||
|
this.objModelObject[i].show = v
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.error("参数必须为boolean")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async on() {
|
||||||
|
let url = ""
|
||||||
|
if (this.options.host.endsWith("yjearth4.0"))
|
||||||
|
url = this.options.host + '/api/v1/source/obj'
|
||||||
|
else
|
||||||
|
url = this.options.host + '/yjearth4.0/api/v1/source/obj'
|
||||||
|
if (this.options.code) {
|
||||||
|
url = url + '?code=' + this.options.code
|
||||||
|
}
|
||||||
|
const res = await fetch(url, {
|
||||||
|
method: 'get',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
"token": getToken(),
|
||||||
|
"Authorization": "Bearer " + getToken(),
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (res.ok) {
|
||||||
|
this.objModelObject = []
|
||||||
|
this.list = (await res.json()).data;
|
||||||
|
if (this.options.count) {
|
||||||
|
this.list = this.list.splice(0, this.options.count)
|
||||||
|
}
|
||||||
|
for (let i = 0; i < this.list.length; i++) {
|
||||||
|
let options = JSON.parse(this.list[i].detail)
|
||||||
|
options.host = this.options.host
|
||||||
|
if (this.options.show || this.options.show === false) {
|
||||||
|
options.show = this.options.show
|
||||||
|
}
|
||||||
|
let object = new LoadObjModel(this.sdk, options);
|
||||||
|
this.objModelObject.push(object)
|
||||||
|
}
|
||||||
|
this._loaded = true
|
||||||
|
if (this._loadEvent) {
|
||||||
|
this._loadEvent()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
remove() {
|
||||||
|
for (let i = 0; i < this.objModelObject.length; i++) {
|
||||||
|
this.objModelObject[i].load(() => {
|
||||||
|
this.objModelObject[i].remove()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
load(callback) {
|
||||||
|
if (this._loaded) {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this._loadEvent = callback
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
180
src/DZ/XJ/LoadObjModel/index.js
Normal file
180
src/DZ/XJ/LoadObjModel/index.js
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
import AModelLoader from '../../../Obj/Base/LoadObjModel/AModelLoader'
|
||||||
|
import { getHost, getToken } from "../../../on";
|
||||||
|
import BaseLoadObjModel from '../../../Obj/Base/LoadObjModel'
|
||||||
|
export default class LoadObjModel extends BaseLoadObjModel {
|
||||||
|
constructor(sdk, options, CallBack) {
|
||||||
|
super(sdk, options, CallBack)
|
||||||
|
this._loadEvent = void 0
|
||||||
|
this._loaded = false
|
||||||
|
this.options.objId = options.objId
|
||||||
|
this.options.videoId = options.videoId
|
||||||
|
this.options.videoType = options.videoType || 'flv'
|
||||||
|
}
|
||||||
|
|
||||||
|
async addResource() {
|
||||||
|
let that = this
|
||||||
|
that.options.xmlURL = that.options.objUrl.replace('.obj', '.xml')
|
||||||
|
if (that.options.xmlURL !== '') {
|
||||||
|
const xml = await fetch(that.options.xmlURL)
|
||||||
|
if (xml.ok) {
|
||||||
|
const xmlString = await xml.text()
|
||||||
|
const parser = new DOMParser()
|
||||||
|
const xmlDoc = parser.parseFromString(xmlString, 'text/xml')
|
||||||
|
// console.log('xmlDocxmlDocxmlDoc', xmlDoc)
|
||||||
|
const position = xmlDoc
|
||||||
|
.getElementsByTagName('Position')[0]
|
||||||
|
.textContent.split(',')
|
||||||
|
// const bbox = xmlDoc.getElementsByTagName('bbox')[0]
|
||||||
|
const crs = xmlDoc.getElementsByTagName('Crs')[0].textContent
|
||||||
|
const result = that.convert(
|
||||||
|
[{ x: position[0], y: position[1], z: position[2] }],
|
||||||
|
crs,
|
||||||
|
'EPSG:4326'
|
||||||
|
)
|
||||||
|
|
||||||
|
that.options.position = that.options.position || { lng: result.points[0].x, lat: result.points[0].y, alt: result.points[0].z }
|
||||||
|
that.ControllerObject.position = that.options.position
|
||||||
|
const scene = that.viwer.scene
|
||||||
|
const origin = Cesium.Cartesian3.fromDegrees(
|
||||||
|
that.options.position.lng,
|
||||||
|
that.options.position.lat,
|
||||||
|
that.options.position.alt
|
||||||
|
)
|
||||||
|
const obj_modelMatrix = Cesium.Transforms.headingPitchRollToFixedFrame(
|
||||||
|
origin,
|
||||||
|
new Cesium.HeadingPitchRoll(
|
||||||
|
Cesium.Math.toRadians(0.85),
|
||||||
|
Cesium.Math.toRadians(0),
|
||||||
|
Cesium.Math.toRadians(0)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
let objLoader = new AModelLoader(that.viwer.scene.context)
|
||||||
|
let obj = await objLoader.Load(that.options.objUrl, that.options.videoId, that.options.host)
|
||||||
|
obj.modelMatrix = obj_modelMatrix
|
||||||
|
obj.show = that.options.show
|
||||||
|
obj.setFlvVideo(that.options.videoUrl)
|
||||||
|
scene.primitives.add(obj)
|
||||||
|
that.primitive = obj
|
||||||
|
that.controllerCallBack({
|
||||||
|
rotate: { x: that.options.roll, y: -that.options.pitch, z: -that.options.heading },
|
||||||
|
position: { ...that.options.position }
|
||||||
|
})
|
||||||
|
that.loaded = true
|
||||||
|
that._loaded = true
|
||||||
|
if (that._loadEvent) {
|
||||||
|
that._loadEvent()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (that.options.objUrl === '') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async requestResource() {
|
||||||
|
let that = this
|
||||||
|
if(!that._loaded) {
|
||||||
|
if(that.options.objId) {
|
||||||
|
that.options.objUrl = await that.requestObjResource()
|
||||||
|
}
|
||||||
|
if(that.options.videoId) {
|
||||||
|
that.options.videoUrl = await that.requestVideoResource()
|
||||||
|
}
|
||||||
|
await that.addResource()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
requestObjResource() {
|
||||||
|
let host = ""
|
||||||
|
if (this.options.host.endsWith("yjearth4.0"))
|
||||||
|
host = this.options.host
|
||||||
|
else
|
||||||
|
host = this.options.host + '/yjearth4.0'
|
||||||
|
let url = host + '/obj/' + this.options.objId
|
||||||
|
return fetch(url, {
|
||||||
|
method: 'get',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
"token": getToken(),
|
||||||
|
"Authorization": "Bearer " + getToken(),
|
||||||
|
}
|
||||||
|
}).then(async (res) => {
|
||||||
|
let text = await res.text()
|
||||||
|
text = JSON.parse(text)
|
||||||
|
if ([0, 200].includes(text.code)) {
|
||||||
|
if (text.data.objPath.length)
|
||||||
|
return host + '/obj/wirte/file/' + text.data.objPath
|
||||||
|
else
|
||||||
|
console.warn('资源不存在')
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
console.warn(text.msg || text.message)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
requestVideoResource() {
|
||||||
|
let host = ""
|
||||||
|
if (this.options.host.endsWith("yjearth4.0"))
|
||||||
|
host = this.options.host
|
||||||
|
else
|
||||||
|
host = this.options.host + '/yjearth4.0'
|
||||||
|
let url = host + '/videoFusion/' + this.options.videoId
|
||||||
|
return fetch(url, {
|
||||||
|
method: 'get',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
"token": getToken(),
|
||||||
|
"Authorization": "Bearer " + getToken(),
|
||||||
|
}
|
||||||
|
}).then(async (res) => {
|
||||||
|
let text = await res.text()
|
||||||
|
text = JSON.parse(text)
|
||||||
|
if ([0, 200].includes(text.code)) {
|
||||||
|
if (text.data.deviceCode.length) {
|
||||||
|
return fetch(host+'/videoFusion/vide/stream', {
|
||||||
|
method: 'post',
|
||||||
|
body: JSON.stringify({type: 'flv', deviceCode: text.data.deviceCode}),
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
"token": getToken(),
|
||||||
|
"Authorization": "Bearer " + getToken(),
|
||||||
|
}
|
||||||
|
}).then(async (res2) => {
|
||||||
|
let text2 = await res2.text()
|
||||||
|
text2 = JSON.parse(text2)
|
||||||
|
if ([0, 200].includes(text2.code)) {
|
||||||
|
if (text2.data.flv && text2.data.flv.length) {
|
||||||
|
return text2.data.flv
|
||||||
|
}
|
||||||
|
else
|
||||||
|
console.warn('地址不存在')
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
console.warn(text2.msg || text2.message)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
else
|
||||||
|
console.warn('设备不存在')
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
console.warn(text.msg || text.message)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
load(callback) {
|
||||||
|
if (this._loaded) {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this._loadEvent = callback
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
69
src/Draw/draw.js
Normal file
69
src/Draw/draw.js
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
/**
|
||||||
|
* @name: draw
|
||||||
|
* @author: Administrator
|
||||||
|
* @date: 2022-06-14 16:29
|
||||||
|
* @description:draw
|
||||||
|
* @update: 2022-06-14 16:29
|
||||||
|
*/
|
||||||
|
import Tools from '../Tools'
|
||||||
|
import { get2DView } from '../Global/MultiViewportMode'
|
||||||
|
|
||||||
|
class Draw extends Tools {
|
||||||
|
/**
|
||||||
|
* @constructor
|
||||||
|
* */
|
||||||
|
constructor(sdk, options = {}, is2D = false) {
|
||||||
|
super(sdk, options)
|
||||||
|
this.viewer = sdk.viewer
|
||||||
|
this.entityHasCreated = false
|
||||||
|
this.event = null
|
||||||
|
this.tip = null
|
||||||
|
this.points_ids = []
|
||||||
|
this.color = options.color || 'rgba(185,14,14,0.58)'
|
||||||
|
this._is2D = is2D
|
||||||
|
this._sdk2D = get2DView()
|
||||||
|
}
|
||||||
|
|
||||||
|
create_point(cartesian, viewer = this.viewer) {
|
||||||
|
let id = this.randomString()
|
||||||
|
viewer.entities.add(
|
||||||
|
new Cesium.Entity({
|
||||||
|
id: id,
|
||||||
|
position: cartesian,
|
||||||
|
billboard: {
|
||||||
|
image: this.getSourceRootPath() + '/img/point.png',
|
||||||
|
// verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||||||
|
color: Cesium.Color.WHITE.withAlpha(0.99)
|
||||||
|
// disableDepthTestDistance: 1000000
|
||||||
|
},
|
||||||
|
})
|
||||||
|
)
|
||||||
|
return id
|
||||||
|
}
|
||||||
|
|
||||||
|
remove_entity(id) {
|
||||||
|
this.viewer.entities.removeById(id)
|
||||||
|
if (!this._is2D && this._sdk2D && this._sdk2D.viewer && this._sdk2D.viewer.entities) {
|
||||||
|
this._sdk2D.viewer.entities.removeById(id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
start() {
|
||||||
|
// this.setPickStatus(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
end() {
|
||||||
|
// this.setPickStatus(true)
|
||||||
|
|
||||||
|
YJ.Measure.SetMeasureStatus(false)
|
||||||
|
this.entityHasCreated = false
|
||||||
|
this.event && this.event.destroy()
|
||||||
|
this.event2D && this.event2D.destroy()
|
||||||
|
this.tip && this.tip.destroy()
|
||||||
|
this.points_ids.forEach((id) => {
|
||||||
|
this.remove_entity(id)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Draw
|
||||||
595
src/Draw/drawAssemble.js
Normal file
595
src/Draw/drawAssemble.js
Normal file
@ -0,0 +1,595 @@
|
|||||||
|
import MouseTip from '../MouseTip'
|
||||||
|
import MouseEvent from '../Event'
|
||||||
|
import Draw from './draw'
|
||||||
|
|
||||||
|
const transformCartesianToWGS84 = cartesian => {
|
||||||
|
let ellipsoid = Cesium.Ellipsoid.WGS84
|
||||||
|
let cartographic = ellipsoid.cartesianToCartographic(cartesian)
|
||||||
|
const x = Cesium.Math.toDegrees(cartographic.longitude)
|
||||||
|
const y = Cesium.Math.toDegrees(cartographic.latitude)
|
||||||
|
const z = cartographic.height
|
||||||
|
return { x, y, z }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @extends Draw*/
|
||||||
|
class DrawAssemble extends Draw {
|
||||||
|
/**
|
||||||
|
* @constructor
|
||||||
|
* @param sdk
|
||||||
|
* @param [options] {object} 面属性
|
||||||
|
* @param [options.color=rgba(185,14,14,0.58)] {object} 线属性
|
||||||
|
|
||||||
|
* */
|
||||||
|
constructor(sdk, options = {}) {
|
||||||
|
super(sdk, options)
|
||||||
|
this.points = null
|
||||||
|
this.polygonHasCreated = false
|
||||||
|
}
|
||||||
|
|
||||||
|
static polygon(that, viewer = that.viewer) {
|
||||||
|
let id = that.randomString()
|
||||||
|
return viewer.entities.add(
|
||||||
|
new Cesium.Entity({
|
||||||
|
name: 'AssemblePolygon',
|
||||||
|
id,
|
||||||
|
polygon: {
|
||||||
|
hierarchy: new Cesium.CallbackProperty(e => {
|
||||||
|
let arr = that.computeAssemble(that.positions)
|
||||||
|
for (let i = 0; i < arr.length; i++) {
|
||||||
|
if (isNaN(arr[i].x)) {
|
||||||
|
arr = []
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new Cesium.PolygonHierarchy(arr)
|
||||||
|
}, false),
|
||||||
|
material: Cesium.Color.fromCssColorString(that.color),
|
||||||
|
outline: true,
|
||||||
|
outlineColor: Cesium.Color.GREEN,
|
||||||
|
zIndex: 99999999
|
||||||
|
}
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @desc 开始动态绘制面
|
||||||
|
* @method start
|
||||||
|
* @param cb {function} 回调函数
|
||||||
|
* @memberOf DrawPolygon
|
||||||
|
* @example draw.start((err,positions)=>{
|
||||||
|
*
|
||||||
|
* })
|
||||||
|
* */
|
||||||
|
start(cb) {
|
||||||
|
let that = this
|
||||||
|
// eslint-disable-next-line no-undef
|
||||||
|
if (YJ.Measure.GetMeasureStatus()) {
|
||||||
|
cb('上一次测量未结束')
|
||||||
|
} else {
|
||||||
|
super.start()
|
||||||
|
// eslint-disable-next-line no-undef
|
||||||
|
YJ.Measure.SetMeasureStatus(true)
|
||||||
|
let into
|
||||||
|
this.tip = new MouseTip('左键确定,右键取消;', that.sdk)
|
||||||
|
this.event = new MouseEvent(that.sdk)
|
||||||
|
this.positions = []
|
||||||
|
this.points_ids = [] //存放左键点击时临时添加的point的id
|
||||||
|
let cache_positions = []
|
||||||
|
let cache_84_position = []
|
||||||
|
this.anchorpoints = []
|
||||||
|
this.event.mouse_left((movement, cartesian) => {
|
||||||
|
if (into === '2D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
into = '3D'
|
||||||
|
if (!cartesian) return
|
||||||
|
if (this.anchorpoints.length === 3) {
|
||||||
|
this.anchorpoints[1] = cartesian;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.anchorpoints.push(cartesian)
|
||||||
|
}
|
||||||
|
|
||||||
|
cache_positions.push(this.cartesian3Towgs84(cartesian, this.viewer))
|
||||||
|
// console.log(this.cartesian3Towgs84(cartesian))
|
||||||
|
this.points_ids.push(this.create_point(cartesian))
|
||||||
|
if (this.points_ids.length === 3) {
|
||||||
|
let array = [cache_positions[0], cache_positions[2], cache_positions[1]]
|
||||||
|
cb(null, array)
|
||||||
|
this.end()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.event.mouse_move((movement, cartesian) => {
|
||||||
|
if (into === '2D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.tip.setPosition(
|
||||||
|
cartesian,
|
||||||
|
movement.endPosition.x,
|
||||||
|
movement.endPosition.y
|
||||||
|
)
|
||||||
|
if (!cartesian || this.points_ids.length === 0) return
|
||||||
|
if (cache_positions.length > 1) {
|
||||||
|
this.positions = [cache_positions[0], this.cartesian3Towgs84(cartesian, this.viewer), cache_positions[1]]
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.positions = [cache_positions[0], this.cartesian3Towgs84(cartesian, this.viewer)]
|
||||||
|
}
|
||||||
|
if (this.points_ids.length === 1 && !Cesium.defined(this.assemblePolygon)) {
|
||||||
|
this.assemblePolygon = DrawAssemble.polygon(this)
|
||||||
|
}
|
||||||
|
if (this.anchorpoints.length >= 2) {
|
||||||
|
if (this.points_ids.length === 1) {
|
||||||
|
let pnts = new Array();
|
||||||
|
this.positions.forEach((item) => {
|
||||||
|
pnts.push([item.lng, item.lat]);
|
||||||
|
});
|
||||||
|
|
||||||
|
let mid = P.PlotUtils.mid(pnts[0], pnts[1])
|
||||||
|
let d = P.PlotUtils.distance(pnts[0], mid) / 0.9
|
||||||
|
let pnt = P.PlotUtils.getThirdPoint(pnts[0], mid, P.Constants.HALF_PI, d, true)
|
||||||
|
this.positions = [this.positions[0], { lng: pnt[0], lat: pnt[1] }, this.positions[1]];
|
||||||
|
}
|
||||||
|
//替换中间点
|
||||||
|
this.anchorpoints[1] = cartesian;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.anchorpoints.push(cartesian)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.event.mouse_right((movement, cartesian) => {
|
||||||
|
if (into === '2D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
cb(null)
|
||||||
|
this.end()
|
||||||
|
})
|
||||||
|
|
||||||
|
this.event.gesture_pinck_start((movement, cartesian) => {
|
||||||
|
if (into === '2D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let startTime = new Date()
|
||||||
|
this.event.gesture_pinck_end(() => {
|
||||||
|
let endTime = new Date()
|
||||||
|
if (endTime - startTime >= 500) {
|
||||||
|
this.end()
|
||||||
|
cb(false)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (this.anchorpoints.length === 2) {
|
||||||
|
this.anchorpoints.push(cartesian)
|
||||||
|
cb(null, this.positions)
|
||||||
|
this.end()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (!cartesian || Cesium.defined(this.assemblePolygon)) return
|
||||||
|
this.tip.setPosition(
|
||||||
|
cartesian,
|
||||||
|
(movement.position1.x + movement.position2.x) / 2,
|
||||||
|
(movement.position1.y + movement.position2.y) / 2
|
||||||
|
)
|
||||||
|
this.anchorpoints.push(cartesian)
|
||||||
|
this.assemblePolygon = DrawAssemble.polygon(this)
|
||||||
|
cache_positions.push(this.cartesian3Towgs84(cartesian))
|
||||||
|
// console.log(this.cartesian3Towgs84(cartesian))
|
||||||
|
this.points_ids.push(this.create_point(cartesian))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!this._is2D && this._sdk2D) {
|
||||||
|
this.event2D = new MouseEvent(this._sdk2D)
|
||||||
|
this.event2D.mouse_left((movement, cartesian) => {
|
||||||
|
if (into === '3D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
into = '2D'
|
||||||
|
if (!cartesian) return
|
||||||
|
if (this.anchorpoints.length === 3) {
|
||||||
|
this.anchorpoints[1] = cartesian;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.anchorpoints.push(cartesian)
|
||||||
|
}
|
||||||
|
|
||||||
|
cache_positions.push(this.cartesian3Towgs84(cartesian, this.viewer))
|
||||||
|
// console.log(this.cartesian3Towgs84(cartesian))
|
||||||
|
this.points_ids.push(this.create_point(cartesian, this._sdk2D.viewer))
|
||||||
|
if (this.points_ids.length === 3) {
|
||||||
|
let array = [cache_positions[0], cache_positions[2], cache_positions[1]]
|
||||||
|
cb(null, array)
|
||||||
|
this.end()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.event2D.mouse_move((movement, cartesian) => {
|
||||||
|
if (into === '3D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.tip.setPosition(
|
||||||
|
cartesian,
|
||||||
|
movement.endPosition.x + this.viewer.canvas.width,
|
||||||
|
movement.endPosition.y
|
||||||
|
)
|
||||||
|
if (!cartesian || this.points_ids.length === 0) return
|
||||||
|
if (cache_positions.length > 1) {
|
||||||
|
this.positions = [cache_positions[0], this.cartesian3Towgs84(cartesian, this.viewer), cache_positions[1]]
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.positions = [cache_positions[0], this.cartesian3Towgs84(cartesian, this.viewer)]
|
||||||
|
}
|
||||||
|
if (this.points_ids.length === 1 && !Cesium.defined(this.assemblePolygon)) {
|
||||||
|
this.assemblePolygon = DrawAssemble.polygon(this, this._sdk2D.viewer)
|
||||||
|
}
|
||||||
|
if (this.anchorpoints.length >= 2) {
|
||||||
|
if (this.points_ids.length === 1) {
|
||||||
|
let pnts = new Array();
|
||||||
|
this.positions.forEach((item) => {
|
||||||
|
pnts.push([item.lng, item.lat]);
|
||||||
|
});
|
||||||
|
|
||||||
|
let mid = P.PlotUtils.mid(pnts[0], pnts[1])
|
||||||
|
let d = P.PlotUtils.distance(pnts[0], mid) / 0.9
|
||||||
|
let pnt = P.PlotUtils.getThirdPoint(pnts[0], mid, P.Constants.HALF_PI, d, true)
|
||||||
|
this.positions = [this.positions[0], { lng: pnt[0], lat: pnt[1] }, this.positions[1]];
|
||||||
|
}
|
||||||
|
//替换中间点
|
||||||
|
this.anchorpoints[1] = cartesian;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.anchorpoints.push(cartesian)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.event2D.mouse_right((movement, cartesian) => {
|
||||||
|
if (into === '3D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
cb(null)
|
||||||
|
this.end()
|
||||||
|
})
|
||||||
|
|
||||||
|
this.event2D.gesture_pinck_start((movement, cartesian) => {
|
||||||
|
if (into === '3D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let startTime = new Date()
|
||||||
|
this.event2D.gesture_pinck_end(() => {
|
||||||
|
let endTime = new Date()
|
||||||
|
if (endTime - startTime >= 500) {
|
||||||
|
this.end()
|
||||||
|
cb(false)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (this.anchorpoints.length === 2) {
|
||||||
|
this.anchorpoints.push(cartesian)
|
||||||
|
cb(null, this.positions)
|
||||||
|
this.end()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (!cartesian || Cesium.defined(this.assemblePolygon)) return
|
||||||
|
this.tip.setPosition(
|
||||||
|
cartesian,
|
||||||
|
((movement.position1.x + movement.position2.x) / 2) + this.viewer.canvas.width,
|
||||||
|
(movement.position1.y + movement.position2.y) / 2
|
||||||
|
)
|
||||||
|
this.anchorpoints.push(cartesian)
|
||||||
|
this.assemblePolygon = DrawAssemble.polygon(this, this._sdk2D.viewer)
|
||||||
|
cache_positions.push(this.cartesian3Towgs84(cartesian))
|
||||||
|
// console.log(this.cartesian3Towgs84(cartesian))
|
||||||
|
this.points_ids.push(this.create_point(cartesian, this._sdk2D.viewer))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
end() {
|
||||||
|
super.end();
|
||||||
|
this.viewer.entities.remove(this.assemblePolygon)
|
||||||
|
if (!this._is2D && this._sdk2D) {
|
||||||
|
this._sdk2D.viewer.entities.remove(this.assemblePolygon)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// computeAssemblePoints(anchorpoints) {
|
||||||
|
// let points = []
|
||||||
|
|
||||||
|
// let originP = transformCartesianToWGS84(anchorpoints[0])
|
||||||
|
// let lastP = anchorpoints[1]
|
||||||
|
// ? transformCartesianToWGS84(anchorpoints[1])
|
||||||
|
// : { x: originP.x + 0.00001, y: originP.y + 0.00001, z: originP.z }
|
||||||
|
// let vectorOL = { x: lastP.x - originP.x, y: lastP.y - originP.y }
|
||||||
|
// let dOL = Math.sqrt(vectorOL.x * vectorOL.x + vectorOL.y * vectorOL.y)
|
||||||
|
// let v_O_P1_lr = this.calculateVector(
|
||||||
|
// vectorOL,
|
||||||
|
// Math.PI / 3,
|
||||||
|
// (Math.sqrt(3) / 12) * dOL
|
||||||
|
// )
|
||||||
|
// let originP_P1 = v_O_P1_lr[1]
|
||||||
|
// let p1 = { x: originP.x + originP_P1.x, y: originP.y + originP_P1.y }
|
||||||
|
// let p2 = { x: (originP.x + lastP.x) / 2, y: (originP.y + lastP.y) / 2 }
|
||||||
|
// let v_L_P3_lr = this.calculateVector(
|
||||||
|
// vectorOL,
|
||||||
|
// (Math.PI * 2) / 3,
|
||||||
|
// (Math.sqrt(3) / 12) * dOL
|
||||||
|
// )
|
||||||
|
// let lastP_P3 = v_L_P3_lr[1]
|
||||||
|
// let p3 = { x: lastP.x + lastP_P3.x, y: lastP.y + lastP_P3.y }
|
||||||
|
// let v_O_P5_lr = this.calculateVector(vectorOL, Math.PI / 2, (1 / 2) * dOL)
|
||||||
|
// let v_O_P5 = v_O_P5_lr[0]
|
||||||
|
// let p5 = { x: v_O_P5.x + p2.x, y: v_O_P5.y + p2.y }
|
||||||
|
// let p0 = originP
|
||||||
|
// let p4 = lastP
|
||||||
|
// points.push(p0, p1, p2, p3, p4, p5)
|
||||||
|
// const closeCardinal = this.createCloseCardinal(points)
|
||||||
|
// const fb_points = this.calculatePointsFBZ3(closeCardinal, 100)
|
||||||
|
// let result = []
|
||||||
|
// let result2 = []
|
||||||
|
// for (let index = 0; index < fb_points.length; index++) {
|
||||||
|
// const ele = fb_points[index]
|
||||||
|
// let obj = {
|
||||||
|
// lng: ele.x,
|
||||||
|
// lat: ele.y,
|
||||||
|
// alt: 0
|
||||||
|
// }
|
||||||
|
// result.push(ele.x, ele.y, 0)
|
||||||
|
// result2.push(obj)
|
||||||
|
// }
|
||||||
|
// this.position = result2
|
||||||
|
// this.points = result
|
||||||
|
// }
|
||||||
|
|
||||||
|
// computeAssemblePoints2(anchorpoints) {
|
||||||
|
// let points = anchorpoints.length;
|
||||||
|
// if (points < 2) {
|
||||||
|
// return false
|
||||||
|
// } else {
|
||||||
|
// let pnts = new Array();
|
||||||
|
// anchorpoints.forEach((item) => {
|
||||||
|
// let posLonLat = this.cartesian3Towgs84(item, this.viewer);;
|
||||||
|
// pnts.push([posLonLat.lng, posLonLat.lat]);
|
||||||
|
// });
|
||||||
|
// //console.log("pnts6666",pnts);
|
||||||
|
// // pnts.push(tailPoint);
|
||||||
|
// // pnts.push(headerPoint);
|
||||||
|
|
||||||
|
// if (pnts.length === 2) {
|
||||||
|
// let mid = P.PlotUtils.mid(pnts[0], pnts[1])
|
||||||
|
// //let d = utils.MathDistance(pnts[0], mid) / 0.9
|
||||||
|
// let d = P.PlotUtils.distance(pnts[0], mid) / 0.9
|
||||||
|
// //console.log("d",d);
|
||||||
|
// let pnt = P.PlotUtils.getThirdPoint(pnts[0], mid, P.Constants.HALF_PI, d, true)
|
||||||
|
// pnts = [pnts[0], pnt, pnts[1]];
|
||||||
|
// //console.log("pnt",pnt);
|
||||||
|
// //createPoint(Cesium.Cartesian3.fromDegrees(pnt[0], pnt[1]));
|
||||||
|
// }
|
||||||
|
// let mid = P.PlotUtils.mid(pnts[0], pnts[2])
|
||||||
|
// pnts.push(mid, pnts[0], pnts[1])
|
||||||
|
|
||||||
|
// let [normals, pnt1, pnt2, pnt3, result, result2] = [[], undefined, undefined, undefined, [], []]
|
||||||
|
// for (let i = 0; i < pnts.length - 2; i++) {
|
||||||
|
// pnt1 = pnts[i]
|
||||||
|
// pnt2 = pnts[i + 1]
|
||||||
|
// pnt3 = pnts[i + 2]
|
||||||
|
// let normalPoints = P.PlotUtils.getBisectorNormals(0.4, pnt1, pnt2, pnt3)
|
||||||
|
// normals = normals.concat(normalPoints)
|
||||||
|
// }
|
||||||
|
// let count = normals.length
|
||||||
|
// normals = [normals[count - 1]].concat(normals.slice(0, count - 1))
|
||||||
|
// for (let i = 0; i < pnts.length - 2; i++) {
|
||||||
|
// pnt1 = pnts[i]
|
||||||
|
// pnt2 = pnts[i + 1]
|
||||||
|
// result = result.concat([...pnt1, 0])
|
||||||
|
// result2.push(
|
||||||
|
// {
|
||||||
|
// lng: pnt1[0],
|
||||||
|
// lat: pnt1[1],
|
||||||
|
// alt: 0
|
||||||
|
// }
|
||||||
|
// )
|
||||||
|
// for (let t = 0; t <= P.Constants.FITTING_COUNT; t++) {
|
||||||
|
// let pnt = P.PlotUtils.getCubicValue(t / P.Constants.FITTING_COUNT, pnt1, normals[i * 2], normals[i * 2 + 1], pnt2)
|
||||||
|
// result = result.concat([...pnt, 0])
|
||||||
|
// result2.push(
|
||||||
|
// {
|
||||||
|
// lng: pnt[0],
|
||||||
|
// lat: pnt[1],
|
||||||
|
// alt: 0
|
||||||
|
// }
|
||||||
|
// )
|
||||||
|
// }
|
||||||
|
// result = result.concat([...pnt2, 0])
|
||||||
|
// result2.push(
|
||||||
|
// {
|
||||||
|
// lng: pnt2[0],
|
||||||
|
// lat: pnt2[1],
|
||||||
|
// alt: 0
|
||||||
|
// }
|
||||||
|
// )
|
||||||
|
// }
|
||||||
|
// this.position = result2
|
||||||
|
// this.points = result
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
calculateVector(v, theta, d) {
|
||||||
|
if (!theta) theta = Math.PI / 2
|
||||||
|
if (!d) d = 1
|
||||||
|
let x_1
|
||||||
|
let x_2
|
||||||
|
let y_1
|
||||||
|
let y_2
|
||||||
|
let v_l
|
||||||
|
let v_r
|
||||||
|
let d_v = Math.sqrt(v.x * v.x + v.y * v.y)
|
||||||
|
if (v.y == 0) {
|
||||||
|
x_1 = x_2 = (d_v * d * Math.cos(theta)) / v.x
|
||||||
|
if (v.x > 0) {
|
||||||
|
y_1 = Math.sqrt(d * d - x_1 * x_1)
|
||||||
|
y_2 = -y_1
|
||||||
|
} else if (v.x < 0) {
|
||||||
|
y_2 = Math.sqrt(d * d - x_1 * x_1)
|
||||||
|
y_1 = -y_2
|
||||||
|
}
|
||||||
|
v_l = { x: x_1, y: y_1 }
|
||||||
|
v_r = { x: x_2, y: y_2 }
|
||||||
|
} else {
|
||||||
|
let n = -v.x / v.y
|
||||||
|
let m = (d * d_v * Math.cos(theta)) / v.y
|
||||||
|
let a = 1 + n * n
|
||||||
|
let b = 2 * n * m
|
||||||
|
let c = m * m - d * d
|
||||||
|
x_1 = (-b - Math.sqrt(b * b - 4 * a * c)) / (2 * a)
|
||||||
|
x_2 = (-b + Math.sqrt(b * b - 4 * a * c)) / (2 * a)
|
||||||
|
y_1 = n * x_1 + m
|
||||||
|
y_2 = n * x_2 + m
|
||||||
|
if (v.y >= 0) {
|
||||||
|
v_l = { x: x_1, y: y_1 }
|
||||||
|
v_r = { x: x_2, y: y_2 }
|
||||||
|
} else if (v.y < 0) {
|
||||||
|
v_l = { x: x_2, y: y_2 }
|
||||||
|
v_r = { x: x_1, y: y_1 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return [v_l, v_r]
|
||||||
|
}
|
||||||
|
|
||||||
|
createCloseCardinal(points) {
|
||||||
|
if (points == null || points.length < 3) {
|
||||||
|
return points
|
||||||
|
}
|
||||||
|
//获取起点,作为终点,以闭合曲线。
|
||||||
|
let lastP = points[0]
|
||||||
|
points.push(lastP)
|
||||||
|
//定义传入的点数组,将在点数组中央(每两个点)插入两个控制点
|
||||||
|
let cPoints = points
|
||||||
|
//包含输入点和控制点的数组
|
||||||
|
let cardinalPoints = []
|
||||||
|
//至少三个点以上
|
||||||
|
//这些都是相关资料测出的经验数值
|
||||||
|
//定义张力系数,取值在0<t<0.5
|
||||||
|
let t = 0.4
|
||||||
|
//为端点张力系数因子,取值在0<b<1
|
||||||
|
// let b = 0.5;
|
||||||
|
//误差控制,是一个大于等于0的数,用于三点非常趋近与一条直线时,减少计算量
|
||||||
|
let e = 0.005
|
||||||
|
//传入的点数量,至少有三个,n至少为2
|
||||||
|
let n = cPoints.length - 1
|
||||||
|
//从开始遍历到倒数第二个,其中倒数第二个用于计算起点(终点)的插值控制点
|
||||||
|
for (let k = 0; k <= n - 1; k++) {
|
||||||
|
let p0, p1, p2
|
||||||
|
//计算起点(终点)的左右控制点
|
||||||
|
if (k == n - 1) {
|
||||||
|
//三个基础输入点
|
||||||
|
p0 = cPoints[n - 1]
|
||||||
|
p1 = cPoints[0]
|
||||||
|
p2 = cPoints[1]
|
||||||
|
} else {
|
||||||
|
p0 = cPoints[k]
|
||||||
|
p1 = cPoints[k + 1]
|
||||||
|
p2 = cPoints[k + 2]
|
||||||
|
}
|
||||||
|
//定义p1的左控制点和右控制点
|
||||||
|
let p1l = { x: undefined, y: undefined }
|
||||||
|
let p1r = { x: undefined, y: undefined }
|
||||||
|
//通过p0、p1、p2计算p1点的做控制点p1l和又控制点p1r
|
||||||
|
//计算向量p0_p1和p1_p2
|
||||||
|
let p0_p1 = { x: p1.x - p0.x, y: p1.y - p0.y }
|
||||||
|
let p1_p2 = { x: p2.x - p1.x, y: p2.y - p1.y }
|
||||||
|
//并计算模
|
||||||
|
let d01 = Math.sqrt(p0_p1.x * p0_p1.x + p0_p1.y * p0_p1.y)
|
||||||
|
let d12 = Math.sqrt(p1_p2.x * p1_p2.x + p1_p2.y * p1_p2.y)
|
||||||
|
//向量单位化
|
||||||
|
let p0_p1_1 = { x: p0_p1.x / d01, y: p0_p1.y / d01 }
|
||||||
|
let p1_p2_1 = { x: p1_p2.x / d12, y: p1_p2.y / d12 }
|
||||||
|
//计算向量p0_p1和p1_p2的夹角平分线向量
|
||||||
|
let p0_p1_p2 = { x: p0_p1_1.x + p1_p2_1.x, y: p0_p1_1.y + p1_p2_1.y }
|
||||||
|
//计算向量 p0_p1_p2 的模
|
||||||
|
let d012 = Math.sqrt(p0_p1_p2.x * p0_p1_p2.x + p0_p1_p2.y * p0_p1_p2.y)
|
||||||
|
//单位化向量p0_p1_p2
|
||||||
|
let p0_p1_p2_1 = { x: p0_p1_p2.x / d012, y: p0_p1_p2.y / d012 }
|
||||||
|
//判断p0、p1、p2是否共线,这里判定向量p0_p1和p1_p2的夹角的余弦和1的差值小于e就认为三点共线
|
||||||
|
let cosE_p0p1p2 = (p0_p1_1.x * p1_p2_1.x + p0_p1_1.y * p1_p2_1.y) / 1
|
||||||
|
//共线
|
||||||
|
if (Math.abs(1 - cosE_p0p1p2) < e) {
|
||||||
|
//计算p1l的坐标
|
||||||
|
p1l.x = p1.x - p1_p2_1.x * d01 * t
|
||||||
|
p1l.y = p1.y - p1_p2_1.y * d01 * t
|
||||||
|
//计算p1r的坐标
|
||||||
|
p1r.x = p1.x + p0_p1_1.x * d12 * t
|
||||||
|
p1r.y = p1.y + p0_p1_1.y * d12 * t
|
||||||
|
}
|
||||||
|
//非共线
|
||||||
|
else {
|
||||||
|
//计算p1l的坐标
|
||||||
|
p1l.x = p1.x - p0_p1_p2_1.x * d01 * t
|
||||||
|
p1l.y = p1.y - p0_p1_p2_1.y * d01 * t
|
||||||
|
//计算p1r的坐标
|
||||||
|
p1r.x = p1.x + p0_p1_p2_1.x * d12 * t
|
||||||
|
p1r.y = p1.y + p0_p1_p2_1.y * d12 * t
|
||||||
|
}
|
||||||
|
//记录起点(终点)的左右插值控制点及倒数第二个控制点
|
||||||
|
if (k == n - 1) {
|
||||||
|
cardinalPoints[0] = p1
|
||||||
|
cardinalPoints[1] = p1r
|
||||||
|
cardinalPoints[(n - 2) * 3 + 2 + 3] = p1l
|
||||||
|
cardinalPoints[(n - 2) * 3 + 2 + 4] = cPoints[n]
|
||||||
|
} else {
|
||||||
|
//记录下这三个控制点
|
||||||
|
cardinalPoints[k * 3 + 2 + 0] = p1l
|
||||||
|
cardinalPoints[k * 3 + 2 + 1] = p1
|
||||||
|
cardinalPoints[k * 3 + 2 + 2] = p1r
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cardinalPoints
|
||||||
|
}
|
||||||
|
|
||||||
|
calculatePointsFBZ3(points, part) {
|
||||||
|
if (!part) part = 20
|
||||||
|
//获取待拆分的点
|
||||||
|
let bezierPts = []
|
||||||
|
let scale = 0.05
|
||||||
|
if (part > 0) {
|
||||||
|
scale = 1 / part
|
||||||
|
}
|
||||||
|
for (let i = 0; i < points.length - 3;) {
|
||||||
|
//起始点
|
||||||
|
let pointS = points[i]
|
||||||
|
//第一个控制点
|
||||||
|
let pointC1 = points[i + 1]
|
||||||
|
//第二个控制点
|
||||||
|
let pointC2 = points[i + 2]
|
||||||
|
//结束点
|
||||||
|
let pointE = points[i + 3]
|
||||||
|
bezierPts.push(pointS)
|
||||||
|
for (let t = 0; t < 1;) {
|
||||||
|
//三次贝塞尔曲线公式
|
||||||
|
let x =
|
||||||
|
(1 - t) * (1 - t) * (1 - t) * pointS.x +
|
||||||
|
3 * t * (1 - t) * (1 - t) * pointC1.x +
|
||||||
|
3 * t * t * (1 - t) * pointC2.x +
|
||||||
|
t * t * t * pointE.x
|
||||||
|
let y =
|
||||||
|
(1 - t) * (1 - t) * (1 - t) * pointS.y +
|
||||||
|
3 * t * (1 - t) * (1 - t) * pointC1.y +
|
||||||
|
3 * t * t * (1 - t) * pointC2.y +
|
||||||
|
t * t * t * pointE.y
|
||||||
|
let point = { x: x, y: y }
|
||||||
|
bezierPts.push(point)
|
||||||
|
t += scale
|
||||||
|
}
|
||||||
|
i += 3
|
||||||
|
if (i >= points.length) {
|
||||||
|
bezierPts.push(pointS)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return bezierPts
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default DrawAssemble
|
||||||
263
src/Draw/drawAttackArrow.js
Normal file
263
src/Draw/drawAttackArrow.js
Normal file
@ -0,0 +1,263 @@
|
|||||||
|
/**
|
||||||
|
* @name: drawAttackArrow
|
||||||
|
* @author: Administrator
|
||||||
|
* @date: 2022-06-15 16:38
|
||||||
|
* @description:drawAttackArrow
|
||||||
|
* @update: 2022-06-15 16:38
|
||||||
|
*/
|
||||||
|
import Draw from './draw'
|
||||||
|
import MouseTip from '../MouseTip'
|
||||||
|
import MouseEvent from '../Event'
|
||||||
|
|
||||||
|
export default class DrawAttackArrow extends Draw {
|
||||||
|
constructor(sdk, options = {}) {
|
||||||
|
super(sdk, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
static create_arrow_polygon(that, viewer = that.viewer) {
|
||||||
|
that.entityHasCreated = true
|
||||||
|
let id = that.randomString()
|
||||||
|
viewer.entities.add(
|
||||||
|
new Cesium.Entity({
|
||||||
|
id: id,
|
||||||
|
polygon: {
|
||||||
|
classificationType: Cesium.ClassificationType.BOTH,
|
||||||
|
hierarchy: new Cesium.CallbackProperty((e) => {
|
||||||
|
let arr = that.computeAttackArrow(that.positions)
|
||||||
|
for (let i = 0; i < arr.length; i++) {
|
||||||
|
if (isNaN(arr[i].x)) {
|
||||||
|
arr = []
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new Cesium.PolygonHierarchy(arr)
|
||||||
|
}, false),
|
||||||
|
material: Cesium.Color.fromCssColorString(that.color),
|
||||||
|
zIndex: 99999999
|
||||||
|
},
|
||||||
|
})
|
||||||
|
)
|
||||||
|
return id
|
||||||
|
}
|
||||||
|
|
||||||
|
start(cb) {
|
||||||
|
if (YJ.Measure.GetMeasureStatus()) {
|
||||||
|
cb('上一次测量未结束')
|
||||||
|
} else {
|
||||||
|
super.start()
|
||||||
|
|
||||||
|
let into
|
||||||
|
YJ.Measure.SetMeasureStatus(true)
|
||||||
|
this.tip = new MouseTip('左键确定,右键结束;CTRL+右键撤销', this.sdk)
|
||||||
|
this.event = new MouseEvent(this.sdk)
|
||||||
|
this.positions = []
|
||||||
|
this.points_ids = [] //存放左键点击时临时添加的point的id
|
||||||
|
let cache_positions = []
|
||||||
|
let isMove = false
|
||||||
|
this.event.mouse_left((movement, cartesian) => {
|
||||||
|
if(into === '2D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
into = '3D'
|
||||||
|
if (!this.entityHasCreated) {
|
||||||
|
let polyline_id = DrawAttackArrow.create_arrow_polygon(this)
|
||||||
|
this.points_ids.push(polyline_id)
|
||||||
|
}
|
||||||
|
this.points_ids.push(this.create_point(cartesian))
|
||||||
|
cache_positions.push(this.cartesian3Towgs84(cartesian, this.viewer))
|
||||||
|
isMove = false
|
||||||
|
})
|
||||||
|
this.event.mouse_right((movement, cartesian) => {
|
||||||
|
if(into === '2D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let c = []
|
||||||
|
if (this.points_ids.length > 2) {
|
||||||
|
let positions = this.viewer.entities.getById(this.points_ids[0]).polygon.hierarchy.getValue().positions
|
||||||
|
positions.forEach(it => {
|
||||||
|
c.push(this.cartesian3Towgs84(it, this.viewer))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
this.end()
|
||||||
|
if (isMove) {
|
||||||
|
this.positions.pop()
|
||||||
|
}
|
||||||
|
cb(null, this.positions, c)
|
||||||
|
})
|
||||||
|
this.event.mouse_move((movement, cartesian) => {
|
||||||
|
if(into === '2D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
isMove = true
|
||||||
|
this.positions = cache_positions.concat(
|
||||||
|
this.cartesian3Towgs84(cartesian, this.viewer)
|
||||||
|
)
|
||||||
|
this.tip.setPosition(
|
||||||
|
cartesian,
|
||||||
|
movement.endPosition.x,
|
||||||
|
movement.endPosition.y
|
||||||
|
)
|
||||||
|
})
|
||||||
|
this.event.mouse_right_keyboard_ctrl((movement, cartesian) => {
|
||||||
|
if(into === '2D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (this.points_ids.length > 1) {
|
||||||
|
this.remove_entity(this.points_ids.pop()) //移除point
|
||||||
|
cache_positions.pop()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
this.event.gesture_pinck_start_keyboard_ctrl(() => {
|
||||||
|
if(into === '2D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (this.points_ids.length > 1) {
|
||||||
|
this.remove_entity(this.points_ids.pop()) //移除point
|
||||||
|
cache_positions.pop()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
this.event.gesture_pinck_start((movement, cartesian) => {
|
||||||
|
if(into === '2D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let startTime = new Date()
|
||||||
|
this.event.gesture_pinck_end(() => {
|
||||||
|
let endTime = new Date()
|
||||||
|
if (endTime - startTime >= 500) {
|
||||||
|
let c = []
|
||||||
|
if (this.points_ids.length > 2) {
|
||||||
|
let positions = this.viewer.entities.getById(this.points_ids[0]).polygon.hierarchy.getValue().positions
|
||||||
|
positions.forEach(it => {
|
||||||
|
c.push(this.cartesian3Towgs84(it, this.viewer))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
this.end()
|
||||||
|
cb(null, this.positions, c)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (!this.entityHasCreated) {
|
||||||
|
let polyline_id = DrawAttackArrow.create_arrow_polygon(this)
|
||||||
|
this.points_ids.push(polyline_id)
|
||||||
|
}
|
||||||
|
this.points_ids.push(this.create_point(cartesian))
|
||||||
|
cache_positions.push(this.cartesian3Towgs84(cartesian, this.viewer))
|
||||||
|
this.positions = cache_positions.concat(
|
||||||
|
this.cartesian3Towgs84(cartesian, this.viewer)
|
||||||
|
)
|
||||||
|
this.tip.setPosition(
|
||||||
|
cartesian,
|
||||||
|
(movement.position1.x + movement.position2.x) / 2,
|
||||||
|
(movement.position1.y + movement.position2.y) / 2
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!this._is2D && this._sdk2D) {
|
||||||
|
this.event2D = new MouseEvent(this._sdk2D)
|
||||||
|
this.event2D.mouse_left((movement, cartesian) => {
|
||||||
|
if(into === '3D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
into = '2D'
|
||||||
|
if (!this.entityHasCreated) {
|
||||||
|
let polyline_id = DrawAttackArrow.create_arrow_polygon(this, this._sdk2D.viewer)
|
||||||
|
this.points_ids.push(polyline_id)
|
||||||
|
}
|
||||||
|
this.points_ids.push(this.create_point(cartesian, this._sdk2D.viewer))
|
||||||
|
cache_positions.push(this.cartesian3Towgs84(cartesian, this.viewer))
|
||||||
|
isMove = false
|
||||||
|
})
|
||||||
|
this.event2D.mouse_right((movement, cartesian) => {
|
||||||
|
if(into === '3D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let c = []
|
||||||
|
if (this.points_ids.length > 2) {
|
||||||
|
let positions = this.event2D.viewer.entities.getById(this.points_ids[0]).polygon.hierarchy.getValue().positions
|
||||||
|
positions.forEach(it => {
|
||||||
|
c.push(this.cartesian3Towgs84(it, this.viewer))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
this.end()
|
||||||
|
if (isMove) {
|
||||||
|
this.positions.pop()
|
||||||
|
}
|
||||||
|
cb(null, this.positions, c)
|
||||||
|
})
|
||||||
|
this.event2D.mouse_move((movement, cartesian) => {
|
||||||
|
if(into === '3D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
isMove = true
|
||||||
|
this.positions = cache_positions.concat(
|
||||||
|
this.cartesian3Towgs84(cartesian, this.viewer)
|
||||||
|
)
|
||||||
|
this.tip.setPosition(
|
||||||
|
cartesian,
|
||||||
|
movement.endPosition.x + this.viewer.canvas.width,
|
||||||
|
movement.endPosition.y
|
||||||
|
)
|
||||||
|
})
|
||||||
|
this.event2D.mouse_right_keyboard_ctrl((movement, cartesian) => {
|
||||||
|
if(into === '3D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (this.points_ids.length > 1) {
|
||||||
|
this.remove_entity(this.points_ids.pop()) //移除point
|
||||||
|
cache_positions.pop()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
this.event2D.gesture_pinck_start_keyboard_ctrl(() => {
|
||||||
|
if(into === '3D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (this.points_ids.length > 1) {
|
||||||
|
this.remove_entity(this.points_ids.pop()) //移除point
|
||||||
|
cache_positions.pop()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
this.event2D.gesture_pinck_start((movement, cartesian) => {
|
||||||
|
if(into === '3D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let startTime = new Date()
|
||||||
|
this.event2D.gesture_pinck_end(() => {
|
||||||
|
let endTime = new Date()
|
||||||
|
if (endTime - startTime >= 500) {
|
||||||
|
let c = []
|
||||||
|
if (this.points_ids.length > 2) {
|
||||||
|
let positions = this.viewer.entities.getById(this.points_ids[0]).polygon.hierarchy.getValue().positions
|
||||||
|
positions.forEach(it => {
|
||||||
|
c.push(this.cartesian3Towgs84(it, this.viewer))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
this.end()
|
||||||
|
cb(null, this.positions, c)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (!this.entityHasCreated) {
|
||||||
|
let polyline_id = DrawAttackArrow.create_arrow_polygon(this, this._sdk2D.viewer)
|
||||||
|
this.points_ids.push(polyline_id)
|
||||||
|
}
|
||||||
|
this.points_ids.push(this.create_point(cartesian, this._sdk2D.viewer))
|
||||||
|
cache_positions.push(this.cartesian3Towgs84(cartesian, this.viewer))
|
||||||
|
this.positions = cache_positions.concat(
|
||||||
|
this.cartesian3Towgs84(cartesian, this.viewer)
|
||||||
|
)
|
||||||
|
this.tip.setPosition(
|
||||||
|
cartesian,
|
||||||
|
((movement.position1.x + movement.position2.x) / 2) + this.viewer.canvas.width,
|
||||||
|
(movement.position1.y + movement.position2.y) / 2
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
271
src/Draw/drawCircle.js
Normal file
271
src/Draw/drawCircle.js
Normal file
@ -0,0 +1,271 @@
|
|||||||
|
/**
|
||||||
|
* @name: drawCircle
|
||||||
|
* @author: Administrator
|
||||||
|
* @date: 2022-06-15 14:55
|
||||||
|
* @description:drawCircle
|
||||||
|
* @update: 2022-06-15 14:55
|
||||||
|
*/
|
||||||
|
import Draw from './draw'
|
||||||
|
import MouseTip from '../MouseTip'
|
||||||
|
import MouseEvent from '../Event'
|
||||||
|
|
||||||
|
export default class DrawCircle extends Draw {
|
||||||
|
constructor(sdk, options = {}) {
|
||||||
|
super(sdk, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
start(cb) {
|
||||||
|
if (YJ.Measure.GetMeasureStatus()) {
|
||||||
|
cb('上一次测量未结束')
|
||||||
|
} else {
|
||||||
|
super.start()
|
||||||
|
let into
|
||||||
|
YJ.Measure.SetMeasureStatus(true)
|
||||||
|
this.tip = new MouseTip('左键开始,右键取消', this.sdk)
|
||||||
|
this.event = new MouseEvent(this.sdk)
|
||||||
|
let clickNum = 0
|
||||||
|
this.circle_id = this.randomString() //圆id
|
||||||
|
let radius_points = []
|
||||||
|
let cache_points = []
|
||||||
|
let radius = 1 //默认半径
|
||||||
|
let positions = []
|
||||||
|
let center = {}
|
||||||
|
let endpoint = null
|
||||||
|
|
||||||
|
this.event.mouse_left((movement, cartesian) => {
|
||||||
|
if(into === '2D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
into = '3D'
|
||||||
|
this.tip.set_text('再次左键,完成绘制;右键取消')
|
||||||
|
clickNum++
|
||||||
|
if (clickNum === 1) {
|
||||||
|
this.point_id = this.create_point(cartesian)
|
||||||
|
center = this.cartesian3Towgs84(cartesian, this.viewer)
|
||||||
|
positions = this.createCircle(center, 0.01)
|
||||||
|
cache_points.push(cartesian)
|
||||||
|
createCirclePolygon()
|
||||||
|
}
|
||||||
|
if (clickNum === 2) {
|
||||||
|
radius_points = cache_points.concat(cartesian)
|
||||||
|
endpoint = this.cartesian3Towgs84(cartesian, this.viewer)
|
||||||
|
radius = this.computeDistance([center, endpoint])
|
||||||
|
positions = this.createCircle(center, radius)
|
||||||
|
this.end()
|
||||||
|
cb(null, { center, radius: Number(radius) })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.event.mouse_right((movement, cartesian) => {
|
||||||
|
if(into === '2D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.end()
|
||||||
|
cb(false)
|
||||||
|
})
|
||||||
|
this.event.mouse_move((movement, cartesian) => {
|
||||||
|
if(into === '2D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.tip.setPosition(
|
||||||
|
cartesian,
|
||||||
|
movement.endPosition.x,
|
||||||
|
movement.endPosition.y
|
||||||
|
)
|
||||||
|
if (clickNum) {
|
||||||
|
radius_points = cache_points.concat(cartesian)
|
||||||
|
endpoint = this.cartesian3Towgs84(cartesian, this.viewer)
|
||||||
|
radius = this.computeDistance([center, endpoint])
|
||||||
|
positions = this.createCircle(center, radius)
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
this.event.gesture_pinck_start((movement, cartesian) => {
|
||||||
|
if(into === '2D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let startTime = new Date()
|
||||||
|
this.event.gesture_pinck_end(() => {
|
||||||
|
let endTime = new Date()
|
||||||
|
if (endTime - startTime >= 500) {
|
||||||
|
this.end()
|
||||||
|
cb(false)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.tip.set_text('再次左键,完成绘制;右键取消')
|
||||||
|
clickNum++
|
||||||
|
if (clickNum === 1) {
|
||||||
|
this.point_id = this.create_point(cartesian)
|
||||||
|
center = this.cartesian3Towgs84(cartesian, this.viewer)
|
||||||
|
cache_points.push(cartesian)
|
||||||
|
createCirclePolygon()
|
||||||
|
this.tip.setPosition(
|
||||||
|
cartesian,
|
||||||
|
(movement.position1.x + movement.position2.x) / 2,
|
||||||
|
(movement.position1.y + movement.position2.y) / 2
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if (clickNum === 2) {
|
||||||
|
radius_points = cache_points.concat(cartesian)
|
||||||
|
endpoint = this.cartesian3Towgs84(cartesian, this.viewer)
|
||||||
|
radius = this.computeDistance([center, endpoint])
|
||||||
|
positions = this.createCircle(center, radius)
|
||||||
|
this.end()
|
||||||
|
cb(null, { center, radius: Number(radius) })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!this._is2D && this._sdk2D) {
|
||||||
|
this.event2D = new MouseEvent(this._sdk2D)
|
||||||
|
this.event2D.mouse_left((movement, cartesian) => {
|
||||||
|
if(into === '3D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
into = '2D'
|
||||||
|
this.tip.set_text('再次左键,完成绘制;右键取消')
|
||||||
|
clickNum++
|
||||||
|
if (clickNum === 1) {
|
||||||
|
this.point_id = this.create_point(cartesian, this._sdk2D.viewer)
|
||||||
|
center = this.cartesian3Towgs84(cartesian, this.viewer)
|
||||||
|
positions = this.createCircle(center, 0.01)
|
||||||
|
cache_points.push(cartesian)
|
||||||
|
createCirclePolygon(this._sdk2D.viewer)
|
||||||
|
}
|
||||||
|
if (clickNum === 2) {
|
||||||
|
radius_points = cache_points.concat(cartesian)
|
||||||
|
endpoint = this.cartesian3Towgs84(cartesian, this.viewer)
|
||||||
|
radius = this.computeDistance([center, endpoint])
|
||||||
|
positions = this.createCircle(center, radius)
|
||||||
|
this.end()
|
||||||
|
cb(null, { center, radius: Number(radius) })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.event2D.mouse_right((movement, cartesian) => {
|
||||||
|
if(into === '3D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.end()
|
||||||
|
cb(false)
|
||||||
|
})
|
||||||
|
this.event2D.mouse_move((movement, cartesian) => {
|
||||||
|
if(into === '3D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.tip.setPosition(
|
||||||
|
cartesian,
|
||||||
|
movement.endPosition.x + this.viewer.canvas.width,
|
||||||
|
movement.endPosition.y
|
||||||
|
)
|
||||||
|
if (clickNum) {
|
||||||
|
radius_points = cache_points.concat(cartesian)
|
||||||
|
endpoint = this.cartesian3Towgs84(cartesian, this.viewer)
|
||||||
|
radius = this.computeDistance([center, endpoint])
|
||||||
|
positions = this.createCircle(center, radius)
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
this.event2D.gesture_pinck_start((movement, cartesian) => {
|
||||||
|
if(into === '3D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let startTime = new Date()
|
||||||
|
this.event2D.gesture_pinck_end(() => {
|
||||||
|
let endTime = new Date()
|
||||||
|
if (endTime - startTime >= 500) {
|
||||||
|
this.end()
|
||||||
|
cb(false)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.tip.set_text('再次左键,完成绘制;右键取消')
|
||||||
|
clickNum++
|
||||||
|
if (clickNum === 1) {
|
||||||
|
this.point_id = this.create_point(cartesian, this._sdk2D.viewer)
|
||||||
|
center = this.cartesian3Towgs84(cartesian, this.viewer)
|
||||||
|
cache_points.push(cartesian)
|
||||||
|
createCirclePolygon(this._sdk2D.viewer)
|
||||||
|
this.tip.setPosition(
|
||||||
|
cartesian,
|
||||||
|
((movement.position1.x + movement.position2.x) / 2) + this.viewer.canvas.width,
|
||||||
|
(movement.position1.y + movement.position2.y) / 2
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if (clickNum === 2) {
|
||||||
|
radius_points = cache_points.concat(cartesian)
|
||||||
|
endpoint = this.cartesian3Towgs84(cartesian, this.viewer)
|
||||||
|
radius = this.computeDistance([center, endpoint])
|
||||||
|
positions = this.createCircle(center, radius)
|
||||||
|
this.end()
|
||||||
|
cb(null, { center, radius: Number(radius) })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
let that = this
|
||||||
|
|
||||||
|
function createCirclePolygon(viewer = that.viewer) {
|
||||||
|
let a = viewer.entities.add(
|
||||||
|
new Cesium.Entity({
|
||||||
|
id: that.circle_id,
|
||||||
|
position: new Cesium.CallbackProperty((e) => {
|
||||||
|
if (endpoint) {
|
||||||
|
let c = that.computeMidpoint(center, endpoint)
|
||||||
|
return Cesium.Cartesian3.fromDegrees(c.lng, c.lat, endpoint.alt)
|
||||||
|
} else {
|
||||||
|
return Cesium.Cartesian3()
|
||||||
|
}
|
||||||
|
}, false),
|
||||||
|
label: {
|
||||||
|
text: new Cesium.CallbackProperty((e) => {
|
||||||
|
if (radius > 1000) {
|
||||||
|
return '半径:' + (radius / 1000).toFixed(2) + ' 公里'
|
||||||
|
}
|
||||||
|
return '半径:' + radius + ' 米'
|
||||||
|
}, false),
|
||||||
|
font: '20px Microsoft YaHei',
|
||||||
|
distanceDisplayCondition: 10000000,
|
||||||
|
scale: 1,
|
||||||
|
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
|
||||||
|
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||||||
|
fillColor: Cesium.Color.fromCssColorString('#f5ce0a'),
|
||||||
|
style: Cesium.LabelStyle.FILL_AND_OUTLINE
|
||||||
|
},
|
||||||
|
polygon: {
|
||||||
|
classificationType: Cesium.ClassificationType.BOTH,
|
||||||
|
hierarchy: new Cesium.CallbackProperty((e) => {
|
||||||
|
return new Cesium.PolygonHierarchy(
|
||||||
|
Cesium.Cartesian3.fromDegreesArray(positions)
|
||||||
|
)
|
||||||
|
}, false),
|
||||||
|
material: Cesium.Color.fromCssColorString(that.color),
|
||||||
|
zIndex: 99999999
|
||||||
|
},
|
||||||
|
polyline: {
|
||||||
|
positions: new Cesium.CallbackProperty((e) => {
|
||||||
|
return radius_points
|
||||||
|
}, false),
|
||||||
|
width: 2,
|
||||||
|
material:
|
||||||
|
Cesium.Color.fromCssColorString('#c1c505').withAlpha(0.5),
|
||||||
|
clampToGround: true,
|
||||||
|
zIndex: 99999999
|
||||||
|
}
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
end() {
|
||||||
|
this.remove_entity(this.circle_id)
|
||||||
|
this.remove_entity(this.point_id)
|
||||||
|
YJ.Measure.SetMeasureStatus(false)
|
||||||
|
this.tip && this.tip.destroy()
|
||||||
|
this.event && this.event.destroy()
|
||||||
|
this.event2D && this.event2D.destroy()
|
||||||
|
}
|
||||||
|
}
|
||||||
244
src/Draw/drawElliptic.js
Normal file
244
src/Draw/drawElliptic.js
Normal file
@ -0,0 +1,244 @@
|
|||||||
|
import Draw from './draw'
|
||||||
|
import MouseTip from '../MouseTip'
|
||||||
|
import MouseEvent from '../Event'
|
||||||
|
|
||||||
|
export default class DrawElliptic extends Draw {
|
||||||
|
constructor(sdk, options = {}) {
|
||||||
|
super(sdk, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
start(cb) {
|
||||||
|
if (YJ.Measure.GetMeasureStatus()) {
|
||||||
|
cb('上一次测量未结束')
|
||||||
|
} else {
|
||||||
|
super.start()
|
||||||
|
let into
|
||||||
|
this.entity_ids = []
|
||||||
|
YJ.Measure.SetMeasureStatus(true)
|
||||||
|
this.tip = new MouseTip('左键开始,右键取消', this.sdk)
|
||||||
|
this.event = new MouseEvent(this.sdk)
|
||||||
|
let clickNum = 0
|
||||||
|
this.elliptic_id = this.randomString() //圆id
|
||||||
|
let radius_points = []
|
||||||
|
let cache_points = []
|
||||||
|
let cache_84_position = []
|
||||||
|
let radius = 1 //默认半径
|
||||||
|
let positions = []
|
||||||
|
let center
|
||||||
|
let semiMinorAxis = 0
|
||||||
|
let semiMajorAxis = 0
|
||||||
|
let endpoint = null
|
||||||
|
let distanceAB = 0
|
||||||
|
let distanceAC = 0
|
||||||
|
let distanceBC = 0
|
||||||
|
let bearing = 0
|
||||||
|
|
||||||
|
this.event.mouse_left((movement, cartesian) => {
|
||||||
|
if(into === '2D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
into = '3D'
|
||||||
|
this.tip.set_text('再次左键,完成绘制;右键取消')
|
||||||
|
clickNum++
|
||||||
|
this.points_ids.push(this.create_point(cartesian))
|
||||||
|
cache_points.push(cartesian)
|
||||||
|
if (clickNum === 1) {
|
||||||
|
cache_points = [cartesian, cartesian, cartesian]
|
||||||
|
let pos84 = this.cartesian3Towgs84(cartesian, this.viewer)
|
||||||
|
center = pos84
|
||||||
|
cache_84_position = [pos84, pos84, pos84]
|
||||||
|
|
||||||
|
calculateElliptic()
|
||||||
|
createEllipticPolygon()
|
||||||
|
}
|
||||||
|
if (clickNum === 2) {
|
||||||
|
cache_points[1] = cartesian
|
||||||
|
cache_points[2] = cartesian
|
||||||
|
let pos84 = this.cartesian3Towgs84(cartesian, this.viewer)
|
||||||
|
cache_84_position[1] = pos84
|
||||||
|
cache_84_position[2] = pos84
|
||||||
|
}
|
||||||
|
if (clickNum >= 3) {
|
||||||
|
this.end()
|
||||||
|
cb(null, { center, bearing, semiMajorAxis, semiMinorAxis })
|
||||||
|
}
|
||||||
|
// if (clickNum === 2) {
|
||||||
|
// radius_points = cache_points.concat(cartesian)
|
||||||
|
// endpoint = this.cartesian3Towgs84(cartesian, this.viewer)
|
||||||
|
// radius = this.computeDistance([center, endpoint])
|
||||||
|
// positions = this.createCircle(center, radius)
|
||||||
|
// this.end()
|
||||||
|
// cb(null, { center, radius: Number(radius) })
|
||||||
|
// }
|
||||||
|
})
|
||||||
|
this.event.mouse_right((movement, cartesian) => {
|
||||||
|
if(into === '2D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.end()
|
||||||
|
cb(false)
|
||||||
|
})
|
||||||
|
this.event.mouse_move((movement, cartesian) => {
|
||||||
|
if(into === '2D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.tip.setPosition(
|
||||||
|
cartesian,
|
||||||
|
movement.endPosition.x,
|
||||||
|
movement.endPosition.y
|
||||||
|
)
|
||||||
|
cache_points[clickNum] = cartesian
|
||||||
|
cache_84_position[clickNum] = this.cartesian3Towgs84(cartesian, this.viewer)
|
||||||
|
if (clickNum !== 0) {
|
||||||
|
calculateElliptic()
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!this._is2D && this._sdk2D) {
|
||||||
|
this.event2D = new MouseEvent(this._sdk2D)
|
||||||
|
this.event2D.mouse_left((movement, cartesian) => {
|
||||||
|
if(into === '3D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
into = '2D'
|
||||||
|
this.tip.set_text('再次左键,完成绘制;右键取消')
|
||||||
|
clickNum++
|
||||||
|
this.points_ids.push(this.create_point(cartesian, this._sdk2D.viewer))
|
||||||
|
cache_points.push(cartesian)
|
||||||
|
if (clickNum === 1) {
|
||||||
|
cache_points = [cartesian, cartesian, cartesian]
|
||||||
|
let pos84 = this.cartesian3Towgs84(cartesian, this.viewer)
|
||||||
|
center = pos84
|
||||||
|
cache_84_position = [pos84, pos84, pos84]
|
||||||
|
|
||||||
|
calculateElliptic()
|
||||||
|
createEllipticPolygon(this._sdk2D.viewer)
|
||||||
|
}
|
||||||
|
if (clickNum === 2) {
|
||||||
|
cache_points[1] = cartesian
|
||||||
|
cache_points[2] = cartesian
|
||||||
|
let pos84 = this.cartesian3Towgs84(cartesian, this.viewer)
|
||||||
|
cache_84_position[1] = pos84
|
||||||
|
cache_84_position[2] = pos84
|
||||||
|
}
|
||||||
|
if (clickNum >= 3) {
|
||||||
|
this.end()
|
||||||
|
cb(null, { center, bearing, semiMajorAxis, semiMinorAxis })
|
||||||
|
}
|
||||||
|
// if (clickNum === 2) {
|
||||||
|
// radius_points = cache_points.concat(cartesian)
|
||||||
|
// endpoint = this.cartesian3Towgs84(cartesian, this.viewer)
|
||||||
|
// radius = this.computeDistance([center, endpoint])
|
||||||
|
// positions = this.createCircle(center, radius)
|
||||||
|
// this.end()
|
||||||
|
// cb(null, { center, radius: Number(radius) })
|
||||||
|
// }
|
||||||
|
})
|
||||||
|
this.event2D.mouse_right((movement, cartesian) => {
|
||||||
|
if(into === '3D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.end()
|
||||||
|
cb(false)
|
||||||
|
})
|
||||||
|
this.event2D.mouse_move((movement, cartesian) => {
|
||||||
|
if(into === '3D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.tip.setPosition(
|
||||||
|
cartesian,
|
||||||
|
movement.endPosition.x + this.viewer.canvas.width,
|
||||||
|
movement.endPosition.y
|
||||||
|
)
|
||||||
|
cache_points[clickNum] = cartesian
|
||||||
|
cache_84_position[clickNum] = this.cartesian3Towgs84(cartesian, this.viewer)
|
||||||
|
if (clickNum !== 0) {
|
||||||
|
calculateElliptic()
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
let that = this
|
||||||
|
|
||||||
|
function calculateElliptic() {
|
||||||
|
let pointA = Cesium.Cartesian3.fromDegrees(cache_84_position[0].lng, cache_84_position[0].lat);
|
||||||
|
let pointB = Cesium.Cartesian3.fromDegrees(cache_84_position[1].lng, cache_84_position[1].lat);
|
||||||
|
let pointC = Cesium.Cartesian3.fromDegrees(cache_84_position[2].lng, cache_84_position[2].lat);
|
||||||
|
if (clickNum === 1) {
|
||||||
|
distanceAB = Cesium.Cartesian3.distance(pointA, pointB);
|
||||||
|
semiMajorAxis = distanceAB
|
||||||
|
semiMinorAxis = semiMajorAxis / 2;
|
||||||
|
|
||||||
|
let start = { x: center.lng, y: center.lat }
|
||||||
|
let end = { x: cache_84_position[1].lng, y: cache_84_position[1].lat }
|
||||||
|
|
||||||
|
let rad = Math.PI / 180,
|
||||||
|
lat1 = start.y * rad,
|
||||||
|
lat2 = end.y * rad,
|
||||||
|
lon1 = start.x * rad,
|
||||||
|
lon2 = end.x * rad;
|
||||||
|
const a = Math.sin(lon2 - lon1) * Math.cos(lat2);
|
||||||
|
const b =
|
||||||
|
Math.cos(lat1) * Math.sin(lat2) -
|
||||||
|
Math.sin(lat1) * Math.cos(lat2) * Math.cos(lon2 - lon1);
|
||||||
|
const radians = Math.atan2(a, b)
|
||||||
|
const degrees = radians % (2 * Math.PI);
|
||||||
|
bearing = 450 - ((degrees * 180) / Math.PI < 0
|
||||||
|
? 360 + (degrees * 180) / Math.PI
|
||||||
|
: (degrees * 180) / Math.PI);
|
||||||
|
}
|
||||||
|
if (clickNum === 2) {
|
||||||
|
distanceAC = Cesium.Cartesian3.distance(pointA, pointC);
|
||||||
|
distanceBC = Cesium.Cartesian3.distance(pointB, pointC);
|
||||||
|
|
||||||
|
let point1 = turf.point([cache_84_position[0].lng, cache_84_position[0].lat]);
|
||||||
|
let point2 = turf.point([cache_84_position[1].lng, cache_84_position[1].lat]);
|
||||||
|
let point3 = turf.point([cache_84_position[2].lng, cache_84_position[2].lat]);
|
||||||
|
const bearing1 = turf.rhumbBearing(point1, point2);
|
||||||
|
const bearing2 = turf.rhumbBearing(point2, point3);
|
||||||
|
const angleDiff = Math.abs(bearing1 - bearing2);
|
||||||
|
let finalAngle = angleDiff > 180 ? 360 - angleDiff : angleDiff;
|
||||||
|
finalAngle = 180 - finalAngle
|
||||||
|
|
||||||
|
semiMinorAxis = distanceBC * Math.sin(Cesium.Math.toRadians(finalAngle));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function createEllipticPolygon(viewer = that.viewer) {
|
||||||
|
viewer.entities.add(
|
||||||
|
new Cesium.Entity({
|
||||||
|
id: that.elliptic_id,
|
||||||
|
position: Cesium.Cartesian3.fromDegrees(center.lng, center.lat),
|
||||||
|
ellipse: {
|
||||||
|
semiMinorAxis: new Cesium.CallbackProperty((e) => {
|
||||||
|
return semiMinorAxis
|
||||||
|
}, false),
|
||||||
|
semiMajorAxis: new Cesium.CallbackProperty((e) => {
|
||||||
|
return semiMajorAxis
|
||||||
|
}, false),
|
||||||
|
granularity: Cesium.Math.toRadians(0.1),
|
||||||
|
rotation: new Cesium.CallbackProperty((e) => {
|
||||||
|
return Cesium.Math.toRadians(bearing)
|
||||||
|
}, false),
|
||||||
|
material: Cesium.Color.fromCssColorString(that.color),
|
||||||
|
zIndex: 99999999
|
||||||
|
}
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
end() {
|
||||||
|
this.remove_entity(this.elliptic_id)
|
||||||
|
this.points_ids.forEach((id) => {
|
||||||
|
this.remove_entity(id)
|
||||||
|
})
|
||||||
|
YJ.Measure.SetMeasureStatus(false)
|
||||||
|
this.tip && this.tip.destroy()
|
||||||
|
this.event && this.event.destroy()
|
||||||
|
this.event2D && this.event2D.destroy()
|
||||||
|
}
|
||||||
|
}
|
||||||
273
src/Draw/drawPincerArrow.js
Normal file
273
src/Draw/drawPincerArrow.js
Normal file
@ -0,0 +1,273 @@
|
|||||||
|
/**
|
||||||
|
* @name: drawPincerArrow
|
||||||
|
* @author: Administrator
|
||||||
|
* @date: 2022-06-15 17:12
|
||||||
|
* @description:drawPincerArrow
|
||||||
|
* @update: 2022-06-15 17:12
|
||||||
|
*/
|
||||||
|
import Draw from './draw'
|
||||||
|
import MouseTip from '../MouseTip'
|
||||||
|
import MouseEvent from '../Event'
|
||||||
|
|
||||||
|
export default class DrawPincerArrow extends Draw {
|
||||||
|
constructor(sdk, options = {}) {
|
||||||
|
super(sdk, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
static create_arrow_polygon(that, viewer = that.viewer) {
|
||||||
|
that.entityHasCreated = true
|
||||||
|
let id = that.randomString()
|
||||||
|
viewer.entities.add(
|
||||||
|
new Cesium.Entity({
|
||||||
|
id: id,
|
||||||
|
polygon: {
|
||||||
|
classificationType: Cesium.ClassificationType.BOTH,
|
||||||
|
hierarchy: new Cesium.CallbackProperty((e) => {
|
||||||
|
let arr = that.computePincerArrow(that.positions)
|
||||||
|
for (let i = 0; i < arr.length; i++) {
|
||||||
|
if (isNaN(arr[i].x)) {
|
||||||
|
arr = []
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new Cesium.PolygonHierarchy(arr)
|
||||||
|
}, false),
|
||||||
|
material: Cesium.Color.fromCssColorString(that.color),
|
||||||
|
zIndex: 99999999
|
||||||
|
},
|
||||||
|
})
|
||||||
|
)
|
||||||
|
return id
|
||||||
|
}
|
||||||
|
|
||||||
|
start(cb) {
|
||||||
|
if (YJ.Measure.GetMeasureStatus()) {
|
||||||
|
cb('上一次测量未结束')
|
||||||
|
} else {
|
||||||
|
super.start()
|
||||||
|
let into
|
||||||
|
YJ.Measure.SetMeasureStatus(true)
|
||||||
|
this.tip = new MouseTip('左键确定,右键取消;CTRL+右键撤销', this.sdk)
|
||||||
|
this.event = new MouseEvent(this.sdk)
|
||||||
|
this.positions = []
|
||||||
|
this.points_ids = [] //存放左键点击时临时添加的point的id
|
||||||
|
let cache_positions = []
|
||||||
|
this.event.mouse_left((movement, cartesian) => {
|
||||||
|
if(into === '2D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
into = '3D'
|
||||||
|
if (!this.entityHasCreated) {
|
||||||
|
let polyline_id = DrawPincerArrow.create_arrow_polygon(this)
|
||||||
|
this.points_ids.push(polyline_id)
|
||||||
|
}
|
||||||
|
this.points_ids.push(this.create_point(cartesian))
|
||||||
|
cache_positions.push(this.cartesian3Towgs84(cartesian, this.viewer))
|
||||||
|
if (cache_positions.length === 5) {
|
||||||
|
let c = []
|
||||||
|
if (this.points_ids.length > 2) {
|
||||||
|
let positions = this.viewer.entities.getById(this.points_ids[0]).polygon.hierarchy.getValue().positions
|
||||||
|
positions.forEach(it => {
|
||||||
|
c.push(this.cartesian3Towgs84(it, this.viewer))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
this.end()
|
||||||
|
cb(null, cache_positions, c)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.event.mouse_right((movement, cartesian) => {
|
||||||
|
if(into === '2D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.end()
|
||||||
|
cb('取消绘制')
|
||||||
|
})
|
||||||
|
this.event.mouse_move((movement, cartesian) => {
|
||||||
|
if(into === '2D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.positions = cache_positions.concat(
|
||||||
|
this.cartesian3Towgs84(cartesian, this.viewer)
|
||||||
|
)
|
||||||
|
this.tip.setPosition(
|
||||||
|
cartesian,
|
||||||
|
movement.endPosition.x,
|
||||||
|
movement.endPosition.y
|
||||||
|
)
|
||||||
|
})
|
||||||
|
this.event.mouse_right_keyboard_ctrl((movement, cartesian) => {
|
||||||
|
if(into === '2D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (this.points_ids.length > 1) {
|
||||||
|
this.remove_entity(this.points_ids.pop()) //移除point
|
||||||
|
cache_positions.pop()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
this.event.gesture_pinck_start_keyboard_ctrl(() => {
|
||||||
|
if(into === '2D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (this.points_ids.length > 1) {
|
||||||
|
this.remove_entity(this.points_ids.pop()) //移除point
|
||||||
|
cache_positions.pop()
|
||||||
|
this.positions = cache_positions.concat(
|
||||||
|
this.cartesian3Towgs84(cartesian, this.viewer)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
this.event.gesture_pinck_start((movement, cartesian) => {
|
||||||
|
if(into === '2D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let startTime = new Date()
|
||||||
|
this.event.gesture_pinck_end(() => {
|
||||||
|
let endTime = new Date()
|
||||||
|
if (endTime - startTime >= 500) {
|
||||||
|
this.end()
|
||||||
|
cb('取消绘制')
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (!this.entityHasCreated) {
|
||||||
|
let polyline_id = DrawPincerArrow.create_arrow_polygon(this)
|
||||||
|
this.points_ids.push(polyline_id)
|
||||||
|
}
|
||||||
|
this.points_ids.push(this.create_point(cartesian))
|
||||||
|
cache_positions.push(this.cartesian3Towgs84(cartesian, this.viewer))
|
||||||
|
this.positions = cache_positions.concat(
|
||||||
|
this.cartesian3Towgs84(cartesian, this.viewer)
|
||||||
|
)
|
||||||
|
this.tip.setPosition(
|
||||||
|
cartesian,
|
||||||
|
(movement.position1.x + movement.position2.x) / 2,
|
||||||
|
(movement.position1.y + movement.position2.y) / 2
|
||||||
|
)
|
||||||
|
if (cache_positions.length === 5) {
|
||||||
|
let c = []
|
||||||
|
if (this.points_ids.length > 2) {
|
||||||
|
let positions = this.viewer.entities.getById(this.points_ids[0]).polygon.hierarchy.getValue().positions
|
||||||
|
positions.forEach(it => {
|
||||||
|
c.push(this.cartesian3Towgs84(it, this.viewer))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
this.end()
|
||||||
|
cb(null, cache_positions, c)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!this._is2D && this._sdk2D) {
|
||||||
|
this.event2D = new MouseEvent(this._sdk2D)
|
||||||
|
this.event2D.mouse_left((movement, cartesian) => {
|
||||||
|
if(into === '3D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
into = '2D'
|
||||||
|
if (!this.entityHasCreated) {
|
||||||
|
let polyline_id = DrawPincerArrow.create_arrow_polygon(this, this._sdk2D.viewer)
|
||||||
|
this.points_ids.push(polyline_id)
|
||||||
|
}
|
||||||
|
this.points_ids.push(this.create_point(cartesian, this._sdk2D.viewer))
|
||||||
|
cache_positions.push(this.cartesian3Towgs84(cartesian, this.viewer))
|
||||||
|
if (cache_positions.length === 5) {
|
||||||
|
let c = []
|
||||||
|
if (this.points_ids.length > 2) {
|
||||||
|
let positions = this.event2D.viewer.entities.getById(this.points_ids[0]).polygon.hierarchy.getValue().positions
|
||||||
|
positions.forEach(it => {
|
||||||
|
c.push(this.cartesian3Towgs84(it, this.viewer))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
this.end()
|
||||||
|
cb(null, cache_positions, c)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.event2D.mouse_right((movement, cartesian) => {
|
||||||
|
if(into === '3D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.end()
|
||||||
|
cb('取消绘制')
|
||||||
|
})
|
||||||
|
this.event2D.mouse_move((movement, cartesian) => {
|
||||||
|
if(into === '3D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.positions = cache_positions.concat(
|
||||||
|
this.cartesian3Towgs84(cartesian, this.viewer)
|
||||||
|
)
|
||||||
|
this.tip.setPosition(
|
||||||
|
cartesian,
|
||||||
|
movement.endPosition.x + this.viewer.canvas.width,
|
||||||
|
movement.endPosition.y
|
||||||
|
)
|
||||||
|
})
|
||||||
|
this.event2D.mouse_right_keyboard_ctrl((movement, cartesian) => {
|
||||||
|
if(into === '3D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (this.points_ids.length > 1) {
|
||||||
|
this.remove_entity(this.points_ids.pop()) //移除point
|
||||||
|
cache_positions.pop()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
this.event2D.gesture_pinck_start_keyboard_ctrl(() => {
|
||||||
|
if(into === '3D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (this.points_ids.length > 1) {
|
||||||
|
this.remove_entity(this.points_ids.pop()) //移除point
|
||||||
|
cache_positions.pop()
|
||||||
|
this.positions = cache_positions.concat(
|
||||||
|
this.cartesian3Towgs84(cartesian, this.viewer)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
this.event2D.gesture_pinck_start((movement, cartesian) => {
|
||||||
|
if(into === '3D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let startTime = new Date()
|
||||||
|
this.event2D.gesture_pinck_end(() => {
|
||||||
|
let endTime = new Date()
|
||||||
|
if (endTime - startTime >= 500) {
|
||||||
|
this.end()
|
||||||
|
cb('取消绘制')
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (!this.entityHasCreated) {
|
||||||
|
let polyline_id = DrawPincerArrow.create_arrow_polygon(this, this._sdk2D.viewer)
|
||||||
|
this.points_ids.push(polyline_id)
|
||||||
|
}
|
||||||
|
this.points_ids.push(this.create_point(cartesian, this._sdk2D.viewer))
|
||||||
|
cache_positions.push(this.cartesian3Towgs84(cartesian, this.viewer))
|
||||||
|
this.positions = cache_positions.concat(
|
||||||
|
this.cartesian3Towgs84(cartesian, this.viewer)
|
||||||
|
)
|
||||||
|
this.tip.setPosition(
|
||||||
|
cartesian,
|
||||||
|
((movement.position1.x + movement.position2.x) / 2) + this.viewer.canvas.width,
|
||||||
|
(movement.position1.y + movement.position2.y) / 2
|
||||||
|
)
|
||||||
|
if (cache_positions.length === 5) {
|
||||||
|
let c = []
|
||||||
|
if (this.points_ids.length > 2) {
|
||||||
|
let positions = this.event2D.viewer.entities.getById(this.points_ids[0]).polygon.hierarchy.getValue().positions
|
||||||
|
positions.forEach(it => {
|
||||||
|
c.push(this.cartesian3Towgs84(it, this.viewer))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
this.end()
|
||||||
|
cb(null, cache_positions, c)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
116
src/Draw/drawPoint.js
Normal file
116
src/Draw/drawPoint.js
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
import MouseTip from '../MouseTip'
|
||||||
|
import MouseEvent from '../Event'
|
||||||
|
import Draw from "./draw";
|
||||||
|
|
||||||
|
|
||||||
|
class DrawPoint extends Draw {
|
||||||
|
/**
|
||||||
|
* @constructor
|
||||||
|
* @desc 获取坐标点
|
||||||
|
* */
|
||||||
|
constructor(sdk, options = {}, is2D = false) {
|
||||||
|
super(sdk, options, is2D)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @desc 开始动态获取坐标点
|
||||||
|
* @method start
|
||||||
|
* @param cb {function} 回调函数
|
||||||
|
* @memberOf DrawPoint
|
||||||
|
* @example draw.start((err,position)=>{
|
||||||
|
*
|
||||||
|
* })
|
||||||
|
* */
|
||||||
|
|
||||||
|
start(cb) {
|
||||||
|
if (YJ.Measure.GetMeasureStatus()) {
|
||||||
|
cb('上一次测量未结束')
|
||||||
|
} else {
|
||||||
|
let car = undefined
|
||||||
|
YJ.Measure.SetMeasureStatus(true)
|
||||||
|
this.tip = new MouseTip('左键确定,右键结束;', this.sdk)
|
||||||
|
this.event = new MouseEvent(this.sdk)
|
||||||
|
this.event.mouse_left((movement, cartesian) => {
|
||||||
|
this.end()
|
||||||
|
let p = this.cartesian3Towgs84(car || cartesian, this.viewer)
|
||||||
|
cb(null, p, Cesium)
|
||||||
|
})
|
||||||
|
this.event.mouse_right((movement, cartesian) => {
|
||||||
|
this.end()
|
||||||
|
cb(false)
|
||||||
|
})
|
||||||
|
this.event.mouse_move((movement, cartesian) => {
|
||||||
|
car = cartesian
|
||||||
|
this.tip.setPosition(
|
||||||
|
cartesian,
|
||||||
|
movement.endPosition.x,
|
||||||
|
movement.endPosition.y
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
this.event.gesture_pinck_start((movement, cartesian) => {
|
||||||
|
let startTime = new Date()
|
||||||
|
this.event.gesture_pinck_end(() => {
|
||||||
|
let endTime = new Date()
|
||||||
|
if (endTime - startTime >= 500) {
|
||||||
|
this.end()
|
||||||
|
cb(false)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.end()
|
||||||
|
let p = this.cartesian3Towgs84(car || cartesian, this.viewer)
|
||||||
|
cb(null, p)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (!this._is2D && this._sdk2D) {
|
||||||
|
this.event2D = new MouseEvent(this._sdk2D)
|
||||||
|
this.event2D.mouse_left((movement, cartesian) => {
|
||||||
|
this.end()
|
||||||
|
let p = this.cartesian3Towgs84(car || cartesian, this.viewer)
|
||||||
|
cb(null, p, Cesium)
|
||||||
|
})
|
||||||
|
this.event2D.mouse_right((movement, cartesian) => {
|
||||||
|
this.end()
|
||||||
|
cb(false)
|
||||||
|
})
|
||||||
|
this.event2D.mouse_move((movement, cartesian) => {
|
||||||
|
car = cartesian
|
||||||
|
this.tip.setPosition(
|
||||||
|
cartesian,
|
||||||
|
movement.endPosition.x + this.viewer.canvas.width,
|
||||||
|
movement.endPosition.y
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
this.event2D.gesture_pinck_start((movement, cartesian) => {
|
||||||
|
let startTime = new Date()
|
||||||
|
this.event2D.gesture_pinck_end(() => {
|
||||||
|
let endTime = new Date()
|
||||||
|
if (endTime - startTime >= 500) {
|
||||||
|
this.end()
|
||||||
|
cb(false)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.end()
|
||||||
|
let p = this.cartesian3Towgs84(car || cartesian, this.viewer)
|
||||||
|
cb(null, p)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
end() {
|
||||||
|
YJ.Measure.SetMeasureStatus(false)
|
||||||
|
this.event && this.event.destroy()
|
||||||
|
this.event2D && this.event2D.destroy()
|
||||||
|
this.tip && this.tip.destroy()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default DrawPoint
|
||||||
276
src/Draw/drawPolygon.js
Normal file
276
src/Draw/drawPolygon.js
Normal file
@ -0,0 +1,276 @@
|
|||||||
|
import MouseTip from '../MouseTip'
|
||||||
|
import MouseEvent from '../Event'
|
||||||
|
import Draw from './draw'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @extends Draw*/
|
||||||
|
class DrawPolygon extends Draw {
|
||||||
|
/**
|
||||||
|
* @constructor
|
||||||
|
* @param [options] {object} 面属性
|
||||||
|
* @param [options.color=rgba(185,14,14,0.58)] {object} 线属性
|
||||||
|
|
||||||
|
* */
|
||||||
|
constructor(sdk, options = {}) {
|
||||||
|
super(sdk, options)
|
||||||
|
this.polygonHasCreated = false
|
||||||
|
}
|
||||||
|
|
||||||
|
static create_polygon(that, viewer = that.viewer) {
|
||||||
|
that.polygonHasCreated = true
|
||||||
|
let id = that.randomString()
|
||||||
|
viewer.entities.add(
|
||||||
|
new Cesium.Entity({
|
||||||
|
id: id,
|
||||||
|
polygon: {
|
||||||
|
classificationType: Cesium.ClassificationType.BOTH,
|
||||||
|
hierarchy: new Cesium.CallbackProperty((e) => {
|
||||||
|
return new Cesium.PolygonHierarchy(that.positions)
|
||||||
|
}),
|
||||||
|
material: Cesium.Color.fromCssColorString(that.color),
|
||||||
|
zIndex: 99999999
|
||||||
|
},
|
||||||
|
polyline: {
|
||||||
|
positions: new Cesium.CallbackProperty((e) => {
|
||||||
|
return that.positions.concat(that.positions[0])
|
||||||
|
}),
|
||||||
|
width: 2,
|
||||||
|
material: Cesium.Color.fromCssColorString('#c1c505').withAlpha(0.5),
|
||||||
|
clampToGround: true,
|
||||||
|
zIndex: 99999999
|
||||||
|
},
|
||||||
|
})
|
||||||
|
)
|
||||||
|
return id
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @desc 开始动态绘制面
|
||||||
|
* @method start
|
||||||
|
* @param cb {function} 回调函数
|
||||||
|
* @memberOf DrawPolygon
|
||||||
|
* @example draw.start((err,positions)=>{
|
||||||
|
*
|
||||||
|
* })
|
||||||
|
* */
|
||||||
|
start(cb) {
|
||||||
|
if (YJ.Measure.GetMeasureStatus()) {
|
||||||
|
cb('上一次测量未结束')
|
||||||
|
} else {
|
||||||
|
this.polygonHasCreated = false
|
||||||
|
super.start()
|
||||||
|
YJ.Measure.SetMeasureStatus(true)
|
||||||
|
let into
|
||||||
|
this.tip = new MouseTip('左键确定,右键结束;CTRL+右键撤销', this.sdk)
|
||||||
|
this.event = new MouseEvent(this.sdk)
|
||||||
|
this.positions = []
|
||||||
|
this.points_ids = [] //存放左键点击时临时添加的point的id
|
||||||
|
let cache_positions = []
|
||||||
|
let cache_84_position = []
|
||||||
|
this.event.mouse_left((movement, cartesian) => {
|
||||||
|
if(into === '2D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
into = '3D'
|
||||||
|
this.positions = cache_positions.concat({ ...cartesian })
|
||||||
|
this.tip.setPosition(
|
||||||
|
cartesian,
|
||||||
|
movement.position.x,
|
||||||
|
movement.position.y
|
||||||
|
)
|
||||||
|
if (!this.polygonHasCreated) {
|
||||||
|
let polyline_id = DrawPolygon.create_polygon(this)
|
||||||
|
this.points_ids.push(polyline_id)
|
||||||
|
}
|
||||||
|
cache_positions.push(cartesian)
|
||||||
|
// console.log(cache_positions)
|
||||||
|
cache_84_position.push(this.cartesian3Towgs84(cartesian, this.viewer))
|
||||||
|
// console.log(this.cartesian3Towgs84(cartesian))
|
||||||
|
this.points_ids.push(this.create_point(cartesian))
|
||||||
|
})
|
||||||
|
this.event.mouse_right((movement, cartesian) => {
|
||||||
|
if(into === '2D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// let positions = []
|
||||||
|
// console.log(cache_positions)
|
||||||
|
// cache_positions.forEach((item) => {
|
||||||
|
// let p = this.cartesian3Towgs84(item)
|
||||||
|
// console.log(item)
|
||||||
|
// positions.push(p)
|
||||||
|
// })
|
||||||
|
cb(null, cache_84_position)
|
||||||
|
this.end()
|
||||||
|
})
|
||||||
|
this.event.mouse_move((movement, cartesian) => {
|
||||||
|
if(into === '2D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.positions = cache_positions.concat({ ...cartesian })
|
||||||
|
this.tip.setPosition(
|
||||||
|
cartesian,
|
||||||
|
movement.endPosition.x,
|
||||||
|
movement.endPosition.y
|
||||||
|
)
|
||||||
|
})
|
||||||
|
this.event.mouse_right_keyboard_ctrl((movement, cartesian) => {
|
||||||
|
if(into === '2D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (this.points_ids.length > 1) {
|
||||||
|
this.remove_entity(this.points_ids.pop()) //移除point
|
||||||
|
cache_positions.pop()
|
||||||
|
cache_84_position.pop()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
this.event.gesture_pinck_start_keyboard_ctrl(() => {
|
||||||
|
if(into === '2D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (this.points_ids.length > 1) {
|
||||||
|
this.remove_entity(this.points_ids.pop()) //移除point
|
||||||
|
cache_positions.pop()
|
||||||
|
cache_84_position.pop()
|
||||||
|
this.positions = cache_positions.concat(cartesian)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
this.event.gesture_pinck_start((movement, cartesian) => {
|
||||||
|
if(into === '2D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let startTime = new Date()
|
||||||
|
this.event.gesture_pinck_end(() => {
|
||||||
|
let endTime = new Date()
|
||||||
|
if (endTime - startTime >= 500) {
|
||||||
|
cb(null, cache_84_position)
|
||||||
|
this.end()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.tip.setPosition(
|
||||||
|
cartesian,
|
||||||
|
(movement.position1.x + movement.position2.x) / 2,
|
||||||
|
(movement.position1.y + movement.position2.y) / 2
|
||||||
|
)
|
||||||
|
if (!this.polygonHasCreated) {
|
||||||
|
let polyline_id = DrawPolygon.create_polygon(this)
|
||||||
|
this.points_ids.push(polyline_id)
|
||||||
|
}
|
||||||
|
cache_positions.push(cartesian)
|
||||||
|
// console.log(cache_positions)
|
||||||
|
cache_84_position.push(this.cartesian3Towgs84(cartesian, this.viewer))
|
||||||
|
// console.log(this.cartesian3Towgs84(cartesian))
|
||||||
|
this.points_ids.push(this.create_point(cartesian))
|
||||||
|
this.positions = cache_positions.concat(cartesian)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!this._is2D && this._sdk2D) {
|
||||||
|
this.event2D = new MouseEvent(this._sdk2D)
|
||||||
|
this.event2D.mouse_left((movement, cartesian) => {
|
||||||
|
if(into === '3D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
into = '2D'
|
||||||
|
this.positions = cache_positions.concat({ ...cartesian })
|
||||||
|
this.tip.setPosition(
|
||||||
|
cartesian,
|
||||||
|
movement.position.x + this.viewer.canvas.width,
|
||||||
|
movement.position.y
|
||||||
|
)
|
||||||
|
if (!this.polygonHasCreated) {
|
||||||
|
let polyline_id = DrawPolygon.create_polygon(this, this._sdk2D.viewer)
|
||||||
|
this.points_ids.push(polyline_id)
|
||||||
|
}
|
||||||
|
cache_positions.push(cartesian)
|
||||||
|
// console.log(cache_positions)
|
||||||
|
cache_84_position.push(this.cartesian3Towgs84(cartesian, this.viewer))
|
||||||
|
// console.log(this.cartesian3Towgs84(cartesian))
|
||||||
|
this.points_ids.push(this.create_point(cartesian, this._sdk2D.viewer))
|
||||||
|
})
|
||||||
|
this.event2D.mouse_right((movement, cartesian) => {
|
||||||
|
if(into === '3D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// let positions = []
|
||||||
|
// console.log(cache_positions)
|
||||||
|
// cache_positions.forEach((item) => {
|
||||||
|
// let p = this.cartesian3Towgs84(item)
|
||||||
|
// console.log(item)
|
||||||
|
// positions.push(p)
|
||||||
|
// })
|
||||||
|
cb(null, cache_84_position)
|
||||||
|
this.end()
|
||||||
|
})
|
||||||
|
this.event2D.mouse_move((movement, cartesian) => {
|
||||||
|
if(into === '3D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.positions = cache_positions.concat({ ...cartesian })
|
||||||
|
this.tip.setPosition(
|
||||||
|
cartesian,
|
||||||
|
movement.endPosition.x + this.viewer.canvas.width,
|
||||||
|
movement.endPosition.y
|
||||||
|
)
|
||||||
|
})
|
||||||
|
this.event2D.mouse_right_keyboard_ctrl((movement, cartesian) => {
|
||||||
|
if(into === '3D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (this.points_ids.length > 1) {
|
||||||
|
this.remove_entity(this.points_ids.pop()) //移除point
|
||||||
|
cache_positions.pop()
|
||||||
|
cache_84_position.pop()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
this.event2D.gesture_pinck_start_keyboard_ctrl(() => {
|
||||||
|
if(into === '3D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (this.points_ids.length > 1) {
|
||||||
|
this.remove_entity(this.points_ids.pop()) //移除point
|
||||||
|
cache_positions.pop()
|
||||||
|
cache_84_position.pop()
|
||||||
|
this.positions = cache_positions.concat(cartesian)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
this.event2D.gesture_pinck_start((movement, cartesian) => {
|
||||||
|
if(into === '3D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let startTime = new Date()
|
||||||
|
this.event2D.gesture_pinck_end(() => {
|
||||||
|
let endTime = new Date()
|
||||||
|
if (endTime - startTime >= 500) {
|
||||||
|
cb(null, cache_84_position)
|
||||||
|
this.end()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.tip.setPosition(
|
||||||
|
cartesian,
|
||||||
|
((movement.position1.x + movement.position2.x) / 2) + this.viewer.canvas.width,
|
||||||
|
(movement.position1.y + movement.position2.y) / 2
|
||||||
|
)
|
||||||
|
if (!this.polygonHasCreated) {
|
||||||
|
let polyline_id = DrawPolygon.create_polygon(this, this._sdk2D.viewer)
|
||||||
|
this.points_ids.push(polyline_id)
|
||||||
|
}
|
||||||
|
cache_positions.push(cartesian)
|
||||||
|
// console.log(cache_positions)
|
||||||
|
cache_84_position.push(this.cartesian3Towgs84(cartesian, this.viewer))
|
||||||
|
// console.log(this.cartesian3Towgs84(cartesian))
|
||||||
|
this.points_ids.push(this.create_point(cartesian, this._sdk2D.viewer))
|
||||||
|
this.positions = cache_positions.concat(cartesian)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default DrawPolygon
|
||||||
348
src/Draw/drawPolyline.js
Normal file
348
src/Draw/drawPolyline.js
Normal file
@ -0,0 +1,348 @@
|
|||||||
|
import MouseTip from '../MouseTip'
|
||||||
|
import MouseEvent from '../Event'
|
||||||
|
import Draw from './draw'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @extends Draw
|
||||||
|
*/
|
||||||
|
|
||||||
|
class DrawPolyline extends Draw {
|
||||||
|
/**
|
||||||
|
* @constructor
|
||||||
|
* @param [options] {object} 线属性
|
||||||
|
* @param [options.color=rgba(185,14,14,0.58)] {object} 线属性
|
||||||
|
*
|
||||||
|
* */
|
||||||
|
constructor(sdk, options = {}) {
|
||||||
|
super(sdk, options)
|
||||||
|
this.options.curve = options.curve || false
|
||||||
|
let number = Number(options.number)
|
||||||
|
if (!isNaN(number)) {
|
||||||
|
if (number < 2) {
|
||||||
|
this.options.number = 2
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.options.number = number
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.options.number = Infinity
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static create_polyline(that, viewer = that.viewer) {
|
||||||
|
that.entityHasCreated = true
|
||||||
|
let id = that.randomString()
|
||||||
|
viewer.entities.add(
|
||||||
|
new Cesium.Entity({
|
||||||
|
id: id,
|
||||||
|
polyline: {
|
||||||
|
positions: new Cesium.CallbackProperty(() => {
|
||||||
|
if (that.options.curve) {
|
||||||
|
let positions = that.smoothHandle(that.positions)
|
||||||
|
return positions
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return that.positions
|
||||||
|
}
|
||||||
|
}, false),
|
||||||
|
width: 5,
|
||||||
|
material: Cesium.Color.fromCssColorString(that.color),
|
||||||
|
clampToGround: true,
|
||||||
|
zIndex: 99999999
|
||||||
|
}
|
||||||
|
})
|
||||||
|
)
|
||||||
|
return id
|
||||||
|
}
|
||||||
|
|
||||||
|
// 平滑处理
|
||||||
|
smoothHandle(positions) {
|
||||||
|
if (positions.length > 1) {
|
||||||
|
let newPositions = []
|
||||||
|
let time = []
|
||||||
|
for (let i = 0; i < positions.length; i++) {
|
||||||
|
time.push(i / (positions.length - 1))
|
||||||
|
}
|
||||||
|
let spline = new Cesium.CatmullRomSpline({
|
||||||
|
times: time,
|
||||||
|
points: positions
|
||||||
|
});
|
||||||
|
let length = positions.length * 20
|
||||||
|
for (let i = 0; i <= length; i++) {
|
||||||
|
let cartesian3 = spline.evaluate(i / length);
|
||||||
|
newPositions.push(cartesian3);
|
||||||
|
}
|
||||||
|
return newPositions
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return positions
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @desc 开始动态获绘制线
|
||||||
|
* @method start
|
||||||
|
* @param cb {function} 回调函数
|
||||||
|
* @memberOf DrawPolyline
|
||||||
|
* @example draw.start((err,positions)=>{
|
||||||
|
*
|
||||||
|
* })
|
||||||
|
* */
|
||||||
|
start(cb) {
|
||||||
|
if (YJ.Measure.GetMeasureStatus()) {
|
||||||
|
cb('上一次测量未结束')
|
||||||
|
} else {
|
||||||
|
super.start()
|
||||||
|
let into
|
||||||
|
YJ.Measure.SetMeasureStatus(true)
|
||||||
|
this.tip = new MouseTip('左键确定,右键结束;CTRL+右键撤销', this.sdk)
|
||||||
|
this.event = new MouseEvent(this.sdk)
|
||||||
|
this.positions = []
|
||||||
|
this.points_ids = [] //存放左键点击时临时添加的point的id
|
||||||
|
|
||||||
|
let cache_positions = []
|
||||||
|
let car = undefined
|
||||||
|
this.event.mouse_left((movement, cartesian) => {
|
||||||
|
if(into === '2D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
into = '3D'
|
||||||
|
this.positions = cache_positions.concat(cartesian)
|
||||||
|
this.tip.setPosition(
|
||||||
|
cartesian,
|
||||||
|
movement.position.x,
|
||||||
|
movement.position.y
|
||||||
|
)
|
||||||
|
if (!this.entityHasCreated) {
|
||||||
|
let polyline_id = DrawPolyline.create_polyline(this, this.viewer)
|
||||||
|
this.points_ids.push(polyline_id)
|
||||||
|
}
|
||||||
|
cache_positions.push(cartesian)
|
||||||
|
this.points_ids.push(this.create_point(cartesian, this.viewer))
|
||||||
|
|
||||||
|
if (cache_positions.length >= this.options.number) {
|
||||||
|
let positions = []
|
||||||
|
cache_positions.forEach((item) => {
|
||||||
|
positions.push(this.cartesian3Towgs84(item, this.viewer))
|
||||||
|
})
|
||||||
|
let smoothPos
|
||||||
|
if (this.options.curve) {
|
||||||
|
let pos = this.smoothHandle(cache_positions)
|
||||||
|
smoothPos = []
|
||||||
|
for (let i = 0; i < pos.length; i++) {
|
||||||
|
smoothPos[i] = this.cartesian3Towgs84(pos[i], this.viewer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cb(null, positions, smoothPos)
|
||||||
|
this.end()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.event.mouse_right((movement, cartesian) => {
|
||||||
|
if(into === '2D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let positions = []
|
||||||
|
cache_positions.forEach((item) => {
|
||||||
|
positions.push(this.cartesian3Towgs84(item, this.viewer))
|
||||||
|
})
|
||||||
|
let smoothPos
|
||||||
|
if (this.options.curve) {
|
||||||
|
let pos = this.smoothHandle(cache_positions)
|
||||||
|
smoothPos = []
|
||||||
|
for (let i = 0; i < pos.length; i++) {
|
||||||
|
smoothPos[i] = this.cartesian3Towgs84(pos[i], this.viewer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cb(null, positions, smoothPos)
|
||||||
|
this.end()
|
||||||
|
})
|
||||||
|
this.event.mouse_move((movement, cartesian) => {
|
||||||
|
if(into === '2D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.positions = cache_positions.concat(cartesian)
|
||||||
|
this.tip.setPosition(
|
||||||
|
cartesian,
|
||||||
|
movement.endPosition.x,
|
||||||
|
movement.endPosition.y
|
||||||
|
)
|
||||||
|
})
|
||||||
|
this.event.mouse_right_keyboard_ctrl((movement, cartesian) => {
|
||||||
|
if(into === '2D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (this.points_ids.length > 1) {
|
||||||
|
this.remove_entity(this.points_ids.pop()) //移除point
|
||||||
|
cache_positions.pop()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
this.event.gesture_pinck_start_keyboard_ctrl(() => {
|
||||||
|
if(into === '2D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (this.points_ids.length > 1) {
|
||||||
|
this.remove_entity(this.points_ids.pop()) //移除point
|
||||||
|
cache_positions.pop()
|
||||||
|
this.positions = cache_positions.concat(cartesian)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
this.event.gesture_pinck_start((movement, cartesian) => {
|
||||||
|
if(into === '2D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let startTime = new Date()
|
||||||
|
this.event.gesture_pinck_end(() => {
|
||||||
|
let endTime = new Date()
|
||||||
|
if (endTime - startTime >= 500) {
|
||||||
|
let positions = []
|
||||||
|
cache_positions.forEach((item) => {
|
||||||
|
positions.push(this.cartesian3Towgs84(item, this.viewer))
|
||||||
|
})
|
||||||
|
let smoothPos
|
||||||
|
if (this.options.curve) {
|
||||||
|
let pos = this.smoothHandle(cache_positions)
|
||||||
|
smoothPos = []
|
||||||
|
for (let i = 0; i < pos.length; i++) {
|
||||||
|
smoothPos[i] = this.cartesian3Towgs84(pos[i], this.viewer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cb(null, positions, smoothPos)
|
||||||
|
this.end()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.tip.setPosition(
|
||||||
|
cartesian,
|
||||||
|
(movement.position1.x + movement.position2.x) / 2,
|
||||||
|
(movement.position1.y + movement.position2.y) / 2
|
||||||
|
)
|
||||||
|
if (!this.entityHasCreated) {
|
||||||
|
let polyline_id = DrawPolyline.create_polyline(this, this.viewer)
|
||||||
|
this.points_ids.push(polyline_id)
|
||||||
|
}
|
||||||
|
cache_positions.push(cartesian)
|
||||||
|
this.points_ids.push(this.create_point(cartesian, this.viewer))
|
||||||
|
this.positions = cache_positions.concat(cartesian)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
if (!this._is2D && this._sdk2D) {
|
||||||
|
this.event2D = new MouseEvent(this._sdk2D)
|
||||||
|
this.event2D.mouse_left((movement, cartesian) => {
|
||||||
|
if(into === '3D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
into = '2D'
|
||||||
|
this.positions = cache_positions.concat(cartesian)
|
||||||
|
this.tip.setPosition(
|
||||||
|
cartesian,
|
||||||
|
movement.position.x + this.viewer.canvas.width,
|
||||||
|
movement.position.y
|
||||||
|
)
|
||||||
|
if (!this.entityHasCreated) {
|
||||||
|
let polyline_id = DrawPolyline.create_polyline(this, this._sdk2D.viewer)
|
||||||
|
this.points_ids.push(polyline_id)
|
||||||
|
}
|
||||||
|
cache_positions.push(cartesian)
|
||||||
|
this.points_ids.push(this.create_point(cartesian, this._sdk2D.viewer))
|
||||||
|
})
|
||||||
|
this.event2D.mouse_right((movement, cartesian) => {
|
||||||
|
if(into === '3D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let positions = []
|
||||||
|
cache_positions.forEach((item) => {
|
||||||
|
positions.push(this.cartesian3Towgs84(item, this.viewer))
|
||||||
|
})
|
||||||
|
let smoothPos
|
||||||
|
if (this.options.curve) {
|
||||||
|
let pos = this.smoothHandle(cache_positions)
|
||||||
|
smoothPos = []
|
||||||
|
for (let i = 0; i < pos.length; i++) {
|
||||||
|
smoothPos[i] = this.cartesian3Towgs84(pos[i], this.viewer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cb(null, positions, smoothPos)
|
||||||
|
this.end()
|
||||||
|
})
|
||||||
|
this.event2D.mouse_move((movement, cartesian) => {
|
||||||
|
if(into === '3D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.positions = cache_positions.concat(cartesian)
|
||||||
|
this.tip.setPosition(
|
||||||
|
cartesian,
|
||||||
|
movement.endPosition.x + this.viewer.canvas.width,
|
||||||
|
movement.endPosition.y
|
||||||
|
)
|
||||||
|
})
|
||||||
|
this.event2D.mouse_right_keyboard_ctrl((movement, cartesian) => {
|
||||||
|
if(into === '3D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (this.points_ids.length > 1) {
|
||||||
|
this.remove_entity(this.points_ids.pop()) //移除point
|
||||||
|
cache_positions.pop()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
this.event2D.gesture_pinck_start_keyboard_ctrl(() => {
|
||||||
|
if(into === '3D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (this.points_ids.length > 1) {
|
||||||
|
this.remove_entity(this.points_ids.pop()) //移除point
|
||||||
|
cache_positions.pop()
|
||||||
|
this.positions = cache_positions.concat(cartesian)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
this.event2D.gesture_pinck_start((movement, cartesian) => {
|
||||||
|
if(into === '3D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let startTime = new Date()
|
||||||
|
this.event2D.gesture_pinck_end(() => {
|
||||||
|
let endTime = new Date()
|
||||||
|
if (endTime - startTime >= 500) {
|
||||||
|
let positions = []
|
||||||
|
cache_positions.forEach((item) => {
|
||||||
|
positions.push(this.cartesian3Towgs84(item, this.viewer))
|
||||||
|
})
|
||||||
|
let smoothPos
|
||||||
|
if (this.options.curve) {
|
||||||
|
let pos = this.smoothHandle(cache_positions)
|
||||||
|
smoothPos = []
|
||||||
|
for (let i = 0; i < pos.length; i++) {
|
||||||
|
smoothPos[i] = this.cartesian3Towgs84(pos[i], this.viewer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cb(null, positions, smoothPos)
|
||||||
|
this.end()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.tip.setPosition(
|
||||||
|
cartesian,
|
||||||
|
((movement.position1.x + movement.position2.x) / 2) + this.viewer.canvas.width,
|
||||||
|
(movement.position1.y + movement.position2.y) / 2
|
||||||
|
)
|
||||||
|
if (!this.entityHasCreated) {
|
||||||
|
let polyline_id = DrawPolyline.create_polyline(this, this._sdk2D.viewer)
|
||||||
|
this.points_ids.push(polyline_id)
|
||||||
|
}
|
||||||
|
cache_positions.push(cartesian)
|
||||||
|
this.points_ids.push(this.create_point(cartesian, this._sdk2D.viewer))
|
||||||
|
this.positions = cache_positions.concat(cartesian)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default DrawPolyline
|
||||||
278
src/Draw/drawRect.js
Normal file
278
src/Draw/drawRect.js
Normal file
@ -0,0 +1,278 @@
|
|||||||
|
import MouseTip from '../MouseTip'
|
||||||
|
import MouseEvent from '../Event'
|
||||||
|
import Draw from './draw'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @extends Draw*/
|
||||||
|
class DrawRect extends Draw {
|
||||||
|
/**
|
||||||
|
* @constructor
|
||||||
|
* @param [options] {object} 面属性
|
||||||
|
* @param [options.color=rgba(185,14,14,0.58)] {object} 线属性
|
||||||
|
|
||||||
|
* */
|
||||||
|
constructor(sdk, options = {}) {
|
||||||
|
super(sdk, options)
|
||||||
|
this.rhumb = options.rhumb
|
||||||
|
this.polygonHasCreated = false
|
||||||
|
this.rect = []
|
||||||
|
this.rectObj = []
|
||||||
|
this.entity = null
|
||||||
|
}
|
||||||
|
|
||||||
|
static create_polygon(that, viewer = that.viewer) {
|
||||||
|
let id = that.randomString()
|
||||||
|
viewer.entities.add(
|
||||||
|
(this.entity = new Cesium.Entity({
|
||||||
|
id: id,
|
||||||
|
polygon: {
|
||||||
|
// classificationType: Cesium.ClassificationType.BOTH,
|
||||||
|
hierarchy: new Cesium.CallbackProperty(e => {
|
||||||
|
return new Cesium.PolygonHierarchy(
|
||||||
|
Cesium.Cartesian3.fromDegreesArray(that.rect)
|
||||||
|
)
|
||||||
|
},false),
|
||||||
|
material: Cesium.Color.fromCssColorString(that.color),
|
||||||
|
arcType: that.rhumb ? Cesium.ArcType.RHUMB : Cesium.ArcType.GEODESIC,
|
||||||
|
zIndex: 99999999
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
)
|
||||||
|
return id
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @desc 开始动态绘制面
|
||||||
|
* @method start
|
||||||
|
* @param cb {function} 回调函数
|
||||||
|
* @memberOf DrawRect
|
||||||
|
* @example draw.start((err,positions)=>{
|
||||||
|
*
|
||||||
|
* })
|
||||||
|
* */
|
||||||
|
start(cb) {
|
||||||
|
let that = this
|
||||||
|
if (YJ.Measure.GetMeasureStatus()) {
|
||||||
|
cb('上一次测量未结束')
|
||||||
|
} else {
|
||||||
|
super.start()
|
||||||
|
let into
|
||||||
|
YJ.Measure.SetMeasureStatus(true)
|
||||||
|
this.tip = new MouseTip('左键确定,右键取消', that.sdk)
|
||||||
|
this.event = new MouseEvent(that.sdk)
|
||||||
|
this.positions = []
|
||||||
|
this.points_ids = [] //存放左键点击时临时添加的point的id
|
||||||
|
let cache_positions = []
|
||||||
|
let cache_84_position = []
|
||||||
|
let cnt = 0
|
||||||
|
let firstPoint = null
|
||||||
|
let secondtPoint = null
|
||||||
|
this.event.mouse_left((movement, cartesian) => {
|
||||||
|
if(into === '2D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
into = '3D'
|
||||||
|
cnt++
|
||||||
|
let wgs84 = this.cartesian3Towgs84(cartesian, this.viewer)
|
||||||
|
|
||||||
|
if (!this.polygonHasCreated) {
|
||||||
|
this.polygonHasCreated = true
|
||||||
|
let polyline_id = DrawRect.create_polygon(this)
|
||||||
|
this.points_ids.push(polyline_id)
|
||||||
|
firstPoint = wgs84
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cnt == 2) {
|
||||||
|
secondtPoint = wgs84
|
||||||
|
this.end()
|
||||||
|
cb(null, that.rectObj, [firstPoint, secondtPoint])
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
})
|
||||||
|
this.event.mouse_right((movement, cartesian) => {
|
||||||
|
if(into === '2D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.end()
|
||||||
|
cb('取消', '')
|
||||||
|
})
|
||||||
|
this.event.mouse_move((movement, cartesian) => {
|
||||||
|
if(into === '2D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.tip.setPosition(
|
||||||
|
cartesian,
|
||||||
|
movement.endPosition.x,
|
||||||
|
movement.endPosition.y
|
||||||
|
)
|
||||||
|
if (cnt == 1) {
|
||||||
|
let wgs84 = this.cartesian3Towgs84(cartesian, this.viewer)
|
||||||
|
this.calrect(firstPoint, wgs84)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
this.event.gesture_pinck_start((movement, cartesian) => {
|
||||||
|
if(into === '2D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let startTime = new Date()
|
||||||
|
this.event.gesture_pinck_end(() => {
|
||||||
|
let endTime = new Date()
|
||||||
|
if (endTime - startTime >= 500) {
|
||||||
|
cb('取消', '')
|
||||||
|
this.end()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.tip.setPosition(
|
||||||
|
cartesian,
|
||||||
|
(movement.position1.x + movement.position2.x) / 2,
|
||||||
|
(movement.position1.y + movement.position2.y) / 2
|
||||||
|
)
|
||||||
|
cnt++
|
||||||
|
let wgs84 = this.cartesian3Towgs84(cartesian)
|
||||||
|
|
||||||
|
if (!this.polygonHasCreated) {
|
||||||
|
this.polygonHasCreated = true
|
||||||
|
let polyline_id = DrawRect.create_polygon(this)
|
||||||
|
this.points_ids.push(polyline_id)
|
||||||
|
firstPoint = wgs84
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cnt == 2) {
|
||||||
|
this.calrect(firstPoint, wgs84)
|
||||||
|
secondtPoint = wgs84
|
||||||
|
this.end()
|
||||||
|
cb(null, that.rectObj, [firstPoint, secondtPoint])
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!this._is2D && this._sdk2D) {
|
||||||
|
this.event2D = new MouseEvent(this._sdk2D)
|
||||||
|
this.event2D.mouse_left((movement, cartesian) => {
|
||||||
|
if(into === '3D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
into = '2D'
|
||||||
|
cnt++
|
||||||
|
let wgs84 = this.cartesian3Towgs84(cartesian, this.viewer)
|
||||||
|
|
||||||
|
if (!this.polygonHasCreated) {
|
||||||
|
this.polygonHasCreated = true
|
||||||
|
let polyline_id = DrawRect.create_polygon(this, this._sdk2D.viewer)
|
||||||
|
this.points_ids.push(polyline_id)
|
||||||
|
firstPoint = wgs84
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cnt == 2) {
|
||||||
|
secondtPoint = wgs84
|
||||||
|
this.end()
|
||||||
|
cb(null, that.rectObj, [firstPoint, secondtPoint])
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
})
|
||||||
|
this.event2D.mouse_right((movement, cartesian) => {
|
||||||
|
if(into === '3D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.end()
|
||||||
|
cb('取消', '')
|
||||||
|
})
|
||||||
|
this.event2D.mouse_move((movement, cartesian) => {
|
||||||
|
if(into === '3D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.tip.setPosition(
|
||||||
|
cartesian,
|
||||||
|
movement.endPosition.x + this.viewer.canvas.width,
|
||||||
|
movement.endPosition.y
|
||||||
|
)
|
||||||
|
if (cnt == 1) {
|
||||||
|
let wgs84 = this.cartesian3Towgs84(cartesian, this.viewer)
|
||||||
|
this.calrect(firstPoint, wgs84)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
this.event2D.gesture_pinck_start((movement, cartesian) => {
|
||||||
|
if(into === '3D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let startTime = new Date()
|
||||||
|
this.event2D.gesture_pinck_end(() => {
|
||||||
|
let endTime = new Date()
|
||||||
|
if (endTime - startTime >= 500) {
|
||||||
|
cb('取消', '')
|
||||||
|
this.end()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.tip.setPosition(
|
||||||
|
cartesian,
|
||||||
|
((movement.position1.x + movement.position2.x) / 2) + this.viewer.canvas.width,
|
||||||
|
(movement.position1.y + movement.position2.y) / 2
|
||||||
|
)
|
||||||
|
cnt++
|
||||||
|
let wgs84 = this.cartesian3Towgs84(cartesian)
|
||||||
|
|
||||||
|
if (!this.polygonHasCreated) {
|
||||||
|
this.polygonHasCreated = true
|
||||||
|
let polyline_id = DrawRect.create_polygon(this, this._sdk2D.viewer)
|
||||||
|
this.points_ids.push(polyline_id)
|
||||||
|
firstPoint = wgs84
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cnt == 2) {
|
||||||
|
this.calrect(firstPoint, wgs84)
|
||||||
|
secondtPoint = wgs84
|
||||||
|
this.end()
|
||||||
|
cb(null, that.rectObj, [firstPoint, secondtPoint])
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
calrect(firstPoint, secondPoint) {
|
||||||
|
let positions = []
|
||||||
|
let arr = []
|
||||||
|
let arr2 = []
|
||||||
|
positions.push(
|
||||||
|
[firstPoint.lng, firstPoint.lat, firstPoint.alt],
|
||||||
|
[secondPoint.lng, secondPoint.lat, secondPoint.alt]
|
||||||
|
)
|
||||||
|
let bboxPolygon
|
||||||
|
if (positions.length === 2) {
|
||||||
|
let line = turf.lineString(positions)
|
||||||
|
let bbox = turf.bbox(line)
|
||||||
|
bboxPolygon = turf.bboxPolygon(bbox)
|
||||||
|
}
|
||||||
|
if (bboxPolygon) {
|
||||||
|
// console.log('bboxPolygon',bboxPolygon.geometry.coordinates[0])
|
||||||
|
bboxPolygon.geometry.coordinates[0].forEach(item => {
|
||||||
|
arr.push(item[0])
|
||||||
|
arr.push(item[1])
|
||||||
|
let obj = {
|
||||||
|
lng: item[0],
|
||||||
|
lat: item[1],
|
||||||
|
alt: firstPoint.alt
|
||||||
|
}
|
||||||
|
arr2.push(obj)
|
||||||
|
})
|
||||||
|
this.rect = [...arr]
|
||||||
|
this.rectObj = [...arr2]
|
||||||
|
this.rectObj.pop()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default DrawRect
|
||||||
268
src/Draw/drawSector.js
Normal file
268
src/Draw/drawSector.js
Normal file
@ -0,0 +1,268 @@
|
|||||||
|
import MouseTip from '../MouseTip'
|
||||||
|
import MouseEvent from '../Event'
|
||||||
|
import Draw from './draw'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @extends Draw*/
|
||||||
|
class DrawSector extends Draw {
|
||||||
|
constructor(sdk, options = {}) {
|
||||||
|
super(sdk, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @desc 开始动态绘制面
|
||||||
|
* @method start
|
||||||
|
* @param cb {function} 回调函数
|
||||||
|
* @memberOf DrawRect
|
||||||
|
* @example draw.start((err,positions)=>{
|
||||||
|
*
|
||||||
|
* })
|
||||||
|
* */
|
||||||
|
start(cb) {
|
||||||
|
let that = this
|
||||||
|
if (YJ.Measure.GetMeasureStatus()) {
|
||||||
|
cb('上一次测量未结束')
|
||||||
|
} else {
|
||||||
|
super.start()
|
||||||
|
let into
|
||||||
|
YJ.Measure.SetMeasureStatus(true)
|
||||||
|
this.tip = new MouseTip('左键确认,右键取消', that.sdk)
|
||||||
|
this.event = new MouseEvent(that.sdk)
|
||||||
|
this._sector_id = null; //扇形
|
||||||
|
this._positions = []; //活动点
|
||||||
|
this.points_ids = []; //脏数据
|
||||||
|
this._entities_sector = []; //脏数据
|
||||||
|
this._radius = 0; //半径
|
||||||
|
this._startAngle = 0; //起始角度
|
||||||
|
this._endAngle = 0; //结束角度
|
||||||
|
this.event.mouse_left((movement, cartesian) => {
|
||||||
|
if(into === '2D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
into = '3D'
|
||||||
|
// if(that._positions.length == 3) return
|
||||||
|
|
||||||
|
if (this._positions.length < 3) {
|
||||||
|
this.points_ids.push(this.create_point(cartesian));
|
||||||
|
this._positions.push(this.cartesian3Towgs84(cartesian, this.viewer));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.end()
|
||||||
|
cb(null, { center: this._positions[0], radius: this._radius, startAngle: this._startAngle, endAngle: this._endAngle })
|
||||||
|
}
|
||||||
|
if (this._positions.length === 2) {
|
||||||
|
let pointA = Cesium.Cartesian3.fromDegrees(this._positions[0].lng, this._positions[0].lat, this._positions[0].alt);
|
||||||
|
let pointB = cartesian;
|
||||||
|
this._radius = Cesium.Cartesian3.distance(pointA, pointB);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.event.mouse_move((movement, cartesian) => {
|
||||||
|
if(into === '2D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.tip.setPosition(
|
||||||
|
cartesian,
|
||||||
|
movement.endPosition.x,
|
||||||
|
movement.endPosition.y
|
||||||
|
)
|
||||||
|
if (this._positions.length < 2) return;
|
||||||
|
if (this._positions.length == 2) {
|
||||||
|
this._positions.push(this.cartesian3Towgs84(cartesian, this.viewer));
|
||||||
|
}
|
||||||
|
if (this._positions.length == 3) {
|
||||||
|
this._positions.pop();
|
||||||
|
this._positions.push(this.cartesian3Towgs84(cartesian, this.viewer));
|
||||||
|
if (!Cesium.defined(this._sector_id)) {
|
||||||
|
this._sector_id = this.createsector();
|
||||||
|
this.points_ids.push(this._sector_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
let options = that.calculateAangle(that._positions)
|
||||||
|
that._startAngle = options.angle1;
|
||||||
|
that._endAngle = options.angle2;
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
this.event.mouse_right((movement, cartesian) => {
|
||||||
|
if(into === '2D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.end()
|
||||||
|
cb(null)
|
||||||
|
})
|
||||||
|
if (!this._is2D && this._sdk2D) {
|
||||||
|
this.event2D = new MouseEvent(this._sdk2D)
|
||||||
|
this.event2D.mouse_left((movement, cartesian) => {
|
||||||
|
if(into === '3D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
into = '2D'
|
||||||
|
// if(that._positions.length == 3) return
|
||||||
|
|
||||||
|
if (this._positions.length < 3) {
|
||||||
|
this.points_ids.push(this.create_point(cartesian, this._sdk2D.viewer));
|
||||||
|
this._positions.push(this.cartesian3Towgs84(cartesian, this.viewer));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.end()
|
||||||
|
cb(null, { center: this._positions[0], radius: this._radius, startAngle: this._startAngle, endAngle: this._endAngle })
|
||||||
|
}
|
||||||
|
if (this._positions.length === 2) {
|
||||||
|
let pointA = Cesium.Cartesian3.fromDegrees(this._positions[0].lng, this._positions[0].lat, this._positions[0].alt);
|
||||||
|
let pointB = cartesian;
|
||||||
|
this._radius = Cesium.Cartesian3.distance(pointA, pointB);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.event2D.mouse_move((movement, cartesian) => {
|
||||||
|
if(into === '3D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.tip.setPosition(
|
||||||
|
cartesian,
|
||||||
|
movement.endPosition.x + this.viewer.canvas.width,
|
||||||
|
movement.endPosition.y
|
||||||
|
)
|
||||||
|
if (this._positions.length < 2) return;
|
||||||
|
if (this._positions.length == 2) {
|
||||||
|
this._positions.push(this.cartesian3Towgs84(cartesian, this.viewer));
|
||||||
|
}
|
||||||
|
if (this._positions.length == 3) {
|
||||||
|
this._positions.pop();
|
||||||
|
this._positions.push(this.cartesian3Towgs84(cartesian, this.viewer));
|
||||||
|
if (!Cesium.defined(this._sector_id)) {
|
||||||
|
this._sector_id = this.createsector(this._sdk2D.viewer);
|
||||||
|
this.points_ids.push(this._sector_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
let options = that.calculateAangle(that._positions)
|
||||||
|
that._startAngle = options.angle1;
|
||||||
|
that._endAngle = options.angle2;
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
this.event2D.mouse_right((movement, cartesian) => {
|
||||||
|
if(into === '3D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.end()
|
||||||
|
cb(null)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//创建直线扇形
|
||||||
|
createsector(viewer = this.viewer) {
|
||||||
|
// console.log(this._positions)
|
||||||
|
let that = this;
|
||||||
|
let angle
|
||||||
|
let hierarchy = new Cesium.CallbackProperty(
|
||||||
|
() => {
|
||||||
|
let pList = that.calSector(that._positions[0], that._radius, that._startAngle, that._endAngle)
|
||||||
|
return new Cesium.PolygonHierarchy(pList);
|
||||||
|
})
|
||||||
|
// let text = new Cesium.CallbackProperty(
|
||||||
|
// () => {
|
||||||
|
// angle = that._endAngle - that._startAngle
|
||||||
|
// if (angle < 0) {
|
||||||
|
// angle = 360 + angle
|
||||||
|
// }
|
||||||
|
// return angle.toFixed(2) + '°';
|
||||||
|
// })
|
||||||
|
let id = that.randomString()
|
||||||
|
let arrowEntity = viewer.entities.add({
|
||||||
|
id: id,
|
||||||
|
position: Cesium.Cartesian3.fromDegrees(that._positions[0].lng, that._positions[0].lat),
|
||||||
|
// label: {
|
||||||
|
// text,
|
||||||
|
// font: "24px Helvetica",
|
||||||
|
// fillColor: Cesium.Color.SKYBLUE,
|
||||||
|
// outlineColor: Cesium.Color.BLACK,
|
||||||
|
// outlineWidth: 2,
|
||||||
|
// style: Cesium.LabelStyle.FILL_AND_OUTLINE,
|
||||||
|
// pixelOffset: new Cesium.Cartesian2(0, -12),
|
||||||
|
// horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
|
||||||
|
// verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||||||
|
// disableDepthTestDistance: Number.POSITIVE_INFINITY
|
||||||
|
// },
|
||||||
|
polygon: {
|
||||||
|
hierarchy,
|
||||||
|
show: true,
|
||||||
|
fill: true,
|
||||||
|
clampToGround: true,
|
||||||
|
material: Cesium.Color.fromCssColorString(that.color),
|
||||||
|
zIndex: 99999999
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
that._entities_sector.push(arrowEntity);
|
||||||
|
return id
|
||||||
|
}
|
||||||
|
|
||||||
|
cartesianToLatlng(cartesian) {
|
||||||
|
let latlng = this.viewer.scene.globe.ellipsoid.cartesianToCartographic(cartesian);
|
||||||
|
let lat = Cesium.Math.toDegrees(latlng.latitude);
|
||||||
|
let lng = Cesium.Math.toDegrees(latlng.longitude);
|
||||||
|
return [lng, lat];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 经纬度坐标转墨卡托坐标
|
||||||
|
*/
|
||||||
|
// 墨卡托坐标系:展开地球,赤道作为x轴,向东为x轴正方,本初子午线作为y轴,向北为y轴正方向。
|
||||||
|
// 数字20037508.34是地球赤道周长的一半:地球半径6378137米,赤道周长2*PI*r = 2 * 20037508.3427892,墨卡托坐标x轴区间[-20037508.3427892,20037508.3427892]
|
||||||
|
lonLatToMercator(Latlng) {
|
||||||
|
let E = Latlng[0];
|
||||||
|
let N = Latlng[1];
|
||||||
|
let x = E * 20037508.34 / 180;
|
||||||
|
let y = Math.log(Math.tan((90 + N) * Math.PI / 360)) / (Math.PI / 180);
|
||||||
|
y = y * 20037508.34 / 180;
|
||||||
|
return [x, y]
|
||||||
|
}
|
||||||
|
|
||||||
|
WebMercator2lonLat(mercator) {
|
||||||
|
let x = mercator[0] / 20037508.34 * 180;
|
||||||
|
let ly = mercator[1] / 20037508.34 * 180;
|
||||||
|
let y = 180 / Math.PI * (2 * Math.atan(Math.exp(ly * Math.PI / 180)) - Math.PI / 2)
|
||||||
|
return [x, y];
|
||||||
|
}
|
||||||
|
|
||||||
|
//计算角度
|
||||||
|
calculateAangle(arr) {
|
||||||
|
function getAangle(start, end) {
|
||||||
|
let rad = Math.PI / 180,
|
||||||
|
lat1 = start.y * rad,
|
||||||
|
lat2 = end.y * rad,
|
||||||
|
lon1 = start.x * rad,
|
||||||
|
lon2 = end.x * rad;
|
||||||
|
const a = Math.sin(lon2 - lon1) * Math.cos(lat2);
|
||||||
|
const b =
|
||||||
|
Math.cos(lat1) * Math.sin(lat2) -
|
||||||
|
Math.sin(lat1) * Math.cos(lat2) * Math.cos(lon2 - lon1);
|
||||||
|
const radians = Math.atan2(a, b)
|
||||||
|
const degrees = radians % (2 * Math.PI);
|
||||||
|
let bearing = 450 - ((degrees * 180) / Math.PI < 0
|
||||||
|
? 360 + (degrees * 180) / Math.PI
|
||||||
|
: (degrees * 180) / Math.PI) - 90;
|
||||||
|
return 360 - (bearing % 360)
|
||||||
|
}
|
||||||
|
|
||||||
|
let center = arr[0]
|
||||||
|
let pos84_1 = arr[1]
|
||||||
|
let pos84_2 = arr[2]
|
||||||
|
|
||||||
|
let start = { x: center.lng, y: center.lat }
|
||||||
|
let end1 = { x: pos84_1.lng, y: pos84_1.lat }
|
||||||
|
let end2 = { x: pos84_2.lng, y: pos84_2.lat }
|
||||||
|
|
||||||
|
let angle1 = getAangle(start, end1)
|
||||||
|
let angle2 = getAangle(start, end2)
|
||||||
|
|
||||||
|
return {
|
||||||
|
angle1,
|
||||||
|
angle2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default DrawSector
|
||||||
262
src/Draw/drawStraightArrow.js
Normal file
262
src/Draw/drawStraightArrow.js
Normal file
@ -0,0 +1,262 @@
|
|||||||
|
import MouseTip from '../MouseTip'
|
||||||
|
import MouseEvent from '../Event'
|
||||||
|
import Draw from './draw'
|
||||||
|
|
||||||
|
const transformCartesianToWGS84 = cartesian => {
|
||||||
|
let ellipsoid = Cesium.Ellipsoid.WGS84
|
||||||
|
let cartographic = ellipsoid.cartesianToCartographic(cartesian)
|
||||||
|
const x = Cesium.Math.toDegrees(cartographic.longitude)
|
||||||
|
const y = Cesium.Math.toDegrees(cartographic.latitude)
|
||||||
|
const z = cartographic.height
|
||||||
|
return { x, y, z }
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @extends Draw*/
|
||||||
|
class DrawStraightArrow extends Draw {
|
||||||
|
/**
|
||||||
|
* @constructor
|
||||||
|
* @param sdk
|
||||||
|
* @param [options] {object} 面属性
|
||||||
|
* @param [options.color=rgba(185,14,14,0.58)] {object} 线属性
|
||||||
|
|
||||||
|
* */
|
||||||
|
constructor(sdk, options = {}) {
|
||||||
|
super(sdk, options)
|
||||||
|
this.points = null
|
||||||
|
this.polygonHasCreated = false
|
||||||
|
}
|
||||||
|
|
||||||
|
static polygon(that, viewer = that.viewer) {
|
||||||
|
let id = that.randomString()
|
||||||
|
return viewer.entities.add(
|
||||||
|
new Cesium.Entity({
|
||||||
|
name: 'ArrowPolygon',
|
||||||
|
id,
|
||||||
|
polygon: {
|
||||||
|
hierarchy: new Cesium.CallbackProperty(e => {
|
||||||
|
let arr = that.computeStraightArrow(that.positions)
|
||||||
|
for (let i = 0; i < arr.length; i++) {
|
||||||
|
if (isNaN(arr[i].x)) {
|
||||||
|
arr = []
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new Cesium.PolygonHierarchy(arr)
|
||||||
|
}, false),
|
||||||
|
material: Cesium.Color.fromCssColorString(that.color),
|
||||||
|
outline: true,
|
||||||
|
outlineColor: Cesium.Color.GREEN,
|
||||||
|
zIndex: 99999999
|
||||||
|
}
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @desc 开始动态绘制面
|
||||||
|
* @method start
|
||||||
|
* @param cb {function} 回调函数
|
||||||
|
* @memberOf DrawPolygon
|
||||||
|
* @example draw.start((err,positions)=>{
|
||||||
|
*
|
||||||
|
* })
|
||||||
|
* */
|
||||||
|
start(cb) {
|
||||||
|
let that = this
|
||||||
|
// eslint-disable-next-line no-undef
|
||||||
|
if (YJ.Measure.GetMeasureStatus()) {
|
||||||
|
cb('上一次测量未结束')
|
||||||
|
} else {
|
||||||
|
super.start()
|
||||||
|
// eslint-disable-next-line no-undef
|
||||||
|
let into
|
||||||
|
YJ.Measure.SetMeasureStatus(true)
|
||||||
|
this.tip = new MouseTip('左键确定,右键取消;', that.sdk)
|
||||||
|
this.event = new MouseEvent(that.sdk)
|
||||||
|
this.positions = []
|
||||||
|
this.points_ids = [] //存放左键点击时临时添加的point的id
|
||||||
|
let cache_positions = []
|
||||||
|
let cache_84_position = []
|
||||||
|
this.anchorpoints = []
|
||||||
|
this.event.mouse_left((movement, cartesian) => {
|
||||||
|
if(into === '2D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
into = '3D'
|
||||||
|
if (!cartesian || this.anchorpoints[0]===cartesian) return
|
||||||
|
this.anchorpoints.push(cartesian)
|
||||||
|
|
||||||
|
let p = this.cartesian3Towgs84(cartesian, this.viewer)
|
||||||
|
p.lng = Number(p.lng.toFixed(8))
|
||||||
|
p.lat = Number(p.lat.toFixed(8))
|
||||||
|
if(cache_positions[0] && (p.lng === cache_positions[0].lng && p.lat === cache_positions[0].lat)) return;
|
||||||
|
cache_positions.push(p)
|
||||||
|
this.positions.push(p)
|
||||||
|
// console.log(this.cartesian3Towgs84(cartesian))
|
||||||
|
this.points_ids.push(this.create_point(cartesian))
|
||||||
|
if (this.points_ids.length === 2) {
|
||||||
|
let array = [cache_positions[0], cache_positions[1]]
|
||||||
|
cb(null, array)
|
||||||
|
this.end()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.event.mouse_move((movement, cartesian) => {
|
||||||
|
if(into === '2D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.tip.setPosition(
|
||||||
|
cartesian,
|
||||||
|
movement.endPosition.x,
|
||||||
|
movement.endPosition.y
|
||||||
|
)
|
||||||
|
if (!cartesian || this.points_ids.length === 0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let p = this.cartesian3Towgs84(cartesian, this.viewer)
|
||||||
|
this.positions = [this.positions[0], p];
|
||||||
|
if (this.points_ids.length === 1 && !Cesium.defined(this.arrowPolygon)) {
|
||||||
|
this.arrowPolygon = DrawStraightArrow.polygon(this)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.event.mouse_right((movement, cartesian) => {
|
||||||
|
if(into === '2D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
cb(null)
|
||||||
|
this.end()
|
||||||
|
})
|
||||||
|
|
||||||
|
this.event.gesture_pinck_start((movement, cartesian) => {
|
||||||
|
if(into === '2D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let startTime = new Date()
|
||||||
|
this.event.gesture_pinck_end(() => {
|
||||||
|
let endTime = new Date()
|
||||||
|
if (endTime - startTime >= 500) {
|
||||||
|
this.end()
|
||||||
|
cb(false)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (this.anchorpoints.length === 2) {
|
||||||
|
this.anchorpoints.push(cartesian)
|
||||||
|
cb(null, this.positions)
|
||||||
|
this.end()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (!cartesian || Cesium.defined(this.arrowPolygon)) return
|
||||||
|
this.tip.setPosition(
|
||||||
|
cartesian,
|
||||||
|
(movement.position1.x + movement.position2.x) / 2,
|
||||||
|
(movement.position1.y + movement.position2.y) / 2
|
||||||
|
)
|
||||||
|
this.anchorpoints.push(cartesian)
|
||||||
|
this.arrowPolygon = DrawStraightArrow.polygon(this)
|
||||||
|
cache_positions.push(this.cartesian3Towgs84(cartesian))
|
||||||
|
// console.log(this.cartesian3Towgs84(cartesian))
|
||||||
|
this.points_ids.push(this.create_point(cartesian))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!this._is2D && this._sdk2D) {
|
||||||
|
this.event2D = new MouseEvent(this._sdk2D)
|
||||||
|
this.event2D.mouse_left((movement, cartesian) => {
|
||||||
|
if(into === '3D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
into = '2D'
|
||||||
|
if (!cartesian || this.anchorpoints[0]===cartesian) return
|
||||||
|
this.anchorpoints.push(cartesian)
|
||||||
|
|
||||||
|
let p = this.cartesian3Towgs84(cartesian, this.viewer)
|
||||||
|
p.lng = Number(p.lng.toFixed(8))
|
||||||
|
p.lat = Number(p.lat.toFixed(8))
|
||||||
|
if(cache_positions[0] && (p.lng === cache_positions[0].lng && p.lat === cache_positions[0].lat)) return;
|
||||||
|
cache_positions.push(p)
|
||||||
|
this.positions.push(p)
|
||||||
|
// console.log(this.cartesian3Towgs84(cartesian))
|
||||||
|
this.points_ids.push(this.create_point(cartesian, this._sdk2D.viewer))
|
||||||
|
if (this.points_ids.length === 2) {
|
||||||
|
let array = [cache_positions[0], cache_positions[1]]
|
||||||
|
cb(null, array)
|
||||||
|
this.end()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.event2D.mouse_move((movement, cartesian) => {
|
||||||
|
if(into === '3D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.tip.setPosition(
|
||||||
|
cartesian,
|
||||||
|
movement.endPosition.x + this.viewer.canvas.width,
|
||||||
|
movement.endPosition.y
|
||||||
|
)
|
||||||
|
if (!cartesian || this.points_ids.length === 0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let p = this.cartesian3Towgs84(cartesian, this.viewer)
|
||||||
|
this.positions = [this.positions[0], p];
|
||||||
|
if (this.points_ids.length === 1 && !Cesium.defined(this.arrowPolygon)) {
|
||||||
|
this.arrowPolygon = DrawStraightArrow.polygon(this, this._sdk2D.viewer)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.event2D.mouse_right((movement, cartesian) => {
|
||||||
|
if(into === '3D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
cb(null)
|
||||||
|
this.end()
|
||||||
|
})
|
||||||
|
|
||||||
|
this.event2D.gesture_pinck_start((movement, cartesian) => {
|
||||||
|
if(into === '3D') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let startTime = new Date()
|
||||||
|
this.event2D.gesture_pinck_end(() => {
|
||||||
|
let endTime = new Date()
|
||||||
|
if (endTime - startTime >= 500) {
|
||||||
|
this.end()
|
||||||
|
cb(false)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (this.anchorpoints.length === 2) {
|
||||||
|
this.anchorpoints.push(cartesian)
|
||||||
|
cb(null, this.positions)
|
||||||
|
this.end()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (!cartesian || Cesium.defined(this.arrowPolygon)) return
|
||||||
|
this.tip.setPosition(
|
||||||
|
cartesian,
|
||||||
|
(movement.position1.x + movement.position2.x) / 2 + this.viewer.canvas.width,
|
||||||
|
(movement.position1.y + movement.position2.y) / 2
|
||||||
|
)
|
||||||
|
this.anchorpoints.push(cartesian)
|
||||||
|
this.arrowPolygon = DrawStraightArrow.polygon(this, this._sdk2D.viewer)
|
||||||
|
cache_positions.push(this.cartesian3Towgs84(cartesian))
|
||||||
|
// console.log(this.cartesian3Towgs84(cartesian))
|
||||||
|
this.points_ids.push(this.create_point(cartesian, this._sdk2D.viewer))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
end() {
|
||||||
|
super.end();
|
||||||
|
this.viewer.entities.remove(this.arrowPolygon)
|
||||||
|
if (!this._is2D && this._sdk2D) {
|
||||||
|
this._sdk2D.viewer.entities.remove(this.arrowPolygon)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default DrawStraightArrow
|
||||||
196
src/Event/index.js
Normal file
196
src/Event/index.js
Normal file
@ -0,0 +1,196 @@
|
|||||||
|
/**
|
||||||
|
* @name: index
|
||||||
|
* @author: Administrator
|
||||||
|
* @date: 2022-06-14 14:44
|
||||||
|
* @description:index
|
||||||
|
* @update: 2022-06-14 14:44
|
||||||
|
*/
|
||||||
|
|
||||||
|
export default class MouseEvent {
|
||||||
|
constructor(sdk) {
|
||||||
|
this.sdk = sdk
|
||||||
|
this.viewer = sdk.viewer
|
||||||
|
this.handler = new Cesium.ScreenSpaceEventHandler(
|
||||||
|
this.viewer.canvas
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/*事件*/
|
||||||
|
mouse_left(cb) {
|
||||||
|
// //左键点击事件
|
||||||
|
this.handler && this.handler.setInputAction((movement) => {
|
||||||
|
let cartesian = this.getcartesian(movement)
|
||||||
|
// cartesian = this.earth.czm.viewer.scene.pickPosition(movement.position)
|
||||||
|
// if (!cartesian) {
|
||||||
|
// cartesian = this.viewer.scene.camera.pickEllipsoid(
|
||||||
|
// movement.position,
|
||||||
|
// this.viewer.scene.globe.ellipsoid
|
||||||
|
// )
|
||||||
|
// }
|
||||||
|
// if (cartesian) {
|
||||||
|
// cb(movement, cartesian)
|
||||||
|
// }
|
||||||
|
if (cartesian) {
|
||||||
|
cb(movement, cartesian)
|
||||||
|
}
|
||||||
|
}, Cesium.ScreenSpaceEventType.LEFT_CLICK)
|
||||||
|
}
|
||||||
|
|
||||||
|
mouse_left_down(cb) {
|
||||||
|
// //左键按下事件
|
||||||
|
this.handler && this.handler.setInputAction((movement) => {
|
||||||
|
let cartesian = this.getcartesian(movement)
|
||||||
|
if (cartesian) {
|
||||||
|
cb(movement, cartesian)
|
||||||
|
}
|
||||||
|
}, Cesium.ScreenSpaceEventType.LEFT_DOWN)
|
||||||
|
}
|
||||||
|
mouse_left_up(cb) {
|
||||||
|
// //左键抬起事件
|
||||||
|
this.handler && this.handler.setInputAction((movement) => {
|
||||||
|
let cartesian = this.getcartesian(movement)
|
||||||
|
if (cartesian) {
|
||||||
|
cb(movement, cartesian)
|
||||||
|
}
|
||||||
|
}, Cesium.ScreenSpaceEventType.LEFT_UP)
|
||||||
|
}
|
||||||
|
|
||||||
|
mouse_move(cb, allowNull = false) {
|
||||||
|
this.handler && this.handler.setInputAction((movement) => {
|
||||||
|
let cartesian = this.getcartesian(movement)
|
||||||
|
|
||||||
|
if (cartesian || allowNull) {
|
||||||
|
cb(movement, cartesian)
|
||||||
|
}
|
||||||
|
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE)
|
||||||
|
}
|
||||||
|
|
||||||
|
mouse_right(cb, allowNull = false) {
|
||||||
|
this.handler && this.handler.setInputAction((movement) => {
|
||||||
|
let cartesian = this.getcartesian(movement)
|
||||||
|
if (cartesian || allowNull) {
|
||||||
|
cb(movement, cartesian)
|
||||||
|
}
|
||||||
|
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK)
|
||||||
|
}
|
||||||
|
|
||||||
|
mouse_right_down(cb, allowNull = false) {
|
||||||
|
this.handler && this.handler.setInputAction((movement) => {
|
||||||
|
let cartesian = this.getcartesian(movement)
|
||||||
|
if (cartesian || allowNull) {
|
||||||
|
cb(movement, cartesian)
|
||||||
|
}
|
||||||
|
}, Cesium.ScreenSpaceEventType.RIGHT_DOWN)
|
||||||
|
}
|
||||||
|
|
||||||
|
mouse_right_up(cb, allowNull = false) {
|
||||||
|
this.handler && this.handler.setInputAction((movement) => {
|
||||||
|
let cartesian = this.getcartesian(movement)
|
||||||
|
if (cartesian || allowNull) {
|
||||||
|
cb(movement, cartesian)
|
||||||
|
}
|
||||||
|
}, Cesium.ScreenSpaceEventType.RIGHT_UP)
|
||||||
|
}
|
||||||
|
|
||||||
|
mouse_wheel(cb) {
|
||||||
|
this.handler && this.handler.setInputAction(() => {
|
||||||
|
cb()
|
||||||
|
}, Cesium.ScreenSpaceEventType.WHEEL)
|
||||||
|
}
|
||||||
|
|
||||||
|
getcartesian(movement) {
|
||||||
|
// if (movement.endPosition) {
|
||||||
|
// movement.endPosition.y -= 2
|
||||||
|
// }
|
||||||
|
let position = movement.position || movement.endPosition
|
||||||
|
if(movement.position1 && movement.position2) {
|
||||||
|
position = {
|
||||||
|
x: (movement.position1.x + movement.position2.x) / 2,
|
||||||
|
y: (movement.position1.y + movement.position2.y) / 2,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let cartesian = this.viewer.scene.pickPosition(position)
|
||||||
|
if (!cartesian) {
|
||||||
|
const ray = this.viewer.camera.getPickRay(position); //相交的射线
|
||||||
|
let pickedObjects = this.viewer.scene.drillPickFromRay(ray, 10);
|
||||||
|
let result = {}
|
||||||
|
for (let i = 0; i < pickedObjects.length; i++) {
|
||||||
|
if (pickedObjects[i].position) {
|
||||||
|
result = pickedObjects[i]
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cartesian = result.position
|
||||||
|
if(!cartesian) {
|
||||||
|
cartesian = this.viewer.scene.globe.pick(ray, this.viewer.scene);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// console.log(cartesian)
|
||||||
|
// const updatedPositions = await Cesium.sampleTerrainMostDetailed(this.sdk.viewer.terrainProvider, Cesium.Cartographic.fromCartesian(cartesian, this.viewer.scene.globe.ellipsoid));
|
||||||
|
// console.log(updatedPositions)
|
||||||
|
return cartesian
|
||||||
|
// return this.earth.czm.viewer.scene.pickPosition(position)
|
||||||
|
}
|
||||||
|
|
||||||
|
//鼠标右键+键盘ctrl
|
||||||
|
mouse_right_keyboard_ctrl(cb) {
|
||||||
|
// //左键点击事件
|
||||||
|
this.handler && this.handler.setInputAction(
|
||||||
|
(movement) => {
|
||||||
|
let cartesian = this.getcartesian(movement)
|
||||||
|
if (cartesian) {
|
||||||
|
cb(movement, cartesian)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Cesium.ScreenSpaceEventType.RIGHT_CLICK,
|
||||||
|
Cesium.KeyboardEventModifier.CTRL
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 手势-双指触摸开始
|
||||||
|
gesture_pinck_start(cb) {
|
||||||
|
this.handler && this.handler.setInputAction((movement) => {
|
||||||
|
let cartesian = this.getcartesian(movement)
|
||||||
|
if (cartesian) {
|
||||||
|
cb(movement, cartesian)
|
||||||
|
}
|
||||||
|
}, Cesium.ScreenSpaceEventType.PINCH_START)
|
||||||
|
}
|
||||||
|
|
||||||
|
//手势-双指触摸开始+键盘ctrl
|
||||||
|
gesture_pinck_start_keyboard_ctrl(cb) {
|
||||||
|
this.handler && this.handler.setInputAction(
|
||||||
|
(movement) => {
|
||||||
|
let cartesian = this.getcartesian(movement)
|
||||||
|
if (cartesian) {
|
||||||
|
cb(movement, cartesian)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Cesium.ScreenSpaceEventType.PINCH_START,
|
||||||
|
Cesium.KeyboardEventModifier.CTRL
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 手势-双指触摸结束
|
||||||
|
gesture_pinck_end(cb) {
|
||||||
|
this.handler && this.handler.setInputAction((movement) => {
|
||||||
|
cb()
|
||||||
|
}, Cesium.ScreenSpaceEventType.PINCH_END)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 手势-双指触摸修改
|
||||||
|
gesture_pinck_move(cb) {
|
||||||
|
this.handler && this.handler.setInputAction((movement) => {
|
||||||
|
// let cartesian = this.getcartesian(movement)
|
||||||
|
// if (cartesian) {
|
||||||
|
// cb(movement, cartesian)
|
||||||
|
// }
|
||||||
|
}, Cesium.ScreenSpaceEventType.PINCH_MOVE)
|
||||||
|
}
|
||||||
|
|
||||||
|
destroy() {
|
||||||
|
if (this.handler)
|
||||||
|
this.handler.destroy() //关闭事件句柄
|
||||||
|
this.handler = null
|
||||||
|
}
|
||||||
|
}
|
||||||
578
src/Global/ClickCallback/index.js
Normal file
578
src/Global/ClickCallback/index.js
Normal file
@ -0,0 +1,578 @@
|
|||||||
|
/**
|
||||||
|
* @name: click
|
||||||
|
* @author: Administrator
|
||||||
|
* @date: 2023-05-28 11:05
|
||||||
|
* @description:click
|
||||||
|
* @update: 2023-05-28 11:05
|
||||||
|
*/
|
||||||
|
let leftClickHandler = null
|
||||||
|
let rightClickHandler = null
|
||||||
|
let MoveHandler = null
|
||||||
|
let leftClickCallbackMap = new Map()
|
||||||
|
let rightClickCallbackMap = new Map()
|
||||||
|
let MoveCallbackMap = new Map()
|
||||||
|
let selectedFeature;
|
||||||
|
|
||||||
|
|
||||||
|
function cartesian3Towgs84(cartesian, viewer) {
|
||||||
|
var ellipsoid = viewer.scene.globe.ellipsoid
|
||||||
|
var cartesian3 = new Cesium.Cartesian3(
|
||||||
|
cartesian.x,
|
||||||
|
cartesian.y,
|
||||||
|
cartesian.z
|
||||||
|
)
|
||||||
|
var cartographic = ellipsoid.cartesianToCartographic(cartesian3)
|
||||||
|
var lat = Cesium.Math.toDegrees(cartographic.latitude)
|
||||||
|
var lng = Cesium.Math.toDegrees(cartographic.longitude)
|
||||||
|
var alt = cartographic.height < 0 ? 0 : cartographic.height
|
||||||
|
return {
|
||||||
|
lng: lng,
|
||||||
|
lat: lat,
|
||||||
|
alt: alt,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getcartesian(sdk, movement) {
|
||||||
|
if (movement.endPosition) {
|
||||||
|
movement.endPosition.y -= 2
|
||||||
|
}
|
||||||
|
let position = movement.position || movement.endPosition
|
||||||
|
// 获取世界坐标系地表坐标,考虑地形,不包括模型,倾斜摄影模型表面;
|
||||||
|
let cartesian = sdk.viewer.scene.pickPosition(position)
|
||||||
|
if (!cartesian) {
|
||||||
|
const ray = sdk.viewer.camera.getPickRay(position); //相交的射线
|
||||||
|
cartesian = sdk.viewer.scene.globe.pick(ray, sdk.viewer.scene);
|
||||||
|
}
|
||||||
|
return cartesian
|
||||||
|
}
|
||||||
|
|
||||||
|
function openLeftClick(sdk, cb) {
|
||||||
|
if (!sdk || !sdk.viewer) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let click = true
|
||||||
|
leftClickHandler = new Cesium.ScreenSpaceEventHandler(sdk.viewer.canvas)
|
||||||
|
leftClickHandler.setInputAction((movement) => {
|
||||||
|
let cartesian = sdk.viewer.scene.pickPosition(movement.position)
|
||||||
|
if (!cartesian) {
|
||||||
|
const ray = sdk.viewer.camera.getPickRay(movement.position); //相交的射线
|
||||||
|
cartesian = sdk.viewer.scene.globe.pick(ray, sdk.viewer.scene);
|
||||||
|
}
|
||||||
|
if (!cartesian) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let pos84 = cartesian3Towgs84(cartesian, sdk.viewer)
|
||||||
|
|
||||||
|
cb && cb(pos84)
|
||||||
|
|
||||||
|
if (click) {
|
||||||
|
click = false
|
||||||
|
setTimeout(() => {
|
||||||
|
click = true
|
||||||
|
}, 600);
|
||||||
|
if (!YJ.Measure.GetMeasureStatus() && cartesian) {
|
||||||
|
let flag = false
|
||||||
|
for (let i = leftClickCallbackMap.size - 1; i >= 0; i--) {
|
||||||
|
let key = Array.from(leftClickCallbackMap.keys())[i]
|
||||||
|
let obj = leftClickCallbackMap.get(key)
|
||||||
|
if (obj) {
|
||||||
|
|
||||||
|
if (obj.that) {
|
||||||
|
// 是否为多边形
|
||||||
|
if (obj.that.type === 'PolygonObject') {
|
||||||
|
// 是否可点击y
|
||||||
|
if (obj.that.picking) {
|
||||||
|
if (obj.that.options.positions && obj.that.options.positions.length >= 3) {
|
||||||
|
let pt = turf.point([pos84.lng, pos84.lat]);
|
||||||
|
let polyPos = []
|
||||||
|
for (let i = 0; i < obj.that.options.positions.length; i++) {
|
||||||
|
polyPos.push([
|
||||||
|
obj.that.options.positions[i].lng,
|
||||||
|
obj.that.options.positions[i].lat
|
||||||
|
])
|
||||||
|
}
|
||||||
|
polyPos.push([
|
||||||
|
obj.that.options.positions[0].lng,
|
||||||
|
obj.that.options.positions[0].lat
|
||||||
|
])
|
||||||
|
let poly = turf.polygon([polyPos]);
|
||||||
|
let contain = turf.booleanPointInPolygon(pt, poly);
|
||||||
|
if (contain) {
|
||||||
|
obj.callback(
|
||||||
|
movement,
|
||||||
|
obj.that.options.id,
|
||||||
|
cartesian3Towgs84(getcartesian(sdk, movement), sdk.viewer), obj.that)
|
||||||
|
flag = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 聚集地
|
||||||
|
else if (obj.that.type === 'AssembleObject') {
|
||||||
|
if (obj.that.picking) {
|
||||||
|
if (obj.that.options.positions && obj.that.options.positions.length >= 3) {
|
||||||
|
let positions = obj.that.computeAssemble(obj.that.options.positions, true)
|
||||||
|
let pt = turf.point([pos84.lng, pos84.lat]);
|
||||||
|
let polyPos = []
|
||||||
|
for (let i = 0; i < positions.length; i += 2) {
|
||||||
|
polyPos.push([
|
||||||
|
positions[i],
|
||||||
|
positions[i + 1]
|
||||||
|
])
|
||||||
|
}
|
||||||
|
let poly = turf.polygon([polyPos]);
|
||||||
|
let contain = turf.booleanPointInPolygon(pt, poly);
|
||||||
|
if (contain) {
|
||||||
|
obj.callback(
|
||||||
|
movement,
|
||||||
|
obj.that.options.id,
|
||||||
|
cartesian3Towgs84(getcartesian(sdk, movement), sdk.viewer), obj.that)
|
||||||
|
flag = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 单箭头
|
||||||
|
else if (obj.that.type === 'AttackArrowObject') {
|
||||||
|
if (obj.that.picking) {
|
||||||
|
if (obj.that.options.positions && obj.that.options.positions.length >= 3) {
|
||||||
|
let pt = turf.point([pos84.lng, pos84.lat]);
|
||||||
|
let positions = obj.that.computeAttackArrow(obj.that.options.positions)
|
||||||
|
let polyPos = []
|
||||||
|
for (let m = 0; m < positions.length; m++) {
|
||||||
|
let pos84 = cartesian3Towgs84(positions[m], sdk.viewer)
|
||||||
|
polyPos.push([pos84.lng, pos84.lat])
|
||||||
|
}
|
||||||
|
let poly = turf.polygon([polyPos]);
|
||||||
|
let contain = turf.booleanPointInPolygon(pt, poly);
|
||||||
|
if (contain) {
|
||||||
|
obj.callback(
|
||||||
|
movement,
|
||||||
|
obj.that.options.id,
|
||||||
|
cartesian3Towgs84(getcartesian(sdk, movement), sdk.viewer), obj.that)
|
||||||
|
flag = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 双箭头
|
||||||
|
else if (obj.that.type === 'PincerArrowObject') {
|
||||||
|
if (obj.that.picking) {
|
||||||
|
if (obj.that.options.positions && obj.that.options.positions.length >= 5) {
|
||||||
|
let pt = turf.point([pos84.lng, pos84.lat]);
|
||||||
|
let positions = obj.that.computePincerArrow(obj.that.options.positions)
|
||||||
|
let polyPos = []
|
||||||
|
for (let m = 0; m < positions.length; m++) {
|
||||||
|
let pos84 = cartesian3Towgs84(positions[m], sdk.viewer)
|
||||||
|
polyPos.push([pos84.lng, pos84.lat])
|
||||||
|
}
|
||||||
|
let pos84_0 = cartesian3Towgs84(positions[0], sdk.viewer)
|
||||||
|
polyPos.push([pos84_0.lng, pos84_0.lat])
|
||||||
|
let poly = turf.polygon([polyPos]);
|
||||||
|
let contain = turf.booleanPointInPolygon(pt, poly);
|
||||||
|
if (contain) {
|
||||||
|
obj.callback(
|
||||||
|
movement,
|
||||||
|
obj.that.options.id,
|
||||||
|
cartesian3Towgs84(getcartesian(sdk, movement), sdk.viewer), obj.that)
|
||||||
|
flag = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 圆
|
||||||
|
else if (obj.that.type === 'CircleObject') {
|
||||||
|
if (obj.that.picking) {
|
||||||
|
let pt = turf.point([pos84.lng, pos84.lat]);
|
||||||
|
if (obj.that.options.center && obj.that.options.radius) {
|
||||||
|
let center = [obj.that.options.center.lng, obj.that.options.center.lat];
|
||||||
|
let radius = obj.that.options.radius / 1000;
|
||||||
|
let options = { steps: 360, units: 'kilometers' };
|
||||||
|
let circle = turf.circle(center, radius, options);
|
||||||
|
let contain = turf.booleanPointInPolygon(pt, circle);
|
||||||
|
if (contain) {
|
||||||
|
obj.callback(
|
||||||
|
movement,
|
||||||
|
obj.that.options.id,
|
||||||
|
cartesian3Towgs84(getcartesian(sdk, movement), sdk.viewer), obj.that)
|
||||||
|
flag = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 扇形
|
||||||
|
else if (obj.that.type === 'SectorObject') {
|
||||||
|
if (obj.that.picking) {
|
||||||
|
let pt = turf.point([pos84.lng, pos84.lat]);
|
||||||
|
if (obj.that.options.center && obj.that.options.radius && obj.that.options.startAngle && obj.that.options.endAngle) {
|
||||||
|
let positions = obj.that.calSector(obj.that.options.center, obj.that.options.radius, obj.that.options.startAngle, obj.that.options.endAngle, undefined, true)
|
||||||
|
let polyPos = []
|
||||||
|
for (let m = 0; m < positions.length; m++) {
|
||||||
|
polyPos.push([positions[m].lng, positions[m].lat])
|
||||||
|
}
|
||||||
|
let poly = turf.polygon([polyPos]);
|
||||||
|
let contain = turf.booleanPointInPolygon(pt, poly);
|
||||||
|
if (contain) {
|
||||||
|
obj.callback(
|
||||||
|
movement,
|
||||||
|
obj.that.options.id,
|
||||||
|
cartesian3Towgs84(getcartesian(sdk, movement), sdk.viewer), obj.that)
|
||||||
|
flag = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!flag) {
|
||||||
|
const pick = sdk.viewer.scene.pick(movement.position)
|
||||||
|
if (pick) {
|
||||||
|
if (pick.id) {
|
||||||
|
let entityId
|
||||||
|
// 矢量
|
||||||
|
if (pick.id.type && pick.id.type === 'vector' && pick.id.parentId) {
|
||||||
|
let obj = leftClickCallbackMap.get(pick.id.parentId)
|
||||||
|
if (obj.that.picking && obj.that.geojson) {
|
||||||
|
for (let i = 0; i < obj.that.geojson.features.length; i++) {
|
||||||
|
if (obj.that.geojson.features[i].id === pick.id._id) {
|
||||||
|
obj.callback(
|
||||||
|
movement,
|
||||||
|
obj.that.geojson.features[i].id,
|
||||||
|
cartesian3Towgs84(getcartesian(sdk, movement), sdk.viewer), obj.that)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (typeof pick.id.id == 'string') {
|
||||||
|
let array = pick.id.id.split('-')
|
||||||
|
array.splice(array.length - 1, 1)
|
||||||
|
entityId = array.join('-')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pick.id.properties && pick.id.properties.id && leftClickCallbackMap.has(pick.id.properties.id._value)) {
|
||||||
|
let obj = leftClickCallbackMap.get(pick.id.properties.id._value)
|
||||||
|
if (obj.that.picking) {
|
||||||
|
obj.callback(
|
||||||
|
movement,
|
||||||
|
pick.id.properties.id._value,
|
||||||
|
cartesian3Towgs84(getcartesian(sdk, movement), sdk.viewer), obj.that)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (leftClickCallbackMap.has(pick.id.id)) {
|
||||||
|
let obj = leftClickCallbackMap.get(pick.id.id)
|
||||||
|
if (obj.that.picking) {
|
||||||
|
obj.callback(
|
||||||
|
movement,
|
||||||
|
pick.id.id,
|
||||||
|
cartesian3Towgs84(getcartesian(sdk, movement), sdk.viewer), obj.that)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (entityId && leftClickCallbackMap.has(entityId)) {
|
||||||
|
let obj = leftClickCallbackMap.get(entityId)
|
||||||
|
if (obj.that.picking) {
|
||||||
|
obj.callback(
|
||||||
|
movement,
|
||||||
|
entityId,
|
||||||
|
cartesian3Towgs84(getcartesian(sdk, movement), sdk.viewer), obj.that)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (pick.primitive) {
|
||||||
|
if (typeof pick.id == 'string' && leftClickCallbackMap.has(pick.id)) {
|
||||||
|
let obj = leftClickCallbackMap.get(pick.id)
|
||||||
|
obj.callback(
|
||||||
|
movement,
|
||||||
|
pick.id,
|
||||||
|
cartesian3Towgs84(getcartesian(sdk, movement), sdk.viewer), obj.that)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (pick.primitive && pick.primitive.id) {
|
||||||
|
if (leftClickCallbackMap.has(pick.primitive.id)) {
|
||||||
|
let obj = leftClickCallbackMap.get(pick.primitive.id)
|
||||||
|
if (obj.that.picking) {
|
||||||
|
if (obj.that.type === 'bim') {
|
||||||
|
if (YJ.Global.getBimPickStatus(sdk)) {
|
||||||
|
obj.callback(
|
||||||
|
movement,
|
||||||
|
pick.primitive,
|
||||||
|
cartesian3Towgs84(getcartesian(sdk, movement), sdk.viewer), obj.that)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
obj.callback(
|
||||||
|
movement,
|
||||||
|
pick.primitive.id,
|
||||||
|
cartesian3Towgs84(getcartesian(sdk, movement), sdk.viewer), obj.that)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pick.content && (!pick.primitive || !pick.primitive.id)) {
|
||||||
|
if (leftClickCallbackMap.has(pick.content.tileset.id)) {
|
||||||
|
let obj = leftClickCallbackMap.get(pick.content.tileset.id)
|
||||||
|
if (obj.that.picking) {
|
||||||
|
if (obj.that.type === 'bim') {
|
||||||
|
if (YJ.Global.getBimPickStatus(sdk)) {
|
||||||
|
obj.callback(
|
||||||
|
movement,
|
||||||
|
pick.content.tileset,
|
||||||
|
cartesian3Towgs84(getcartesian(sdk, movement), sdk.viewer), obj.that)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
obj.callback(
|
||||||
|
movement,
|
||||||
|
pick.content.tileset.id,
|
||||||
|
cartesian3Towgs84(getcartesian(sdk, movement), sdk.viewer), obj.that)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// if (click) {
|
||||||
|
// click = false
|
||||||
|
// setTimeout(() => {
|
||||||
|
// click = true
|
||||||
|
// }, 300);
|
||||||
|
// if (!YJ.Measure.GetMeasureStatus()) {
|
||||||
|
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}, Cesium.ScreenSpaceEventType.LEFT_CLICK)
|
||||||
|
|
||||||
|
// leftClickHandler.setInputAction(function (movement) {
|
||||||
|
// const feature = sdk.viewer.scene.pick(movement.endPosition);
|
||||||
|
// // unselectFeature(selectedFeature);
|
||||||
|
// if (selectedFeature) {
|
||||||
|
// selectedFeature.color = Cesium.Color.WHITE;
|
||||||
|
// }
|
||||||
|
// selectedFeature = feature
|
||||||
|
// if (feature) {
|
||||||
|
// feature.color = Cesium.Color.YELLOW;
|
||||||
|
// }
|
||||||
|
// }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
|
||||||
|
// }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeLeftClick(sdk) {
|
||||||
|
leftClickHandler.destroy() //关闭事件句柄
|
||||||
|
leftClickHandler = null
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
function openRightClick(sdk) {
|
||||||
|
if (!sdk || !sdk.viewer) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
rightClickHandler = new Cesium.ScreenSpaceEventHandler(sdk.viewer.canvas)
|
||||||
|
rightClickHandler.setInputAction((movement) => {
|
||||||
|
if (!YJ.Measure.GetMeasureStatus()) {
|
||||||
|
const pick = sdk.viewer.scene.pick(movement.position)
|
||||||
|
if (pick && pick.id) {
|
||||||
|
let id
|
||||||
|
if (pick.id.type && pick.id.type === 'vector' && pick.id.parentId) {
|
||||||
|
let obj = rightClickCallbackMap.get(pick.id.parentId)
|
||||||
|
if (obj.that.picking && obj.that.geojson) {
|
||||||
|
for (let i = 0; i < obj.that.geojson.features.length; i++) {
|
||||||
|
if (obj.that.geojson.features[i].id === pick.id._id) {
|
||||||
|
obj.callback(
|
||||||
|
movement,
|
||||||
|
obj.that.geojson.features[i].id,
|
||||||
|
cartesian3Towgs84(getcartesian(sdk, movement), sdk.viewer), obj.that)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (typeof pick.id === 'string') {
|
||||||
|
id = pick.id
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
id = pick.id.id
|
||||||
|
}
|
||||||
|
if (rightClickCallbackMap.has(id)) {
|
||||||
|
let obj = rightClickCallbackMap.get(id)
|
||||||
|
if (obj.that.picking) {
|
||||||
|
let cartesian = getcartesian(sdk, movement)
|
||||||
|
if (!cartesian) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
obj.callback(
|
||||||
|
movement,
|
||||||
|
id,
|
||||||
|
cartesian3Towgs84(cartesian, sdk.viewer), obj.that)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pick && pick.content) {
|
||||||
|
if (rightClickCallbackMap.has(pick.content.tileset.id)) {
|
||||||
|
let obj = rightClickCallbackMap.get(pick.content.tileset.id)
|
||||||
|
if (obj.that.picking) {
|
||||||
|
if (obj.that.type === 'bim') {
|
||||||
|
if (YJ.Global.getBimPickStatus(sdk)) {
|
||||||
|
let cartesian = getcartesian(sdk, movement)
|
||||||
|
if (!cartesian) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
obj.callback(
|
||||||
|
movement,
|
||||||
|
pick.getProperty('id'),
|
||||||
|
cartesian3Towgs84(cartesian, sdk.viewer), obj.that)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
let cartesian = getcartesian(sdk, movement)
|
||||||
|
if (!cartesian) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
obj.callback(
|
||||||
|
movement,
|
||||||
|
pick.content.tileset.id,
|
||||||
|
cartesian3Towgs84(cartesian, sdk.viewer), obj.that)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK)
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeRightClick() {
|
||||||
|
if (rightClickHandler) {
|
||||||
|
rightClickHandler.destroy() //关闭事件句柄
|
||||||
|
rightClickHandler = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function openMove(sdk) {
|
||||||
|
MoveHandler = new Cesium.ScreenSpaceEventHandler(sdk.viewer.canvas)
|
||||||
|
MoveHandler.setInputAction(function (movement) {
|
||||||
|
const pick = sdk.viewer.scene.pick(movement.endPosition);
|
||||||
|
// unselectFeature(selectedFeature);
|
||||||
|
// if (selectedFeature) {
|
||||||
|
// let color = '#fff'
|
||||||
|
// let state = selectedFeature.getProperty('state')
|
||||||
|
// switch (state) {
|
||||||
|
// case '0':
|
||||||
|
// color = '#fff'
|
||||||
|
// break;
|
||||||
|
// case '1':
|
||||||
|
// color = '#f00'
|
||||||
|
// break;
|
||||||
|
// case '2':
|
||||||
|
// color = '#0f0'
|
||||||
|
// break;
|
||||||
|
// case '3':
|
||||||
|
// color = '#00f'
|
||||||
|
// break;
|
||||||
|
// default:
|
||||||
|
// }
|
||||||
|
// selectedFeature.color = Cesium.Color.fromCssColorString(color).withAlpha(selectedFeature.tileset.transparency)
|
||||||
|
// }
|
||||||
|
// if (pick && pick.id) { }
|
||||||
|
// if (pick && pick.content) {
|
||||||
|
// if (MoveCallbackMap.has(pick.content.tileset.id)) {
|
||||||
|
// let obj = MoveCallbackMap.get(pick.content.tileset.id)
|
||||||
|
// if (obj.that.picking) {
|
||||||
|
// if (obj.that.type === 'bim') {
|
||||||
|
// if (YJ.Global.getBimPickStatus(sdk)) {
|
||||||
|
// selectedFeature = pick
|
||||||
|
// pick.color = Cesium.Color.YELLOW;
|
||||||
|
// }
|
||||||
|
// else {
|
||||||
|
// selectedFeature = null
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// else {
|
||||||
|
// selectedFeature = pick
|
||||||
|
// pick.color = Cesium.Color.YELLOW;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// else {
|
||||||
|
// selectedFeature = null
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeMove() {
|
||||||
|
if (MoveHandler) {
|
||||||
|
MoveHandler.destroy() //关闭事件句柄
|
||||||
|
MoveHandler = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*注册左键回调*/
|
||||||
|
function regLeftClickCallback(id, callback, that) {
|
||||||
|
|
||||||
|
leftClickCallbackMap.set(id, { callback, that })
|
||||||
|
}/*取消左键回调*/
|
||||||
|
function unRegLeftClickCallback(id,) {
|
||||||
|
leftClickCallbackMap.delete(id,)
|
||||||
|
}
|
||||||
|
|
||||||
|
/*注册右键回调*/
|
||||||
|
function regRightClickCallback(id, callback, that) {
|
||||||
|
rightClickCallbackMap.set(id, { callback, that })
|
||||||
|
}/*取消右键回调*/
|
||||||
|
function unRegRightClickCallback(id,) {
|
||||||
|
rightClickCallbackMap.delete(id,)
|
||||||
|
}
|
||||||
|
|
||||||
|
/*注册左键回调*/
|
||||||
|
function regMoveCallback(id, callback, that) {
|
||||||
|
MoveCallbackMap.set(id, { callback, that })
|
||||||
|
}/*取消左键回调*/
|
||||||
|
function unregMoveCallback(id,) {
|
||||||
|
MoveCallbackMap.delete(id,)
|
||||||
|
}
|
||||||
|
|
||||||
|
function getLeftClickState() {
|
||||||
|
if (leftClickHandler) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getRightClickState() {
|
||||||
|
if (rightClickHandler) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getMoveState() {
|
||||||
|
if (MoveHandler) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export { openLeftClick, closeLeftClick, regLeftClickCallback, unRegLeftClickCallback, openRightClick, closeRightClick, regRightClickCallback, unRegRightClickCallback, openMove, closeMove, regMoveCallback, unregMoveCallback, getLeftClickState, getRightClickState, getMoveState }
|
||||||
253
src/Global/Contour/index.js
Normal file
253
src/Global/Contour/index.js
Normal file
@ -0,0 +1,253 @@
|
|||||||
|
/**
|
||||||
|
* 等高线
|
||||||
|
*/
|
||||||
|
import Dialog from "../../Obj/Element/Dialog";
|
||||||
|
import Tools from "../../Tools";
|
||||||
|
|
||||||
|
let _DialogObject = null;
|
||||||
|
let material = null;
|
||||||
|
let handler = null;
|
||||||
|
let activeHeightElm = null;
|
||||||
|
let tools
|
||||||
|
activeHeightElm = document.createElement('div')
|
||||||
|
activeHeightElm.className = 'YJ-customize-active-height-elm'
|
||||||
|
activeHeightElm.style.position = 'absolute'
|
||||||
|
activeHeightElm.style.left = '10px'
|
||||||
|
activeHeightElm.style.top = '10px'
|
||||||
|
activeHeightElm.style.width = '100px'
|
||||||
|
// activeHeightElm.style.backgroundColor = 'rgba(0, 0, 0, 0.5)'
|
||||||
|
activeHeightElm.style.textAlign = 'center'
|
||||||
|
activeHeightElm.style.pointerEvents = 'none'
|
||||||
|
activeHeightElm.style.color = '#ff0000'
|
||||||
|
activeHeightElm.style.display = 'none'
|
||||||
|
async function dialog(sdk) {
|
||||||
|
if (!sdk || _DialogObject) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!material) {
|
||||||
|
createMaterial()
|
||||||
|
}
|
||||||
|
if (!tools) {
|
||||||
|
tools = new Tools()
|
||||||
|
}
|
||||||
|
|
||||||
|
_DialogObject = await new Dialog(sdk, {}, {
|
||||||
|
title: "等高线", left: '180px',
|
||||||
|
top: '100px',
|
||||||
|
confirmCallBack: options => { },
|
||||||
|
closeCallBack: () => {
|
||||||
|
_DialogObject = null
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
_DialogObject._element.body.className =
|
||||||
|
_DialogObject._element.body.className + ' contour'
|
||||||
|
let contentElm = document.createElement('div')
|
||||||
|
contentElm.innerHTML = `
|
||||||
|
<span class="custom-divider"></span>
|
||||||
|
<div class="div-item">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col input-select-unit-box">
|
||||||
|
<span class="label">高差</span>
|
||||||
|
<div class="input-number input-number-unit-1">
|
||||||
|
<input class="input gap" type="number" title="" min="0" max="1000">
|
||||||
|
<span class="unit">m</span>
|
||||||
|
<span class="arrow"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col input-select-unit-box" style="flex: 0 0 120px;">
|
||||||
|
<span class="label">主线颜色</span>
|
||||||
|
<div class="primary-lice-color"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col input-select-unit-box">
|
||||||
|
<span class="label">次线条数</span>
|
||||||
|
<div class="input-number input-number-unit-1">
|
||||||
|
<input class="input gap2" type="number" title="" min="0" max="10">
|
||||||
|
<span class="unit"></span>
|
||||||
|
<span class="arrow"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col input-select-unit-box" style="flex: 0 0 120px;">
|
||||||
|
<span class="label">次线颜色</span>
|
||||||
|
<div class="secondary-lice-color"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row" style="align-items: flex-start;">
|
||||||
|
<div class="col">
|
||||||
|
</div>
|
||||||
|
<div class="col" style="flex: 0 0 120px;">
|
||||||
|
<span class="label">开关</span>
|
||||||
|
<input class="btn-switch" type="checkbox">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<span class="custom-divider"></span>
|
||||||
|
`
|
||||||
|
contentElm.innerHTML = `
|
||||||
|
<span class="custom-divider"></span>
|
||||||
|
<div class="div-item">
|
||||||
|
<div class="row" style="align-items: flex-start;">
|
||||||
|
<div class="col" style="flex: 0 0 120px;">
|
||||||
|
<span class="label">开关</span>
|
||||||
|
<input class="btn-switch" type="checkbox">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
_DialogObject.contentAppChild(contentElm)
|
||||||
|
|
||||||
|
contentElm.getElementsByClassName('btn-switch')[0].addEventListener('change', (e) => {
|
||||||
|
if (e.target.checked) {
|
||||||
|
if (handler) {
|
||||||
|
handler.destroy()
|
||||||
|
}
|
||||||
|
if (!sdk.viewer.container.getElementsByClassName('YJ-customize-active-height-elm')[0]) {
|
||||||
|
sdk.viewer.container.appendChild(activeHeightElm)
|
||||||
|
}
|
||||||
|
|
||||||
|
handler = new Cesium.ScreenSpaceEventHandler(
|
||||||
|
sdk.viewer.canvas
|
||||||
|
)
|
||||||
|
handler.setInputAction((movement) => {
|
||||||
|
let cartesian = sdk.viewer.scene.pickPosition(movement.endPosition)
|
||||||
|
if (cartesian) {
|
||||||
|
let top = 0
|
||||||
|
let left = 0
|
||||||
|
if (sdk.viewer && sdk.viewer._element) {
|
||||||
|
let element = sdk.viewer._element.getElementsByClassName('cesium-widget')[0].getElementsByTagName('canvas')[0]
|
||||||
|
top = element.getBoundingClientRect().top + window.scrollY
|
||||||
|
left = element.getBoundingClientRect().left + window.scrollX
|
||||||
|
}
|
||||||
|
activeHeightElm.style.left = movement.endPosition.x - 50 + left + 'px'
|
||||||
|
activeHeightElm.style.top = movement.endPosition.y - 40 + top + 'px'
|
||||||
|
activeHeightElm.style.display = 'block'
|
||||||
|
let pos84 = tools.cartesian3Towgs84(cartesian, sdk.viewer)
|
||||||
|
let mainContourHeight = Math.floor(pos84.alt / material.uniforms.spacing) * material.uniforms.spacing
|
||||||
|
let gap = pos84.alt - mainContourHeight
|
||||||
|
let gap2 = material.uniforms.spacing / (material.uniforms.secondaryLinesCount + 1)
|
||||||
|
let activeHeight = Math.floor(gap / gap2) * gap2 + mainContourHeight
|
||||||
|
if ((pos84.alt - activeHeight) > gap2 / 2) {
|
||||||
|
activeHeight = activeHeight + gap2
|
||||||
|
}
|
||||||
|
material.uniforms.mouseHeight = pos84.alt
|
||||||
|
material.uniforms.mousePosition = cartesian
|
||||||
|
activeHeightElm.innerHTML = `${activeHeight.toFixed(0)}`
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
activeHeightElm.style.display = 'none'
|
||||||
|
}
|
||||||
|
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE)
|
||||||
|
sdk.viewer.scene.globe.material = material;
|
||||||
|
} else {
|
||||||
|
if (handler) {
|
||||||
|
handler.destroy()
|
||||||
|
handler = null
|
||||||
|
}
|
||||||
|
if (sdk.viewer.container.getElementsByClassName('YJ-customize-active-height-elm')[0]) {
|
||||||
|
activeHeightElm.style.display = 'none'
|
||||||
|
sdk.viewer.container.removeChild(activeHeightElm)
|
||||||
|
}
|
||||||
|
sdk.viewer.scene.globe.material = null;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function createMaterial() {
|
||||||
|
Cesium.Material._materialCache._materials.ElevationContour.fabric.source = `
|
||||||
|
uniform vec4 color;
|
||||||
|
uniform vec4 secondaryLinesColor;
|
||||||
|
uniform float spacing;
|
||||||
|
uniform float width;
|
||||||
|
uniform float secondaryLinesWidth;
|
||||||
|
uniform float mouseHeight;
|
||||||
|
uniform float secondaryLinesCount; // 0=无次线, 1=1条次线, 2=2条次线...
|
||||||
|
|
||||||
|
czm_material czm_getMaterial(czm_materialInput materialInput)
|
||||||
|
{
|
||||||
|
czm_material material = czm_getDefaultMaterial(materialInput);
|
||||||
|
|
||||||
|
// 主等高线计算
|
||||||
|
float distanceToMainContour = mod(materialInput.height, spacing);
|
||||||
|
|
||||||
|
// 抗锯齿计算
|
||||||
|
#if (__VERSION__ == 300 || defined(GL_OES_standard_derivatives))
|
||||||
|
float dxc = abs(dFdx(materialInput.height));
|
||||||
|
float dyc = abs(dFdy(materialInput.height));
|
||||||
|
float dFMain = max(dxc, dyc) * czm_pixelRatio * width;
|
||||||
|
#else
|
||||||
|
float dFMain = czm_pixelRatio * width;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bool isMainContour = distanceToMainContour < dFMain;
|
||||||
|
bool isSecondaryContour = false;
|
||||||
|
float dFSecondary = 0.0;
|
||||||
|
float secondarySpacing = 0.0;
|
||||||
|
|
||||||
|
// 只有当存在次线时才计算次线
|
||||||
|
if(secondaryLinesCount > 0.0) {
|
||||||
|
secondarySpacing = spacing / (secondaryLinesCount + 1.0);
|
||||||
|
float distanceToSecondaryContour = mod(materialInput.height, secondarySpacing);
|
||||||
|
|
||||||
|
// 确保次线不会与主线重叠
|
||||||
|
float minDistanceToMain = min(distanceToMainContour, spacing - distanceToMainContour);
|
||||||
|
bool notCloseToMain = minDistanceToMain > dFMain * 2.0; // 2倍线宽缓冲
|
||||||
|
|
||||||
|
#if (__VERSION__ == 300 || defined(GL_OES_standard_derivatives))
|
||||||
|
dFSecondary = max(dxc, dyc) * czm_pixelRatio * secondaryLinesWidth;
|
||||||
|
#else
|
||||||
|
dFSecondary = czm_pixelRatio * secondaryLinesWidth;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
isSecondaryContour = (distanceToSecondaryContour < dFSecondary) && notCloseToMain;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算当前高度所属的等高线高度
|
||||||
|
float mainContourHeight = floor(materialInput.height / spacing) * spacing;
|
||||||
|
float secondaryContourHeight = floor(materialInput.height / spacing * (secondaryLinesCount + 1.0)) * spacing / (secondaryLinesCount + 1.0);
|
||||||
|
|
||||||
|
// 高亮判断
|
||||||
|
bool shouldHighlight = false;
|
||||||
|
if(isMainContour && abs(mainContourHeight - mouseHeight) < 0.5 * (spacing/(secondaryLinesCount+1.0))) {
|
||||||
|
shouldHighlight = true;
|
||||||
|
} else if(isSecondaryContour && abs(secondaryContourHeight - mouseHeight) < 0.5 * (spacing/(secondaryLinesCount+1.0))) {
|
||||||
|
shouldHighlight = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 颜色输出
|
||||||
|
vec4 outColor;
|
||||||
|
if(shouldHighlight) {
|
||||||
|
outColor = vec4(1.0, 0.0, 0.0, 1.0);
|
||||||
|
} else if(isMainContour) {
|
||||||
|
outColor = czm_gammaCorrect(vec4(color.rgb, color.a));
|
||||||
|
} else if(isSecondaryContour) {
|
||||||
|
outColor = czm_gammaCorrect(vec4(secondaryLinesColor.rgb, secondaryLinesColor.a));
|
||||||
|
} else {
|
||||||
|
outColor = vec4(0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
material.diffuse = outColor.rgb;
|
||||||
|
material.alpha = outColor.a;
|
||||||
|
return material;
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
material = new Cesium.Material({
|
||||||
|
fabric: {
|
||||||
|
type: "ElevationContour",
|
||||||
|
uniforms: {
|
||||||
|
width: 2,
|
||||||
|
secondaryLinesWidth: 1, // 次级线宽度
|
||||||
|
spacing: 200,
|
||||||
|
color: Cesium.Color.fromCssColorString('#ffd000'),
|
||||||
|
secondaryLinesColor: Cesium.Color.fromCssColorString('#0dff00').withAlpha(0.5),
|
||||||
|
mouseHeight: -100000,
|
||||||
|
mousePosition: new Cesium.Cartesian3(0, 0, 0),
|
||||||
|
secondaryLinesCount: 3
|
||||||
|
},
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export { dialog }
|
||||||
37
src/Global/DTH/changeClassificationPrimitive.js
Normal file
37
src/Global/DTH/changeClassificationPrimitive.js
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
function changeClassificationPrimitive(options, array) {
|
||||||
|
this.options = options
|
||||||
|
this.array = array
|
||||||
|
}
|
||||||
|
|
||||||
|
changeClassificationPrimitive.prototype.getGeometry = function () {
|
||||||
|
return Cesium.PolygonGeometry.createGeometry(this.options);
|
||||||
|
};
|
||||||
|
changeClassificationPrimitive.prototype.update = function (context, frameState, commandList) {
|
||||||
|
var geometry = this.getGeometry();
|
||||||
|
if (!geometry) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._primitive = new Cesium.ClassificationPrimitive({
|
||||||
|
geometryInstances: new Cesium.GeometryInstance({
|
||||||
|
geometry: geometry,
|
||||||
|
id: {
|
||||||
|
type: 'dth',
|
||||||
|
...this.array,
|
||||||
|
},
|
||||||
|
attributes: {
|
||||||
|
color: Cesium.ColorGeometryInstanceAttribute.fromColor(
|
||||||
|
Cesium.Color.fromRandom({ alpha: 0.5 })
|
||||||
|
),
|
||||||
|
show: new Cesium.ShowGeometryInstanceAttribute(true),
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
classificationType: Cesium.ClassificationType.CESIUM_3D_TILE,
|
||||||
|
});
|
||||||
|
var primitive = this._primitive
|
||||||
|
|
||||||
|
primitive.update(context, frameState, commandList);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
export { changeClassificationPrimitive }
|
||||||
538
src/Global/DTH/index.js
Normal file
538
src/Global/DTH/index.js
Normal file
@ -0,0 +1,538 @@
|
|||||||
|
import { getHost, getToken } from "../../on";
|
||||||
|
class DTH {
|
||||||
|
constructor(sdk, options = {}) {
|
||||||
|
this.sdk = sdk
|
||||||
|
this.primitives = {
|
||||||
|
building: [],
|
||||||
|
unit: [],
|
||||||
|
dth: []
|
||||||
|
}
|
||||||
|
this.options = { ...options }
|
||||||
|
this.options.host = this.options.host || getHost()
|
||||||
|
this.temporaryDth = []
|
||||||
|
this.dth = {}
|
||||||
|
this.PickBuildingEvent = new Cesium.Event();
|
||||||
|
this.initEvents()
|
||||||
|
this.activeBuilding
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 注册点击的事件回调
|
||||||
|
* @memberOf DTH
|
||||||
|
* */
|
||||||
|
PickCallback(that, cb) {
|
||||||
|
this.PickBuildingEvent.addEventListener(
|
||||||
|
cb,
|
||||||
|
that
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
//场景事件
|
||||||
|
initEvents() {
|
||||||
|
new Cesium.ScreenSpaceEventHandler(this.sdk.viewer.scene.canvas).setInputAction(((e) => {
|
||||||
|
if (YJ.Measure.GetMeasureStatus()) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!this.isActivate) return;
|
||||||
|
let pickFeature = this.sdk.viewer.scene.pick(e.position);
|
||||||
|
if (pickFeature) {
|
||||||
|
//点击了已有的分户单体化
|
||||||
|
if (pickFeature.primitive && pickFeature.primitive instanceof Cesium.ClassificationPrimitive && pickFeature.id && (pickFeature.id.type == "yj-dth-dth" || pickFeature.id.type == "yj-dth-highlight")) {
|
||||||
|
this.getIDBypickFeature(pickFeature); //处理点击到的楼层
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (pickFeature.primitive && pickFeature.primitive instanceof Cesium.ClassificationPrimitive && pickFeature.id && pickFeature.id.type == "yj-dth-unit") {
|
||||||
|
this.highlightPrimitive && this.sdk.viewer.scene.primitives.remove(this.highlightPrimitive)
|
||||||
|
this.handlePickEvent(pickFeature.id)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if (pickFeature.id && pickFeature.id.type === 'yj-dth-highlight') {
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
this.highlightPrimitive && this.sdk.viewer.scene.primitives.remove(this.highlightPrimitive)
|
||||||
|
let position = this.sdk.viewer.scene.pickPosition(e.position); //屏幕坐标转为笛卡尔空间坐标
|
||||||
|
if (!position) return;
|
||||||
|
|
||||||
|
let c = Cesium.Cartographic.fromCartesian(position); //笛卡尔坐标转为经纬度(弧度)
|
||||||
|
let point = [Cesium.Math.toDegrees(c.longitude), Cesium.Math.toDegrees(c.latitude)]; //转为经纬度点
|
||||||
|
this.queryByPoint(point, c.height);
|
||||||
|
}), Cesium.ScreenSpaceEventType.LEFT_CLICK);
|
||||||
|
|
||||||
|
let coverLabelEntity = this.sdk.viewer.entities.getOrCreateEntity('yj-dth-cover-label')
|
||||||
|
coverLabelEntity.show = false
|
||||||
|
// this.sdk.viewer.entities.add({
|
||||||
|
// position: Cesium.Cartesian3.fromDegrees(-75.1641667, 39.9522222),
|
||||||
|
// label: {
|
||||||
|
// text: "Philadelphia",
|
||||||
|
// font: "24px Helvetica",
|
||||||
|
// fillColor: Cesium.Color.SKYBLUE,
|
||||||
|
// outlineColor: Cesium.Color.BLACK,
|
||||||
|
// outlineWidth: 2,
|
||||||
|
// style: Cesium.LabelStyle.FILL_AND_OUTLINE,
|
||||||
|
// },
|
||||||
|
// });
|
||||||
|
let lastPickTime = 0;
|
||||||
|
let _this = this
|
||||||
|
let timeoutEvent
|
||||||
|
new Cesium.ScreenSpaceEventHandler(this.sdk.viewer.scene.canvas).setInputAction(((movement) => {
|
||||||
|
if (YJ.Measure.GetMeasureStatus()) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const now = Date.now();
|
||||||
|
if (now - lastPickTime < 100) {
|
||||||
|
clearTimeout(timeoutEvent)
|
||||||
|
timeoutEvent = setTimeout(() => {
|
||||||
|
pick(movement)
|
||||||
|
}, 100);
|
||||||
|
return
|
||||||
|
}
|
||||||
|
clearTimeout(timeoutEvent)
|
||||||
|
lastPickTime = now;
|
||||||
|
pick(movement)
|
||||||
|
} catch (error) {
|
||||||
|
}
|
||||||
|
}), Cesium.ScreenSpaceEventType.MOUSE_MOVE);
|
||||||
|
function pick(e) {
|
||||||
|
let pickFeature = _this.sdk.viewer.scene.pick(e.endPosition);
|
||||||
|
if (pickFeature) {
|
||||||
|
let labelText = ''
|
||||||
|
if (pickFeature.primitive && pickFeature.primitive instanceof Cesium.ClassificationPrimitive && pickFeature.id && (pickFeature.id.type === "yj-dth-dth" || pickFeature.id.type === "yj-dth-highlight")) {
|
||||||
|
labelText = pickFeature.id.build_info.name + ' - ' + pickFeature.id.unit_info.name + ' - ' + pickFeature.id.room_num
|
||||||
|
}
|
||||||
|
else if (pickFeature.primitive && pickFeature.primitive instanceof Cesium.ClassificationPrimitive && pickFeature.id && pickFeature.id.type === "yj-dth-unit") {
|
||||||
|
if (pickFeature.id.build_info.name) {
|
||||||
|
labelText = pickFeature.id.build_info.name + ' - ' + pickFeature.id.name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (pickFeature.primitive && pickFeature.primitive instanceof Cesium.ClassificationPrimitive && pickFeature.id && pickFeature.id.type === "yj-dth-build") {
|
||||||
|
if (pickFeature.id.name) {
|
||||||
|
labelText = pickFeature.id.name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (pickFeature.primitive && pickFeature.primitive.id && pickFeature.primitive.id.id && pickFeature.primitive.id.id === 'yj-dth-cover-label') {
|
||||||
|
coverLabelEntity.position = _this.sdk.viewer.scene.pickPosition(e.endPosition)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
coverLabelEntity.show = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (labelText) {
|
||||||
|
coverLabelEntity.position = _this.sdk.viewer.scene.pickPosition(e.endPosition)
|
||||||
|
coverLabelEntity.label = new Cesium.LabelGraphics({
|
||||||
|
text: labelText,
|
||||||
|
font: "20px Helvetica",
|
||||||
|
pixelOffset: { x: 0, y: -30 },
|
||||||
|
fillColor: Cesium.Color.fromCssColorString('#ffffff'),
|
||||||
|
outlineColor: Cesium.Color.BLACK,
|
||||||
|
outlineWidth: 1,
|
||||||
|
showBackground: true,
|
||||||
|
backgroundColor: Cesium.Color.fromCssColorString('#000000').withAlpha(0.8),
|
||||||
|
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
|
||||||
|
disableDepthTestDistance: Number.POSITIVE_INFINITY,
|
||||||
|
})
|
||||||
|
coverLabelEntity.show = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*根据用户信息查询单体化*/
|
||||||
|
queryByUserInfo(data) {
|
||||||
|
this.queryByPoint([data.position.lng, data.position.lat], data.position.alt, data.id)
|
||||||
|
}
|
||||||
|
|
||||||
|
//点查询 点击查询是查询分层的数据
|
||||||
|
async queryByPoint(point) {
|
||||||
|
let url = ""
|
||||||
|
if (this.options.host.endsWith("yjearth4.0")) {
|
||||||
|
url = this.options.host + '/api/v1/dth/build/query_by_point'
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
url = this.options.host + '/yjearth4.0/api/v1/dth/build/query_by_point'
|
||||||
|
}
|
||||||
|
url += '?point=' + JSON.stringify({ 'lng': point[0], 'lat': point[1] })
|
||||||
|
let response = await fetch(url, {
|
||||||
|
method: 'get',
|
||||||
|
// body: JSON.stringify({point: {'lng': point[0],'lat': point[1]}}),
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
"token": getToken(),
|
||||||
|
"Authorization": "Bearer " + getToken(),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (response.status === 200) {
|
||||||
|
let data = await response.json()
|
||||||
|
if (data.code === 200 || data.code === 0) {
|
||||||
|
this.processQueryByPointResults(data.data)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
window.ELEMENT && window.ELEMENT.Message({
|
||||||
|
message: data.msg || data.message,
|
||||||
|
type: 'warning',
|
||||||
|
duration: 1500
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理查询结果
|
||||||
|
async processQueryByPointResults(data, isflyto, offset = { heading: 0.0, pitch: -90.0, roll: 0.0 }) {
|
||||||
|
data.build_info && this.handlePickEvent(data)
|
||||||
|
let range
|
||||||
|
this.clearAllDthPrimitive()
|
||||||
|
this.clearAllUnitPrimitive()
|
||||||
|
if (this.activeBuilding) {
|
||||||
|
this.clearBuildingPrimitive(this.activeBuilding)
|
||||||
|
this.activeBuilding = null
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.build_info) {
|
||||||
|
range = JSON.parse(data.build_info.range)
|
||||||
|
if (data.dan_yuan.length > 0) {
|
||||||
|
for (let i = 0; i < data.dan_yuan.length; i++) {
|
||||||
|
if (data.dan_yuan[i].children.length > 0) {
|
||||||
|
this.addDthPrimitive(data.dan_yuan[i].children, data.build_info, data.dan_yuan[i])
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.addUnitPrimitive([data.dan_yuan[i]], data.build_info, data.dan_yuan[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.activeBuilding = data.build_info.ID || data.build_info.id
|
||||||
|
this.addBuildingPrimitive([data.build_info])
|
||||||
|
}
|
||||||
|
if (isflyto) {
|
||||||
|
if (data.info && data.info.dan_yuan) {
|
||||||
|
range = JSON.parse(data.info.dan_yuan.range)
|
||||||
|
}
|
||||||
|
if (data.info && data.info.hu) {
|
||||||
|
range = JSON.parse(data.info.hu.range)
|
||||||
|
for (let i = 0; i < range.length; i++) {
|
||||||
|
range[i].alt = data.info.hu.bottom
|
||||||
|
}
|
||||||
|
for (let i = 0; i < this.primitives.dth.length; i++) {
|
||||||
|
await this.primitives.dth[i].readyPromise
|
||||||
|
let primitivesData = this.primitives.dth[i]._primitiveOptions.geometryInstances[0].id
|
||||||
|
if (primitivesData.ID === data.info.hu.ID && primitivesData.room_num === data.info.hu.room_num) {
|
||||||
|
let pickFeature = {
|
||||||
|
id: { ...data.info.hu, build_info: { ...data.build_info }, unit_info: data.info.dan_yuan },
|
||||||
|
primitive: this.primitives.dth[i]
|
||||||
|
}
|
||||||
|
this.getIDBypickFeature(pickFeature)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.flyTo(range, offset)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加房屋Primitive
|
||||||
|
async addBuildingPrimitive(array) {
|
||||||
|
for (let i = 0; i < array.length; i++) {
|
||||||
|
let fromDegreesArray = []
|
||||||
|
let extrudedHeight = 0
|
||||||
|
let positions = JSON.parse(array[i].range)
|
||||||
|
for (let m = 0; m < positions.length; m++) {
|
||||||
|
if (extrudedHeight < positions[m].alt) {
|
||||||
|
extrudedHeight = positions[m].alt
|
||||||
|
}
|
||||||
|
fromDegreesArray.push(positions[m].lng, positions[m].lat, 0)
|
||||||
|
}
|
||||||
|
let polygonGeometry = new Cesium.PolygonGeometry({
|
||||||
|
polygonHierarchy: new Cesium.PolygonHierarchy(
|
||||||
|
Cesium.Cartesian3.fromDegreesArrayHeights(fromDegreesArray)
|
||||||
|
),
|
||||||
|
// perPositionHeight: true, //使用z坐标 否则高度从0开始
|
||||||
|
extrudedHeight: 100000000, //拉伸高度
|
||||||
|
});
|
||||||
|
this.primitives.building.push(this.sdk.viewer.scene.primitives.add(
|
||||||
|
new Cesium.ClassificationPrimitive({
|
||||||
|
geometryInstances: new Cesium.GeometryInstance({
|
||||||
|
id: {
|
||||||
|
type: 'yj-dth-build',
|
||||||
|
...array[i],
|
||||||
|
},
|
||||||
|
geometry: Cesium.PolygonGeometry.createGeometry(polygonGeometry),
|
||||||
|
attributes: {
|
||||||
|
color: Cesium.ColorGeometryInstanceAttribute.fromColor(
|
||||||
|
Cesium.Color.fromCssColorString('rgb(255, 235, 59, 0.4)')
|
||||||
|
),
|
||||||
|
show: new Cesium.ShowGeometryInstanceAttribute(true),
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
classificationType: Cesium.ClassificationType.CESIUM_3D_TILE,
|
||||||
|
})
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 根据id删除房屋Primitive
|
||||||
|
clearBuildingPrimitive(id) {
|
||||||
|
for (let i = this.primitives.building.length - 1; i >= 0; i--) {
|
||||||
|
if (id === this.primitives.building[i]._primitiveOptions.geometryInstances[0].id.ID || id === this.primitives.building[i]._primitiveOptions.geometryInstances[0].id.id) {
|
||||||
|
this.sdk.viewer.scene.primitives.remove(this.primitives.building[i])
|
||||||
|
this.primitives.building.splice(i, 1)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 删除全部房屋Primitive
|
||||||
|
clearAllBuildingPrimitive() {
|
||||||
|
for (let i = this.primitives.building.length - 1; i >= 0; i--) {
|
||||||
|
this.sdk.viewer.scene.primitives.remove(this.primitives.building[i])
|
||||||
|
}
|
||||||
|
this.primitives.building = []
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加单元Primitive
|
||||||
|
async addUnitPrimitive(array, build_info, unit_info) {
|
||||||
|
for (let i = 0; i < array.length; i++) {
|
||||||
|
let fromDegreesArray = []
|
||||||
|
let extrudedHeight = 0
|
||||||
|
let positions = JSON.parse(array[i].range)
|
||||||
|
for (let m = 0; m < positions.length; m++) {
|
||||||
|
if (extrudedHeight < positions[m].alt) {
|
||||||
|
extrudedHeight = positions[m].alt
|
||||||
|
}
|
||||||
|
fromDegreesArray.push(positions[m].lng, positions[m].lat, 0)
|
||||||
|
}
|
||||||
|
let polygonGeometry = new Cesium.PolygonGeometry({
|
||||||
|
polygonHierarchy: new Cesium.PolygonHierarchy(
|
||||||
|
Cesium.Cartesian3.fromDegreesArrayHeights(fromDegreesArray)
|
||||||
|
),
|
||||||
|
// perPositionHeight: true, //使用z坐标 否则高度从0开始
|
||||||
|
extrudedHeight: 100000000, //拉伸高度
|
||||||
|
});
|
||||||
|
this.primitives.unit.push(this.sdk.viewer.scene.primitives.add(
|
||||||
|
new Cesium.ClassificationPrimitive({
|
||||||
|
geometryInstances: new Cesium.GeometryInstance({
|
||||||
|
id: {
|
||||||
|
type: 'yj-dth-unit',
|
||||||
|
...array[i],
|
||||||
|
build_info: { ...build_info },
|
||||||
|
unit_info: { ...unit_info }
|
||||||
|
},
|
||||||
|
geometry: Cesium.PolygonGeometry.createGeometry(polygonGeometry),
|
||||||
|
attributes: {
|
||||||
|
color: Cesium.ColorGeometryInstanceAttribute.fromColor(
|
||||||
|
Cesium.Color.fromCssColorString('rgb(255, 235, 59, 0.4)')
|
||||||
|
),
|
||||||
|
show: new Cesium.ShowGeometryInstanceAttribute(true),
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
classificationType: Cesium.ClassificationType.CESIUM_3D_TILE,
|
||||||
|
})
|
||||||
|
))
|
||||||
|
this.primitives.unit.push(this.sdk.viewer.scene.primitives.add(
|
||||||
|
new Cesium.GroundPolylinePrimitive({
|
||||||
|
geometryInstances: new Cesium.GeometryInstance({
|
||||||
|
geometry: new Cesium.GroundPolylineGeometry({
|
||||||
|
positions: Cesium.Cartesian3.fromDegreesArrayHeights(fromDegreesArray),
|
||||||
|
width: 2.0
|
||||||
|
}),
|
||||||
|
attributes: {
|
||||||
|
color: Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.fromCssColorString('#00ff0a').withAlpha(0.8))
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
appearance: new Cesium.PolylineColorAppearance()
|
||||||
|
})
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 根据id删除单元Primitive
|
||||||
|
clearUnitPrimitive(id) {
|
||||||
|
for (let i = this.primitives.building.length - 1; i >= 0; i--) {
|
||||||
|
if (id === this.primitives.building[i]._primitiveOptions.geometryInstances[0].id.ID || id === this.primitives.building[i]._primitiveOptions.geometryInstances[0].id.id) {
|
||||||
|
this.sdk.viewer.scene.primitives.remove(this.primitives.unit[i])
|
||||||
|
this.primitives.unit.splice(i, 1)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除全部单元Primitive
|
||||||
|
clearAllUnitPrimitive() {
|
||||||
|
for (let i = this.primitives.unit.length - 1; i >= 0; i--) {
|
||||||
|
this.sdk.viewer.scene.primitives.remove(this.primitives.unit[i])
|
||||||
|
}
|
||||||
|
this.primitives.unit = []
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加单体化Primitive
|
||||||
|
addDthPrimitive(array, build_info, unit_info) {
|
||||||
|
for (let i = 0; i < array.length; i++) {
|
||||||
|
let positions = JSON.parse(array[i].range)
|
||||||
|
let fromDegreesArray = []
|
||||||
|
for (let m = 0; m < positions.length; m++) {
|
||||||
|
fromDegreesArray.push(positions[m].lng, positions[m].lat, array[i].bottom + 0.3)
|
||||||
|
}
|
||||||
|
let polygonGeometry = new Cesium.PolygonGeometry({
|
||||||
|
polygonHierarchy: new Cesium.PolygonHierarchy(
|
||||||
|
Cesium.Cartesian3.fromDegreesArrayHeights(fromDegreesArray)
|
||||||
|
),
|
||||||
|
perPositionHeight: true, //使用z坐标 否则高度从0开始
|
||||||
|
extrudedHeight: array[i].height + array[i].bottom, //拉伸高度
|
||||||
|
});
|
||||||
|
let polygonGeometryBorder = new Cesium.PolygonGeometry({
|
||||||
|
polygonHierarchy: new Cesium.PolygonHierarchy(
|
||||||
|
Cesium.Cartesian3.fromDegreesArrayHeights(fromDegreesArray)
|
||||||
|
),
|
||||||
|
perPositionHeight: true, //使用z坐标 否则高度从0开始
|
||||||
|
extrudedHeight: array[i].bottom, //拉伸高度
|
||||||
|
});
|
||||||
|
this.primitives.dth.push(this.sdk.viewer.scene.primitives.add(
|
||||||
|
new Cesium.ClassificationPrimitive({
|
||||||
|
geometryInstances: new Cesium.GeometryInstance({
|
||||||
|
id: {
|
||||||
|
type: 'yj-dth-dth',
|
||||||
|
...array[i],
|
||||||
|
build_info: { ...build_info },
|
||||||
|
unit_info: { ...unit_info }
|
||||||
|
},
|
||||||
|
geometry: Cesium.PolygonGeometry.createGeometry(polygonGeometry),
|
||||||
|
attributes: {
|
||||||
|
color: Cesium.ColorGeometryInstanceAttribute.fromColor(
|
||||||
|
Cesium.Color.fromCssColorString('rgb(0, 64, 255, 0.4)')
|
||||||
|
),
|
||||||
|
show: new Cesium.ShowGeometryInstanceAttribute(true),
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
classificationType: Cesium.ClassificationType.CESIUM_3D_TILE,
|
||||||
|
})
|
||||||
|
));
|
||||||
|
this.primitives.dth.push(this.sdk.viewer.scene.primitives.add(
|
||||||
|
new Cesium.ClassificationPrimitive({
|
||||||
|
geometryInstances: new Cesium.GeometryInstance({
|
||||||
|
id: {
|
||||||
|
type: 'yj-dth-dth-border',
|
||||||
|
...array[i],
|
||||||
|
},
|
||||||
|
geometry: Cesium.PolygonGeometry.createGeometry(polygonGeometryBorder),
|
||||||
|
attributes: {
|
||||||
|
color: Cesium.ColorGeometryInstanceAttribute.fromColor(
|
||||||
|
Cesium.Color.fromCssColorString('rgb(0, 0, 0, 1)')
|
||||||
|
),
|
||||||
|
show: new Cesium.ShowGeometryInstanceAttribute(true),
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
classificationType: Cesium.ClassificationType.CESIUM_3D_TILE,
|
||||||
|
})
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 根据id删除单体化Primitive
|
||||||
|
clearDthPrimitive(id) {
|
||||||
|
for (let i = this.primitives.dth.length - 1; i >= 0; i--) {
|
||||||
|
if (id === this.primitives.dth[i]._primitiveOptions.geometryInstances[0].id.ID || id === this.primitives.dth[i]._primitiveOptions.geometryInstances[0].id.id) {
|
||||||
|
this.sdk.viewer.scene.primitives.remove(this.primitives.dth[i])
|
||||||
|
this.primitives.dth.splice(i, 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除全部单体化Primitive
|
||||||
|
clearAllDthPrimitive() {
|
||||||
|
this.highlightPrimitive && this.sdk.viewer.scene.primitives.remove(this.highlightPrimitive)
|
||||||
|
for (let i = this.primitives.dth.length - 1; i >= 0; i--) {
|
||||||
|
this.sdk.viewer.scene.primitives.remove(this.primitives.dth[i])
|
||||||
|
}
|
||||||
|
this.primitives.dth = []
|
||||||
|
}
|
||||||
|
|
||||||
|
getIDBypickFeature(pickFeature) {
|
||||||
|
//恢复上一个贴对象面显示
|
||||||
|
if (this.clickHighlightPrimitive) {
|
||||||
|
this.clickHighlightPrimitive.show = true;
|
||||||
|
}
|
||||||
|
this.highlightPrimitive && this.sdk.viewer.scene.primitives.remove(this.highlightPrimitive)
|
||||||
|
this.highlightPrimitive = this.sdk.viewer.scene.primitives.add(
|
||||||
|
new Cesium.ClassificationPrimitive({
|
||||||
|
geometryInstances: new Cesium.GeometryInstance({
|
||||||
|
id: {
|
||||||
|
...pickFeature.id,
|
||||||
|
type: 'yj-dth-highlight',
|
||||||
|
|
||||||
|
},
|
||||||
|
geometry: pickFeature.primitive._primitiveOptions.geometryInstances[0].geometry,
|
||||||
|
attributes: {
|
||||||
|
color: Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.fromCssColorString('#ff9800').withAlpha(0.8)),
|
||||||
|
show: new Cesium.ShowGeometryInstanceAttribute(true),
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
classificationType: Cesium.ClassificationType.CESIUM_3D_TILE,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
this.highlightPrimitive.readyPromise.then(() => {
|
||||||
|
//设置当前点击的贴对象面不显示
|
||||||
|
pickFeature.primitive.show = false;
|
||||||
|
})
|
||||||
|
this.clickHighlightPrimitive = pickFeature.primitive;
|
||||||
|
|
||||||
|
let range = pickFeature.id.range
|
||||||
|
if (typeof pickFeature.id.range === 'string') {
|
||||||
|
range = JSON.parse(pickFeature.id.range)
|
||||||
|
}
|
||||||
|
this.getHilightArea(range)
|
||||||
|
this.handlePickEvent(pickFeature.id)
|
||||||
|
}
|
||||||
|
|
||||||
|
//处理点击事件
|
||||||
|
handlePickEvent(id) {
|
||||||
|
this.PickBuildingEvent.raiseEvent(id); //触发选中事件 通知界面更新
|
||||||
|
}
|
||||||
|
|
||||||
|
getHilightArea(points, radius = 1) {
|
||||||
|
let arr = []
|
||||||
|
points.forEach((point) => {
|
||||||
|
arr.push([(point.lng), (point.lat)])
|
||||||
|
})
|
||||||
|
arr.push(arr[0])
|
||||||
|
var poly = turf.polygon([arr])
|
||||||
|
var buffered = turf.buffer(poly, Number(radius) / 1000)
|
||||||
|
return buffered.geometry.coordinates
|
||||||
|
}
|
||||||
|
|
||||||
|
async flyTo(positions, offset = { heading: 0.0, pitch: -90.0, roll: 0.0 }) {
|
||||||
|
let tools = new YJ.Tools(this.sdk)
|
||||||
|
let height = 0
|
||||||
|
let positionArray = []
|
||||||
|
for (let i = 0; i < positions.length; i++) {
|
||||||
|
if (positions[i].alt) {
|
||||||
|
height = positions[i].alt
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
height = await tools.getClampToHeight(positions[i])
|
||||||
|
}
|
||||||
|
let a = Cesium.Cartesian3.fromDegrees(positions[i].lng, positions[i].lat, height)
|
||||||
|
positionArray.push(a.x, a.y, a.z)
|
||||||
|
}
|
||||||
|
let BoundingSphere = await Cesium.BoundingSphere.fromVertices(positionArray)
|
||||||
|
this.sdk.viewer.camera.flyToBoundingSphere(BoundingSphere, {
|
||||||
|
offset: {
|
||||||
|
heading: Cesium.Math.toRadians(offset.heading || 0),
|
||||||
|
pitch: Cesium.Math.toRadians((offset.pitch || offset.pitch === 0) ? offset.pitch : -90),
|
||||||
|
roll: Cesium.Math.toRadians(offset.roll || 0)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
activate() {
|
||||||
|
this.isActivate = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
deactivate() {
|
||||||
|
this.isActivate = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default DTH
|
||||||
267
src/Global/DTH/index1.js
Normal file
267
src/Global/DTH/index1.js
Normal file
@ -0,0 +1,267 @@
|
|||||||
|
import { getHost, getToken } from "../../on";
|
||||||
|
class DTH {
|
||||||
|
constructor(sdk, options = {}) {
|
||||||
|
this.sdk = sdk
|
||||||
|
this.primitives = {
|
||||||
|
building: [],
|
||||||
|
dth: []
|
||||||
|
}
|
||||||
|
this.options = {...options}
|
||||||
|
this.options.host = this.options.host || getHost()
|
||||||
|
this.temporaryDth = []
|
||||||
|
this.dth = {}
|
||||||
|
this.HandlePickHouseEvent = new Cesium.Event();
|
||||||
|
this.initEvents()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 注册分户点击的事件回调
|
||||||
|
* @memberOf DTH
|
||||||
|
* */
|
||||||
|
houseSelectedCallback(that, cb) {
|
||||||
|
this.HandlePickHouseEvent.addEventListener(
|
||||||
|
cb,
|
||||||
|
that
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
//场景事件
|
||||||
|
initEvents() {
|
||||||
|
new Cesium.ScreenSpaceEventHandler(this.sdk.viewer.scene.canvas).setInputAction(((e) => {
|
||||||
|
if (!this.isActivate) return;
|
||||||
|
let pickFeature = this.sdk.viewer.scene.pick(e.position);
|
||||||
|
if (pickFeature) {
|
||||||
|
//点击了已有的分户单体化
|
||||||
|
if (pickFeature.primitive && pickFeature.primitive instanceof Cesium.ClassificationPrimitive && pickFeature.id && pickFeature.id.type == "dth") {
|
||||||
|
this.getIDBypickFeature(pickFeature); //处理点击到的楼层
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pickFeature.id && pickFeature.id.type === 'highlight') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.highlightPrimitive && this.sdk.viewer.scene.primitives.remove(this.highlightPrimitive)
|
||||||
|
let position = this.sdk.viewer.scene.pickPosition(e.position); //屏幕坐标转为笛卡尔空间坐标
|
||||||
|
if (!position) return;
|
||||||
|
|
||||||
|
let c = Cesium.Cartographic.fromCartesian(position); //笛卡尔坐标转为经纬度(弧度)
|
||||||
|
let point = [Cesium.Math.toDegrees(c.longitude), Cesium.Math.toDegrees(c.latitude)]; //转为经纬度点
|
||||||
|
this.queryByPoint(point, c.height);
|
||||||
|
}), Cesium.ScreenSpaceEventType.LEFT_CLICK);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*根据用户信息查询单体化*/
|
||||||
|
queryByUserInfo(data) {
|
||||||
|
this.queryByPoint([data.position.lng, data.position.lat], data.position.alt, data.id)
|
||||||
|
}
|
||||||
|
|
||||||
|
//点查询 点击查询是查询分层的数据
|
||||||
|
async queryByPoint(point) {
|
||||||
|
let url = ""
|
||||||
|
if (this.options.host.endsWith("yjearth4.0")) {
|
||||||
|
url = this.options.host + '/api/v1/dth/query_by_point'
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
url = this.options.host + '/yjearth4.0/api/v1/dth/query_by_point'
|
||||||
|
}
|
||||||
|
url += '?point=' + JSON.stringify({'lng': point[0],'lat': point[1]})
|
||||||
|
let response = await fetch(url, {
|
||||||
|
method: 'get',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
"token": getToken(),
|
||||||
|
"Authorization": "Bearer " + getToken(),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (response.status === 200) {
|
||||||
|
let data = await response.json()
|
||||||
|
if (data.code === 200 || data.code === 0) {
|
||||||
|
this.clearAllDthPrimitive()
|
||||||
|
this.addDthPrimitive(data.data.list)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
window.ELEMENT && window.ELEMENT.Message({
|
||||||
|
message: data.msg || data.message,
|
||||||
|
type: 'warning',
|
||||||
|
duration: 1500
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 添加房屋Primitive
|
||||||
|
async addBuildingPrimitive(array) {
|
||||||
|
for (let i = 0; i < array.length; i++) {
|
||||||
|
let fromDegreesArray = []
|
||||||
|
let extrudedHeight = 0
|
||||||
|
let positions = JSON.parse(array[i].range)
|
||||||
|
for (let m = 0; m < positions.length; m++) {
|
||||||
|
if (extrudedHeight < positions[m].alt) {
|
||||||
|
extrudedHeight = positions[m].alt
|
||||||
|
}
|
||||||
|
fromDegreesArray.push(positions[m].lng, positions[m].lat, 0)
|
||||||
|
}
|
||||||
|
let polygonGeometry = new Cesium.PolygonGeometry({
|
||||||
|
polygonHierarchy: new Cesium.PolygonHierarchy(
|
||||||
|
Cesium.Cartesian3.fromDegreesArrayHeights(fromDegreesArray)
|
||||||
|
),
|
||||||
|
// perPositionHeight: true, //使用z坐标 否则高度从0开始
|
||||||
|
extrudedHeight: 100000000, //拉伸高度
|
||||||
|
});
|
||||||
|
this.primitives.building.push(this.sdk.viewer.scene.primitives.add(
|
||||||
|
new Cesium.ClassificationPrimitive({
|
||||||
|
geometryInstances: new Cesium.GeometryInstance({
|
||||||
|
id: {
|
||||||
|
...array[i],
|
||||||
|
},
|
||||||
|
geometry: Cesium.PolygonGeometry.createGeometry(polygonGeometry),
|
||||||
|
attributes: {
|
||||||
|
color: Cesium.ColorGeometryInstanceAttribute.fromColor(
|
||||||
|
Cesium.Color.fromCssColorString('rgb(255, 235, 59, 0.4)')
|
||||||
|
),
|
||||||
|
show: new Cesium.ShowGeometryInstanceAttribute(true),
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
classificationType: Cesium.ClassificationType.CESIUM_3D_TILE,
|
||||||
|
}), 0
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 根据id删除房屋Primitive
|
||||||
|
clearBuildingPrimitive(id) {
|
||||||
|
for (let i = this.primitives.building.length - 1; i >= 0; i--) {
|
||||||
|
if (id === this.primitives.building[i]._primitiveOptions.geometryInstances[0].id.ID) {
|
||||||
|
this.sdk.viewer.scene.primitives.remove(this.primitives.building[i])
|
||||||
|
this.primitives.building.splice(i, 1)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 删除全部房屋Primitive
|
||||||
|
clearAllBuildingPrimitive() {
|
||||||
|
for (let i = this.primitives.building.length - 1; i >= 0; i--) {
|
||||||
|
this.sdk.viewer.scene.primitives.remove(this.primitives.building[i])
|
||||||
|
}
|
||||||
|
this.primitives.building = []
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加单体化Primitive
|
||||||
|
addDthPrimitive(array) {
|
||||||
|
let readyIndex = 0
|
||||||
|
let Primitives = []
|
||||||
|
for (let i = 0; i < array.length; i++) {
|
||||||
|
let positions = JSON.parse(array[i].range)
|
||||||
|
let fromDegreesArray = []
|
||||||
|
for (let m = 0; m < positions.length; m++) {
|
||||||
|
fromDegreesArray.push(positions[m].lng, positions[m].lat, array[i].bottom)
|
||||||
|
}
|
||||||
|
let polygonGeometry = new Cesium.PolygonGeometry({
|
||||||
|
polygonHierarchy: new Cesium.PolygonHierarchy(
|
||||||
|
Cesium.Cartesian3.fromDegreesArrayHeights(fromDegreesArray)
|
||||||
|
),
|
||||||
|
perPositionHeight: true, //使用z坐标 否则高度从0开始
|
||||||
|
extrudedHeight: array[i].height + array[i].bottom, //拉伸高度
|
||||||
|
});
|
||||||
|
let Primitive = new Cesium.ClassificationPrimitive({
|
||||||
|
geometryInstances: new Cesium.GeometryInstance({
|
||||||
|
id: {
|
||||||
|
type: 'dth',
|
||||||
|
...array[i],
|
||||||
|
},
|
||||||
|
geometry: Cesium.PolygonGeometry.createGeometry(polygonGeometry),
|
||||||
|
attributes: {
|
||||||
|
color: Cesium.ColorGeometryInstanceAttribute.fromColor(
|
||||||
|
Cesium.Color.fromCssColorString('rgb(255, 235, 59, 0.4)')
|
||||||
|
),
|
||||||
|
show: new Cesium.ShowGeometryInstanceAttribute(true),
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
classificationType: Cesium.ClassificationType.CESIUM_3D_TILE,
|
||||||
|
})
|
||||||
|
Primitives.push(Primitive)
|
||||||
|
this.sdk.viewer.scene.primitives.add(Primitive)
|
||||||
|
Primitive._readyPromise.then(()=>{
|
||||||
|
this.clearDthPrimitive(Primitive._primitiveOptions.geometryInstances[0].id.ID)
|
||||||
|
readyIndex ++
|
||||||
|
if(readyIndex >= array.length) {
|
||||||
|
this.primitives.dth.push(...Primitives);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 根据id删除单体化Primitive
|
||||||
|
clearDthPrimitive(id) {
|
||||||
|
for (let i = this.primitives.dth.length - 1; i >= 0; i--) {
|
||||||
|
if (id === this.primitives.dth[i]._primitiveOptions.geometryInstances[0].id.ID) {
|
||||||
|
this.sdk.viewer.scene.primitives.remove(this.primitives.dth[i])
|
||||||
|
this.primitives.dth.splice(i, 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getDthPrimitive(id) {
|
||||||
|
for (let i = this.primitives.dth.length - 1; i >= 0; i--) {
|
||||||
|
if (id === this.primitives.dth[i]._primitiveOptions.geometryInstances[0].id.ID) {
|
||||||
|
return this.primitives.dth[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除全部单体化Primitive
|
||||||
|
clearAllDthPrimitive() {
|
||||||
|
for (let i = this.primitives.dth.length - 1; i >= 0; i--) {
|
||||||
|
this.sdk.viewer.scene.primitives.remove(this.primitives.dth[i])
|
||||||
|
}
|
||||||
|
this.primitives.dth = []
|
||||||
|
}
|
||||||
|
|
||||||
|
getIDBypickFeature(pickFeature) {
|
||||||
|
//恢复上一个贴对象面显示
|
||||||
|
if (this.clickHighlightPrimitive) {
|
||||||
|
this.clickHighlightPrimitive.show = true;
|
||||||
|
}
|
||||||
|
this.highlightPrimitive && this.sdk.viewer.scene.primitives.remove(this.highlightPrimitive)
|
||||||
|
this.highlightPrimitive = this.sdk.viewer.scene.primitives.add(
|
||||||
|
new Cesium.ClassificationPrimitive({
|
||||||
|
geometryInstances: new Cesium.GeometryInstance({
|
||||||
|
id: {
|
||||||
|
type: 'highlight',
|
||||||
|
},
|
||||||
|
geometry: pickFeature.primitive._primitiveOptions.geometryInstances[0].geometry,
|
||||||
|
attributes: {
|
||||||
|
color: Cesium.ColorGeometryInstanceAttribute.fromColor(
|
||||||
|
Cesium.Color.fromCssColorString('rgb(255, 0, 0, 1)')
|
||||||
|
),
|
||||||
|
show: new Cesium.ShowGeometryInstanceAttribute(true),
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
classificationType: Cesium.ClassificationType.CESIUM_3D_TILE,
|
||||||
|
})
|
||||||
|
)
|
||||||
|
this.highlightPrimitive.readyPromise.then(() => {
|
||||||
|
//设置当前点击的贴对象面不显示
|
||||||
|
pickFeature.primitive.show = false;
|
||||||
|
})
|
||||||
|
this.clickHighlightPrimitive = pickFeature.primitive;
|
||||||
|
this.handlePickHouse(pickFeature.id)
|
||||||
|
}
|
||||||
|
|
||||||
|
//处理拾取到的户室信息
|
||||||
|
handlePickHouse(id) {
|
||||||
|
this.HandlePickHouseEvent.raiseEvent({}); //触发选中事件 通知界面更新
|
||||||
|
}
|
||||||
|
|
||||||
|
activate() {
|
||||||
|
this.isActivate = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
deactivate() {
|
||||||
|
this.isActivate = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default DTH
|
||||||
53
src/Global/ExportKml/index.js
Normal file
53
src/Global/ExportKml/index.js
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
/**
|
||||||
|
* @name: index
|
||||||
|
* @author: Administrator
|
||||||
|
* @date: 2023-09-11 16:41
|
||||||
|
* @description:index
|
||||||
|
* @update: 2023-09-11 16:41
|
||||||
|
*/
|
||||||
|
import BillboardObject from "../../Obj/Base/BillboardObject";
|
||||||
|
import PolygonObject from "../../Obj/Base/PolygonObject";
|
||||||
|
import PolylineObject from "../../Obj/Base/PolylineObject";
|
||||||
|
import Circle from "../../Obj/Base/CircleDiffuse";
|
||||||
|
|
||||||
|
function exportKml(list = []) {
|
||||||
|
|
||||||
|
let entities = new Cesium.EntityCollection();
|
||||||
|
list.forEach(entity => {
|
||||||
|
if (
|
||||||
|
entity instanceof BillboardObject ||
|
||||||
|
entity instanceof PolygonObject ||
|
||||||
|
entity instanceof Circle ||
|
||||||
|
entity instanceof PolylineObject
|
||||||
|
) {
|
||||||
|
entities.add(entity.entity)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (entities.values.length) {
|
||||||
|
let promise = Cesium.exportKml({entities})
|
||||||
|
promise.then(e => {
|
||||||
|
// Cesium.exportKml(e.kml,)
|
||||||
|
funDownload(e.kml, new Date().getTime() + ".kml")
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
console.error("允许导出为kml的对象为空")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function funDownload(content, filename) {
|
||||||
|
let eleLink = document.createElement("a");
|
||||||
|
eleLink.download = filename;
|
||||||
|
eleLink.style.display = "none";
|
||||||
|
// 字符内容转变成blob地址
|
||||||
|
let blob = new Blob([content]);
|
||||||
|
eleLink.href = URL.createObjectURL(blob);
|
||||||
|
// 触发点击
|
||||||
|
document.body.appendChild(eleLink);
|
||||||
|
eleLink.click();
|
||||||
|
// 然后移除
|
||||||
|
document.body.removeChild(eleLink);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export default exportKml
|
||||||
|
|
||||||
67
src/Global/FlyRoam/_element.js
Normal file
67
src/Global/FlyRoam/_element.js
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
function html() {
|
||||||
|
return `
|
||||||
|
<span class="custom-divider"></span>
|
||||||
|
<div class="div-item">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<span class="label">名称</span>
|
||||||
|
<input class="input" type="text" name="name">
|
||||||
|
</div>
|
||||||
|
<div class="col"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<span class="custom-divider"></span>
|
||||||
|
<div class="div-item">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<input type="checkbox" name="isTotalTime" style="width: 16px; line-height: 15px; height: 15px; cursor: pointer; width: auto; margin-right: 5px;">
|
||||||
|
<span class="label">设置总时长</span>
|
||||||
|
<div class="input-number input-number-unit-3">
|
||||||
|
<input class="input total-time" type="number" title="" min="0" max="999999.99" step="0.01" name="totalTime" value="0">
|
||||||
|
<span class="unit" style="top: 6px;">秒(s)</span>
|
||||||
|
<span class="arrow"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<input type="checkbox" name="repeat" style="width: 16px; line-height: 15px; height: 15px; cursor: pointer; width: auto; margin-right: 5px;">
|
||||||
|
<span class="label">是否循环播放</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<span class="custom-divider"></span>
|
||||||
|
<div class="div-item">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<button class="add-point"><svg class="icon-add"><use xlink:href="#yj-icon-add"></use></svg>增加视点</button>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<button class="modify-point"><svg class="icon-edit"><use xlink:href="#yj-icon-edit"></use></svg>调整视点</button>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<button class="afreshPlay"><svg class="icon-play"><use xlink:href="#yj-icon-play"></use></svg>播放</button>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<button class="cease"><svg class="icon-pause"><use xlink:href="#yj-icon-pause"></use></svg>结束</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="table">
|
||||||
|
<div class="table-head">
|
||||||
|
<div class="tr">
|
||||||
|
<div class="th">序号</div>
|
||||||
|
<div class="th">时长(s)</div>
|
||||||
|
<div class="th">操作</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="table-body">
|
||||||
|
<div class="table-empty">
|
||||||
|
<div class="empty-img"></div>
|
||||||
|
<p>暂无数据</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<span class="custom-divider"></span>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
|
export { html }
|
||||||
389
src/Global/FlyRoam/index.js
Normal file
389
src/Global/FlyRoam/index.js
Normal file
@ -0,0 +1,389 @@
|
|||||||
|
|
||||||
|
/**
|
||||||
|
* @description 飞行漫游
|
||||||
|
*/
|
||||||
|
import Dialog from '../../BaseDialog';
|
||||||
|
import { html } from "./_element";
|
||||||
|
import Tools from "../../Tools";
|
||||||
|
import { closeRotateAround, closeViewFollow} from '../../Global/global'
|
||||||
|
let _DialogObject = null
|
||||||
|
let clickHandler
|
||||||
|
let repeat = 0
|
||||||
|
let currentRepeat = 0
|
||||||
|
|
||||||
|
|
||||||
|
const open = async (sdk, options = {}, _Dialog = {}) => {
|
||||||
|
let name = options.name || '漫游路径'
|
||||||
|
options.points || (options.points = [])
|
||||||
|
if(options.repeat) {
|
||||||
|
repeat = Number(options.repeat)
|
||||||
|
}
|
||||||
|
let viewer = sdk.viewer
|
||||||
|
let tools = new Tools(sdk)
|
||||||
|
let active = 0
|
||||||
|
|
||||||
|
if (_DialogObject && _DialogObject.close) {
|
||||||
|
_DialogObject.close()
|
||||||
|
_DialogObject = null
|
||||||
|
}
|
||||||
|
|
||||||
|
_DialogObject = await new Dialog(viewer._container, {
|
||||||
|
title: '飞行漫游', left: '180px', top: '100px',
|
||||||
|
closeCallBack: () => {
|
||||||
|
cease({ viewer })
|
||||||
|
},
|
||||||
|
})
|
||||||
|
await _DialogObject.init()
|
||||||
|
let contentElm = document.createElement('div');
|
||||||
|
contentElm.className = 'fly-roam'
|
||||||
|
contentElm.innerHTML = html()
|
||||||
|
_DialogObject.contentAppChild(contentElm)
|
||||||
|
|
||||||
|
let all_elm = contentElm.getElementsByTagName("*")
|
||||||
|
// EventBinding(all_elm)
|
||||||
|
|
||||||
|
let tableBody = contentElm.getElementsByClassName('table-body')[0];
|
||||||
|
let tableEmpty = contentElm.getElementsByClassName('table-empty')[0]
|
||||||
|
|
||||||
|
let handler = {
|
||||||
|
set: function (target, prop, value) {
|
||||||
|
target[prop] = value;
|
||||||
|
if (target.length > 0) {
|
||||||
|
tableEmpty.style.display = 'none'
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
tableEmpty.style.display = 'flex'
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
let i = 0
|
||||||
|
let points = new Proxy([], handler);
|
||||||
|
for (i = 0; i < options.points.length; i++) {
|
||||||
|
points.push(options.points[i])
|
||||||
|
addTrElm(options.points[i])
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// let nameImputBoxElm = contentElm.getElementsByClassName('input-box')[0]
|
||||||
|
// check(nameImputBoxElm, { validator: 'notEmpty', message: '名称不能为空!', trigger: 'input' })
|
||||||
|
let nameElm = contentElm.querySelector("input[name='name']")
|
||||||
|
nameElm.value = name
|
||||||
|
nameElm.addEventListener('input', () => {
|
||||||
|
name = nameElm.value
|
||||||
|
})
|
||||||
|
|
||||||
|
let addListBtn = document.createElement('button');
|
||||||
|
addListBtn.innerHTML = '保存'
|
||||||
|
addListBtn.addEventListener('click', () => {
|
||||||
|
if (!name) {
|
||||||
|
name = '漫游路径'
|
||||||
|
nameElm.value = name
|
||||||
|
}
|
||||||
|
let newPoints = []
|
||||||
|
points.map((item) => {
|
||||||
|
newPoints.push(item)
|
||||||
|
})
|
||||||
|
_Dialog.clickSavePath && _Dialog.clickSavePath(
|
||||||
|
{
|
||||||
|
name: name,
|
||||||
|
points: newPoints,
|
||||||
|
repeat: repeat+''
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})
|
||||||
|
_DialogObject.footAppChild(addListBtn)
|
||||||
|
|
||||||
|
let endBtn = contentElm.getElementsByClassName('cease')[0]
|
||||||
|
endBtn.addEventListener('click', () => {
|
||||||
|
viewer.camera.cancelFlight()
|
||||||
|
})
|
||||||
|
|
||||||
|
let flyBtn = contentElm.getElementsByClassName('afreshPlay')[0]
|
||||||
|
flyBtn.addEventListener('click', () => {
|
||||||
|
if (points.length > 0) {
|
||||||
|
flyTo(sdk, points, 0)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
let addBtn = contentElm.getElementsByClassName('add-point')[0]
|
||||||
|
addBtn.addEventListener('click', () => {
|
||||||
|
let position = tools.cartesian3Towgs84(viewer.camera.position, viewer)
|
||||||
|
let time = 0
|
||||||
|
let data = {
|
||||||
|
duration: time,
|
||||||
|
position: position,
|
||||||
|
orientation: {
|
||||||
|
heading: viewer.camera.heading,
|
||||||
|
pitch: viewer.camera.pitch,
|
||||||
|
roll: viewer.camera.roll
|
||||||
|
}
|
||||||
|
}
|
||||||
|
points.splice(active, 0, data)
|
||||||
|
addTrElm(data)
|
||||||
|
i++
|
||||||
|
})
|
||||||
|
let modifyBtn = contentElm.getElementsByClassName('modify-point')[0]
|
||||||
|
modifyBtn.addEventListener('click', () => {
|
||||||
|
if (!active) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let position = tools.cartesian3Towgs84(viewer.camera.position, viewer)
|
||||||
|
points[active - 1].position = position
|
||||||
|
points[active - 1].orientation = {
|
||||||
|
heading: viewer.camera.heading,
|
||||||
|
pitch: viewer.camera.pitch,
|
||||||
|
roll: viewer.camera.roll
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
let totalTimeElm = contentElm.querySelector("input[name='totalTime']")
|
||||||
|
let isTotalTimeElm = contentElm.querySelector("input[name='isTotalTime']")
|
||||||
|
let repeatElm = contentElm.querySelector("input[name='repeat']")
|
||||||
|
isTotalTimeElm.addEventListener('change', () => {
|
||||||
|
let trList = tableBody.getElementsByClassName('tr')
|
||||||
|
if (isTotalTimeElm.checked && trList.length > 0) {
|
||||||
|
let time = Number((Number(totalTimeElm.value) / (trList.length - 1)).toFixed(2))
|
||||||
|
for (let i = 0; i < trList.length - 1; i++) {
|
||||||
|
points[i].duration = time
|
||||||
|
trList[i].querySelector("input[name='time']").value = time
|
||||||
|
}
|
||||||
|
trList[trList.length - 1].querySelector("input[name='time']").value = 0
|
||||||
|
}
|
||||||
|
})
|
||||||
|
totalTimeElm.addEventListener('blur', () => {
|
||||||
|
let trList = tableBody.getElementsByClassName('tr')
|
||||||
|
totalTimeElm.value = Number(totalTimeElm.value)
|
||||||
|
if (totalTimeElm.value < 0) {
|
||||||
|
totalTimeElm.value = 0
|
||||||
|
}
|
||||||
|
if (isTotalTimeElm.checked && trList.length > 0) {
|
||||||
|
let time = Number((Number(totalTimeElm.value) / (trList.length - 1)).toFixed(2))
|
||||||
|
for (let i = 0; i < trList.length - 1; i++) {
|
||||||
|
points[i].duration = time
|
||||||
|
trList[i].querySelector("input[name='time']").value = time
|
||||||
|
}
|
||||||
|
trList[trList.length - 1].querySelector("input[name='time']").value = 0
|
||||||
|
}
|
||||||
|
})
|
||||||
|
repeatElm.checked = (repeat === Infinity ? true : false)
|
||||||
|
repeatElm.addEventListener('change', () => {
|
||||||
|
if (repeatElm.checked) {
|
||||||
|
repeat = Infinity
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
repeat = 0
|
||||||
|
}
|
||||||
|
currentRepeat = repeat
|
||||||
|
_Dialog.changeRepeatStateCallBack && _Dialog.changeRepeatStateCallBack(repeatElm.checked)
|
||||||
|
})
|
||||||
|
|
||||||
|
// Object.defineProperty(options, 'points', {
|
||||||
|
// get() {
|
||||||
|
// return e_allArea.value
|
||||||
|
// },
|
||||||
|
// set(value) {
|
||||||
|
// e_allArea.value = value
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
|
||||||
|
function addTrElm(data) {
|
||||||
|
let trList = tableBody.getElementsByClassName('tr')
|
||||||
|
if (trList.length > 0) {
|
||||||
|
trList[trList.length - 1].querySelector("input[name='time']").disabled = undefined
|
||||||
|
}
|
||||||
|
let tr_active = tableBody.getElementsByClassName('tr active')[0]
|
||||||
|
tr_active && (tr_active.className = 'tr')
|
||||||
|
let tr = document.createElement('div');
|
||||||
|
tr.className = 'tr active'
|
||||||
|
tr.innerHTML = `
|
||||||
|
<div class="td" style="justify-content: center;">视点${i + 1}</div>
|
||||||
|
<div class="td">
|
||||||
|
<input class="input time" type="number" title="" min="0" max="999.99" step="0.01" name="time" value="${data.duration}">
|
||||||
|
</div>
|
||||||
|
<div class="td action">
|
||||||
|
<button class="play">播放</span>
|
||||||
|
<button class="delete">删除</span>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
tr.addEventListener('click', (v) => {
|
||||||
|
if (v.target.parentNode === tr) {
|
||||||
|
let tr_active = tableBody.getElementsByClassName('tr active')[0]
|
||||||
|
tr_active && (tr_active.className = 'tr')
|
||||||
|
tr.className = 'tr active'
|
||||||
|
for (let m = 0; m < trList.length; m++) {
|
||||||
|
if (trList[m] === tr) {
|
||||||
|
active = m + 1
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
tr.addEventListener('dblclick', (v) => {
|
||||||
|
if (v.target.parentNode === tr) {
|
||||||
|
for (let m = 0; m < trList.length; m++) {
|
||||||
|
if (trList[m] === tr) {
|
||||||
|
viewer.camera.flyTo({
|
||||||
|
destination: Cesium.Cartesian3.fromDegrees(points[m].position.lng, points[m].position.lat, points[m].position.alt),
|
||||||
|
orientation: points[m].orientation,
|
||||||
|
duration: 1
|
||||||
|
})
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
let e_play = tr.getElementsByClassName('play')[0]
|
||||||
|
let e_delete = tr.getElementsByClassName('delete')[0]
|
||||||
|
let e_time = tr.querySelector("input[name='time']")
|
||||||
|
e_play.addEventListener('click', () => {
|
||||||
|
for (let m = 0; m < trList.length; m++) {
|
||||||
|
if (trList[m] === e_delete.parentNode.parentNode) {
|
||||||
|
flyTo(sdk, points, m)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
e_delete.addEventListener("click", (v) => {
|
||||||
|
for (let m = 0; m < trList.length; m++) {
|
||||||
|
if (trList[m] === e_delete.parentNode.parentNode) {
|
||||||
|
points.splice(m, 1)
|
||||||
|
points[points.length-1] && (points[points.length-1].duration = 0)
|
||||||
|
tableBody.removeChild(tr)
|
||||||
|
if (active > m + 1) {
|
||||||
|
active--
|
||||||
|
trList[active - 1].className = 'tr active'
|
||||||
|
}
|
||||||
|
else if (active == m + 1) {
|
||||||
|
if (trList.length == m) {
|
||||||
|
active -= 1
|
||||||
|
}
|
||||||
|
if (trList.length != 0) {
|
||||||
|
trList[active - 1].className = 'tr active'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// else if(active == m) {
|
||||||
|
// console.log(trList.length-1, active)
|
||||||
|
// if (trList.length == active-1) {
|
||||||
|
// trList[active-2].className = 'tr active'
|
||||||
|
// }
|
||||||
|
// else {
|
||||||
|
// trList[active-1].className = 'tr active'
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
if (trList.length > 0) {
|
||||||
|
let lastElm = trList[trList.length - 1].querySelector("input[name='time']")
|
||||||
|
lastElm.disabled = 'disabled'
|
||||||
|
lastElm.value = 0
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// points.splice(i, 1)
|
||||||
|
// tableBody.removeChild(tr)
|
||||||
|
// if (trList.length > 0) {
|
||||||
|
// trList[trList.length - 1].querySelector("input[name='time']").disabled = 'disabled'
|
||||||
|
// }
|
||||||
|
})
|
||||||
|
e_time.addEventListener('input', (v) => {
|
||||||
|
isTotalTimeElm.checked = false
|
||||||
|
data.duration = Number(e_time.value)
|
||||||
|
if (data.duration < 0) {
|
||||||
|
data.duration = 0
|
||||||
|
}
|
||||||
|
})
|
||||||
|
e_time.addEventListener('blur', () => {
|
||||||
|
e_time.value = Number(Number(e_time.value).toFixed(2))
|
||||||
|
if (e_time.value < 0) {
|
||||||
|
e_time.value = 0
|
||||||
|
}
|
||||||
|
});
|
||||||
|
tableBody.insertBefore(tr, trList[active])
|
||||||
|
active++
|
||||||
|
trList[trList.length - 1].querySelector("input[name='time']").disabled = 'disabled'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const close = () => {
|
||||||
|
if (_DialogObject && _DialogObject.close) {
|
||||||
|
_DialogObject.close()
|
||||||
|
_DialogObject = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const executeFlyTo = (sdk, points = [], index = 0, noStart) => {
|
||||||
|
if (clickHandler) {
|
||||||
|
clickHandler.destroy()
|
||||||
|
}
|
||||||
|
clickHandler = new Cesium.ScreenSpaceEventHandler(sdk.viewer.canvas)
|
||||||
|
clickHandler.setInputAction((movement) => {
|
||||||
|
cease(sdk)
|
||||||
|
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK)
|
||||||
|
let viewer = sdk.viewer
|
||||||
|
viewer.camera.cancelFlight()
|
||||||
|
// function pauseExecution(seconds) {
|
||||||
|
// return new Promise(resolve => setTimeout(resolve, seconds * 1000));
|
||||||
|
// }
|
||||||
|
closeRotateAround(sdk)
|
||||||
|
closeViewFollow(sdk)
|
||||||
|
viewer.camera.flyTo({
|
||||||
|
destination: Cesium.Cartesian3.fromDegrees(points[index].position.lng, points[index].position.lat, points[index].position.alt),
|
||||||
|
orientation: points[index].orientation,
|
||||||
|
duration: noStart ? points[index - 1].duration : 0.5,
|
||||||
|
maximumHeight: points[index].position.alt,
|
||||||
|
complete: async () => {
|
||||||
|
if (!noStart) {
|
||||||
|
// await pauseExecution(2)
|
||||||
|
}
|
||||||
|
index++
|
||||||
|
if (index <= points.length - 1) {
|
||||||
|
executeFlyTo(sdk, points, index, true)
|
||||||
|
}
|
||||||
|
else if (currentRepeat && points.length > 1) {
|
||||||
|
currentRepeat--
|
||||||
|
executeFlyTo(sdk, points, 0)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (clickHandler) {
|
||||||
|
clickHandler.destroy()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
easingFunction: noStart ? Cesium.EasingFunction.LINEAR_NONE : Cesium.EasingFunction.EXPONENTIAL_OUT
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const flyTo = (sdk, points = [], index = 0, noStart) => {
|
||||||
|
currentRepeat = repeat
|
||||||
|
executeFlyTo(sdk, points, index, noStart)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**设置循环次数 (Infinity: 无限循环)*/
|
||||||
|
const setRepeat = (v) => {
|
||||||
|
if (repeat != Number(v)) {
|
||||||
|
repeat = Number(v)
|
||||||
|
currentRepeat = repeat
|
||||||
|
if (_DialogObject && _DialogObject._element && _DialogObject._element.content) {
|
||||||
|
let repeatElm = _DialogObject._element.content.querySelector("input[name='repeat']")
|
||||||
|
if (v === Infinity) {
|
||||||
|
repeatElm.checked = true
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
repeatElm.checked = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** 停止 */
|
||||||
|
const cease = (sdk) => {
|
||||||
|
sdk && sdk.viewer && sdk.viewer.camera.cancelFlight()
|
||||||
|
if (clickHandler) {
|
||||||
|
clickHandler.destroy()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export { open, close, flyTo, setRepeat, cease }
|
||||||
235
src/Global/KeyBoard/index.js
Normal file
235
src/Global/KeyBoard/index.js
Normal file
@ -0,0 +1,235 @@
|
|||||||
|
/*
|
||||||
|
* @Description: 使用键盘控制地图漫游
|
||||||
|
* @Version: 1.0
|
||||||
|
* @Author: Julian
|
||||||
|
* @Date: 2022-04-07 16:04:07
|
||||||
|
* @LastEditors: Julian
|
||||||
|
* @LastEditTime: 2022-04-07 18:40:40
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: 使用键盘控制地图漫游初始化
|
||||||
|
* @param {*} _viewer
|
||||||
|
* @return {*}
|
||||||
|
*/
|
||||||
|
function keyboardMapRoamingInit(_viewer) {
|
||||||
|
// 添加键盘监听事件
|
||||||
|
document.addEventListener('keydown', keyDown.bind(_viewer), false);
|
||||||
|
document.addEventListener('keyup', keyUp.bind(_viewer), false);
|
||||||
|
|
||||||
|
// 为每一帧添加监听事件
|
||||||
|
_viewer && _viewer.clock.onTick.addEventListener(function () {
|
||||||
|
keyboardMapRoamingRender(_viewer);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 定义事件组
|
||||||
|
let flags = {
|
||||||
|
// 相机位置
|
||||||
|
moveForward: false,
|
||||||
|
moveBackward: false,
|
||||||
|
moveLeft: false,
|
||||||
|
moveRight: false,
|
||||||
|
moveUp: false,
|
||||||
|
moveDown: false,
|
||||||
|
// 相机姿态
|
||||||
|
lookUp: false,
|
||||||
|
lookDown: false,
|
||||||
|
lookLeft: false,
|
||||||
|
lookRight: false,
|
||||||
|
twistLeft: false,
|
||||||
|
twistRight: false,
|
||||||
|
// 缩放
|
||||||
|
zoomIn: false,
|
||||||
|
zoomOut: false
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 相机位置:W:向前;S:向后;D:向右;A:向左;Q:升高;E:降低;
|
||||||
|
// 相机姿态:↑:抬头;↓:低头;←:左转;→:右转;0:顺时针;.:逆时针
|
||||||
|
// 缩放:+:放大,-:缩小;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: 根据键盘输入字符返回事件信息
|
||||||
|
* @param {*} key
|
||||||
|
* @return {*}
|
||||||
|
*/
|
||||||
|
function getFlagFromKeyboard(key) {
|
||||||
|
switch (key) {
|
||||||
|
// 按字符的Unicode编码
|
||||||
|
// 相机位置
|
||||||
|
case 87:
|
||||||
|
return 'moveForward';
|
||||||
|
case 83:
|
||||||
|
return 'moveBackward';
|
||||||
|
case 68:
|
||||||
|
return 'moveRight';
|
||||||
|
case 65:
|
||||||
|
return 'moveLeft';
|
||||||
|
case 81:
|
||||||
|
return 'moveUp';
|
||||||
|
case 69:
|
||||||
|
return 'moveDown';
|
||||||
|
// 相机姿态
|
||||||
|
case 38:
|
||||||
|
return 'lookUp';
|
||||||
|
case 40:
|
||||||
|
return 'lookDown';
|
||||||
|
case 37:
|
||||||
|
return 'lookLeft';
|
||||||
|
case 39:
|
||||||
|
return 'lookRight';
|
||||||
|
case 96:
|
||||||
|
return 'twistLeft';
|
||||||
|
case 110:
|
||||||
|
return 'twistRight';
|
||||||
|
// 缩放
|
||||||
|
case 107:
|
||||||
|
return 'zoomIn';
|
||||||
|
case 109:
|
||||||
|
return 'zoomOut';
|
||||||
|
default:
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: 键盘按下
|
||||||
|
* @param {*} event
|
||||||
|
* @return {*}
|
||||||
|
*/
|
||||||
|
function keyDown(event) {
|
||||||
|
let _viewer = this
|
||||||
|
// 判断是否有输入框聚焦
|
||||||
|
function isInputFocused() {
|
||||||
|
const activeElement = document.activeElement;
|
||||||
|
return (activeElement.tagName.toLowerCase() === 'input' && activeElement.type !== 'checkbox') ||
|
||||||
|
activeElement.tagName.toLowerCase() === 'textarea' ||
|
||||||
|
activeElement.getAttribute('role') === 'textarea';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isInputFocused()) {
|
||||||
|
// console.log('页面上有输入框已经获取焦点');
|
||||||
|
} else if (_viewer.trackedEntity) {
|
||||||
|
// console.log('视角跟随中');
|
||||||
|
} else if (_viewer._firstPersonView) {
|
||||||
|
// console.log('第一人称视角中');
|
||||||
|
} else if (_viewer._disableKeyboardEvent) {
|
||||||
|
// console.log('禁用键盘事件');
|
||||||
|
} else if (event.ctrlKey && event.altKey) {
|
||||||
|
if (event.key === 'v' || event.key === 'V') {
|
||||||
|
let camera = _viewer.camera
|
||||||
|
_viewer._CAMERA_SHORTCUT_VIEW = {
|
||||||
|
orientation: { heading: camera.heading, pitch: camera.pitch, roll: camera.roll },
|
||||||
|
position: { x: camera.position.x, y: camera.position.y, z: camera.position.z }
|
||||||
|
}
|
||||||
|
localStorage.setItem('CAMERA_SHORTCUT_VIEW', JSON.stringify(_viewer._CAMERA_SHORTCUT_VIEW))
|
||||||
|
}
|
||||||
|
if (event.key === 'f' || event.key === 'F') {
|
||||||
|
let CAMERA_SHORTCUT_VIEW = localStorage.getItem('CAMERA_SHORTCUT_VIEW')
|
||||||
|
_viewer._CAMERA_SHORTCUT_VIEW = JSON.parse(CAMERA_SHORTCUT_VIEW)
|
||||||
|
if (_viewer._CAMERA_SHORTCUT_VIEW && _viewer._CAMERA_SHORTCUT_VIEW.position && _viewer._CAMERA_SHORTCUT_VIEW.orientation) {
|
||||||
|
_viewer.camera.flyTo({
|
||||||
|
destination: _viewer._CAMERA_SHORTCUT_VIEW.position,
|
||||||
|
orientation: _viewer._CAMERA_SHORTCUT_VIEW.orientation
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// console.log('页面上没有输入框获取焦点');
|
||||||
|
let flagName = getFlagFromKeyboard(event.keyCode);
|
||||||
|
if (typeof flagName !== 'undefined') {
|
||||||
|
flags[flagName] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: 键盘弹起
|
||||||
|
* @param {*} event
|
||||||
|
* @return {*}
|
||||||
|
*/
|
||||||
|
function keyUp(event) {
|
||||||
|
let flagName = getFlagFromKeyboard(event.keyCode);
|
||||||
|
if (typeof flagName !== 'undefined') {
|
||||||
|
flags[flagName] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description: 根据事件调整相机
|
||||||
|
* @param {*} _viewer
|
||||||
|
* @return {*}
|
||||||
|
*/
|
||||||
|
function keyboardMapRoamingRender(_viewer) {
|
||||||
|
if(!_viewer.scene.screenSpaceCameraController.enableTilt) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let camera = _viewer.camera;
|
||||||
|
let ellipsoid = _viewer.scene.globe.ellipsoid;
|
||||||
|
let cameraHeight = ellipsoid.cartesianToCartographic(camera.position).height;
|
||||||
|
|
||||||
|
// 根据相机高度设置移动距离,比默认距离移动效果更好
|
||||||
|
let moveRate = cameraHeight / 20.0;
|
||||||
|
let rotationRate = moveRate / 500000 / Cesium.Math.toDegrees(camera.pitch);
|
||||||
|
|
||||||
|
if (flags.moveForward) {
|
||||||
|
// camera.moveForward(moveRate);
|
||||||
|
camera.rotate(camera.right, -rotationRate);
|
||||||
|
}
|
||||||
|
if (flags.moveBackward) {
|
||||||
|
// camera.moveBackward(moveRate);
|
||||||
|
camera.rotate(camera.right, rotationRate);
|
||||||
|
}
|
||||||
|
if (flags.moveLeft) {
|
||||||
|
// camera.moveLeft(moveRate);
|
||||||
|
camera.rotate(camera.up, -rotationRate);
|
||||||
|
}
|
||||||
|
if (flags.moveRight) {
|
||||||
|
// camera.moveRight(moveRate);
|
||||||
|
camera.rotate(camera.up, rotationRate);
|
||||||
|
}
|
||||||
|
if (flags.moveUp) {
|
||||||
|
camera.moveUp(moveRate);
|
||||||
|
}
|
||||||
|
if (flags.moveDown) {
|
||||||
|
camera.moveDown(moveRate);
|
||||||
|
}
|
||||||
|
if (flags.lookUp) {
|
||||||
|
camera.lookUp();
|
||||||
|
}
|
||||||
|
if (flags.lookDown) {
|
||||||
|
camera.lookDown();
|
||||||
|
}
|
||||||
|
if (flags.lookLeft) {
|
||||||
|
camera.lookLeft();
|
||||||
|
}
|
||||||
|
if (flags.lookRight) {
|
||||||
|
camera.lookRight();
|
||||||
|
}
|
||||||
|
if (flags.twistLeft) {
|
||||||
|
camera.twistLeft();
|
||||||
|
}
|
||||||
|
if (flags.twistRight) {
|
||||||
|
camera.twistRight();
|
||||||
|
}
|
||||||
|
// 根据相机高度设置缩放参数
|
||||||
|
if (flags.zoomIn) {
|
||||||
|
let height = cameraHeight / 2
|
||||||
|
if (height < 1) {
|
||||||
|
height = 0
|
||||||
|
}
|
||||||
|
camera.zoomIn(height);
|
||||||
|
}
|
||||||
|
if (flags.zoomOut) {
|
||||||
|
let height = cameraHeight / 2
|
||||||
|
if ((cameraHeight + cameraHeight) >= 50000000) {
|
||||||
|
height = 50000000 - cameraHeight
|
||||||
|
}
|
||||||
|
camera.zoomOut(height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export { keyboardMapRoamingInit }
|
||||||
117
src/Global/MapPrint/dataSource.js
Normal file
117
src/Global/MapPrint/dataSource.js
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
function getTemplateData(tools) {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
"name": "模板一",
|
||||||
|
"value": "模板一",
|
||||||
|
"id": "1",
|
||||||
|
margin: 0.03,
|
||||||
|
title: {
|
||||||
|
text: '标题一',
|
||||||
|
height: 0.05,
|
||||||
|
bgColor: '#5d5d5d',
|
||||||
|
color: '#ffffff',
|
||||||
|
show: true,
|
||||||
|
},
|
||||||
|
border: {
|
||||||
|
show: false,
|
||||||
|
url: '/custom/img/map-border1.svg',
|
||||||
|
width: 0.01,
|
||||||
|
color: ''
|
||||||
|
},
|
||||||
|
plottingScale: {
|
||||||
|
cell: 2,
|
||||||
|
color: '#ffffff',
|
||||||
|
show: true,
|
||||||
|
isSelected: false,
|
||||||
|
x: 0.87,
|
||||||
|
y: 0.97,
|
||||||
|
},
|
||||||
|
data: [
|
||||||
|
{
|
||||||
|
text: '',
|
||||||
|
x: 0.02,
|
||||||
|
y: 0.93,
|
||||||
|
isSelected: false,
|
||||||
|
show: true,
|
||||||
|
color: '#ffffff',
|
||||||
|
height: 0.03
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '',
|
||||||
|
x: 0.02,
|
||||||
|
y: 0.97,
|
||||||
|
isSelected: false,
|
||||||
|
show: true,
|
||||||
|
color: '#ffffff',
|
||||||
|
height: 0.03
|
||||||
|
},
|
||||||
|
{
|
||||||
|
x: 0.02,
|
||||||
|
y: 0.1,
|
||||||
|
show: false,
|
||||||
|
isSelected: false,
|
||||||
|
url: '/custom/img/icon-compass1.svg',
|
||||||
|
width: 0.1,
|
||||||
|
height: 0.1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "模板二",
|
||||||
|
"value": "模板二",
|
||||||
|
"id": "2",
|
||||||
|
margin: 0.03,
|
||||||
|
border: {
|
||||||
|
show: true,
|
||||||
|
url: '/custom/img/map-border2.svg',
|
||||||
|
width: 0.01,
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
text: '标题二',
|
||||||
|
height: 0.05,
|
||||||
|
bgColor: '#5d5d5d',
|
||||||
|
color: '#ffffff',
|
||||||
|
show: true,
|
||||||
|
},
|
||||||
|
plottingScale: {
|
||||||
|
cell: 2,
|
||||||
|
color: '#ffffff',
|
||||||
|
show: true,
|
||||||
|
isSelected: false,
|
||||||
|
x: 0.02,
|
||||||
|
y: 0.97,
|
||||||
|
},
|
||||||
|
data: [
|
||||||
|
{
|
||||||
|
text: '',
|
||||||
|
x: 0.88,
|
||||||
|
y: 0.93,
|
||||||
|
isSelected: false,
|
||||||
|
show: true,
|
||||||
|
color: '#ffffff',
|
||||||
|
height: 0.03
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: '',
|
||||||
|
x: 0.87,
|
||||||
|
y: 0.97,
|
||||||
|
isSelected: false,
|
||||||
|
show: true,
|
||||||
|
color: '#ffffff',
|
||||||
|
height: 0.03
|
||||||
|
},
|
||||||
|
{
|
||||||
|
x: 0.91,
|
||||||
|
y: 0.1,
|
||||||
|
show: true,
|
||||||
|
isSelected: false,
|
||||||
|
url: '/custom/img/icon-compass4.svg',
|
||||||
|
width: 0.1,
|
||||||
|
height: 0.1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
export { getTemplateData };
|
||||||
1449
src/Global/MapPrint/index.js
Normal file
1449
src/Global/MapPrint/index.js
Normal file
File diff suppressed because it is too large
Load Diff
170
src/Global/MapX/index.js
Normal file
170
src/Global/MapX/index.js
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
import Tools from '../../Tools'
|
||||||
|
import Event from '../../Event'
|
||||||
|
|
||||||
|
let tools
|
||||||
|
let Xevent
|
||||||
|
let mapx = {}
|
||||||
|
let curRectangle = undefined;
|
||||||
|
let centerResult = undefined
|
||||||
|
let mouseStart = false
|
||||||
|
let syncObject = {}
|
||||||
|
const init = (sdk) => {
|
||||||
|
tools = new Tools()
|
||||||
|
let div = document.createElement('div');
|
||||||
|
div.id = 'mapxDiv'
|
||||||
|
div.style.width = '222px';
|
||||||
|
div.style.height = '112px';
|
||||||
|
div.style.position = 'absolute';
|
||||||
|
div.style.right = '10px';
|
||||||
|
div.style.bottom = '82px';
|
||||||
|
div.style.zIndex = '1';
|
||||||
|
document.getElementById(sdk.div_id).appendChild(div)
|
||||||
|
let options = {
|
||||||
|
imageryProvider: new Cesium.TileMapServiceImageryProvider({
|
||||||
|
url: Cesium.buildModuleUrl("Assets/Textures/NaturalEarthII"),
|
||||||
|
}),
|
||||||
|
sceneMode: Cesium.SceneMode.SCENE2D,
|
||||||
|
// mapMode2D: Cesium.MapMode2D.ROTATE,
|
||||||
|
baseLayerPicker: false,
|
||||||
|
geocoder: false,
|
||||||
|
animation: false,
|
||||||
|
fullscreenButton: false,
|
||||||
|
navigationHelpButton: false,
|
||||||
|
// vrButton?: boolean;
|
||||||
|
homeButton: false,
|
||||||
|
infoBox: false,
|
||||||
|
sceneModePicker: false,
|
||||||
|
selectionIndicator: false,
|
||||||
|
timeline: false,
|
||||||
|
shouldAnimate: true
|
||||||
|
}
|
||||||
|
mapx.viewer = new Cesium.Viewer('mapxDiv', options);
|
||||||
|
mapx.viewer.camera.setView({
|
||||||
|
destination: Cesium.Cartesian3.fromDegrees(0, 0, 40000000),
|
||||||
|
})
|
||||||
|
mapx.viewer.trackedEntity = undefined;
|
||||||
|
mapx.viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(
|
||||||
|
Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK
|
||||||
|
);
|
||||||
|
mapx.viewer.scene.screenSpaceCameraController.enableRotate = false;
|
||||||
|
mapx.viewer.scene.screenSpaceCameraController.enableTranslate = false;
|
||||||
|
mapx.viewer.scene.screenSpaceCameraController.enableZoom = false;
|
||||||
|
mapx.viewer.scene.screenSpaceCameraController.enableTilt = false;
|
||||||
|
mapx.viewer.scene.screenSpaceCameraController.enableLook = false;
|
||||||
|
|
||||||
|
// 创建范围框
|
||||||
|
let entity = mapx.viewer.entities.add({
|
||||||
|
name: 'mapX rectangle',
|
||||||
|
position: new Cesium.CallbackProperty(function () {
|
||||||
|
return (
|
||||||
|
centerResult || Cesium.Cartesian3.fromDegrees(0, 0, 0)
|
||||||
|
);
|
||||||
|
}, false),
|
||||||
|
rectangle: {
|
||||||
|
coordinates: new Cesium.CallbackProperty(function () {
|
||||||
|
return (
|
||||||
|
curRectangle || Cesium.Rectangle.fromDegrees(0.0, 0.0, 0.01, 0.01)
|
||||||
|
);
|
||||||
|
}, false),
|
||||||
|
material: Cesium.Color.RED.withAlpha(0.01),
|
||||||
|
outline: true,
|
||||||
|
outlineColor: Cesium.Color.RED,
|
||||||
|
outlineWidth: 2,
|
||||||
|
height: 1,
|
||||||
|
},
|
||||||
|
billboard: {
|
||||||
|
image: tools.getSourceRootPath() + '/img/cross.svg',
|
||||||
|
scale: 1,
|
||||||
|
width: 16,
|
||||||
|
height: 16
|
||||||
|
},
|
||||||
|
});
|
||||||
|
syncObject = { sdk, entity }
|
||||||
|
mapx.viewer.camera.percentageChanged = 0.001;
|
||||||
|
sdk.viewer.scene.preRender.addEventListener(syncViewer, syncObject); // 鹰眼与主图同步
|
||||||
|
let pick
|
||||||
|
Xevent = new Event({ viewer: mapx.viewer })
|
||||||
|
Xevent.mouse_left_down((movement, cartesian) => {
|
||||||
|
mouseStart = true
|
||||||
|
pick = mapx.viewer.scene.pick(movement.position)
|
||||||
|
})
|
||||||
|
Xevent.mouse_left_up((movement, cartesian) => {
|
||||||
|
mouseStart = false
|
||||||
|
})
|
||||||
|
Xevent.mouse_move((movement, cartesian) => {
|
||||||
|
if (pick && mouseStart) {
|
||||||
|
let sdkCH = tools.cartesian3Towgs84(sdk.viewer.camera.position, sdk.viewer).alt
|
||||||
|
let pos84 = tools.cartesian3Towgs84(cartesian, mapx.viewer)
|
||||||
|
// sdk.viewer.camera.position = Cesium.Cartesian3.fromDegrees(pos84.lng, pos84.lat, sdkCH)
|
||||||
|
sdk.viewer.camera.flyTo({
|
||||||
|
destination: Cesium.Cartesian3.fromDegrees(pos84.lng, pos84.lat, sdkCH),
|
||||||
|
duration: 0
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
function syncViewer() {
|
||||||
|
if(!this.sdk || !this.sdk.viewer) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 视角中心点(伪)
|
||||||
|
centerResult = this.sdk.viewer.camera.pickEllipsoid(
|
||||||
|
new Cesium.Cartesian2(
|
||||||
|
this.sdk.viewer.canvas.clientWidth / 2,
|
||||||
|
this.sdk.viewer.canvas.clientHeight / (2 - ((90 + this.sdk.viewer.camera.pitch / (Cesium.Math.PI / 180)) / 110)),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
if (!centerResult) {
|
||||||
|
centerResult = this.sdk.viewer.camera.position
|
||||||
|
}
|
||||||
|
let height = tools.cartesian3Towgs84(this.sdk.viewer.camera.position, this.sdk.viewer).alt
|
||||||
|
let centerResult84 = tools.cartesian3Towgs84(centerResult, this.sdk.viewer)
|
||||||
|
let stepX = 120000
|
||||||
|
let stepY = 280000
|
||||||
|
if (height > 9000000) {
|
||||||
|
height = 9000000
|
||||||
|
}
|
||||||
|
if (height < 100000) {
|
||||||
|
this.entity.billboard.show = true
|
||||||
|
this.entity.rectangle.show = false
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.entity.billboard.show = false
|
||||||
|
this.entity.rectangle.show = true
|
||||||
|
}
|
||||||
|
curRectangle = new Cesium.Rectangle(Cesium.Math.toRadians(centerResult84.lng - (height / stepX)), Cesium.Math.toRadians(centerResult84.lat - (height / stepY)), Cesium.Math.toRadians(centerResult84.lng + (height / stepX)), Cesium.Math.toRadians(centerResult84.lat + (height / stepY)))
|
||||||
|
};
|
||||||
|
function open(sdk) {
|
||||||
|
if (!mapx.viewer) {
|
||||||
|
init(sdk)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mapx.viewer.container.style.display = 'block';
|
||||||
|
let entity
|
||||||
|
let entities = mapx.viewer.entities.values
|
||||||
|
for (let i = 0; i < entities.length; i++) {
|
||||||
|
if (entities[i].name === 'mapX rectangle') {
|
||||||
|
entity = entities[i]
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sdk.viewer.scene.preRender.addEventListener(syncViewer, syncObject); // 鹰眼与主图同步
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function close(sdk) {
|
||||||
|
if (!mapx.viewer) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
mapx.viewer.container.style.display = 'none';
|
||||||
|
let entity
|
||||||
|
let entities = mapx.viewer.entities.values
|
||||||
|
for (let i = 0; i < entities.length; i++) {
|
||||||
|
if (entities[i].name === 'mapX rectangle') {
|
||||||
|
entity = entities[i]
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sdk.viewer.scene.preRender.removeEventListener(syncViewer, syncObject)
|
||||||
|
}
|
||||||
|
|
||||||
|
export { open, close }
|
||||||
112
src/Global/MouseCoordinate/index.js
Normal file
112
src/Global/MouseCoordinate/index.js
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
/**
|
||||||
|
* 鼠标坐标
|
||||||
|
*/
|
||||||
|
import Tools from "../../Tools";
|
||||||
|
import { getCoordinateSystem } from "../../Global/global";
|
||||||
|
import MouseEvent from '../../Event/index'
|
||||||
|
|
||||||
|
let event
|
||||||
|
let MouseCoordinateElm
|
||||||
|
let requestAnimationFrameEventId
|
||||||
|
|
||||||
|
const MouseCoordinate = (sdk, status) => {
|
||||||
|
let tools = new Tools(sdk)
|
||||||
|
if (status) {
|
||||||
|
if (event) {
|
||||||
|
event.destroy()
|
||||||
|
}
|
||||||
|
event = new MouseEvent(sdk)
|
||||||
|
let position = {
|
||||||
|
x: '',
|
||||||
|
y: '',
|
||||||
|
z: ''
|
||||||
|
}
|
||||||
|
let contentElm
|
||||||
|
if (MouseCoordinateElm) {
|
||||||
|
contentElm = MouseCoordinateElm
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
contentElm = document.createElement('div');
|
||||||
|
contentElm.style.position = 'absolute';
|
||||||
|
contentElm.style['z-index'] = 777;
|
||||||
|
contentElm.style.color = '#ff0000';
|
||||||
|
contentElm.style.left = '0px';
|
||||||
|
contentElm.style.top = '0px';
|
||||||
|
contentElm.style.width = '100%';
|
||||||
|
contentElm.style.height = '100%';
|
||||||
|
contentElm.style['font-size'] = '12px';
|
||||||
|
contentElm.style['pointer-events'] = 'none';
|
||||||
|
contentElm.style.background = `url(${tools.getSourceRootPath()}/img/cross.png) no-repeat 100% 100%`;
|
||||||
|
contentElm.style['background-size'] = `200% 200%`;
|
||||||
|
MouseCoordinateElm = contentElm
|
||||||
|
}
|
||||||
|
sdk.viewer._element.appendChild(contentElm)
|
||||||
|
let tmovement
|
||||||
|
event.mouse_move((movement, cartesian) => {
|
||||||
|
tmovement = { ...movement }
|
||||||
|
})
|
||||||
|
|
||||||
|
const getPosition = () => {
|
||||||
|
if(!tmovement) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let canvas = sdk.viewer._element.getElementsByTagName('canvas')[0]
|
||||||
|
let left = tmovement.endPosition.x;
|
||||||
|
let top = tmovement.endPosition.y;
|
||||||
|
let cartesian = event.getcartesian(tmovement)
|
||||||
|
contentElm.style['background-position-x'] = `${-canvas.width + left + 4}px`;
|
||||||
|
contentElm.style['background-position-y'] = `${-canvas.height + top - 2}px`;
|
||||||
|
// this.entity.position = cartesian
|
||||||
|
if (cartesian) {
|
||||||
|
let degrees = tools.cartesian3Towgs84(cartesian, sdk.viewer)
|
||||||
|
let coordinateSystem = getCoordinateSystem()
|
||||||
|
if (coordinateSystem === 'EPSG:4326') {
|
||||||
|
position = {
|
||||||
|
x: degrees.lng,
|
||||||
|
y: degrees.lat,
|
||||||
|
z: degrees.alt
|
||||||
|
}
|
||||||
|
contentElm.innerHTML = `<div style='width: 150px;position: absolute; z-index: 777; color: #ff0000; font-size: 12px; left:${left + 20}px; top:${top + 10}px;'><p style='margin: 0;'>经度:${degrees.lng.toFixed(6)}°</p><p style='margin: 0;'>维度:${degrees.lat.toFixed(6)}°</p><p style='margin: 0;'>海拔:${degrees.alt.toFixed(2)} m</p></div>`
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
let result = tools.convert([{ x: degrees.lng, y: degrees.lat, z: degrees.alt }], 'EPSG:4326', coordinateSystem)
|
||||||
|
position = result.points[0]
|
||||||
|
contentElm.innerHTML = `<div style='width: 150px;position: absolute; z-index: 777; color: #ff0000; font-size: 12px; left:${left + 20}px; top:${top + 10}px;'><p style='margin: 0;'>x:${position.x.toFixed(6)}</p><p style='margin: 0;'>y:${position.y.toFixed(6)}</p><p style='margin: 0;'>z:${position.z.toFixed(6)}</p></div>`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
let coordinateSystem = getCoordinateSystem()
|
||||||
|
if (coordinateSystem === 'EPSG:4326') {
|
||||||
|
contentElm.innerHTML = `<div style='width: 150px;position: absolute; z-index: 777; color: #ff0000; font-size: 12px; left:${left + 20}px; top:${top + 10}px;'><p style='margin: 0;'>经度:-</p><p style='margin: 0;'>维度:-</p><p style='margin: 0;'>海拔:-</p></div>`
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
contentElm.innerHTML = `<div style='width: 150px;position: absolute; z-index: 777; color: #ff0000; font-size: 12px; left:${left + 20}px; top:${top + 10}px;'><p style='margin: 0;'>x:-</p><p style='margin: 0;'>y:-</p><p style='margin: 0;'>z:-</p></div>`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
animateUpdate()
|
||||||
|
function animateUpdate() {
|
||||||
|
requestAnimationFrameEventId = requestAnimationFrame(
|
||||||
|
animateUpdate
|
||||||
|
)
|
||||||
|
getPosition()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (event) {
|
||||||
|
event.destroy()
|
||||||
|
event = undefined
|
||||||
|
}
|
||||||
|
if (MouseCoordinateElm) {
|
||||||
|
sdk.viewer._element.removeChild(MouseCoordinateElm)
|
||||||
|
MouseCoordinateElm = undefined
|
||||||
|
}
|
||||||
|
if (requestAnimationFrameEventId) {
|
||||||
|
cancelAnimationFrame(requestAnimationFrameEventId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export { MouseCoordinate }
|
||||||
561
src/Global/MultiViewportMode/index.js
Normal file
561
src/Global/MultiViewportMode/index.js
Normal file
@ -0,0 +1,561 @@
|
|||||||
|
/**
|
||||||
|
* 多视口模式
|
||||||
|
* */
|
||||||
|
import Tools from "../../Tools";
|
||||||
|
import MouseEvent from '../../Event'
|
||||||
|
import { CesiumContainer } from '../global'
|
||||||
|
import { off as offSplitScreen } from "../SplitScreen";
|
||||||
|
import { FlwStatusSwitch, JwwStatusSwitch, getFlwStatus, getJwwStatus } from "../global"
|
||||||
|
import { SheetIndexStatusSwitch, getStatus } from '../SheetIndex'
|
||||||
|
|
||||||
|
let sdk2D
|
||||||
|
let sdk3D
|
||||||
|
let activeViewer
|
||||||
|
let controlViewer
|
||||||
|
let syncObject = {}
|
||||||
|
let handlers = []
|
||||||
|
async function init(sdk) {
|
||||||
|
sdk3D = sdk
|
||||||
|
activeViewer = 0
|
||||||
|
let tools = new Tools()
|
||||||
|
let sdk2 = await new YJ.YJEarth(sdk.div_id)
|
||||||
|
sdk2.viewer._element.className = 'cesium-viewer 2d'
|
||||||
|
SheetIndexStatusSwitch(sdk2, getStatus())
|
||||||
|
// setTimeout(() => {
|
||||||
|
// let switchCluster = new YJ.Global.switchCluster(sdk2, true)
|
||||||
|
// }, 500);
|
||||||
|
CesiumContainer(sdk2, {
|
||||||
|
compass: false, // 罗盘
|
||||||
|
// legend: false, // 比例尺
|
||||||
|
info: false, // 信息栏
|
||||||
|
frame: false // 刷新率
|
||||||
|
})
|
||||||
|
sdk2.viewer.scene.mode = Cesium.SceneMode.SCENE2D
|
||||||
|
sdk2D = await sdk2
|
||||||
|
// window.sdk2D = sdk2D
|
||||||
|
solveBug()
|
||||||
|
syncObject = { sdks: [sdk, sdk2], tools }
|
||||||
|
await eventBind(sdk, 0, syncObject)
|
||||||
|
await eventBind(sdk2, 1, syncObject)
|
||||||
|
await syncData(sdk)
|
||||||
|
sdk.viewer.scene.preRender.addEventListener(syncViewer, syncObject)
|
||||||
|
|
||||||
|
sdk.viewer.imageryLayers.layerAdded.addEventListener(syncImageryLayerAdded);
|
||||||
|
sdk.viewer.imageryLayers.layerMoved.addEventListener(syncImageryLayerMoved);
|
||||||
|
sdk.viewer.imageryLayers.layerRemoved.addEventListener(syncImageryLayerRemoved);
|
||||||
|
sdk.viewer.imageryLayers.layerShownOrHidden.addEventListener(syncImageryLayerShownOrHidden);
|
||||||
|
let imageryLayers = [...sdk.viewer.imageryLayers._layers]
|
||||||
|
imageryLayers.sort((a, b) => a._layerIndex - b._layerIndex);
|
||||||
|
sdk2D.viewer.imageryLayers.removeAll()
|
||||||
|
for (let i = 0; i < imageryLayers.length; i++) {
|
||||||
|
let entity = sdk2D.viewer.imageryLayers.addImageryProvider(imageryLayers[i].imageryProvider, imageryLayers[i]._layerIndex)
|
||||||
|
entity.show = imageryLayers[i].show
|
||||||
|
}
|
||||||
|
// sdk.viewer.entities.collectionChanged.addEventListener(syncEntities)
|
||||||
|
// sdk.viewer.dataSources.dataSourceAdded.addEventListener(syncDataSources)
|
||||||
|
|
||||||
|
if (getFlwStatus(sdk)) {
|
||||||
|
FlwStatusSwitch(sdk2, true)
|
||||||
|
}
|
||||||
|
if (getJwwStatus(sdk)) {
|
||||||
|
JwwStatusSwitch(sdk2, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
async function on(sdk) {
|
||||||
|
if (sdk2D) {
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
init(sdk)
|
||||||
|
offSplitScreen()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function off(sdk) {
|
||||||
|
sdk.viewer.scene.preRender.removeEventListener(syncViewer, syncObject)
|
||||||
|
sdk.viewer.imageryLayers.layerAdded.removeEventListener(syncImageryLayerAdded);
|
||||||
|
sdk.viewer.imageryLayers.layerMoved.removeEventListener(syncImageryLayerMoved);
|
||||||
|
sdk.viewer.imageryLayers.layerRemoved.removeEventListener(syncImageryLayerRemoved);
|
||||||
|
sdk.viewer.imageryLayers.layerShownOrHidden.removeEventListener(syncImageryLayerShownOrHidden);
|
||||||
|
// sdk.viewer.entities.collectionChanged.removeEventListener(syncEntities)
|
||||||
|
// sdk.viewer.dataSources.dataSourceAdded.removeEventListener(syncDataSources)
|
||||||
|
|
||||||
|
//primitiveAdded=undefined基元同步设置在add位置
|
||||||
|
// sdk.viewer.scene.primitives.primitiveAdded.removeEventListener(syncPrimitivesAdded)
|
||||||
|
for (let i = 0; i < handlers.length; i++) {
|
||||||
|
handlers[i].destroy()
|
||||||
|
}
|
||||||
|
if (sdk2D) {
|
||||||
|
sdk2D.destroy()
|
||||||
|
handlers = []
|
||||||
|
sdk2D = null
|
||||||
|
sdk3D = null
|
||||||
|
activeViewer = null
|
||||||
|
syncObject = {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function syncData2(sdk, id, entityId) {
|
||||||
|
if (sdk && sdk.viewer && sdk.viewer._element && sdk.viewer._element.className === 'cesium-viewer 2d') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!sdk3D || !sdk2D) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let entityMap = sdk3D.entityMap
|
||||||
|
if (id) {
|
||||||
|
let that = entityMap.get(id)
|
||||||
|
if (that) {
|
||||||
|
let that2 = sdk2D.entityMap.get(id)
|
||||||
|
if (that2) {
|
||||||
|
await that2.remove()
|
||||||
|
}
|
||||||
|
let options = syncObject.tools.deepCopyObj(that.options)
|
||||||
|
if (that.type === 'BillboardObject') {
|
||||||
|
options.heightReference = 1
|
||||||
|
}
|
||||||
|
if (that.type === 'PolygonObject') {
|
||||||
|
options.heightMode = 0
|
||||||
|
options.height = 0
|
||||||
|
}
|
||||||
|
if (!that.type || (that.type !== 'tileset' && that.type !== 'bim' && that.type !== 'glb' && that.type !== 'layer')) {
|
||||||
|
let newObject = await new that.constructor(sdk2D, options)
|
||||||
|
newObject.onClick = that.onClick
|
||||||
|
newObject.onRightClick = that.onRightClick
|
||||||
|
newObject.onMouseMove = that.onMouseMove
|
||||||
|
if (that.type === 'TrajectoryMotion') {
|
||||||
|
that.firstPersonView = false
|
||||||
|
if (that.TweenAnimate) {
|
||||||
|
let state = that.state
|
||||||
|
if (state) {
|
||||||
|
that.state = false
|
||||||
|
}
|
||||||
|
if (!newObject.state) {
|
||||||
|
setTimeout(() => {
|
||||||
|
newObject.setMovePositionByDistance(Number(that.TweenAnimate._object.distance.toFixed(8)) + 0.00000001)
|
||||||
|
setTimeout(() => {
|
||||||
|
newObject.setMovePositionByDistance(Number(that.TweenAnimate._object.distance.toFixed(8)) + 0.00000002)
|
||||||
|
}, 500);
|
||||||
|
}, 500);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
newObject.setMovePositionByDistance(Number(that.TweenAnimate._object.distance.toFixed(8)))
|
||||||
|
}
|
||||||
|
that.state = state
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
setTimeout(() => {
|
||||||
|
newObject.setMovePositionByDistance(0.00000001)
|
||||||
|
setTimeout(() => {
|
||||||
|
newObject.setMovePositionByDistance(0.00000002)
|
||||||
|
}, 500)
|
||||||
|
}, 500)
|
||||||
|
}
|
||||||
|
if (that.viewFollow) {
|
||||||
|
newObject.viewFollow = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (that.type === 'AttackArrowObject' || that.type === 'StraightArrowObject') {
|
||||||
|
if (that.spreadState && that.TweenAnimate && that.TweenAnimate._object) {
|
||||||
|
newObject.setSpreadProgressByTime(that.TweenAnimate._object.distance / that.TweenAnimate._valuesEnd.distance * that.spreadTime)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (that.type === 'PincerArrowObject') {
|
||||||
|
if (that.spreadState && that.TweenAnimate && that.TweenAnimate._object) {
|
||||||
|
newObject.setSpreadProgressByTime(that.TweenAnimate._object.distance1 / that.TweenAnimate._valuesEnd.distance1 * that.spreadTime)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (newObject.on && newObject.type !== 'glb') {
|
||||||
|
if (newObject.type === 'vector') {
|
||||||
|
newObject.data = that.data
|
||||||
|
newObject.load(() => {
|
||||||
|
if (newObject.entity) {
|
||||||
|
for (let i = 0; i < newObject.entity.entities.values.length; i++) {
|
||||||
|
newObject.entity.entities.values[i].show = that.entity.entities.values[i]._customShow === false ? false : true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
await newObject.on()
|
||||||
|
}
|
||||||
|
// if (newObject.type && (newObject.type === 'tileset' || newObject.type === 'bim')) {
|
||||||
|
// newObject.height = -10000
|
||||||
|
// }
|
||||||
|
// // Cesium1.98版本二维模式下初次显示有问题,1.110以上版本正常
|
||||||
|
// if (newObject.type && (newObject.type === 'glb')) {
|
||||||
|
// newObject.options.position.alt = 0
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
let that2 = sdk2D.entityMap.get(id)
|
||||||
|
if (that2) {
|
||||||
|
await that2.remove()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for (let [key, obj] of sdk2D.entityMap) {
|
||||||
|
let that = sdk2D.entityMap.get(key)
|
||||||
|
if (that) {
|
||||||
|
await that.remove()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (let [key, obj] of entityMap) {
|
||||||
|
if (obj.type === 'BillboardObject') {
|
||||||
|
obj.options.heightReference = 1
|
||||||
|
}
|
||||||
|
let options = syncObject.tools.deepCopyObj(obj.options)
|
||||||
|
if (!obj.type || (obj.type !== 'tileset' && obj.type !== 'bim' && obj.type !== 'glb' && obj.type !== 'layer')) {
|
||||||
|
let target = await new obj.constructor(sdk2D, options)
|
||||||
|
target.onClick = obj.onClick
|
||||||
|
target.onRightClick = obj.onRightClick
|
||||||
|
target.onMouseMove = obj.onMouseMove
|
||||||
|
if (obj.type === 'TrajectoryMotion') {
|
||||||
|
obj.firstPersonView = false
|
||||||
|
if (obj.TweenAnimate) {
|
||||||
|
let state = obj.state
|
||||||
|
if (state) {
|
||||||
|
obj.state = false
|
||||||
|
}
|
||||||
|
if (!target.state) {
|
||||||
|
setTimeout(() => {
|
||||||
|
target.setMovePositionByDistance(Number(obj.TweenAnimate._object.distance.toFixed(8)) + 0.000000001)
|
||||||
|
setTimeout(() => {
|
||||||
|
target.setMovePositionByDistance(Number(obj.TweenAnimate._object.distance.toFixed(8)) + 0.000000002)
|
||||||
|
}, 1500);
|
||||||
|
}, 1500);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
target.setMovePositionByDistance(Number(obj.TweenAnimate._object.distance.toFixed(8)))
|
||||||
|
}
|
||||||
|
obj.state = state
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
setTimeout(() => {
|
||||||
|
target.setMovePositionByDistance(0.000000001)
|
||||||
|
setTimeout(() => {
|
||||||
|
target.setMovePositionByDistance(0.000000002)
|
||||||
|
}, 1500);
|
||||||
|
}, 1500);
|
||||||
|
}
|
||||||
|
if (obj.viewFollow) {
|
||||||
|
target.viewFollow = true
|
||||||
|
}
|
||||||
|
// else {
|
||||||
|
// newObject.viewFollow = false
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
if (obj.type === 'AttackArrowObject' || obj.type === 'StraightArrowObject') {
|
||||||
|
if (obj.spreadState && obj.TweenAnimate && obj.TweenAnimate._object) {
|
||||||
|
target.setSpreadProgressByTime(obj.TweenAnimate._object.distance / obj.TweenAnimate._valuesEnd.distance * obj.spreadTime)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (obj.type === 'PincerArrowObject') {
|
||||||
|
if (obj.spreadState && obj.TweenAnimate && obj.TweenAnimate._object) {
|
||||||
|
target.setSpreadProgressByTime(obj.TweenAnimate._object.distance1 / obj.TweenAnimate._valuesEnd.distance1 * obj.spreadTime)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (target.on && obj.type !== 'glb') {
|
||||||
|
if (target.type === 'vector') {
|
||||||
|
target.data = obj.data
|
||||||
|
target.load(() => {
|
||||||
|
if (target.entity) {
|
||||||
|
for (let i = 0; i < target.entity.entities.values.length; i++) {
|
||||||
|
target.entity.entities.values[i].show = obj.entity.entities.values[i]._customShow === false ? false : true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
await target.on()
|
||||||
|
}
|
||||||
|
// if (obj.type && (obj.type === 'tileset' || obj.type === 'bim')) {
|
||||||
|
// target.height = -10000
|
||||||
|
// }
|
||||||
|
// if (obj.type && (obj.type === 'glb')) {
|
||||||
|
// target.options.position.alt = 0
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function syncData(sdk, id, entityId) {
|
||||||
|
syncData2(sdk, id, entityId)
|
||||||
|
// syncEntities()
|
||||||
|
// syncDataSources()
|
||||||
|
}
|
||||||
|
|
||||||
|
function syncEntities(entities1, entities2) {
|
||||||
|
if (!sdk3D) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (sdk2D) {
|
||||||
|
if (Array.isArray(entities1) || Array.isArray(entities2)) {
|
||||||
|
entities1 = null
|
||||||
|
entities2 = null
|
||||||
|
}
|
||||||
|
if (!entities1) {
|
||||||
|
entities1 = sdk2D.viewer.entities
|
||||||
|
}
|
||||||
|
if (!entities2) {
|
||||||
|
entities2 = sdk3D.viewer.entities
|
||||||
|
}
|
||||||
|
let entities2D = entities1
|
||||||
|
let entities3D = entities2
|
||||||
|
for (let i = entities2D.values.length - 1; i >= 0; i--) {
|
||||||
|
let flag = false
|
||||||
|
for (let m = entities3D.values.length - 1; m >= 0; m--) {
|
||||||
|
if (entities2D.values[i].id === entities3D.values[m].id) {
|
||||||
|
flag = true
|
||||||
|
entities2D.values[i] === entities3D.values[m]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!flag) {
|
||||||
|
entities2D.remove(entities2D.values[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (let m = entities3D.values.length - 1; m >= 0; m--) {
|
||||||
|
let flag = false
|
||||||
|
for (let i = entities2D.values.length - 1; i >= 0; i--) {
|
||||||
|
if (entities2D.values[i].id === entities3D.values[m].id) {
|
||||||
|
flag = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!flag) {
|
||||||
|
let entity = entities2D.add(entities3D.values[m])
|
||||||
|
// if (entity.rectangle) {
|
||||||
|
// // 设置高度,否则在某些位置无法显示,但色彩会变暗
|
||||||
|
// entity.rectangle.height = 0
|
||||||
|
// console.log('242342354235',entities3D.values[m])
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function syncDataSources(dataSources, type) {
|
||||||
|
if (!sdk3D) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (sdk2D) {
|
||||||
|
let dataSources2D = sdk2D.viewer.dataSources
|
||||||
|
if (dataSources) {
|
||||||
|
for (let i = dataSources2D._dataSources.length - 1; i >= 0; i--) {
|
||||||
|
if (dataSources2D._dataSources[i].name === dataSources.name) {
|
||||||
|
if (type === 'entities') {
|
||||||
|
syncEntities(dataSources2D._dataSources[i].entities, dataSources.entities)
|
||||||
|
}
|
||||||
|
if (type === 'clustering') {
|
||||||
|
dataSources2D._dataSources[i].clustering.enabled = dataSources.clustering.enabled
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// for (let m = dataSources3D._dataSources.length - 1; m >= 0; m--) {
|
||||||
|
// let flag = false
|
||||||
|
// for (let i = dataSources2D._dataSources.length - 1; i >= 0; i--) {
|
||||||
|
// console.log(dataSources2D._dataSources[i].name, dataSources3D._dataSources[m].name)
|
||||||
|
// if (dataSources2D._dataSources[i].name === dataSources3D._dataSources[m].name) {
|
||||||
|
// flag = true
|
||||||
|
// break
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// if (!flag) {
|
||||||
|
// dataSources2D.add(dataSources3D._dataSources[m])
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function syncImageryLayerAdded(layer, index) {
|
||||||
|
sdk2D.viewer.imageryLayers.addImageryProvider(layer.imageryProvider, index)
|
||||||
|
}
|
||||||
|
function syncImageryLayerMoved(layer, newindxe, oldindex) {
|
||||||
|
let layer2d = sdk2D.viewer.imageryLayers._layers[oldindex]
|
||||||
|
if (!layer2d) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 移到最底层
|
||||||
|
if (newindxe === 0) {
|
||||||
|
sdk2D.viewer.imageryLayers.lowerToBottom(layer2d)
|
||||||
|
}
|
||||||
|
// 移到最高层
|
||||||
|
else if (newindxe === sdk3D.viewer.imageryLayers._layers.length - 1) {
|
||||||
|
sdk2D.viewer.imageryLayers.raiseToTop(layer2d)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (newindxe < oldindex) {
|
||||||
|
sdk2D.viewer.imageryLayers.lower(layer2d)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sdk2D.viewer.imageryLayers.raise(layer2d)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function syncImageryLayerRemoved(layer, index) {
|
||||||
|
let layer2d = sdk2D.viewer.imageryLayers._layers[index]
|
||||||
|
if (!layer2d) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
sdk2D.viewer.imageryLayers.remove(layer2d)
|
||||||
|
}
|
||||||
|
function syncImageryLayerShownOrHidden(layer, index, state) {
|
||||||
|
let layer2d = sdk2D.viewer.imageryLayers._layers[index]
|
||||||
|
if (!layer2d) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
layer2d.show = state
|
||||||
|
}
|
||||||
|
|
||||||
|
async function syncPrimitives(primitive) {
|
||||||
|
if (!sdk3D) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (sdk2D) {
|
||||||
|
// await sdk2D.viewer.scene.primitives.remove(primitive)
|
||||||
|
// await sdk2D.viewer.scene.primitives.add(primitive)
|
||||||
|
let primitives2D = sdk2D.viewer.scene.primitives._primitives
|
||||||
|
let primitives3D = sdk3D.viewer.scene.primitives._primitives
|
||||||
|
// console.log(primitives2D, primitives3D)
|
||||||
|
// setTimeout(() => {
|
||||||
|
// sdk2D.viewer.scene.primitives._primitives[1] = sdk3D.viewer.scene.primitives._primitives[1]
|
||||||
|
// }, 2000);
|
||||||
|
for (let i = primitives2D.length - 1; i >= 1; i--) {
|
||||||
|
let flag = false
|
||||||
|
for (let m = primitives3D.length - 1; m >= 1; m--) {
|
||||||
|
if (primitives3D[m].id && primitives2D[m].id && (primitives3D[m].id === primitives2D[i].id)) {
|
||||||
|
flag = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!flag) {
|
||||||
|
sdk2D.viewer.scene.primitives.remove(primitives2D[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (let m = primitives3D.length - 1; m >= 1; m--) {
|
||||||
|
let flag = false
|
||||||
|
for (let i = primitives2D.length - 1; i >= 1; i--) {
|
||||||
|
if (primitives3D[m].id && primitives2D[m].id && (primitives3D[m].id === primitives2D[i].id)) {
|
||||||
|
flag = true
|
||||||
|
primitives2D[i].show = primitives3D[m].show
|
||||||
|
primitives2D[i].startColor = primitives3D[m].startColor
|
||||||
|
primitives2D[i].endColor = primitives3D[m].endColor
|
||||||
|
primitives2D[i].minimumSpeed = primitives3D[m].minimumSpeed
|
||||||
|
primitives2D[i].maximumSpeed = primitives3D[m].maximumSpeed
|
||||||
|
primitives2D[i].minimumParticleLife = primitives3D[m].minimumParticleLife
|
||||||
|
primitives2D[i].maximumParticleLife = primitives3D[m].maximumParticleLife
|
||||||
|
primitives2D[i].startScale = primitives3D[m].startScale
|
||||||
|
primitives2D[i].endScale = primitives3D[m].endScale
|
||||||
|
primitives2D[i].emissionRate = primitives3D[m].emissionRate
|
||||||
|
primitives2D[i].particleSize = primitives3D[m].particleSize
|
||||||
|
primitives2D[i].modelMatrix = primitives3D[m].modelMatrix
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!flag) {
|
||||||
|
sdk2D.viewer.scene.primitives.add(primitives3D[m])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function eventBind(sdk, i, syncObject) {
|
||||||
|
let handler = new Cesium.ScreenSpaceEventHandler(
|
||||||
|
sdk.viewer.canvas
|
||||||
|
)
|
||||||
|
handler.setInputAction(() => {
|
||||||
|
activeViewer = i
|
||||||
|
}, Cesium.ScreenSpaceEventType.LEFT_DOWN)
|
||||||
|
handler.setInputAction(() => {
|
||||||
|
activeViewer = i
|
||||||
|
}, Cesium.ScreenSpaceEventType.RIGHT_DOWN)
|
||||||
|
handler.setInputAction(() => {
|
||||||
|
activeViewer = i
|
||||||
|
}, Cesium.ScreenSpaceEventType.WHEEL)
|
||||||
|
handlers.push(handler)
|
||||||
|
}
|
||||||
|
|
||||||
|
function syncViewer() {
|
||||||
|
let sdk = this.sdks[activeViewer]
|
||||||
|
let sdk2
|
||||||
|
|
||||||
|
if (activeViewer === 0) {
|
||||||
|
sdk2 = this.sdks[1]
|
||||||
|
}
|
||||||
|
else if (activeViewer === 1) {
|
||||||
|
sdk2 = this.sdks[0]
|
||||||
|
}
|
||||||
|
// this.sdks[0].viewer.trackedEntity = null
|
||||||
|
// this.sdks[1].viewer.trackedEntity = null
|
||||||
|
if (sdk.viewer.scene.mode === 2) {
|
||||||
|
if (this.sdks[0].viewer.trackedEntity) {
|
||||||
|
let distance = sdk.viewer.camera.positionCartographic.height
|
||||||
|
sdk2.viewer.camera.lookAt(
|
||||||
|
Cesium.Cartesian3.fromRadians(sdk.viewer.camera.positionCartographic.longitude, sdk.viewer.camera.positionCartographic.latitude, 0),
|
||||||
|
new Cesium.HeadingPitchRange(0, Cesium.Math.toRadians(-90), distance)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (this.sdks[1].viewer.trackedEntity) {
|
||||||
|
this.sdks[1].viewer.entities.remove(this.sdks[1].viewer.trackedEntity)
|
||||||
|
this.sdks[1].viewer.trackedEntity = null
|
||||||
|
}
|
||||||
|
let centerResult84 = this.tools.cartesian3Towgs84(Cesium.Cartesian3.fromRadians(sdk.viewer.camera.positionCartographic.longitude, sdk.viewer.camera.positionCartographic.latitude, sdk.viewer.camera.positionCartographic.height), sdk.viewer)
|
||||||
|
sdk2.viewer.camera.setView({
|
||||||
|
destination: Cesium.Cartesian3.fromDegrees(centerResult84.lng, centerResult84.lat, centerResult84.alt),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// 视角中心点(伪)
|
||||||
|
let centerResult = sdk.viewer.camera.pickEllipsoid(
|
||||||
|
new Cesium.Cartesian2(
|
||||||
|
sdk.viewer.canvas.clientWidth / 2,
|
||||||
|
sdk.viewer.canvas.clientHeight / (2 - ((90 + sdk.viewer.camera.pitch / (Cesium.Math.PI / 180)) / 110)),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
if (!centerResult) {
|
||||||
|
centerResult = sdk.viewer.camera.positionWC
|
||||||
|
}
|
||||||
|
|
||||||
|
let height = this.tools.cartesian3Towgs84(sdk.viewer.camera.positionWC, sdk.viewer).alt
|
||||||
|
let centerResult84 = this.tools.cartesian3Towgs84(centerResult, sdk.viewer)
|
||||||
|
|
||||||
|
// console.log('--------------', sdk.viewer.camera.position, sdk.viewer.camera.positionWC, centerResult84, height)
|
||||||
|
|
||||||
|
sdk2.viewer.camera.setView({
|
||||||
|
destination: Cesium.Cartesian3.fromDegrees(centerResult84.lng, centerResult84.lat, height),
|
||||||
|
// orientation: {
|
||||||
|
// heading: sdk2.viewer.camera.heading,
|
||||||
|
// pitch: sdk2.viewer.camera.pitch,
|
||||||
|
// roll: sdk2.viewer.camera.roll
|
||||||
|
// }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function get2DView() {
|
||||||
|
return sdk2D
|
||||||
|
}
|
||||||
|
|
||||||
|
function get3DView() {
|
||||||
|
return sdk3D
|
||||||
|
}
|
||||||
|
|
||||||
|
function solveBug() {
|
||||||
|
// 在能显示的地方加载一个多边形,解决二维模式下某些地方无法显示多边形的bug,原因不明
|
||||||
|
sdk2D && sdk2D.viewer.entities.add({
|
||||||
|
show: false,
|
||||||
|
polygon: {
|
||||||
|
hierarchy: new Cesium.PolygonHierarchy(Cesium.Cartesian3.fromDegreesArray([100, 50, 100.0001, 50, 100.0001, 50.0001]))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function setActiveViewer(v) {
|
||||||
|
activeViewer = v
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export { on, off, syncData, syncEntities, syncDataSources, syncPrimitives, get2DView, get3DView, setActiveViewer }
|
||||||
92
src/Global/ScreenRecord/index.js
Normal file
92
src/Global/ScreenRecord/index.js
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
class ScreenRecord {
|
||||||
|
constructor() {
|
||||||
|
this.start()
|
||||||
|
}
|
||||||
|
|
||||||
|
start() {
|
||||||
|
navigator.mediaDevices.getDisplayMedia({
|
||||||
|
video: true
|
||||||
|
})
|
||||||
|
.then((stream) => {
|
||||||
|
// 需要更好的浏览器支持
|
||||||
|
// const mime = MediaRecorder.isTypeSupported('video/webm; codecs=vp9')
|
||||||
|
// ? 'video/webm; codecs=vp9'
|
||||||
|
// : 'video/webm'
|
||||||
|
this.mediaRecorder = new MediaRecorder(stream, {
|
||||||
|
// mimeType: mime,
|
||||||
|
mimeType: 'video/webm',
|
||||||
|
})
|
||||||
|
|
||||||
|
let chunks = []
|
||||||
|
this.mediaRecorder.addEventListener('dataavailable', function (e) {
|
||||||
|
chunks.push(e.data)
|
||||||
|
})
|
||||||
|
|
||||||
|
this.mediaRecorder.addEventListener('stop', async () => {
|
||||||
|
try {
|
||||||
|
let blob = new Blob(chunks, {
|
||||||
|
type: 'video/mp4',
|
||||||
|
})
|
||||||
|
const opts = {
|
||||||
|
suggestedName: '视频录制.mp4',
|
||||||
|
types: [
|
||||||
|
{
|
||||||
|
description: '文件类型',
|
||||||
|
accept: {
|
||||||
|
'video/mp4': ['.mp4'],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
excludeAcceptAllOption: true
|
||||||
|
};
|
||||||
|
|
||||||
|
const handle = await window.showSaveFilePicker(opts); // 打开保存文件对话框
|
||||||
|
const writable = await handle.createWritable(); // 创建可写入的文件对象
|
||||||
|
// 写入视频内容
|
||||||
|
writable.write(blob);
|
||||||
|
await writable.close();
|
||||||
|
YJ.Global.ScreenRecord.screenRecord = null
|
||||||
|
} catch (error) {
|
||||||
|
console.info('文件保存失败:', error);
|
||||||
|
}
|
||||||
|
|
||||||
|
// let blob = new Blob(chunks, {
|
||||||
|
// type: chunks[0].type,
|
||||||
|
// })
|
||||||
|
// let url = URL.createObjectURL(blob)
|
||||||
|
|
||||||
|
// let a = document.createElement('a')
|
||||||
|
// a.href = url
|
||||||
|
// a.download = 'video.webm'
|
||||||
|
// a.click()
|
||||||
|
// this.recording = false
|
||||||
|
// YJ.Global.ScreenRecord.screenRecord = null
|
||||||
|
})
|
||||||
|
|
||||||
|
// 必须手动启动
|
||||||
|
this.mediaRecorder.start()
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
console.info('取消录屏')
|
||||||
|
console.info(e)
|
||||||
|
YJ.Global.ScreenRecord.screenRecord = null
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function startScreenRecord() {
|
||||||
|
if (YJ.Global.ScreenRecord.screenRecord) {
|
||||||
|
return '录屏任务进行中'
|
||||||
|
} else {
|
||||||
|
YJ.Global.ScreenRecord.screenRecord = new ScreenRecord()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function stopScreenRecord() {
|
||||||
|
if (YJ.Global.ScreenRecord && YJ.Global.ScreenRecord.screenRecord && YJ.Global.ScreenRecord.screenRecord) {
|
||||||
|
YJ.Global.ScreenRecord.screenRecord.mediaRecorder.stop()
|
||||||
|
YJ.Global.ScreenRecord.screenRecord = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export { startScreenRecord, stopScreenRecord }
|
||||||
707
src/Global/ScreenShot/index.js
Normal file
707
src/Global/ScreenShot/index.js
Normal file
@ -0,0 +1,707 @@
|
|||||||
|
import Tools from '../../Tools'
|
||||||
|
import Dialog from '../../Obj/Element/Dialog';
|
||||||
|
import { legp } from '../../Obj/Element/datalist';
|
||||||
|
import MapPrint from '../MapPrint';
|
||||||
|
import { off as offSplitScreen } from "../SplitScreen";
|
||||||
|
import { off as offMultiViewportMode } from "../MultiViewportMode";
|
||||||
|
|
||||||
|
// 生成快照
|
||||||
|
const convertToImage = (container, options = {}) => {
|
||||||
|
// 设置放大倍数
|
||||||
|
const scale = window.devicePixelRatio;
|
||||||
|
|
||||||
|
// 传入节点原始宽高
|
||||||
|
const width = container.offsetWidth;
|
||||||
|
const height = container.offsetHeight;
|
||||||
|
|
||||||
|
// html2canvas配置项
|
||||||
|
const ops = {
|
||||||
|
scale,//比例,越大分辨率越高,图片越小
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
async: false,
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
backgroundColor: 'rgb(20,47,65)',
|
||||||
|
imageTimeout: 0,
|
||||||
|
useCORS: true,//允许跨域
|
||||||
|
allowTaint: false, //允许跨域数据污染'被污染'的canvas
|
||||||
|
tainttest: true,
|
||||||
|
foreignObjectRendering: true, //在浏览器支持的情况下使用ForeignObject模式渲染图片
|
||||||
|
...options
|
||||||
|
};
|
||||||
|
|
||||||
|
return html2canvas(container, ops).then(canvas => {
|
||||||
|
// 返回图片的二进制数据
|
||||||
|
return canvas.toDataURL("image/png");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function ScreenShot(sdk, cd = () => { }) {
|
||||||
|
// const imgBlobData = await convertToImage(sdk.viewer.canvas);
|
||||||
|
const imgBlobData = sdk.viewer.canvas.toDataURL()
|
||||||
|
cd && cd(imgBlobData)
|
||||||
|
// try {
|
||||||
|
// const imgBlobData = await convertToImage(sdk.viewer.canvas);
|
||||||
|
// let arr = imgBlobData.split(','), mime = arr[0].match(/:(.*?);/)[1],
|
||||||
|
// bstr = atob(arr[1]), i = bstr.length, u8arr = new Uint8Array(i);
|
||||||
|
// while (i--) {
|
||||||
|
// u8arr[i] = bstr.charCodeAt(i);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// let blob = new Blob([u8arr], { type: mime });
|
||||||
|
// const opts = {
|
||||||
|
// suggestedName: '截图.png',
|
||||||
|
// types: [
|
||||||
|
// {
|
||||||
|
// description: '文件类型',
|
||||||
|
// accept: {
|
||||||
|
// 'image/png': ['.png'],
|
||||||
|
// 'image/jpg': ['.jpg']
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// ],
|
||||||
|
// excludeAcceptAllOption: true
|
||||||
|
// };
|
||||||
|
|
||||||
|
// const handle = await window.showSaveFilePicker(opts); // 打开保存文件对话框
|
||||||
|
// const writable = await handle.createWritable(); // 创建可写入的文件对象
|
||||||
|
// // 写入视频内容
|
||||||
|
// writable.write(blob);
|
||||||
|
// await writable.close();
|
||||||
|
// YJ.Global.ScreenRecord.screenRecord = null
|
||||||
|
// } catch (error) {
|
||||||
|
// console.info('文件保存失败:', error);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
let _DialogObject
|
||||||
|
|
||||||
|
async function ScreenShotHD(sdk, options = {}, cd = () => { }) {
|
||||||
|
if (!sdk) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
offSplitScreen(sdk)
|
||||||
|
offMultiViewportMode(sdk)
|
||||||
|
if (_DialogObject) {
|
||||||
|
_DialogObject.close()
|
||||||
|
_DialogObject = null
|
||||||
|
}
|
||||||
|
|
||||||
|
let enableTranslate = sdk.viewer.scene.screenSpaceCameraController.enableTranslate
|
||||||
|
let enableTilt = sdk.viewer.scene.screenSpaceCameraController.enableTilt
|
||||||
|
let enableLook = sdk.viewer.scene.screenSpaceCameraController.enableLook
|
||||||
|
|
||||||
|
let scale = 1
|
||||||
|
let level
|
||||||
|
|
||||||
|
let progressInputElm
|
||||||
|
let progressBarElm
|
||||||
|
let rangeNodeActive
|
||||||
|
let rangeNodeActiveText
|
||||||
|
let startScreenShotObject
|
||||||
|
let tools = new Tools();
|
||||||
|
_DialogObject = await new Dialog(sdk, {}, {
|
||||||
|
title: '高清出图', left: '180px', top: '100px',
|
||||||
|
confirmCallBack: (options) => {
|
||||||
|
if (startScreenShotObject) {
|
||||||
|
startScreenShotObject.desist()
|
||||||
|
startScreenShotObject = null
|
||||||
|
}
|
||||||
|
progressInputElm && (progressInputElm.style.width = '0%')
|
||||||
|
rangeNodeActive && (rangeNodeActive.style.left = '0%')
|
||||||
|
progressBarElm && (progressBarElm.style.width = '0%')
|
||||||
|
rangeNodeActiveText && (rangeNodeActiveText.innerHTML = '0%')
|
||||||
|
startScreenShotObject = new startScreenShot()
|
||||||
|
},
|
||||||
|
closeCallBack: () => {
|
||||||
|
sdk.viewer.scene.screenSpaceCameraController.enableTranslate = enableTranslate;
|
||||||
|
sdk.viewer.scene.screenSpaceCameraController.enableTilt = enableTilt;
|
||||||
|
sdk.viewer.scene.screenSpaceCameraController.enableLook = enableLook;
|
||||||
|
sdk.viewer._element.getElementsByClassName('compass')[0].style.pointerEvents = 'auto'
|
||||||
|
if (startScreenShotObject) {
|
||||||
|
startScreenShotObject.desist()
|
||||||
|
startScreenShotObject = null
|
||||||
|
}
|
||||||
|
_DialogObject = undefined
|
||||||
|
}
|
||||||
|
})
|
||||||
|
_DialogObject._element.body.className = _DialogObject._element.body.className + ' screenShotHD'
|
||||||
|
let contentElm = document.createElement('div');
|
||||||
|
contentElm.innerHTML = `
|
||||||
|
<span class="custom-divider"></span>
|
||||||
|
<div class="div-item">
|
||||||
|
<div class="row text" style="align-items: flex-start;">
|
||||||
|
<div class="col">
|
||||||
|
<span>当前窗口长宽:<span class="input-width">${sdk.viewer.canvas.width}</span>*<span class="input-height">${sdk.viewer.canvas.height}</span>像素</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row scale-box" style="align-items: flex-start;">
|
||||||
|
<div class="col">
|
||||||
|
<span class="label">图片大小</span>
|
||||||
|
<div class="input input-select scale"></div>
|
||||||
|
<span>倍窗口</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row text" style="align-items: flex-start;">
|
||||||
|
<div class="col">
|
||||||
|
<span>输出图片长宽:<span class="output-width">${sdk.viewer.canvas.width * scale}</span>*<span class="output-height">${sdk.viewer.canvas.height * scale}</span>像素</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row" style="align-items: flex-start; margin-bottom: 20px;">
|
||||||
|
<div class="col">
|
||||||
|
<span class="label">输出进度</span>
|
||||||
|
<div class="range-box">
|
||||||
|
<div class="range-bg">
|
||||||
|
<div class="range-process-box">
|
||||||
|
<div class="range-process"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="range-node-box">
|
||||||
|
<span class="range-node-text">0%</span>
|
||||||
|
<span class="range-node-text">100%</span>
|
||||||
|
<div class="range-node-active"><span class="range-node-active-text">0%</span></div>
|
||||||
|
</div>
|
||||||
|
<input class="progress-input" type="range" max="100" min="0" step="0.01">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<span class="custom-divider"></span>
|
||||||
|
`
|
||||||
|
_DialogObject.contentAppChild(contentElm)
|
||||||
|
|
||||||
|
sdk.viewer.scene.screenSpaceCameraController.enableTranslate = false;
|
||||||
|
sdk.viewer.scene.screenSpaceCameraController.enableTilt = false;
|
||||||
|
sdk.viewer.scene.screenSpaceCameraController.enableLook = false;
|
||||||
|
sdk.viewer._element.getElementsByClassName('compass')[0].style.pointerEvents = 'none'
|
||||||
|
|
||||||
|
|
||||||
|
let centerResult = sdk.viewer.camera.pickEllipsoid(
|
||||||
|
new Cesium.Cartesian2(
|
||||||
|
sdk.viewer.canvas.clientWidth / 2,
|
||||||
|
sdk.viewer.canvas.clientHeight / 2,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
if (!centerResult) {
|
||||||
|
centerResult = sdk.viewer.camera.pickEllipsoid(
|
||||||
|
new Cesium.Cartesian2(
|
||||||
|
sdk.viewer.canvas.clientWidth / 2,
|
||||||
|
sdk.viewer.canvas.clientHeight / (2 - ((90 + sdk.viewer.camera.pitch / (Cesium.Math.PI / 180)) / 110)),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
if (!centerResult) {
|
||||||
|
centerResult = sdk.viewer.camera.position
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let height = tools.cartesian3Towgs84(sdk.viewer.camera.position, sdk.viewer).alt
|
||||||
|
let centerResult84 = tools.cartesian3Towgs84(centerResult, sdk.viewer)
|
||||||
|
sdk.viewer.camera.flyTo({
|
||||||
|
destination: Cesium.Cartesian3.fromDegrees(centerResult84.lng, centerResult84.lat, height),
|
||||||
|
orientation: { heading: 0, pitch: Cesium.Math.toRadians(-90), roll: 0 },
|
||||||
|
duration: 1,
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
let scaleData = []
|
||||||
|
for (let i = 1; i <= 10; i++) {
|
||||||
|
scaleData.push({
|
||||||
|
name: i,
|
||||||
|
value: i
|
||||||
|
})
|
||||||
|
}
|
||||||
|
progressInputElm = document.getElementsByClassName('progress-input')[0]
|
||||||
|
progressBarElm = document.getElementsByClassName('range-process')[0]
|
||||||
|
rangeNodeActive = contentElm.getElementsByClassName('range-node-active')[0]
|
||||||
|
rangeNodeActiveText = contentElm.getElementsByClassName('range-node-active-text')[0]
|
||||||
|
let scaleDataLegpObject = legp(_DialogObject._element.content.getElementsByClassName('scale-box')[0], ".scale")
|
||||||
|
if (scaleDataLegpObject) {
|
||||||
|
scaleDataLegpObject.legp_search(scaleData)
|
||||||
|
let scaleDataLegpElm = _DialogObject._element.content.getElementsByClassName('scale')[0].getElementsByTagName('input')[0]
|
||||||
|
scale = scaleData[0].value
|
||||||
|
scaleDataLegpObject.legp_searchActive(scaleData[0].value)
|
||||||
|
scaleDataLegpElm.value = scaleData[0].value
|
||||||
|
scaleDataLegpElm.addEventListener('input', () => {
|
||||||
|
for (let i = 0; i < scaleData.length; i++) {
|
||||||
|
if (scaleData[i].value == scaleDataLegpElm.value) {
|
||||||
|
scale = scaleData[i].value
|
||||||
|
_DialogObject._element.content.getElementsByClassName('output-width')[0].innerHTML = sdk.viewer.canvas.width * scale
|
||||||
|
_DialogObject._element.content.getElementsByClassName('output-height')[0].innerHTML = sdk.viewer.canvas.height * scale
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
class startScreenShot {
|
||||||
|
constructor() {
|
||||||
|
this.state = false
|
||||||
|
this.start()
|
||||||
|
}
|
||||||
|
start() {
|
||||||
|
if (sdk.viewer.scene.imageryLayers._layers.length <= 1) {
|
||||||
|
this.error = '未加载底图!'
|
||||||
|
window.ELEMENT && window.ELEMENT.Message({
|
||||||
|
message: this.error,
|
||||||
|
type: 'warning',
|
||||||
|
duration: 1500
|
||||||
|
});
|
||||||
|
console.warn(this.error)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let haveBaseMap = false
|
||||||
|
for (let i = 0; i < sdk.viewer.scene.imageryLayers._layers.length; i++) {
|
||||||
|
let layer = sdk.viewer.scene.imageryLayers._layers[i];
|
||||||
|
if (layer && layer.show && (!layer.notes || layer.notes !== 'default-base-map')) {
|
||||||
|
haveBaseMap = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!haveBaseMap) {
|
||||||
|
this.error = '未加载底图!'
|
||||||
|
window.ELEMENT && window.ELEMENT.Message({
|
||||||
|
message: this.error,
|
||||||
|
type: 'warning',
|
||||||
|
duration: 1500
|
||||||
|
});
|
||||||
|
console.warn(this.error)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let scaleZoom = 0;
|
||||||
|
this.state = true;
|
||||||
|
let _this = this
|
||||||
|
computeLayers(1);
|
||||||
|
|
||||||
|
function computeLayers(s) {
|
||||||
|
let num = s * 2;
|
||||||
|
if (num <= scale) {
|
||||||
|
scaleZoom++;
|
||||||
|
computeLayers(num);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
scaleZoom = scaleZoom + 1;
|
||||||
|
let centerResult = sdk.viewer.camera.pickEllipsoid(
|
||||||
|
new Cesium.Cartesian2(
|
||||||
|
sdk.viewer.canvas.width / 2,
|
||||||
|
sdk.viewer.canvas.height / (2 - ((90 + sdk.viewer.camera.pitch / (Cesium.Math.PI / 180)) / 110))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
if (!centerResult) {
|
||||||
|
centerResult = sdk.viewer.camera.position;
|
||||||
|
}
|
||||||
|
function altitudeToZoom(altitude) {
|
||||||
|
let A = 40487.57;
|
||||||
|
let B = 0.00007096758;
|
||||||
|
let C = 91610.74;
|
||||||
|
let D = -40467.74;
|
||||||
|
return Math.round(D + (A - D) / (1 + Math.pow(altitude / C, B)));
|
||||||
|
}
|
||||||
|
let height = tools.cartesian3Towgs84(sdk.viewer.camera.position, sdk.viewer).alt;
|
||||||
|
let zoom = altitudeToZoom(height) + 1;
|
||||||
|
|
||||||
|
let rectangle = sdk.viewer.camera.computeViewRectangle();
|
||||||
|
// if (height > 9000000) {
|
||||||
|
// height = 9000000
|
||||||
|
// }
|
||||||
|
// let curRectangle = new Cesium.Rectangle(Cesium.Math.toRadians(centerResult84.lng - (height / stepX)), Cesium.Math.toRadians(centerResult84.lat - (height / stepY)), Cesium.Math.toRadians(centerResult84.lng + (height / stepX)), Cesium.Math.toRadians(centerResult84.lat + (height / stepY)))
|
||||||
|
// for (let i = 1; i < sdk.viewer.scene.imageryLayers._layers.length; i++) {
|
||||||
|
// let layer = sdk.viewer.scene.imageryLayers._layers[i]
|
||||||
|
// createCanvas(layer)
|
||||||
|
// }
|
||||||
|
let total;
|
||||||
|
let totalCount = 0;
|
||||||
|
let progress = {};
|
||||||
|
let index = 0;
|
||||||
|
let layerLength = 0
|
||||||
|
let countIndex = 0
|
||||||
|
for (let i = 0; i < sdk.viewer.scene.imageryLayers._layers.length; i++) {
|
||||||
|
let layer = sdk.viewer.scene.imageryLayers._layers[i];
|
||||||
|
if (layer && layer.show && layer.imageryProvider && layer.imageryProvider.url && Cesium.Rectangle.intersection(rectangle, layer.imageryProvider.rectangle) && (!layer.notes || layer.notes !== 'default-base-map')) {
|
||||||
|
layerLength++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let itemTotalProgress = 100 / layerLength
|
||||||
|
let flag = false
|
||||||
|
createCanvas(index);
|
||||||
|
function createCanvas(i, totalCanvas) {
|
||||||
|
let layer = sdk.viewer.scene.imageryLayers._layers[i];
|
||||||
|
if (!layer) {
|
||||||
|
if (!flag) {
|
||||||
|
_this.error = '当前范围内未找到底图数据!'
|
||||||
|
window.ELEMENT && window.ELEMENT.Message({
|
||||||
|
message: _this.error,
|
||||||
|
type: 'warning',
|
||||||
|
duration: 1500
|
||||||
|
});
|
||||||
|
console.warn(_this.error)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!layer.show || !layer.imageryProvider || !layer.imageryProvider.url || !Cesium.Rectangle.intersection(rectangle, layer.imageryProvider.rectangle) || (layer.notes && layer.notes === 'default-base-map')) {
|
||||||
|
let m = i += 1;
|
||||||
|
createCanvas(m, totalCanvas);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
flag = true
|
||||||
|
countIndex++
|
||||||
|
progress[i] = {
|
||||||
|
value: 0
|
||||||
|
}
|
||||||
|
let itemTotalCount = 0;
|
||||||
|
let targetLevel
|
||||||
|
let imageryProvider = layer.imageryProvider;
|
||||||
|
if (level || level === 0) {
|
||||||
|
targetLevel = level
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
targetLevel = (zoom + scaleZoom - 1)
|
||||||
|
if (targetLevel > imageryProvider.maximumLevel) {
|
||||||
|
targetLevel = imageryProvider.maximumLevel
|
||||||
|
}
|
||||||
|
if (targetLevel < imageryProvider.minimumLevel) {
|
||||||
|
targetLevel = imageryProvider.minimumLevel
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function readyPromise() {
|
||||||
|
let MinTile = imageryProvider.tilingScheme.positionToTileXY(
|
||||||
|
Cesium.Rectangle.northwest(rectangle),
|
||||||
|
targetLevel
|
||||||
|
);
|
||||||
|
let MaxTile = imageryProvider.tilingScheme.positionToTileXY(
|
||||||
|
Cesium.Rectangle.southeast(rectangle),
|
||||||
|
targetLevel
|
||||||
|
);
|
||||||
|
if (!MinTile || !MaxTile) {
|
||||||
|
let error = '超出地球范围!'
|
||||||
|
window.ELEMENT && window.ELEMENT.Message({
|
||||||
|
message: error,
|
||||||
|
type: 'warning',
|
||||||
|
duration: 1500
|
||||||
|
});
|
||||||
|
console.warn(error)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let OfXTilesAtLevel = imageryProvider.tilingScheme.getNumberOfXTilesAtLevel(targetLevel)
|
||||||
|
let OfYTilesAtLevel = imageryProvider.tilingScheme.getNumberOfYTilesAtLevel(targetLevel)
|
||||||
|
let MinTileX = MinTile.x;
|
||||||
|
let MinTileY = MinTile.y;
|
||||||
|
let MaxTileX = MaxTile.x;
|
||||||
|
let MaxTileY = MaxTile.y;
|
||||||
|
|
||||||
|
// if (MinTileX > MaxTileX) {
|
||||||
|
// MinTileX = MinTileX - OfXTilesAtLevel
|
||||||
|
// }
|
||||||
|
|
||||||
|
let imgWidth = 256;
|
||||||
|
let imgHeight = 256;
|
||||||
|
|
||||||
|
let itemTotal = (MaxTileX - MinTileX + 1) * (MaxTileY - MinTileY + 1);
|
||||||
|
// var canvas = new fabric.Canvas();
|
||||||
|
let canvas = document.createElement('canvas');
|
||||||
|
canvas.width = (MaxTileX - MinTileX + 1) * imgWidth;
|
||||||
|
canvas.height = (MaxTileY - MinTileY + 1) * imgHeight;
|
||||||
|
let ctx = canvas.getContext('2d');
|
||||||
|
let maxRectangle = imageryProvider.tilingScheme.tileXYToRectangle(MaxTileX, MaxTileY, targetLevel);
|
||||||
|
let minRectangle = imageryProvider.tilingScheme.tileXYToRectangle(MinTileX, MinTileY, targetLevel);
|
||||||
|
let canvasNativeRectangle = new Cesium.Rectangle(minRectangle.west, maxRectangle.south, maxRectangle.east, minRectangle.north);
|
||||||
|
// sdk.viewer.entities.add({
|
||||||
|
// rectangle: {
|
||||||
|
// coordinates: canvasNativeRectangle,
|
||||||
|
// material: Cesium.Color.YELLOW.withAlpha(0.2),
|
||||||
|
// },
|
||||||
|
// });
|
||||||
|
// sdk.viewer.entities.add({
|
||||||
|
// rectangle: {
|
||||||
|
// coordinates: rectangle,
|
||||||
|
// material: Cesium.Color.BLACK.withAlpha(0.2),
|
||||||
|
// },
|
||||||
|
// });
|
||||||
|
let nativeRectangle = rectangle;
|
||||||
|
let x1 = nativeRectangle.west - canvasNativeRectangle.west;
|
||||||
|
let x2 = canvasNativeRectangle.east - nativeRectangle.east;
|
||||||
|
let y1 = canvasNativeRectangle.north - nativeRectangle.north;
|
||||||
|
let y2 = nativeRectangle.south - canvasNativeRectangle.south;
|
||||||
|
|
||||||
|
let ratioX1 = x1 / (canvasNativeRectangle.east - canvasNativeRectangle.west);
|
||||||
|
if (ratioX1 === Infinity) {
|
||||||
|
ratioX1 = 0;
|
||||||
|
}
|
||||||
|
let ratioX2 = x2 / (canvasNativeRectangle.east - canvasNativeRectangle.west);
|
||||||
|
if (ratioX2 === Infinity) {
|
||||||
|
ratioX2 = 0;
|
||||||
|
}
|
||||||
|
let ratioY1 = y1 / (canvasNativeRectangle.north - canvasNativeRectangle.south);
|
||||||
|
if (ratioY1 === Infinity) {
|
||||||
|
ratioY1 = 0;
|
||||||
|
}
|
||||||
|
let ratioY2 = y2 / (canvasNativeRectangle.north - canvasNativeRectangle.south);
|
||||||
|
if (ratioY2 === Infinity) {
|
||||||
|
ratioY2 = 0;
|
||||||
|
}
|
||||||
|
let differenceX1 = canvas.width * ratioX1;
|
||||||
|
let differenceY1 = canvas.height * ratioY1;
|
||||||
|
let differenceX2 = canvas.width * ratioX2;
|
||||||
|
let differenceY2 = canvas.height * ratioY2;
|
||||||
|
canvas.width = canvas.width - differenceX1 - differenceX2;
|
||||||
|
canvas.height = canvas.height - differenceY1 - differenceY2;
|
||||||
|
if (canvas.width == 0) {
|
||||||
|
canvas.width = 1
|
||||||
|
}
|
||||||
|
if (canvas.height == 0) {
|
||||||
|
canvas.height = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
let y = MaxTileY;
|
||||||
|
let x = MaxTileX;
|
||||||
|
|
||||||
|
let tileArray = []
|
||||||
|
for (let y = MaxTileY; y >= MinTileY; y--) {
|
||||||
|
for (let x = MaxTileX; x >= MinTileX; x--) {
|
||||||
|
tileArray.push({ x, y })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let speed = 30
|
||||||
|
|
||||||
|
let obj = {
|
||||||
|
count: 0
|
||||||
|
};
|
||||||
|
let count = 0;
|
||||||
|
|
||||||
|
let times = -1
|
||||||
|
let obj2 = {
|
||||||
|
count: 0
|
||||||
|
}
|
||||||
|
let count2 = 0
|
||||||
|
Object.defineProperty(obj2, 'count', {
|
||||||
|
get: function () {
|
||||||
|
return count2;
|
||||||
|
},
|
||||||
|
set: function (newValue) {
|
||||||
|
count2 = newValue;
|
||||||
|
if (count2 >= speed) {
|
||||||
|
traversal10()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Object.defineProperty(obj, 'count', {
|
||||||
|
get: function () {
|
||||||
|
return count;
|
||||||
|
},
|
||||||
|
set: function (newValue) {
|
||||||
|
count = newValue;
|
||||||
|
progress[i].value = itemTotalCount / itemTotal * itemTotalProgress;
|
||||||
|
let totalProgress = 0
|
||||||
|
for (const key in progress) {
|
||||||
|
totalProgress = totalProgress + progress[key].value
|
||||||
|
}
|
||||||
|
progressBarElm.style.width = totalProgress * 0.99 + '%';
|
||||||
|
rangeNodeActive.style.left = totalProgress * 0.99 + '%';
|
||||||
|
rangeNodeActiveText.innerHTML = Math.floor(totalProgress * 0.99 * 100) / 100 + '%';
|
||||||
|
if (count === (MaxTileX - MinTileX + 1) * (MaxTileY - MinTileY + 1)) {
|
||||||
|
let ctx = canvas.getContext('2d');
|
||||||
|
let cloneCanvas = canvas.cloneNode(true);
|
||||||
|
let cloneCtx = cloneCanvas.getContext('2d');
|
||||||
|
let imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
|
||||||
|
cloneCtx.putImageData(imageData, 0, 0);
|
||||||
|
canvas.width = sdk.viewer.canvas.width * scale;
|
||||||
|
canvas.height = sdk.viewer.canvas.height * scale;
|
||||||
|
ctx.drawImage(cloneCanvas, 0, 0, canvas.width, canvas.height);
|
||||||
|
if (totalCanvas) {
|
||||||
|
let ctx = totalCanvas.getContext('2d');
|
||||||
|
ctx.drawImage(canvas, 0, 0);
|
||||||
|
if (countIndex != layerLength) {
|
||||||
|
let m = i += 1;
|
||||||
|
createCanvas(m, totalCanvas);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
let imgBlobData = totalCanvas.toDataURL('image/jpeg', 0.95);
|
||||||
|
const tempCanvas = document.createElement('canvas');
|
||||||
|
const tempCtx = tempCanvas.getContext('2d');
|
||||||
|
tempCanvas.width = totalCanvas.width / scale
|
||||||
|
tempCanvas.height = totalCanvas.height / scale
|
||||||
|
tempCtx.drawImage(totalCanvas, 0, 0, tempCanvas.width, tempCanvas.height);
|
||||||
|
MapPrint(sdk, tempCanvas.toDataURL('image/jpeg', 0.95), rectangle, imgBlobData)
|
||||||
|
progressBarElm.style.width = '100%';
|
||||||
|
rangeNodeActive.style.left = '100%';
|
||||||
|
rangeNodeActiveText.innerHTML = '100%';
|
||||||
|
_this.state = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
if (countIndex != layerLength) {
|
||||||
|
let m = i += 1;
|
||||||
|
createCanvas(m, canvas);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
let imgBlobData = canvas.toDataURL('image/jpeg', 0.95);
|
||||||
|
const tempCanvas = document.createElement('canvas');
|
||||||
|
const tempCtx = tempCanvas.getContext('2d');
|
||||||
|
tempCanvas.width = canvas.width / scale;
|
||||||
|
tempCanvas.height = canvas.height / scale;
|
||||||
|
tempCtx.drawImage(canvas, 0, 0, tempCanvas.width, tempCanvas.height);
|
||||||
|
// canvas.width = canvas.width / scale
|
||||||
|
// canvas.height = canvas.height / scale
|
||||||
|
MapPrint(sdk, tempCanvas.toDataURL('image/jpeg', 0.95), rectangle, imgBlobData)
|
||||||
|
progressBarElm.style.width = '100%';
|
||||||
|
rangeNodeActive.style.left = '100%';
|
||||||
|
rangeNodeActiveText.innerHTML = '100%';
|
||||||
|
_this.state = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (imageryProvider._readyError) {
|
||||||
|
obj.count = (MaxTileX - MinTileX + 1) * (MaxTileY - MinTileY + 1)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
traversal10()
|
||||||
|
}
|
||||||
|
|
||||||
|
function traversal10() {
|
||||||
|
obj2.count = 0
|
||||||
|
count2 = 0
|
||||||
|
times++
|
||||||
|
for (let i = times * speed; i < (times + 1) * speed; i++) {
|
||||||
|
if (i >= tileArray.length) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
traversal(i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function traversal(i) {
|
||||||
|
if (!_this.state) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
let x = tileArray[i].x
|
||||||
|
if (x < 0) {
|
||||||
|
x = x + OfXTilesAtLevel
|
||||||
|
}
|
||||||
|
const img = new Image();
|
||||||
|
img.setAttribute('crossOrigin', 'anonymous');
|
||||||
|
img.onload = async function () {
|
||||||
|
ctx.drawImage(img, ((tileArray[i].x - MinTileX) * imgWidth) - parseFloat(differenceX1.toFixed(0)), ((tileArray[i].y - MinTileY) * imgHeight) - parseFloat(differenceY1.toFixed(0)), imgWidth, imgHeight);
|
||||||
|
itemTotalCount++;
|
||||||
|
obj.count++;
|
||||||
|
obj2.count++;
|
||||||
|
};
|
||||||
|
img.onerror = function () {
|
||||||
|
itemTotalCount++;
|
||||||
|
obj.count++;
|
||||||
|
obj2.count++;
|
||||||
|
};
|
||||||
|
|
||||||
|
let url;
|
||||||
|
if (imageryProvider.url.indexOf('{x}') !== -1 && imageryProvider.url.indexOf('{y}') !== -1 && imageryProvider.url.indexOf('{z}') !== -1) {
|
||||||
|
url = imageryProvider.url.replace(/\{x\}/g, x).replace(/\{y\}/g, tileArray[i].y).replace(/\{z\}/g, targetLevel);
|
||||||
|
}
|
||||||
|
else if (imageryProvider.url.indexOf('{TileMatrix}') !== -1 && imageryProvider.url.indexOf('{TileRow}') !== -1 && imageryProvider.url.indexOf('{TileCol}') !== -1) {
|
||||||
|
url = imageryProvider.url.replace(/\{TileCol\}/g, x).replace(/\{TileRow\}/g, tileArray[i].y).replace(/\{TileMatrix\}/g, targetLevel);
|
||||||
|
}
|
||||||
|
else if (imageryProvider._layer && imageryProvider._style && imageryProvider._tileMatrixSetID && imageryProvider._format) {
|
||||||
|
url = imageryProvider.url + `&tilematrix=${targetLevel}&layer=${imageryProvider._layer}&style=${imageryProvider._style}&tilerow=${y}&tilecol=${x}&tilematrixset=${imageryProvider._tileMatrixSetID}&format=${imageryProvider._format}`;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
url = imageryProvider.url + `tile/${targetLevel}/${tileArray[i].y}/${x}`;
|
||||||
|
}
|
||||||
|
img.src = url;
|
||||||
|
} catch (error) {
|
||||||
|
itemTotalCount++;
|
||||||
|
obj.count++;
|
||||||
|
obj2.count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function traversal2() {
|
||||||
|
if (!_this.state) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const img = new Image();
|
||||||
|
img.setAttribute('crossOrigin', 'anonymous');
|
||||||
|
img.onload = async function () {
|
||||||
|
ctx.drawImage(img, ((x - MinTileX) * imgWidth) - parseFloat(differenceX1.toFixed(0)), ((y - MinTileY) * imgHeight) - parseFloat(differenceY1.toFixed(0)), imgWidth, imgHeight);
|
||||||
|
itemTotalCount++;
|
||||||
|
obj.count++;
|
||||||
|
|
||||||
|
if (x > MinTileX) {
|
||||||
|
x--
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (y > MinTileY) {
|
||||||
|
y--
|
||||||
|
x = MaxTileX
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
traversal()
|
||||||
|
};
|
||||||
|
|
||||||
|
let url;
|
||||||
|
if (imageryProvider.url.indexOf('{x}') !== -1 && imageryProvider.url.indexOf('{y}') !== -1 && imageryProvider.url.indexOf('{z}') !== -1) {
|
||||||
|
url = imageryProvider.url.replace(/\{x\}/g, x).replace(/\{y\}/g, y).replace(/\{z\}/g, targetLevel);
|
||||||
|
}
|
||||||
|
else if (imageryProvider.url.indexOf('{TileMatrix}') !== -1 && imageryProvider.url.indexOf('{TileRow}') !== -1 && imageryProvider.url.indexOf('{TileCol}') !== -1) {
|
||||||
|
url = imageryProvider.url.replace(/\{TileCol\}/g, x).replace(/\{TileRow\}/g, y).replace(/\{TileMatrix\}/g, targetLevel);
|
||||||
|
}
|
||||||
|
else if (imageryProvider._layer && imageryProvider._style && imageryProvider._tileMatrixSetID && imageryProvider._format) {
|
||||||
|
url = imageryProvider.url + `&tilematrix=${targetLevel}&layer=${imageryProvider._layer}&style=${imageryProvider._style}&tilerow=${y}&tilecol=${x}&tilematrixset=${imageryProvider._tileMatrixSetID}&format=${imageryProvider._format}`;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
url = imageryProvider.url + `tile/${targetLevel}/${y}/${x}`;
|
||||||
|
}
|
||||||
|
img.src = url;
|
||||||
|
} catch (error) {
|
||||||
|
itemTotalCount++;
|
||||||
|
obj.count++;
|
||||||
|
if (x >= MinTileX) {
|
||||||
|
x--
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (y >= MinTileY) {
|
||||||
|
y--
|
||||||
|
x = MaxTileX
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
traversal()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
if (imageryProvider._readyError) {
|
||||||
|
progress[i] = {
|
||||||
|
value: itemTotalProgress
|
||||||
|
}
|
||||||
|
readyPromise()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
imageryProvider.readyPromise.then(() => {
|
||||||
|
readyPromise()
|
||||||
|
}).catch((e) => {
|
||||||
|
imageryProvider._readyError = true
|
||||||
|
progress[i] = {
|
||||||
|
value: itemTotalProgress
|
||||||
|
}
|
||||||
|
readyPromise()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
desist() {
|
||||||
|
this.state = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export { ScreenShot, ScreenShotHD }
|
||||||
655
src/Global/SheetIndex/index.js
Normal file
655
src/Global/SheetIndex/index.js
Normal file
@ -0,0 +1,655 @@
|
|||||||
|
|
||||||
|
import { get2DView } from '../MultiViewportMode'
|
||||||
|
import { getSdk } from '../SplitScreen'
|
||||||
|
import { flyTo } from '../global'
|
||||||
|
import Tools from '../../Tools'
|
||||||
|
|
||||||
|
let tools
|
||||||
|
let state = false
|
||||||
|
let scale = '1:100万'
|
||||||
|
|
||||||
|
function SheetIndexStatusSwitch(sdk, s = false) {
|
||||||
|
if(!sdk) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!tools) {
|
||||||
|
tools = new Tools()
|
||||||
|
}
|
||||||
|
state = s ? true : false
|
||||||
|
|
||||||
|
if (state) {
|
||||||
|
changeScale(sdk, scale)
|
||||||
|
} else {
|
||||||
|
close(sdk)
|
||||||
|
}
|
||||||
|
let sdk2D = get2DView()
|
||||||
|
if (sdk2D) {
|
||||||
|
if (state) {
|
||||||
|
changeScale(sdk, scale)
|
||||||
|
} else {
|
||||||
|
close(sdk2D)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let sdkD = getSdk().sdkD
|
||||||
|
if(sdkD && sdk !== sdkD) {
|
||||||
|
SheetIndexStatusSwitch(sdkD, s)
|
||||||
|
}
|
||||||
|
|
||||||
|
// return new Promise(async (resolve, reject) => {
|
||||||
|
// setTimeout(() => {
|
||||||
|
// resolve()
|
||||||
|
// }, 1000);
|
||||||
|
// })
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function changeScale(sdk, v) {
|
||||||
|
scale = v
|
||||||
|
if (state) {
|
||||||
|
open(sdk)
|
||||||
|
}
|
||||||
|
let sdk2D = get2DView()
|
||||||
|
if (sdk2D) {
|
||||||
|
if (state) {
|
||||||
|
open(sdk2D)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new Promise(async (resolve, reject) => {
|
||||||
|
setTimeout(() => {
|
||||||
|
resolve()
|
||||||
|
}, 1000);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function getStatus() {
|
||||||
|
return state
|
||||||
|
}
|
||||||
|
|
||||||
|
function open(sdk) {
|
||||||
|
close(sdk)
|
||||||
|
let cartographic = sdk.viewer.camera.positionCartographic
|
||||||
|
let options = {
|
||||||
|
position: {
|
||||||
|
lng: Cesium.Math.toDegrees(cartographic.longitude),
|
||||||
|
lat: Cesium.Math.toDegrees(cartographic.latitude),
|
||||||
|
alt: cartographic.height,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
let viewer = sdk.viewer;
|
||||||
|
switch (scale) {
|
||||||
|
case '1:100万':
|
||||||
|
options.position.alt = 16000000
|
||||||
|
break
|
||||||
|
case '1:50万':
|
||||||
|
options.position.alt = 5000000
|
||||||
|
break
|
||||||
|
case '1:25万':
|
||||||
|
options.position.alt = 2300000
|
||||||
|
break
|
||||||
|
case '1:10万':
|
||||||
|
options.position.alt = 680000
|
||||||
|
break
|
||||||
|
case '1:5万':
|
||||||
|
options.position.alt = 385000
|
||||||
|
break
|
||||||
|
case '1:2.5万':
|
||||||
|
options.position.alt = 180000
|
||||||
|
break
|
||||||
|
case '1:1万':
|
||||||
|
options.position.alt = 90000
|
||||||
|
break
|
||||||
|
case '1:5000':
|
||||||
|
options.position.alt = 46000
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
let gridPrimitives
|
||||||
|
let labelCollection
|
||||||
|
for (let i = 0; i < viewer.scene.primitives._primitives.length; i++) {
|
||||||
|
if (viewer.scene.primitives._primitives[i].name === 'SheetIndexGridPrimitives') {
|
||||||
|
gridPrimitives = viewer.scene.primitives._primitives[i];
|
||||||
|
for (let j = 0; j < gridPrimitives._primitives.length; j++) {
|
||||||
|
if (gridPrimitives._primitives[j].name === 'SheetIndexLabelCollection') {
|
||||||
|
labelCollection = gridPrimitives._primitives[j];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!gridPrimitives) {
|
||||||
|
gridPrimitives = new Cesium.PrimitiveCollection();
|
||||||
|
gridPrimitives.name = 'SheetIndexGridPrimitives';
|
||||||
|
viewer.scene.primitives.add(gridPrimitives);
|
||||||
|
}
|
||||||
|
if (!labelCollection) {
|
||||||
|
labelCollection = new Cesium.LabelCollection();
|
||||||
|
labelCollection.name = 'SheetIndexLabelCollection';
|
||||||
|
}
|
||||||
|
|
||||||
|
let stationaryFrames = 0;
|
||||||
|
let maxRectangle = null;
|
||||||
|
gridPrimitives.postRenderEvent = () => {
|
||||||
|
let height = sdk.viewer.camera.positionCartographic.height
|
||||||
|
switch (scale) {
|
||||||
|
case '1:100万':
|
||||||
|
options.position.alt = 16000000
|
||||||
|
break
|
||||||
|
case '1:50万':
|
||||||
|
options.position.alt = 5000000
|
||||||
|
break
|
||||||
|
case '1:25万':
|
||||||
|
options.position.alt = 2300000
|
||||||
|
break
|
||||||
|
case '1:10万':
|
||||||
|
options.position.alt = 680000
|
||||||
|
break
|
||||||
|
case '1:5万':
|
||||||
|
options.position.alt = 385000
|
||||||
|
break
|
||||||
|
case '1:2.5万':
|
||||||
|
options.position.alt = 180000
|
||||||
|
break
|
||||||
|
case '1:1万':
|
||||||
|
options.position.alt = 90000
|
||||||
|
break
|
||||||
|
case '1:5000':
|
||||||
|
options.position.alt = 46000
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if (height > options.position.alt * 5) {
|
||||||
|
maxRectangle = null;
|
||||||
|
gridPrimitives.removeAll();
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let isChanged = false
|
||||||
|
let rectangle = getViewExtend();
|
||||||
|
|
||||||
|
let minLng = Cesium.Math.toDegrees(rectangle.west)
|
||||||
|
let minLat = Cesium.Math.toDegrees(rectangle.south)
|
||||||
|
let maxLng = Cesium.Math.toDegrees(rectangle.east)
|
||||||
|
let maxLat = Cesium.Math.toDegrees(rectangle.north)
|
||||||
|
if (minLng > maxLng) {
|
||||||
|
maxLng += 360
|
||||||
|
}
|
||||||
|
rectangle = { minLng, minLat, maxLng, maxLat }
|
||||||
|
if (maxRectangle) {
|
||||||
|
if ((maxRectangle.minLng > rectangle.minLng || maxRectangle.minLat > rectangle.minLat || maxRectangle.maxLng < rectangle.maxLng || maxRectangle.maxLat < rectangle.maxLat) && Cesium.Math.toDegrees(sdk.viewer.camera.pitch) < 0) {
|
||||||
|
isChanged = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
countMapSheet(scale)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isChanged) {
|
||||||
|
stationaryFrames++;
|
||||||
|
// 确认相机已经静止足够多帧
|
||||||
|
if (stationaryFrames >= 50) {
|
||||||
|
countMapSheet(scale)
|
||||||
|
isChanged = false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
stationaryFrames = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
options.complete = () => {
|
||||||
|
viewer.scene.postRender.addEventListener(gridPrimitives.postRenderEvent);
|
||||||
|
}
|
||||||
|
flyTo(sdk, options, 0.5)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据比例尺创建图幅线
|
||||||
|
* @param {string} scale - 比例尺(可选值:'1:100万', '1:50万', '1:25万', '1:10万', '1:5万', '1:2.5万', '1:1万', '1:5000')
|
||||||
|
*/
|
||||||
|
function countMapSheet(scale) {
|
||||||
|
labelCollection.removeAll();
|
||||||
|
gridPrimitives.removeAll();
|
||||||
|
labelCollection = new Cesium.LabelCollection();
|
||||||
|
labelCollection.name = 'SheetIndexLabelCollection';
|
||||||
|
gridPrimitives.add(labelCollection);
|
||||||
|
let rectangle = getViewExtend();
|
||||||
|
|
||||||
|
let lngStep // 经度步长
|
||||||
|
let latStep // 纬度步长
|
||||||
|
// let limitLng // 显示界限(根据图幅线数量显隐)
|
||||||
|
// let limitLat
|
||||||
|
// Math.abs(maxLng-minLng)/lngStep, Math.abs(maxLat-minLat)/latStep
|
||||||
|
let scaleByDistance
|
||||||
|
switch (scale) {
|
||||||
|
case '1:100万':
|
||||||
|
lngStep = 6;
|
||||||
|
latStep = 4;
|
||||||
|
scaleByDistance = new Cesium.NearFarScalar(
|
||||||
|
20000000,
|
||||||
|
1,
|
||||||
|
80000000,
|
||||||
|
0
|
||||||
|
)
|
||||||
|
break
|
||||||
|
case '1:50万':
|
||||||
|
lngStep = 3;
|
||||||
|
latStep = 2;
|
||||||
|
scaleByDistance = new Cesium.NearFarScalar(
|
||||||
|
5000000,
|
||||||
|
1,
|
||||||
|
30000000,
|
||||||
|
0
|
||||||
|
)
|
||||||
|
break
|
||||||
|
case '1:25万':
|
||||||
|
lngStep = 1.5;
|
||||||
|
latStep = 1;
|
||||||
|
scaleByDistance = new Cesium.NearFarScalar(
|
||||||
|
2300000,
|
||||||
|
1,
|
||||||
|
20000000,
|
||||||
|
0
|
||||||
|
)
|
||||||
|
break
|
||||||
|
case '1:10万':
|
||||||
|
lngStep = 0.5;
|
||||||
|
latStep = 1 / 3;
|
||||||
|
scaleByDistance = new Cesium.NearFarScalar(
|
||||||
|
680000,
|
||||||
|
1,
|
||||||
|
5000000,
|
||||||
|
0
|
||||||
|
)
|
||||||
|
break
|
||||||
|
case '1:5万':
|
||||||
|
lngStep = 0.25;
|
||||||
|
latStep = 1 / 6;
|
||||||
|
scaleByDistance = new Cesium.NearFarScalar(
|
||||||
|
385000,
|
||||||
|
1,
|
||||||
|
2400000,
|
||||||
|
0
|
||||||
|
)
|
||||||
|
break
|
||||||
|
case '1:2.5万':
|
||||||
|
lngStep = 0.125;
|
||||||
|
latStep = 1 / 12;
|
||||||
|
scaleByDistance = new Cesium.NearFarScalar(
|
||||||
|
180000,
|
||||||
|
1,
|
||||||
|
1200000,
|
||||||
|
0
|
||||||
|
)
|
||||||
|
break
|
||||||
|
case '1:1万':
|
||||||
|
lngStep = 0.0625;
|
||||||
|
latStep = 1 / 24;
|
||||||
|
scaleByDistance = new Cesium.NearFarScalar(
|
||||||
|
90000,
|
||||||
|
1,
|
||||||
|
700000,
|
||||||
|
0
|
||||||
|
)
|
||||||
|
break
|
||||||
|
case '1:5000':
|
||||||
|
lngStep = 0.03125;
|
||||||
|
latStep = 1 / 48;
|
||||||
|
scaleByDistance = new Cesium.NearFarScalar(
|
||||||
|
46000,
|
||||||
|
1,
|
||||||
|
300000,
|
||||||
|
0
|
||||||
|
)
|
||||||
|
break
|
||||||
|
// case '1:1000':
|
||||||
|
// lngStep = 0.01041667;
|
||||||
|
// latStep = 0.00694444;
|
||||||
|
// break
|
||||||
|
// case '1:2000':
|
||||||
|
// lngStep = 0.00520833;
|
||||||
|
// latStep = 0.00347222;
|
||||||
|
// break
|
||||||
|
}
|
||||||
|
|
||||||
|
let minLng = Math.floor((180 + Cesium.Math.toDegrees(rectangle.west)) / lngStep) * lngStep - 180;
|
||||||
|
let minLat = Math.floor((88 + Cesium.Math.toDegrees(rectangle.south)) / latStep) * latStep - 88;
|
||||||
|
let maxLng = Math.ceil((180 + Cesium.Math.toDegrees(rectangle.east)) / lngStep) * lngStep - 180;
|
||||||
|
let maxLat = Math.ceil((88 + Cesium.Math.toDegrees(rectangle.north)) / latStep) * latStep - 88;
|
||||||
|
|
||||||
|
if (minLng > maxLng) {
|
||||||
|
maxLng += 360
|
||||||
|
}
|
||||||
|
|
||||||
|
maxRectangle = { minLng, minLat, maxLng, maxLat }
|
||||||
|
if (minLat < -88) {
|
||||||
|
minLat = -88
|
||||||
|
}
|
||||||
|
if (maxLat > 88) {
|
||||||
|
maxLat = 88
|
||||||
|
}
|
||||||
|
|
||||||
|
if (((maxRectangle.maxLng - maxRectangle.minLng) / lngStep) * ((maxRectangle.maxLat - maxRectangle.minLat) / latStep) > 7000) {
|
||||||
|
maxRectangle = null
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 绘制经线
|
||||||
|
for (let lng = minLng; lng <= maxLng; lng += lngStep) {
|
||||||
|
const positions = [];
|
||||||
|
let a = []
|
||||||
|
for (let lat = minLat; Math.floor(lat * 1000000000) / 1000000000 <= maxLat; lat += (latStep / 2)) {
|
||||||
|
a.push([lng, lat])
|
||||||
|
positions.push(Cesium.Cartesian3.fromDegrees(lng, lat, 8848));
|
||||||
|
}
|
||||||
|
if (maxLat != 88 && maxLat + (latStep / 2) >= 88) {
|
||||||
|
positions.push(Cesium.Cartesian3.fromDegrees(lng, 88, 8848));
|
||||||
|
}
|
||||||
|
const geometryInstances = new Cesium.GeometryInstance({
|
||||||
|
geometry: new Cesium.PolylineGeometry({
|
||||||
|
positions: positions,
|
||||||
|
width: 1,
|
||||||
|
vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT,
|
||||||
|
arcType: Cesium.ArcType.RHUMB,
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
gridPrimitives.add(new Cesium.Primitive({
|
||||||
|
geometryInstances: geometryInstances,
|
||||||
|
appearance: new Cesium.PolylineMaterialAppearance({
|
||||||
|
material: Cesium.Material.fromType('Color', {
|
||||||
|
color: Cesium.Color.fromCssColorString('#fcfc00')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}));
|
||||||
|
|
||||||
|
if (lng < maxLng) {
|
||||||
|
// 计算图幅中心坐标
|
||||||
|
for (let lat = minLat; lat < maxLat; lat += latStep) {
|
||||||
|
let position = { lng: lng + (lngStep / 2), lat: lat + (latStep / 2) };
|
||||||
|
if (position.lat > maxLat) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
let sheetNumber = calculateMapSheetNumber(position.lng, position.lat, scale);
|
||||||
|
labelCollection.add({
|
||||||
|
position: Cesium.Cartesian3.fromDegrees(position.lng, position.lat, 8848),
|
||||||
|
text: sheetNumber,
|
||||||
|
font: '16px Inter, sans-serif',
|
||||||
|
fillColor: Cesium.Color.fromCssColorString('#fcfc00'),
|
||||||
|
// backgroundColor: Cesium.Color.fromCssColorString('#FFA145'),
|
||||||
|
// backgroundPadding: new Cesium.Cartesian2(8, 4),
|
||||||
|
pixelOffset: new Cesium.Cartesian2(0, 0),
|
||||||
|
showBackground: false,
|
||||||
|
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||||||
|
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
|
||||||
|
scale: 1.0,
|
||||||
|
distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 80000000),
|
||||||
|
scaleByDistance: scaleByDistance
|
||||||
|
})
|
||||||
|
// labelCollection.add({
|
||||||
|
// position: Cesium.Cartesian3.fromDegrees(position.lng, position.lat, 10000),
|
||||||
|
// text: position.lng + ' , ' + position.lat,
|
||||||
|
// font: '16px Inter, sans-serif',
|
||||||
|
// fillColor: Cesium.Color.WHITE,
|
||||||
|
// backgroundColor: Cesium.Color.fromCssColorString('#165DFF').withAlpha(0.8),
|
||||||
|
// backgroundPadding: new Cesium.Cartesian2(8, 4),
|
||||||
|
// pixelOffset: new Cesium.Cartesian2(0, 30),
|
||||||
|
// showBackground: true,
|
||||||
|
// verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||||||
|
// horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
|
||||||
|
// scale: 1.0,
|
||||||
|
// distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0, 20000000),
|
||||||
|
// scaleByDistance: new Cesium.NearFarScalar(
|
||||||
|
// 5000000,
|
||||||
|
// 1,
|
||||||
|
// 20000000,
|
||||||
|
// 0
|
||||||
|
// )
|
||||||
|
// })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 绘制纬线
|
||||||
|
for (let lat = minLat; Math.floor(lat * 1000000000) / 1000000000 <= maxLat; lat += latStep) {
|
||||||
|
const positions = [];
|
||||||
|
let a = []
|
||||||
|
for (let lng = minLng; lng <= maxLng; lng += (lngStep / 2)) {
|
||||||
|
a.push([lng, lat])
|
||||||
|
positions.push(Cesium.Cartesian3.fromDegrees(lng, lat, 8848));
|
||||||
|
}
|
||||||
|
const geometryInstances = new Cesium.GeometryInstance({
|
||||||
|
geometry: new Cesium.PolylineGeometry({
|
||||||
|
positions: positions,
|
||||||
|
width: 1,
|
||||||
|
vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT,
|
||||||
|
arcType: Cesium.ArcType.RHUMB,
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
gridPrimitives.add(new Cesium.Primitive({
|
||||||
|
geometryInstances: geometryInstances,
|
||||||
|
appearance: new Cesium.PolylineMaterialAppearance({
|
||||||
|
material: Cesium.Material.fromType('Color', {
|
||||||
|
color: Cesium.Color.fromCssColorString('#fcfc00')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据经纬度和比例尺计算地图图幅编号
|
||||||
|
* @param {number} longitude - 经度(十进制格式)
|
||||||
|
* @param {number} latitude - 纬度(十进制格式)
|
||||||
|
* @param {string} scale - 比例尺(可选值:'1:100万', '1:50万', '1:25万', '1:10万', '1:5万', '1:2.5万', '1:1万', '1:5000')
|
||||||
|
* @returns {string} 对应的图幅编号
|
||||||
|
*/
|
||||||
|
function calculateMapSheetNumber(lng, lat, scale) {
|
||||||
|
let lngStep // 经度步长
|
||||||
|
let latStep // 纬度步长
|
||||||
|
switch (scale) {
|
||||||
|
case '1:100万':
|
||||||
|
lngStep = 6;
|
||||||
|
latStep = 4;
|
||||||
|
break
|
||||||
|
case '1:50万':
|
||||||
|
lngStep = 3;
|
||||||
|
latStep = 2;
|
||||||
|
break
|
||||||
|
case '1:25万':
|
||||||
|
lngStep = 1.5;
|
||||||
|
latStep = 1;
|
||||||
|
break
|
||||||
|
case '1:10万':
|
||||||
|
lngStep = 0.5;
|
||||||
|
latStep = 1 / 3;
|
||||||
|
break
|
||||||
|
case '1:5万':
|
||||||
|
lngStep = 0.25;
|
||||||
|
latStep = 1 / 6;
|
||||||
|
break
|
||||||
|
case '1:2.5万':
|
||||||
|
lngStep = 0.125;
|
||||||
|
latStep = 1 / 12;
|
||||||
|
break
|
||||||
|
case '1:1万':
|
||||||
|
lngStep = 0.0625;
|
||||||
|
latStep = 1 / 24;
|
||||||
|
break
|
||||||
|
case '1:5000':
|
||||||
|
lngStep = 0.03125;
|
||||||
|
latStep = 1 / 48;
|
||||||
|
break
|
||||||
|
// case '1:1000':
|
||||||
|
// lngStep = 0.01041667;
|
||||||
|
// latStep = 0.00694444;
|
||||||
|
// break
|
||||||
|
// case '1:2000':
|
||||||
|
// lngStep = 0.00520833;
|
||||||
|
// latStep = 0.00347222;
|
||||||
|
// break
|
||||||
|
}
|
||||||
|
// 确保纬度在 -88 到 88 度之间(因为 88° 以上采用特殊分幅)
|
||||||
|
lat = Math.max(-88, Math.min(88, lat));
|
||||||
|
lat = Math.abs(lat); // 取绝对值
|
||||||
|
|
||||||
|
let B6 = 'ABCDEFGHIJKLMNOPQRSTUV'
|
||||||
|
let B2 = lng
|
||||||
|
let B3 = lat
|
||||||
|
|
||||||
|
// 计算 1:100 万地形图的列号
|
||||||
|
const col100W = Math.floor(B2 / 6 + 31);
|
||||||
|
// 1:100 万地形图的行号对应的字母(A-V)
|
||||||
|
const rowChar = B6.charAt(Math.floor(B3 / 4 + 1) - 1);
|
||||||
|
|
||||||
|
// 比例尺代码映射
|
||||||
|
const scaleCodeMap = {
|
||||||
|
'1:100万': '', // 1:100万不需要额外代码
|
||||||
|
'1:50万': 'B',
|
||||||
|
'1:25万': 'C',
|
||||||
|
'1:10万': 'D',
|
||||||
|
'1:5万': 'E',
|
||||||
|
'1:2.5万': 'F',
|
||||||
|
'1:1万': 'G',
|
||||||
|
'1:5000': 'H'
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// 获取比例尺代码
|
||||||
|
const scaleCode = scaleCodeMap[scale];
|
||||||
|
if (!scaleCode && scale !== '1:100万') {
|
||||||
|
throw new Error('不支持的比例尺,请使用: 1:100万, 1:50万, 1:25万, 1:10万, 1:5万, 1:2.5万, 1:1万, 1:5000');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算在 1:100 万图幅内的行列号(根据不同比例尺)
|
||||||
|
let rowIn100W, colIn100W;
|
||||||
|
rowIn100W = rowChar + col100W;
|
||||||
|
|
||||||
|
const num1 = Math.floor((Math.ceil(B3 / 4) * 4 - B3) / latStep) + 1;
|
||||||
|
const rowNum = ("000" + num1).slice(-3);
|
||||||
|
const remainder = B2 - Math.floor(B2 / 6) * 6;
|
||||||
|
const num2 = Math.floor(remainder / lngStep) + 1;
|
||||||
|
const colNum = ("000" + num2).slice(-3);
|
||||||
|
|
||||||
|
switch (scale) {
|
||||||
|
case '1:100万':
|
||||||
|
// 1:100万直接使用行号和列号
|
||||||
|
return rowIn100W;
|
||||||
|
case '1:50万':
|
||||||
|
break;
|
||||||
|
case '1:25万':
|
||||||
|
break;
|
||||||
|
case '1:10万':
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '1:5万':
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '1:2.5万':
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '1:1万':
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '1:5000':
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new Error('不支持的比例尺');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生成最终编号
|
||||||
|
return rowIn100W + scaleCode + rowNum + colNum;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取当前视角矩形范围(二维模式)
|
||||||
|
function getViewExtend() {
|
||||||
|
let params = {};
|
||||||
|
let extend = viewer.camera.computeViewRectangle();
|
||||||
|
if (viewer.scene.mode == 2) {
|
||||||
|
//2D下会可能拾取不到坐标,extend返回undefined,所以做以下转换
|
||||||
|
let canvas = viewer.scene.canvas;
|
||||||
|
let upperLeft = new Cesium.Cartesian2(0, 0);//canvas左上角坐标转2d坐标
|
||||||
|
let lowerRight = new Cesium.Cartesian2(
|
||||||
|
canvas.clientWidth,
|
||||||
|
canvas.clientHeight
|
||||||
|
);//canvas右下角坐标转2d坐标
|
||||||
|
|
||||||
|
let ellipsoid = viewer.scene.globe.ellipsoid;
|
||||||
|
let upperLeft3 = viewer.camera.pickEllipsoid(
|
||||||
|
upperLeft,
|
||||||
|
ellipsoid
|
||||||
|
);//2D转3D世界坐标
|
||||||
|
|
||||||
|
let lowerRight3 = viewer.camera.pickEllipsoid(
|
||||||
|
lowerRight,
|
||||||
|
ellipsoid
|
||||||
|
);//2D转3D世界坐标
|
||||||
|
|
||||||
|
if (!upperLeft3) {
|
||||||
|
let cartesian2 = Cesium.SceneTransforms.wgs84ToWindowCoordinates(viewer.scene, { x: 0, y: 0, z: 6356755 });
|
||||||
|
upperLeft.y = cartesian2.y + 5
|
||||||
|
upperLeft3 = viewer.camera.pickEllipsoid(
|
||||||
|
upperLeft,
|
||||||
|
ellipsoid
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (!lowerRight3) {
|
||||||
|
let cartesian2 = Cesium.SceneTransforms.wgs84ToWindowCoordinates(viewer.scene, { x: 0, y: 0, z: -6356755 });
|
||||||
|
lowerRight.y = cartesian2.y - 5
|
||||||
|
lowerRight3 = viewer.camera.pickEllipsoid(
|
||||||
|
lowerRight,
|
||||||
|
ellipsoid
|
||||||
|
);
|
||||||
|
// console.log('lowerRight3', lowerRight, lowerRight3)
|
||||||
|
}
|
||||||
|
let upperLeftCartographic = viewer.scene.globe.ellipsoid.cartesianToCartographic(
|
||||||
|
upperLeft3
|
||||||
|
);//3D世界坐标转弧度
|
||||||
|
let lowerRightCartographic = viewer.scene.globe.ellipsoid.cartesianToCartographic(
|
||||||
|
lowerRight3
|
||||||
|
);//3D世界坐标转弧度
|
||||||
|
|
||||||
|
if ((lowerRight.y - upperLeft.y) / (lowerRight.x - upperLeft.x) <= 0.49998752339363695) {
|
||||||
|
extend = new Cesium.Rectangle(Cesium.Math.toRadians(-180), Cesium.Math.toRadians(-90), Cesium.Math.toRadians(180), Cesium.Math.toRadians(90))
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
extend = new Cesium.Rectangle(upperLeftCartographic.longitude, lowerRightCartographic.latitude, lowerRightCartographic.longitude, upperLeftCartographic.latitude);
|
||||||
|
}
|
||||||
|
|
||||||
|
// console.log("经度:" + minx + "----" + maxx);
|
||||||
|
// console.log("纬度:" + miny + "----" + maxy);
|
||||||
|
|
||||||
|
return extend;
|
||||||
|
} else {
|
||||||
|
//3D获取方式
|
||||||
|
return extend;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
function close(sdk) {
|
||||||
|
let viewer = sdk.viewer;
|
||||||
|
let gridPrimitives
|
||||||
|
let labelCollection
|
||||||
|
for (let i = 0; i < viewer.scene.primitives._primitives.length; i++) {
|
||||||
|
if (viewer.scene.primitives._primitives[i].name === 'SheetIndexGridPrimitives') {
|
||||||
|
gridPrimitives = viewer.scene.primitives._primitives[i];
|
||||||
|
for (let j = 0; j < gridPrimitives._primitives.length; j++) {
|
||||||
|
if (gridPrimitives._primitives[j].name === 'SheetIndexLabelCollection') {
|
||||||
|
labelCollection = gridPrimitives._primitives[j];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
labelCollection && (labelCollection.removeAll());
|
||||||
|
gridPrimitives && (gridPrimitives.removeAll());
|
||||||
|
gridPrimitives && (viewer.scene.postRender.removeEventListener(gridPrimitives.postRenderEvent));
|
||||||
|
}
|
||||||
|
|
||||||
|
export { SheetIndexStatusSwitch, changeScale, getStatus }
|
||||||
30
src/Global/Skin/index.js
Normal file
30
src/Global/Skin/index.js
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
let theme = {
|
||||||
|
"yingguangse": new Map(),
|
||||||
|
"gonganlan": new Map(),
|
||||||
|
"hong": new Map(),
|
||||||
|
}
|
||||||
|
// 主色
|
||||||
|
theme.yingguangse.set("--color-sdk-base", "#00ffff")
|
||||||
|
// 辅色
|
||||||
|
theme.yingguangse.set("--color-sdk-auxiliary", "#004242")
|
||||||
|
theme.yingguangse.set("--color-sdk-auxiliary-public", "#ffffff")
|
||||||
|
// 预警色
|
||||||
|
theme.yingguangse.set("--color-sdk-warning-0", "#1BF8C3")
|
||||||
|
theme.yingguangse.set("--color-sdk-warning-1", "#F16C55")
|
||||||
|
theme.yingguangse.set("--color-sdk-warning-2", "#FFA145")
|
||||||
|
theme.yingguangse.set("--color-sdk-warning-3", "#FFDF53")
|
||||||
|
// 文本色
|
||||||
|
theme.yingguangse.set("--color-sdk-text-head", "#FFFFFF")
|
||||||
|
theme.yingguangse.set("--color-sdk-text-head-1", "#E6F7FF")
|
||||||
|
theme.yingguangse.set("--color-sdk-text-head-2", "#ADF1FF")
|
||||||
|
// 渐变色
|
||||||
|
theme.yingguangse.set("--color-sdk-gradual", "#00ffff 6.25%, #00ffff 100%")
|
||||||
|
theme.yingguangse.set("--color-sdk-bg-gradual", "#00ffff33 0%, #00ffff00 100%")
|
||||||
|
|
||||||
|
export default theme;
|
||||||
|
|
||||||
|
function setSkin(name) {
|
||||||
|
document.documentElement.style.setProperty('--color-sdk-base', 'rgba(0, 55, 55, 1)');
|
||||||
|
}
|
||||||
|
|
||||||
|
export { setSkin }
|
||||||
578
src/Global/SplitScreen/ClickCallback/index.js
Normal file
578
src/Global/SplitScreen/ClickCallback/index.js
Normal file
@ -0,0 +1,578 @@
|
|||||||
|
/**
|
||||||
|
* @name: click
|
||||||
|
* @author: Administrator
|
||||||
|
* @date: 2023-05-28 11:05
|
||||||
|
* @description:click
|
||||||
|
* @update: 2023-05-28 11:05
|
||||||
|
*/
|
||||||
|
let leftClickHandler = null
|
||||||
|
let rightClickHandler = null
|
||||||
|
let MoveHandler = null
|
||||||
|
let leftClickCallbackMap = new Map()
|
||||||
|
let rightClickCallbackMap = new Map()
|
||||||
|
let MoveCallbackMap = new Map()
|
||||||
|
let selectedFeature;
|
||||||
|
|
||||||
|
|
||||||
|
function cartesian3Towgs84(cartesian, viewer) {
|
||||||
|
var ellipsoid = viewer.scene.globe.ellipsoid
|
||||||
|
var cartesian3 = new Cesium.Cartesian3(
|
||||||
|
cartesian.x,
|
||||||
|
cartesian.y,
|
||||||
|
cartesian.z
|
||||||
|
)
|
||||||
|
var cartographic = ellipsoid.cartesianToCartographic(cartesian3)
|
||||||
|
var lat = Cesium.Math.toDegrees(cartographic.latitude)
|
||||||
|
var lng = Cesium.Math.toDegrees(cartographic.longitude)
|
||||||
|
var alt = cartographic.height < 0 ? 0 : cartographic.height
|
||||||
|
return {
|
||||||
|
lng: lng,
|
||||||
|
lat: lat,
|
||||||
|
alt: alt,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getcartesian(sdk, movement) {
|
||||||
|
if (movement.endPosition) {
|
||||||
|
movement.endPosition.y -= 2
|
||||||
|
}
|
||||||
|
let position = movement.position || movement.endPosition
|
||||||
|
// 获取世界坐标系地表坐标,考虑地形,不包括模型,倾斜摄影模型表面;
|
||||||
|
let cartesian = sdk.viewer.scene.pickPosition(position)
|
||||||
|
if (!cartesian) {
|
||||||
|
const ray = sdk.viewer.camera.getPickRay(position); //相交的射线
|
||||||
|
cartesian = sdk.viewer.scene.globe.pick(ray, sdk.viewer.scene);
|
||||||
|
}
|
||||||
|
return cartesian
|
||||||
|
}
|
||||||
|
|
||||||
|
function openLeftClick(sdk, cb) {
|
||||||
|
if (!sdk || !sdk.viewer) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let click = true
|
||||||
|
leftClickHandler = new Cesium.ScreenSpaceEventHandler(sdk.viewer.canvas)
|
||||||
|
leftClickHandler.setInputAction((movement) => {
|
||||||
|
let cartesian = sdk.viewer.scene.pickPosition(movement.position)
|
||||||
|
if (!cartesian) {
|
||||||
|
const ray = sdk.viewer.camera.getPickRay(movement.position); //相交的射线
|
||||||
|
cartesian = sdk.viewer.scene.globe.pick(ray, sdk.viewer.scene);
|
||||||
|
}
|
||||||
|
if (!cartesian) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let pos84 = cartesian3Towgs84(cartesian, sdk.viewer)
|
||||||
|
|
||||||
|
cb && cb(pos84)
|
||||||
|
|
||||||
|
if (click) {
|
||||||
|
click = false
|
||||||
|
setTimeout(() => {
|
||||||
|
click = true
|
||||||
|
}, 600);
|
||||||
|
if (!YJ.Measure.GetMeasureStatus() && cartesian) {
|
||||||
|
let flag = false
|
||||||
|
for (let i = leftClickCallbackMap.size - 1; i >= 0; i--) {
|
||||||
|
let key = Array.from(leftClickCallbackMap.keys())[i]
|
||||||
|
let obj = leftClickCallbackMap.get(key)
|
||||||
|
if (obj) {
|
||||||
|
|
||||||
|
if (obj.that) {
|
||||||
|
// 是否为多边形
|
||||||
|
if (obj.that.type === 'PolygonObject') {
|
||||||
|
// 是否可点击y
|
||||||
|
if (obj.that.picking) {
|
||||||
|
if (obj.that.options.positions && obj.that.options.positions.length >= 3) {
|
||||||
|
let pt = turf.point([pos84.lng, pos84.lat]);
|
||||||
|
let polyPos = []
|
||||||
|
for (let i = 0; i < obj.that.options.positions.length; i++) {
|
||||||
|
polyPos.push([
|
||||||
|
obj.that.options.positions[i].lng,
|
||||||
|
obj.that.options.positions[i].lat
|
||||||
|
])
|
||||||
|
}
|
||||||
|
polyPos.push([
|
||||||
|
obj.that.options.positions[0].lng,
|
||||||
|
obj.that.options.positions[0].lat
|
||||||
|
])
|
||||||
|
let poly = turf.polygon([polyPos]);
|
||||||
|
let contain = turf.booleanPointInPolygon(pt, poly);
|
||||||
|
if (contain) {
|
||||||
|
obj.callback(
|
||||||
|
movement,
|
||||||
|
obj.that.options.id,
|
||||||
|
cartesian3Towgs84(getcartesian(sdk, movement), sdk.viewer), obj.that)
|
||||||
|
flag = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 聚集地
|
||||||
|
else if (obj.that.type === 'AssembleObject') {
|
||||||
|
if (obj.that.picking) {
|
||||||
|
if (obj.that.options.positions && obj.that.options.positions.length >= 3) {
|
||||||
|
let positions = obj.that.computeAssemble(obj.that.options.positions, true)
|
||||||
|
let pt = turf.point([pos84.lng, pos84.lat]);
|
||||||
|
let polyPos = []
|
||||||
|
for (let i = 0; i < positions.length; i += 2) {
|
||||||
|
polyPos.push([
|
||||||
|
positions[i],
|
||||||
|
positions[i + 1]
|
||||||
|
])
|
||||||
|
}
|
||||||
|
let poly = turf.polygon([polyPos]);
|
||||||
|
let contain = turf.booleanPointInPolygon(pt, poly);
|
||||||
|
if (contain) {
|
||||||
|
obj.callback(
|
||||||
|
movement,
|
||||||
|
obj.that.options.id,
|
||||||
|
cartesian3Towgs84(getcartesian(sdk, movement), sdk.viewer), obj.that)
|
||||||
|
flag = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 单箭头
|
||||||
|
else if (obj.that.type === 'AttackArrowObject') {
|
||||||
|
if (obj.that.picking) {
|
||||||
|
if (obj.that.options.positions && obj.that.options.positions.length >= 3) {
|
||||||
|
let pt = turf.point([pos84.lng, pos84.lat]);
|
||||||
|
let positions = obj.that.computeAttackArrow(obj.that.options.positions)
|
||||||
|
let polyPos = []
|
||||||
|
for (let m = 0; m < positions.length; m++) {
|
||||||
|
let pos84 = cartesian3Towgs84(positions[m], sdk.viewer)
|
||||||
|
polyPos.push([pos84.lng, pos84.lat])
|
||||||
|
}
|
||||||
|
let poly = turf.polygon([polyPos]);
|
||||||
|
let contain = turf.booleanPointInPolygon(pt, poly);
|
||||||
|
if (contain) {
|
||||||
|
obj.callback(
|
||||||
|
movement,
|
||||||
|
obj.that.options.id,
|
||||||
|
cartesian3Towgs84(getcartesian(sdk, movement), sdk.viewer), obj.that)
|
||||||
|
flag = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 双箭头
|
||||||
|
else if (obj.that.type === 'PincerArrowObject') {
|
||||||
|
if (obj.that.picking) {
|
||||||
|
if (obj.that.options.positions && obj.that.options.positions.length >= 5) {
|
||||||
|
let pt = turf.point([pos84.lng, pos84.lat]);
|
||||||
|
let positions = obj.that.computePincerArrow(obj.that.options.positions)
|
||||||
|
let polyPos = []
|
||||||
|
for (let m = 0; m < positions.length; m++) {
|
||||||
|
let pos84 = cartesian3Towgs84(positions[m], sdk.viewer)
|
||||||
|
polyPos.push([pos84.lng, pos84.lat])
|
||||||
|
}
|
||||||
|
let pos84_0 = cartesian3Towgs84(positions[0], sdk.viewer)
|
||||||
|
polyPos.push([pos84_0.lng, pos84_0.lat])
|
||||||
|
let poly = turf.polygon([polyPos]);
|
||||||
|
let contain = turf.booleanPointInPolygon(pt, poly);
|
||||||
|
if (contain) {
|
||||||
|
obj.callback(
|
||||||
|
movement,
|
||||||
|
obj.that.options.id,
|
||||||
|
cartesian3Towgs84(getcartesian(sdk, movement), sdk.viewer), obj.that)
|
||||||
|
flag = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 圆
|
||||||
|
else if (obj.that.type === 'CircleObject') {
|
||||||
|
if (obj.that.picking) {
|
||||||
|
let pt = turf.point([pos84.lng, pos84.lat]);
|
||||||
|
if (obj.that.options.center && obj.that.options.radius) {
|
||||||
|
let center = [obj.that.options.center.lng, obj.that.options.center.lat];
|
||||||
|
let radius = obj.that.options.radius / 1000;
|
||||||
|
let options = { steps: 360, units: 'kilometers' };
|
||||||
|
let circle = turf.circle(center, radius, options);
|
||||||
|
let contain = turf.booleanPointInPolygon(pt, circle);
|
||||||
|
if (contain) {
|
||||||
|
obj.callback(
|
||||||
|
movement,
|
||||||
|
obj.that.options.id,
|
||||||
|
cartesian3Towgs84(getcartesian(sdk, movement), sdk.viewer), obj.that)
|
||||||
|
flag = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 扇形
|
||||||
|
else if (obj.that.type === 'SectorObject') {
|
||||||
|
if (obj.that.picking) {
|
||||||
|
let pt = turf.point([pos84.lng, pos84.lat]);
|
||||||
|
if (obj.that.options.center && obj.that.options.radius && obj.that.options.startAngle && obj.that.options.endAngle) {
|
||||||
|
let positions = obj.that.calSector(obj.that.options.center, obj.that.options.radius, obj.that.options.startAngle, obj.that.options.endAngle, undefined, true)
|
||||||
|
let polyPos = []
|
||||||
|
for (let m = 0; m < positions.length; m++) {
|
||||||
|
polyPos.push([positions[m].lng, positions[m].lat])
|
||||||
|
}
|
||||||
|
let poly = turf.polygon([polyPos]);
|
||||||
|
let contain = turf.booleanPointInPolygon(pt, poly);
|
||||||
|
if (contain) {
|
||||||
|
obj.callback(
|
||||||
|
movement,
|
||||||
|
obj.that.options.id,
|
||||||
|
cartesian3Towgs84(getcartesian(sdk, movement), sdk.viewer), obj.that)
|
||||||
|
flag = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!flag) {
|
||||||
|
const pick = sdk.viewer.scene.pick(movement.position)
|
||||||
|
if (pick) {
|
||||||
|
if (pick.id) {
|
||||||
|
let entityId
|
||||||
|
// 矢量
|
||||||
|
if (pick.id.type && pick.id.type === 'vector' && pick.id.parentId) {
|
||||||
|
let obj = leftClickCallbackMap.get(pick.id.parentId)
|
||||||
|
if (obj.that.picking && obj.that.geojson) {
|
||||||
|
for (let i = 0; i < obj.that.geojson.features.length; i++) {
|
||||||
|
if (obj.that.geojson.features[i].id === pick.id._id) {
|
||||||
|
obj.callback(
|
||||||
|
movement,
|
||||||
|
obj.that.geojson.features[i].id,
|
||||||
|
cartesian3Towgs84(getcartesian(sdk, movement), sdk.viewer), obj.that)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (typeof pick.id.id == 'string') {
|
||||||
|
let array = pick.id.id.split('-')
|
||||||
|
array.splice(array.length - 1, 1)
|
||||||
|
entityId = array.join('-')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pick.id.properties && pick.id.properties.id && leftClickCallbackMap.has(pick.id.properties.id._value)) {
|
||||||
|
let obj = leftClickCallbackMap.get(pick.id.properties.id._value)
|
||||||
|
if (obj.that.picking) {
|
||||||
|
obj.callback(
|
||||||
|
movement,
|
||||||
|
pick.id.properties.id._value,
|
||||||
|
cartesian3Towgs84(getcartesian(sdk, movement), sdk.viewer), obj.that)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (leftClickCallbackMap.has(pick.id.id)) {
|
||||||
|
let obj = leftClickCallbackMap.get(pick.id.id)
|
||||||
|
if (obj.that.picking) {
|
||||||
|
obj.callback(
|
||||||
|
movement,
|
||||||
|
pick.id.id,
|
||||||
|
cartesian3Towgs84(getcartesian(sdk, movement), sdk.viewer), obj.that)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (entityId && leftClickCallbackMap.has(entityId)) {
|
||||||
|
let obj = leftClickCallbackMap.get(entityId)
|
||||||
|
if (obj.that.picking) {
|
||||||
|
obj.callback(
|
||||||
|
movement,
|
||||||
|
entityId,
|
||||||
|
cartesian3Towgs84(getcartesian(sdk, movement), sdk.viewer), obj.that)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (pick.primitive) {
|
||||||
|
if (typeof pick.id == 'string' && leftClickCallbackMap.has(pick.id)) {
|
||||||
|
let obj = leftClickCallbackMap.get(pick.id)
|
||||||
|
obj.callback(
|
||||||
|
movement,
|
||||||
|
pick.id,
|
||||||
|
cartesian3Towgs84(getcartesian(sdk, movement), sdk.viewer), obj.that)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (pick.primitive && pick.primitive.id) {
|
||||||
|
if (leftClickCallbackMap.has(pick.primitive.id)) {
|
||||||
|
let obj = leftClickCallbackMap.get(pick.primitive.id)
|
||||||
|
if (obj.that.picking) {
|
||||||
|
if (obj.that.type === 'bim') {
|
||||||
|
if (YJ.Global.getBimPickStatus(sdk)) {
|
||||||
|
obj.callback(
|
||||||
|
movement,
|
||||||
|
pick.primitive,
|
||||||
|
cartesian3Towgs84(getcartesian(sdk, movement), sdk.viewer), obj.that)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
obj.callback(
|
||||||
|
movement,
|
||||||
|
pick.primitive.id,
|
||||||
|
cartesian3Towgs84(getcartesian(sdk, movement), sdk.viewer), obj.that)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pick.content && (!pick.primitive || !pick.primitive.id)) {
|
||||||
|
if (leftClickCallbackMap.has(pick.content.tileset.id)) {
|
||||||
|
let obj = leftClickCallbackMap.get(pick.content.tileset.id)
|
||||||
|
if (obj.that.picking) {
|
||||||
|
if (obj.that.type === 'bim') {
|
||||||
|
if (YJ.Global.getBimPickStatus(sdk)) {
|
||||||
|
obj.callback(
|
||||||
|
movement,
|
||||||
|
pick.content.tileset,
|
||||||
|
cartesian3Towgs84(getcartesian(sdk, movement), sdk.viewer), obj.that)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
obj.callback(
|
||||||
|
movement,
|
||||||
|
pick.content.tileset.id,
|
||||||
|
cartesian3Towgs84(getcartesian(sdk, movement), sdk.viewer), obj.that)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// if (click) {
|
||||||
|
// click = false
|
||||||
|
// setTimeout(() => {
|
||||||
|
// click = true
|
||||||
|
// }, 300);
|
||||||
|
// if (!YJ.Measure.GetMeasureStatus()) {
|
||||||
|
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}, Cesium.ScreenSpaceEventType.LEFT_CLICK)
|
||||||
|
|
||||||
|
// leftClickHandler.setInputAction(function (movement) {
|
||||||
|
// const feature = sdk.viewer.scene.pick(movement.endPosition);
|
||||||
|
// // unselectFeature(selectedFeature);
|
||||||
|
// if (selectedFeature) {
|
||||||
|
// selectedFeature.color = Cesium.Color.WHITE;
|
||||||
|
// }
|
||||||
|
// selectedFeature = feature
|
||||||
|
// if (feature) {
|
||||||
|
// feature.color = Cesium.Color.YELLOW;
|
||||||
|
// }
|
||||||
|
// }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
|
||||||
|
// }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeLeftClick(sdk) {
|
||||||
|
leftClickHandler.destroy() //关闭事件句柄
|
||||||
|
leftClickHandler = null
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
function openRightClick(sdk) {
|
||||||
|
if (!sdk || !sdk.viewer) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
rightClickHandler = new Cesium.ScreenSpaceEventHandler(sdk.viewer.canvas)
|
||||||
|
rightClickHandler.setInputAction((movement) => {
|
||||||
|
if (!YJ.Measure.GetMeasureStatus()) {
|
||||||
|
const pick = sdk.viewer.scene.pick(movement.position)
|
||||||
|
if (pick && pick.id) {
|
||||||
|
let id
|
||||||
|
if (pick.id.type && pick.id.type === 'vector' && pick.id.parentId) {
|
||||||
|
let obj = rightClickCallbackMap.get(pick.id.parentId)
|
||||||
|
if (obj.that.picking && obj.that.geojson) {
|
||||||
|
for (let i = 0; i < obj.that.geojson.features.length; i++) {
|
||||||
|
if (obj.that.geojson.features[i].id === pick.id._id) {
|
||||||
|
obj.callback(
|
||||||
|
movement,
|
||||||
|
obj.that.geojson.features[i].id,
|
||||||
|
cartesian3Towgs84(getcartesian(sdk, movement), sdk.viewer), obj.that)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (typeof pick.id === 'string') {
|
||||||
|
id = pick.id
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
id = pick.id.id
|
||||||
|
}
|
||||||
|
if (rightClickCallbackMap.has(id)) {
|
||||||
|
let obj = rightClickCallbackMap.get(id)
|
||||||
|
if (obj.that.picking) {
|
||||||
|
let cartesian = getcartesian(sdk, movement)
|
||||||
|
if (!cartesian) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
obj.callback(
|
||||||
|
movement,
|
||||||
|
id,
|
||||||
|
cartesian3Towgs84(cartesian, sdk.viewer), obj.that)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pick && pick.content) {
|
||||||
|
if (rightClickCallbackMap.has(pick.content.tileset.id)) {
|
||||||
|
let obj = rightClickCallbackMap.get(pick.content.tileset.id)
|
||||||
|
if (obj.that.picking) {
|
||||||
|
if (obj.that.type === 'bim') {
|
||||||
|
if (YJ.Global.getBimPickStatus(sdk)) {
|
||||||
|
let cartesian = getcartesian(sdk, movement)
|
||||||
|
if (!cartesian) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
obj.callback(
|
||||||
|
movement,
|
||||||
|
pick.getProperty('id'),
|
||||||
|
cartesian3Towgs84(cartesian, sdk.viewer), obj.that)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
let cartesian = getcartesian(sdk, movement)
|
||||||
|
if (!cartesian) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
obj.callback(
|
||||||
|
movement,
|
||||||
|
pick.content.tileset.id,
|
||||||
|
cartesian3Towgs84(cartesian, sdk.viewer), obj.that)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK)
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeRightClick() {
|
||||||
|
if (rightClickHandler) {
|
||||||
|
rightClickHandler.destroy() //关闭事件句柄
|
||||||
|
rightClickHandler = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function openMove(sdk) {
|
||||||
|
MoveHandler = new Cesium.ScreenSpaceEventHandler(sdk.viewer.canvas)
|
||||||
|
MoveHandler.setInputAction(function (movement) {
|
||||||
|
const pick = sdk.viewer.scene.pick(movement.endPosition);
|
||||||
|
// unselectFeature(selectedFeature);
|
||||||
|
// if (selectedFeature) {
|
||||||
|
// let color = '#fff'
|
||||||
|
// let state = selectedFeature.getProperty('state')
|
||||||
|
// switch (state) {
|
||||||
|
// case '0':
|
||||||
|
// color = '#fff'
|
||||||
|
// break;
|
||||||
|
// case '1':
|
||||||
|
// color = '#f00'
|
||||||
|
// break;
|
||||||
|
// case '2':
|
||||||
|
// color = '#0f0'
|
||||||
|
// break;
|
||||||
|
// case '3':
|
||||||
|
// color = '#00f'
|
||||||
|
// break;
|
||||||
|
// default:
|
||||||
|
// }
|
||||||
|
// selectedFeature.color = Cesium.Color.fromCssColorString(color).withAlpha(selectedFeature.tileset.transparency)
|
||||||
|
// }
|
||||||
|
// if (pick && pick.id) { }
|
||||||
|
// if (pick && pick.content) {
|
||||||
|
// if (MoveCallbackMap.has(pick.content.tileset.id)) {
|
||||||
|
// let obj = MoveCallbackMap.get(pick.content.tileset.id)
|
||||||
|
// if (obj.that.picking) {
|
||||||
|
// if (obj.that.type === 'bim') {
|
||||||
|
// if (YJ.Global.getBimPickStatus(sdk)) {
|
||||||
|
// selectedFeature = pick
|
||||||
|
// pick.color = Cesium.Color.YELLOW;
|
||||||
|
// }
|
||||||
|
// else {
|
||||||
|
// selectedFeature = null
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// else {
|
||||||
|
// selectedFeature = pick
|
||||||
|
// pick.color = Cesium.Color.YELLOW;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// else {
|
||||||
|
// selectedFeature = null
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeMove() {
|
||||||
|
if (MoveHandler) {
|
||||||
|
MoveHandler.destroy() //关闭事件句柄
|
||||||
|
MoveHandler = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*注册左键回调*/
|
||||||
|
function regLeftClickCallback(id, callback, that) {
|
||||||
|
|
||||||
|
leftClickCallbackMap.set(id, { callback, that })
|
||||||
|
}/*取消左键回调*/
|
||||||
|
function unRegLeftClickCallback(id,) {
|
||||||
|
leftClickCallbackMap.delete(id,)
|
||||||
|
}
|
||||||
|
|
||||||
|
/*注册右键回调*/
|
||||||
|
function regRightClickCallback(id, callback, that) {
|
||||||
|
rightClickCallbackMap.set(id, { callback, that })
|
||||||
|
}/*取消右键回调*/
|
||||||
|
function unRegRightClickCallback(id,) {
|
||||||
|
rightClickCallbackMap.delete(id,)
|
||||||
|
}
|
||||||
|
|
||||||
|
/*注册左键回调*/
|
||||||
|
function regMoveCallback(id, callback, that) {
|
||||||
|
MoveCallbackMap.set(id, { callback, that })
|
||||||
|
}/*取消左键回调*/
|
||||||
|
function unregMoveCallback(id,) {
|
||||||
|
MoveCallbackMap.delete(id,)
|
||||||
|
}
|
||||||
|
|
||||||
|
function getLeftClickState() {
|
||||||
|
if (leftClickHandler) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getRightClickState() {
|
||||||
|
if (rightClickHandler) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getMoveState() {
|
||||||
|
if (MoveHandler) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export { openLeftClick, closeLeftClick, regLeftClickCallback, unRegLeftClickCallback, openRightClick, closeRightClick, regRightClickCallback, unRegRightClickCallback, openMove, closeMove, regMoveCallback, unregMoveCallback, getLeftClickState, getRightClickState, getMoveState }
|
||||||
1441
src/Global/SplitScreen/index.js
Normal file
1441
src/Global/SplitScreen/index.js
Normal file
File diff suppressed because it is too large
Load Diff
366
src/Global/cluster/cluster.js
Normal file
366
src/Global/cluster/cluster.js
Normal file
@ -0,0 +1,366 @@
|
|||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
let datasource=null
|
||||||
|
let dataSourcePromise = null
|
||||||
|
// let enabled = true
|
||||||
|
let dataSourcexg = null
|
||||||
|
function createCluster(viewer) {
|
||||||
|
datasource = new Cesium.CustomDataSource("dataSource1");
|
||||||
|
dataSourcePromise = viewer.dataSources.add(datasource);
|
||||||
|
dataSourcePromise.then((dataSource)=> {
|
||||||
|
// return;
|
||||||
|
const pixelRange = 15;
|
||||||
|
const minimumClusterSize = 3;
|
||||||
|
const enabled = false;
|
||||||
|
dataSourcexg = dataSource
|
||||||
|
|
||||||
|
dataSource.clustering.enabled = enabled; //聚合开启
|
||||||
|
dataSource.clustering.pixelRange = pixelRange; //设置像素范围,以扩展显示边框
|
||||||
|
dataSource.clustering.minimumClusterSize = minimumClusterSize; //设置最小的聚合点数目,超过此数目才能聚合
|
||||||
|
|
||||||
|
let removeListener;
|
||||||
|
|
||||||
|
//按聚合层级创建对应图标
|
||||||
|
const pinBuilder = new Cesium.PinBuilder();
|
||||||
|
// console.log('pinBuilder',pinBuilder);
|
||||||
|
var pin100 = pinBuilder
|
||||||
|
.fromText("100+", Cesium.Color.BLUE, 48)
|
||||||
|
.toDataURL();
|
||||||
|
var pin50 = pinBuilder
|
||||||
|
.fromText("50+", Cesium.Color.BLUE, 48)
|
||||||
|
.toDataURL();
|
||||||
|
var pin40 = pinBuilder
|
||||||
|
.fromText("40+", Cesium.Color.RED, 48)
|
||||||
|
.toDataURL();
|
||||||
|
var pin30 = pinBuilder
|
||||||
|
.fromText("30+", Cesium.Color.RED, 48)
|
||||||
|
.toDataURL();
|
||||||
|
var pin20 = pinBuilder
|
||||||
|
.fromText("20+", Cesium.Color.RED, 48)
|
||||||
|
.toDataURL();
|
||||||
|
var pin10 = pinBuilder
|
||||||
|
.fromText("10+", Cesium.Color.RED, 48)
|
||||||
|
.toDataURL();
|
||||||
|
// 10以内聚合图标
|
||||||
|
const singleDigitPins = new Array(8);
|
||||||
|
for (let i = 0; i < singleDigitPins.length; ++i) {
|
||||||
|
singleDigitPins[i] = pinBuilder
|
||||||
|
.fromText(`${i + 2}`, Cesium.Color.VIOLET, 48)
|
||||||
|
.toDataURL();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function customStyle() {
|
||||||
|
if (Cesium.defined(removeListener)) {
|
||||||
|
removeListener();
|
||||||
|
removeListener = undefined;
|
||||||
|
} else {
|
||||||
|
removeListener = dataSource.clustering.clusterEvent.addEventListener(
|
||||||
|
function(clusteredEntities, cluster) {
|
||||||
|
cluster.label.show = false;
|
||||||
|
cluster.billboard.show = true;
|
||||||
|
cluster.billboard.id = cluster.label.id;
|
||||||
|
cluster.billboard.verticalOrigin = Cesium.VerticalOrigin.BOTTOM;
|
||||||
|
if (clusteredEntities.length >= 100) {
|
||||||
|
cluster.billboard.image = pin100;
|
||||||
|
} else if (clusteredEntities.length >= 50) {
|
||||||
|
cluster.billboard.image = pin50;
|
||||||
|
} else if (clusteredEntities.length >= 40) {
|
||||||
|
cluster.billboard.image = pin40;
|
||||||
|
} else if (clusteredEntities.length >= 30) {
|
||||||
|
cluster.billboard.image = pin30;
|
||||||
|
} else if (clusteredEntities.length >= 20) {
|
||||||
|
cluster.billboard.image = pin20;
|
||||||
|
} else if (clusteredEntities.length >= 10) {
|
||||||
|
cluster.billboard.image = pin10;
|
||||||
|
} else {
|
||||||
|
cluster.billboard.image =
|
||||||
|
singleDigitPins[clusteredEntities.length - 2];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// force a re-cluster with the new styling
|
||||||
|
const pixelRange = dataSource.clustering.pixelRange;
|
||||||
|
dataSource.clustering.pixelRange = 0;
|
||||||
|
dataSource.clustering.pixelRange = pixelRange;
|
||||||
|
}
|
||||||
|
|
||||||
|
customStyle();
|
||||||
|
|
||||||
|
var viewModel = {
|
||||||
|
pixelRange: pixelRange,
|
||||||
|
minimumClusterSize: minimumClusterSize,
|
||||||
|
};
|
||||||
|
Cesium.knockout.track(viewModel);
|
||||||
|
|
||||||
|
|
||||||
|
function subscribeParameter(name) {
|
||||||
|
Cesium.knockout
|
||||||
|
.getObservable(viewModel, name)
|
||||||
|
.subscribe(function (newValue) {
|
||||||
|
dataSource.clustering[name] = newValue;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
subscribeParameter("pixelRange");
|
||||||
|
subscribeParameter("minimumClusterSize");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function addCluster(entity) {
|
||||||
|
datasource.entities.add(entity)
|
||||||
|
}
|
||||||
|
function remove_entity_from_cluster(entity) {
|
||||||
|
datasource.entities.remove(entity)
|
||||||
|
}
|
||||||
|
|
||||||
|
function switchCluster(status){
|
||||||
|
dataSourcexg.clustering.enabled = status
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
import Tools from '../../Tools'
|
||||||
|
import {
|
||||||
|
getGroundCover
|
||||||
|
} from '../../Global/global'
|
||||||
|
|
||||||
|
|
||||||
|
/*创建聚合,只能聚合point ,billboard,label*/
|
||||||
|
function createCluster(viewer) {
|
||||||
|
let tools = new Tools()
|
||||||
|
let cluster = new Cesium.CustomDataSource("sdk-dataSource1")
|
||||||
|
let dataSourcePromise = viewer.dataSources.add(cluster)
|
||||||
|
dataSourcePromise.then(dataSource => {
|
||||||
|
// if (!get2DView()) {
|
||||||
|
// dataSource.entities.collectionChanged.addEventListener((entities) => {
|
||||||
|
// syncDataSources(dataSource, 'entities')
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
var pixelRange = 15;
|
||||||
|
var minimumClusterSize = 2;
|
||||||
|
var enabled = false;
|
||||||
|
dataSource.clustering.enabled = enabled;
|
||||||
|
dataSource.clustering.pixelRange = pixelRange;
|
||||||
|
dataSource.clustering.minimumClusterSize = minimumClusterSize;
|
||||||
|
var removeListener;
|
||||||
|
|
||||||
|
var pinBuilder = new Cesium.PinBuilder();
|
||||||
|
var pin50 = pinBuilder
|
||||||
|
.fromText("50+", Cesium.Color.RED, 48)
|
||||||
|
.toDataURL();
|
||||||
|
var pin40 = pinBuilder
|
||||||
|
.fromText("40+", Cesium.Color.ORANGE, 48)
|
||||||
|
.toDataURL();
|
||||||
|
var pin30 = pinBuilder
|
||||||
|
.fromText("30+", Cesium.Color.YELLOW, 48)
|
||||||
|
.toDataURL();
|
||||||
|
var pin20 = pinBuilder
|
||||||
|
.fromText("20+", Cesium.Color.GREEN, 48)
|
||||||
|
.toDataURL();
|
||||||
|
var pin10 = pinBuilder
|
||||||
|
.fromText("10+", Cesium.Color.BLUE, 48)
|
||||||
|
.toDataURL();
|
||||||
|
|
||||||
|
var singleDigitPins = new Array(8);
|
||||||
|
for (var i = 0; i < singleDigitPins.length; ++i) {
|
||||||
|
singleDigitPins[i] = pinBuilder
|
||||||
|
.fromText("" + (i + 2), Cesium.Color.VIOLET, 48)
|
||||||
|
.toDataURL();
|
||||||
|
}
|
||||||
|
|
||||||
|
function customStyle() {
|
||||||
|
if (Cesium.defined(removeListener)) {
|
||||||
|
removeListener();
|
||||||
|
removeListener = undefined;
|
||||||
|
} else {
|
||||||
|
removeListener = dataSource.clustering.clusterEvent.addEventListener(
|
||||||
|
function (clusteredEntities, cluster) {
|
||||||
|
// cluster.label.show = false;
|
||||||
|
// cluster.label.verticalOrigin = false;
|
||||||
|
cluster.billboard.show = true;
|
||||||
|
cluster.billboard.id = cluster.label.id;
|
||||||
|
cluster.billboard.verticalOrigin =
|
||||||
|
Cesium.VerticalOrigin.BOTTOM;
|
||||||
|
// 根据聚合数量的多少设置不同层级的图片以及大小
|
||||||
|
/*if (clusteredEntities.length >= 50) {
|
||||||
|
cluster.billboard.image = that.combineIconAndLabel(host + '1_大红.png', clusteredEntities.length, 64);
|
||||||
|
cluster.billboard.width = 72;
|
||||||
|
cluster.billboard.height = 72;
|
||||||
|
} else if (clusteredEntities.length >= 40) {
|
||||||
|
cluster.billboard.image = that.combineIconAndLabel(host + '1_大黄.png', clusteredEntities.length, 64);
|
||||||
|
cluster.billboard.width = 56;
|
||||||
|
cluster.billboard.height = 56;
|
||||||
|
} else if (clusteredEntities.length >= 30) {
|
||||||
|
cluster.billboard.image = that.combineIconAndLabel(host + '1_大蓝.png', clusteredEntities.length, 64);
|
||||||
|
cluster.billboard.width = 48;
|
||||||
|
cluster.billboard.height = 48;
|
||||||
|
} else if (clusteredEntities.length >= 20) {
|
||||||
|
cluster.billboard.image = that.combineIconAndLabel(host + '1_小红.png', clusteredEntities.length, 64);
|
||||||
|
cluster.billboard.width = 48;
|
||||||
|
cluster.billboard.height = 48;
|
||||||
|
} else if (clusteredEntities.length >= 10) {
|
||||||
|
cluster.billboard.image = that.combineIconAndLabel(host + '1_小黄.png', clusteredEntities.length, 64);
|
||||||
|
cluster.billboard.width = 48;
|
||||||
|
cluster.billboard.height = 48;
|
||||||
|
} else {
|
||||||
|
cluster.billboard.image = that.combineIconAndLabel(host + '1_小蓝.png', clusteredEntities.length, 64);
|
||||||
|
cluster.billboard.width = 40;
|
||||||
|
cluster.billboard.height = 40;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
|
||||||
|
cluster.billboard.image = tools.getSourceRootPath() + '/img/cluster.png'
|
||||||
|
cluster.billboard.disableDepthTestDistance = getGroundCover() ? undefined : Number.POSITIVE_INFINITY
|
||||||
|
|
||||||
|
cluster.label.verticalOrigin = Cesium.VerticalOrigin.CENTER
|
||||||
|
cluster.label.font = "18px Arial,sans-serif",
|
||||||
|
// cluster.label.scale = 0.5
|
||||||
|
cluster.label.disableDepthTestDistance = getGroundCover() ? undefined : Number.POSITIVE_INFINITY
|
||||||
|
cluster.label.style = Cesium.LabelStyle.FILL
|
||||||
|
cluster.label.showBackground = true
|
||||||
|
cluster.label.backgroundColor = Cesium.Color.WHITE.withAlpha(0.0)
|
||||||
|
|
||||||
|
if (clusteredEntities.length >= 1000) {
|
||||||
|
cluster.billboard.scale = 1.5;
|
||||||
|
cluster.label.pixelOffset = new Cesium.Cartesian2(-28, -46)
|
||||||
|
} else if (clusteredEntities.length >= 100) {
|
||||||
|
cluster.billboard.scale = 1.25;
|
||||||
|
cluster.label.pixelOffset = new Cesium.Cartesian2(-21, -40)
|
||||||
|
} else if (clusteredEntities.length >= 50) {
|
||||||
|
cluster.billboard.scale = 1.1;
|
||||||
|
cluster.label.pixelOffset = new Cesium.Cartesian2(-16, -36)
|
||||||
|
} else if (clusteredEntities.length >= 40) {
|
||||||
|
cluster.billboard.scale = 1.05;
|
||||||
|
cluster.label.pixelOffset = new Cesium.Cartesian2(-16, -34)
|
||||||
|
} else if (clusteredEntities.length >= 30) {
|
||||||
|
cluster.billboard.scale = 1;
|
||||||
|
cluster.label.pixelOffset = new Cesium.Cartesian2(-16, -32)
|
||||||
|
} else if (clusteredEntities.length >= 20) {
|
||||||
|
cluster.billboard.scale = 0.95;
|
||||||
|
cluster.label.pixelOffset = new Cesium.Cartesian2(-16, -30)
|
||||||
|
} else if (clusteredEntities.length >= 10) {
|
||||||
|
cluster.billboard.scale = 0.9;
|
||||||
|
cluster.label.pixelOffset = new Cesium.Cartesian2(-16, -28)
|
||||||
|
} else {
|
||||||
|
cluster.billboard.scale = 0.8;
|
||||||
|
cluster.label.pixelOffset = new Cesium.Cartesian2(-11, -25)
|
||||||
|
}
|
||||||
|
|
||||||
|
// if (clusteredEntities.length >= 50) {
|
||||||
|
// cluster.billboard.image = pin50;
|
||||||
|
// } else if (clusteredEntities.length >= 40) {
|
||||||
|
// cluster.billboard.image = pin40;
|
||||||
|
// } else if (clusteredEntities.length >= 30) {
|
||||||
|
// cluster.billboard.image = pin30;
|
||||||
|
// } else if (clusteredEntities.length >= 20) {
|
||||||
|
// cluster.billboard.image = pin20;
|
||||||
|
// } else if (clusteredEntities.length >= 10) {
|
||||||
|
// cluster.billboard.image = pin10;
|
||||||
|
// } else {
|
||||||
|
// cluster.billboard.image =
|
||||||
|
// singleDigitPins[clusteredEntities.length - 2];
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// force a re-cluster with the new styling
|
||||||
|
var pixelRange = dataSource.clustering.pixelRange;
|
||||||
|
dataSource.clustering.pixelRange = 0;
|
||||||
|
dataSource.clustering.pixelRange = pixelRange;
|
||||||
|
}
|
||||||
|
|
||||||
|
// start with custom style
|
||||||
|
customStyle();
|
||||||
|
|
||||||
|
var viewModel = {
|
||||||
|
pixelRange: pixelRange,
|
||||||
|
minimumClusterSize: minimumClusterSize,
|
||||||
|
};
|
||||||
|
Cesium.knockout.track(viewModel);
|
||||||
|
|
||||||
|
|
||||||
|
function subscribeParameter(name) {
|
||||||
|
Cesium.knockout
|
||||||
|
.getObservable(viewModel, name)
|
||||||
|
.subscribe(function (newValue) {
|
||||||
|
dataSource.clustering[name] = newValue;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
subscribeParameter("pixelRange");
|
||||||
|
subscribeParameter("minimumClusterSize");
|
||||||
|
// var handler = new Cesium.ScreenSpaceEventHandler(this.sdk.viewer.scene.canvas);
|
||||||
|
// handler.setInputAction((movement) => {
|
||||||
|
// var pickedLabel = this.sdk.viewer.scene.pick(movement.position);
|
||||||
|
//
|
||||||
|
// if (Cesium.defined(pickedLabel)) {
|
||||||
|
// this.log(pickedLabel)
|
||||||
|
// var ids = pickedLabel.id;
|
||||||
|
// if (Array.isArray(ids)) {
|
||||||
|
// for (var i = 0; i < ids.length; ++i) {
|
||||||
|
// ids[i].billboard.color = Cesium.Color.RED;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 开启/关闭聚合效果
|
||||||
|
* @method set_cluster_status
|
||||||
|
* @param [enable=false] {boolean}默认关闭
|
||||||
|
* @memberOf Tool-3D
|
||||||
|
* */
|
||||||
|
function switchCluster(sdk, enable = false) {
|
||||||
|
let viewer = sdk.viewer
|
||||||
|
for (let i = 0; i < viewer.dataSources._dataSources.length; i++) {
|
||||||
|
if (viewer.dataSources._dataSources[i].name === "sdk-dataSource1") {
|
||||||
|
viewer.dataSources._dataSources[i].clustering.enabled = enable
|
||||||
|
// syncDataSources(viewer.dataSources._dataSources[i], 'clustering')
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function addCluster(sdk, entity) {
|
||||||
|
let viewer = sdk.viewer
|
||||||
|
if(!viewer) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for (let i = 0; i < viewer.dataSources._dataSources.length; i++) {
|
||||||
|
if (viewer.dataSources._dataSources[i].name === "sdk-dataSource1") {
|
||||||
|
viewer.dataSources._dataSources[i].entities.add(entity)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function remove_entity_from_cluster(viewer, entity) {
|
||||||
|
for (let i = 0; i < viewer.dataSources._dataSources.length; i++) {
|
||||||
|
if (viewer.dataSources._dataSources[i].name === "sdk-dataSource1") {
|
||||||
|
viewer.dataSources._dataSources[i].entities.remove(entity)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateCluster(viewer) {
|
||||||
|
if(!viewer) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for (let i = 0; i < viewer.dataSources._dataSources.length; i++) {
|
||||||
|
if (viewer.dataSources._dataSources[i].name === "sdk-dataSource1") {
|
||||||
|
viewer.dataSources._dataSources[i].clustering._cluster()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export { createCluster, addCluster, switchCluster, remove_entity_from_cluster, updateCluster }
|
||||||
159
src/Global/efflect/index.js
Normal file
159
src/Global/efflect/index.js
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
/*全局特效*/
|
||||||
|
|
||||||
|
let rainStages = null;
|
||||||
|
let snowStages = null;
|
||||||
|
let fogStages = null;
|
||||||
|
let nightVisionStages = null;
|
||||||
|
|
||||||
|
// 雨
|
||||||
|
const FS_Rain = `uniform sampler2D colorTexture;//输入的场景渲染照片
|
||||||
|
varying vec2 v_textureCoordinates;
|
||||||
|
uniform float tiltAngle;
|
||||||
|
uniform float rainSize;
|
||||||
|
uniform float rainWidth;
|
||||||
|
uniform float rainSpeed;
|
||||||
|
|
||||||
|
float hash(float x){
|
||||||
|
return fract(sin(x*133.3)*13.13);
|
||||||
|
}
|
||||||
|
void main(void){
|
||||||
|
float time = czm_frameNumber / rainSpeed;
|
||||||
|
vec2 resolution = czm_viewport.zw;
|
||||||
|
vec2 uv=(gl_FragCoord.xy*2.-resolution.xy)/min(resolution.x,resolution.y);
|
||||||
|
vec3 c=vec3(.6,.7,.8);
|
||||||
|
float a= tiltAngle;
|
||||||
|
float si=sin(a),co=cos(a);
|
||||||
|
uv*=mat2(co,-si,si,co);
|
||||||
|
uv*=length(uv+vec2(0,4.9))*rainSize+1.;
|
||||||
|
float v=1.-sin(hash(floor(uv.x*rainWidth))*2.);
|
||||||
|
float b=clamp(abs(sin(20.*time*v+uv.y*(5./(2.+v))))-.95,0.,1.)*20.;
|
||||||
|
c*=v*b; //屏幕上雨的颜色
|
||||||
|
gl_FragColor = mix(texture2D(colorTexture, v_textureCoordinates), vec4(c,1), 0.5); //将雨和三维场景融合
|
||||||
|
}`
|
||||||
|
|
||||||
|
// 雪
|
||||||
|
const FS_Snow = `uniform sampler2D colorTexture;
|
||||||
|
varying vec2 v_textureCoordinates;
|
||||||
|
uniform float snowSize;
|
||||||
|
uniform float snowSpeed;
|
||||||
|
|
||||||
|
float snow(vec2 uv,float scale)
|
||||||
|
{
|
||||||
|
float time = czm_frameNumber / snowSpeed;
|
||||||
|
float w=smoothstep(1.,0.,-uv.y*(scale/10.));if(w<.1)return 0.;
|
||||||
|
uv+=time/scale;uv.y+=time*2./scale;uv.x+=sin(uv.y+time*.5)/scale;
|
||||||
|
uv*=scale;vec2 s=floor(uv),f=fract(uv),p;float k=3.,d;
|
||||||
|
p=.5+.35*sin(11.*fract(sin((s+p+scale)*mat2(7,3,6,5))*5.))-f;d=length(p);k=min(d,k);
|
||||||
|
k=smoothstep(0.,k,sin(f.x+f.y)*0.01*snowSize);
|
||||||
|
return k*w;
|
||||||
|
}
|
||||||
|
void main(void){
|
||||||
|
vec2 resolution = czm_viewport.zw;
|
||||||
|
vec2 uv=(gl_FragCoord.xy*2.-resolution.xy)/min(resolution.x,resolution.y);
|
||||||
|
vec3 finalColor=vec3(0);
|
||||||
|
//float c=smoothstep(1.,0.3,clamp(uv.y*.3+.8,0.,.75));
|
||||||
|
float c = 0.0;
|
||||||
|
c+=snow(uv,30.)*.0;
|
||||||
|
c+=snow(uv,20.)*.0;
|
||||||
|
c+=snow(uv,15.)*.0;
|
||||||
|
c+=snow(uv,10.);
|
||||||
|
c+=snow(uv,8.);
|
||||||
|
c+=snow(uv,6.);
|
||||||
|
c+=snow(uv,5.);
|
||||||
|
finalColor=(vec3(c));
|
||||||
|
gl_FragColor = mix(texture2D(colorTexture, v_textureCoordinates), vec4(finalColor,1), 0.5);
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
// 雾
|
||||||
|
const FS_Fog = `
|
||||||
|
uniform sampler2D colorTexture;
|
||||||
|
uniform sampler2D depthTexture;
|
||||||
|
uniform float visibility;
|
||||||
|
uniform vec4 fogColor;
|
||||||
|
varying vec2 v_textureCoordinates;
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
vec4 origcolor = texture2D(colorTexture, v_textureCoordinates);
|
||||||
|
float depth = czm_readDepth(depthTexture, v_textureCoordinates);
|
||||||
|
vec4 depthcolor = texture2D(depthTexture, v_textureCoordinates);
|
||||||
|
float f = visibility * (depthcolor.r - 0.3) / 0.2;
|
||||||
|
if (f < 0.0) f = 0.0;
|
||||||
|
else if (f > 1.0) f = 1.0;
|
||||||
|
gl_FragColor = mix(origcolor, fogColor, f);
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
|
||||||
|
/*雨天*/
|
||||||
|
function rain(sdk, status = false) {
|
||||||
|
rainStages && sdk.viewer.scene.postProcessStages.remove(rainStages)
|
||||||
|
if (status) {
|
||||||
|
rainStages = new Cesium.PostProcessStage({
|
||||||
|
name: "rain",
|
||||||
|
fragmentShader: FS_Rain,
|
||||||
|
uniforms: {
|
||||||
|
tiltAngle: -0.4, // 倾斜角度
|
||||||
|
rainSize: 0.3, // 雨大小
|
||||||
|
rainWidth: 40, //雨长度
|
||||||
|
rainSpeed: 100, //雨速
|
||||||
|
},
|
||||||
|
});
|
||||||
|
sdk.viewer.scene.postProcessStages.add(rainStages);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 雪
|
||||||
|
function snow(sdk, status = false) {
|
||||||
|
snowStages && sdk.viewer.scene.postProcessStages.remove(snowStages)
|
||||||
|
if (status) {
|
||||||
|
snowStages = new Cesium.PostProcessStage({
|
||||||
|
name: "snow",
|
||||||
|
fragmentShader: FS_Snow,
|
||||||
|
uniforms: {
|
||||||
|
snowSize: 2, // 大小
|
||||||
|
snowSpeed: 60, //速度
|
||||||
|
},
|
||||||
|
});
|
||||||
|
sdk.viewer.scene.postProcessStages.add(snowStages);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 雾天
|
||||||
|
function fog(sdk, status = false) {
|
||||||
|
fogStages && sdk.viewer.scene.postProcessStages.remove(fogStages)
|
||||||
|
if (status) {
|
||||||
|
fogStages = new Cesium.PostProcessStage({
|
||||||
|
name: "fog",
|
||||||
|
fragmentShader: FS_Fog,
|
||||||
|
uniforms: {
|
||||||
|
visibility: 0.2, //
|
||||||
|
fogColor: Cesium.Color.WHITE,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
sdk.viewer.scene.postProcessStages.add(fogStages);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 夜视
|
||||||
|
function nightVision(sdk, status = false) {
|
||||||
|
nightVisionStages && sdk.viewer.scene.postProcessStages.remove(nightVisionStages)
|
||||||
|
if (status) {
|
||||||
|
nightVisionStages = Cesium.PostProcessStageLibrary.createNightVisionStage();
|
||||||
|
sdk.viewer.scene.postProcessStages.add(nightVisionStages);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 星空
|
||||||
|
function skyStarry(sdk, status = false) {
|
||||||
|
sdk.viewer.scene.skyAtmosphere.show = !status
|
||||||
|
}
|
||||||
|
|
||||||
|
// 光照
|
||||||
|
function illumination(sdk, status = false) {
|
||||||
|
sdk.viewer.shadows = status
|
||||||
|
sdk.viewer._shadows = status
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export { rain, snow, fog, nightVision, skyStarry, illumination }
|
||||||
825
src/Global/global.js
Normal file
825
src/Global/global.js
Normal file
@ -0,0 +1,825 @@
|
|||||||
|
/**
|
||||||
|
* @name: global
|
||||||
|
* @author: Administrator
|
||||||
|
* @date: 2023-12-01 14:15
|
||||||
|
* @description:global
|
||||||
|
* @update: 2023-12-01 14:15
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*获取当前视角*/
|
||||||
|
import MouseEvent from '../Event/index'
|
||||||
|
import Tools from "../Tools";
|
||||||
|
import { Proj } from "../Tools/proj";
|
||||||
|
import { getTheme, setTheme } from "../Obj/Element/theme";
|
||||||
|
import { setActiveViewer as setMultiViewportActiveViewer } from './MultiViewportMode'
|
||||||
|
import { setActiveViewer as setSplitActiveViewer, getSdk } from './SplitScreen'
|
||||||
|
import { updateCluster } from './cluster/cluster'
|
||||||
|
|
||||||
|
let coordinateSystem = 'EPSG:4326'
|
||||||
|
let _cartesian
|
||||||
|
let GroundCover = false
|
||||||
|
let bimPickObject = {}
|
||||||
|
let containerObject = {}
|
||||||
|
let rotateAroundObject = {}
|
||||||
|
function getCurrentView(sdk) {
|
||||||
|
let tools = new Tools()
|
||||||
|
let viewer = sdk.viewer
|
||||||
|
return JSON.parse(JSON.stringify({
|
||||||
|
// heading: viewer.camera.heading,
|
||||||
|
// pitch: viewer.camera.pitch,
|
||||||
|
// roll: viewer.camera.roll,
|
||||||
|
position: tools.cartesian3Towgs84(viewer.camera.position, viewer),
|
||||||
|
orientation: {
|
||||||
|
heading: Cesium.Math.toDegrees(viewer.camera.heading),
|
||||||
|
pitch: Cesium.Math.toDegrees(viewer.camera.pitch),
|
||||||
|
roll: Cesium.Math.toDegrees(viewer.camera.roll)
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
/*设置默认视角*/
|
||||||
|
function setDefaultView(sdk, options) {
|
||||||
|
let viewer = sdk.viewer
|
||||||
|
if (options) {
|
||||||
|
viewer.CAMERA_DEFAULT_VIEW_RECTANGLE = {
|
||||||
|
destination: options.destination || {},
|
||||||
|
orientation: options.orientation || {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
viewer.CAMERA_DEFAULT_VIEW_RECTANGLE = undefined
|
||||||
|
//设置cesium的默认视角
|
||||||
|
Cesium.Camera.DEFAULT_VIEW_RECTANGLE = Cesium.Rectangle.fromDegrees(
|
||||||
|
//西边的经度
|
||||||
|
89.5,
|
||||||
|
//南边的纬度
|
||||||
|
10.4,
|
||||||
|
//东边的经度
|
||||||
|
110.4,
|
||||||
|
//北边的维度
|
||||||
|
61.2
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*定位到指定视角*/
|
||||||
|
async function flyTo(sdk, options, duration = 3) {
|
||||||
|
let tools = new Tools(sdk)
|
||||||
|
let destination
|
||||||
|
let orientation = options.orientation
|
||||||
|
if (options.position) {
|
||||||
|
if (options.position.alt !== 0 && !options.position.alt) {
|
||||||
|
options.position.alt = await tools.getClampToHeight(options.position)
|
||||||
|
}
|
||||||
|
let h = 0
|
||||||
|
if (!orientation) {
|
||||||
|
h = 500
|
||||||
|
}
|
||||||
|
destination = Cesium.Cartesian3.fromDegrees(options.position.lng, options.position.lat, options.position.alt + h)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
let bbox = tools.cal_envelope(options.positions)
|
||||||
|
destination = new Cesium.Rectangle(
|
||||||
|
Cesium.Math.toRadians(bbox[3][0]),
|
||||||
|
Cesium.Math.toRadians(bbox[3][1]),
|
||||||
|
Cesium.Math.toRadians(bbox[1][0]),
|
||||||
|
Cesium.Math.toRadians(bbox[1][1])
|
||||||
|
)
|
||||||
|
}
|
||||||
|
closeRotateAround(sdk)
|
||||||
|
sdk.viewer.camera.flyTo({ destination, duration, orientation, complete: options.complete, })
|
||||||
|
}
|
||||||
|
|
||||||
|
/*相机锁定*/
|
||||||
|
function CameraController(sdk, status = true) {
|
||||||
|
if (!sdk || !sdk.viewer) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let viewer = sdk.viewer
|
||||||
|
viewer.scene.screenSpaceCameraController.enableRotate = status;
|
||||||
|
viewer.scene.screenSpaceCameraController.enableTranslate = status;
|
||||||
|
viewer.scene.screenSpaceCameraController.enableZoom = status;
|
||||||
|
viewer.scene.screenSpaceCameraController.enableTilt = status;
|
||||||
|
viewer.scene.screenSpaceCameraController.enableLook = status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*控件显隐*/
|
||||||
|
function CesiumContainer(sdk, options) {
|
||||||
|
if (!sdk || !sdk.viewer) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
containerObject[sdk.viewer._element.className] || (containerObject[sdk.viewer._element.className] = {})
|
||||||
|
containerObject[sdk.viewer._element.className].event && containerObject[sdk.viewer._element.className].event.destroy()
|
||||||
|
let tools = new Tools()
|
||||||
|
let element = sdk.viewer._element
|
||||||
|
let proj = sdk.proj
|
||||||
|
for (let key in options) {
|
||||||
|
switch (key) {
|
||||||
|
case 'compass':
|
||||||
|
let compass = element.getElementsByClassName('compass')[0]
|
||||||
|
let navigation = element.getElementsByClassName('navigation-controls')[0]
|
||||||
|
if (options[key]) {
|
||||||
|
compass && (compass.style.display = 'block')
|
||||||
|
navigation && (navigation.style.display = 'flex')
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
compass && (compass.style.display = 'none')
|
||||||
|
navigation && (navigation.style.display = 'none')
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'legend':
|
||||||
|
let distanceLegend = element.getElementsByClassName('distance-legend')[0]
|
||||||
|
if (options[key]) {
|
||||||
|
distanceLegend && (distanceLegend.parentNode.style.display = 'block')
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
distanceLegend && (distanceLegend.parentNode.style.display = 'none')
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'info':
|
||||||
|
let infoElm = element.getElementsByClassName('cesium-info')[0]
|
||||||
|
if (options[key]) {
|
||||||
|
if (infoElm) {
|
||||||
|
update()
|
||||||
|
infoElm.style.display = 'block'
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
infoElm = document.createElement('div');
|
||||||
|
infoElm.className = "cesium-info"
|
||||||
|
infoElm.style.position = 'absolute';
|
||||||
|
infoElm.style.bottom = '32px';
|
||||||
|
infoElm.style.right = '240px';
|
||||||
|
infoElm.style['font-size'] = '14px';
|
||||||
|
infoElm.style['background-color'] = 'rgba(47,53,60,.8)';
|
||||||
|
infoElm.style.color = '#fff';
|
||||||
|
infoElm.style.padding = '4px 10px';
|
||||||
|
infoElm.style['border-radius'] = '18px';
|
||||||
|
|
||||||
|
if (coordinateSystem === 'EPSG:4326') {
|
||||||
|
infoElm.innerHTML = `
|
||||||
|
<span>经度:</span><span>-</span>
|
||||||
|
<span>纬度:</span><span>-</span>
|
||||||
|
<span>海拔高度:</span><span>-</span>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
infoElm.innerHTML = `
|
||||||
|
<span>x:</span><span>-</span>
|
||||||
|
<span>y:</span><span>-</span>
|
||||||
|
<span>z:</span><span>-</span>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
sdk.viewer._element.appendChild(infoElm)
|
||||||
|
}
|
||||||
|
let event = new MouseEvent(sdk)
|
||||||
|
containerObject[sdk.viewer._element.className].event = event
|
||||||
|
event.mouse_move((movement, cartesian) => {
|
||||||
|
_cartesian = cartesian
|
||||||
|
update()
|
||||||
|
})
|
||||||
|
function update() {
|
||||||
|
if (!_cartesian) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let position = tools.cartesian3Towgs84(_cartesian, sdk.viewer)
|
||||||
|
if (coordinateSystem === 'EPSG:4326') {
|
||||||
|
infoElm.innerHTML = `
|
||||||
|
<span>经度:</span><span>${Number(position.lng.toFixed(6))}° </span>
|
||||||
|
<span>纬度:</span><span>${Number(position.lat.toFixed(6))}° </span>
|
||||||
|
<span>海拔高度:</span><span>${Number(position.alt.toFixed(2))}米</span>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
let result = proj.convert([{ x: position.lng, y: position.lat, z: position.alt }], 'EPSG:4326', coordinateSystem)
|
||||||
|
infoElm.innerHTML = `
|
||||||
|
<span>x:</span><span>${Number(result.points[0].x.toFixed(6))}</span>
|
||||||
|
<span style="margin-left: 5px;">y:</span><span>${Number(result.points[0].y.toFixed(6))}</span>
|
||||||
|
<span style="margin-left: 5px;">z:</span><span>${Number(result.points[0].z.toFixed(6))}</span>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
infoElm && (infoElm.style.display = 'none')
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'frame':
|
||||||
|
if (options[key]) {
|
||||||
|
sdk.viewer.scene.debugShowFramesPerSecond = true;
|
||||||
|
setTimeout(() => {
|
||||||
|
let cesiumWidgetContainerElm = sdk.viewer._element.getElementsByClassName('cesium-viewer-cesiumWidgetContainer')[0]
|
||||||
|
let defaultContainer = cesiumWidgetContainerElm.getElementsByClassName('cesium-performanceDisplay-defaultContainer')[0]
|
||||||
|
if (defaultContainer) {
|
||||||
|
cesiumWidgetContainerElm.appendChild(defaultContainer)
|
||||||
|
}
|
||||||
|
}, 50);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sdk.viewer.scene.debugShowFramesPerSecond = false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// let compass = element.getElementsByClassName('compass')[0]
|
||||||
|
// let navigation = element.getElementsByClassName('navigation-controls')[0]
|
||||||
|
// let distanceLegend = element.getElementsByClassName('distance-legend')[0]
|
||||||
|
// if(status) {
|
||||||
|
// compass && (compass.style.display = 'block')
|
||||||
|
// navigation && (navigation.style.display = 'block')
|
||||||
|
// distanceLegend && (distanceLegend.style.display = 'block')
|
||||||
|
// }
|
||||||
|
// else {
|
||||||
|
// compass && (compass.style.display = 'none')
|
||||||
|
// navigation && (navigation.style.display = 'none')
|
||||||
|
// distanceLegend && (distanceLegend.style.display = 'none')
|
||||||
|
// viewer.cesiumNavigation.distanceLegendViewModel.destroy()
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
/*设置广告牌默认图标*/
|
||||||
|
function setBillboardDefaultUrl(url, name) {
|
||||||
|
if (name) {
|
||||||
|
name = 'billboard_default_url_' + name
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
name = 'billboard_default_url'
|
||||||
|
}
|
||||||
|
localStorage.setItem(name, url);
|
||||||
|
}
|
||||||
|
/*获取广告牌默认图标*/
|
||||||
|
function getBillboardDefaultUrl(name) {
|
||||||
|
if (name) {
|
||||||
|
name = 'billboard_default_url_' + name
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
name = 'billboard_default_url'
|
||||||
|
}
|
||||||
|
return localStorage.getItem(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*设置高度参考*/
|
||||||
|
function setGroundCover(sdk, status) {
|
||||||
|
GroundCover = status ? true : false
|
||||||
|
updateCluster(sdk.viewer)
|
||||||
|
}
|
||||||
|
|
||||||
|
/*获取高度参考*/
|
||||||
|
function getGroundCover() {
|
||||||
|
return GroundCover
|
||||||
|
}
|
||||||
|
|
||||||
|
function setBimPickStatus(sdk, status) {
|
||||||
|
if (!sdk || !sdk.viewer) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
bimPickObject[sdk.viewer._element.className] || (bimPickObject[sdk.viewer._element.className] = {})
|
||||||
|
bimPickObject[sdk.viewer._element.className].status = status
|
||||||
|
if (bimPickObject[sdk.viewer._element.className].MoveHandler) {
|
||||||
|
bimPickObject[sdk.viewer._element.className].MoveHandler.destroy()
|
||||||
|
}
|
||||||
|
if (!status) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
bimPickObject[sdk.viewer._element.className].MoveHandler = new Cesium.ScreenSpaceEventHandler(sdk.viewer.canvas)
|
||||||
|
bimPickObject[sdk.viewer._element.className].MoveHandler.setInputAction(function (movement) {
|
||||||
|
const pick = sdk.viewer.scene.pick(movement.endPosition);
|
||||||
|
let selectedId = bimPickObject[sdk.viewer._element.className].selectedId
|
||||||
|
let that = sdk.entityMap.get(bimPickObject[sdk.viewer._element.className].id)
|
||||||
|
// if (selectedFeatureId) {
|
||||||
|
// let color = '#fff'
|
||||||
|
// let state = selectedFeature.getProperty('state')
|
||||||
|
// switch (state) {
|
||||||
|
// case '0':
|
||||||
|
// color = '#fff'
|
||||||
|
// break;
|
||||||
|
// case '1':
|
||||||
|
// color = '#f00'
|
||||||
|
// break;
|
||||||
|
// case '2':
|
||||||
|
// color = '#0f0'
|
||||||
|
// break;
|
||||||
|
// case '3':
|
||||||
|
// color = '#00f'
|
||||||
|
// break;
|
||||||
|
// default:
|
||||||
|
// }
|
||||||
|
// selectedFeature.color = Cesium.Color.fromCssColorString(color).withAlpha(selectedFeature.tileset.transparency)
|
||||||
|
// }
|
||||||
|
if (that) {
|
||||||
|
if (that.features.has(selectedId)) {
|
||||||
|
let features = that.features.get(selectedId).features
|
||||||
|
for (let key in features) {
|
||||||
|
if (features[key].content._model) {
|
||||||
|
let color = features[key].customColor || Cesium.Color.fromCssColorString('#fff')
|
||||||
|
features[key].color = Cesium.Color.fromCssColorString(`rgba(${Cesium.Color.floatToByte(color.red)},${Cesium.Color.floatToByte(color.green)},${Cesium.Color.floatToByte(color.blue)},${color.alpha * ((features[key].customAlpha || features[key].customAlpha === 0) ? features[key].customAlpha : 1)})`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pick && pick.content) {
|
||||||
|
let obj = sdk.getIncetance(pick.content.tileset.id)
|
||||||
|
if (obj.type === 'bim') {
|
||||||
|
if (pick.primitive && pick.primitive.id) {
|
||||||
|
let that = sdk.entityMap.get(pick.primitive.id)
|
||||||
|
selectedId = pick.getProperty('id')
|
||||||
|
if (that.features.has(selectedId)) {
|
||||||
|
let features = that.features.get(selectedId).features
|
||||||
|
for (let key in features) {
|
||||||
|
if (features[key].content._model) {
|
||||||
|
features[key].color = Cesium.Color.fromCssColorString('#ffeb3b')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bimPickObject[sdk.viewer._element.className].id = pick.primitive.id
|
||||||
|
bimPickObject[sdk.viewer._element.className].selectedId = selectedId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
pick.primitive.id = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE)
|
||||||
|
}
|
||||||
|
|
||||||
|
function getBimPickStatus(sdk) {
|
||||||
|
if (!sdk || !sdk.viewer) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return bimPickObject[sdk.viewer._element.className] ? bimPickObject[sdk.viewer._element.className].status : false
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 围绕坐标旋转 */
|
||||||
|
function rotateAround(sdk, position) {
|
||||||
|
if (!sdk || !sdk.viewer) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
setActiveViewer(0)
|
||||||
|
sdk.viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY);
|
||||||
|
// 关闭Controller
|
||||||
|
sdk.entityMap.forEach((item) => {
|
||||||
|
item.editObj && item.editObj.destroy()
|
||||||
|
item.ControllerObject && item.ControllerObject.destroy()
|
||||||
|
})
|
||||||
|
rotateAroundObject[sdk.viewer._element.className] || (rotateAroundObject[sdk.viewer._element.className] = {})
|
||||||
|
rotateAroundObject[sdk.viewer._element.className].animate && TWEEN.remove(rotateAroundObject[sdk.viewer._element.className].animate)
|
||||||
|
rotateAroundObject[sdk.viewer._element.className].event && rotateAroundObject[sdk.viewer._element.className].event.destroy()
|
||||||
|
if (!position) {
|
||||||
|
CameraController(sdk, true)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let point = Cesium.Cartesian3.fromDegrees(position.lng, position.lat, position.alt)
|
||||||
|
let angle = Cesium.Math.toDegrees(sdk.viewer.camera.heading)
|
||||||
|
let range = Cesium.Cartesian3.distance(sdk.viewer.camera.position, point);
|
||||||
|
CameraController(sdk, false)
|
||||||
|
let pitch = sdk.viewer.camera.pitch
|
||||||
|
let degrees = Cesium.Math.toDegrees(pitch)
|
||||||
|
if (degrees < -89.99) {
|
||||||
|
pitch = Cesium.Math.toRadians(-89.99)
|
||||||
|
}
|
||||||
|
rotateAroundObject[sdk.viewer._element.className].animate = new TWEEN.Tween({ angle: angle }).to({ angle: angle - 360 }, 30000).easing(TWEEN.Easing.Linear.None).repeat(Infinity).onUpdate(async (r, a) => {
|
||||||
|
if (!sdk.viewer) {
|
||||||
|
TWEEN.remove(rotateAroundObject[sdk.viewer._element.className].animate)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
sdk.viewer.camera.lookAt(
|
||||||
|
point,
|
||||||
|
new Cesium.HeadingPitchRange(Cesium.Math.toRadians(r.angle), pitch, range)
|
||||||
|
)
|
||||||
|
|
||||||
|
sdk.viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY);
|
||||||
|
}).start()
|
||||||
|
|
||||||
|
let event = new MouseEvent(sdk)
|
||||||
|
rotateAroundObject[sdk.viewer._element.className].event = event
|
||||||
|
event.mouse_left_down(() => {
|
||||||
|
rotateAroundObject[sdk.viewer._element.className].animate && TWEEN.remove(rotateAroundObject[sdk.viewer._element.className].animate)
|
||||||
|
rotateAroundObject[sdk.viewer._element.className].event && rotateAroundObject[sdk.viewer._element.className].event.destroy()
|
||||||
|
CameraController(sdk, true)
|
||||||
|
sdk.viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 关闭围绕坐标旋转 */
|
||||||
|
function closeRotateAround(sdk) {
|
||||||
|
if (!sdk || !sdk.viewer) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (rotateAroundObject[sdk.viewer._element.className]) {
|
||||||
|
rotateAroundObject[sdk.viewer._element.className].animate && TWEEN.remove(rotateAroundObject[sdk.viewer._element.className].animate)
|
||||||
|
rotateAroundObject[sdk.viewer._element.className].event && rotateAroundObject[sdk.viewer._element.className].event.destroy()
|
||||||
|
CameraController(sdk, true)
|
||||||
|
sdk.viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeViewFollow(sdk) {
|
||||||
|
if (sdk && sdk.entityMap) {
|
||||||
|
let entityMap = sdk.entityMap
|
||||||
|
for (let [key, value] of entityMap) {
|
||||||
|
if (value.type === 'TrajectoryMotion' && value.viewFollow) {
|
||||||
|
value.viewFollow = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 方里网状态开关 */
|
||||||
|
function FlwStatusSwitch(sdk, status) {
|
||||||
|
if(!sdk) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let layer
|
||||||
|
let sdkD = getSdk().sdkD
|
||||||
|
if(sdkD && sdk !== sdkD) {
|
||||||
|
FlwStatusSwitch(sdkD, status)
|
||||||
|
}
|
||||||
|
for (let i = 0; i < sdk.viewer.imageryLayers._layers.length; i++) {
|
||||||
|
if (sdk.viewer.imageryLayers._layers[i]._imageryProvider && sdk.viewer.imageryLayers._layers[i]._imageryProvider._type && sdk.viewer.imageryLayers._layers[i]._imageryProvider._type === 'flw') {
|
||||||
|
layer = sdk.viewer.imageryLayers._layers[i]
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (layer) {
|
||||||
|
sdk.viewer.imageryLayers.remove(layer)
|
||||||
|
}
|
||||||
|
if (status) {
|
||||||
|
sdk.viewer.imageryLayers.addImageryProvider(new Cesium.TileCoordinatesImageryProviderFlw(
|
||||||
|
{
|
||||||
|
tileWidth: 128,
|
||||||
|
tileHeight: 128,
|
||||||
|
}
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getFlwStatus(sdk) {
|
||||||
|
let status = false
|
||||||
|
for (let i = 0; i < sdk.viewer.imageryLayers._layers.length; i++) {
|
||||||
|
if (sdk.viewer.imageryLayers._layers[i]._imageryProvider && sdk.viewer.imageryLayers._layers[i]._imageryProvider._type && sdk.viewer.imageryLayers._layers[i]._imageryProvider._type === 'flw') {
|
||||||
|
status = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return status
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 经纬网状态开关 */
|
||||||
|
function JwwStatusSwitch(sdk, status) {
|
||||||
|
if(!sdk) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let layer
|
||||||
|
let sdkD = getSdk().sdkD
|
||||||
|
if(sdkD && sdk !== sdkD) {
|
||||||
|
JwwStatusSwitch(sdkD, status)
|
||||||
|
}
|
||||||
|
for (let i = 0; i < sdk.viewer.imageryLayers._layers.length; i++) {
|
||||||
|
if (sdk.viewer.imageryLayers._layers[i]._imageryProvider && sdk.viewer.imageryLayers._layers[i]._imageryProvider._type && sdk.viewer.imageryLayers._layers[i]._imageryProvider._type === 'jww') {
|
||||||
|
layer = sdk.viewer.imageryLayers._layers[i]
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (layer) {
|
||||||
|
sdk.viewer.imageryLayers.remove(layer)
|
||||||
|
}
|
||||||
|
if (status) {
|
||||||
|
sdk.viewer.imageryLayers.addImageryProvider(new Cesium.TileCoordinatesImageryProviderJww());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getJwwStatus(sdk) {
|
||||||
|
let status = false
|
||||||
|
for (let i = 0; i < sdk.viewer.imageryLayers._layers.length; i++) {
|
||||||
|
if (sdk.viewer.imageryLayers._layers[i]._imageryProvider && sdk.viewer.imageryLayers._layers[i]._imageryProvider._type && sdk.viewer.imageryLayers._layers[i]._imageryProvider._type === 'jww') {
|
||||||
|
status = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return status
|
||||||
|
}
|
||||||
|
|
||||||
|
function splitScreen2(sdk, status) {
|
||||||
|
let sliderElm = sdk.viewer._element.getElementsByClassName('YJ-custom-slider')[0]
|
||||||
|
let leftElm = sdk.viewer._element.getElementsByClassName('YJ-custom-checkbox-left')[0]
|
||||||
|
let rightElm = sdk.viewer._element.getElementsByClassName('YJ-custom-checkbox-right')[0]
|
||||||
|
if (sliderElm) {
|
||||||
|
sdk.viewer._element.removeChild(sliderElm)
|
||||||
|
sdk.viewer._element.removeChild(leftElm)
|
||||||
|
sdk.viewer._element.removeChild(rightElm)
|
||||||
|
}
|
||||||
|
if (status) {
|
||||||
|
sliderElm = document.createElement('div');
|
||||||
|
sliderElm.className = 'YJ-custom-slider'
|
||||||
|
sliderElm.style.position = 'absolute'
|
||||||
|
sliderElm.style.left = '50%'
|
||||||
|
sliderElm.style.top = '0px'
|
||||||
|
|
||||||
|
leftElm = document.createElement('input');
|
||||||
|
leftElm.className = 'YJ-custom-checkbox-left'
|
||||||
|
leftElm.type = 'checkbox'
|
||||||
|
leftElm.style.position = 'absolute'
|
||||||
|
leftElm.style.left = 'calc(50% - 50px)'
|
||||||
|
rightElm = document.createElement('input');
|
||||||
|
rightElm.className = 'YJ-custom-checkbox-right'
|
||||||
|
rightElm.type = 'checkbox'
|
||||||
|
rightElm.style.position = 'absolute'
|
||||||
|
rightElm.style.right = 'calc(50% - 50px)'
|
||||||
|
sdk.viewer._element.appendChild(leftElm)
|
||||||
|
sdk.viewer._element.appendChild(rightElm)
|
||||||
|
|
||||||
|
leftElm.checked = true
|
||||||
|
leftElm.addEventListener('change', (e) => {
|
||||||
|
if (!e.target.checked) {
|
||||||
|
if (!rightElm.checked) {
|
||||||
|
rightElm.checked = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
changeEntitySplitStatus()
|
||||||
|
})
|
||||||
|
rightElm.addEventListener('change', (e) => {
|
||||||
|
if (!e.target.checked) {
|
||||||
|
if (!leftElm.checked) {
|
||||||
|
leftElm.checked = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
changeEntitySplitStatus()
|
||||||
|
})
|
||||||
|
|
||||||
|
sliderElm.addEventListener('mousedown', () => {
|
||||||
|
document.body.addEventListener('mousemove', mousemove)
|
||||||
|
sliderElm.addEventListener('mouseup', () => {
|
||||||
|
document.body.removeEventListener('mousemove', mousemove)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
function mousemove(a, b) {
|
||||||
|
if (sdk.viewer._element.getElementsByTagName('canvas')[0] === a.target) {
|
||||||
|
sliderElm.style.left = (a.offsetX / sdk.viewer._element.scrollWidth * 100) + '%'
|
||||||
|
sdk.viewer.scene.splitPosition = a.offsetX / sdk.viewer._element.scrollWidth
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sdk.viewer._element.appendChild(sliderElm)
|
||||||
|
sdk.viewer.scene.splitStatus = status
|
||||||
|
sdk.viewer.scene.splitPosition = 0.5
|
||||||
|
changeEntitySplitStatus()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sdk.viewer.scene.splitPosition = 0
|
||||||
|
changeEntitySplitStatus(0)
|
||||||
|
sdk.viewer.scene.splitStatus = status
|
||||||
|
}
|
||||||
|
|
||||||
|
function changeEntitySplitStatus(v) {
|
||||||
|
let value
|
||||||
|
if (v === undefined || v === null) {
|
||||||
|
if (leftElm.checked && rightElm.checked) {
|
||||||
|
value = 0
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (leftElm.checked) {
|
||||||
|
value = -1
|
||||||
|
}
|
||||||
|
if (rightElm.checked) {
|
||||||
|
value = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
value = v
|
||||||
|
}
|
||||||
|
|
||||||
|
sdk.entityMap.forEach((item, key) => {
|
||||||
|
if (sdk.viewer.scene.splitStatus) {
|
||||||
|
if (item.entity.billboard) {
|
||||||
|
item.entity.billboard.splitDirection = value
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
item.entity && (item.entity.splitDirection = value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function splitScreen(sdk, status) {
|
||||||
|
let sliderElm = sdk.viewer._element.getElementsByClassName('YJ-custom-slider')[0]
|
||||||
|
let leftElm = sdk.viewer._element.getElementsByClassName('YJ-custom-checkbox-left')[0]
|
||||||
|
let rightElm = sdk.viewer._element.getElementsByClassName('YJ-custom-checkbox-right')[0]
|
||||||
|
if (sliderElm) {
|
||||||
|
sdk.viewer._element.removeChild(sliderElm)
|
||||||
|
sdk.viewer._element.removeChild(leftElm)
|
||||||
|
sdk.viewer._element.removeChild(rightElm)
|
||||||
|
}
|
||||||
|
if (status) {
|
||||||
|
sliderElm = document.createElement('div');
|
||||||
|
sliderElm.className = 'YJ-custom-slider'
|
||||||
|
sliderElm.style.position = 'absolute'
|
||||||
|
sliderElm.style.left = '50%'
|
||||||
|
sliderElm.style.top = '0px'
|
||||||
|
|
||||||
|
leftElm = document.createElement('input');
|
||||||
|
leftElm.className = 'YJ-custom-checkbox-left'
|
||||||
|
leftElm.type = 'checkbox'
|
||||||
|
leftElm.style.position = 'absolute'
|
||||||
|
leftElm.style.left = 'calc(50% - 50px)'
|
||||||
|
rightElm = document.createElement('input');
|
||||||
|
rightElm.className = 'YJ-custom-checkbox-right'
|
||||||
|
rightElm.type = 'checkbox'
|
||||||
|
rightElm.style.position = 'absolute'
|
||||||
|
rightElm.style.right = 'calc(50% - 50px)'
|
||||||
|
sdk.viewer._element.appendChild(leftElm)
|
||||||
|
sdk.viewer._element.appendChild(rightElm)
|
||||||
|
|
||||||
|
leftElm.checked = true
|
||||||
|
leftElm.addEventListener('change', (e) => {
|
||||||
|
if (!e.target.checked) {
|
||||||
|
if (!rightElm.checked) {
|
||||||
|
rightElm.checked = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
changeEntitySplitStatus()
|
||||||
|
})
|
||||||
|
rightElm.addEventListener('change', (e) => {
|
||||||
|
if (!e.target.checked) {
|
||||||
|
if (!leftElm.checked) {
|
||||||
|
leftElm.checked = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
changeEntitySplitStatus()
|
||||||
|
})
|
||||||
|
|
||||||
|
sliderElm.addEventListener('mousedown', () => {
|
||||||
|
document.body.addEventListener('mousemove', mousemove)
|
||||||
|
sliderElm.addEventListener('mouseup', () => {
|
||||||
|
document.body.removeEventListener('mousemove', mousemove)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
function mousemove(a, b) {
|
||||||
|
if (sdk.viewer._element.getElementsByTagName('canvas')[0] === a.target) {
|
||||||
|
sliderElm.style.left = (a.offsetX / sdk.viewer._element.scrollWidth * 100) + '%'
|
||||||
|
sdk.viewer.scene.splitPosition = a.offsetX / sdk.viewer._element.scrollWidth
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sdk.viewer._element.appendChild(sliderElm)
|
||||||
|
sdk.viewer.scene.splitStatus = status
|
||||||
|
sdk.viewer.scene.splitPosition = 0.5
|
||||||
|
changeEntitySplitStatus()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sdk.viewer.scene.splitPosition = 0
|
||||||
|
changeEntitySplitStatus(0)
|
||||||
|
sdk.viewer.scene.splitStatus = status
|
||||||
|
}
|
||||||
|
|
||||||
|
function changeEntitySplitStatus(v) {
|
||||||
|
let value
|
||||||
|
if (v === undefined || v === null) {
|
||||||
|
if (leftElm.checked && rightElm.checked) {
|
||||||
|
value = 0
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (leftElm.checked) {
|
||||||
|
value = -1
|
||||||
|
}
|
||||||
|
if (rightElm.checked) {
|
||||||
|
value = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
value = v
|
||||||
|
}
|
||||||
|
|
||||||
|
sdk.entityMap.forEach((item, key) => {
|
||||||
|
if (sdk.viewer.scene.splitStatus) {
|
||||||
|
if (item.entity.billboard) {
|
||||||
|
item.entity.billboard.splitDirection = value
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
item.entity && (item.entity.splitDirection = value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCoordinateSystem() {
|
||||||
|
return coordinateSystem
|
||||||
|
}
|
||||||
|
|
||||||
|
function setCoordinateSystem(sdk, epsg) {
|
||||||
|
coordinateSystem = epsg || 'EPSG:4326'
|
||||||
|
if (!sdk || !sdk.viewer || !sdk.viewer._element) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let infoElm = sdk.viewer._element.getElementsByClassName('cesium-info')[0]
|
||||||
|
if (!_cartesian || !infoElm) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let tools = new Tools()
|
||||||
|
let proj = sdk.proj
|
||||||
|
let position = tools.cartesian3Towgs84(_cartesian, sdk.viewer)
|
||||||
|
if (coordinateSystem === 'EPSG:4326') {
|
||||||
|
infoElm.innerHTML = `
|
||||||
|
<span>经度:</span><span>${Number(position.lng.toFixed(6))}° </span>
|
||||||
|
<span>纬度:</span><span>${Number(position.lat.toFixed(6))}° </span>
|
||||||
|
<span>海拔高度:</span><span>${Number(position.alt.toFixed(2))}米</span>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
let result = proj.convert([{ x: position.lng, y: position.lat, z: position.alt }], 'EPSG:4326', coordinateSystem)
|
||||||
|
infoElm.innerHTML = `
|
||||||
|
<span>x:</span><span>${Number(result.points[0].x.toFixed(6))}</span>
|
||||||
|
<span style="margin-left: 5px;">y:</span><span>${Number(result.points[0].y.toFixed(6))}</span>
|
||||||
|
<span style="margin-left: 5px;">z:</span><span>${Number(result.points[0].z.toFixed(6))}</span>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function cameraChanged(sdk, cb) {
|
||||||
|
let tools = new Tools()
|
||||||
|
//设置相机变化的监听事件
|
||||||
|
let removeChanged = sdk.viewer.camera.changed.addEventListener(percentage => {
|
||||||
|
cb({
|
||||||
|
position: tools.cartesian3Towgs84(sdk.viewer.camera.position, sdk.viewer),
|
||||||
|
orientation: {
|
||||||
|
heading: sdk.viewer.camera.heading,
|
||||||
|
pitch: sdk.viewer.camera.pitch,
|
||||||
|
roll: sdk.viewer.camera.roll
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
return removeChanged
|
||||||
|
}
|
||||||
|
|
||||||
|
function setMaximumRequestsPerServer(v) {
|
||||||
|
if (typeof v == 'number')
|
||||||
|
Cesium.RequestScheduler.maximumRequestsPerServer = v
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 键盘事件 */
|
||||||
|
function setKeyboardEventActive(sdk, status) {
|
||||||
|
if (!sdk) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (status) {
|
||||||
|
sdk.viewer._disableKeyboardEvent = false
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sdk.viewer._disableKeyboardEvent = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCesiumIndexedDBMaxSize() {
|
||||||
|
const baseUnit = 1024 * 1024 * 1024
|
||||||
|
let size = Number(Number(localStorage.getItem('IndexedDBMaxSize')).toFixed(0))
|
||||||
|
if (isNaN(size) || size < baseUnit) {
|
||||||
|
size = baseUnit
|
||||||
|
}
|
||||||
|
return size
|
||||||
|
}
|
||||||
|
function setCesiumIndexedDBMaxSize(v) {
|
||||||
|
const baseUnit = 1024 * 1024 * 1024
|
||||||
|
let maxSize = Number(Number(v).toFixed(0))
|
||||||
|
if (isNaN(maxSize) || maxSize < baseUnit) {
|
||||||
|
maxSize = baseUnit
|
||||||
|
}
|
||||||
|
Cesium.ManageIndexedDB && Cesium.ManageIndexedDB.SetIndexedDBMaxSize(maxSize)
|
||||||
|
localStorage.setItem('IndexedDBMaxSize', maxSize)
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCesiumManageIndexexDBState() {
|
||||||
|
let state = localStorage.getItem('ManageIndexexDBState')
|
||||||
|
if (state === 'false') {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return Boolean(state)
|
||||||
|
}
|
||||||
|
function setCesiumManageIndexexDBState(v) {
|
||||||
|
if (typeof v === "boolean") {
|
||||||
|
Cesium.ManageIndexedDB && Cesium.ManageIndexedDB.SetManageIndexexDBState(v)
|
||||||
|
localStorage.setItem('ManageIndexexDBState', v)
|
||||||
|
} else {
|
||||||
|
console.error("参数必须为boolean")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCesiumIndexedDBCurrentSize() {
|
||||||
|
return Cesium.ManageIndexedDB && Cesium.ManageIndexedDB.GetIndexedDBCurrentSize()
|
||||||
|
}
|
||||||
|
|
||||||
|
function setActiveViewer(v) {
|
||||||
|
setMultiViewportActiveViewer(v)
|
||||||
|
setSplitActiveViewer(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置地球透明度
|
||||||
|
function enablePerspective(sdk, alpha = 1) {
|
||||||
|
if (!alpha && alpha != 0) {
|
||||||
|
alpha = 1
|
||||||
|
}
|
||||||
|
sdk.viewer.scene.globe.translucency.frontFaceAlpha = alpha
|
||||||
|
}
|
||||||
|
|
||||||
|
export { getCurrentView, setDefaultView, flyTo, CameraController, CesiumContainer, setBillboardDefaultUrl, getBillboardDefaultUrl, setGroundCover, getGroundCover, getBimPickStatus, setBimPickStatus, rotateAround, closeRotateAround, closeViewFollow, FlwStatusSwitch, JwwStatusSwitch, getFlwStatus, getJwwStatus, getCoordinateSystem, setCoordinateSystem, cameraChanged, setMaximumRequestsPerServer, setKeyboardEventActive, getTheme, setTheme, getCesiumIndexedDBMaxSize, setCesiumIndexedDBMaxSize, getCesiumManageIndexexDBState, setCesiumManageIndexexDBState, getCesiumIndexedDBCurrentSize, setActiveViewer, enablePerspective }
|
||||||
218
src/Global/mouseRightMenu/index.js
Normal file
218
src/Global/mouseRightMenu/index.js
Normal file
@ -0,0 +1,218 @@
|
|||||||
|
/* 右键点击菜单 */
|
||||||
|
import MouseEvent from '../../Event/index'
|
||||||
|
import Tools from '../../Tools'
|
||||||
|
import { rotateAround } from '../../Global/global'
|
||||||
|
import { getSdk } from '../SplitScreen'
|
||||||
|
|
||||||
|
let eventListener = {}
|
||||||
|
|
||||||
|
function MouseRightMenu(sdk, status, callBack) {
|
||||||
|
if (!sdk || !sdk.div_id) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let sdkD = getSdk().sdkD
|
||||||
|
let _element = document.getElementById(sdk.div_id).getElementsByClassName('cesium-viewer')[0]
|
||||||
|
let tools = new Tools()
|
||||||
|
if (!eventListener[sdk.div_id]) {
|
||||||
|
eventListener[sdk.div_id] = {}
|
||||||
|
}
|
||||||
|
if (eventListener[sdk.div_id].mousedown) {
|
||||||
|
document.removeEventListener(
|
||||||
|
'mousedown',
|
||||||
|
eventListener[sdk.div_id].mousedown
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if (eventListener[sdk.div_id].click) {
|
||||||
|
document.removeEventListener('click', eventListener[sdk.div_id].click)
|
||||||
|
}
|
||||||
|
if(!eventListener[sdk.div_id].callBack) {
|
||||||
|
eventListener[sdk.div_id].callBack = callBack
|
||||||
|
}
|
||||||
|
|
||||||
|
if(sdk !== sdkD) {
|
||||||
|
eventListener[sdk.div_id].mouseRightMenuEvent &&
|
||||||
|
eventListener[sdk.div_id].mouseRightMenuEvent.destroy()
|
||||||
|
}
|
||||||
|
|
||||||
|
let menuElm = document.getElementById('custom-menu')
|
||||||
|
if (menuElm) {
|
||||||
|
_element.removeChild(menuElm)
|
||||||
|
}
|
||||||
|
eventListener[sdk.div_id].status = status
|
||||||
|
if (status) {
|
||||||
|
eventListener[sdk.div_id].mousedown = e => {
|
||||||
|
if (
|
||||||
|
(e.target.parentNode && e.target.parentNode.id == 'custom-menu') ||
|
||||||
|
(e.target.parentNode &&
|
||||||
|
e.target.parentNode.parentNode &&
|
||||||
|
e.target.parentNode.parentNode.id == 'custom-menu')
|
||||||
|
) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let menuElm = document.getElementById('custom-menu')
|
||||||
|
if (menuElm) {
|
||||||
|
_element.removeChild(menuElm)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
document.addEventListener('mousedown', eventListener[sdk.div_id].mousedown)
|
||||||
|
eventListener[sdk.div_id].click = e => {
|
||||||
|
if (
|
||||||
|
(e.target.parentNode && e.target.parentNode.id == 'custom-menu') ||
|
||||||
|
(e.target.parentNode &&
|
||||||
|
e.target.parentNode.parentNode &&
|
||||||
|
e.target.parentNode.parentNode.id == 'custom-menu')
|
||||||
|
) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let menuElm = document.getElementById('custom-menu')
|
||||||
|
if (menuElm) {
|
||||||
|
_element.removeChild(menuElm)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
document.addEventListener('click', eventListener[sdk.div_id].click)
|
||||||
|
|
||||||
|
eventListener[sdk.div_id].mouseRightMenuEvent = new MouseEvent(sdk)
|
||||||
|
eventListener[sdk.div_id].mouseRightMenuEvent.mouse_right(
|
||||||
|
(movement, cartesian) => {
|
||||||
|
if (YJ.Measure.GetMeasureStatus() || sdk.viewer.trackedEntity) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let entity = sdk.viewer.entities.getById('svg-control-points_0')
|
||||||
|
if (entity && entity.show) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let menuElm = document.getElementById('custom-menu')
|
||||||
|
if (menuElm) {
|
||||||
|
_element.removeChild(menuElm)
|
||||||
|
}
|
||||||
|
let entityId = getEntityId(movement)
|
||||||
|
let targetId
|
||||||
|
if(Object.prototype.toString.call(entityId) === '[object Object]') {
|
||||||
|
targetId = entityId.id
|
||||||
|
entityId = entityId.parentId
|
||||||
|
}
|
||||||
|
let addedMenu = ''
|
||||||
|
let that = sdk.entityMap.get(entityId)
|
||||||
|
if (!that && entityId) {
|
||||||
|
let array = entityId.split('-')
|
||||||
|
array.splice(array.length - 1, 1)
|
||||||
|
entityId = array.join('-')
|
||||||
|
that = sdk.entityMap.get(entityId)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (that && that.picking) {
|
||||||
|
addedMenu = `
|
||||||
|
<span class="divider" style="display: block;border-top: 1px solid #ddd;margin: 5px;"></span>
|
||||||
|
<ul class="added" style="list-style: none;padding: 0;margin: 0;font-size: 12px;">
|
||||||
|
<li style="padding: 3px 10px;cursor: pointer;">属性</li>
|
||||||
|
</ul>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
let position = tools.cartesian3Towgs84(cartesian, sdk.viewer)
|
||||||
|
menuElm = document.createElement('div')
|
||||||
|
menuElm.id = 'custom-menu'
|
||||||
|
menuElm.style.position = 'absolute'
|
||||||
|
menuElm.style.width = '110px'
|
||||||
|
menuElm.style.backgroundColor = '#00000085'
|
||||||
|
menuElm.style.color = '#ffffff'
|
||||||
|
menuElm.style.padding = '6px 0'
|
||||||
|
menuElm.style.boxShadow = '4px 4px 4px 0px rgba(0, 0, 0, 0.8)'
|
||||||
|
menuElm.innerHTML = `
|
||||||
|
<ul class="base" style="list-style: none;padding: 0;margin: 0;font-size: 12px;">
|
||||||
|
<li style="padding: 3px 10px;cursor: pointer;">绕鼠标点旋转</li>
|
||||||
|
</ul>
|
||||||
|
${addedMenu}
|
||||||
|
`
|
||||||
|
_element.appendChild(menuElm)
|
||||||
|
let left = movement.position.x
|
||||||
|
let top = movement.position.y
|
||||||
|
if (
|
||||||
|
movement.position.x + menuElm.offsetWidth >
|
||||||
|
_element.offsetWidth
|
||||||
|
) {
|
||||||
|
left = movement.position.x - menuElm.offsetWidth
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
movement.position.y + menuElm.offsetHeight >
|
||||||
|
_element.offsetHeight
|
||||||
|
) {
|
||||||
|
top = movement.position.y - menuElm.offsetHeight
|
||||||
|
}
|
||||||
|
menuElm.style.left = left + 'px'
|
||||||
|
menuElm.style.top = top + 'px'
|
||||||
|
|
||||||
|
menuElm.addEventListener('contextmenu', function(event) {
|
||||||
|
event.preventDefault()
|
||||||
|
})
|
||||||
|
let liElms = menuElm.getElementsByTagName('li')
|
||||||
|
let object = {}
|
||||||
|
for (let i = 0; i < liElms.length; i++) {
|
||||||
|
liElms[i].addEventListener('mouseover', () => {
|
||||||
|
liElms[i].style.backgroundColor = '#5e5e5e'
|
||||||
|
})
|
||||||
|
liElms[i].addEventListener('mouseout', () => {
|
||||||
|
liElms[i].style.backgroundColor = 'unset'
|
||||||
|
})
|
||||||
|
liElms[i].addEventListener('click', () => {
|
||||||
|
let key = ''
|
||||||
|
switch (liElms[i].innerHTML) {
|
||||||
|
case '绕鼠标点旋转':
|
||||||
|
object.position = position
|
||||||
|
key = 'rotateAround'
|
||||||
|
// this.rotateAround(position)
|
||||||
|
break
|
||||||
|
case '属性':
|
||||||
|
if(targetId) {
|
||||||
|
object.id = targetId
|
||||||
|
object.parentId = that.options.id
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
object.id = that.options.id
|
||||||
|
}
|
||||||
|
key = 'attribute'
|
||||||
|
// that.edit(true)
|
||||||
|
// this.attribute(entityId)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
eventListener[sdk.div_id].callBack(key, object)
|
||||||
|
_element.removeChild(menuElm)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function getEntityId(movement) {
|
||||||
|
let pick = sdk.viewer.scene.pick(movement.position)
|
||||||
|
if (pick) {
|
||||||
|
if (pick.id) {
|
||||||
|
if (pick.id.type && pick.id.type === 'vector' && pick.id.parentId) {
|
||||||
|
return {
|
||||||
|
parentId: pick.id.parentId,
|
||||||
|
id: pick.id.id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (pick.id.id) {
|
||||||
|
return pick.id.id
|
||||||
|
} else if (typeof pick.id == 'string') {
|
||||||
|
return pick.id
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (pick.primitive && pick.primitive.id) {
|
||||||
|
return pick.primitive.id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getMouseRightMenuStatus(sdk) {
|
||||||
|
if (!sdk || !sdk.div_id || !eventListener[sdk.div_id]) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return eventListener[sdk.div_id].status
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export { MouseRightMenu, getMouseRightMenuStatus }
|
||||||
156
src/Global/mouseRightMenu/index2.js
Normal file
156
src/Global/mouseRightMenu/index2.js
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
/* 右键点击菜单 */
|
||||||
|
import MouseEvent from '../../Event/index'
|
||||||
|
import Tools from '../../Tools';
|
||||||
|
import { rotateAround } from '../../Global/global'
|
||||||
|
|
||||||
|
|
||||||
|
class mouseRightMenu {
|
||||||
|
constructor(sdk, cd) {
|
||||||
|
this.sdk = sdk
|
||||||
|
this.callBack = cd
|
||||||
|
this.mouseRightMenuEvent
|
||||||
|
this.tools = new Tools()
|
||||||
|
document.addEventListener('mousedown', (e)=>{
|
||||||
|
if((e.target.parentNode && e.target.parentNode.id == "custom-menu") || (e.target.parentNode && e.target.parentNode.parentNode && e.target.parentNode.parentNode.id == "custom-menu")) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let menuElm = document.getElementById('custom-menu')
|
||||||
|
if (menuElm) {
|
||||||
|
this.sdk.viewer._element.removeChild(menuElm)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
document.addEventListener('click', (e)=>{
|
||||||
|
if((e.target.parentNode && e.target.parentNode.id == "custom-menu") || (e.target.parentNode && e.target.parentNode.parentNode && e.target.parentNode.parentNode.id == "custom-menu")) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let menuElm = document.getElementById('custom-menu')
|
||||||
|
if (menuElm) {
|
||||||
|
this.sdk.viewer._element.removeChild(menuElm)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
open() {
|
||||||
|
this.mouseRightMenuEvent && this.mouseRightMenuEvent.destroy()
|
||||||
|
this.mouseRightMenuEvent = new MouseEvent(this.sdk)
|
||||||
|
this.mouseRightMenuEvent.mouse_right((movement, cartesian) => {
|
||||||
|
if (YJ.Measure.GetMeasureStatus()) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let menuElm = document.getElementById('custom-menu')
|
||||||
|
if (menuElm) {
|
||||||
|
this.sdk.viewer._element.removeChild(menuElm)
|
||||||
|
}
|
||||||
|
let entityId = this.getEntityId(movement)
|
||||||
|
let addedMenu = ''
|
||||||
|
let that = this.sdk.entityMap.get(entityId)
|
||||||
|
if(!that && entityId) {
|
||||||
|
let array = entityId.split("-");
|
||||||
|
array.splice(array.length - 1, 1)
|
||||||
|
entityId = array.join('-')
|
||||||
|
that = this.sdk.entityMap.get(entityId)
|
||||||
|
}
|
||||||
|
if (that && that.picking) {
|
||||||
|
addedMenu = `
|
||||||
|
<span class="divider" style="display: block;border-top: 1px solid #ddd;margin: 5px;"></span>
|
||||||
|
<ul class="added" style="list-style: none;padding: 0;margin: 0;font-size: 12px;">
|
||||||
|
<li style="padding: 3px 10px;cursor: pointer;">属性</li>
|
||||||
|
</ul>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
let position = this.tools.cartesian3Towgs84(cartesian, this.sdk.viewer)
|
||||||
|
menuElm = document.createElement('div');
|
||||||
|
menuElm.id = 'custom-menu'
|
||||||
|
menuElm.style.position = 'absolute'
|
||||||
|
menuElm.style.width = '110px'
|
||||||
|
menuElm.style.backgroundColor = '#00000085'
|
||||||
|
menuElm.style.color = '#ffffff'
|
||||||
|
menuElm.style.padding = '6px 0'
|
||||||
|
menuElm.style.boxShadow = '4px 4px 4px 0px rgba(0, 0, 0, 0.8)'
|
||||||
|
menuElm.innerHTML = `
|
||||||
|
<ul class="base" style="list-style: none;padding: 0;margin: 0;font-size: 12px;">
|
||||||
|
<li style="padding: 3px 10px;cursor: pointer;">绕鼠标点旋转</li>
|
||||||
|
</ul>
|
||||||
|
${addedMenu}
|
||||||
|
`
|
||||||
|
this.sdk.viewer._element.appendChild(menuElm)
|
||||||
|
let left = movement.position.x
|
||||||
|
let top = movement.position.y
|
||||||
|
if ((movement.position.x + menuElm.offsetWidth) > this.sdk.viewer._element.offsetWidth) {
|
||||||
|
left = movement.position.x - menuElm.offsetWidth
|
||||||
|
}
|
||||||
|
if ((movement.position.y + menuElm.offsetHeight) > this.sdk.viewer._element.offsetHeight) {
|
||||||
|
top = movement.position.y - menuElm.offsetHeight
|
||||||
|
}
|
||||||
|
menuElm.style.left = left + 'px'
|
||||||
|
menuElm.style.top = top + 'px'
|
||||||
|
|
||||||
|
menuElm.addEventListener('contextmenu', function (event) {
|
||||||
|
event.preventDefault();
|
||||||
|
})
|
||||||
|
let liElms = menuElm.getElementsByTagName('li')
|
||||||
|
let object = {}
|
||||||
|
for (let i = 0; i < liElms.length; i++) {
|
||||||
|
liElms[i].addEventListener('mouseover', () => {
|
||||||
|
liElms[i].style.backgroundColor = '#5e5e5e'
|
||||||
|
})
|
||||||
|
liElms[i].addEventListener('mouseout', () => {
|
||||||
|
liElms[i].style.backgroundColor = 'unset'
|
||||||
|
})
|
||||||
|
liElms[i].addEventListener('click', () => {
|
||||||
|
switch (liElms[i].innerHTML) {
|
||||||
|
case '绕中心点旋转':
|
||||||
|
object.position = position
|
||||||
|
// this.rotateAround(position)
|
||||||
|
break
|
||||||
|
case '属性':
|
||||||
|
object.id = that.options.id
|
||||||
|
// that.edit(true)
|
||||||
|
// this.attribute(entityId)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
this.callBack(liElms[i].innerHTML, object)
|
||||||
|
this.sdk.viewer._element.removeChild(menuElm)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
getEntityId(movement) {
|
||||||
|
let pick = this.sdk.viewer.scene.pick(movement.position)
|
||||||
|
if (pick) {
|
||||||
|
if (pick.id) {
|
||||||
|
if (pick.id.id) {
|
||||||
|
return pick.id.id
|
||||||
|
}
|
||||||
|
else if (typeof pick.id == 'string') {
|
||||||
|
return pick.id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (pick.primitive && pick.primitive.id) {
|
||||||
|
return pick.primitive.id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rotateAround(position) {
|
||||||
|
rotateAround(this.sdk, position)
|
||||||
|
}
|
||||||
|
|
||||||
|
attribute(entityId) {
|
||||||
|
if(entityId.endsWith('-label')) {
|
||||||
|
entityId = entityId.replace('-label', '')
|
||||||
|
}
|
||||||
|
let that = this.sdk.entityMap.get(entityId)
|
||||||
|
that && that.edit(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
close() {
|
||||||
|
this.mouseRightMenuEvent && this.mouseRightMenuEvent.destroy()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default mouseRightMenu
|
||||||
397
src/In/index.js
Normal file
397
src/In/index.js
Normal file
@ -0,0 +1,397 @@
|
|||||||
|
import { on } from '../on'
|
||||||
|
import YJEarth from '../YJEarth'
|
||||||
|
import {
|
||||||
|
getCurrentView,
|
||||||
|
setDefaultView,
|
||||||
|
flyTo,
|
||||||
|
CameraController,
|
||||||
|
CesiumContainer,
|
||||||
|
setBillboardDefaultUrl,
|
||||||
|
getBillboardDefaultUrl,
|
||||||
|
setGroundCover,
|
||||||
|
getGroundCover,
|
||||||
|
setBimPickStatus,
|
||||||
|
getBimPickStatus,
|
||||||
|
FlwStatusSwitch,
|
||||||
|
JwwStatusSwitch,
|
||||||
|
rotateAround,
|
||||||
|
getCoordinateSystem,
|
||||||
|
setCoordinateSystem,
|
||||||
|
cameraChanged,
|
||||||
|
setMaximumRequestsPerServer,
|
||||||
|
setKeyboardEventActive,
|
||||||
|
getTheme,
|
||||||
|
setTheme,
|
||||||
|
getCesiumManageIndexexDBState,
|
||||||
|
setCesiumManageIndexexDBState,
|
||||||
|
getCesiumIndexedDBMaxSize,
|
||||||
|
setCesiumIndexedDBMaxSize,
|
||||||
|
getCesiumIndexedDBCurrentSize,
|
||||||
|
enablePerspective,
|
||||||
|
closeRotateAround
|
||||||
|
} from '../Global/global'
|
||||||
|
import { SheetIndexStatusSwitch, changeScale as SheetIndexShangeScale } from '../Global/SheetIndex'
|
||||||
|
import { switchCluster } from '../Global/cluster/cluster'
|
||||||
|
import DTH from '../Global/DTH'
|
||||||
|
import {
|
||||||
|
closeLeftClick,
|
||||||
|
openLeftClick,
|
||||||
|
closeRightClick,
|
||||||
|
openRightClick,
|
||||||
|
openMove,
|
||||||
|
closeMove
|
||||||
|
} from '../Global/ClickCallback'
|
||||||
|
import { startScreenRecord, stopScreenRecord } from '../Global/ScreenRecord'
|
||||||
|
import { ScreenShot, ScreenShotHD } from '../Global/ScreenShot'
|
||||||
|
import ExportKml from '../Global/ExportKml'
|
||||||
|
import { setSkin } from '../Global/Skin'
|
||||||
|
import {
|
||||||
|
open as FlyRoamOpen,
|
||||||
|
close as FlyRoamClose,
|
||||||
|
flyTo as FlyRoamFlyTo,
|
||||||
|
setRepeat as FlyRoamSetRepeat,
|
||||||
|
cease as FlyRoamCease
|
||||||
|
} from '../Global/FlyRoam'
|
||||||
|
import {
|
||||||
|
rain,
|
||||||
|
snow,
|
||||||
|
fog,
|
||||||
|
nightVision,
|
||||||
|
skyStarry,
|
||||||
|
illumination
|
||||||
|
} from '../Global/efflect'
|
||||||
|
import { open as mapxOpen, close as mapxClose } from '../Global/MapX'
|
||||||
|
import {
|
||||||
|
on as multiViewportModeOn,
|
||||||
|
off as multiViewportModeOff,
|
||||||
|
get2DView
|
||||||
|
} from '../Global/MultiViewportMode'
|
||||||
|
import { MouseCoordinate } from '../Global/MouseCoordinate'
|
||||||
|
import { MouseRightMenu } from '../Global/mouseRightMenu'
|
||||||
|
import { dialog as ContourDialog } from '../Global/Contour'
|
||||||
|
import { on as SplitScreenOn, off as SplitScreenOff, setActiveId as SplitScreenSetActiveId } from '../Global/SplitScreen'
|
||||||
|
import LocateCurrent from '../Obj/Base/LocateCurrent'
|
||||||
|
|
||||||
|
import { Clear as AnalysisClear } from '../Obj/Analysis/clear'
|
||||||
|
import CutFillAnalysis from '../Obj/Analysis/CutFill'
|
||||||
|
import Submerge from '../Obj/Analysis/Submerge'
|
||||||
|
import ViewShed from '../Obj/Analysis/ViewShed'
|
||||||
|
import CircleViewShed from '../Obj/Analysis/CircleViewShed'
|
||||||
|
// import Test2 from '../Obj/Analysis/test2'
|
||||||
|
import SlopeAspect from '../Obj/Analysis/SlopeAspect'
|
||||||
|
import Profile from '../Obj/Analysis/Profile'
|
||||||
|
import Visibility from '../Obj/Analysis/Visibility'
|
||||||
|
import Contour from '../Obj/Analysis/Contour'
|
||||||
|
import Section from '../Obj/Analysis/Section'
|
||||||
|
import TerrainExcavation from '../Obj/Analysis/TerrainExcavation'
|
||||||
|
import Flat from '../Obj/Analysis/Flat'
|
||||||
|
|
||||||
|
import MeasureDistance from '../Measure/MeasureDistance'
|
||||||
|
import MeasureProjectionDistance from '../Measure/MeasureProjectionDistance'
|
||||||
|
import MeasureSlopeDistance from '../Measure/MeasureSlopeDistance'
|
||||||
|
import { Clear } from '../Measure/clear'
|
||||||
|
import MeasureTyArea from '../Measure/MeasureTyArea'
|
||||||
|
import MeasureTdArea from '../Measure/MeasureTdArea'
|
||||||
|
import MeasureTriangle from '../Measure/MeasureTriangle'
|
||||||
|
import MeasureLocation from '../Measure/MeasureLocation'
|
||||||
|
import MeasureHeight from '../Measure/MeasureHeight'
|
||||||
|
import MeasureAngle from '../Measure/MeasureAngle'
|
||||||
|
import MeasureAzimuth from '../Measure/MeasureAzimuth'
|
||||||
|
import DrawPolyline from '../Draw/drawPolyline'
|
||||||
|
import DrawPolygon from '../Draw/drawPolygon'
|
||||||
|
import DrawPoint from '../Draw/drawPoint'
|
||||||
|
import DrawCircle from '../Draw/drawCircle'
|
||||||
|
import DrawElliptic from '../Draw/drawElliptic'
|
||||||
|
import DrawAttackArrow from '../Draw/drawAttackArrow'
|
||||||
|
import DrawPincerArrow from '../Draw/drawPincerArrow'
|
||||||
|
import DrawStraightArrow from '../Draw/drawStraightArrow'
|
||||||
|
import DrawRect from '../Draw/drawRect'
|
||||||
|
import DrawAssemble from '../Draw/drawAssemble'
|
||||||
|
import DrawSector from '../Draw/drawSector'
|
||||||
|
import {
|
||||||
|
ArcgisBLUEImagery,
|
||||||
|
ArcgisLWImagery,
|
||||||
|
ArcgisWXImagery
|
||||||
|
} from '../Obj/Base/BaseSource/BaseLayer/ArcgisImagery'
|
||||||
|
import {
|
||||||
|
GDLWImagery,
|
||||||
|
GDSLImagery,
|
||||||
|
GDWXImagery
|
||||||
|
} from '../Obj/Base/BaseSource/BaseLayer/GdImagery'
|
||||||
|
import Tileset from '../Obj/Base/BaseSource/BaseTileset/Tileset'
|
||||||
|
import BIM from '../Obj/Base/BaseSource/BaseTileset/BIM'
|
||||||
|
import Model from '../Obj/Base/BaseSource/BaseModel/Model'
|
||||||
|
import Model2 from '../Obj/Base/BaseSource/BaseModel/Model2'
|
||||||
|
import Layer from '../Obj/Base/BaseSource/BaseLayer/Layer'
|
||||||
|
import Layer3rdparty from '../Obj/Base/BaseSource/BaseLayer/Layer3rdparty'
|
||||||
|
import Terrain from '../Obj/Base/BaseSource/BaseTerrain'
|
||||||
|
import Flame from '../Obj/Base/ParticleEffects/Flame'
|
||||||
|
import Smoke from '../Obj/Base/ParticleEffects/Smoke'
|
||||||
|
import Fountain from '../Obj/Base/ParticleEffects/Fountain'
|
||||||
|
import Spout from '../Obj/Base/ParticleEffects/Spout'
|
||||||
|
import PolygonObject from '../Obj/Base/PolygonObject'
|
||||||
|
import PolyhedronObject from '../Obj/Base/PolyhedronObject'
|
||||||
|
// import PolyhedronObject2 from '../Obj/Base/PolyhedronObject2'
|
||||||
|
import AssembleObject from '../Obj/Base/AssembleObject'
|
||||||
|
import AttackArrowObject from '../Obj/Base/AttackArrowObject'
|
||||||
|
import PincerArrowObject from '../Obj/Base/PincerArrowObject'
|
||||||
|
import StraightArrowObject from '../Obj/Base/StraightArrowObject'
|
||||||
|
import CircleDiffuse from '../Obj/Base/CircleDiffuse'
|
||||||
|
import CircleObject from '../Obj/Base/CircleObject'
|
||||||
|
import EllipseObject from '../Obj/Base/EllipseObject'
|
||||||
|
import WallStereoscopic from '../Obj/Base/WallStereoscopic'
|
||||||
|
import WallRealStereoscopic from '../Obj/Base/WallRealStereoscopic'
|
||||||
|
// import Corridor from '../Obj/Base/Corridor'
|
||||||
|
import BillboardObject from '../Obj/Base/BillboardObject'
|
||||||
|
import PolylineObject from '../Obj/Base/PolylineObject'
|
||||||
|
import CurvelineObject from '../Obj/Base/CurvelineObject'
|
||||||
|
// import EllipseObject from '../Obj/Base/EllipseObject'
|
||||||
|
import Explosion from '../Obj/Base/Explosion'
|
||||||
|
import RadarScan from '../Obj/Base/RadarScan'
|
||||||
|
import RadarScanStereoscopic from '../Obj/Base/RadarScanStereoscopic'
|
||||||
|
import SectorObject from '../Obj/Base/SectorObject'
|
||||||
|
import KML from '../Obj/Base/KML'
|
||||||
|
import GeoJson from '../Obj/Base/GeoJson'
|
||||||
|
import WaterSurface from '../Obj/Base/WaterSurface'
|
||||||
|
// import ItineraryMove from '../Obj/Base/ItineraryMove'
|
||||||
|
import TrajectoryMotion from '../Obj/Base/TrajectoryMotion'
|
||||||
|
import TrajectoryMotionObject from '../Obj/Base/TrajectoryMotionObject'
|
||||||
|
import Road from '../Obj/Base/Road'
|
||||||
|
import Graffiti from '../Obj/Base/Graffiti'
|
||||||
|
import GroundImage from '../Obj/Base/GroundImage'
|
||||||
|
import GroundSvg from '../Obj/Base/GroundSvg'
|
||||||
|
import RoutePlanning from '../Obj/Base/RoutePlanning'
|
||||||
|
import Shp from '../Obj/Base/Shp'
|
||||||
|
import Vector from '../Obj/Base/Vector'
|
||||||
|
// import Text3D from "../Obj/Base/TextObject/3DText";
|
||||||
|
import GroundText from '../Obj/Base/TextObject/GroundText'
|
||||||
|
import StandText from '../Obj/Base/TextObject/StandText'
|
||||||
|
import { Clear as ClearAllRoutePlanning } from '../Obj/Base/RoutePlanning/clear'
|
||||||
|
import RichText from '../Obj/Element/richText'
|
||||||
|
import Tools from '../Tools'
|
||||||
|
import { Proj } from '../Tools/proj'
|
||||||
|
import CoordTransform from '../transform/CoordTransform'
|
||||||
|
import LoadObjModel from '../Obj/Base/LoadObjModel'
|
||||||
|
import DZXJLoadObjModel from '../DZ/XJ/LoadObjModel'
|
||||||
|
import BatchLoadObjModel from '../DZ/XJ/BatchLoadObjModel'
|
||||||
|
import Heatmap from '../Obj/Base/Heatmap'
|
||||||
|
import FlyRoam from '../Obj/Base/FlyRoam'
|
||||||
|
import Dialog from '../Obj/Element/Dialog'
|
||||||
|
// import AirLine from '../Obj/AirLine'
|
||||||
|
// import GenerateRoute from '../Obj/AirLine/GenerateRoute'
|
||||||
|
import newAirLine from '../Obj/AirLine/pointRoute.js'
|
||||||
|
import Frustum from '../Obj/AirLine/frustum'
|
||||||
|
import DrawTakeOff from '../Obj/AirLine/DrawTakeOff'
|
||||||
|
|
||||||
|
const YJEarthismeasuring = Symbol('测量状态')
|
||||||
|
const screenRecord = Symbol('录屏对象')
|
||||||
|
if (!window.YJ) {
|
||||||
|
window.YJ = {
|
||||||
|
on,
|
||||||
|
Obj: {
|
||||||
|
ArcgisWXImagery,
|
||||||
|
ArcgisBLUEImagery,
|
||||||
|
ArcgisLWImagery,
|
||||||
|
GDLWImagery,
|
||||||
|
GDWXImagery,
|
||||||
|
GDSLImagery,
|
||||||
|
Tileset,
|
||||||
|
BIM,
|
||||||
|
Layer,
|
||||||
|
Layer3rdparty,
|
||||||
|
Terrain,
|
||||||
|
Flame,
|
||||||
|
Smoke,
|
||||||
|
Fountain,
|
||||||
|
Spout,
|
||||||
|
WaterSurface,
|
||||||
|
CircleDiffuse,
|
||||||
|
CircleObject,
|
||||||
|
EllipseObject,
|
||||||
|
RadarScan,
|
||||||
|
RadarScanStereoscopic,
|
||||||
|
SectorObject,
|
||||||
|
WallStereoscopic,
|
||||||
|
WallRealStereoscopic,
|
||||||
|
KML,
|
||||||
|
GeoJson,
|
||||||
|
// ItineraryMove,
|
||||||
|
BillboardObject,
|
||||||
|
PolygonObject,
|
||||||
|
PolyhedronObject,
|
||||||
|
// PolyhedronObject2,
|
||||||
|
AssembleObject,
|
||||||
|
AttackArrowObject,
|
||||||
|
PincerArrowObject,
|
||||||
|
StraightArrowObject,
|
||||||
|
// Corridor,
|
||||||
|
PolylineObject,
|
||||||
|
CurvelineObject,
|
||||||
|
// EllipseObject,
|
||||||
|
Explosion,
|
||||||
|
Model,
|
||||||
|
Model2,
|
||||||
|
TrajectoryMotion,
|
||||||
|
TrajectoryMotionObject,
|
||||||
|
Road,
|
||||||
|
Graffiti,
|
||||||
|
GroundImage,
|
||||||
|
GroundSvg,
|
||||||
|
RoutePlanning,
|
||||||
|
Shp,
|
||||||
|
Vector,
|
||||||
|
// Text3D,
|
||||||
|
GroundText,
|
||||||
|
StandText,
|
||||||
|
RichText,
|
||||||
|
LocateCurrent,
|
||||||
|
LoadObjModel,
|
||||||
|
Heatmap,
|
||||||
|
FlyRoam,
|
||||||
|
// AirLine,
|
||||||
|
newAirLine,
|
||||||
|
FRUSTUN: Frustum,
|
||||||
|
// GenerateRoute
|
||||||
|
Dialog
|
||||||
|
},
|
||||||
|
YJEarth,
|
||||||
|
Tools,
|
||||||
|
Proj,
|
||||||
|
Global: {
|
||||||
|
getCurrentView,
|
||||||
|
setDefaultView,
|
||||||
|
switchCluster,
|
||||||
|
openLeftClick,
|
||||||
|
closeLeftClick,
|
||||||
|
closeRightClick,
|
||||||
|
openRightClick,
|
||||||
|
openMove,
|
||||||
|
closeMove,
|
||||||
|
ScreenRecord: {
|
||||||
|
start: () => {
|
||||||
|
return startScreenRecord(screenRecord)
|
||||||
|
},
|
||||||
|
stop: () => {
|
||||||
|
return stopScreenRecord()
|
||||||
|
},
|
||||||
|
screenRecord: null
|
||||||
|
},
|
||||||
|
MapX: {
|
||||||
|
open: mapxOpen,
|
||||||
|
close: mapxClose
|
||||||
|
},
|
||||||
|
ScreenShot,
|
||||||
|
ScreenShotHD,
|
||||||
|
ExportKml,
|
||||||
|
FlyRoam: {
|
||||||
|
open: FlyRoamOpen,
|
||||||
|
close: FlyRoamClose,
|
||||||
|
flyTo: FlyRoamFlyTo,
|
||||||
|
setRepeat: FlyRoamSetRepeat,
|
||||||
|
cease: FlyRoamCease
|
||||||
|
},
|
||||||
|
flyTo,
|
||||||
|
efflect: { rain, snow, fog, nightVision, skyStarry, illumination },
|
||||||
|
CameraController,
|
||||||
|
CesiumContainer,
|
||||||
|
setBillboardDefaultUrl,
|
||||||
|
getBillboardDefaultUrl,
|
||||||
|
multiViewportMode: {
|
||||||
|
on: multiViewportModeOn,
|
||||||
|
off: multiViewportModeOff,
|
||||||
|
get2DView
|
||||||
|
},
|
||||||
|
MouseCoordinate,
|
||||||
|
MouseRightMenu,
|
||||||
|
setGroundCover,
|
||||||
|
getGroundCover,
|
||||||
|
setBimPickStatus,
|
||||||
|
getBimPickStatus,
|
||||||
|
FlwStatusSwitch,
|
||||||
|
JwwStatusSwitch,
|
||||||
|
rotateAround,
|
||||||
|
getCoordinateSystem,
|
||||||
|
setCoordinateSystem,
|
||||||
|
DTH,
|
||||||
|
cameraChanged,
|
||||||
|
setMaximumRequestsPerServer,
|
||||||
|
setKeyboardEventActive,
|
||||||
|
setSkin,
|
||||||
|
getTheme,
|
||||||
|
setTheme,
|
||||||
|
getCesiumManageIndexexDBState,
|
||||||
|
setCesiumManageIndexexDBState,
|
||||||
|
getCesiumIndexedDBMaxSize,
|
||||||
|
setCesiumIndexedDBMaxSize,
|
||||||
|
getCesiumIndexedDBCurrentSize,
|
||||||
|
enablePerspective,
|
||||||
|
closeRotateAround,
|
||||||
|
SheetIndexStatusSwitch,
|
||||||
|
SheetIndexShangeScale,
|
||||||
|
splitScreen: {
|
||||||
|
on: SplitScreenOn,
|
||||||
|
off: SplitScreenOff,
|
||||||
|
setActiveId: SplitScreenSetActiveId
|
||||||
|
},
|
||||||
|
Contour: ContourDialog
|
||||||
|
}, //测量
|
||||||
|
Measure: {
|
||||||
|
GetMeasureStatus: () => {
|
||||||
|
return YJ.Measure[YJEarthismeasuring]
|
||||||
|
},
|
||||||
|
SetMeasureStatus: (status = false) => {
|
||||||
|
YJ.Measure[YJEarthismeasuring] = status
|
||||||
|
},
|
||||||
|
Clear,
|
||||||
|
Measures: [],
|
||||||
|
MeasureDistance,
|
||||||
|
MeasureProjectionDistance,
|
||||||
|
MeasureSlopeDistance,
|
||||||
|
MeasureTyArea,
|
||||||
|
MeasureTdArea,
|
||||||
|
MeasureTriangle,
|
||||||
|
MeasureLocation,
|
||||||
|
MeasureHeight,
|
||||||
|
MeasureAngle,
|
||||||
|
MeasureAzimuth
|
||||||
|
},
|
||||||
|
Draw: {
|
||||||
|
DrawPolyline,
|
||||||
|
DrawPolygon,
|
||||||
|
DrawPoint,
|
||||||
|
DrawCircle,
|
||||||
|
DrawElliptic,
|
||||||
|
DrawAttackArrow,
|
||||||
|
DrawPincerArrow,
|
||||||
|
DrawStraightArrow,
|
||||||
|
DrawRect,
|
||||||
|
DrawAssemble,
|
||||||
|
DrawSector,
|
||||||
|
DrawTakeOff,
|
||||||
|
},
|
||||||
|
// 分析
|
||||||
|
Analysis: {
|
||||||
|
Clear: AnalysisClear,
|
||||||
|
CutFillAnalysis,
|
||||||
|
Submerge,
|
||||||
|
ViewShed,
|
||||||
|
CircleViewShed,
|
||||||
|
// Test2,
|
||||||
|
SlopeAspect,
|
||||||
|
Profile,
|
||||||
|
Visibility,
|
||||||
|
Contour,
|
||||||
|
Section,
|
||||||
|
TerrainExcavation,
|
||||||
|
Flat,
|
||||||
|
Analyses: []
|
||||||
|
},
|
||||||
|
CoordTransform,
|
||||||
|
RoutePlanningArrays: [],
|
||||||
|
ClearAllRoutePlanning
|
||||||
|
}
|
||||||
|
if (process.env.DZ === 'xj') {
|
||||||
|
window.YJ.Obj.LoadObjModel = DZXJLoadObjModel
|
||||||
|
window.YJ.Obj.BatchLoadObjModel = BatchLoadObjModel
|
||||||
|
}
|
||||||
|
}
|
||||||
209
src/Measure/MeasureAngle/index.js
Normal file
209
src/Measure/MeasureAngle/index.js
Normal file
@ -0,0 +1,209 @@
|
|||||||
|
/**
|
||||||
|
* @name: index
|
||||||
|
* @author: Administrator
|
||||||
|
* @date: 2023-12-29 10:11
|
||||||
|
* @description:index
|
||||||
|
* @update: 2023-12-29 10:11
|
||||||
|
*/
|
||||||
|
import Measure from "../index";
|
||||||
|
|
||||||
|
class MeasureAngle extends Measure {
|
||||||
|
constructor(sdk) {
|
||||||
|
super(sdk, { text: "左键开始,右键取消" });
|
||||||
|
this.cachePositions = []
|
||||||
|
this.positions = []
|
||||||
|
this.arcPositions = []
|
||||||
|
this.line_id = ""
|
||||||
|
this.label_id = ""
|
||||||
|
this.arc_id = ""
|
||||||
|
this.bearing = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
createPolyline() {
|
||||||
|
let that = this
|
||||||
|
let id = that.randomString()
|
||||||
|
that.viewer.entities.add(new Cesium.Entity({
|
||||||
|
id,
|
||||||
|
polyline: {
|
||||||
|
positions: new Cesium.CallbackProperty(() => {
|
||||||
|
return that.positions
|
||||||
|
}, false),
|
||||||
|
clampToGround: true,
|
||||||
|
width: 5,
|
||||||
|
material: new Cesium.Color.fromCssColorString(that.options.color || that.defaultColor),
|
||||||
|
zIndex: 99999999
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
return id
|
||||||
|
}
|
||||||
|
|
||||||
|
end() {
|
||||||
|
super.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
destroy() {
|
||||||
|
super.destroy();
|
||||||
|
let arr = [this.line_id, this.label_id, this.arc_id]
|
||||||
|
arr.forEach(id => {
|
||||||
|
if (id)
|
||||||
|
this.remove_entity(id)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
cancel() {
|
||||||
|
this.end()
|
||||||
|
this.destroy()
|
||||||
|
}
|
||||||
|
|
||||||
|
caculateAngle(points = []) {
|
||||||
|
let p1 = this.cartesian3Towgs84(points[0], this.viewer)
|
||||||
|
let p2 = this.cartesian3Towgs84(points[1], this.viewer)
|
||||||
|
let p3 = this.cartesian3Towgs84(points[2], this.viewer)
|
||||||
|
let point1 = turf.point([p1.lng, p1.lat]);
|
||||||
|
let point2 = turf.point([p2.lng, p2.lat]);
|
||||||
|
let point3 = turf.point([p3.lng, p3.lat]);
|
||||||
|
let options = { units: 'kilometers' };
|
||||||
|
let distance1 = turf.rhumbDistance(point1, point2, options);
|
||||||
|
let distance2 = turf.rhumbDistance(point3, point2, options);
|
||||||
|
let distance = distance1
|
||||||
|
if (distance1 > distance2) {
|
||||||
|
distance = distance2
|
||||||
|
}
|
||||||
|
|
||||||
|
let bearing1 = turf.rhumbBearing(point1, point2)
|
||||||
|
let bearing2 = turf.rhumbBearing(point3, point2)
|
||||||
|
|
||||||
|
let bearing = Math.abs(((bearing1 - bearing2) + 360) % 360)
|
||||||
|
if (bearing > 180) {
|
||||||
|
this.bearing = 360 - bearing
|
||||||
|
} else {
|
||||||
|
this.bearing = bearing
|
||||||
|
}
|
||||||
|
this.bearing = this.bearing.toFixed(2)
|
||||||
|
|
||||||
|
let b1 = (bearing1 - 180)
|
||||||
|
let b2 = (bearing2 - 180)
|
||||||
|
let arc = turf.lineArc(point2, (distance / 3), b2, b1);
|
||||||
|
if (bearing > 180) {
|
||||||
|
arc = turf.lineArc(point2, (distance / 3), b1, b2);
|
||||||
|
}
|
||||||
|
let arcPos = []
|
||||||
|
for (let i = 0; i < arc.geometry.coordinates.length; i++) {
|
||||||
|
arcPos.push(Cesium.Cartesian3.fromDegrees(arc.geometry.coordinates[i][0], arc.geometry.coordinates[i][1]))
|
||||||
|
}
|
||||||
|
this.arcPositions = arcPos
|
||||||
|
|
||||||
|
// if (bearing1 > 0 && bearing2 > 0) {
|
||||||
|
// this.bearing = Math.abs(bearing1 - bearing2).toFixed(1)
|
||||||
|
// } else if (bearing1 < 0 && bearing2 < 0) {
|
||||||
|
// this.bearing = Math.abs(bearing1 - bearing2).toFixed(1)
|
||||||
|
// } else if (bearing1 > 0 && bearing2 < 0) {
|
||||||
|
// this.bearing = Math.abs(360 - Math.abs(bearing2) - bearing1).toFixed(1)
|
||||||
|
// } else {
|
||||||
|
// this.bearing = Math.abs(360 - Math.abs(bearing1) - bearing2).toFixed(1)
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
start() {
|
||||||
|
if (!YJ.Measure.GetMeasureStatus()) {
|
||||||
|
super.start();
|
||||||
|
|
||||||
|
let leftEvent = (movement, car) => {
|
||||||
|
if (this.ids.length === 0) {
|
||||||
|
//需要创建一个线
|
||||||
|
this.line_id = this.createPolyline()
|
||||||
|
}
|
||||||
|
|
||||||
|
this.ids.push(this.create_point(car))
|
||||||
|
this.tip.setPosition(car, movement.position.x, movement.position.y)
|
||||||
|
this.cachePositions.push(car)
|
||||||
|
if (this.cachePositions.length) {
|
||||||
|
this.positions = this.cachePositions.concat(car)
|
||||||
|
}
|
||||||
|
if (this.ids.length === 2) {
|
||||||
|
this.label_id = Cesium.createGuid()
|
||||||
|
this.arc_id = Cesium.createGuid()
|
||||||
|
let p = this.cartesian3Towgs84(car, this.viewer)
|
||||||
|
this.sampleHeightMostDetailed([p]).then((res) => {
|
||||||
|
let arc = this.viewer.entities.add({
|
||||||
|
id: this.arc_id,
|
||||||
|
polyline: {
|
||||||
|
positions: new Cesium.CallbackProperty(() => {
|
||||||
|
return this.arcPositions
|
||||||
|
}, false),
|
||||||
|
clampToGround: true,
|
||||||
|
width: 5,
|
||||||
|
material: new Cesium.Color.fromCssColorString(this.options.color || this.defaultColor),
|
||||||
|
zIndex: 99999999
|
||||||
|
}
|
||||||
|
})
|
||||||
|
let label = this.viewer.entities.add({
|
||||||
|
id: this.label_id,
|
||||||
|
position: Cesium.Cartesian3.fromDegrees(p.lng, p.lat, (res[0].height || 0) + 0.1),
|
||||||
|
label: {
|
||||||
|
text: new Cesium.CallbackProperty(() => {
|
||||||
|
return "夹角:" + this.bearing + "°"
|
||||||
|
}, false),
|
||||||
|
font: '20px Microsoft YaHei',
|
||||||
|
fillColor: Cesium.Color.fromCssColorString('#f1e605'),
|
||||||
|
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
|
||||||
|
//标注的遮挡距离设置为100则视角与标注的距离大于100米时会有遮挡
|
||||||
|
// distanceDisplayCondition: this.distanceDisplayCondition,
|
||||||
|
scale: 1,
|
||||||
|
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
|
||||||
|
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||||||
|
disableDepthTestDistance: Number.POSITIVE_INFINITY,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (this.ids.length === 3) {
|
||||||
|
this.caculateAngle([this.positions[0], this.positions[1], this.positions[2]])
|
||||||
|
//需要停止绘制
|
||||||
|
this.end()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
this.event.mouse_left(leftEvent)
|
||||||
|
this.event.mouse_move((movement, car) => {
|
||||||
|
this.tip.setPosition(car, movement.endPosition.x, movement.endPosition.y)
|
||||||
|
if (this.cachePositions.length) {
|
||||||
|
this.positions = this.cachePositions.concat(car)
|
||||||
|
}
|
||||||
|
if (this.positions.length > 2) {
|
||||||
|
//需要开始计算夹角
|
||||||
|
this.caculateAngle([this.positions[0], this.positions[1], this.positions[2]])
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.event.mouse_right((movement, car) => {
|
||||||
|
this.cancel()
|
||||||
|
})
|
||||||
|
|
||||||
|
this.event.gesture_pinck_start((movement, cartesian) => {
|
||||||
|
let startTime = new Date()
|
||||||
|
let pos = {
|
||||||
|
position: {
|
||||||
|
x: (movement.position1.x + movement.position2.x) / 2,
|
||||||
|
y: (movement.position1.y + movement.position2.y) / 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.event.gesture_pinck_end(() => {
|
||||||
|
let endTime = new Date()
|
||||||
|
if (endTime - startTime >= 500) {
|
||||||
|
// 长按取消
|
||||||
|
this.cancel()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
leftEvent(pos, cartesian)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default MeasureAngle
|
||||||
206
src/Measure/MeasureAzimuth/index.js
Normal file
206
src/Measure/MeasureAzimuth/index.js
Normal file
@ -0,0 +1,206 @@
|
|||||||
|
import Measure from "../index";
|
||||||
|
|
||||||
|
class MeasureAzimuth extends Measure {
|
||||||
|
/**
|
||||||
|
* @constructor
|
||||||
|
* @param sdk
|
||||||
|
* @description 方位角测量
|
||||||
|
* */
|
||||||
|
constructor(sdk) {
|
||||||
|
super(sdk, { text: "左键开始,右键取消" });
|
||||||
|
this.cachePositions = []
|
||||||
|
this.positions = []
|
||||||
|
this.arcPositions = []
|
||||||
|
this.line_id = ""
|
||||||
|
this.label_id = ""
|
||||||
|
this.arc_id = ""
|
||||||
|
this.bearing = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
createPolyline() {
|
||||||
|
let that = this
|
||||||
|
let id = that.randomString()
|
||||||
|
that.viewer.entities.add(new Cesium.Entity({
|
||||||
|
id,
|
||||||
|
polyline: {
|
||||||
|
positions: new Cesium.CallbackProperty(() => {
|
||||||
|
return that.positions
|
||||||
|
}, false),
|
||||||
|
clampToGround: true,
|
||||||
|
width: 5,
|
||||||
|
material: new Cesium.Color.fromCssColorString(that.options.color || that.defaultColor),
|
||||||
|
zIndex: 99999999
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
return id
|
||||||
|
}
|
||||||
|
|
||||||
|
end() {
|
||||||
|
super.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
destroy() {
|
||||||
|
super.destroy();
|
||||||
|
let arr = [this.line_id, this.label_id, this.arc_id]
|
||||||
|
arr.forEach(id => {
|
||||||
|
if (id)
|
||||||
|
this.remove_entity(id)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
cancel() {
|
||||||
|
this.end()
|
||||||
|
this.destroy()
|
||||||
|
}
|
||||||
|
|
||||||
|
caculateAngle(line1 = [], line2 = []) {
|
||||||
|
let c = this.cartesian3Towgs84(line2[1], this.viewer)
|
||||||
|
let p2 = this.cartesian3Towgs84(line2[0], this.viewer)
|
||||||
|
let center = turf.point([c.lng, c.lat])
|
||||||
|
let point2 = turf.point([p2.lng, p2.lat])
|
||||||
|
let bearing = this.rhumbBearing(p2, c)
|
||||||
|
this.bearing = (180 + bearing).toFixed(2)
|
||||||
|
|
||||||
|
let distance = turf.rhumbDistance(center, point2, { units: 'kilometers' });
|
||||||
|
let arc = turf.lineArc(center, (distance/3), 0, this.bearing);
|
||||||
|
let arcPos = []
|
||||||
|
for (let i = 0; i < arc.geometry.coordinates.length; i++) {
|
||||||
|
arcPos.push(Cesium.Cartesian3.fromDegrees(arc.geometry.coordinates[i][0], arc.geometry.coordinates[i][1]))
|
||||||
|
}
|
||||||
|
this.arcPositions = arcPos
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
start() {
|
||||||
|
if (!YJ.Measure.GetMeasureStatus()) {
|
||||||
|
super.start();
|
||||||
|
|
||||||
|
let leftEvent = async (movement, car) => {
|
||||||
|
if (this.ids.length === 0) {
|
||||||
|
//需要创建一个线
|
||||||
|
this.line_id = this.createPolyline()
|
||||||
|
}
|
||||||
|
this.tip.setPosition(car, movement.position.x, movement.position.y)
|
||||||
|
if (this.cachePositions.length) {
|
||||||
|
this.positions = this.cachePositions.concat(car)
|
||||||
|
let p = this.cartesian3Towgs84(car, this.viewer)
|
||||||
|
let pc = this.cartesian3Towgs84(this.positions[1], this.viewer)
|
||||||
|
let from = turf.point([pc.lng, pc.lat]);
|
||||||
|
let to = turf.point([p.lng, p.lat]);
|
||||||
|
let options = { units: 'kilometers' };
|
||||||
|
let distance = turf.rhumbDistance(from, to, options);
|
||||||
|
|
||||||
|
let bearing = 0;
|
||||||
|
let destination = turf.destination(from, distance, bearing, options);
|
||||||
|
this.positions[0] = Cesium.Cartesian3.fromDegrees(...destination.geometry.coordinates)
|
||||||
|
}
|
||||||
|
this.cachePositions.push(car)
|
||||||
|
this.cachePositions.push(car)
|
||||||
|
if (this.positions.length > 2) {
|
||||||
|
//需要开始计算夹角
|
||||||
|
this.caculateAngle(
|
||||||
|
[this.positions[0], this.positions[1]],
|
||||||
|
[this.positions[2], this.positions[1]])
|
||||||
|
}
|
||||||
|
if (this.ids.length >= 2) {
|
||||||
|
//需要停止绘制
|
||||||
|
this.end()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.ids.push(this.create_point(car))
|
||||||
|
this.ids.push(this.create_point(car))
|
||||||
|
if (this.ids.length === 2) {
|
||||||
|
this.label_id = Cesium.createGuid()
|
||||||
|
this.arc_id = Cesium.createGuid()
|
||||||
|
let p = this.cartesian3Towgs84(car, this.viewer)
|
||||||
|
let res = await this.sampleHeightMostDetailed([p])
|
||||||
|
|
||||||
|
let arc = this.viewer.entities.add({
|
||||||
|
id: this.arc_id,
|
||||||
|
polyline: {
|
||||||
|
positions: new Cesium.CallbackProperty(() => {
|
||||||
|
return this.arcPositions
|
||||||
|
}, false),
|
||||||
|
clampToGround: true,
|
||||||
|
width: 5,
|
||||||
|
material: new Cesium.Color.fromCssColorString(this.options.color || this.defaultColor),
|
||||||
|
zIndex: 99999999
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
let label = this.viewer.entities.add({
|
||||||
|
id: this.label_id,
|
||||||
|
position: Cesium.Cartesian3.fromDegrees(p.lng, p.lat, (res[0].height || 0) + 0.1),
|
||||||
|
label: {
|
||||||
|
text: new Cesium.CallbackProperty(() => {
|
||||||
|
return "方位夹角:" + this.bearing + "°"
|
||||||
|
}, false),
|
||||||
|
font: '20px Microsoft YaHei',
|
||||||
|
fillColor: Cesium.Color.fromCssColorString('#f1e605'),
|
||||||
|
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
|
||||||
|
//标注的遮挡距离设置为100则视角与标注的距离大于100米时会有遮挡
|
||||||
|
// distanceDisplayCondition: this.distanceDisplayCondition,
|
||||||
|
scale: 1,
|
||||||
|
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
|
||||||
|
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||||||
|
disableDepthTestDistance: Number.POSITIVE_INFINITY,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
//需要创建夹角的显示效果
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
this.event.mouse_left(leftEvent)
|
||||||
|
this.event.mouse_move((movement, car) => {
|
||||||
|
this.tip.setPosition(car, movement.endPosition.x, movement.endPosition.y)
|
||||||
|
if (this.cachePositions.length) {
|
||||||
|
this.positions = this.cachePositions.concat(car)
|
||||||
|
let p = this.cartesian3Towgs84(car, this.viewer)
|
||||||
|
let pc = this.cartesian3Towgs84(this.positions[1], this.viewer)
|
||||||
|
let from = turf.point([pc.lng, pc.lat]);
|
||||||
|
let to = turf.point([p.lng, p.lat]);
|
||||||
|
let options = { units: 'kilometers' };
|
||||||
|
let distance = turf.rhumbDistance(from, to, options);
|
||||||
|
|
||||||
|
let bearing = 0;
|
||||||
|
let destination = turf.destination(from, distance, bearing, options);
|
||||||
|
this.positions[0] = Cesium.Cartesian3.fromDegrees(...destination.geometry.coordinates)
|
||||||
|
}
|
||||||
|
if (this.positions.length > 2) {
|
||||||
|
//需要开始计算夹角
|
||||||
|
this.caculateAngle(
|
||||||
|
[this.positions[0], this.positions[1]],
|
||||||
|
[this.positions[2], this.positions[1]])
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.event.mouse_right((movement, car) => {
|
||||||
|
this.cancel()
|
||||||
|
})
|
||||||
|
|
||||||
|
this.event.gesture_pinck_start((movement, cartesian) => {
|
||||||
|
let startTime = new Date()
|
||||||
|
let pos = {
|
||||||
|
position: {
|
||||||
|
x: (movement.position1.x + movement.position2.x) / 2,
|
||||||
|
y: (movement.position1.y + movement.position2.y) / 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.event.gesture_pinck_end(() => {
|
||||||
|
let endTime = new Date()
|
||||||
|
if (endTime - startTime >= 500) {
|
||||||
|
// 长按取消
|
||||||
|
this.cancel()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
leftEvent(pos, cartesian)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default MeasureAzimuth
|
||||||
18
src/Measure/MeasureCircle/index.js
Normal file
18
src/Measure/MeasureCircle/index.js
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import Measure from '../index'
|
||||||
|
|
||||||
|
/**@extends Measure*/
|
||||||
|
class MeasureCircle extends Measure {
|
||||||
|
constructor(sdk, options = {}) {
|
||||||
|
super(sdk, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
start() {
|
||||||
|
super.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
end() {
|
||||||
|
super.end();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default MeasureCircle
|
||||||
326
src/Measure/MeasureDistance/index.js
Normal file
326
src/Measure/MeasureDistance/index.js
Normal file
@ -0,0 +1,326 @@
|
|||||||
|
/**
|
||||||
|
* @name: index
|
||||||
|
* @author: Administrator
|
||||||
|
* @date: 2022-07-11 10:31
|
||||||
|
* @description:index
|
||||||
|
* @update: 2022-07-11 10:31
|
||||||
|
*/
|
||||||
|
|
||||||
|
import Measure from "../index"
|
||||||
|
|
||||||
|
class MeasureDistance extends Measure {
|
||||||
|
/**
|
||||||
|
* @constructor
|
||||||
|
* @param sdk
|
||||||
|
* @description 距离测量
|
||||||
|
* */
|
||||||
|
constructor(sdk, options = {}) {
|
||||||
|
super(sdk, options)
|
||||||
|
this.options.color = this.options.color || "#00ffff"
|
||||||
|
this.start_id = ""
|
||||||
|
this.end_id = ""
|
||||||
|
this.polyline_id = ""
|
||||||
|
this.clampPositions = []
|
||||||
|
}
|
||||||
|
|
||||||
|
async clampToGroundMeasure(meters, cb) {
|
||||||
|
let positions = []
|
||||||
|
this.ids.forEach((id, index) => {
|
||||||
|
let p = this.viewer.entities.getById(id).position.getValue()
|
||||||
|
positions.push(this.cartesian3Towgs84(p, this.viewer))
|
||||||
|
})
|
||||||
|
let res = this.chunkLine(positions, meters)
|
||||||
|
let coordinates = []
|
||||||
|
res.forEach((Feature, index) => {
|
||||||
|
if (index === 0) {
|
||||||
|
coordinates = [...Feature.geometry.coordinates]
|
||||||
|
} else {
|
||||||
|
coordinates.push(Feature.geometry.coordinates[1])
|
||||||
|
}
|
||||||
|
})
|
||||||
|
let total = coordinates.length
|
||||||
|
|
||||||
|
for (const item of coordinates) {
|
||||||
|
const index = coordinates.indexOf(item);
|
||||||
|
let r = await this.getHeight({lng: item[0], lat: item[1], alt: 0}, index, total,)
|
||||||
|
cb(null, r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async computeDisByTowPoint(p1, p2) {
|
||||||
|
let d = this.computeDistance([p1, p2])
|
||||||
|
let meters = 10
|
||||||
|
let createLabel = (distance) => {
|
||||||
|
if(this._isDestroy) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let label = this.getLabel("贴地距离:" + Number(distance).toFixed(2) + "米")
|
||||||
|
label.pixelOffset = new Cesium.Cartesian2(
|
||||||
|
0, -(32)
|
||||||
|
)
|
||||||
|
this.ids.push(MeasureDistance.create_point(Cesium.Cartesian3.fromDegrees(p2.lng, p2.lat, p2.alt), {label: label}, this))
|
||||||
|
}
|
||||||
|
let start = async (meters) => {
|
||||||
|
let res = this.chunkLine([p1, p2], meters)
|
||||||
|
let coordinates = []
|
||||||
|
res.forEach((Feature, index) => {
|
||||||
|
if (index === 0) {
|
||||||
|
coordinates = [...Feature.geometry.coordinates]
|
||||||
|
} else {
|
||||||
|
coordinates.push(Feature.geometry.coordinates[1])
|
||||||
|
}
|
||||||
|
})
|
||||||
|
let arr = []
|
||||||
|
for (const item of coordinates) {
|
||||||
|
const index = coordinates.indexOf(item);
|
||||||
|
let r = await this.sampleHeight({lng: item[0], lat: item[1], alt: 0}, index)
|
||||||
|
arr.push(r)
|
||||||
|
}
|
||||||
|
let total_length = 0
|
||||||
|
let l = arr.length - 1
|
||||||
|
arr.forEach((item, index) => {
|
||||||
|
if (index !== l) {
|
||||||
|
let d1 = this.computeDistance([item.position, arr[index + 1].position])
|
||||||
|
let d2 = Math.abs(item.position.alt - arr[index + 1].position.alt)
|
||||||
|
let d3 = Math.sqrt(d1 * d1 + d2 * d2)
|
||||||
|
total_length += d3
|
||||||
|
}
|
||||||
|
})
|
||||||
|
createLabel(total_length)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//暂时固定取20个点
|
||||||
|
if (d > 20) {//大于20m时,固定取20个点
|
||||||
|
meters = d / 20
|
||||||
|
await start(meters)
|
||||||
|
} else if (d < 1) {
|
||||||
|
//不计算
|
||||||
|
createLabel(d)
|
||||||
|
} else {//小于20m的时候
|
||||||
|
meters = 1
|
||||||
|
await start(meters)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async sampleHeight(p1, index) {
|
||||||
|
let p2 = await this.sampleHeightMostDetailed([p1])
|
||||||
|
p1.alt = p2[0].height
|
||||||
|
return {position: p1, index}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async getHeight(p1, index, total) {
|
||||||
|
let p2 = await this.sampleHeightMostDetailed([p1])
|
||||||
|
p1.alt = p2[0].height
|
||||||
|
this.clampPositions.push({position: p1, index})
|
||||||
|
if (total === this.clampPositions.length) {
|
||||||
|
let total_length = this.startCompute()
|
||||||
|
return {total, current: this.clampPositions.length, total_length}
|
||||||
|
}
|
||||||
|
return {total, current: this.clampPositions.length,}
|
||||||
|
}
|
||||||
|
|
||||||
|
startCompute() {
|
||||||
|
this.clampPositions.sort(function (a, b) {
|
||||||
|
return a.index < b.index
|
||||||
|
})
|
||||||
|
let total_length = 0
|
||||||
|
let l = this.clampPositions.length - 1
|
||||||
|
this.clampPositions.forEach((item, index) => {
|
||||||
|
if (index !== l) {
|
||||||
|
let d1 = this.computeDistance([item.position, this.clampPositions[index + 1].position])
|
||||||
|
let d2 = Math.abs(item.position.alt - this.clampPositions[index + 1].position.alt)
|
||||||
|
let d3 = Math.sqrt(d1 * d1 + d2 * d2)
|
||||||
|
total_length += d3
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return Number(total_length.toFixed(2))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static createPolyline(that) {
|
||||||
|
let id = that.randomString()
|
||||||
|
that.viewer.entities.add(new Cesium.Entity({
|
||||||
|
id,
|
||||||
|
polyline: {
|
||||||
|
positions: new Cesium.CallbackProperty(() => {
|
||||||
|
return that.positions
|
||||||
|
}, false),
|
||||||
|
clampToGround: true,
|
||||||
|
width: 3,
|
||||||
|
material: new Cesium.PolylineDashMaterialProperty({
|
||||||
|
color: new Cesium.Color.fromCssColorString(that.options.color || that.defaultColor),
|
||||||
|
dashLength: 20, //短划线长度
|
||||||
|
}),
|
||||||
|
zIndex: 99999999
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
return id
|
||||||
|
}
|
||||||
|
|
||||||
|
static create_point(cartesian, {
|
||||||
|
label, image = "point.png",
|
||||||
|
width,
|
||||||
|
height
|
||||||
|
}, that) {
|
||||||
|
let id = that.randomString()
|
||||||
|
let p = that.cartesian3Towgs84(cartesian, that.viewer)
|
||||||
|
if (label) {
|
||||||
|
label.pixelOffset = new Cesium.Cartesian2(
|
||||||
|
0, -(height || 32)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
that.viewer.entities.add(
|
||||||
|
new Cesium.Entity({
|
||||||
|
id: id,
|
||||||
|
label,
|
||||||
|
position: Cesium.Cartesian3.fromDegrees(p.lng, p.lat, p.alt),
|
||||||
|
billboard: {
|
||||||
|
image: that.getSourceRootPath() + '/img/' + image,
|
||||||
|
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||||||
|
disableDepthTestDistance: Number.POSITIVE_INFINITY,
|
||||||
|
width,
|
||||||
|
height
|
||||||
|
}
|
||||||
|
})
|
||||||
|
)
|
||||||
|
return id
|
||||||
|
}
|
||||||
|
|
||||||
|
getLabel(text) {
|
||||||
|
return {
|
||||||
|
text: text || '',
|
||||||
|
//标注文字描述
|
||||||
|
font: '20px Microsoft YaHei',
|
||||||
|
fillColor: Cesium.Color.fromCssColorString('#f1e605'),
|
||||||
|
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
|
||||||
|
//标注的遮挡距离设置为100则视角与标注的距离大于100米时会有遮挡
|
||||||
|
// distanceDisplayCondition: this.distanceDisplayCondition,
|
||||||
|
scale: 1,
|
||||||
|
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
|
||||||
|
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||||||
|
disableDepthTestDistance: Number.POSITIVE_INFINITY,
|
||||||
|
|
||||||
|
// disableDepthTestDistance: this.disableDepthTestDistance,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开始测量
|
||||||
|
*/
|
||||||
|
start() {
|
||||||
|
if (!YJ.Measure.GetMeasureStatus()) {
|
||||||
|
super.start()
|
||||||
|
this.positions = []
|
||||||
|
this.cachePositions = []
|
||||||
|
|
||||||
|
|
||||||
|
let leftEvent = async (movement, car) => {
|
||||||
|
if (this.ids.length === 0) {
|
||||||
|
this.polyline_id = (MeasureDistance.createPolyline(this))
|
||||||
|
this.start_id = MeasureDistance.create_point(car, {
|
||||||
|
image: "start1.png", width: 30, height: 38, label: this.getLabel("")
|
||||||
|
}, this)
|
||||||
|
//创建起点
|
||||||
|
}
|
||||||
|
|
||||||
|
this.tip.setPosition(car, movement.position.x, movement.position.y)
|
||||||
|
this.positions = this.cachePositions.concat(car)
|
||||||
|
|
||||||
|
if (this.ids.length !== 0) {
|
||||||
|
let cur_point = this.cartesian3Towgs84(car, this.viewer)
|
||||||
|
let pre_p = this.cartesian3Towgs84(this.cachePositions[this.cachePositions.length - 1], this.viewer)
|
||||||
|
this.cachePositions.push(car)
|
||||||
|
await this.computeDisByTowPoint(pre_p, cur_point)
|
||||||
|
} else {
|
||||||
|
this.cachePositions.push(car)
|
||||||
|
this.ids.push(MeasureDistance.create_point(car, {}, this))
|
||||||
|
let startPoint = this.viewer.entities.getById(this.ids[0])
|
||||||
|
if(startPoint) {
|
||||||
|
startPoint.billboard.show = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let rightEvent = (movement, car) => {
|
||||||
|
if (this.cachePositions.length) {
|
||||||
|
this.positions = this.cachePositions
|
||||||
|
this.end_id = MeasureDistance.create_point(this.cachePositions[this.cachePositions.length - 1], {
|
||||||
|
image: "end1.png",
|
||||||
|
width: 30,
|
||||||
|
height: 38,
|
||||||
|
}, this)
|
||||||
|
let endPoint = this.viewer.entities.getById(this.ids[this.ids.length-1])
|
||||||
|
if(endPoint) {
|
||||||
|
endPoint.billboard.show = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.cachePositions.length < 2) {
|
||||||
|
this.destroy()
|
||||||
|
YJ.Measure.Measures.pop()//弹出测量实体
|
||||||
|
}
|
||||||
|
this.end()
|
||||||
|
}
|
||||||
|
this.event.mouse_left(leftEvent)
|
||||||
|
this.event.mouse_move((movement, car) => {
|
||||||
|
this.tip.setPosition(car, movement.endPosition.x, movement.endPosition.y)
|
||||||
|
this.positions = this.cachePositions.concat(car)
|
||||||
|
// if (this.cachePositions.length) {
|
||||||
|
// let cur_point = this.cartesian3Towgs84(car, this.viewer)
|
||||||
|
// let pre_p = this.cartesian3Towgs84(this.cachePositions[this.cachePositions.length - 1], this.viewer)
|
||||||
|
// let cur_len = this.computeDistance([cur_point, pre_p])
|
||||||
|
// let text = "当前投影距离:" + cur_len + " 米"
|
||||||
|
// // this.tip.set_text(text)
|
||||||
|
// }
|
||||||
|
})
|
||||||
|
this.event.mouse_right(rightEvent)
|
||||||
|
|
||||||
|
this.event.gesture_pinck_start((movement, cartesian) => {
|
||||||
|
let startTime = new Date()
|
||||||
|
let pos = {
|
||||||
|
position: {
|
||||||
|
x: (movement.position1.x + movement.position2.x) / 2,
|
||||||
|
y: (movement.position1.y + movement.position2.y) / 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.event.gesture_pinck_end(() => {
|
||||||
|
let endTime = new Date()
|
||||||
|
if (endTime - startTime >= 500) {
|
||||||
|
// 长按取消
|
||||||
|
rightEvent(pos, cartesian)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
leftEvent(pos, cartesian)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清除测量
|
||||||
|
*/
|
||||||
|
destroy() {
|
||||||
|
[this.polyline_id, this.end_id, this.start_id, ...this.ids].forEach(id => {
|
||||||
|
this.remove_entity(id)
|
||||||
|
})
|
||||||
|
super.destroy()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 结束测量
|
||||||
|
*/
|
||||||
|
end() {
|
||||||
|
// YJ.Measure.SetMeasureStatus(false)
|
||||||
|
// this.tip.destroy()
|
||||||
|
// this.event.destroy()
|
||||||
|
super.end()
|
||||||
|
// this.setPickStatus(this.pickStatus.pick)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default MeasureDistance
|
||||||
327
src/Measure/MeasureDistance/index2.js
Normal file
327
src/Measure/MeasureDistance/index2.js
Normal file
@ -0,0 +1,327 @@
|
|||||||
|
/**
|
||||||
|
* @name: index
|
||||||
|
* @author: Administrator
|
||||||
|
* @date: 2022-07-11 10:31
|
||||||
|
* @description:index
|
||||||
|
* @update: 2022-07-11 10:31
|
||||||
|
*/
|
||||||
|
|
||||||
|
import Measure from "../index"
|
||||||
|
|
||||||
|
class MeasureDistance extends Measure {
|
||||||
|
/**
|
||||||
|
* @constructor
|
||||||
|
* @param sdk
|
||||||
|
* @description 距离测量
|
||||||
|
* */
|
||||||
|
constructor(sdk, options = {}) {
|
||||||
|
super(sdk, options)
|
||||||
|
this.start_id = ""
|
||||||
|
this.end_id = ""
|
||||||
|
this.polyline_id = ""
|
||||||
|
this.clampPositions = []
|
||||||
|
}
|
||||||
|
|
||||||
|
async clampToGroundMeasure(meters, cb) {
|
||||||
|
let positions = []
|
||||||
|
this.ids.forEach((id, index) => {
|
||||||
|
let p = this.viewer.entities.getById(id).position.getValue()
|
||||||
|
positions.push(this.cartesian3Towgs84(p, this.viewer))
|
||||||
|
})
|
||||||
|
let res = this.chunkLine(positions, meters)
|
||||||
|
let coordinates = []
|
||||||
|
res.forEach((Feature, index) => {
|
||||||
|
if (index === 0) {
|
||||||
|
coordinates = [...Feature.geometry.coordinates]
|
||||||
|
} else {
|
||||||
|
coordinates.push(Feature.geometry.coordinates[1])
|
||||||
|
}
|
||||||
|
})
|
||||||
|
let total = coordinates.length
|
||||||
|
|
||||||
|
for (const item of coordinates) {
|
||||||
|
const index = coordinates.indexOf(item);
|
||||||
|
let r = await this.getHeight({lng: item[0], lat: item[1], alt: 0}, index, total,)
|
||||||
|
cb(null, r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async computeDisByTowPoint(p1, p2) {
|
||||||
|
let d = this.computeDistance([p1, p2])
|
||||||
|
let meters = 10
|
||||||
|
let createLabel = (distance) => {
|
||||||
|
let label = this.getLabel("贴地距离:" + distance.toFixed(2) + "米")
|
||||||
|
label.pixelOffset = new Cesium.Cartesian2(
|
||||||
|
0, -(84)
|
||||||
|
)
|
||||||
|
let id = this.randomString()
|
||||||
|
this.viewer.entities.add(
|
||||||
|
new Cesium.Entity({
|
||||||
|
id: id,
|
||||||
|
label,
|
||||||
|
position: Cesium.Cartesian3.fromDegrees(p2.lng, p2.lat, p2.alt),
|
||||||
|
})
|
||||||
|
)
|
||||||
|
this.ids.push(id)
|
||||||
|
}
|
||||||
|
let start = async (meters) => {
|
||||||
|
let res = this.chunkLine([p1, p2], meters)
|
||||||
|
let coordinates = []
|
||||||
|
res.forEach((Feature, index) => {
|
||||||
|
if (index === 0) {
|
||||||
|
coordinates = [...Feature.geometry.coordinates]
|
||||||
|
} else {
|
||||||
|
coordinates.push(Feature.geometry.coordinates[1])
|
||||||
|
}
|
||||||
|
})
|
||||||
|
let arr = []
|
||||||
|
for (const item of coordinates) {
|
||||||
|
const index = coordinates.indexOf(item);
|
||||||
|
let r = await this.sampleHeight({lng: item[0], lat: item[1], alt: 0}, index)
|
||||||
|
arr.push(r)
|
||||||
|
}
|
||||||
|
let total_length = 0
|
||||||
|
let l = arr.length - 1
|
||||||
|
arr.forEach((item, index) => {
|
||||||
|
if (index !== l) {
|
||||||
|
let d1 = this.computeDistance([item.position, arr[index + 1].position])
|
||||||
|
let d2 = Math.abs(item.position.alt - arr[index + 1].position.alt)
|
||||||
|
let d3 = Math.sqrt(d1 * d1 + d2 * d2)
|
||||||
|
total_length += d3
|
||||||
|
}
|
||||||
|
})
|
||||||
|
createLabel(total_length)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//暂时固定取20个点
|
||||||
|
if (d > 20) {//大于20m时,固定取20个点
|
||||||
|
meters = d / 20
|
||||||
|
await start(meters)
|
||||||
|
} else if (d < 1) {
|
||||||
|
//不计算
|
||||||
|
createLabel(d)
|
||||||
|
} else {//小于20m的时候
|
||||||
|
meters = 1
|
||||||
|
await start(meters)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async sampleHeight(p1, index) {
|
||||||
|
let p2 = await this.sampleHeightMostDetailed([p1])
|
||||||
|
p1.alt = p2[0].height
|
||||||
|
return {position: p1, index}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async getHeight(p1, index, total) {
|
||||||
|
let p2 = await this.sampleHeightMostDetailed([p1])
|
||||||
|
p1.alt = p2[0].height
|
||||||
|
this.clampPositions.push({position: p1, index})
|
||||||
|
if (total === this.clampPositions.length) {
|
||||||
|
let total_length = this.startCompute()
|
||||||
|
return {total, current: this.clampPositions.length, total_length}
|
||||||
|
}
|
||||||
|
return {total, current: this.clampPositions.length,}
|
||||||
|
}
|
||||||
|
|
||||||
|
startCompute() {
|
||||||
|
this.clampPositions.sort(function (a, b) {
|
||||||
|
return a.index < b.index
|
||||||
|
})
|
||||||
|
let total_length = 0
|
||||||
|
let l = this.clampPositions.length - 1
|
||||||
|
this.clampPositions.forEach((item, index) => {
|
||||||
|
if (index !== l) {
|
||||||
|
let d1 = this.computeDistance([item.position, this.clampPositions[index + 1].position])
|
||||||
|
let d2 = Math.abs(item.position.alt - this.clampPositions[index + 1].position.alt)
|
||||||
|
let d3 = Math.sqrt(d1 * d1 + d2 * d2)
|
||||||
|
total_length += d3
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return Number(total_length.toFixed(2))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static createPolyline(that) {
|
||||||
|
let id = that.randomString()
|
||||||
|
that.viewer.entities.add(new Cesium.Entity({
|
||||||
|
id,
|
||||||
|
polyline: {
|
||||||
|
positions: new Cesium.CallbackProperty(() => {
|
||||||
|
return that.positions
|
||||||
|
}, false),
|
||||||
|
clampToGround: true,
|
||||||
|
width: 5,
|
||||||
|
material: new Cesium.Color.fromCssColorString(that.options.color || that.defaultColor),
|
||||||
|
zIndex: 99999999
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
return id
|
||||||
|
}
|
||||||
|
|
||||||
|
static create_point(cartesian, {
|
||||||
|
label, image = "point.png",
|
||||||
|
width,
|
||||||
|
height
|
||||||
|
}, that) {
|
||||||
|
let id = that.randomString()
|
||||||
|
let p = that.cartesian3Towgs84(cartesian, that.viewer)
|
||||||
|
if (label) {
|
||||||
|
label.pixelOffset = new Cesium.Cartesian2(
|
||||||
|
0, -(height || 32)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
that.viewer.entities.add(
|
||||||
|
new Cesium.Entity({
|
||||||
|
id: id,
|
||||||
|
label,
|
||||||
|
position: Cesium.Cartesian3.fromDegrees(p.lng, p.lat, p.alt),
|
||||||
|
billboard: {
|
||||||
|
image: that.getSourceRootPath() + '/img/' + image,
|
||||||
|
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||||||
|
disableDepthTestDistance: Number.POSITIVE_INFINITY,
|
||||||
|
width,
|
||||||
|
height
|
||||||
|
}
|
||||||
|
})
|
||||||
|
)
|
||||||
|
return id
|
||||||
|
}
|
||||||
|
|
||||||
|
getLabel(text) {
|
||||||
|
return {
|
||||||
|
text: text || '',
|
||||||
|
//标注文字描述
|
||||||
|
font: '20px Microsoft YaHei',
|
||||||
|
fillColor: Cesium.Color.fromCssColorString('#f1e605'),
|
||||||
|
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
|
||||||
|
//标注的遮挡距离设置为100则视角与标注的距离大于100米时会有遮挡
|
||||||
|
// distanceDisplayCondition: this.distanceDisplayCondition,
|
||||||
|
scale: 1,
|
||||||
|
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
|
||||||
|
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||||||
|
disableDepthTestDistance: Number.POSITIVE_INFINITY,
|
||||||
|
|
||||||
|
// disableDepthTestDistance: this.disableDepthTestDistance,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开始测量
|
||||||
|
*/
|
||||||
|
start() {
|
||||||
|
if (!YJ.Measure.GetMeasureStatus()) {
|
||||||
|
super.start()
|
||||||
|
this.positions = []
|
||||||
|
this.cachePositions = []
|
||||||
|
|
||||||
|
|
||||||
|
this.event.mouse_left(async (movement, car) => {
|
||||||
|
if (this.ids.length === 0) {
|
||||||
|
this.polyline_id = (MeasureDistance.createPolyline(this))
|
||||||
|
this.start_id = MeasureDistance.create_point(car, {
|
||||||
|
image: "start.png", width: 32, height: 32, label: this.getLabel("")
|
||||||
|
}, this)
|
||||||
|
//创建起点
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.ids.length !== 0) {
|
||||||
|
let cur_point = this.cartesian3Towgs84(car, this.viewer)
|
||||||
|
let pre_p = this.cartesian3Towgs84(this.cachePositions[this.cachePositions.length - 1], this.viewer)
|
||||||
|
let cur_len = this.computeDistance([cur_point, pre_p])
|
||||||
|
let text = "投影距离:" + cur_len + " 米"
|
||||||
|
this.ids.push(MeasureDistance.create_point(car, {label: this.getLabel(text)}, this))
|
||||||
|
this.cachePositions.push(car)
|
||||||
|
//计算坡度
|
||||||
|
this.computeAngle(pre_p, cur_point)
|
||||||
|
await this.computeDisByTowPoint(pre_p, cur_point)
|
||||||
|
} else {
|
||||||
|
this.cachePositions.push(car)
|
||||||
|
this.ids.push(MeasureDistance.create_point(car, {}, this))
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
this.event.mouse_move((movement, car) => {
|
||||||
|
this.tip.setPosition(car, movement.endPosition.x, movement.endPosition.y)
|
||||||
|
this.positions = this.cachePositions.concat(car)
|
||||||
|
if (this.cachePositions.length) {
|
||||||
|
let cur_point = this.cartesian3Towgs84(car, this.viewer)
|
||||||
|
let pre_p = this.cartesian3Towgs84(this.cachePositions[this.cachePositions.length - 1], this.viewer)
|
||||||
|
let cur_len = this.computeDistance([cur_point, pre_p])
|
||||||
|
let text = "当前投影距离:" + cur_len + " 米"
|
||||||
|
this.tip.set_text(text)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.event.mouse_right((movement, car) => {
|
||||||
|
if (this.cachePositions.length) {
|
||||||
|
this.positions = this.cachePositions
|
||||||
|
this.end_id = MeasureDistance.create_point(this.cachePositions[this.cachePositions.length - 1], {
|
||||||
|
image: "end.png",
|
||||||
|
width: 32,
|
||||||
|
height: 32,
|
||||||
|
}, this)
|
||||||
|
}
|
||||||
|
if (this.cachePositions.length === 0) {
|
||||||
|
this.destroy()
|
||||||
|
YJ.Measure.Measures.pop()//弹出测量实体
|
||||||
|
}
|
||||||
|
this.end()
|
||||||
|
})
|
||||||
|
this.event.mouse_right_keyboard_ctrl((movement, car) => {
|
||||||
|
if (this.cachePositions.length) {
|
||||||
|
this.cachePositions.pop()
|
||||||
|
this.remove_entity(this.ids.pop())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
computeAngle(start, end) {
|
||||||
|
let d1 = this.computeDistance([start, end])
|
||||||
|
let d2 = Math.abs(start.alt - end.alt)
|
||||||
|
let d3 = Math.sqrt(d1 * d1 + d2 * d2)
|
||||||
|
let cosAlpha = d1 / d3
|
||||||
|
let acos = Math.acos(cosAlpha)
|
||||||
|
let angle = this.radiansToDegrees(acos)
|
||||||
|
let label = this.getLabel("坡度:" + angle.toFixed(1) + "°")
|
||||||
|
label.pixelOffset = new Cesium.Cartesian2(
|
||||||
|
0, -(58)
|
||||||
|
)
|
||||||
|
let id = this.randomString()
|
||||||
|
this.viewer.entities.add(
|
||||||
|
new Cesium.Entity({
|
||||||
|
id: id,
|
||||||
|
label,
|
||||||
|
position: Cesium.Cartesian3.fromDegrees(end.lng, end.lat, end.alt),
|
||||||
|
})
|
||||||
|
)
|
||||||
|
this.ids.push(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清除测量
|
||||||
|
*/
|
||||||
|
destroy() {
|
||||||
|
[this.polyline_id, this.end_id, this.start_id, ...this.ids].forEach(id => {
|
||||||
|
this.remove_entity(id)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 结束测量
|
||||||
|
*/
|
||||||
|
end() {
|
||||||
|
// YJ.Measure.SetMeasureStatus(false)
|
||||||
|
// this.tip.destroy()
|
||||||
|
// this.event.destroy()
|
||||||
|
super.end()
|
||||||
|
// this.setPickStatus(this.pickStatus.pick)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default MeasureDistance
|
||||||
197
src/Measure/MeasureHeight/index.js
Normal file
197
src/Measure/MeasureHeight/index.js
Normal file
@ -0,0 +1,197 @@
|
|||||||
|
/**
|
||||||
|
* @name: index
|
||||||
|
* @author: Administrator
|
||||||
|
* @date: 2022-07-22 17:15
|
||||||
|
* @description:index
|
||||||
|
* @update: 2022-07-22 17:15
|
||||||
|
*/
|
||||||
|
import Measure from "../index";
|
||||||
|
|
||||||
|
class MeasureHeight extends Measure {
|
||||||
|
/**
|
||||||
|
* @constructor
|
||||||
|
* @param sdk
|
||||||
|
* @description 高度测量
|
||||||
|
* */
|
||||||
|
constructor(sdk) {
|
||||||
|
super(sdk, {text: "左键开始,右键取消"});
|
||||||
|
}
|
||||||
|
|
||||||
|
static create_polygon(that) {
|
||||||
|
let id = that.randomString()
|
||||||
|
let a = that.viewer.entities.add(new Cesium.Entity({
|
||||||
|
id,
|
||||||
|
billboard: {
|
||||||
|
image: that.getSourceRootPath() + '/img/point.png',
|
||||||
|
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||||||
|
disableDepthTestDistance: Number.POSITIVE_INFINITY,
|
||||||
|
color: Cesium.Color.WHITE.withAlpha(0.99)
|
||||||
|
|
||||||
|
},
|
||||||
|
position: new Cesium.CallbackProperty(() => {
|
||||||
|
return that.position
|
||||||
|
}, false),
|
||||||
|
label: {
|
||||||
|
text: new Cesium.CallbackProperty(() => {
|
||||||
|
return that.text
|
||||||
|
}, false),
|
||||||
|
scale: 1,
|
||||||
|
// fillColor: Cesium.Color.RED,
|
||||||
|
font: 'normal 20px MicroSoft YaHei',
|
||||||
|
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||||||
|
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
|
||||||
|
pixelOffset: new Cesium.Cartesian2(0, -15),
|
||||||
|
disableDepthTestDistance: Number.POSITIVE_INFINITY,
|
||||||
|
|
||||||
|
},
|
||||||
|
polyline: {
|
||||||
|
positions: new Cesium.CallbackProperty(e => {
|
||||||
|
return that.positions;
|
||||||
|
}, false),
|
||||||
|
width: 2,
|
||||||
|
material: Cesium.Color.YELLOW,
|
||||||
|
zIndex: 99999999
|
||||||
|
},
|
||||||
|
ellipse: {
|
||||||
|
height: new Cesium.CallbackProperty(() => {
|
||||||
|
return that.height + that.firstpoint.alt;
|
||||||
|
}, false),
|
||||||
|
semiMinorAxis: new Cesium.CallbackProperty(e => {
|
||||||
|
return that.circleRadius;
|
||||||
|
}, false),
|
||||||
|
semiMajorAxis: new Cesium.CallbackProperty(e => {
|
||||||
|
return that.circleRadius;
|
||||||
|
}, false),
|
||||||
|
material: new Cesium.Color.fromCssColorString(that.defaultColor)
|
||||||
|
|
||||||
|
},
|
||||||
|
}))
|
||||||
|
return id
|
||||||
|
}
|
||||||
|
|
||||||
|
static create_point(that, cartesian, option = {}) {
|
||||||
|
let id = that.randomString()
|
||||||
|
let p = that.cartesian3Towgs84(cartesian, that.viewer)
|
||||||
|
let params = {
|
||||||
|
id: id,
|
||||||
|
position: Cesium.Cartesian3.fromDegrees(p.lng, p.lat, p.alt),
|
||||||
|
billboard: {
|
||||||
|
image: that.getSourceRootPath() + '/img/point.png',
|
||||||
|
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||||||
|
disableDepthTestDistance: Number.POSITIVE_INFINITY,
|
||||||
|
color: Cesium.Color.WHITE.withAlpha(0.99)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (option.label) {
|
||||||
|
params.label = {
|
||||||
|
text: option.label.text,
|
||||||
|
scale: 1,
|
||||||
|
// fillColor: Cesium.Color.fromCssColorString("#06eee5"),
|
||||||
|
font: 'normal 20px MicroSoft YaHei',
|
||||||
|
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||||||
|
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
|
||||||
|
pixelOffset: new Cesium.Cartesian2(0, -15),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
that.viewer.entities.add(
|
||||||
|
new Cesium.Entity(params)
|
||||||
|
)
|
||||||
|
return id
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开始测量
|
||||||
|
*/
|
||||||
|
start() {
|
||||||
|
if (!YJ.Measure.GetMeasureStatus()) {
|
||||||
|
super.start()
|
||||||
|
this.positions = []
|
||||||
|
this.position = new Cesium.Cartesian3()
|
||||||
|
this.height = 0
|
||||||
|
this.text = ""
|
||||||
|
this.circleRadius = 0
|
||||||
|
let count = 0;
|
||||||
|
this.firstpoint = null
|
||||||
|
|
||||||
|
let leftEvent = (movement, cartesian) => {
|
||||||
|
if (this.firstpoint === null) {
|
||||||
|
this.positions.push(cartesian)
|
||||||
|
this.firstpoint = this.cartesian3Towgs84(cartesian, this.viewer)
|
||||||
|
this.ids.push(MeasureHeight.create_polygon(this))
|
||||||
|
this.ids.push(MeasureHeight.create_point(this, cartesian))
|
||||||
|
}
|
||||||
|
count++
|
||||||
|
this.tip.setPosition(cartesian, movement.position.x, movement.position.y)
|
||||||
|
if (count === 2) {
|
||||||
|
if (this.firstpoint) {
|
||||||
|
let cur_point = this.cartesian3Towgs84(cartesian, this.viewer)
|
||||||
|
this.positions[1] = Cesium.Cartesian3.fromDegrees(this.firstpoint.lng, this.firstpoint.lat, cur_point.alt)
|
||||||
|
this.positions[2] = cartesian
|
||||||
|
this.position = this.positions[1]
|
||||||
|
this.circleRadius = this.computeDistance([this.firstpoint, cur_point])
|
||||||
|
this.height = Number((cur_point.alt - this.firstpoint.alt).toFixed(2))
|
||||||
|
this.text = "相对高度:" + this.height + " 米"
|
||||||
|
this.tip.set_text("左键完成,右键取消;半径:" + this.circleRadius + " 米")
|
||||||
|
}
|
||||||
|
this.ids.push(MeasureHeight.create_point(this, cartesian, {label: {text: "半径:" + this.circleRadius + " 米"}}))
|
||||||
|
this.end()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.event.mouse_left(leftEvent)
|
||||||
|
this.event.mouse_move((movement, cartesian) => {
|
||||||
|
this.tip.setPosition(cartesian, movement.endPosition.x, movement.endPosition.y)
|
||||||
|
if (this.firstpoint) {
|
||||||
|
let cur_point = this.cartesian3Towgs84(cartesian, this.viewer)
|
||||||
|
this.positions[1] = Cesium.Cartesian3.fromDegrees(this.firstpoint.lng, this.firstpoint.lat, cur_point.alt)
|
||||||
|
this.positions[2] = cartesian
|
||||||
|
this.position = this.positions[1]
|
||||||
|
this.circleRadius = this.computeDistance([this.firstpoint, cur_point])
|
||||||
|
this.height = Number((cur_point.alt - this.firstpoint.alt).toFixed(2))
|
||||||
|
this.text = "相对高度:" + this.height + " 米"
|
||||||
|
this.tip.set_text("左键完成,右键取消;半径:" + this.circleRadius + " 米")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.event.mouse_right((movement, cartesian) => {
|
||||||
|
this.end()
|
||||||
|
this.destroy()
|
||||||
|
})
|
||||||
|
this.event.gesture_pinck_start((movement, cartesian) => {
|
||||||
|
let startTime = new Date()
|
||||||
|
let pos = {
|
||||||
|
position: {
|
||||||
|
x: (movement.position1.x + movement.position2.x) / 2,
|
||||||
|
y: (movement.position1.y + movement.position2.y) / 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.event.gesture_pinck_end(() => {
|
||||||
|
let endTime = new Date()
|
||||||
|
if (endTime - startTime >= 500) {
|
||||||
|
// 长按取消
|
||||||
|
this.end()
|
||||||
|
this.destroy()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
leftEvent(pos, cartesian)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 结束测量
|
||||||
|
*/
|
||||||
|
end() {
|
||||||
|
super.end()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清除测量
|
||||||
|
*/
|
||||||
|
destroy() {
|
||||||
|
super.destroy()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default MeasureHeight
|
||||||
182
src/Measure/MeasureLocation/index.js
Normal file
182
src/Measure/MeasureLocation/index.js
Normal file
@ -0,0 +1,182 @@
|
|||||||
|
/**
|
||||||
|
* @name: index
|
||||||
|
* @author: Administrator
|
||||||
|
* @date: 2022-07-22 16:13
|
||||||
|
* @description:index
|
||||||
|
* @update: 2022-07-22 16:13
|
||||||
|
*/
|
||||||
|
import Measure from "../index";
|
||||||
|
import { Proj } from "../../Tools/proj";
|
||||||
|
import { getCoordinateSystem } from "../../Global/global";
|
||||||
|
|
||||||
|
class MeasureLocation extends Measure {
|
||||||
|
/**
|
||||||
|
* @constructor
|
||||||
|
* @param sdk
|
||||||
|
* @description 坐标测量
|
||||||
|
* */
|
||||||
|
constructor(sdk) {
|
||||||
|
super(sdk, {text: ""});
|
||||||
|
this.defaultColor = "#f11515"
|
||||||
|
this.locationID = this.randomString()
|
||||||
|
this.position = new Cesium.Cartesian3()
|
||||||
|
this.text = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
static createLocation(that) {
|
||||||
|
that.viewer.entities.add(new Cesium.Entity({
|
||||||
|
id: that.locationID,
|
||||||
|
show: false,
|
||||||
|
position: new Cesium.CallbackProperty(() => {
|
||||||
|
return that.position
|
||||||
|
}, false),
|
||||||
|
label: {
|
||||||
|
text: new Cesium.CallbackProperty(() => {
|
||||||
|
return that.text
|
||||||
|
}, false),
|
||||||
|
//标注文字描述
|
||||||
|
font: '22px Microsoft YaHei',
|
||||||
|
|
||||||
|
fillColor: new Cesium.Color.fromCssColorString(that.defaultColor),
|
||||||
|
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
|
||||||
|
//标注的遮挡距离设置为100则视角与标注的距离大于100米时会有遮挡
|
||||||
|
// distanceDisplayCondition: this.distanceDisplayCondition,
|
||||||
|
// scale: this.options.label.scale,
|
||||||
|
horizontalOrigin: Cesium.HorizontalOrigin.LEFT,
|
||||||
|
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||||||
|
disableDepthTestDistance: Number.POSITIVE_INFINITY,
|
||||||
|
|
||||||
|
pixelOffset: new Cesium.Cartesian2(
|
||||||
|
-100,
|
||||||
|
-50
|
||||||
|
),
|
||||||
|
// disableDepthTestDistance: this.disableDepthTestDistance,
|
||||||
|
},
|
||||||
|
billboard: {
|
||||||
|
image: that.getSourceRootPath() + "/img/location.png",
|
||||||
|
color: Cesium.Color.fromCssColorString(`rgba(255,255,255,0.99)`),
|
||||||
|
disableDepthTestDistance: Number.POSITIVE_INFINITY,
|
||||||
|
// scaleByDistance: new Cesium.NearFarScalar(
|
||||||
|
// 2000,
|
||||||
|
// 1,
|
||||||
|
// 1000000,
|
||||||
|
// 0
|
||||||
|
// ),
|
||||||
|
scale: 1,
|
||||||
|
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
|
||||||
|
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||||||
|
width: 48,
|
||||||
|
height: 48
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
static create_point(that) {
|
||||||
|
let id = that.randomString()
|
||||||
|
that.viewer.entities.add(
|
||||||
|
new Cesium.Entity({
|
||||||
|
id: id,
|
||||||
|
position: new Cesium.CallbackProperty(() => {
|
||||||
|
return that.position
|
||||||
|
}, false),
|
||||||
|
billboard: {
|
||||||
|
image: that.getSourceRootPath() + '/img/point.png',
|
||||||
|
color: Cesium.Color.fromCssColorString(`rgba(255,255,255,0.99)`),
|
||||||
|
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||||||
|
disableDepthTestDistance: Number.POSITIVE_INFINITY,
|
||||||
|
color: Cesium.Color.WHITE.withAlpha(0.99)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
)
|
||||||
|
return id
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开始测量
|
||||||
|
*/
|
||||||
|
start() {
|
||||||
|
if (!YJ.Measure.GetMeasureStatus()) {
|
||||||
|
super.start()
|
||||||
|
this.cache_id = MeasureLocation.create_point(this)
|
||||||
|
MeasureLocation.createLocation(this)
|
||||||
|
|
||||||
|
let leftEvent = (movement, cartesian) => {
|
||||||
|
this.position = cartesian
|
||||||
|
let entity = this.viewer.entities.getById(this.locationID)
|
||||||
|
if(entity) {
|
||||||
|
entity.show = true
|
||||||
|
}
|
||||||
|
let p = this.cartesian3Towgs84(cartesian, this.viewer)
|
||||||
|
let coordinateSystem = getCoordinateSystem()
|
||||||
|
if(coordinateSystem==='EPSG:4326') {
|
||||||
|
this.text = `经度:${Number(p.lng.toFixed(8))}\n纬度:${Number(p.lat.toFixed(8))}\n海拔:${Number(p.alt.toFixed(2))}`
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
let result = this.convert([{x: p.lng, y: p.lat, z: p.alt}], 'EPSG:4326', coordinateSystem)
|
||||||
|
this.text = `x:${Number(result.points[0].x.toFixed(8))}\ny:${Number(result.points[0].y.toFixed(8))}\nz:${Number(result.points[0].z.toFixed(2))}`
|
||||||
|
}
|
||||||
|
this.end()
|
||||||
|
}
|
||||||
|
this.event.mouse_left(leftEvent)
|
||||||
|
this.event.mouse_right((movement, cartesian) => {
|
||||||
|
this.destroy()
|
||||||
|
this.end()
|
||||||
|
})
|
||||||
|
this.event.mouse_move((movement, cartesian) => {
|
||||||
|
this.tip.setPosition(cartesian, movement.endPosition.x, movement.endPosition.y)
|
||||||
|
let entity = this.viewer.entities.getById(this.locationID)
|
||||||
|
if(entity) {
|
||||||
|
entity.show = true
|
||||||
|
}
|
||||||
|
this.position = cartesian
|
||||||
|
let p = this.cartesian3Towgs84(cartesian, this.viewer)
|
||||||
|
let coordinateSystem = getCoordinateSystem()
|
||||||
|
if(coordinateSystem==='EPSG:4326') {
|
||||||
|
this.text = `经度:${Number(p.lng.toFixed(8))}\n纬度:${Number(p.lat.toFixed(8))}\n海拔:${Number(p.alt.toFixed(2))}`
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
let result = this.convert([{x: p.lng, y: p.lat, z: p.alt}], 'EPSG:4326', coordinateSystem)
|
||||||
|
this.text = `x:${Number(result.points[0].x.toFixed(8))}\ny:${Number(result.points[0].y.toFixed(8))}\nz:${Number(result.points[0].z.toFixed(2))}`
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.event.gesture_pinck_start((movement, cartesian) => {
|
||||||
|
let startTime = new Date()
|
||||||
|
let pos = {
|
||||||
|
position: {
|
||||||
|
x: (movement.position1.x + movement.position2.x) / 2,
|
||||||
|
y: (movement.position1.y + movement.position2.y) / 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.event.gesture_pinck_end(() => {
|
||||||
|
let endTime = new Date()
|
||||||
|
if (endTime - startTime >= 500) {
|
||||||
|
// 长按取消
|
||||||
|
this.destroy()
|
||||||
|
this.end()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
leftEvent(pos, cartesian)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清除测量
|
||||||
|
*/
|
||||||
|
destroy() {
|
||||||
|
this.remove_entity(this.locationID)
|
||||||
|
this.remove_entity(this.cache_id)
|
||||||
|
super.destroy()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 结束测量
|
||||||
|
*/
|
||||||
|
end() {
|
||||||
|
super.end()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default MeasureLocation
|
||||||
276
src/Measure/MeasureProjectionDistance/index.js
Normal file
276
src/Measure/MeasureProjectionDistance/index.js
Normal file
@ -0,0 +1,276 @@
|
|||||||
|
/**
|
||||||
|
* @name: index
|
||||||
|
* @author: Administrator
|
||||||
|
* @date: 2022-07-11 10:31
|
||||||
|
* @description:index
|
||||||
|
* @update: 2022-07-11 10:31
|
||||||
|
*/
|
||||||
|
|
||||||
|
import Measure from "../index"
|
||||||
|
|
||||||
|
class MeasureProjectionDistance extends Measure {
|
||||||
|
/**
|
||||||
|
* @constructor
|
||||||
|
* @param sdk
|
||||||
|
* @description 投影距离测量
|
||||||
|
* */
|
||||||
|
constructor(sdk, options = {}) {
|
||||||
|
super(sdk, options)
|
||||||
|
this.options.color = this.options.color || "#00ffff"
|
||||||
|
this.start_id = ""
|
||||||
|
this.end_id = ""
|
||||||
|
this.polyline_id = ""
|
||||||
|
this.clampPositions = []
|
||||||
|
}
|
||||||
|
|
||||||
|
async clampToGroundMeasure(meters, cb) {
|
||||||
|
let positions = []
|
||||||
|
this.ids.forEach((id, index) => {
|
||||||
|
let p = this.viewer.entities.getById(id).position.getValue()
|
||||||
|
positions.push(this.cartesian3Towgs84(p, this.viewer))
|
||||||
|
})
|
||||||
|
let res = this.chunkLine(positions, meters)
|
||||||
|
let coordinates = []
|
||||||
|
res.forEach((Feature, index) => {
|
||||||
|
if (index === 0) {
|
||||||
|
coordinates = [...Feature.geometry.coordinates]
|
||||||
|
} else {
|
||||||
|
coordinates.push(Feature.geometry.coordinates[1])
|
||||||
|
}
|
||||||
|
})
|
||||||
|
let total = coordinates.length
|
||||||
|
|
||||||
|
for (const item of coordinates) {
|
||||||
|
const index = coordinates.indexOf(item);
|
||||||
|
let r = await this.getHeight({lng: item[0], lat: item[1], alt: 0}, index, total,)
|
||||||
|
cb(null, r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async sampleHeight(p1, index) {
|
||||||
|
let p2 = await this.sampleHeightMostDetailed([p1])
|
||||||
|
p1.alt = p2[0].height
|
||||||
|
return {position: p1, index}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async getHeight(p1, index, total) {
|
||||||
|
let p2 = await this.sampleHeightMostDetailed([p1])
|
||||||
|
p1.alt = p2[0].height
|
||||||
|
this.clampPositions.push({position: p1, index})
|
||||||
|
if (total === this.clampPositions.length) {
|
||||||
|
let total_length = this.startCompute()
|
||||||
|
return {total, current: this.clampPositions.length, total_length}
|
||||||
|
}
|
||||||
|
return {total, current: this.clampPositions.length,}
|
||||||
|
}
|
||||||
|
|
||||||
|
startCompute() {
|
||||||
|
this.clampPositions.sort(function (a, b) {
|
||||||
|
return a.index < b.index
|
||||||
|
})
|
||||||
|
let total_length = 0
|
||||||
|
let l = this.clampPositions.length - 1
|
||||||
|
this.clampPositions.forEach((item, index) => {
|
||||||
|
if (index !== l) {
|
||||||
|
let d1 = this.computeDistance([item.position, this.clampPositions[index + 1].position])
|
||||||
|
let d2 = Math.abs(item.position.alt - this.clampPositions[index + 1].position.alt)
|
||||||
|
let d3 = Math.sqrt(d1 * d1 + d2 * d2)
|
||||||
|
total_length += d3
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return Number(total_length.toFixed(2))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static createPolyline(that) {
|
||||||
|
let id = that.randomString()
|
||||||
|
that.viewer.entities.add(new Cesium.Entity({
|
||||||
|
id,
|
||||||
|
polyline: {
|
||||||
|
positions: new Cesium.CallbackProperty(() => {
|
||||||
|
return that.positions
|
||||||
|
}, false),
|
||||||
|
clampToGround: true,
|
||||||
|
width: 3,
|
||||||
|
material: new Cesium.PolylineDashMaterialProperty({
|
||||||
|
color: new Cesium.Color.fromCssColorString(that.options.color || that.defaultColor),
|
||||||
|
dashLength: 20, //短划线长度
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
zIndex: 99999999
|
||||||
|
}))
|
||||||
|
return id
|
||||||
|
}
|
||||||
|
|
||||||
|
static create_point(cartesian, {
|
||||||
|
label, image = "point.png",
|
||||||
|
width,
|
||||||
|
height
|
||||||
|
}, that) {
|
||||||
|
let id = that.randomString()
|
||||||
|
let p = that.cartesian3Towgs84(cartesian, that.viewer)
|
||||||
|
if (label) {
|
||||||
|
label.pixelOffset = new Cesium.Cartesian2(
|
||||||
|
0, -(height || 32)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
that.viewer.entities.add(
|
||||||
|
new Cesium.Entity({
|
||||||
|
id: id,
|
||||||
|
label,
|
||||||
|
position: Cesium.Cartesian3.fromDegrees(p.lng, p.lat, p.alt),
|
||||||
|
billboard: {
|
||||||
|
image: that.getSourceRootPath() + '/img/' + image,
|
||||||
|
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||||||
|
disableDepthTestDistance: Number.POSITIVE_INFINITY,
|
||||||
|
width,
|
||||||
|
height
|
||||||
|
}
|
||||||
|
})
|
||||||
|
)
|
||||||
|
return id
|
||||||
|
}
|
||||||
|
|
||||||
|
getLabel(text) {
|
||||||
|
return {
|
||||||
|
text: text || '',
|
||||||
|
//标注文字描述
|
||||||
|
font: '20px Microsoft YaHei',
|
||||||
|
fillColor: Cesium.Color.fromCssColorString('#f1e605'),
|
||||||
|
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
|
||||||
|
//标注的遮挡距离设置为100则视角与标注的距离大于100米时会有遮挡
|
||||||
|
// distanceDisplayCondition: this.distanceDisplayCondition,
|
||||||
|
scale: 1,
|
||||||
|
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
|
||||||
|
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||||||
|
disableDepthTestDistance: Number.POSITIVE_INFINITY,
|
||||||
|
|
||||||
|
// disableDepthTestDistance: this.disableDepthTestDistance,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开始测量
|
||||||
|
*/
|
||||||
|
start() {
|
||||||
|
if (!YJ.Measure.GetMeasureStatus()) {
|
||||||
|
super.start()
|
||||||
|
this.positions = []
|
||||||
|
this.cachePositions = []
|
||||||
|
|
||||||
|
let leftEvent = async (movement, car) => {
|
||||||
|
if (this.ids.length === 0) {
|
||||||
|
this.polyline_id = (MeasureProjectionDistance.createPolyline(this))
|
||||||
|
this.start_id = MeasureProjectionDistance.create_point(car, {
|
||||||
|
image: "start1.png", width: 30, height: 38, label: this.getLabel("")
|
||||||
|
}, this)
|
||||||
|
//创建起点
|
||||||
|
}
|
||||||
|
|
||||||
|
this.positions = this.cachePositions.concat(car)
|
||||||
|
this.tip.setPosition(car, movement.position.x, movement.position.y)
|
||||||
|
|
||||||
|
if (this.ids.length !== 0) {
|
||||||
|
let cur_point = this.cartesian3Towgs84(car, this.viewer)
|
||||||
|
let pre_p = this.cartesian3Towgs84(this.cachePositions[this.cachePositions.length - 1], this.viewer)
|
||||||
|
let cur_len = this.computeDistance([cur_point, pre_p])
|
||||||
|
let text = "投影距离:" + cur_len + " 米"
|
||||||
|
this.ids.push(MeasureProjectionDistance.create_point(car, {label: this.getLabel(text)}, this))
|
||||||
|
this.cachePositions.push(car)
|
||||||
|
} else {
|
||||||
|
this.cachePositions.push(car)
|
||||||
|
this.ids.push(MeasureProjectionDistance.create_point(car, {show: false}, this))
|
||||||
|
let startPoint = this.viewer.entities.getById(this.ids[0])
|
||||||
|
if(startPoint) {
|
||||||
|
startPoint.billboard.show = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
let rightEvent = (movement, car) => {
|
||||||
|
if (this.cachePositions.length) {
|
||||||
|
this.positions = this.cachePositions
|
||||||
|
this.end_id = MeasureProjectionDistance.create_point(this.cachePositions[this.cachePositions.length - 1], {
|
||||||
|
image: "end1.png",
|
||||||
|
width: 30,
|
||||||
|
height: 38,
|
||||||
|
}, this)
|
||||||
|
let endPoint = this.viewer.entities.getById(this.ids[this.ids.length-1])
|
||||||
|
if(endPoint) {
|
||||||
|
endPoint.billboard.show = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.cachePositions.length < 2) {
|
||||||
|
this.destroy()
|
||||||
|
YJ.Measure.Measures.pop()//弹出测量实体
|
||||||
|
}
|
||||||
|
this.end()
|
||||||
|
}
|
||||||
|
|
||||||
|
this.event.mouse_left(leftEvent)
|
||||||
|
this.event.mouse_move((movement, car) => {
|
||||||
|
this.tip.setPosition(car, movement.endPosition.x, movement.endPosition.y)
|
||||||
|
this.positions = this.cachePositions.concat(car)
|
||||||
|
if (this.cachePositions.length) {
|
||||||
|
let cur_point = this.cartesian3Towgs84(car, this.viewer)
|
||||||
|
let pre_p = this.cartesian3Towgs84(this.cachePositions[this.cachePositions.length - 1], this.viewer)
|
||||||
|
let cur_len = this.computeDistance([cur_point, pre_p])
|
||||||
|
let text = "当前投影距离:" + cur_len + " 米"
|
||||||
|
this.tip.set_text(text)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.event.mouse_right(rightEvent)
|
||||||
|
this.event.mouse_right_keyboard_ctrl((movement, car) => {
|
||||||
|
if (this.cachePositions.length) {
|
||||||
|
this.cachePositions.pop()
|
||||||
|
this.remove_entity(this.ids.pop())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.event.gesture_pinck_start((movement, cartesian) => {
|
||||||
|
let startTime = new Date()
|
||||||
|
let pos = {
|
||||||
|
position: {
|
||||||
|
x: (movement.position1.x + movement.position2.x) / 2,
|
||||||
|
y: (movement.position1.y + movement.position2.y) / 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.event.gesture_pinck_end(() => {
|
||||||
|
let endTime = new Date()
|
||||||
|
if (endTime - startTime >= 500) {
|
||||||
|
// 长按取消
|
||||||
|
rightEvent(pos, cartesian)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
leftEvent(pos, cartesian)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清除测量
|
||||||
|
*/
|
||||||
|
destroy() {
|
||||||
|
[this.polyline_id, this.end_id, this.start_id, ...this.ids].forEach(id => {
|
||||||
|
this.remove_entity(id)
|
||||||
|
})
|
||||||
|
super.destroy()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 结束测量
|
||||||
|
*/
|
||||||
|
end() {
|
||||||
|
// YJ.Measure.SetMeasureStatus(false)
|
||||||
|
// this.tip.destroy()
|
||||||
|
// this.event.destroy()
|
||||||
|
super.end()
|
||||||
|
// this.setPickStatus(this.pickStatus.pick)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default MeasureProjectionDistance
|
||||||
316
src/Measure/MeasureSlopeDistance/index.js
Normal file
316
src/Measure/MeasureSlopeDistance/index.js
Normal file
@ -0,0 +1,316 @@
|
|||||||
|
/**
|
||||||
|
* @name: index
|
||||||
|
* @author: Administrator
|
||||||
|
* @date: 2022-07-11 10:31
|
||||||
|
* @description:index
|
||||||
|
* @update: 2022-07-11 10:31
|
||||||
|
*/
|
||||||
|
|
||||||
|
import Measure from "../index"
|
||||||
|
import MouseEvent from "../../Event";
|
||||||
|
|
||||||
|
class MeasureSlopeDistance extends Measure {
|
||||||
|
/**
|
||||||
|
* @constructor
|
||||||
|
* @param sdk
|
||||||
|
* @description 坡度测量
|
||||||
|
* */
|
||||||
|
constructor(sdk, options = {}) {
|
||||||
|
super(sdk, options)
|
||||||
|
this.options.color = this.options.color || "#00ffff"
|
||||||
|
this.start_id = ""
|
||||||
|
this.end_id = ""
|
||||||
|
this.polyline_id = ""
|
||||||
|
this.clampPositions = []
|
||||||
|
this.event = new MouseEvent(sdk)
|
||||||
|
}
|
||||||
|
|
||||||
|
async clampToGroundMeasure(meters, cb) {
|
||||||
|
let positions = []
|
||||||
|
this.ids.forEach((id, index) => {
|
||||||
|
let p = this.viewer.entities.getById(id).position.getValue()
|
||||||
|
positions.push(this.cartesian3Towgs84(p, this.viewer))
|
||||||
|
})
|
||||||
|
let res = this.chunkLine(positions, meters)
|
||||||
|
let coordinates = []
|
||||||
|
res.forEach((Feature, index) => {
|
||||||
|
if (index === 0) {
|
||||||
|
coordinates = [...Feature.geometry.coordinates]
|
||||||
|
} else {
|
||||||
|
coordinates.push(Feature.geometry.coordinates[1])
|
||||||
|
}
|
||||||
|
})
|
||||||
|
let total = coordinates.length
|
||||||
|
|
||||||
|
for (const item of coordinates) {
|
||||||
|
const index = coordinates.indexOf(item);
|
||||||
|
let r = await this.getHeight({ lng: item[0], lat: item[1], alt: 0 }, index, total,)
|
||||||
|
cb(null, r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async sampleHeight(p1, index) {
|
||||||
|
let p2 = await this.sampleHeightMostDetailed([p1])
|
||||||
|
p1.alt = p2[0].height
|
||||||
|
return { position: p1, index }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async getHeight(p1, index, total) {
|
||||||
|
let p2 = await this.sampleHeightMostDetailed([p1])
|
||||||
|
p1.alt = p2[0].height
|
||||||
|
this.clampPositions.push({ position: p1, index })
|
||||||
|
if (total === this.clampPositions.length) {
|
||||||
|
let total_length = this.startCompute()
|
||||||
|
return { total, current: this.clampPositions.length, total_length }
|
||||||
|
}
|
||||||
|
return { total, current: this.clampPositions.length, }
|
||||||
|
}
|
||||||
|
|
||||||
|
startCompute() {
|
||||||
|
this.clampPositions.sort(function (a, b) {
|
||||||
|
return a.index < b.index
|
||||||
|
})
|
||||||
|
let total_length = 0
|
||||||
|
let l = this.clampPositions.length - 1
|
||||||
|
this.clampPositions.forEach((item, index) => {
|
||||||
|
if (index !== l) {
|
||||||
|
let d1 = this.computeDistance([item.position, this.clampPositions[index + 1].position])
|
||||||
|
let d2 = Math.abs(item.position.alt - this.clampPositions[index + 1].position.alt)
|
||||||
|
let d3 = Math.sqrt(d1 * d1 + d2 * d2)
|
||||||
|
total_length += d3
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return Number(total_length.toFixed(2))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static createPolyline(that) {
|
||||||
|
let id = that.randomString()
|
||||||
|
that.viewer.entities.add(new Cesium.Entity({
|
||||||
|
id,
|
||||||
|
polyline: {
|
||||||
|
positions: new Cesium.CallbackProperty(() => {
|
||||||
|
return that.positions
|
||||||
|
}, false),
|
||||||
|
clampToGround: true,
|
||||||
|
width: 3,
|
||||||
|
material: new Cesium.PolylineDashMaterialProperty({
|
||||||
|
color: new Cesium.Color.fromCssColorString(that.options.color || that.defaultColor),
|
||||||
|
dashLength: 20, //短划线长度
|
||||||
|
}),
|
||||||
|
zIndex: 99999999
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
return id
|
||||||
|
}
|
||||||
|
|
||||||
|
static create_point(cartesian, {
|
||||||
|
label, image = "point.png",
|
||||||
|
width,
|
||||||
|
height
|
||||||
|
}, that) {
|
||||||
|
let id = that.randomString()
|
||||||
|
let p = that.cartesian3Towgs84(cartesian, that.viewer)
|
||||||
|
if (label) {
|
||||||
|
label.pixelOffset = new Cesium.Cartesian2(
|
||||||
|
0, -(height || 32)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
that.viewer.entities.add(
|
||||||
|
new Cesium.Entity({
|
||||||
|
id: id,
|
||||||
|
label,
|
||||||
|
position: Cesium.Cartesian3.fromDegrees(p.lng, p.lat, p.alt),
|
||||||
|
billboard: {
|
||||||
|
image: that.getSourceRootPath() + '/img/' + image,
|
||||||
|
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||||||
|
disableDepthTestDistance: Number.POSITIVE_INFINITY,
|
||||||
|
width,
|
||||||
|
height
|
||||||
|
}
|
||||||
|
})
|
||||||
|
)
|
||||||
|
return id
|
||||||
|
}
|
||||||
|
|
||||||
|
getLabel(text) {
|
||||||
|
return {
|
||||||
|
text: text || '',
|
||||||
|
//标注文字描述
|
||||||
|
font: '20px Microsoft YaHei',
|
||||||
|
fillColor: Cesium.Color.fromCssColorString('#f1e605'),
|
||||||
|
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
|
||||||
|
//标注的遮挡距离设置为100则视角与标注的距离大于100米时会有遮挡
|
||||||
|
// distanceDisplayCondition: this.distanceDisplayCondition,
|
||||||
|
scale: 1,
|
||||||
|
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
|
||||||
|
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||||||
|
disableDepthTestDistance: Number.POSITIVE_INFINITY,
|
||||||
|
|
||||||
|
// disableDepthTestDistance: this.disableDepthTestDistance,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开始测量
|
||||||
|
*/
|
||||||
|
start() {
|
||||||
|
if (!YJ.Measure.GetMeasureStatus()) {
|
||||||
|
super.start()
|
||||||
|
this.positions = []
|
||||||
|
this.cachePositions = []
|
||||||
|
|
||||||
|
let leftEvent = (movement, car) => {
|
||||||
|
if (this.ids.length === 0) {
|
||||||
|
this.polyline_id = (MeasureSlopeDistance.createPolyline(this))
|
||||||
|
this.start_id = MeasureSlopeDistance.create_point(car, {
|
||||||
|
image: "start1.png", width: 30, height: 38, label: this.getLabel("")
|
||||||
|
}, this)
|
||||||
|
//创建起点
|
||||||
|
}
|
||||||
|
this.tip.setPosition(car, movement.position.x, movement.position.y)
|
||||||
|
this.positions = this.cachePositions.concat(car)
|
||||||
|
if (this.ids.length !== 0) {
|
||||||
|
let cur_point = this.cartesian3Towgs84(car, this.viewer)
|
||||||
|
let pre_p = this.cartesian3Towgs84(this.cachePositions[this.cachePositions.length - 1], this.viewer)
|
||||||
|
if (cur_point.lng !== pre_p.lng || cur_point.lat !== pre_p.lat || cur_point.alt !== pre_p.alt) {
|
||||||
|
this.cachePositions.push(car)
|
||||||
|
//计算坡度
|
||||||
|
this.computeAngle(pre_p, cur_point)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.cachePositions.push(car)
|
||||||
|
this.ids.push(MeasureSlopeDistance.create_point(car, {}, this))
|
||||||
|
let startPoint = this.viewer.entities.getById(this.ids[0])
|
||||||
|
if(startPoint) {
|
||||||
|
startPoint.billboard.show = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
let rightEvent = (movement, car) => {
|
||||||
|
if (this.ids.length !== 0) {
|
||||||
|
// let cur_point = this.cartesian3Towgs84(car, this.viewer)
|
||||||
|
// let pre_p = this.cartesian3Towgs84(this.cachePositions[this.cachePositions.length - 1], this.viewer)
|
||||||
|
// if (cur_point.lng !== pre_p.lng || cur_point.lat !== pre_p.lat || cur_point.alt !== pre_p.alt) {
|
||||||
|
// this.cachePositions.push(car)
|
||||||
|
// //计算坡度
|
||||||
|
// this.computeAngle(pre_p, cur_point)
|
||||||
|
// }
|
||||||
|
} else {
|
||||||
|
// this.cachePositions.push(car)
|
||||||
|
this.ids.push(MeasureSlopeDistance.create_point(car, {}, this))
|
||||||
|
}
|
||||||
|
if (this.cachePositions.length) {
|
||||||
|
this.positions = this.cachePositions
|
||||||
|
this.end_id = MeasureSlopeDistance.create_point(this.cachePositions[this.cachePositions.length - 1], {
|
||||||
|
image: "end1.png",
|
||||||
|
width: 30,
|
||||||
|
height: 38,
|
||||||
|
}, this)
|
||||||
|
let endPoint = this.viewer.entities.getById(this.ids[this.ids.length-1])
|
||||||
|
if(endPoint) {
|
||||||
|
endPoint.billboard.show = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (this.cachePositions.length < 2) {
|
||||||
|
this.destroy()
|
||||||
|
YJ.Measure.Measures.pop()//弹出测量实体
|
||||||
|
}
|
||||||
|
this.end()
|
||||||
|
}
|
||||||
|
|
||||||
|
this.event.mouse_left(leftEvent)
|
||||||
|
this.event.mouse_move((movement, car) => {
|
||||||
|
movement.endPosition.y += 2
|
||||||
|
let position = movement.endPosition
|
||||||
|
let cartesian = this.viewer.scene.pickPosition(position)
|
||||||
|
if (!cartesian) {
|
||||||
|
const ray = this.viewer.camera.getPickRay(position); //相交的射线
|
||||||
|
cartesian = this.viewer.scene.globe.pick(ray, this.viewer.scene);
|
||||||
|
}
|
||||||
|
this.tip.setPosition(car, movement.endPosition.x, movement.endPosition.y)
|
||||||
|
this.positions = this.cachePositions.concat(cartesian)
|
||||||
|
if (this.cachePositions.length) {
|
||||||
|
let cur_point = this.cartesian3Towgs84(cartesian, this.viewer)
|
||||||
|
let pre_p = this.cartesian3Towgs84(this.cachePositions[this.cachePositions.length - 1], this.viewer)
|
||||||
|
let d1 = this.computeDistance([pre_p, cur_point])
|
||||||
|
let d2 = Math.abs(pre_p.alt - cur_point.alt)
|
||||||
|
let d3 = Math.sqrt(d1 * d1 + d2 * d2)
|
||||||
|
let cosAlpha = d1 / d3
|
||||||
|
let acos = Math.acos(cosAlpha)
|
||||||
|
let angle = this.radiansToDegrees(acos)
|
||||||
|
let label = "坡度:" + angle.toFixed(2) + "°"
|
||||||
|
this.tip.set_text(label)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.event.mouse_right(rightEvent)
|
||||||
|
this.event.mouse_right_keyboard_ctrl((movement, car) => {
|
||||||
|
if (this.cachePositions.length) {
|
||||||
|
this.cachePositions.pop()
|
||||||
|
this.remove_entity(this.ids.pop())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
this.event.gesture_pinck_start((movement, cartesian) => {
|
||||||
|
let startTime = new Date()
|
||||||
|
let pos = {
|
||||||
|
position: {
|
||||||
|
x: (movement.position1.x + movement.position2.x) / 2,
|
||||||
|
y: (movement.position1.y + movement.position2.y) / 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.event.gesture_pinck_end(() => {
|
||||||
|
let endTime = new Date()
|
||||||
|
if (endTime - startTime >= 500) {
|
||||||
|
// 长按取消
|
||||||
|
rightEvent(pos, cartesian)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
leftEvent(pos, cartesian)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
computeAngle(start, end) {
|
||||||
|
let d1 = this.computeDistance([start, end])
|
||||||
|
let d2 = Math.abs(start.alt - end.alt)
|
||||||
|
let d3 = Math.sqrt(d1 * d1 + d2 * d2)
|
||||||
|
let cosAlpha = d1 / d3
|
||||||
|
let acos = Math.acos(cosAlpha)
|
||||||
|
let angle = this.radiansToDegrees(acos)
|
||||||
|
let label = this.getLabel("坡度:" + angle.toFixed(2) + "°")
|
||||||
|
label.pixelOffset = new Cesium.Cartesian2(
|
||||||
|
0, -(32)
|
||||||
|
)
|
||||||
|
this.ids.push(MeasureSlopeDistance.create_point(Cesium.Cartesian3.fromDegrees(end.lng, end.lat, end.alt), {label: label}, this))
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清除测量
|
||||||
|
*/
|
||||||
|
destroy() {
|
||||||
|
[this.polyline_id, this.end_id, this.start_id, ...this.ids].forEach(id => {
|
||||||
|
this.remove_entity(id)
|
||||||
|
})
|
||||||
|
super.destroy()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 结束测量
|
||||||
|
*/
|
||||||
|
end() {
|
||||||
|
// YJ.Measure.SetMeasureStatus(false)
|
||||||
|
// this.tip.destroy()
|
||||||
|
// this.event.destroy()
|
||||||
|
super.end()
|
||||||
|
// this.setPickStatus(this.pickStatus.pick)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default MeasureSlopeDistance
|
||||||
173
src/Measure/MeasureTdArea/index.js
Normal file
173
src/Measure/MeasureTdArea/index.js
Normal file
@ -0,0 +1,173 @@
|
|||||||
|
import Measure from "../index"
|
||||||
|
|
||||||
|
/**@extends Measure*/
|
||||||
|
class MeasureTdArea extends Measure {
|
||||||
|
/**
|
||||||
|
* @constructor
|
||||||
|
* @param sdk
|
||||||
|
* @description 贴地面积测量
|
||||||
|
* */
|
||||||
|
constructor(sdk, options = {}) {
|
||||||
|
super(sdk, options);
|
||||||
|
this.options.lineColor = '#ffdf53'
|
||||||
|
this.polygon_id = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
static create_polygon(that) {
|
||||||
|
let id = that.randomString()
|
||||||
|
|
||||||
|
let scaleByDistance = new Cesium.NearFarScalar(2000, 1, 100000, 0)
|
||||||
|
|
||||||
|
let e = that.viewer.entities.add(
|
||||||
|
new Cesium.Entity({
|
||||||
|
id: id,
|
||||||
|
label: {
|
||||||
|
text: new Cesium.CallbackProperty(() => {
|
||||||
|
return that.text
|
||||||
|
}, false),
|
||||||
|
//标注文字描述
|
||||||
|
font: '20px Microsoft YaHei',
|
||||||
|
fillColor: Cesium.Color.fromCssColorString('#ffffff'),
|
||||||
|
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
|
||||||
|
//标注的遮挡距离设置为100则视角与标注的距离大于100米时会有遮挡
|
||||||
|
// distanceDisplayCondition: this.distanceDisplayCondition,
|
||||||
|
|
||||||
|
disableDepthTestDistance: Number.POSITIVE_INFINITY,
|
||||||
|
|
||||||
|
// scaleByDistance,
|
||||||
|
scale: 1,
|
||||||
|
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
|
||||||
|
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||||||
|
},
|
||||||
|
position: new Cesium.CallbackProperty(() => {
|
||||||
|
return that.center
|
||||||
|
}, false),
|
||||||
|
polygon: {
|
||||||
|
classificationType: Cesium.ClassificationType.BOTH,
|
||||||
|
hierarchy: new Cesium.CallbackProperty((e) => {
|
||||||
|
return new Cesium.PolygonHierarchy(that.positions)
|
||||||
|
}, false),
|
||||||
|
material: new Cesium.Color.fromCssColorString(that.options.color || that.defaultColor),
|
||||||
|
zIndex: 99999999
|
||||||
|
},
|
||||||
|
polyline: {
|
||||||
|
positions: new Cesium.CallbackProperty(() => {
|
||||||
|
if (that.positions.length)
|
||||||
|
return that.positions.concat(that.positions[0])
|
||||||
|
return that.positions
|
||||||
|
}, false),
|
||||||
|
width: 2,
|
||||||
|
material: new Cesium.PolylineDashMaterialProperty({
|
||||||
|
color: new Cesium.Color.fromCssColorString(that.options.lineColor || that.defaultColor),
|
||||||
|
dashLength: 20, //短划线长度
|
||||||
|
}),
|
||||||
|
clampToGround: true,
|
||||||
|
zIndex: 99999999
|
||||||
|
}
|
||||||
|
})
|
||||||
|
)
|
||||||
|
return id
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开始测量
|
||||||
|
*/
|
||||||
|
start() {
|
||||||
|
if (!YJ.Measure.GetMeasureStatus()) {
|
||||||
|
super.start()
|
||||||
|
this.ids = []
|
||||||
|
this.positions = []
|
||||||
|
this.text = ""
|
||||||
|
this.center = new Cesium.Cartesian3()
|
||||||
|
this.cachePositions = []
|
||||||
|
let height = 0
|
||||||
|
let text
|
||||||
|
|
||||||
|
let leftEvent = (movement, car) => {
|
||||||
|
if (this.ids.length === 0) {
|
||||||
|
this.polygon_id = MeasureTdArea.create_polygon(this)
|
||||||
|
}
|
||||||
|
this.cachePositions.push({ ...car })
|
||||||
|
this.ids.push(this.create_point({ ...car }, false))
|
||||||
|
let po = this.cartesian3Towgs84({ ...car }, this.viewer)
|
||||||
|
if (po.alt > height) {
|
||||||
|
height = po.alt
|
||||||
|
}
|
||||||
|
|
||||||
|
this.positions = this.cachePositions.concat({ ...car })
|
||||||
|
this.tip.setPosition({ ...car }, movement.position.x, movement.position.y)
|
||||||
|
}
|
||||||
|
let rightEvent = (movement, car) => {
|
||||||
|
this.positions = this.cachePositions
|
||||||
|
if (this.positions.length > 2) {
|
||||||
|
let arr = []
|
||||||
|
this.positions.forEach(item => {
|
||||||
|
let p = this.cartesian3Towgs84(item, this.viewer)
|
||||||
|
arr.push({ lng: p.lng, lat: p.lat })
|
||||||
|
})
|
||||||
|
setTimeout(() => {
|
||||||
|
let center = this.computeCenter(arr)
|
||||||
|
let area = this.computeSignedArea(this.viewer, arr)
|
||||||
|
this.center = new Cesium.Cartesian3.fromDegrees(center.lng, center.lat, height)
|
||||||
|
this.text = "贴地面积:" + area + " ㎡"
|
||||||
|
}, 0);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
let error = '面积计算至少需要三个坐标!'
|
||||||
|
console.warn(error)
|
||||||
|
window.ELEMENT && window.ELEMENT.Message({
|
||||||
|
message: error,
|
||||||
|
type: 'warning',
|
||||||
|
duration: 1500
|
||||||
|
});
|
||||||
|
this.destroy()
|
||||||
|
}
|
||||||
|
this.end()
|
||||||
|
}
|
||||||
|
this.event.mouse_left(leftEvent)
|
||||||
|
this.event.mouse_move((movement, car) => {
|
||||||
|
this.tip.setPosition({ ...car }, movement.endPosition.x, movement.endPosition.y)
|
||||||
|
this.positions = this.cachePositions.concat({ ...car })
|
||||||
|
})
|
||||||
|
this.event.mouse_right(rightEvent)
|
||||||
|
this.event.gesture_pinck_start((movement, cartesian) => {
|
||||||
|
let startTime = new Date()
|
||||||
|
let pos = {
|
||||||
|
position: {
|
||||||
|
x: (movement.position1.x + movement.position2.x) / 2,
|
||||||
|
y: (movement.position1.y + movement.position2.y) / 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.event.gesture_pinck_end(() => {
|
||||||
|
let endTime = new Date()
|
||||||
|
if (endTime - startTime >= 500) {
|
||||||
|
// 长按取消
|
||||||
|
rightEvent(pos, cartesian)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
leftEvent(pos, cartesian)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清除测量
|
||||||
|
*/
|
||||||
|
destroy() {
|
||||||
|
[this.polygon_id, ...this.ids].forEach(id => {
|
||||||
|
this.remove_entity(id)
|
||||||
|
})
|
||||||
|
super.destroy()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 结束测量
|
||||||
|
*/
|
||||||
|
end() {
|
||||||
|
super.end()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default MeasureTdArea
|
||||||
290
src/Measure/MeasureTriangle/index.js
Normal file
290
src/Measure/MeasureTriangle/index.js
Normal file
@ -0,0 +1,290 @@
|
|||||||
|
/**
|
||||||
|
* @name: index
|
||||||
|
* @author: Administrator
|
||||||
|
* @date: 2022-07-21 15:22
|
||||||
|
* @description:index
|
||||||
|
* @update: 2022-07-21 15:22
|
||||||
|
*/
|
||||||
|
import Measure from "../index";
|
||||||
|
|
||||||
|
class MeasureTriangle extends Measure {
|
||||||
|
/**
|
||||||
|
* @constructor
|
||||||
|
* @param sdk
|
||||||
|
* @description 三角测量
|
||||||
|
* */
|
||||||
|
constructor(sdk) {
|
||||||
|
super(sdk);
|
||||||
|
}
|
||||||
|
|
||||||
|
cal_center(positions) {
|
||||||
|
let p1 = this.cartesian3Towgs84(positions[0], this.viewer)
|
||||||
|
let p2 = this.cartesian3Towgs84(positions[1], this.viewer)
|
||||||
|
let center = this.computeCenter([p1, p2]);
|
||||||
|
return Cesium.Cartesian3.fromDegrees(center.lng, center.lat, (p1.alt + p2.alt) / 2)
|
||||||
|
}
|
||||||
|
|
||||||
|
cal_distance(positions) {
|
||||||
|
let p1 = this.cartesian3Towgs84(positions[0], this.viewer)
|
||||||
|
let p2 = this.cartesian3Towgs84(positions[1], this.viewer)
|
||||||
|
let dis = this.computeDistance([p1, p2])
|
||||||
|
p1.alt = p1.alt.toFixed(2)
|
||||||
|
p2.alt = p2.alt.toFixed(2)
|
||||||
|
if (p1.alt === p2.alt) {//水平边
|
||||||
|
return dis
|
||||||
|
} else if (Number(dis) === 0.00) {//竖直边
|
||||||
|
return Math.abs(p1.alt - p2.alt).toFixed(2)
|
||||||
|
} else {//斜边
|
||||||
|
return Math.sqrt(dis * dis + Math.pow(Math.abs(p1.alt - p2.alt).toFixed(2), 2)).toFixed(2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
createPolyline(id) {
|
||||||
|
let obj = this.id_map.get(id)
|
||||||
|
|
||||||
|
this.viewer.entities.add(new Cesium.Entity({
|
||||||
|
id,
|
||||||
|
position: new Cesium.CallbackProperty(() => {
|
||||||
|
if (obj.positions.length === 2)
|
||||||
|
return this.cal_center(obj.positions)
|
||||||
|
else
|
||||||
|
return Cesium.Cartesian3()
|
||||||
|
}, false),
|
||||||
|
label: {
|
||||||
|
text: new Cesium.CallbackProperty(() => {
|
||||||
|
if (obj.positions.length === 2)
|
||||||
|
return this.cal_distance(obj.positions) + "米"
|
||||||
|
else
|
||||||
|
return "0米"
|
||||||
|
}, false),
|
||||||
|
scale: 1,
|
||||||
|
fillColor: Cesium.Color.RED,
|
||||||
|
font: 'normal 20px MicroSoft YaHei',
|
||||||
|
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||||||
|
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
|
||||||
|
pixelOffset: new Cesium.Cartesian2(0, -10),
|
||||||
|
disableDepthTestDistance: Number.POSITIVE_INFINITY,
|
||||||
|
|
||||||
|
},
|
||||||
|
polyline: {
|
||||||
|
positions: new Cesium.CallbackProperty(() => {
|
||||||
|
return obj.positions
|
||||||
|
}, false),
|
||||||
|
width: 2,
|
||||||
|
material: Cesium.Color.YELLOW,
|
||||||
|
zIndex: 99999999
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
|
||||||
|
this.ids.push(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
create_angle_label(positions1, positions2, id, type) {
|
||||||
|
let entity = new Cesium.Entity({
|
||||||
|
id,
|
||||||
|
position: new Cesium.CallbackProperty(() => {
|
||||||
|
if (positions1.length === 2)
|
||||||
|
return this.cal_point(positions1, positions2)
|
||||||
|
else
|
||||||
|
return Cesium.Cartesian3()
|
||||||
|
}),
|
||||||
|
label: {
|
||||||
|
text: new Cesium.CallbackProperty(() => {
|
||||||
|
if (positions1.length === 2)
|
||||||
|
return this.cal_angle(positions1, positions2, type) + "°"
|
||||||
|
else
|
||||||
|
return "0°"
|
||||||
|
}, false),
|
||||||
|
scale: 1,
|
||||||
|
fillColor: Cesium.Color.RED,
|
||||||
|
font: 'normal 20px MicroSoft YaHei',
|
||||||
|
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||||||
|
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
|
||||||
|
pixelOffset: new Cesium.Cartesian2(15, -10),
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.viewer.entities.add(entity)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
cal_point(positions1, positions2) {
|
||||||
|
for (let i = 0; i < positions1.length; i++) {
|
||||||
|
for (let j = 0; j < positions2.length; j++) {
|
||||||
|
if (positions1[i].x === positions2[j].x &&
|
||||||
|
positions1[i].y === positions2[j].y &&
|
||||||
|
positions1[i].z === positions2[j].z
|
||||||
|
) {
|
||||||
|
return positions1[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cal_angle(id1, id2, type) {
|
||||||
|
if (type === 1) {//水平&竖直
|
||||||
|
return 90
|
||||||
|
} else if (type === 2 || type === 3) {//水平&斜边 竖直&斜边
|
||||||
|
let positions1 = this.id_map.get(id1).positions
|
||||||
|
let positions2 = this.id_map.get(id2).positions
|
||||||
|
let p1 = this.cartesian3Towgs84(positions1[0], this.viewer)
|
||||||
|
let p2 = this.cartesian3Towgs84(positions1[1], this.viewer)
|
||||||
|
let shuiping = this.computeDistance([p2, p1])
|
||||||
|
let p3 = this.cartesian3Towgs84(positions2[0], this.viewer)
|
||||||
|
let p4 = this.cartesian3Towgs84(positions2[1], this.viewer)
|
||||||
|
let d = this.computeDistance([p3, p4])
|
||||||
|
let h = Math.abs(p3.alt - p4.alt)
|
||||||
|
let x = Math.sqrt(Math.pow(h, 2) + Math.pow(d, 2))
|
||||||
|
if (shuiping == 0.00) {
|
||||||
|
shuiping = Math.abs(p2.alt - p1.alt)
|
||||||
|
}
|
||||||
|
return (Math.acos(shuiping / x) * 180 / Math.PI).toFixed(2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开始测量
|
||||||
|
*/
|
||||||
|
start() {
|
||||||
|
|
||||||
|
if (!YJ.Measure.GetMeasureStatus()) {
|
||||||
|
super.start()
|
||||||
|
this.positions = []
|
||||||
|
this.cachePositions = []
|
||||||
|
let shuiping_line_id = this.randomString();//水平线
|
||||||
|
let shuizhi_line_id = this.randomString();//竖直边
|
||||||
|
let xiebian_line_id = this.randomString();//斜边
|
||||||
|
|
||||||
|
let angle1 = this.randomString();//角度1
|
||||||
|
let angle2 = this.randomString();//角度2
|
||||||
|
let angle3 = this.randomString();//角度3
|
||||||
|
|
||||||
|
|
||||||
|
let xiebian_line_positions = [];//斜边
|
||||||
|
|
||||||
|
this.id_map = new Map()
|
||||||
|
let first_point = {}
|
||||||
|
this.id_map.set(xiebian_line_id, {positions: []})
|
||||||
|
this.id_map.set(shuiping_line_id, {positions: []})
|
||||||
|
this.id_map.set(shuizhi_line_id, {positions: []})
|
||||||
|
|
||||||
|
let leftEvent = (movement, car) => {
|
||||||
|
xiebian_line_positions.push(car)
|
||||||
|
|
||||||
|
if (this.ids.length === 0) {//创建三角形
|
||||||
|
first_point = this.cartesian3Towgs84(car, this.viewer)
|
||||||
|
this.createPolyline(shuiping_line_id,)
|
||||||
|
this.createPolyline(shuizhi_line_id,)
|
||||||
|
this.createPolyline(xiebian_line_id,)
|
||||||
|
|
||||||
|
// this.cal_angle(shuiping_line_id, shuizhi_line_id, 1)
|
||||||
|
// this.cal_angle(shuiping_line_id, xiebian_line_id, 2)
|
||||||
|
// this.cal_angle(shuizhi_line_id, xiebian_line_id, 3)
|
||||||
|
|
||||||
|
// this.ids.push(shuiping_line_id)
|
||||||
|
// this.ids.push(shuizhi_line_id)
|
||||||
|
// this.ids.push(xiebian_line_id)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.ids.push(this.create_point(car))
|
||||||
|
this.tip.setPosition(car, movement.position.x, movement.position.y)
|
||||||
|
// // 隐藏斜边文字
|
||||||
|
// let xiebian = this.id_map.get(xiebian_line_id)
|
||||||
|
// let xbEntity = this.viewer.entities.getById(xiebian_line_id)
|
||||||
|
// if(xbEntity) {
|
||||||
|
// xbEntity.label.show = false
|
||||||
|
// }
|
||||||
|
if (xiebian_line_positions.length) {
|
||||||
|
// xiebian.positions = xiebian_line_positions.concat(car)
|
||||||
|
let p = this.cartesian3Towgs84(car, this.viewer)
|
||||||
|
let shuzhi = this.id_map.get(shuizhi_line_id)
|
||||||
|
let shuiping = this.id_map.get(shuiping_line_id)
|
||||||
|
if (p.alt < first_point.alt) {
|
||||||
|
shuzhi.positions[0] = car
|
||||||
|
shuzhi.positions[1] = Cesium.Cartesian3.fromDegrees(p.lng, p.lat, first_point.alt)
|
||||||
|
shuiping.positions[0] = Cesium.Cartesian3.fromDegrees(p.lng, p.lat, first_point.alt)
|
||||||
|
shuiping.positions[1] = Cesium.Cartesian3.fromDegrees(first_point.lng, first_point.lat, first_point.alt)
|
||||||
|
|
||||||
|
} else {
|
||||||
|
shuzhi.positions[0] = Cesium.Cartesian3.fromDegrees(first_point.lng, first_point.lat, p.alt)
|
||||||
|
shuzhi.positions[1] = car
|
||||||
|
|
||||||
|
shuiping.positions[0] = Cesium.Cartesian3.fromDegrees(first_point.lng, first_point.lat, p.alt)
|
||||||
|
shuiping.positions[1] = Cesium.Cartesian3.fromDegrees(first_point.lng, first_point.lat, first_point.alt)
|
||||||
|
|
||||||
|
}
|
||||||
|
// shuizhi.positions = shuizhi_positions
|
||||||
|
}
|
||||||
|
if (xiebian_line_positions.length === 2) {
|
||||||
|
this.end()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.event.mouse_left(leftEvent)
|
||||||
|
this.event.mouse_move((movement, car) => {
|
||||||
|
this.tip.setPosition(car, movement.endPosition.x, movement.endPosition.y)
|
||||||
|
let xiebian = this.id_map.get(xiebian_line_id)
|
||||||
|
|
||||||
|
if (xiebian_line_positions.length) {
|
||||||
|
xiebian.positions = xiebian_line_positions.concat(car)
|
||||||
|
let p = this.cartesian3Towgs84(car, this.viewer)
|
||||||
|
let shuzhi = this.id_map.get(shuizhi_line_id)
|
||||||
|
let shuiping = this.id_map.get(shuiping_line_id)
|
||||||
|
if (p.alt < first_point.alt) {
|
||||||
|
shuzhi.positions[0] = car
|
||||||
|
shuzhi.positions[1] = Cesium.Cartesian3.fromDegrees(p.lng, p.lat, first_point.alt)
|
||||||
|
shuiping.positions[0] = Cesium.Cartesian3.fromDegrees(p.lng, p.lat, first_point.alt)
|
||||||
|
shuiping.positions[1] = Cesium.Cartesian3.fromDegrees(first_point.lng, first_point.lat, first_point.alt)
|
||||||
|
|
||||||
|
} else {
|
||||||
|
shuzhi.positions[0] = Cesium.Cartesian3.fromDegrees(first_point.lng, first_point.lat, p.alt)
|
||||||
|
shuzhi.positions[1] = car
|
||||||
|
|
||||||
|
shuiping.positions[0] = Cesium.Cartesian3.fromDegrees(first_point.lng, first_point.lat, p.alt)
|
||||||
|
shuiping.positions[1] = Cesium.Cartesian3.fromDegrees(first_point.lng, first_point.lat, first_point.alt)
|
||||||
|
|
||||||
|
}
|
||||||
|
// shuizhi.positions = shuizhi_positions
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.event.mouse_right((movement, car) => {
|
||||||
|
this.end()
|
||||||
|
})
|
||||||
|
this.event.gesture_pinck_start((movement, cartesian) => {
|
||||||
|
let startTime = new Date()
|
||||||
|
let pos = {
|
||||||
|
position: {
|
||||||
|
x: (movement.position1.x + movement.position2.x) / 2,
|
||||||
|
y: (movement.position1.y + movement.position2.y) / 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.event.gesture_pinck_end(() => {
|
||||||
|
let endTime = new Date()
|
||||||
|
if (endTime - startTime >= 500) {
|
||||||
|
// 长按取消
|
||||||
|
this.end()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
leftEvent(pos, cartesian)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 结束测量
|
||||||
|
*/
|
||||||
|
end() {
|
||||||
|
super.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清除测量
|
||||||
|
*/
|
||||||
|
destroy() {
|
||||||
|
super.destroy()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default MeasureTriangle
|
||||||
197
src/Measure/MeasureTyArea/index.js
Normal file
197
src/Measure/MeasureTyArea/index.js
Normal file
@ -0,0 +1,197 @@
|
|||||||
|
/**
|
||||||
|
* @name: index
|
||||||
|
* @author: Administrator
|
||||||
|
* @date: 2022-07-11 17:28
|
||||||
|
* @description:index
|
||||||
|
* @update: 2022-07-11 17:28
|
||||||
|
*/
|
||||||
|
import Measure from "../index"
|
||||||
|
|
||||||
|
/**@extends Measure*/
|
||||||
|
class MeasureTyArea extends Measure {
|
||||||
|
/**
|
||||||
|
* @constructor
|
||||||
|
* @param sdk
|
||||||
|
* @description 投影面积测量
|
||||||
|
* */
|
||||||
|
constructor(sdk, options = {}) {
|
||||||
|
super(sdk, options);
|
||||||
|
this.options.lineColor = '#ffdf53'
|
||||||
|
this.polygon_id = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
static create_polygon(that) {
|
||||||
|
let id = that.randomString()
|
||||||
|
|
||||||
|
let scaleByDistance = new Cesium.NearFarScalar(2000, 1, 100000, 0)
|
||||||
|
|
||||||
|
let e = that.viewer.entities.add(
|
||||||
|
new Cesium.Entity({
|
||||||
|
id: id,
|
||||||
|
label: {
|
||||||
|
text: new Cesium.CallbackProperty(() => {
|
||||||
|
return that.text
|
||||||
|
}, false),
|
||||||
|
//标注文字描述
|
||||||
|
font: '20px Microsoft YaHei',
|
||||||
|
fillColor: Cesium.Color.fromCssColorString('#ffffff'),
|
||||||
|
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
|
||||||
|
//标注的遮挡距离设置为100则视角与标注的距离大于100米时会有遮挡
|
||||||
|
// distanceDisplayCondition: this.distanceDisplayCondition,
|
||||||
|
|
||||||
|
disableDepthTestDistance: Number.POSITIVE_INFINITY,
|
||||||
|
|
||||||
|
// scaleByDistance,
|
||||||
|
scale: 1,
|
||||||
|
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
|
||||||
|
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||||||
|
},
|
||||||
|
position: new Cesium.CallbackProperty(() => {
|
||||||
|
return that.center
|
||||||
|
}, false),
|
||||||
|
polygon: {
|
||||||
|
classificationType: Cesium.ClassificationType.BOTH,
|
||||||
|
hierarchy: new Cesium.CallbackProperty((e) => {
|
||||||
|
return new Cesium.PolygonHierarchy(that.positions)
|
||||||
|
}, false),
|
||||||
|
material: new Cesium.Color.fromCssColorString(that.options.color || that.defaultColor),
|
||||||
|
zIndex: 99999999
|
||||||
|
},
|
||||||
|
polyline: {
|
||||||
|
positions: new Cesium.CallbackProperty(() => {
|
||||||
|
if (that.positions.length)
|
||||||
|
return that.positions.concat(that.positions[0])
|
||||||
|
return that.positions
|
||||||
|
}, false),
|
||||||
|
width: 2,
|
||||||
|
material: new Cesium.PolylineDashMaterialProperty({
|
||||||
|
color: new Cesium.Color.fromCssColorString(that.options.lineColor || that.defaultColor),
|
||||||
|
dashLength: 20, //短划线长度
|
||||||
|
}),
|
||||||
|
clampToGround: true,
|
||||||
|
zIndex: 99999999
|
||||||
|
}
|
||||||
|
})
|
||||||
|
)
|
||||||
|
return id
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开始测量
|
||||||
|
*/
|
||||||
|
start() {
|
||||||
|
if (!YJ.Measure.GetMeasureStatus()) {
|
||||||
|
super.start()
|
||||||
|
this.ids = []
|
||||||
|
this.positions = []
|
||||||
|
this.text = ""
|
||||||
|
this.center = new Cesium.Cartesian3()
|
||||||
|
this.cachePositions = []
|
||||||
|
let height = 0
|
||||||
|
let lastArea = 0
|
||||||
|
let lastcneter
|
||||||
|
|
||||||
|
let leftEvent = (movement, car) => {
|
||||||
|
if (this.ids.length === 0) {
|
||||||
|
this.polygon_id = MeasureTyArea.create_polygon(this)
|
||||||
|
}
|
||||||
|
this.cachePositions.push({ ...car })
|
||||||
|
this.ids.push(this.create_point({ ...car }, false))
|
||||||
|
let po = this.cartesian3Towgs84({ ...car }, this.viewer)
|
||||||
|
if (po.alt > height) {
|
||||||
|
height = po.alt
|
||||||
|
}
|
||||||
|
|
||||||
|
this.positions = this.cachePositions.concat({ ...car })
|
||||||
|
this.tip.setPosition({ ...car }, movement.position.x, movement.position.y)
|
||||||
|
if (this.positions.length > 2) {
|
||||||
|
let arr = []
|
||||||
|
this.positions.forEach(item => {
|
||||||
|
let p = this.cartesian3Towgs84(item, this.viewer)
|
||||||
|
arr.push({ lng: p.lng, lat: p.lat })
|
||||||
|
})
|
||||||
|
let center = this.computeCenter(arr)
|
||||||
|
let area = this.computeArea(arr)
|
||||||
|
lastArea = area
|
||||||
|
this.center = new Cesium.Cartesian3.fromDegrees(center.lng, center.lat, height)
|
||||||
|
lastcneter = this.center
|
||||||
|
this.text = "投影面积:" + area + " ㎡"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.event.mouse_left(leftEvent)
|
||||||
|
this.event.mouse_move((movement, car) => {
|
||||||
|
this.tip.setPosition({ ...car }, movement.endPosition.x, movement.endPosition.y)
|
||||||
|
this.positions = this.cachePositions.concat({ ...car })
|
||||||
|
if (this.positions.length > 2) {
|
||||||
|
let arr = []
|
||||||
|
this.positions.forEach(item => {
|
||||||
|
let p = this.cartesian3Towgs84(item, this.viewer)
|
||||||
|
arr.push({ lng: p.lng, lat: p.lat })
|
||||||
|
})
|
||||||
|
let center = this.computeCenter(arr)
|
||||||
|
let area = this.computeArea(arr)
|
||||||
|
this.center = new Cesium.Cartesian3.fromDegrees(center.lng, center.lat, height)
|
||||||
|
this.text = "投影面积:" + area + " ㎡"
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.event.mouse_right((movement, car) => {
|
||||||
|
this.positions = this.cachePositions
|
||||||
|
this.center = lastcneter
|
||||||
|
if (this.positions.length < 3) {
|
||||||
|
this.text = ""
|
||||||
|
let error = '面积计算至少需要三个坐标!'
|
||||||
|
console.warn(error)
|
||||||
|
window.ELEMENT && window.ELEMENT.Message({
|
||||||
|
message: error,
|
||||||
|
type: 'warning',
|
||||||
|
duration: 1500
|
||||||
|
});
|
||||||
|
this.destroy()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.text = "投影面积:" + lastArea + " ㎡"
|
||||||
|
}
|
||||||
|
this.end()
|
||||||
|
})
|
||||||
|
this.event.gesture_pinck_start((movement, cartesian) => {
|
||||||
|
let startTime = new Date()
|
||||||
|
let pos = {
|
||||||
|
position: {
|
||||||
|
x: (movement.position1.x + movement.position2.x) / 2,
|
||||||
|
y: (movement.position1.y + movement.position2.y) / 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.event.gesture_pinck_end(() => {
|
||||||
|
let endTime = new Date()
|
||||||
|
if (endTime - startTime >= 500) {
|
||||||
|
// 长按取消
|
||||||
|
this.positions = this.cachePositions
|
||||||
|
this.end()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
leftEvent(pos, cartesian)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清除测量
|
||||||
|
*/
|
||||||
|
destroy() {
|
||||||
|
[this.polygon_id, ...this.ids].forEach(id => {
|
||||||
|
this.remove_entity(id)
|
||||||
|
})
|
||||||
|
super.destroy()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 结束测量
|
||||||
|
*/
|
||||||
|
end() {
|
||||||
|
super.end()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default MeasureTyArea
|
||||||
16
src/Measure/clear.js
Normal file
16
src/Measure/clear.js
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
/**
|
||||||
|
* @name: clear
|
||||||
|
* @author: Administrator
|
||||||
|
* @date: 2022-07-11 15:28
|
||||||
|
* @description:clear
|
||||||
|
* @update: 2022-07-11 15:28
|
||||||
|
*/
|
||||||
|
|
||||||
|
function Clear() {
|
||||||
|
YJ.Measure.Measures.forEach(m => {
|
||||||
|
m.destroy()
|
||||||
|
})
|
||||||
|
YJ.Measure.Measures = []
|
||||||
|
}
|
||||||
|
|
||||||
|
export {Clear}
|
||||||
80
src/Measure/index.js
Normal file
80
src/Measure/index.js
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
import MouseEvent from "../Event";
|
||||||
|
import MouseTip from "../MouseTip";
|
||||||
|
import Tools from "../Tools";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name: measure
|
||||||
|
* @author: Administrator
|
||||||
|
* @date: 2022-07-11 10:52
|
||||||
|
* @description:measure
|
||||||
|
* @update: 2022-07-11 10:52
|
||||||
|
*/
|
||||||
|
|
||||||
|
class Measure extends Tools {
|
||||||
|
constructor(sdk, options = {text: "左键开始,右键结束;"}) {
|
||||||
|
super(sdk, options)
|
||||||
|
this.options = {...options}
|
||||||
|
this.event = new MouseEvent(sdk)
|
||||||
|
this.tip = new MouseTip(options.text, sdk)
|
||||||
|
this.viewer = sdk.viewer
|
||||||
|
this.defaultColor = 'rgba(246,49,49,0.55)'
|
||||||
|
this.ids = []
|
||||||
|
YJ.Measure.Measures.push(this)
|
||||||
|
this._isDestroy = false
|
||||||
|
// this.pickStatus = {pick: YJ.getEarth().interaction.picking.enabled}
|
||||||
|
}
|
||||||
|
|
||||||
|
start() {
|
||||||
|
this.setPickStatus(false)
|
||||||
|
YJ.Measure.SetMeasureStatus(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
destroy() {
|
||||||
|
// YJ.Measure.Measures.pop()
|
||||||
|
this._isDestroy = true
|
||||||
|
this.end()
|
||||||
|
this.ids.forEach(id => {
|
||||||
|
this.remove_entity(id)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
end() {
|
||||||
|
// this.ids.forEach(id => {
|
||||||
|
// this.remove_entity(id)
|
||||||
|
// })
|
||||||
|
//还原上一次的状态
|
||||||
|
// this.setPickStatus(this.pickStatus.pick)
|
||||||
|
YJ.Measure.SetMeasureStatus(false)
|
||||||
|
this.tip && this.tip.destroy()
|
||||||
|
this.event && this.event.destroy()
|
||||||
|
this.tip = null
|
||||||
|
this.event = null
|
||||||
|
}
|
||||||
|
|
||||||
|
create_point(cartesian,show = true) {
|
||||||
|
let id = this.randomString()
|
||||||
|
let p = this.cartesian3Towgs84(cartesian, this.viewer)
|
||||||
|
this.viewer.entities.add(
|
||||||
|
new Cesium.Entity({
|
||||||
|
id: id,
|
||||||
|
position: Cesium.Cartesian3.fromDegrees(p.lng, p.lat, p.alt),
|
||||||
|
billboard: {
|
||||||
|
show: show,
|
||||||
|
image: this.getSourceRootPath() + '/img/point.png',
|
||||||
|
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||||||
|
disableDepthTestDistance: Number.POSITIVE_INFINITY,
|
||||||
|
color: Cesium.Color.WHITE.withAlpha(0.99)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
)
|
||||||
|
return id
|
||||||
|
}
|
||||||
|
|
||||||
|
remove_entity(id) {
|
||||||
|
this.viewer.entities.removeById(id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export default Measure
|
||||||
123
src/MouseTip/index.js
Normal file
123
src/MouseTip/index.js
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
/**
|
||||||
|
* @name: index
|
||||||
|
* @author: Administrator
|
||||||
|
* @date: 2022-06-14 14:37
|
||||||
|
* @description:index
|
||||||
|
* @update: 2022-06-14 14:37
|
||||||
|
*/
|
||||||
|
import Tools from "../Tools";
|
||||||
|
|
||||||
|
//鼠标tip
|
||||||
|
export default class MouseTip {
|
||||||
|
constructor(text = '左键开始,右键结束', sdk) {
|
||||||
|
this.point = undefined
|
||||||
|
this.text = text
|
||||||
|
this.div = undefined
|
||||||
|
this.mouse_type = 0
|
||||||
|
this.position = new Cesium.Cartesian3()
|
||||||
|
|
||||||
|
this.viewer = sdk.viewer
|
||||||
|
this.create_tip(this.viewer)
|
||||||
|
}
|
||||||
|
|
||||||
|
set_text(text) {
|
||||||
|
let textElm = this.div.getElementsByTagName('p')[0]
|
||||||
|
textElm.innerText = text
|
||||||
|
}
|
||||||
|
|
||||||
|
get_mouse_style(type) {
|
||||||
|
let url = 'lib/img/'
|
||||||
|
let style = '' //默认的鼠标箭头样式
|
||||||
|
switch (type) {
|
||||||
|
case 1:
|
||||||
|
style = 'move.png' //移动样式
|
||||||
|
break
|
||||||
|
|
||||||
|
default:
|
||||||
|
style = 'arrow.png'
|
||||||
|
break
|
||||||
|
}
|
||||||
|
return 'url(' + url + style + '),auto'
|
||||||
|
}
|
||||||
|
|
||||||
|
create_tip(viewer) {
|
||||||
|
// let tool = new Tools()
|
||||||
|
// this.point = viewer.entities.add(
|
||||||
|
// new Cesium.Entity({
|
||||||
|
// position: new Cesium.CallbackProperty(() => {
|
||||||
|
// return this.position
|
||||||
|
// }, false),
|
||||||
|
// billboard: {
|
||||||
|
// image: tool.getSourceRootPath() + '/img/point.png',
|
||||||
|
// verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||||||
|
// disableDepthTestDistance: 100000000
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
// )
|
||||||
|
// tool = null
|
||||||
|
// this.style_tip(viewer, this.mouse_type)
|
||||||
|
this.create_tooltip()
|
||||||
|
}
|
||||||
|
|
||||||
|
setPosition(position, x, y) {
|
||||||
|
this.position = position
|
||||||
|
this.move_tooltip(x, y)
|
||||||
|
}
|
||||||
|
|
||||||
|
destroy() {
|
||||||
|
this.viewer.entities.remove(this.point)
|
||||||
|
this.remove_tooltip()
|
||||||
|
// this.style_tip(viewer)
|
||||||
|
}
|
||||||
|
|
||||||
|
create_tooltip() {
|
||||||
|
let tool = new Tools()
|
||||||
|
this.div = document.createElement('div')
|
||||||
|
let c = "#ec131a"
|
||||||
|
this.div.setAttribute(
|
||||||
|
'style',
|
||||||
|
'position: absolute;z-index: 777;color: ' + c + ';left:10px;top:0px;pointer-events: none;'
|
||||||
|
)
|
||||||
|
let textElm = document.createElement('p')
|
||||||
|
textElm.style.margin = '0px'
|
||||||
|
textElm.style.padding = '0px'
|
||||||
|
textElm.innerText = this.text
|
||||||
|
this.div.appendChild(textElm)
|
||||||
|
let imgElm = document.createElement('div')
|
||||||
|
imgElm.style.width = '12px'
|
||||||
|
imgElm.style.height = '12px'
|
||||||
|
imgElm.style.background = `url(${tool.getSourceRootPath() + '/img/point.png'}) 100% 100% no-repeat`
|
||||||
|
imgElm.style.backgroundSize = '100% 100%'
|
||||||
|
imgElm.style.position = 'absolute'
|
||||||
|
imgElm.style.left = '-36px'
|
||||||
|
imgElm.style.top = '-4px'
|
||||||
|
this.div.style.display = 'none'
|
||||||
|
this.div.appendChild(imgElm)
|
||||||
|
tool = null
|
||||||
|
document.querySelector('body').appendChild(this.div)
|
||||||
|
}
|
||||||
|
|
||||||
|
/*移动时的鼠标样式*/
|
||||||
|
style_tip(viewer, type = 0) {
|
||||||
|
viewer._element.style.cursor = this.get_mouse_style(type)
|
||||||
|
}
|
||||||
|
|
||||||
|
remove_tooltip() {
|
||||||
|
document.querySelector('body').contains(this.div) && document.querySelector('body').removeChild(this.div)
|
||||||
|
}
|
||||||
|
|
||||||
|
move_tooltip(x, y) {
|
||||||
|
let top = 0
|
||||||
|
let left = 0
|
||||||
|
this.div.style.display = 'block'
|
||||||
|
|
||||||
|
if (this.viewer && this.viewer._element) {
|
||||||
|
let element = this.viewer._element.getElementsByClassName('cesium-widget')[0].getElementsByTagName('canvas')[0]
|
||||||
|
top = element.getBoundingClientRect().top + window.scrollY
|
||||||
|
left = element.getBoundingClientRect().left + window.scrollX
|
||||||
|
}
|
||||||
|
|
||||||
|
this.div.style.left = x + 30 + left + 'px'
|
||||||
|
this.div.style.top = y + top + 'px'
|
||||||
|
}
|
||||||
|
}
|
||||||
89
src/Obj/AirLine/DrawTakeOff.js
Normal file
89
src/Obj/AirLine/DrawTakeOff.js
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
import MouseTip from '../../MouseTip/index'
|
||||||
|
import MouseEvent from '../../Event/index'
|
||||||
|
import Draw from '../../Draw/draw'
|
||||||
|
|
||||||
|
class DrawTakeOff extends Draw {
|
||||||
|
/**
|
||||||
|
* @constructor
|
||||||
|
* @desc 获取坐标点
|
||||||
|
* */
|
||||||
|
constructor(sdk, options = {}) {
|
||||||
|
super(sdk, options)
|
||||||
|
this.options.tipText = options.tipText
|
||||||
|
? options.tipText
|
||||||
|
: '左键确定,右键结束;'
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @desc 开始动态获取坐标点
|
||||||
|
* @method start
|
||||||
|
* @param cb {function} 回调函数
|
||||||
|
* @memberOf DrawPoint
|
||||||
|
* @example draw.start((err,position)=>{
|
||||||
|
*
|
||||||
|
* })
|
||||||
|
* */
|
||||||
|
|
||||||
|
start(cb) {
|
||||||
|
// eslint-disable-next-line no-undef
|
||||||
|
if (YJ.Measure.GetMeasureStatus()) {
|
||||||
|
cb('上一次测量未结束')
|
||||||
|
} else {
|
||||||
|
let car = undefined
|
||||||
|
// eslint-disable-next-line no-undef
|
||||||
|
YJ.Measure.SetMeasureStatus(true)
|
||||||
|
// this.options
|
||||||
|
this.tip = new MouseTip(this.options.tipText, this.sdk)
|
||||||
|
this.event = new MouseEvent(this.sdk)
|
||||||
|
this.isEntity = false
|
||||||
|
this.event.mouse_left((movement, cartesian) => {
|
||||||
|
this.end()
|
||||||
|
let p = this.cartesian3Towgs84(car || cartesian, this.viewer)
|
||||||
|
var pickedObject = this.viewer.scene.pick(movement.position)
|
||||||
|
if (
|
||||||
|
Cesium.defined(pickedObject) &&
|
||||||
|
Cesium.defined(pickedObject.id) &&
|
||||||
|
pickedObject.id.id === window.airportEntity.options.id
|
||||||
|
) {
|
||||||
|
this.isEntity = true
|
||||||
|
}
|
||||||
|
cb(null, p, this.isEntity)
|
||||||
|
})
|
||||||
|
this.event.mouse_right((movement, cartesian) => {
|
||||||
|
this.end()
|
||||||
|
cb(false)
|
||||||
|
})
|
||||||
|
this.event.mouse_move((movement, cartesian) => {
|
||||||
|
car = cartesian
|
||||||
|
this.tip.setPosition(
|
||||||
|
cartesian,
|
||||||
|
movement.endPosition.x,
|
||||||
|
movement.endPosition.y
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
this.event.gesture_pinck_start((movement, cartesian) => {
|
||||||
|
let startTime = new Date()
|
||||||
|
this.event.gesture_pinck_end(() => {
|
||||||
|
let endTime = new Date()
|
||||||
|
if (endTime - startTime >= 500) {
|
||||||
|
this.end()
|
||||||
|
cb(false)
|
||||||
|
} else {
|
||||||
|
this.end()
|
||||||
|
let p = this.cartesian3Towgs84(car || cartesian, this.viewer)
|
||||||
|
cb(null, p)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
end() {
|
||||||
|
YJ.Measure.SetMeasureStatus(false)
|
||||||
|
this.event.destroy()
|
||||||
|
this.tip.destroy()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default DrawTakeOff
|
||||||
112
src/Obj/AirLine/GenerateRoute.js
Normal file
112
src/Obj/AirLine/GenerateRoute.js
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
// 根据米生成航线
|
||||||
|
function flyLine(earth, positions, unit) {
|
||||||
|
let arr = []
|
||||||
|
positions.forEach(item => {
|
||||||
|
arr.push([item.lng, item.lat])
|
||||||
|
})
|
||||||
|
arr.push(arr[0])
|
||||||
|
// eslint-disable-next-line no-undef
|
||||||
|
const turfPolygon = turf.polygon([arr])
|
||||||
|
// 获取四至
|
||||||
|
// eslint-disable-next-line no-undef
|
||||||
|
const turfExtent = turf.bbox(turfPolygon)
|
||||||
|
// 在turfPolygon中按网格取样点,网格间距3米
|
||||||
|
// eslint-disable-next-line no-undef
|
||||||
|
const turfSamplePoints = turf.pointGrid(turfExtent, unit / 1000, {
|
||||||
|
units: 'kilometers',
|
||||||
|
mask: turfPolygon
|
||||||
|
})
|
||||||
|
// 将turf取样点转为Cesium的取样点
|
||||||
|
const cesiumSamplePoints = []
|
||||||
|
for (let i = 0; i < turfSamplePoints.features.length; i++) {
|
||||||
|
const coord = turfSamplePoints.features[i].geometry.coordinates
|
||||||
|
cesiumSamplePoints.push([coord[0], coord[1]])
|
||||||
|
}
|
||||||
|
// 计算两点的距离
|
||||||
|
function fromTo(point1, point2) {
|
||||||
|
if (!point2) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// eslint-disable-next-line no-undef
|
||||||
|
let from = turf.point(point1)
|
||||||
|
// eslint-disable-next-line no-undef
|
||||||
|
let to = turf.point(point2)
|
||||||
|
// eslint-disable-next-line no-undef
|
||||||
|
return Math.round(turf.distance(from, to) * 1000)
|
||||||
|
}
|
||||||
|
// 进行分组并进行奇数反转
|
||||||
|
let polylinePosition = []
|
||||||
|
let flag = 0
|
||||||
|
let index = -1
|
||||||
|
for (let i = 0; i < cesiumSamplePoints.length; i++) {
|
||||||
|
if (fromTo(cesiumSamplePoints[i], cesiumSamplePoints[i + 1]) > unit) {
|
||||||
|
index++
|
||||||
|
let arr = cesiumSamplePoints.slice(flag, i + 1)
|
||||||
|
if (index % 2 !== 0) {
|
||||||
|
arr.reverse()
|
||||||
|
}
|
||||||
|
polylinePosition.push(arr)
|
||||||
|
flag = i + 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let arr2 = cesiumSamplePoints.slice(flag, cesiumSamplePoints.length)
|
||||||
|
if ((index + 1) % 2 !== 0) {
|
||||||
|
arr2.reverse()
|
||||||
|
}
|
||||||
|
polylinePosition.push(arr2)
|
||||||
|
return polylinePosition.flat()
|
||||||
|
}
|
||||||
|
// 获取高程
|
||||||
|
function sampleHeightMostDetailed(earth, positions) {
|
||||||
|
return earth.viewer.scene.sampleHeightMostDetailed([
|
||||||
|
new Cesium.Cartographic.fromDegrees(positions[0], positions[1])
|
||||||
|
])
|
||||||
|
}
|
||||||
|
// 计算高程
|
||||||
|
async function countHeight(earth, item) {
|
||||||
|
return await sampleHeightMostDetailed(earth, item)
|
||||||
|
}
|
||||||
|
function cartesian3Towgs84(earth, cartesian) {
|
||||||
|
const viewer = earth.viewer
|
||||||
|
var ellipsoid = viewer.scene.globe.ellipsoid
|
||||||
|
var cartesian3 = new Cesium.Cartesian3(cartesian.x, cartesian.y, cartesian.z)
|
||||||
|
var cartographic = ellipsoid.cartesianToCartographic(cartesian3)
|
||||||
|
var lat = Cesium.Math.toDegrees(cartographic.latitude)
|
||||||
|
var lng = Cesium.Math.toDegrees(cartographic.longitude)
|
||||||
|
var alt = cartographic.height < 0 ? 0 : cartographic.height
|
||||||
|
return {
|
||||||
|
longitude: lng,
|
||||||
|
latitude: lat,
|
||||||
|
height: alt
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//更新路径高度
|
||||||
|
async function updateHeight(earth, height, positions, cb) {
|
||||||
|
let Cartesian = []
|
||||||
|
let locationList = []
|
||||||
|
for (let i = 0; i < positions.length; i++) {
|
||||||
|
const element = positions[i]
|
||||||
|
let Cartographic = await countHeight(earth, element)
|
||||||
|
if (isNaN(Cartographic[0].height)) {
|
||||||
|
Cartographic[0].height = 0
|
||||||
|
}
|
||||||
|
Cartographic[0].height = Cartographic[0].height + height
|
||||||
|
Cartesian.push(Cesium.Cartographic.toCartesian(Cartographic[0]))
|
||||||
|
if (i < positions.length) {
|
||||||
|
cb({
|
||||||
|
cur: i + 1,
|
||||||
|
total: positions.length
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (let i = 0; i < Cartesian.length; i++) {
|
||||||
|
locationList.push(cartesian3Towgs84(earth, Cartesian[i]))
|
||||||
|
}
|
||||||
|
let arr = [locationList, Cartesian]
|
||||||
|
cb(arr)
|
||||||
|
}
|
||||||
|
let GenerateRoute = {
|
||||||
|
flyLine,
|
||||||
|
updateHeight
|
||||||
|
}
|
||||||
|
export default GenerateRoute
|
||||||
272
src/Obj/AirLine/billord_point_line.js
Normal file
272
src/Obj/AirLine/billord_point_line.js
Normal file
@ -0,0 +1,272 @@
|
|||||||
|
export default class BillordPointLine {
|
||||||
|
constructor(options, viewer) {
|
||||||
|
this.options = { ...options }
|
||||||
|
this.pointEntity = null
|
||||||
|
this.billboardEntity = null
|
||||||
|
this.lineEntity = null
|
||||||
|
this.updatedPosition = []
|
||||||
|
this.pointUpdatedPosition = []
|
||||||
|
this.viewer = viewer
|
||||||
|
this.handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas)
|
||||||
|
this.pinBuilder = new Cesium.PinBuilder()
|
||||||
|
this.index = null
|
||||||
|
//定义屏幕点击事件处理器
|
||||||
|
BillordPointLine.setDefaultValue(this)
|
||||||
|
BillordPointLine.init(this)
|
||||||
|
}
|
||||||
|
static setDefaultValue(that) {
|
||||||
|
that.options.positions = that.options.positions || {}
|
||||||
|
that.options.normalHeight = that.options.normalHeight || 100
|
||||||
|
that.options.airHeight = that.options.airHeight || 100
|
||||||
|
that.options.image = that.options.image || '/static/img/cluster2.png'
|
||||||
|
that.options.show = that.options.show || true
|
||||||
|
that.options.index = that.options.index || 1
|
||||||
|
that.options.saveFun = that.options.saveFun || null
|
||||||
|
that.options.selectFun = that.options.selectFun || null
|
||||||
|
that.options.keyboard = that.options.keyboard ?? true
|
||||||
|
that.options.updateFrustumFun = that.options.updateFrustumFun || null
|
||||||
|
that.options.frustum = that.options.frustum || null
|
||||||
|
}
|
||||||
|
static init(that) {
|
||||||
|
let positions = that.options.positions
|
||||||
|
// 添加一个Point,稍微偏离地面高度,使其完全可见
|
||||||
|
that.pointEntity = that.viewer.entities.add({
|
||||||
|
show: that.options.show,
|
||||||
|
position: Cesium.Cartesian3.fromDegrees(positions.lng, positions.lat, 0), // 地面上
|
||||||
|
point: {
|
||||||
|
pixelSize: 8,
|
||||||
|
color: Cesium.Color.WITHE,
|
||||||
|
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, // 使用相对地面或贴地,
|
||||||
|
disableDepthTestDistance: 0
|
||||||
|
}
|
||||||
|
})
|
||||||
|
//
|
||||||
|
let pinIndex = that.pinBuilder
|
||||||
|
.fromText(
|
||||||
|
that.options.index,
|
||||||
|
Cesium.Color.fromCssColorString('#00d590'),
|
||||||
|
36
|
||||||
|
)
|
||||||
|
.toDataURL()
|
||||||
|
let altitude = 0
|
||||||
|
if (positions.altitude) {
|
||||||
|
altitude = positions.altitude
|
||||||
|
} else {
|
||||||
|
altitude = that.options.normalHeight
|
||||||
|
}
|
||||||
|
// 添加一个Billboard
|
||||||
|
that.billboardEntity = that.viewer.entities.add({
|
||||||
|
show: that.options.show,
|
||||||
|
position: Cesium.Cartesian3.fromDegrees(
|
||||||
|
positions.lng,
|
||||||
|
positions.lat,
|
||||||
|
positions.alt + that.options.normalHeight
|
||||||
|
),
|
||||||
|
// 判断altitude是否有值
|
||||||
|
|
||||||
|
label: {
|
||||||
|
text: `Lat: ${positions.lng.toFixed(8)}\nLon: ${positions.lat.toFixed(
|
||||||
|
8
|
||||||
|
)}\nAlt: ${altitude.toFixed(8)}m`,
|
||||||
|
font: '14px sans-serif',
|
||||||
|
fillColor: Cesium.Color.YELLOW,
|
||||||
|
outlineColor: Cesium.Color.BLACK,
|
||||||
|
outlineWidth: 2,
|
||||||
|
pixelOffset: new Cesium.Cartesian2(0, -60), // 标签偏移量,防止重叠
|
||||||
|
heightReference: Cesium.HeightReference.RELATIVE_TO_TERRAIN, // 确保标签与地面贴合
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
billboard: {
|
||||||
|
image: pinIndex, // 示例图像路径
|
||||||
|
verticalOrigin: Cesium.VerticalOrigin.BOTTOM, // 图像底部对齐
|
||||||
|
width: 36,
|
||||||
|
height: 36
|
||||||
|
},
|
||||||
|
index: that.options.index
|
||||||
|
})
|
||||||
|
|
||||||
|
// 创建一个连接Point和Billboard的竖线
|
||||||
|
that.lineEntity = that.viewer.entities.add({
|
||||||
|
show: that.options.show,
|
||||||
|
polyline: {
|
||||||
|
positions: new Cesium.CallbackProperty(() => {
|
||||||
|
return [
|
||||||
|
that.pointEntity.position.getValue(),
|
||||||
|
that.billboardEntity.position.getValue()
|
||||||
|
]
|
||||||
|
}, false),
|
||||||
|
width: 1,
|
||||||
|
material: new Cesium.PolylineOutlineMaterialProperty({
|
||||||
|
outlineColor: Cesium.Color.GAINSBORO,
|
||||||
|
outlineWidth: 1,
|
||||||
|
color: Cesium.Color.WITHE
|
||||||
|
}),
|
||||||
|
zIndex: 99999999
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (that.options.keyboard) {
|
||||||
|
that.changeAltitude()
|
||||||
|
}
|
||||||
|
that.handler.setInputAction(function(movement) {
|
||||||
|
var pickedObject = that.viewer.scene.pick(movement.position)
|
||||||
|
if (
|
||||||
|
Cesium.defined(pickedObject) &&
|
||||||
|
Cesium.defined(pickedObject.id) &&
|
||||||
|
pickedObject.id === that.billboardEntity
|
||||||
|
) {
|
||||||
|
if (that.options.selectFun) {
|
||||||
|
that.options.selectFun(that.billboardEntity.index - 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, Cesium.ScreenSpaceEventType.LEFT_CLICK)
|
||||||
|
}
|
||||||
|
// 改变高度
|
||||||
|
changeAltitude() {
|
||||||
|
var isMouseDown = false
|
||||||
|
var startPosition
|
||||||
|
var initialHeight
|
||||||
|
let that = this
|
||||||
|
let HHH = false
|
||||||
|
// 标识Alt键是否被按下
|
||||||
|
document.addEventListener('keydown', function(event) {
|
||||||
|
const key = event.key // 获取按下的键名
|
||||||
|
// 检查特定键是否被按下
|
||||||
|
if (key === 'h') {
|
||||||
|
HHH = true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
document.addEventListener('keyup', function(event) {
|
||||||
|
HHH = false
|
||||||
|
})
|
||||||
|
// 按下鼠标左键
|
||||||
|
this.handler.setInputAction(function(movement) {
|
||||||
|
var pickedObject = that.viewer.scene.pick(movement.position)
|
||||||
|
if (
|
||||||
|
Cesium.defined(pickedObject) &&
|
||||||
|
Cesium.defined(pickedObject.id) &&
|
||||||
|
pickedObject.id === that.billboardEntity
|
||||||
|
) {
|
||||||
|
isMouseDown = true
|
||||||
|
startPosition = movement.position
|
||||||
|
|
||||||
|
// 获取Billboard当前的地理高度
|
||||||
|
var positionCartographic = Cesium.Cartographic.fromCartesian(
|
||||||
|
that.billboardEntity.position.getValue()
|
||||||
|
)
|
||||||
|
initialHeight = positionCartographic.height
|
||||||
|
}
|
||||||
|
}, Cesium.ScreenSpaceEventType.LEFT_DOWN)
|
||||||
|
// 移动鼠标
|
||||||
|
this.handler.setInputAction(function(movement) {
|
||||||
|
if (isMouseDown && HHH == false) {
|
||||||
|
// 移动位置
|
||||||
|
var newCartesian = that.viewer.scene.pickPosition(movement.endPosition)
|
||||||
|
that.disableCameraDrag(that.viewer, false)
|
||||||
|
if (newCartesian) {
|
||||||
|
var newCartographic = Cesium.Cartographic.fromCartesian(newCartesian)
|
||||||
|
// 保持高度不变
|
||||||
|
var newLongitude = newCartographic.longitude
|
||||||
|
var newLatitude = newCartographic.latitude
|
||||||
|
var updatedPosition = Cesium.Cartesian3.fromRadians(
|
||||||
|
newLongitude,
|
||||||
|
newLatitude,
|
||||||
|
initialHeight
|
||||||
|
)
|
||||||
|
var pointUpdatedPosition = Cesium.Cartesian3.fromRadians(
|
||||||
|
newLongitude,
|
||||||
|
newLatitude,
|
||||||
|
0
|
||||||
|
)
|
||||||
|
that.billboardEntity.position = new Cesium.CallbackProperty(() => {
|
||||||
|
return updatedPosition
|
||||||
|
}, false)
|
||||||
|
that.billboardEntity.label.text = `Lat: ${Cesium.Math.toDegrees(
|
||||||
|
newLongitude
|
||||||
|
).toFixed(6)}\nLon: ${Cesium.Math.toDegrees(newLatitude).toFixed(
|
||||||
|
6
|
||||||
|
)}\nAlt: ${initialHeight.toFixed(2)}m`
|
||||||
|
that.pointEntity.position = new Cesium.CallbackProperty(() => {
|
||||||
|
return pointUpdatedPosition
|
||||||
|
}, false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (isMouseDown && HHH) {
|
||||||
|
console.log(HHH)
|
||||||
|
// 改变高度
|
||||||
|
var endPosition = movement.endPosition
|
||||||
|
var deltaY = startPosition.y - endPosition.y // 计算Y轴方向上的移动距离
|
||||||
|
// 根据鼠标移动的距离来调整高度
|
||||||
|
var newHeight = initialHeight + deltaY
|
||||||
|
// 更新billboard位置
|
||||||
|
var positionCartographic = Cesium.Cartographic.fromCartesian(
|
||||||
|
that.billboardEntity.position.getValue()
|
||||||
|
)
|
||||||
|
var newPosition = Cesium.Cartesian3.fromDegrees(
|
||||||
|
Cesium.Math.toDegrees(positionCartographic.longitude),
|
||||||
|
Cesium.Math.toDegrees(positionCartographic.latitude),
|
||||||
|
newHeight
|
||||||
|
)
|
||||||
|
// 禁用相机
|
||||||
|
that.disableCameraDrag(that.viewer, false)
|
||||||
|
that.billboardEntity.position = new Cesium.CallbackProperty(() => {
|
||||||
|
return newPosition
|
||||||
|
}, false)
|
||||||
|
that.billboardEntity.label.text = `Lat: ${Cesium.Math.toDegrees(
|
||||||
|
positionCartographic.longitude
|
||||||
|
).toFixed(6)}\nLon: ${Cesium.Math.toDegrees(
|
||||||
|
positionCartographic.latitude
|
||||||
|
).toFixed(6)}\nAlt: ${newHeight.toFixed(2)}m`
|
||||||
|
}
|
||||||
|
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE)
|
||||||
|
// 松开鼠标左键
|
||||||
|
this.handler.setInputAction(function(movement) {
|
||||||
|
var pickedObject = that.viewer.scene.pick(movement.position)
|
||||||
|
isMouseDown = false // 禁用相机
|
||||||
|
HHH = false //
|
||||||
|
that.disableCameraDrag(that.viewer, true)
|
||||||
|
// 更新frustum的位置
|
||||||
|
if (
|
||||||
|
Cesium.defined(pickedObject) &&
|
||||||
|
Cesium.defined(pickedObject.id) &&
|
||||||
|
pickedObject.id === that.billboardEntity
|
||||||
|
) {
|
||||||
|
if (that.options.saveFun) {
|
||||||
|
that.options.saveFun(null, false)
|
||||||
|
}
|
||||||
|
if (that.options.selectFun) {
|
||||||
|
that.options.selectFun(that.billboardEntity.index - 1)
|
||||||
|
}
|
||||||
|
that.options.frustum.updatePositionHeight(
|
||||||
|
that.billboardEntity.position.getValue()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}, Cesium.ScreenSpaceEventType.LEFT_UP)
|
||||||
|
}
|
||||||
|
|
||||||
|
disableCameraDrag(viewer, bool) {
|
||||||
|
viewer.scene.screenSpaceCameraController.enableRotate = bool
|
||||||
|
viewer.scene.screenSpaceCameraController.enableTranslate = bool
|
||||||
|
viewer.scene.screenSpaceCameraController.enableZoom = bool
|
||||||
|
viewer.scene.screenSpaceCameraController.enableTilt = bool
|
||||||
|
viewer.scene.screenSpaceCameraController.enableLook = bool
|
||||||
|
}
|
||||||
|
get show() {
|
||||||
|
return this.options.show
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param {boolean} bool
|
||||||
|
*/
|
||||||
|
set show(bool) {
|
||||||
|
if (typeof bool === 'boolean') {
|
||||||
|
this.pointEntity.show = bool
|
||||||
|
this.billboardEntity.show = bool
|
||||||
|
this.lineEntity.show = bool
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
remove() {
|
||||||
|
this.viewer.entities.remove(this.pointEntity)
|
||||||
|
this.viewer.entities.remove(this.billboardEntity)
|
||||||
|
this.viewer.entities.remove(this.lineEntity)
|
||||||
|
}
|
||||||
|
}
|
||||||
673
src/Obj/AirLine/frustum.js
Normal file
673
src/Obj/AirLine/frustum.js
Normal file
@ -0,0 +1,673 @@
|
|||||||
|
export default class Frustum {
|
||||||
|
constructor(options, viewer, viewer1) {
|
||||||
|
this.options = { ...options }
|
||||||
|
this.viewer = viewer
|
||||||
|
this.viewer1 = viewer1
|
||||||
|
this.head = 0
|
||||||
|
this.pitch = 90
|
||||||
|
this.po = 0.00001
|
||||||
|
this.position = null
|
||||||
|
this.hpr = null
|
||||||
|
this.currentFrustumOutline = null
|
||||||
|
this.frustum = null
|
||||||
|
this.setInterval1 = null
|
||||||
|
this.webrtc = null
|
||||||
|
|
||||||
|
// 设置默认值
|
||||||
|
Frustum.setDefaultValue(this)
|
||||||
|
this.create()
|
||||||
|
}
|
||||||
|
|
||||||
|
static setDefaultValue(that) {
|
||||||
|
that.options.position = that.options.position || {}
|
||||||
|
that.options.fov = that.options.fov || 30
|
||||||
|
that.options.aspectRatio = that.options.aspectRatio || 1
|
||||||
|
that.options.near = that.options.near || 1
|
||||||
|
that.options.far = that.options.far || 120
|
||||||
|
that.options.heading = that.options.heading || 0
|
||||||
|
that.options.pitch = that.options.pitch || 90
|
||||||
|
that.options.roll = that.options.roll || 0
|
||||||
|
that.options.show = that.options.show ?? true
|
||||||
|
that.options.videoUrl = that.options.videoUrl || ''
|
||||||
|
that.options.index = that.options.index || 0
|
||||||
|
that.options.arr = that.options.arr || []
|
||||||
|
that.options.normalHeight = that.options.normalHeight || 100
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化视锥体
|
||||||
|
create() {
|
||||||
|
this.frustum = new Cesium.PerspectiveFrustum({
|
||||||
|
fov: Cesium.Math.toRadians(this.options.fov),
|
||||||
|
aspectRatio: this.options.aspectRatio,
|
||||||
|
near: this.options.near,
|
||||||
|
far: this.options.far
|
||||||
|
})
|
||||||
|
|
||||||
|
const { lng, lat, alt } = this.options.position
|
||||||
|
const { heading, pitch, roll } = this.options
|
||||||
|
this.position = Cesium.Cartesian3.fromDegrees(
|
||||||
|
lng,
|
||||||
|
lat,
|
||||||
|
alt + this.options.normalHeight
|
||||||
|
)
|
||||||
|
this.hpr = new Cesium.HeadingPitchRoll(
|
||||||
|
Cesium.Math.toRadians(heading),
|
||||||
|
Cesium.Math.toRadians(pitch),
|
||||||
|
Cesium.Math.toRadians(roll)
|
||||||
|
)
|
||||||
|
|
||||||
|
this.drawFrustumOutline()
|
||||||
|
this.drawFrustumFilled()
|
||||||
|
this.monitorKeyboard()
|
||||||
|
this.updateFrustumSquareBase(40)
|
||||||
|
this.syncHpr()
|
||||||
|
if (this.options.videoUrl) {
|
||||||
|
this.addVideoToFrustumTop2()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 监听键盘事件
|
||||||
|
monitorKeyboard() {
|
||||||
|
const keyActions = {
|
||||||
|
KeyQ: () => this.setIntervalhpr(-0.45),
|
||||||
|
KeyE: () => this.setIntervalhpr(0.45),
|
||||||
|
KeyB: () => this.setIntervalhprr(-0.45),
|
||||||
|
KeyN: () => this.setIntervalhprr(0.45),
|
||||||
|
KeyW: () => this.updateFrustumPosition('move', -0.00001),
|
||||||
|
KeyS: () => this.updateFrustumPosition('move', 0.00001),
|
||||||
|
KeyA: () => this.updateFrustumPosition('move', -0.00001, 0),
|
||||||
|
KeyD: () => this.updateFrustumPosition('move', 0.00001, 0),
|
||||||
|
KeyC: () => this.updateFrustumHeight(1), // 增加高度
|
||||||
|
KeyZ: () => this.updateFrustumHeight(-1) // 降低高度
|
||||||
|
}
|
||||||
|
|
||||||
|
this.keydownHandler = event => {
|
||||||
|
if (keyActions[event.code]) keyActions[event.code]()
|
||||||
|
}
|
||||||
|
|
||||||
|
this.keyupHandler = () => this.stopFrustumRotation()
|
||||||
|
|
||||||
|
document.addEventListener('keydown', this.keydownHandler)
|
||||||
|
|
||||||
|
document.addEventListener('keyup', this.keyupHandler)
|
||||||
|
}
|
||||||
|
// 渲染视频
|
||||||
|
addVideoToFrustumTop() {
|
||||||
|
// 创建视频元素
|
||||||
|
const videoElement = document.createElement('video')
|
||||||
|
videoElement.width = 640
|
||||||
|
videoElement.height = 360
|
||||||
|
videoElement.autoplay = true
|
||||||
|
videoElement.loop = true
|
||||||
|
videoElement.muted = true
|
||||||
|
// videoElement.style.display = 'none'; // 隐藏视频元素
|
||||||
|
document.body.appendChild(videoElement)
|
||||||
|
|
||||||
|
// 使用 flv.js 播放 FLV 视频
|
||||||
|
if (flvjs.isSupported()) {
|
||||||
|
const flvPlayer = flvjs.createPlayer({
|
||||||
|
// url: 'http://zmkg.cqet.top:9991/live/2pUbcgTrly3mIDuxsDXN9h3hqcEKU6TlsV_YeIDyqHqXGzXafqWokXdU1q6j_S7hTCP7HynZQIsuNM6KQ5l-ag==.flv',
|
||||||
|
type: 'flv',
|
||||||
|
isLive: true,
|
||||||
|
hasAudio: false,
|
||||||
|
enableStashBuffer: true, //
|
||||||
|
enableWorker: true,
|
||||||
|
autoCleanupSourceBuffer: true, //自动清除缓存
|
||||||
|
url: this.options.videoUrl
|
||||||
|
})
|
||||||
|
flvPlayer.attachMediaElement(videoElement)
|
||||||
|
flvPlayer.load()
|
||||||
|
flvPlayer.play()
|
||||||
|
} else {
|
||||||
|
console.error('FLV.js is not supported in this browser.')
|
||||||
|
}
|
||||||
|
|
||||||
|
const corners = this.computeFrustumCorners(
|
||||||
|
this.frustum,
|
||||||
|
this.position,
|
||||||
|
this.hpr
|
||||||
|
)
|
||||||
|
// 创建 PolygonGeometry 并应用视频作为纹理
|
||||||
|
const polygonHierarchy = new Cesium.PolygonHierarchy([
|
||||||
|
corners.bottomLeft,
|
||||||
|
corners.bottomRight,
|
||||||
|
corners.topRight,
|
||||||
|
corners.topLeft
|
||||||
|
])
|
||||||
|
this.videoEntity = this.viewer.entities.add(
|
||||||
|
new Cesium.Entity({
|
||||||
|
id: '22222222',
|
||||||
|
show: true,
|
||||||
|
polygon: {
|
||||||
|
hierarchy: polygonHierarchy
|
||||||
|
}
|
||||||
|
})
|
||||||
|
)
|
||||||
|
videoElement.addEventListener('loadeddata', () => {
|
||||||
|
this.videoEntity.polygon.material = videoElement // 确保视频纹理加载后再设置
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 渲染视频
|
||||||
|
async addVideoToFrustumTop2() {
|
||||||
|
// 创建视频元素
|
||||||
|
const videoElement = document.createElement('video')
|
||||||
|
videoElement.width = 640
|
||||||
|
videoElement.height = 360
|
||||||
|
videoElement.autoplay = true
|
||||||
|
videoElement.loop = true
|
||||||
|
videoElement.muted = true
|
||||||
|
// videoElement.style.display = 'none'; // 隐藏视频元素
|
||||||
|
document.body.appendChild(videoElement)
|
||||||
|
await this.startPlay(videoElement, this.options.videoUrl)
|
||||||
|
const corners = this.computeFrustumCorners(
|
||||||
|
this.frustum,
|
||||||
|
this.position,
|
||||||
|
this.hpr
|
||||||
|
)
|
||||||
|
// 创建 PolygonGeometry 并应用视频作为纹理
|
||||||
|
const polygonHierarchy = new Cesium.PolygonHierarchy([
|
||||||
|
corners.bottomLeft,
|
||||||
|
corners.bottomRight,
|
||||||
|
corners.topRight,
|
||||||
|
corners.topLeft
|
||||||
|
])
|
||||||
|
this.videoEntity = this.viewer.entities.add(
|
||||||
|
new Cesium.Entity({
|
||||||
|
id: '22222222',
|
||||||
|
show: true,
|
||||||
|
polygon: {
|
||||||
|
hierarchy: polygonHierarchy
|
||||||
|
}
|
||||||
|
})
|
||||||
|
)
|
||||||
|
videoElement.addEventListener('loadeddata', () => {
|
||||||
|
this.videoEntity.polygon.material = videoElement // 确保视频纹理加载后再设置
|
||||||
|
})
|
||||||
|
}
|
||||||
|
async startPlay(element, url) {
|
||||||
|
// Close existing SDK instance if any
|
||||||
|
if (this.webrtc) {
|
||||||
|
this.webrtc.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize a new SDK instance
|
||||||
|
this.webrtc = new SrsRtcWhipWhepAsync()
|
||||||
|
|
||||||
|
// Bind the video player to the SDK stream
|
||||||
|
element.srcObject = this.webrtc.stream
|
||||||
|
|
||||||
|
try {
|
||||||
|
const session = await this.webrtc.play(url)
|
||||||
|
console.log(session)
|
||||||
|
// this.sessionId = session.sessionid
|
||||||
|
// this.simulatorUrl = `${session.simulator}?drop=1&username=${session.sessionid}`
|
||||||
|
} catch (error) {
|
||||||
|
// console.error('Error playing stream:', error)
|
||||||
|
this.webrtc.close()
|
||||||
|
// this.playerVisible = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 计算视锥体远裁剪面(大面)的四个角点
|
||||||
|
computeFrustumCorners(frustum, position, hpr) {
|
||||||
|
const tanFov = Math.tan(frustum.fov * 0.5)
|
||||||
|
const farHeight = frustum.far * tanFov
|
||||||
|
const farWidth = farHeight * frustum.aspectRatio
|
||||||
|
|
||||||
|
const topLeft = new Cesium.Cartesian3(-farWidth, farHeight, -frustum.far)
|
||||||
|
const topRight = new Cesium.Cartesian3(farWidth, farHeight, -frustum.far)
|
||||||
|
const bottomLeft = new Cesium.Cartesian3(
|
||||||
|
-farWidth,
|
||||||
|
-farHeight,
|
||||||
|
-frustum.far
|
||||||
|
)
|
||||||
|
const bottomRight = new Cesium.Cartesian3(
|
||||||
|
farWidth,
|
||||||
|
-farHeight,
|
||||||
|
-frustum.far
|
||||||
|
)
|
||||||
|
const transform = Cesium.Transforms.headingPitchRollToFixedFrame(
|
||||||
|
position,
|
||||||
|
hpr
|
||||||
|
)
|
||||||
|
// console.log('transform111111111111111111111111', transform)
|
||||||
|
return {
|
||||||
|
topLeft: Cesium.Matrix4.multiplyByPoint(
|
||||||
|
transform,
|
||||||
|
topLeft,
|
||||||
|
new Cesium.Cartesian3()
|
||||||
|
),
|
||||||
|
topRight: Cesium.Matrix4.multiplyByPoint(
|
||||||
|
transform,
|
||||||
|
topRight,
|
||||||
|
new Cesium.Cartesian3()
|
||||||
|
),
|
||||||
|
bottomLeft: Cesium.Matrix4.multiplyByPoint(
|
||||||
|
transform,
|
||||||
|
bottomLeft,
|
||||||
|
new Cesium.Cartesian3()
|
||||||
|
),
|
||||||
|
bottomRight: Cesium.Matrix4.multiplyByPoint(
|
||||||
|
transform,
|
||||||
|
bottomRight,
|
||||||
|
new Cesium.Cartesian3()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 封装的函数:更新 Polygon 面的位置
|
||||||
|
updatePolygonPosition() {
|
||||||
|
const corners = this.computeFrustumCorners(
|
||||||
|
this.frustum,
|
||||||
|
this.position,
|
||||||
|
this.hpr
|
||||||
|
)
|
||||||
|
|
||||||
|
this.videoEntity.polygon.hierarchy = new Cesium.CallbackProperty(e => {
|
||||||
|
return new Cesium.PolygonHierarchy([
|
||||||
|
corners.bottomLeft,
|
||||||
|
corners.bottomRight,
|
||||||
|
corners.topRight,
|
||||||
|
corners.topLeft
|
||||||
|
])
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 更新锥体底部为正方形的方法
|
||||||
|
updateFrustumSquareBase(value) {
|
||||||
|
// 将输入值范围从 56 到 1 映射到面积范围 10000 到 100
|
||||||
|
const minArea = 100 // 最小面积
|
||||||
|
const maxArea = 10000 // 最大面积
|
||||||
|
|
||||||
|
// 映射公式(反转映射)
|
||||||
|
const newArea = ((56 - value) / (56 - 1)) * (maxArea - minArea) + minArea
|
||||||
|
|
||||||
|
// 确保aspectRatio保持为1(正方形)
|
||||||
|
this.frustum.aspectRatio = 1
|
||||||
|
|
||||||
|
// 根据面积计算正方形边长
|
||||||
|
const sideLength = Math.sqrt(newArea)
|
||||||
|
|
||||||
|
// 远平面距离
|
||||||
|
const far = this.frustum.far
|
||||||
|
|
||||||
|
// 计算新的fov
|
||||||
|
const fov = 2 * Math.atan(sideLength / (2 * far))
|
||||||
|
|
||||||
|
// 更新视锥体的fov
|
||||||
|
this.frustum.fov = fov
|
||||||
|
|
||||||
|
// 重新绘制视锥体轮廓和填充
|
||||||
|
this.drawFrustumOutline()
|
||||||
|
this.drawFrustumFilled()
|
||||||
|
this.syncHpr()
|
||||||
|
}
|
||||||
|
updateFrustumHeight(deltaHeight) {
|
||||||
|
const cartographic = Cesium.Cartographic.fromCartesian(this.position)
|
||||||
|
cartographic.height += deltaHeight // 更新高度
|
||||||
|
this.position = Cesium.Cartesian3.fromDegrees(
|
||||||
|
Cesium.Math.toDegrees(cartographic.longitude),
|
||||||
|
Cesium.Math.toDegrees(cartographic.latitude),
|
||||||
|
cartographic.height
|
||||||
|
)
|
||||||
|
this.options.position.alt = cartographic.height
|
||||||
|
// this.options.arr[
|
||||||
|
// this.options.index
|
||||||
|
// ] = this.viewer.scene.globe.ellipsoid.cartographicToCartesian(cartographic)
|
||||||
|
this.syncHpr()
|
||||||
|
this.drawFrustumOutline() // 重新绘制视锥体轮廓
|
||||||
|
this.drawFrustumFilled()
|
||||||
|
}
|
||||||
|
// 更新position变化后的视锥体属性
|
||||||
|
updatePositionHeight(p) {
|
||||||
|
this.options.position = this.cartesian3Towgs84(p)
|
||||||
|
this.syncHpr()
|
||||||
|
this.drawFrustumOutline() // 重新绘制视锥体轮廓
|
||||||
|
this.drawFrustumFilled()
|
||||||
|
}
|
||||||
|
cartesian3Towgs84(cartesian) {
|
||||||
|
var ellipsoid = this.viewer.scene.globe.ellipsoid
|
||||||
|
var cartesian3 = new Cesium.Cartesian3(
|
||||||
|
cartesian.x,
|
||||||
|
cartesian.y,
|
||||||
|
cartesian.z
|
||||||
|
)
|
||||||
|
var cartographic = ellipsoid.cartesianToCartographic(cartesian3)
|
||||||
|
var lat = Cesium.Math.toDegrees(cartographic.latitude)
|
||||||
|
var lng = Cesium.Math.toDegrees(cartographic.longitude)
|
||||||
|
var alt = cartographic.height < 0 ? 0 : cartographic.height
|
||||||
|
return {
|
||||||
|
lng: lng,
|
||||||
|
lat: lat,
|
||||||
|
alt: alt
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setIntervalhpr(num) {
|
||||||
|
this.stopFrustumRotation() // 先停止当前的定时器
|
||||||
|
this.setInterval1 = setInterval(() => {
|
||||||
|
this.head += num
|
||||||
|
this.updateFrustumHPR(Cesium.Math.toRadians(this.head), this.pitch)
|
||||||
|
}, 10)
|
||||||
|
}
|
||||||
|
setIntervalhprr(num) {
|
||||||
|
this.stopFrustumRotation() // 先停止当前的定时器
|
||||||
|
this.setInterval1 = setInterval(() => {
|
||||||
|
// 限制 pitch 在 [60, 180] 范围内
|
||||||
|
this.pitch = Math.max(60, Math.min(180, this.pitch + num))
|
||||||
|
this.updateFrustumHPR(this.head, Cesium.Math.toRadians(this.pitch))
|
||||||
|
}, 10)
|
||||||
|
}
|
||||||
|
// 停止视锥体旋转
|
||||||
|
stopFrustumRotation() {
|
||||||
|
if (this.setInterval1) {
|
||||||
|
clearInterval(this.setInterval1)
|
||||||
|
this.setInterval1 = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 新增:绘制填充的视锥体
|
||||||
|
drawFrustumFilled() {
|
||||||
|
let that = this
|
||||||
|
// console.log('that.options.show', that.options.show)
|
||||||
|
|
||||||
|
const transform = Cesium.Transforms.headingPitchRollToFixedFrame(
|
||||||
|
this.position,
|
||||||
|
this.hpr
|
||||||
|
)
|
||||||
|
|
||||||
|
const frustumGeometry = new Cesium.FrustumGeometry({
|
||||||
|
frustum: this.frustum,
|
||||||
|
origin: Cesium.Matrix4.getTranslation(transform, new Cesium.Cartesian3()),
|
||||||
|
orientation: Cesium.Quaternion.fromRotationMatrix(
|
||||||
|
Cesium.Matrix4.getRotation(transform, new Cesium.Matrix3())
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
if (this.currentFrustumFilled) {
|
||||||
|
this.viewer.scene.primitives.remove(this.currentFrustumFilled)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.currentFrustumFilled = new Cesium.Primitive({
|
||||||
|
geometryInstances: new Cesium.GeometryInstance({
|
||||||
|
geometry: frustumGeometry,
|
||||||
|
attributes: {
|
||||||
|
color: Cesium.ColorGeometryInstanceAttribute.fromColor(
|
||||||
|
Cesium.Color.fromAlpha(Cesium.Color.YELLOW, 0.4) // 半透明黄色填充
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
appearance: new Cesium.MaterialAppearance({
|
||||||
|
material: Cesium.Material.fromType('Color', {
|
||||||
|
color: Cesium.Color.fromAlpha(Cesium.Color.YELLOW, 0.4) // 填充颜色
|
||||||
|
}),
|
||||||
|
translucent: true
|
||||||
|
}),
|
||||||
|
asynchronous: false,
|
||||||
|
// show: false
|
||||||
|
show: that.options.show
|
||||||
|
})
|
||||||
|
|
||||||
|
this.viewer.scene.primitives.add(this.currentFrustumFilled)
|
||||||
|
}
|
||||||
|
// 绘制视锥体轮廓
|
||||||
|
drawFrustumOutline() {
|
||||||
|
let that = this
|
||||||
|
// console.log('that.options.show', that.options.show)
|
||||||
|
|
||||||
|
const transform = Cesium.Transforms.headingPitchRollToFixedFrame(
|
||||||
|
this.position,
|
||||||
|
this.hpr
|
||||||
|
)
|
||||||
|
|
||||||
|
const frustumOutlineGeometry = new Cesium.FrustumOutlineGeometry({
|
||||||
|
frustum: this.frustum,
|
||||||
|
origin: Cesium.Matrix4.getTranslation(transform, new Cesium.Cartesian3()),
|
||||||
|
orientation: Cesium.Quaternion.fromRotationMatrix(
|
||||||
|
Cesium.Matrix4.getRotation(transform, new Cesium.Matrix3())
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
if (this.currentFrustumOutline) {
|
||||||
|
this.viewer.scene.primitives.remove(this.currentFrustumOutline)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.currentFrustumOutline = new Cesium.Primitive({
|
||||||
|
geometryInstances: new Cesium.GeometryInstance({
|
||||||
|
geometry: frustumOutlineGeometry,
|
||||||
|
attributes: {
|
||||||
|
color: Cesium.ColorGeometryInstanceAttribute.fromColor(
|
||||||
|
Cesium.Color.YELLOW
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
appearance: new Cesium.PolylineColorAppearance({
|
||||||
|
translucent: false
|
||||||
|
}),
|
||||||
|
asynchronous: false,
|
||||||
|
show: that.options.show
|
||||||
|
// show: false
|
||||||
|
})
|
||||||
|
|
||||||
|
this.viewer.scene.primitives.add(this.currentFrustumOutline)
|
||||||
|
}
|
||||||
|
// 更新视锥体位置
|
||||||
|
updateFrustumPosition(type = 'move', p, deg = 90, flag = true) {
|
||||||
|
if (type === 'move') {
|
||||||
|
// eslint-disable-next-line no-undef
|
||||||
|
const point = turf.point([
|
||||||
|
this.options.position.lng,
|
||||||
|
this.options.position.lat
|
||||||
|
])
|
||||||
|
const degreesValue = Cesium.Math.toDegrees(this.hpr.heading)
|
||||||
|
const bearing = degreesValue + deg
|
||||||
|
const options = { units: 'degrees' }
|
||||||
|
// eslint-disable-next-line no-undef
|
||||||
|
const destination = turf.destination(point, p, bearing, options).geometry
|
||||||
|
.coordinates
|
||||||
|
|
||||||
|
this.position = Cesium.Cartesian3.fromDegrees(
|
||||||
|
destination[0],
|
||||||
|
destination[1],
|
||||||
|
this.options.position.alt + this.options.normalHeight
|
||||||
|
)
|
||||||
|
this.options.position.lng = destination[0]
|
||||||
|
this.options.position.lat = destination[1]
|
||||||
|
|
||||||
|
this.viewer.camera.setView({
|
||||||
|
destination: Cesium.Cartesian3.fromDegrees(
|
||||||
|
destination[0],
|
||||||
|
destination[1],
|
||||||
|
this.viewer.camera.positionCartographic.height
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (type === 'update') {
|
||||||
|
this.position = p
|
||||||
|
this.options.videoUrl && this.updatePolygonPosition()
|
||||||
|
}
|
||||||
|
if (flag) {
|
||||||
|
this.syncHpr()
|
||||||
|
this.updateFrustumAttributes()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 同步视角
|
||||||
|
syncHpr() {
|
||||||
|
// console.log('this.viewer1', this.viewer1);
|
||||||
|
if (this.viewer1) {
|
||||||
|
const { lng, lat, alt } = this.options.position
|
||||||
|
let pitch = -this.hpr.pitch - Cesium.Math.toRadians(-90.0)
|
||||||
|
this.viewer1.camera.setView({
|
||||||
|
destination: Cesium.Cartesian3.fromDegrees(
|
||||||
|
lng,
|
||||||
|
lat,
|
||||||
|
alt + this.options.normalHeight
|
||||||
|
),
|
||||||
|
orientation: {
|
||||||
|
heading: this.hpr.heading + Cesium.Math.toRadians(-90.0),
|
||||||
|
pitch,
|
||||||
|
roll: this.hpr.roll
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 更新视锥体的 HeadingPitchRoll
|
||||||
|
updateFrustumHPR(
|
||||||
|
h = this.head,
|
||||||
|
p = this.pitch,
|
||||||
|
r = 0,
|
||||||
|
flag = true,
|
||||||
|
type = ''
|
||||||
|
) {
|
||||||
|
function degreesToRadians(degrees) {
|
||||||
|
return (degrees * Math.PI) / 180.0
|
||||||
|
}
|
||||||
|
if (type == 'alone') {
|
||||||
|
this.hpr.heading = degreesToRadians(h)
|
||||||
|
this.hpr.pitch = degreesToRadians(p)
|
||||||
|
this.hpr.roll = degreesToRadians(r)
|
||||||
|
} else {
|
||||||
|
this.hpr.heading = Cesium.Math.negativePiToPi(h)
|
||||||
|
this.hpr.pitch = Cesium.Math.negativePiToPi(p)
|
||||||
|
this.hpr.roll = Cesium.Math.negativePiToPi(r)
|
||||||
|
}
|
||||||
|
if (flag) {
|
||||||
|
this.syncHpr()
|
||||||
|
this.updateFrustumAttributes()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 用于更新
|
||||||
|
updateFrustumAttributes() {
|
||||||
|
let that = this
|
||||||
|
// 检查 position 和 hpr 是否已初始化
|
||||||
|
if (!this.position || !this.hpr) {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.error('Position or HPR is not defined:', this.position, this.hpr)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生成变换矩阵
|
||||||
|
const transform = Cesium.Transforms.headingPitchRollToFixedFrame(
|
||||||
|
this.position,
|
||||||
|
this.hpr
|
||||||
|
)
|
||||||
|
|
||||||
|
if (!transform) {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.error('Transform generation failed.')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 准备轮廓几何体和外观
|
||||||
|
const outlineGeometry = new Cesium.FrustumOutlineGeometry({
|
||||||
|
frustum: this.frustum,
|
||||||
|
origin: Cesium.Matrix4.getTranslation(
|
||||||
|
transform,
|
||||||
|
new Cesium.Cartesian3()
|
||||||
|
),
|
||||||
|
orientation: Cesium.Quaternion.fromRotationMatrix(
|
||||||
|
Cesium.Matrix4.getRotation(transform, new Cesium.Matrix3())
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
const outlineAppearance = new Cesium.PolylineColorAppearance({
|
||||||
|
translucent: false
|
||||||
|
})
|
||||||
|
const outlineColor = Cesium.ColorGeometryInstanceAttribute.fromColor(
|
||||||
|
Cesium.Color.YELLOW
|
||||||
|
)
|
||||||
|
|
||||||
|
// 准备填充几何体和外观
|
||||||
|
const filledGeometry = new Cesium.FrustumGeometry({
|
||||||
|
frustum: this.frustum,
|
||||||
|
origin: Cesium.Matrix4.getTranslation(
|
||||||
|
transform,
|
||||||
|
new Cesium.Cartesian3()
|
||||||
|
),
|
||||||
|
orientation: Cesium.Quaternion.fromRotationMatrix(
|
||||||
|
Cesium.Matrix4.getRotation(transform, new Cesium.Matrix3())
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
const filledAppearance = new Cesium.MaterialAppearance({
|
||||||
|
material: Cesium.Material.fromType('Color', {
|
||||||
|
color: Cesium.Color.YELLOW.withAlpha(0.5)
|
||||||
|
}),
|
||||||
|
translucent: true
|
||||||
|
})
|
||||||
|
const filledColor = Cesium.ColorGeometryInstanceAttribute.fromColor(
|
||||||
|
Cesium.Color.RED.withAlpha(0.5)
|
||||||
|
)
|
||||||
|
|
||||||
|
// 删除旧的 Primitive
|
||||||
|
if (this.currentFrustumOutline) {
|
||||||
|
this.viewer.scene.primitives.remove(this.currentFrustumOutline)
|
||||||
|
}
|
||||||
|
if (this.currentFrustumFilled) {
|
||||||
|
this.viewer.scene.primitives.remove(this.currentFrustumFilled)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建并添加新的轮廓 Primitive
|
||||||
|
this.currentFrustumOutline = new Cesium.Primitive({
|
||||||
|
geometryInstances: new Cesium.GeometryInstance({
|
||||||
|
geometry: outlineGeometry,
|
||||||
|
attributes: { color: outlineColor }
|
||||||
|
}),
|
||||||
|
appearance: outlineAppearance,
|
||||||
|
asynchronous: false,
|
||||||
|
show: that.options.show
|
||||||
|
})
|
||||||
|
this.viewer.scene.primitives.add(this.currentFrustumOutline)
|
||||||
|
|
||||||
|
// 创建并添加新的填充 Primitive
|
||||||
|
this.currentFrustumFilled = new Cesium.Primitive({
|
||||||
|
geometryInstances: new Cesium.GeometryInstance({
|
||||||
|
geometry: filledGeometry,
|
||||||
|
attributes: { color: filledColor }
|
||||||
|
}),
|
||||||
|
appearance: filledAppearance,
|
||||||
|
asynchronous: false,
|
||||||
|
show: that.options.show
|
||||||
|
})
|
||||||
|
this.viewer.scene.primitives.add(this.currentFrustumFilled)
|
||||||
|
} catch (error) {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.error('Error in drawFrustum:', error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 调整视锥体的 near 和 far 平面
|
||||||
|
updateFrustumNearFar(newNear, newFar) {
|
||||||
|
this.frustum.near = newNear
|
||||||
|
this.frustum.far = newFar
|
||||||
|
this.drawFrustumOutline()
|
||||||
|
this.drawFrustumFilled()
|
||||||
|
}
|
||||||
|
// 调整视锥体的 fov
|
||||||
|
updateFrustumFov(newFov) {
|
||||||
|
this.frustum.fov = Cesium.Math.toRadians(newFov)
|
||||||
|
this.drawFrustumOutline()
|
||||||
|
this.drawFrustumFilled()
|
||||||
|
}
|
||||||
|
|
||||||
|
get show() {
|
||||||
|
return this.options.show
|
||||||
|
}
|
||||||
|
|
||||||
|
set show(bool) {
|
||||||
|
if (typeof bool === 'boolean') {
|
||||||
|
this.options.show = bool
|
||||||
|
this.currentFrustumOutline.show = bool
|
||||||
|
this.currentFrustumFilled.show = bool
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
remove() {
|
||||||
|
document.removeEventListener('keydown', this.keydownHandler)
|
||||||
|
document.removeEventListener('keyup', this.keyupHandler)
|
||||||
|
if (this.currentFrustumFilled) {
|
||||||
|
this.viewer.scene.primitives.remove(this.currentFrustumFilled)
|
||||||
|
}
|
||||||
|
if (this.currentFrustumOutline) {
|
||||||
|
this.viewer.scene.primitives.remove(this.currentFrustumOutline)
|
||||||
|
}
|
||||||
|
if (this.videoEntity) {
|
||||||
|
this.viewer.entities.remove(this.videoEntity)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
257
src/Obj/AirLine/frustum2.js
Normal file
257
src/Obj/AirLine/frustum2.js
Normal file
@ -0,0 +1,257 @@
|
|||||||
|
export default class FRUSTUN {
|
||||||
|
constructor(options, viewer, viewer1) {
|
||||||
|
this.options = { ...options }
|
||||||
|
this.viewer = viewer
|
||||||
|
this.viewer1 = viewer1
|
||||||
|
this.head = 0
|
||||||
|
this.po = 0.00001
|
||||||
|
this.position = null
|
||||||
|
this.hpr = null
|
||||||
|
this.currentFrustumOutline = null
|
||||||
|
this.frustum = null
|
||||||
|
this.setInterval = null
|
||||||
|
FRUSTUN.setDefaultValue(this)
|
||||||
|
this.create()
|
||||||
|
}
|
||||||
|
static setDefaultValue(that) {
|
||||||
|
that.options.position = that.options.position || {}
|
||||||
|
that.options.fov = that.options.fov || 20
|
||||||
|
that.options.aspectRatio = that.options.aspectRatio || 1
|
||||||
|
that.options.near = that.options.near || 1
|
||||||
|
that.options.far = that.options.far || 100
|
||||||
|
that.options.heading = that.options.heading || 0
|
||||||
|
that.options.pitch = that.options.pitch || 90
|
||||||
|
that.options.roll = that.options.roll || 0
|
||||||
|
that.options.show = that.options.show || true
|
||||||
|
}
|
||||||
|
// 初始化视锥体
|
||||||
|
create() {
|
||||||
|
this.frustum = new Cesium.PerspectiveFrustum()
|
||||||
|
this.frustum.fov = Cesium.Math.toRadians(this.options.fov)
|
||||||
|
this.frustum.aspectRatio = 1.0 // 保持 aspectRatio 不变
|
||||||
|
this.frustum.near = 1.0
|
||||||
|
this.frustum.far = 50.0
|
||||||
|
// 设置初始视锥体位置和方向
|
||||||
|
let { lng, lat, alt } = this.options.position
|
||||||
|
let { heading, pitch, roll } = this.options
|
||||||
|
this.position = Cesium.Cartesian3.fromDegrees(lng, lat, alt + 100)
|
||||||
|
this.hpr = new Cesium.HeadingPitchRoll(
|
||||||
|
Cesium.Math.toRadians(heading),
|
||||||
|
Cesium.Math.toRadians(pitch),
|
||||||
|
Cesium.Math.toRadians(roll)
|
||||||
|
)
|
||||||
|
console.log(heading)
|
||||||
|
this.drawFrustumOutline()
|
||||||
|
this.monitorKeyboard()
|
||||||
|
}
|
||||||
|
|
||||||
|
setIntervalhpr(num) {
|
||||||
|
if (!this.setInterval1) {
|
||||||
|
this.setInterval1 = setInterval(() => {
|
||||||
|
this.head += num
|
||||||
|
this.updateFrustumHPR(Cesium.Math.toRadians(this.head))
|
||||||
|
}, 10)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 监听 键盘事件
|
||||||
|
// monitorKeyboard() {
|
||||||
|
// let that = this;
|
||||||
|
// document.addEventListener("keydown", function (event) {
|
||||||
|
// switch (event.code) {
|
||||||
|
// case "KeyQ":
|
||||||
|
// that.setIntervalhpr(-0.45);
|
||||||
|
// break;
|
||||||
|
// case "KeyE":
|
||||||
|
// that.setIntervalhpr(0.45);
|
||||||
|
// break;
|
||||||
|
// case "KeyW":
|
||||||
|
// that.updateFrustumPosition("move", -0.00001);
|
||||||
|
// break;
|
||||||
|
// case "KeyS":
|
||||||
|
// that.updateFrustumPosition("move", 0.00001);
|
||||||
|
// break;
|
||||||
|
// case "KeyA":
|
||||||
|
// that.updateFrustumPosition("move", -0.00001, 0);
|
||||||
|
// break;
|
||||||
|
// case "KeyD":
|
||||||
|
// that.updateFrustumPosition("move", 0.00001, 0);
|
||||||
|
// break;
|
||||||
|
// default:
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// document.addEventListener("keyup", function (event) {
|
||||||
|
// clearInterval(that.setInterval1);
|
||||||
|
// that.setInterval1 = null; // 重置 interval
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// 监听键盘事件
|
||||||
|
monitorKeyboard() {
|
||||||
|
const keyActions = {
|
||||||
|
KeyQ: () => this.setIntervalhpr(-0.45),
|
||||||
|
KeyE: () => this.setIntervalhpr(0.45),
|
||||||
|
KeyW: () => this.updateFrustumPosition('move', -0.00001),
|
||||||
|
KeyS: () => this.updateFrustumPosition('move', 0.00001),
|
||||||
|
KeyA: () => this.updateFrustumPosition('move', -0.00001, 0),
|
||||||
|
KeyD: () => this.updateFrustumPosition('move', 0.00001, 0),
|
||||||
|
KeyC: () => this.updateFrustumHeight(1), // 增加高度
|
||||||
|
KeyZ: () => this.updateFrustumHeight(-1) // 降低高度
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener('keydown', event => {
|
||||||
|
if (keyActions[event.code]) keyActions[event.code]()
|
||||||
|
})
|
||||||
|
|
||||||
|
document.addEventListener('keyup', () => this.stopFrustumRotation())
|
||||||
|
}
|
||||||
|
// 停止视锥体旋转
|
||||||
|
stopFrustumRotation() {
|
||||||
|
clearInterval(this.setInterval1)
|
||||||
|
this.setInterval1 = null
|
||||||
|
}
|
||||||
|
// 使用 HeadingPitchRoll 创建视锥体轮廓
|
||||||
|
drawFrustumOutline() {
|
||||||
|
const transform = Cesium.Transforms.headingPitchRollToFixedFrame(
|
||||||
|
this.position,
|
||||||
|
this.hpr
|
||||||
|
)
|
||||||
|
const frustumOutlineGeometry = new Cesium.FrustumOutlineGeometry({
|
||||||
|
frustum: this.frustum,
|
||||||
|
origin: Cesium.Matrix4.getTranslation(transform, new Cesium.Cartesian3()),
|
||||||
|
orientation: Cesium.Quaternion.fromRotationMatrix(
|
||||||
|
Cesium.Matrix4.getRotation(transform, new Cesium.Matrix3())
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
if (this.currentFrustumOutline) {
|
||||||
|
this.viewer.scene.primitives.remove(this.currentFrustumOutline)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.currentFrustumOutline = new Cesium.Primitive({
|
||||||
|
geometryInstances: new Cesium.GeometryInstance({
|
||||||
|
geometry: frustumOutlineGeometry,
|
||||||
|
attributes: {
|
||||||
|
color: Cesium.ColorGeometryInstanceAttribute.fromColor(
|
||||||
|
Cesium.Color.YELLOW
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
appearance: new Cesium.PolylineColorAppearance({
|
||||||
|
translucent: false
|
||||||
|
}),
|
||||||
|
asynchronous: false
|
||||||
|
})
|
||||||
|
|
||||||
|
this.viewer.scene.primitives.add(this.currentFrustumOutline)
|
||||||
|
}
|
||||||
|
// 更新视锥体位置
|
||||||
|
updateFrustumPosition(type = 'move', p, deg = 90) {
|
||||||
|
if (type == 'move') {
|
||||||
|
var point = turf.point([
|
||||||
|
this.options.position.lng,
|
||||||
|
this.options.position.lat
|
||||||
|
])
|
||||||
|
const degreesValue = Cesium.Math.toDegrees(this.hpr.heading)
|
||||||
|
var distance = p
|
||||||
|
var bearing = degreesValue + deg
|
||||||
|
var options = { units: 'degrees' }
|
||||||
|
|
||||||
|
var destination = turf.destination(point, distance, bearing, options)
|
||||||
|
.geometry.coordinates
|
||||||
|
this.position = Cesium.Cartesian3.fromDegrees(
|
||||||
|
destination[0],
|
||||||
|
destination[1],
|
||||||
|
this.options.position.alt + 100
|
||||||
|
)
|
||||||
|
this.options.position.lng = destination[0]
|
||||||
|
this.options.position.lat = destination[1]
|
||||||
|
|
||||||
|
this.viewer.camera.setView({
|
||||||
|
destination: Cesium.Cartesian3.fromDegrees(
|
||||||
|
destination[0],
|
||||||
|
destination[1],
|
||||||
|
this.viewer.camera.positionCartographic.height
|
||||||
|
),
|
||||||
|
orientation: {
|
||||||
|
heading: this.viewer.camera.heading,
|
||||||
|
pitch: this.viewer.camera.pitch,
|
||||||
|
roll: this.viewer.camera.roll
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if (type == 'update') {
|
||||||
|
this.position = p
|
||||||
|
}
|
||||||
|
// this.tongbuHpr();
|
||||||
|
this.drawFrustumOutline()
|
||||||
|
}
|
||||||
|
// 同步视角
|
||||||
|
tongbuHpr() {
|
||||||
|
const { lng, lat, alt } = this.options.position
|
||||||
|
this.viewer1.camera.setView({
|
||||||
|
destination: new Cesium.Cartesian3.fromDegrees(lng, lat, alt + 100),
|
||||||
|
orientation: {
|
||||||
|
heading: this.hpr.heading + Cesium.Math.toRadians(-90.0),
|
||||||
|
pitch: this.hpr.pitch + Cesium.Math.toRadians(-90.0),
|
||||||
|
roll: this.hpr.roll
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
updateFrustumHeight(deltaHeight) {
|
||||||
|
const cartographic = Cesium.Cartographic.fromCartesian(this.position)
|
||||||
|
cartographic.height += deltaHeight // 更新高度
|
||||||
|
this.position = Cesium.Cartesian3.fromDegrees(
|
||||||
|
Cesium.Math.toDegrees(cartographic.longitude),
|
||||||
|
Cesium.Math.toDegrees(cartographic.latitude),
|
||||||
|
cartographic.height
|
||||||
|
)
|
||||||
|
this.options.position.alt = cartographic.height
|
||||||
|
// this.tongbuHpr();
|
||||||
|
this.drawFrustumOutline() // 重新绘制视锥体轮廓
|
||||||
|
}
|
||||||
|
// 更新视锥体的 HeadingPitchRoll
|
||||||
|
updateFrustumHPR(h = 0, p = Cesium.Math.toRadians(90), r = 0) {
|
||||||
|
this.hpr.heading = Cesium.Math.negativePiToPi(h)
|
||||||
|
this.hpr.pitch = Cesium.Math.negativePiToPi(p)
|
||||||
|
this.hpr.roll = Cesium.Math.negativePiToPi(r)
|
||||||
|
// this.tongbuHpr();
|
||||||
|
this.drawFrustumOutline()
|
||||||
|
}
|
||||||
|
// 封装的函数:调整视锥体的 near 和 far 平面
|
||||||
|
updateFrustumNearFar(newNear, newFar) {
|
||||||
|
this.frustum.near = newNear
|
||||||
|
this.frustum.far = newFar
|
||||||
|
this.drawFrustumOutline()
|
||||||
|
}
|
||||||
|
// 封装的函数:调整视锥体的 fov(远裁剪面的大小)
|
||||||
|
updateFrustumFov(newFov) {
|
||||||
|
this.frustum.fov = Cesium.Math.toRadians(newFov)
|
||||||
|
this.drawFrustumOutline()
|
||||||
|
this.viewer.scene.requestRender() // 强制重新渲染场景
|
||||||
|
}
|
||||||
|
// 封装的函数:调整视锥体的高度
|
||||||
|
updateFrustumHeight(deltaHeight) {
|
||||||
|
const cartographic = Cesium.Cartographic.fromCartesian(this.position)
|
||||||
|
cartographic.height += deltaHeight
|
||||||
|
this.position = Cesium.Cartesian3.fromDegrees(
|
||||||
|
Cesium.Math.toDegrees(cartographic.longitude),
|
||||||
|
Cesium.Math.toDegrees(cartographic.latitude),
|
||||||
|
cartographic.height
|
||||||
|
)
|
||||||
|
this.drawFrustumOutline()
|
||||||
|
this.viewer.scene.requestRender() // 强制重新渲染场景
|
||||||
|
}
|
||||||
|
get show() {
|
||||||
|
return this.options.show
|
||||||
|
}
|
||||||
|
set show(bool) {
|
||||||
|
if (typeof bool == 'boolean') {
|
||||||
|
this.currentFrustumOutline.show = bool
|
||||||
|
}
|
||||||
|
}
|
||||||
|
remove() {
|
||||||
|
if (this.currentFrustumOutline) {
|
||||||
|
this.viewer.scene.primitives.remove(this.currentFrustumOutline)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
290
src/Obj/AirLine/index.js
Normal file
290
src/Obj/AirLine/index.js
Normal file
@ -0,0 +1,290 @@
|
|||||||
|
import { closeRotateAround, closeViewFollow} from '../../Global/global'
|
||||||
|
export default class AirLine {
|
||||||
|
constructor(options, earth) {
|
||||||
|
this.earth = earth
|
||||||
|
this.positions = null
|
||||||
|
this.options = { ...options }
|
||||||
|
this.Model = null
|
||||||
|
this.pointCollection = null
|
||||||
|
this.entity = null
|
||||||
|
this.dataSouce = new Cesium.CustomDataSource('airLineSource' + options.id)
|
||||||
|
AirLine.setDefaultValue(this)
|
||||||
|
AirLine.add(this)
|
||||||
|
}
|
||||||
|
static setDefaultValue(that) {
|
||||||
|
that.options.id = that.options.id || Cesium.createGuid()
|
||||||
|
that.options.positions = that.options.positions || []
|
||||||
|
that.options.width = that.options.width || 5
|
||||||
|
that.options.show = that.options.show || true
|
||||||
|
that.options.color = that.options.color || '#00FFFF'
|
||||||
|
that.options.height = that.options.height || 20
|
||||||
|
that.options.url = that.options.url || ''
|
||||||
|
that.options.modelShow = that.options.modelShow || false
|
||||||
|
that.options.flag = that.options.flag || true
|
||||||
|
that.options.speed = that.options.speed || 1
|
||||||
|
that.options.billboard.show = that.options.billboard.show || true
|
||||||
|
that.options.billboard.image = that.options.billboard.image || ''
|
||||||
|
that.options.billboard.scale = that.options.billboard.scale || 1
|
||||||
|
that.options.billboard.width = that.options.billboard.width || 64
|
||||||
|
that.options.billboard.height = that.options.billboard.height || 64
|
||||||
|
that.options.billboard.near = that.options.billboard.near ?? 1000
|
||||||
|
that.options.billboard.far = that.options.billboard.far ?? 10000
|
||||||
|
}
|
||||||
|
static add(that) {
|
||||||
|
if (that.options.positions.length < 3) {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.warn('坐标数量至少需要3个')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
that.pointCollection = that.earth.viewer.scene.primitives.add(
|
||||||
|
new Cesium.PointPrimitiveCollection()
|
||||||
|
)
|
||||||
|
for (let i = 0; i < that.options.positions.length - 1; i++) {
|
||||||
|
let entity = that.createLine([
|
||||||
|
that.options.positions[i],
|
||||||
|
that.options.positions[i + 1]
|
||||||
|
])
|
||||||
|
that.dataSouce.entities.add(entity)
|
||||||
|
}
|
||||||
|
that.earth.viewer.dataSources.add(that.dataSouce).then(r => {})
|
||||||
|
that.createPoint()
|
||||||
|
that.createModel()
|
||||||
|
}
|
||||||
|
// 创建线条
|
||||||
|
createLine(positions) {
|
||||||
|
let entity = new Cesium.Entity({
|
||||||
|
id: Cesium.createGuid(),
|
||||||
|
polyline: {
|
||||||
|
positions: positions,
|
||||||
|
clampToGround: false,
|
||||||
|
width: this.options.width,
|
||||||
|
material: new Cesium.PolylineArrowMaterialProperty(
|
||||||
|
Cesium.Color.fromCssColorString(this.options.color)
|
||||||
|
),
|
||||||
|
zIndex: 99999999
|
||||||
|
},
|
||||||
|
show: true,
|
||||||
|
})
|
||||||
|
return entity
|
||||||
|
}
|
||||||
|
// 生成点
|
||||||
|
createPoint() {
|
||||||
|
this.options.positions.forEach((item, index) => {
|
||||||
|
this.pointCollection.add({
|
||||||
|
show: true,
|
||||||
|
position: item,
|
||||||
|
pixelSize: 10.0,
|
||||||
|
color: Cesium.Color.GREENYELLOW,
|
||||||
|
id: index
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
get show() {
|
||||||
|
return this.entity.show
|
||||||
|
}
|
||||||
|
set show(status) {
|
||||||
|
if (typeof status == 'boolean') this.entity.show = status
|
||||||
|
}
|
||||||
|
get modelShow() {
|
||||||
|
return this.Model.show
|
||||||
|
}
|
||||||
|
set modelShow(status) {
|
||||||
|
if (typeof status == 'boolean') this.Model.show = status
|
||||||
|
}
|
||||||
|
// 添加一个模型
|
||||||
|
createModel() {
|
||||||
|
let scaleByDistance = new Cesium.NearFarScalar(
|
||||||
|
this.options.billboard.near,
|
||||||
|
1,
|
||||||
|
this.options.billboard.far,
|
||||||
|
0
|
||||||
|
)
|
||||||
|
const position = this.options.positions[0]
|
||||||
|
const heading = Cesium.Math.toRadians(0)
|
||||||
|
const pitch = 0
|
||||||
|
const roll = 0
|
||||||
|
const hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll)
|
||||||
|
const orientation = Cesium.Transforms.headingPitchRollQuaternion(
|
||||||
|
position,
|
||||||
|
hpr
|
||||||
|
)
|
||||||
|
this.Model = this.earth.viewer.entities.add({
|
||||||
|
name: this.options.billboard.image,
|
||||||
|
position,
|
||||||
|
// orientation,
|
||||||
|
billboard: {
|
||||||
|
show: this.options.billboard.show,
|
||||||
|
image: this.options.billboard.image,
|
||||||
|
scale: this.options.billboard.scale,
|
||||||
|
horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
|
||||||
|
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||||||
|
width: this.options.billboard.width,
|
||||||
|
height: this.options.billboard.height,
|
||||||
|
disableDepthTestDistance: Number.POSITIVE_INFINITY,
|
||||||
|
scaleByDistance,
|
||||||
|
pixelOffsetScaleByDistance: scaleByDistance
|
||||||
|
},
|
||||||
|
// model: {
|
||||||
|
// uri: this.options.url,
|
||||||
|
// minimumPixelSize: 128,
|
||||||
|
// maximumScale: 20000
|
||||||
|
// },
|
||||||
|
show: this.options.modelShow
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 开始飞行
|
||||||
|
start() {
|
||||||
|
if (!this.options.positions) {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.warn('请先绘制并且生成航线')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let i
|
||||||
|
let that = this
|
||||||
|
this.timer = setInterval(function() {
|
||||||
|
if (this.index) {
|
||||||
|
i = this.index
|
||||||
|
} else {
|
||||||
|
i = 0
|
||||||
|
}
|
||||||
|
i++
|
||||||
|
this.index = i
|
||||||
|
if (i > that.options.positions.length) {
|
||||||
|
clearInterval(this.timer)
|
||||||
|
} else {
|
||||||
|
let position = that.options.positions[i]
|
||||||
|
if (position) {
|
||||||
|
that.Model.position = new Cesium.CallbackProperty(e => {
|
||||||
|
return position
|
||||||
|
})
|
||||||
|
that.Model.orientation = that.direction(
|
||||||
|
that.options.positions[i - 1],
|
||||||
|
that.options.positions[i]
|
||||||
|
).orientation
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 100)
|
||||||
|
}
|
||||||
|
// 停止飞行
|
||||||
|
stop() {
|
||||||
|
if (this.timer) {
|
||||||
|
clearInterval(this.timer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 飞入
|
||||||
|
flyTo() {
|
||||||
|
closeRotateAround(this.earth)
|
||||||
|
closeViewFollow(this.earth)
|
||||||
|
let positionArray = []
|
||||||
|
for (let i = 0; i < this.options.positions.length; i++) {
|
||||||
|
let item = this.options.positions[i]
|
||||||
|
positionArray.push(item.x, item.y, item.z)
|
||||||
|
}
|
||||||
|
// console.log('cartesian',cartesian);
|
||||||
|
// let position = Cesium.Cartographic.fromCartesian(cartesian)
|
||||||
|
// console.log('position',position);
|
||||||
|
let BoundingSphere = Cesium.BoundingSphere.fromVertices(positionArray)
|
||||||
|
this.earth.viewer.camera.flyToBoundingSphere(BoundingSphere, {
|
||||||
|
offset: {
|
||||||
|
heading: Cesium.Math.toRadians(0.0),
|
||||||
|
pitch: Cesium.Math.toRadians(-90.0),
|
||||||
|
roll: Cesium.Math.toRadians(0.0)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 计算一个到另一个点的方向
|
||||||
|
direction(pointA, pointB) {
|
||||||
|
//向量AB
|
||||||
|
const vector2 = Cesium.Cartesian3.subtract(
|
||||||
|
pointB,
|
||||||
|
pointA,
|
||||||
|
new Cesium.Cartesian3()
|
||||||
|
)
|
||||||
|
//归一化
|
||||||
|
const normal = Cesium.Cartesian3.normalize(vector2, new Cesium.Cartesian3())
|
||||||
|
//旋转矩阵 rotationMatrixFromPositionVelocity源码中有,并未出现在cesiumAPI中
|
||||||
|
const rotationMatrix3 = Cesium.Transforms.rotationMatrixFromPositionVelocity(
|
||||||
|
pointA,
|
||||||
|
normal,
|
||||||
|
Cesium.Ellipsoid.WGS84
|
||||||
|
)
|
||||||
|
const modelMatrix4 = Cesium.Matrix4.fromRotationTranslation(
|
||||||
|
rotationMatrix3,
|
||||||
|
pointA
|
||||||
|
)
|
||||||
|
// 获取getHeadingPitchRoll
|
||||||
|
let m1 = Cesium.Transforms.eastNorthUpToFixedFrame(
|
||||||
|
Cesium.Matrix4.getTranslation(modelMatrix4, new Cesium.Cartesian3()),
|
||||||
|
Cesium.Ellipsoid.WGS84,
|
||||||
|
new Cesium.Matrix4()
|
||||||
|
)
|
||||||
|
// 矩阵相除
|
||||||
|
let m3 = Cesium.Matrix4.multiply(
|
||||||
|
Cesium.Matrix4.inverse(m1, new Cesium.Matrix4()),
|
||||||
|
modelMatrix4,
|
||||||
|
new Cesium.Matrix4()
|
||||||
|
)
|
||||||
|
// 得到旋转矩阵
|
||||||
|
let mat3 = Cesium.Matrix4.getMatrix3(m3, new Cesium.Matrix3())
|
||||||
|
// 计算四元数
|
||||||
|
let q = Cesium.Quaternion.fromRotationMatrix(mat3)
|
||||||
|
// 计算旋转角(弧度)
|
||||||
|
let hpr = Cesium.HeadingPitchRoll.fromQuaternion(q)
|
||||||
|
// hpr.pitch = hpr.pitch + 3.14 / 2 + 3.14;
|
||||||
|
hpr.pitch = 0
|
||||||
|
let orientation = Cesium.Transforms.headingPitchRollQuaternion(pointA, hpr)
|
||||||
|
return { hpr, orientation }
|
||||||
|
}
|
||||||
|
// 删除
|
||||||
|
remove() {
|
||||||
|
this.earth.viewer.entities.remove(this.entity)
|
||||||
|
this.dataSouce.entities.removeAll()
|
||||||
|
this.pointCollection && this.pointCollection.destroy()
|
||||||
|
this.Model && this.earth.viewer.entities.remove(this.Model)
|
||||||
|
this.timer && clearInterval(this.timer)
|
||||||
|
this.timer = null
|
||||||
|
}
|
||||||
|
// 返回照片数量 航点数
|
||||||
|
getInfo() {
|
||||||
|
return {
|
||||||
|
length: this.countLength(),
|
||||||
|
time: this.countTime(),
|
||||||
|
waypoint: this.options.positions.length,
|
||||||
|
photos: this.options.positions.length
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//计算航线得长度
|
||||||
|
countLength() {
|
||||||
|
let totalDistance = 0
|
||||||
|
for (let i = 0; i < this.options.positions.length - 1; i++) {
|
||||||
|
const start = this.options.positions[i]
|
||||||
|
const end = this.options.positions[i + 1]
|
||||||
|
const distance = Cesium.Cartesian3.distance(start, end)
|
||||||
|
totalDistance += distance
|
||||||
|
}
|
||||||
|
return totalDistance.toFixed(2) // 返回保留两位小数的距离
|
||||||
|
}
|
||||||
|
//计算航线时间
|
||||||
|
countTime() {
|
||||||
|
let time = Math.floor(Number(this.countLength())) / this.options.speed
|
||||||
|
let s = Math.floor(time % 60)
|
||||||
|
let m = Math.floor(time / 60)
|
||||||
|
let str = m + '分' + s + '秒'
|
||||||
|
return str
|
||||||
|
}
|
||||||
|
//显示隐藏
|
||||||
|
isShow(status) {
|
||||||
|
if (typeof status === 'boolean') {
|
||||||
|
this.modelShow = status
|
||||||
|
this.dataSouce.show = status
|
||||||
|
let len = this.pointCollection.length
|
||||||
|
for (let i = 0; i < len; ++i) {
|
||||||
|
let p = this.pointCollection.get(i)
|
||||||
|
p.show = status
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.error('参数须为Boolean类型!')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
359
src/Obj/AirLine/pointRoute.js
Normal file
359
src/Obj/AirLine/pointRoute.js
Normal file
@ -0,0 +1,359 @@
|
|||||||
|
import FRUSTUN from './frustum.js'
|
||||||
|
import BillordPointLine from './billord_point_line'
|
||||||
|
|
||||||
|
export default class PointRoute {
|
||||||
|
constructor(options = {}, viewer, viewer1) {
|
||||||
|
this.options = { ...options }
|
||||||
|
this.viewer = viewer
|
||||||
|
this.viewer1 = viewer1
|
||||||
|
this.entity = null
|
||||||
|
this.frustum = null
|
||||||
|
this.billordPointLineMaps = []
|
||||||
|
this.index = 0
|
||||||
|
this.positions = []
|
||||||
|
PointRoute.setDefaultValue(this)
|
||||||
|
this.create()
|
||||||
|
}
|
||||||
|
static setDefaultValue(that) {
|
||||||
|
that.options.positions = that.options.positions || []
|
||||||
|
that.options.show = that.options.show || true
|
||||||
|
that.options.color = that.options.color || '#00d590'
|
||||||
|
that.options.height = that.options.height || 500
|
||||||
|
that.options.speed = that.options.speed || 1
|
||||||
|
that.options.frustumShow = that.options.frustumShow ?? true
|
||||||
|
that.options.saveFun = that.options.saveFun || null
|
||||||
|
that.options.selectFun = that.options.selectFun || null
|
||||||
|
that.options.keyboard = that.options.keyboard ?? true
|
||||||
|
that.options.normalHeight = that.options.normalHeight || 100
|
||||||
|
that.options.airHeight = that.options.airHeight || 100
|
||||||
|
}
|
||||||
|
create() {
|
||||||
|
if (this.options.positions.length < 2) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let that = this
|
||||||
|
let { frustumShow } = that.options
|
||||||
|
this.entity = this.viewer.entities.add({
|
||||||
|
show: this.options.show,
|
||||||
|
polyline: {
|
||||||
|
positions: new Cesium.CallbackProperty(() => {
|
||||||
|
let positions = []
|
||||||
|
for (let i = 0; i < this.billordPointLineMaps.length; i++) {
|
||||||
|
const element = this.billordPointLineMaps[i]
|
||||||
|
positions.push(element.billboardEntity.position.getValue())
|
||||||
|
}
|
||||||
|
return positions
|
||||||
|
}, false),
|
||||||
|
width: 3,
|
||||||
|
material: Cesium.Color.fromCssColorString(this.options.color)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// 创建点、线、billbord
|
||||||
|
for (let i = 0; i < this.options.positions.length; i++) {
|
||||||
|
const element = this.options.positions[i]
|
||||||
|
// console.log("elementelementelement", element);
|
||||||
|
if (frustumShow && i == this.index) {
|
||||||
|
this.frustum = new FRUSTUN(
|
||||||
|
{
|
||||||
|
position: element,
|
||||||
|
show: false,
|
||||||
|
arr: this.options.positions,
|
||||||
|
index: i,
|
||||||
|
normalHeight: this.options.normalHeight
|
||||||
|
},
|
||||||
|
this.viewer,
|
||||||
|
this.viewer1
|
||||||
|
)
|
||||||
|
}
|
||||||
|
let op = new BillordPointLine(
|
||||||
|
{
|
||||||
|
positions: element,
|
||||||
|
index: i + 1,
|
||||||
|
saveFun: that.options.saveFun,
|
||||||
|
selectFun: that.options.selectFun,
|
||||||
|
keyboard: that.options.keyboard,
|
||||||
|
updateFrustumFun: that.updateFrustumPosition,
|
||||||
|
normalHeight: that.options.normalHeight,
|
||||||
|
frustum: that.frustum,
|
||||||
|
airHeight: that.options.airHeight
|
||||||
|
},
|
||||||
|
this.viewer
|
||||||
|
)
|
||||||
|
this.billordPointLineMaps.push(op)
|
||||||
|
}
|
||||||
|
this.onKey()
|
||||||
|
}
|
||||||
|
get show() {
|
||||||
|
return this.options.show
|
||||||
|
}
|
||||||
|
set show(bool) {
|
||||||
|
if (typeof bool === 'boolean') {
|
||||||
|
this.frustum.currentFrustumOutline.show = bool
|
||||||
|
this.billordPointLineMaps.forEach(item => {
|
||||||
|
item.show = bool
|
||||||
|
})
|
||||||
|
this.entity.show = bool
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 监听键盘事件
|
||||||
|
onKey() {
|
||||||
|
let that = this
|
||||||
|
document.addEventListener('keydown', function(event) {
|
||||||
|
switch (event.key) {
|
||||||
|
case 'ArrowUp':
|
||||||
|
that.index += 1
|
||||||
|
that.updateFrustum(true)
|
||||||
|
break
|
||||||
|
case 'ArrowDown':
|
||||||
|
that.index -= 1
|
||||||
|
that.updateFrustum(false)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 更新frustum
|
||||||
|
updateFrustum(flag) {
|
||||||
|
console.log(this.index)
|
||||||
|
let obj
|
||||||
|
if (this.index > this.options.positions.length - 1 || this.index < 0) {
|
||||||
|
let str = this.index > 0 ? '已选中最后一个航点' : '已选中第一个航点'
|
||||||
|
alert(str)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for (let i = 0; i < this.billordPointLineMaps.length; i++) {
|
||||||
|
const element = this.billordPointLineMaps[i]
|
||||||
|
const hpr = null
|
||||||
|
if (i == this.index) {
|
||||||
|
let position = element.billboardEntity.position.getValue()
|
||||||
|
if (this.index !== 0) {
|
||||||
|
obj = this.direction(
|
||||||
|
this.billordPointLineMaps[
|
||||||
|
i - 1
|
||||||
|
].billboardEntity.position.getValue(),
|
||||||
|
element.billboardEntity.position.getValue()
|
||||||
|
)
|
||||||
|
hpr = obj.hpr
|
||||||
|
}
|
||||||
|
if (this.index == 0) {
|
||||||
|
obj = this.direction(
|
||||||
|
this.billordPointLineMaps[0].billboardEntity.position.getValue(),
|
||||||
|
this.billordPointLineMaps[1].billboardEntity.position.getValue()
|
||||||
|
)
|
||||||
|
hpr = obj.hpr
|
||||||
|
}
|
||||||
|
if (hpr) {
|
||||||
|
this.frustum.updateFrustumHPR(
|
||||||
|
hpr.heading,
|
||||||
|
this.frustum.pitch,
|
||||||
|
hpr.roll
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if (position) {
|
||||||
|
this.frustum.updateFrustumPosition('update', position)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cartesian3Towgs84(cartesian) {
|
||||||
|
var ellipsoid = this.viewer.scene.globe.ellipsoid
|
||||||
|
var cartesian3 = new Cesium.Cartesian3(
|
||||||
|
cartesian.x,
|
||||||
|
cartesian.y,
|
||||||
|
cartesian.z
|
||||||
|
)
|
||||||
|
var cartographic = ellipsoid.cartesianToCartographic(cartesian3)
|
||||||
|
var lat = Cesium.Math.toDegrees(cartographic.latitude)
|
||||||
|
var lng = Cesium.Math.toDegrees(cartographic.longitude)
|
||||||
|
var alt = cartographic.height < 0 ? 0 : cartographic.height
|
||||||
|
return {
|
||||||
|
lng: lng,
|
||||||
|
lat: lat,
|
||||||
|
alt: alt
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 计算一个到另一个点的方向
|
||||||
|
direction(pointA, pointB) {
|
||||||
|
//向量AB
|
||||||
|
const vector2 = Cesium.Cartesian3.subtract(
|
||||||
|
pointA,
|
||||||
|
pointB,
|
||||||
|
new Cesium.Cartesian3()
|
||||||
|
)
|
||||||
|
//归一化
|
||||||
|
const normal = Cesium.Cartesian3.normalize(vector2, new Cesium.Cartesian3())
|
||||||
|
//旋转矩阵 rotationMatrixFromPositionVelocity源码中有,并未出现在cesiumAPI中
|
||||||
|
const rotationMatrix3 = Cesium.Transforms.rotationMatrixFromPositionVelocity(
|
||||||
|
pointA,
|
||||||
|
normal,
|
||||||
|
Cesium.Ellipsoid.WGS84
|
||||||
|
)
|
||||||
|
const modelMatrix4 = Cesium.Matrix4.fromRotationTranslation(
|
||||||
|
rotationMatrix3,
|
||||||
|
pointA
|
||||||
|
)
|
||||||
|
// 获取getHeadingPitchRoll
|
||||||
|
let m1 = Cesium.Transforms.eastNorthUpToFixedFrame(
|
||||||
|
Cesium.Matrix4.getTranslation(modelMatrix4, new Cesium.Cartesian3()),
|
||||||
|
Cesium.Ellipsoid.WGS84,
|
||||||
|
new Cesium.Matrix4()
|
||||||
|
)
|
||||||
|
// 矩阵相除
|
||||||
|
let m3 = Cesium.Matrix4.multiply(
|
||||||
|
Cesium.Matrix4.inverse(m1, new Cesium.Matrix4()),
|
||||||
|
modelMatrix4,
|
||||||
|
new Cesium.Matrix4()
|
||||||
|
)
|
||||||
|
// 得到旋转矩阵
|
||||||
|
let mat3 = Cesium.Matrix4.getMatrix3(m3, new Cesium.Matrix3())
|
||||||
|
// 计算四元数
|
||||||
|
let q = Cesium.Quaternion.fromRotationMatrix(mat3)
|
||||||
|
// 计算旋转角(弧度)
|
||||||
|
let hpr = Cesium.HeadingPitchRoll.fromQuaternion(q)
|
||||||
|
// hpr.pitch = hpr.pitch + 3.14 / 2 + 3.14;
|
||||||
|
hpr.pitch = 90
|
||||||
|
let orientation = Cesium.Transforms.headingPitchRollQuaternion(pointA, hpr)
|
||||||
|
return { hpr, orientation }
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {index} 索引
|
||||||
|
*/
|
||||||
|
// 删除航点
|
||||||
|
delPosition(index) {
|
||||||
|
this.options.positions.splice(index, 1)
|
||||||
|
// this.options.positions = this.options.positions.filter((item, index) => index !== i);
|
||||||
|
this.remove()
|
||||||
|
this.create()
|
||||||
|
}
|
||||||
|
// 获取最新的positions
|
||||||
|
getNewPositions() {
|
||||||
|
let positions = []
|
||||||
|
for (let i = 0; i < this.billordPointLineMaps.length; i++) {
|
||||||
|
const element = this.billordPointLineMaps[i]
|
||||||
|
let position = this.cartesian3Towgs84(
|
||||||
|
element.billboardEntity.position.getValue()
|
||||||
|
)
|
||||||
|
positions.push(position)
|
||||||
|
}
|
||||||
|
return positions
|
||||||
|
}
|
||||||
|
// 删除
|
||||||
|
remove() {
|
||||||
|
this.billordPointLineMaps.forEach((item, i) => {
|
||||||
|
item.remove()
|
||||||
|
})
|
||||||
|
if (this.frustum) {
|
||||||
|
this.frustum.remove()
|
||||||
|
}
|
||||||
|
this.viewer.entities.remove(this.entity)
|
||||||
|
this.billordPointLineMaps = []
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {String} type
|
||||||
|
* @param {Number} index
|
||||||
|
* @param {Array} position
|
||||||
|
*/
|
||||||
|
// 新增航点 (before,after,end)
|
||||||
|
addPoint(positions) {
|
||||||
|
this.options.positions = positions
|
||||||
|
this.remove()
|
||||||
|
this.create()
|
||||||
|
}
|
||||||
|
// 根据选中的点更新视锥的位置
|
||||||
|
updateFrustumPosition(index) {
|
||||||
|
if (!this.billordPointLineMaps || this.billordPointLineMaps.length === 0)
|
||||||
|
return
|
||||||
|
if (this.frustum) {
|
||||||
|
this.frustum.show = true
|
||||||
|
}
|
||||||
|
let current = this.billordPointLineMaps[
|
||||||
|
index
|
||||||
|
].billboardEntity.position.getValue()
|
||||||
|
if (index !== 0) {
|
||||||
|
let obj
|
||||||
|
let after =
|
||||||
|
index === this.billordPointLineMaps.length - 1
|
||||||
|
? this.billordPointLineMaps[
|
||||||
|
index - 1
|
||||||
|
].billboardEntity.position.getValue() // 获取前一个位置
|
||||||
|
: this.billordPointLineMaps[
|
||||||
|
index + 1
|
||||||
|
].billboardEntity.position.getValue() // 获取下一个位置
|
||||||
|
obj = this.direction(
|
||||||
|
index === this.billordPointLineMaps.length - 1 ? after : current,
|
||||||
|
index === this.billordPointLineMaps.length - 1 ? current : after
|
||||||
|
)
|
||||||
|
let { hpr } = obj
|
||||||
|
this.frustum.updateFrustumHPR(
|
||||||
|
hpr.heading,
|
||||||
|
Cesium.Math.toRadians(this.frustum.pitch),
|
||||||
|
hpr.roll
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
let obj
|
||||||
|
let after = this.billordPointLineMaps[1].billboardEntity.position.getValue()
|
||||||
|
obj = this.direction(current, after)
|
||||||
|
let { hpr } = obj
|
||||||
|
this.frustum.updateFrustumHPR(
|
||||||
|
hpr.heading,
|
||||||
|
Cesium.Math.toRadians(this.frustum.pitch),
|
||||||
|
hpr.roll
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if (current) {
|
||||||
|
this.frustum.updateFrustumPosition('update', current)
|
||||||
|
}
|
||||||
|
let position = this.cartesian3Towgs84(current)
|
||||||
|
this.billordPointLineMaps.forEach(item => {
|
||||||
|
item.billboardEntity.label.show = false // 先将所有元素的 label.show 设置为 false
|
||||||
|
})
|
||||||
|
const targetItem = this.billordPointLineMaps.find(
|
||||||
|
item => item.billboardEntity.index == index + 1
|
||||||
|
)
|
||||||
|
if (targetItem) {
|
||||||
|
targetItem.billboardEntity.label.show = true // 然后找到匹配的 index 设置为 true
|
||||||
|
}
|
||||||
|
return position
|
||||||
|
}
|
||||||
|
flyTo() {
|
||||||
|
let positionArray = []
|
||||||
|
for (let i = 0; i < this.options.positions.length; i++) {
|
||||||
|
let a = Cesium.Cartesian3.fromDegrees(
|
||||||
|
this.options.positions[i].lng,
|
||||||
|
this.options.positions[i].lat,
|
||||||
|
this.options.positions[i].alt + this.options.height
|
||||||
|
)
|
||||||
|
positionArray.push(a.x, a.y, a.z)
|
||||||
|
}
|
||||||
|
let BoundingSphere = Cesium.BoundingSphere.fromVertices(positionArray)
|
||||||
|
this.viewer.camera.flyToBoundingSphere(BoundingSphere, {
|
||||||
|
offset: {
|
||||||
|
heading: Cesium.Math.toRadians(0.0),
|
||||||
|
pitch: Cesium.Math.toRadians(-80.0),
|
||||||
|
roll: Cesium.Math.toRadians(0.0)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
//计算航线的长度
|
||||||
|
countLength() {
|
||||||
|
if (this.options.positions.length < 2) {
|
||||||
|
return 0
|
||||||
|
} else {
|
||||||
|
let lineString = []
|
||||||
|
this.options.positions.forEach(item => {
|
||||||
|
lineString.push([item.lng, item.lat])
|
||||||
|
})
|
||||||
|
var line = turf.lineString(lineString)
|
||||||
|
return (turf.length(line) * 1000).toFixed(2)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//计算航线时间
|
||||||
|
countTime() {
|
||||||
|
let time = Math.floor(Number(this.countLength())) / this.options.speed
|
||||||
|
let s = Math.floor(time % 60)
|
||||||
|
let m = Math.floor(time / 60)
|
||||||
|
let str = m + '分' + s + '秒'
|
||||||
|
return str
|
||||||
|
}
|
||||||
|
}
|
||||||
25
src/Obj/Analysis/CircleViewShed/_element.js
Normal file
25
src/Obj/Analysis/CircleViewShed/_element.js
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
function html() {
|
||||||
|
return `
|
||||||
|
<span class="custom-divider"></span>
|
||||||
|
<div class="div-item">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<span class="label">视点高度</span>
|
||||||
|
<div class="input-number input-number-unit-1">
|
||||||
|
<input class="input" type="number" title="" min="0" max="999999" step="0.1" @model="viewPointHeight">
|
||||||
|
<span class="unit">m</span>
|
||||||
|
<span class="arrow"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<span class="label">采样精度</span>
|
||||||
|
<input class="input" type="number" title="" min="1" max="100" step="1" @model="precision">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
|
export { html }
|
||||||
512
src/Obj/Analysis/CircleViewShed/_index.js
Normal file
512
src/Obj/Analysis/CircleViewShed/_index.js
Normal file
@ -0,0 +1,512 @@
|
|||||||
|
/*
|
||||||
|
* @Author: Wang jianLei
|
||||||
|
* @Date: 2022-05-17 21:49:28
|
||||||
|
* @Last Modified by: Wang JianLei
|
||||||
|
* @Last Modified time: 2022-05-19 22:08:14
|
||||||
|
*/
|
||||||
|
|
||||||
|
let ViewShed = function (sdk, canvasEleId) {
|
||||||
|
if (!sdk.viewer) throw new Error("no viewer object!");
|
||||||
|
alert(canvasEleId)
|
||||||
|
let canvasEle = document.getElementById(canvasEleId);
|
||||||
|
if (!canvasEle) throw new Error("the canvas element is not exist");
|
||||||
|
this.canvasEle = canvasEle;
|
||||||
|
this.viewer = sdk.viewer;
|
||||||
|
this.handler = undefined;
|
||||||
|
this.lightCamera;
|
||||||
|
this.pyramid;
|
||||||
|
this.frustumPrimitive;
|
||||||
|
this.viewershedPolygon;
|
||||||
|
};
|
||||||
|
ViewShed.prototype = {
|
||||||
|
/**
|
||||||
|
* 初始化handler
|
||||||
|
*/
|
||||||
|
initHandler() {
|
||||||
|
if (this.handler) {
|
||||||
|
this.handler.destroy();
|
||||||
|
this.handler = undefined;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 开始执行视域分析
|
||||||
|
* @param {number} precision 精度,值越大创建耗时越长,建议在10~20之间
|
||||||
|
*/
|
||||||
|
createViewshed: function (precision) {
|
||||||
|
let $this = this;
|
||||||
|
let scene = $this.viewer.scene;
|
||||||
|
$this.initHandler();
|
||||||
|
$this.clearAll();
|
||||||
|
$this.handler = new Cesium.ScreenSpaceEventHandler($this.viewer.canvas);
|
||||||
|
$this.handler.setInputAction((event) => {
|
||||||
|
// 禁止地球旋转和缩放,地球的旋转会对鼠标移动监听有影响,所以需要禁止
|
||||||
|
scene.screenSpaceCameraController.enableRotate = false;
|
||||||
|
scene.screenSpaceCameraController.enableZoom = false;
|
||||||
|
scene.globe.depthTestAgainstTerrain = true;
|
||||||
|
let earthPosition = scene.pickPosition(event.position);
|
||||||
|
let pos = $this.cartesian3ToDegree(earthPosition);
|
||||||
|
$this.handler.setInputAction(function (event) {
|
||||||
|
let newPosition = scene.pickPosition(event.endPosition);
|
||||||
|
if (Cesium.defined(newPosition)) {
|
||||||
|
let pos1 = $this.cartesian3ToDegree(newPosition);
|
||||||
|
let distance = Cesium.Cartesian3.distance(newPosition, earthPosition);
|
||||||
|
let angle = $this.getAngle(pos[0], pos[1], pos1[0], pos1[1]);
|
||||||
|
let pitch = $this.getPitch(earthPosition, newPosition);
|
||||||
|
$this.ViewShedOptions = {
|
||||||
|
viewPosition: earthPosition, //观测点 笛卡尔坐标
|
||||||
|
endPosition: newPosition, //目标点 笛卡尔坐标
|
||||||
|
direction: angle, //观测方位角 默认为`0`,范围`0~360`
|
||||||
|
pitch: pitch, //俯仰角,radius,默认为`0`
|
||||||
|
horizontalViewAngle: 90, //可视域水平夹角,默认为 `90`,范围`0~360`
|
||||||
|
verticalViewAngle: 60, //可视域垂直夹角,默认为`60`,范围`0~180`
|
||||||
|
visibleAreaColor: Cesium.Color.GREEN, //可视区域颜色,默认为`green`
|
||||||
|
invisibleAreaColor: Cesium.Color.RED, //不可见区域颜色,默认为`red`
|
||||||
|
visualRange: distance, //距离,单位`米`
|
||||||
|
};
|
||||||
|
$this.updateViewShed();
|
||||||
|
}
|
||||||
|
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
|
||||||
|
}, Cesium.ScreenSpaceEventType.LEFT_DOWN);
|
||||||
|
|
||||||
|
$this.handler.setInputAction(() => {
|
||||||
|
$this.initHandler();
|
||||||
|
// 开启地球旋转和缩放
|
||||||
|
scene.screenSpaceCameraController.enableRotate = true;
|
||||||
|
scene.screenSpaceCameraController.enableZoom = true;
|
||||||
|
$this.drawViewershed(precision);
|
||||||
|
}, Cesium.ScreenSpaceEventType.LEFT_UP);
|
||||||
|
},
|
||||||
|
|
||||||
|
ReturnDistance(pos0, pos1) {
|
||||||
|
let distance = 0;
|
||||||
|
let point1cartographic = Cesium.Cartographic.fromCartesian(pos0);
|
||||||
|
let point2cartographic = Cesium.Cartographic.fromCartesian(pos1);
|
||||||
|
/**根据经纬度计算出距离**/
|
||||||
|
let geodesic = new Cesium.EllipsoidGeodesic();
|
||||||
|
geodesic.setEndPoints(point1cartographic, point2cartographic);
|
||||||
|
let s = geodesic.surfaceDistance;
|
||||||
|
return s;
|
||||||
|
},
|
||||||
|
getHeight(x, y, objectsToExclude) {
|
||||||
|
let endCartographic = Cesium.Cartographic.fromDegrees(x, y);
|
||||||
|
let endHeight = this.viewer.scene.sampleHeight(
|
||||||
|
endCartographic,
|
||||||
|
objectsToExclude
|
||||||
|
);
|
||||||
|
return endHeight;
|
||||||
|
},
|
||||||
|
|
||||||
|
cartesian3ToDegree: function (Cartesian3) {
|
||||||
|
let _ellipsoid = this.viewer.scene.globe.ellipsoid;
|
||||||
|
let _cartographic = _ellipsoid.cartesianToCartographic(Cartesian3);
|
||||||
|
let _lat = Cesium.Math.toDegrees(_cartographic.latitude);
|
||||||
|
let _lng = Cesium.Math.toDegrees(_cartographic.longitude);
|
||||||
|
let _alt = _cartographic.height;
|
||||||
|
return [_lng, _lat, _alt];
|
||||||
|
},
|
||||||
|
getAngle: function (lng1, lat1, lng2, lat2) {
|
||||||
|
let dRotateAngle = Math.atan2(Math.abs(lng1 - lng2), Math.abs(lat1 - lat2));
|
||||||
|
if (lng2 >= lng1) {
|
||||||
|
dRotateAngle = lat2 < lat1 ? Math.PI - dRotateAngle : dRotateAngle;
|
||||||
|
} else {
|
||||||
|
dRotateAngle =
|
||||||
|
lat2 >= lat1 ? 2 * Math.PI - dRotateAngle : Math.PI + dRotateAngle;
|
||||||
|
}
|
||||||
|
dRotateAngle = (dRotateAngle * 180) / Math.PI;
|
||||||
|
return dRotateAngle;
|
||||||
|
},
|
||||||
|
|
||||||
|
getPitch(pointA, pointB) {
|
||||||
|
let transfrom = Cesium.Transforms.eastNorthUpToFixedFrame(pointA);
|
||||||
|
const vector = Cesium.Cartesian3.subtract(
|
||||||
|
pointB,
|
||||||
|
pointA,
|
||||||
|
new Cesium.Cartesian3()
|
||||||
|
);
|
||||||
|
let direction = Cesium.Matrix4.multiplyByPointAsVector(
|
||||||
|
Cesium.Matrix4.inverse(transfrom, transfrom),
|
||||||
|
vector,
|
||||||
|
vector
|
||||||
|
);
|
||||||
|
Cesium.Cartesian3.normalize(direction, direction);
|
||||||
|
return Cesium.Math.PI_OVER_TWO - Cesium.Math.acosClamped(direction.z);
|
||||||
|
},
|
||||||
|
|
||||||
|
updateViewShed: function () {
|
||||||
|
this.clear();
|
||||||
|
this.setLightCamera();
|
||||||
|
this.addVisualPyramid();
|
||||||
|
this.createFrustum();
|
||||||
|
},
|
||||||
|
clear: function () {
|
||||||
|
if (this.pyramid) {
|
||||||
|
this.viewer.entities.removeById(this.pyramid.id);
|
||||||
|
this.pyramid = undefined;
|
||||||
|
}
|
||||||
|
if (this.frustumPrimitive) {
|
||||||
|
this.viewer.scene.primitives.remove(this.frustumPrimitive);
|
||||||
|
this.frustumPrimitive = undefined;
|
||||||
|
}
|
||||||
|
if (this.debugModelMatrixPrimitive) {
|
||||||
|
this.viewer.scene.primitives.remove(this.debugModelMatrixPrimitive);
|
||||||
|
this.debugModelMatrixPrimitive = undefined;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
clearAll: function () {
|
||||||
|
this.clear();
|
||||||
|
if (this.viewershedPolygon) {
|
||||||
|
this.viewer.scene.primitives.remove(this.viewershedPolygon);
|
||||||
|
this.viewershedPolygon = undefined;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
addVisualPyramid: function () {
|
||||||
|
let options = this.ViewShedOptions;
|
||||||
|
let position = options.viewPosition;
|
||||||
|
let visualRange = Number(options.visualRange);
|
||||||
|
let transform = Cesium.Transforms.eastNorthUpToFixedFrame(position);
|
||||||
|
this.debugModelMatrixPrimitive = this.viewer.scene.primitives.add(
|
||||||
|
new Cesium.DebugModelMatrixPrimitive({
|
||||||
|
modelMatrix: transform,
|
||||||
|
length: 5.0,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
const halfClock = options.horizontalViewAngle / 2;
|
||||||
|
const halfCone = options.verticalViewAngle / 2;
|
||||||
|
const pitch = Cesium.Math.toDegrees(options.pitch);
|
||||||
|
const ellipsoid = new Cesium.EllipsoidGraphics({
|
||||||
|
radii: new Cesium.Cartesian3(visualRange, visualRange, visualRange),
|
||||||
|
minimumClock: Cesium.Math.toRadians(90 - options.direction - halfClock),
|
||||||
|
maximumClock: Cesium.Math.toRadians(90 - options.direction + halfClock),
|
||||||
|
minimumCone: Cesium.Math.toRadians(90 - pitch - halfCone),
|
||||||
|
maximumCone: Cesium.Math.toRadians(90 - pitch + halfCone),
|
||||||
|
fill: false,
|
||||||
|
outline: true,
|
||||||
|
subdivisions: 256,
|
||||||
|
stackPartitions: 64,
|
||||||
|
slicePartitions: 64,
|
||||||
|
outlineColor: Cesium.Color.YELLOWGREEN.withAlpha(0.5),
|
||||||
|
});
|
||||||
|
const pyramidEntity = new Cesium.Entity({
|
||||||
|
position: position,
|
||||||
|
ellipsoid,
|
||||||
|
});
|
||||||
|
this.pyramid = this.viewer.entities.add(pyramidEntity);
|
||||||
|
},
|
||||||
|
setLightCamera: function () {
|
||||||
|
if (!this.lightCamera) {
|
||||||
|
this.lightCamera = new Cesium.Camera(this.viewer.scene);
|
||||||
|
}
|
||||||
|
let options = this.ViewShedOptions;
|
||||||
|
let visualRange = Number(options.visualRange);
|
||||||
|
this.lightCamera.position = options.viewPosition;
|
||||||
|
this.lightCamera.frustum.near = 0.1;
|
||||||
|
this.lightCamera.frustum.far = visualRange;
|
||||||
|
const hr = Cesium.Math.toRadians(options.horizontalViewAngle);
|
||||||
|
const vr = Cesium.Math.toRadians(options.verticalViewAngle);
|
||||||
|
this.lightCamera.frustum.aspectRatio =
|
||||||
|
(visualRange * Math.tan(hr / 2) * 2) /
|
||||||
|
(visualRange * Math.tan(vr / 2) * 2);
|
||||||
|
this.lightCamera.frustum.fov = hr > vr ? hr : vr;
|
||||||
|
this.lightCamera.setView({
|
||||||
|
destination: options.viewPosition,
|
||||||
|
orientation: {
|
||||||
|
heading: Cesium.Math.toRadians(options.direction || 0),
|
||||||
|
pitch: options.pitch || 0,
|
||||||
|
roll: 0,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
createFrustum: function () {
|
||||||
|
const scratchRight = new Cesium.Cartesian3();
|
||||||
|
const scratchRotation = new Cesium.Matrix3();
|
||||||
|
const scratchOrientation = new Cesium.Quaternion();
|
||||||
|
const direction = this.lightCamera.directionWC;
|
||||||
|
const up = this.lightCamera.upWC;
|
||||||
|
let right = this.lightCamera.rightWC;
|
||||||
|
right = Cesium.Cartesian3.negate(right, scratchRight);
|
||||||
|
let rotation = scratchRotation;
|
||||||
|
Cesium.Matrix3.setColumn(rotation, 0, right, rotation);
|
||||||
|
Cesium.Matrix3.setColumn(rotation, 1, up, rotation);
|
||||||
|
Cesium.Matrix3.setColumn(rotation, 2, direction, rotation);
|
||||||
|
let orientation = Cesium.Quaternion.fromRotationMatrix(
|
||||||
|
rotation,
|
||||||
|
scratchOrientation
|
||||||
|
);
|
||||||
|
let instanceOutline = new Cesium.GeometryInstance({
|
||||||
|
geometry: new Cesium.FrustumOutlineGeometry({
|
||||||
|
frustum: this.lightCamera.frustum,
|
||||||
|
origin: this.ViewShedOptions.viewPosition,
|
||||||
|
orientation: orientation,
|
||||||
|
}),
|
||||||
|
id: "视椎体轮廓线" + Math.random().toString(36).substr(2),
|
||||||
|
attributes: {
|
||||||
|
color: Cesium.ColorGeometryInstanceAttribute.fromColor(
|
||||||
|
new Cesium.Color(0.0, 1.0, 0.0, 1.0)
|
||||||
|
),
|
||||||
|
show: new Cesium.ShowGeometryInstanceAttribute(true),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
this.frustumPrimitive = this.viewer.scene.primitives.add(
|
||||||
|
new Cesium.Primitive({
|
||||||
|
geometryInstances: instanceOutline,
|
||||||
|
appearance: new Cesium.PerInstanceColorAppearance({
|
||||||
|
flat: true,
|
||||||
|
translucent: false,
|
||||||
|
closed: true,
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
);
|
||||||
|
},
|
||||||
|
createPoint: function (firstPos, secondPos) {
|
||||||
|
let entity4FirstPos = new Cesium.Entity({
|
||||||
|
name: "firstPos",
|
||||||
|
show: true,
|
||||||
|
position: firstPos,
|
||||||
|
point: {
|
||||||
|
show: true,
|
||||||
|
pixelSize: 20,
|
||||||
|
color: Cesium.Color.RED,
|
||||||
|
outlineColor: Cesium.Color.YELLOW,
|
||||||
|
outlineWidth: 5,
|
||||||
|
},
|
||||||
|
description: `
|
||||||
|
<p>这是绘制的视椎体起点</p>`,
|
||||||
|
});
|
||||||
|
this.viewer.entities.add(entity4FirstPos);
|
||||||
|
let entity4SecondPos = new Cesium.Entity({
|
||||||
|
name: "secondPos",
|
||||||
|
show: true,
|
||||||
|
position: secondPos,
|
||||||
|
point: {
|
||||||
|
show: true,
|
||||||
|
pixelSize: 30,
|
||||||
|
color: Cesium.Color.YELLOW,
|
||||||
|
outlineColor: Cesium.Color.RED,
|
||||||
|
outlineWidth: 8,
|
||||||
|
},
|
||||||
|
description: `
|
||||||
|
<p>这是绘制的视椎体视角终点</p>`,
|
||||||
|
});
|
||||||
|
this.viewer.entities.add(entity4SecondPos);
|
||||||
|
},
|
||||||
|
|
||||||
|
//绘制可视域
|
||||||
|
add(positionArr) {
|
||||||
|
let polygon = new Cesium.PolygonGeometry({
|
||||||
|
polygonHierarchy: new Cesium.PolygonHierarchy(
|
||||||
|
Cesium.Cartesian3.fromDegreesArray(positionArr)
|
||||||
|
),
|
||||||
|
height: 0.0,
|
||||||
|
extrudedHeight: 0.0,
|
||||||
|
vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT,
|
||||||
|
stRotation: 0.0, // 纹理的旋转坐标(以弧度为单位),正旋转是逆时针方向
|
||||||
|
ellipsoid: Cesium.Ellipsoid.WGS84,
|
||||||
|
granularity: Cesium.Math.RADIANS_PER_DEGREE, // 每个纬度和经度之间的距离(以弧度为单位),确定缓冲区中的位置数
|
||||||
|
perPositionHeight: false, // 每个位置点使用的高度
|
||||||
|
closeTop: true,
|
||||||
|
closeBottom: true,
|
||||||
|
// NONE 与椭圆表面不符的直线;GEODESIC 遵循测地路径;RHUMB 遵循大黄蜂或恶魔般的道路。
|
||||||
|
arcType: Cesium.ArcType.GEODESIC, // 多边形边缘线型
|
||||||
|
});
|
||||||
|
|
||||||
|
let polygonInstance = new Cesium.GeometryInstance({
|
||||||
|
geometry: polygon,
|
||||||
|
name: "ViewershedPolygon",
|
||||||
|
attributes: {
|
||||||
|
color: Cesium.ColorGeometryInstanceAttribute.fromColor(
|
||||||
|
Cesium.Color.BLUE.withAlpha(0.6)
|
||||||
|
),
|
||||||
|
show: new Cesium.ShowGeometryInstanceAttribute(true), //显示或者隐藏
|
||||||
|
},
|
||||||
|
});
|
||||||
|
this.viewershedPolygon = this.viewer.scene.primitives.add(
|
||||||
|
new Cesium.GroundPrimitive({
|
||||||
|
geometryInstances: polygonInstance,
|
||||||
|
appearance: new Cesium.EllipsoidSurfaceAppearance({
|
||||||
|
aboveGround: true,
|
||||||
|
material: new Cesium.Material({
|
||||||
|
fabric: {
|
||||||
|
type: "Image",
|
||||||
|
uniforms: {
|
||||||
|
image: this.returnImgae(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
);
|
||||||
|
},
|
||||||
|
drawViewershed(precision) {
|
||||||
|
const pos = this.cartesian3ToDegree(this.ViewShedOptions.viewPosition);
|
||||||
|
const radius = this.ViewShedOptions.visualRange;
|
||||||
|
const direction = this.ViewShedOptions.direction;
|
||||||
|
let boundary = this.computeBoundaryOptions(pos, radius, direction);
|
||||||
|
const bbox = boundary.bbox;
|
||||||
|
let mask = turf.polygon([boundary.boundaryPoints]);
|
||||||
|
const dis = this.ViewShedOptions.visualRange / (precision * 1000);
|
||||||
|
let gridPoints = turf.pointGrid(bbox, dis, { mask: mask });
|
||||||
|
|
||||||
|
let pointsResult = this.createTargetPoints(gridPoints, dis, pos);
|
||||||
|
let variogram = kriging.train(
|
||||||
|
pointsResult.values,
|
||||||
|
pointsResult.lngs,
|
||||||
|
pointsResult.lats,
|
||||||
|
"exponential",
|
||||||
|
0,
|
||||||
|
100
|
||||||
|
);
|
||||||
|
let grid = kriging.grid([boundary.boundaryPoints], variogram, dis / 1000);
|
||||||
|
const colors = [
|
||||||
|
"#ff000080",
|
||||||
|
"#ff000080",
|
||||||
|
"#ff000080",
|
||||||
|
"#ff000080",
|
||||||
|
"#ff000080",
|
||||||
|
"#ff000080",
|
||||||
|
"#00ff0080",
|
||||||
|
"#00ff0080",
|
||||||
|
"#00ff0080",
|
||||||
|
"#00ff0080",
|
||||||
|
"#00ff0080",
|
||||||
|
"#00ff0080",
|
||||||
|
];
|
||||||
|
|
||||||
|
this.canvasEle.width = 3840;
|
||||||
|
this.canvasEle.height = 2160;
|
||||||
|
kriging.plot(
|
||||||
|
this.canvasEle,
|
||||||
|
grid,
|
||||||
|
[bbox[0], bbox[2]],
|
||||||
|
[bbox[1], bbox[3]],
|
||||||
|
colors
|
||||||
|
);
|
||||||
|
this.add(boundary.positionArr);
|
||||||
|
},
|
||||||
|
computeBoundaryOptions(pos, radius, angle) {
|
||||||
|
let Ea = 6378137; // 赤道半径
|
||||||
|
let Eb = 6356725; // 极半径
|
||||||
|
const lng = pos[0],
|
||||||
|
lat = pos[1];
|
||||||
|
const bbox = [lng, lat, lng, lat]; //[minX, minY, maxX, maxY]
|
||||||
|
let positionArr = [];
|
||||||
|
let boundaryPoints = [];
|
||||||
|
positionArr.push(lng, lat);
|
||||||
|
boundaryPoints.push([lng, lat]);
|
||||||
|
//正北是0°
|
||||||
|
let start = angle + 45 > 360 ? angle - 45 - 360 : angle - 45;
|
||||||
|
let end = start + 90;
|
||||||
|
for (let i = start; i <= end; i++) {
|
||||||
|
let dx = radius * Math.sin((i * Math.PI) / 180.0);
|
||||||
|
let dy = radius * Math.cos((i * Math.PI) / 180.0);
|
||||||
|
let ec = Eb + ((Ea - Eb) * (90.0 - lat)) / 90.0;
|
||||||
|
let ed = ec * Math.cos((lat * Math.PI) / 180);
|
||||||
|
let BJD = lng + ((dx / ed) * 180.0) / Math.PI;
|
||||||
|
let BWD = lat + ((dy / ec) * 180.0) / Math.PI;
|
||||||
|
positionArr.push(BJD, BWD);
|
||||||
|
boundaryPoints.push([BJD, BWD]);
|
||||||
|
this.refreshBBox(bbox, BJD, BWD);
|
||||||
|
}
|
||||||
|
boundaryPoints.push([lng, lat]);
|
||||||
|
return {
|
||||||
|
positionArr,
|
||||||
|
boundaryPoints,
|
||||||
|
bbox,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 更新外围矩形 Bbox
|
||||||
|
* @param {Array} result 外围矩形Bbox-[minX, minY, maxX, maxY]
|
||||||
|
* @param {Number} x 经度
|
||||||
|
* @param {Number} y 纬度
|
||||||
|
*/
|
||||||
|
refreshBBox(result, x, y) {
|
||||||
|
result[0] = x < result[0] ? x : result[0];
|
||||||
|
result[1] = y < result[1] ? y : result[1];
|
||||||
|
result[2] = x > result[2] ? x : result[2];
|
||||||
|
result[3] = y > result[3] ? y : result[3];
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 插值点用射线判断通视性
|
||||||
|
* @param {*} gridPoints 网格点
|
||||||
|
* @param {*} step 步长,可以理解成是精度
|
||||||
|
* @param {*} sourcePos 视域分析起点
|
||||||
|
* @returns kriging插值所需的参数对象{ values:[], lngs:[], lats:[]}
|
||||||
|
*/
|
||||||
|
createTargetPoints(gridPoints, step, sourcePos) {
|
||||||
|
let positionArr = [];
|
||||||
|
let objectsToExclude = [
|
||||||
|
this.frustumPrimitive,
|
||||||
|
this.pyramid,
|
||||||
|
this.debugModelMatrixPrimitive,
|
||||||
|
];
|
||||||
|
let values = [],
|
||||||
|
lngs = [],
|
||||||
|
lats = [];
|
||||||
|
let height = this.getHeight(sourcePos[0], sourcePos[1], objectsToExclude);
|
||||||
|
positionArr.push({
|
||||||
|
x: sourcePos[0],
|
||||||
|
y: sourcePos[1],
|
||||||
|
z: height,
|
||||||
|
});
|
||||||
|
let viewPoint = this.ViewShedOptions.viewPosition;
|
||||||
|
for (let index = 0; index < gridPoints.features.length; index++) {
|
||||||
|
const feature = gridPoints.features[index];
|
||||||
|
const coords = feature.geometry.coordinates;
|
||||||
|
const x = coords[0],
|
||||||
|
y = coords[1];
|
||||||
|
let h = this.getHeight(x, y, objectsToExclude);
|
||||||
|
let endPoint = Cesium.Cartesian3.fromDegrees(x, y, h);
|
||||||
|
let direction = Cesium.Cartesian3.normalize(
|
||||||
|
Cesium.Cartesian3.subtract(
|
||||||
|
endPoint,
|
||||||
|
viewPoint,
|
||||||
|
new Cesium.Cartesian3()
|
||||||
|
),
|
||||||
|
new Cesium.Cartesian3()
|
||||||
|
);
|
||||||
|
// 建立射线
|
||||||
|
let ray = new Cesium.Ray(viewPoint, direction);
|
||||||
|
let result = this.viewer.scene.pickFromRay(ray, objectsToExclude); // 计算交互点,返回第一个
|
||||||
|
if (result) {
|
||||||
|
let buffer = this.ReturnDistance(endPoint, result.position);
|
||||||
|
// let M_color = Cesium.Color.GREEN;
|
||||||
|
if (buffer > step) {
|
||||||
|
// M_color = Cesium.Color.RED;
|
||||||
|
values.push(0);
|
||||||
|
} else {
|
||||||
|
values.push(1);
|
||||||
|
}
|
||||||
|
lngs.push(x);
|
||||||
|
lats.push(y);
|
||||||
|
// this.viewer.entities.add(
|
||||||
|
// new Cesium.Entity({
|
||||||
|
// name: "插值点哦",
|
||||||
|
// show: true,
|
||||||
|
// position: endPoint,
|
||||||
|
// point: {
|
||||||
|
// show: true,
|
||||||
|
// pixelSize: 10,
|
||||||
|
// color: M_color,
|
||||||
|
// outlineWidth: 2,
|
||||||
|
// outlineColor: Cesium.Color.YELLOW,
|
||||||
|
// },
|
||||||
|
// })
|
||||||
|
// );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
values,
|
||||||
|
lngs,
|
||||||
|
lats,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* canvas转image图片
|
||||||
|
* @returns base64图片
|
||||||
|
*/
|
||||||
|
returnImgae() {
|
||||||
|
return this.canvasEle.toDataURL("image/png");
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ViewShed;
|
||||||
131
src/Obj/Analysis/CircleViewShed/glsl.js
Normal file
131
src/Obj/Analysis/CircleViewShed/glsl.js
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
export default `
|
||||||
|
#define USE_CUBE_MAP_SHADOW true
|
||||||
|
uniform sampler2D colorTexture;
|
||||||
|
uniform sampler2D depthTexture;
|
||||||
|
varying vec2 v_textureCoordinates;
|
||||||
|
uniform mat4 camera_projection_matrix;
|
||||||
|
uniform mat4 camera_view_matrix;
|
||||||
|
uniform samplerCube shadowMap_textureCube;
|
||||||
|
uniform mat4 shadowMap_matrix;
|
||||||
|
uniform vec4 shadowMap_lightPositionEC;
|
||||||
|
uniform vec4 shadowMap_normalOffsetScaleDistanceMaxDistanceAndDarkness;
|
||||||
|
uniform vec4 shadowMap_texelSizeDepthBiasAndNormalShadingSmooth;
|
||||||
|
uniform float helsing_viewDistance;
|
||||||
|
uniform vec4 helsing_visibleAreaColor;
|
||||||
|
uniform vec4 helsing_invisibleAreaColor;
|
||||||
|
|
||||||
|
struct zx_shadowParameters
|
||||||
|
{
|
||||||
|
vec3 texCoords;
|
||||||
|
float depthBias;
|
||||||
|
float depth;
|
||||||
|
float nDotL;
|
||||||
|
vec2 texelStepSize;
|
||||||
|
float normalShadingSmooth;
|
||||||
|
float darkness;
|
||||||
|
};
|
||||||
|
|
||||||
|
float czm_shadowVisibility(samplerCube shadowMap, zx_shadowParameters shadowParameters)
|
||||||
|
{
|
||||||
|
float depthBias = shadowParameters.depthBias;
|
||||||
|
float depth = shadowParameters.depth;
|
||||||
|
float nDotL = shadowParameters.nDotL;
|
||||||
|
float normalShadingSmooth = shadowParameters.normalShadingSmooth;
|
||||||
|
float darkness = shadowParameters.darkness;
|
||||||
|
vec3 uvw = shadowParameters.texCoords;
|
||||||
|
depth -= depthBias;
|
||||||
|
float visibility = czm_shadowDepthCompare(shadowMap, uvw, depth);
|
||||||
|
return czm_private_shadowVisibility(visibility, nDotL, normalShadingSmooth, darkness);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 getPositionEC(){
|
||||||
|
return czm_windowToEyeCoordinates(gl_FragCoord);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 getNormalEC(){
|
||||||
|
return vec3(1.);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec4 toEye(in vec2 uv,in float depth){
|
||||||
|
vec2 xy=vec2((uv.x*2.-1.),(uv.y*2.-1.));
|
||||||
|
vec4 posInCamera=czm_inverseProjection*vec4(xy,depth,1.);
|
||||||
|
posInCamera=posInCamera/posInCamera.w;
|
||||||
|
return posInCamera;
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3 pointProjectOnPlane(in vec3 planeNormal,in vec3 planeOrigin,in vec3 point){
|
||||||
|
vec3 v01=point-planeOrigin;
|
||||||
|
float d=dot(planeNormal,v01);
|
||||||
|
return(point-planeNormal*d);
|
||||||
|
}
|
||||||
|
|
||||||
|
float getDepth(in vec4 depth){
|
||||||
|
float z_window=czm_unpackDepth(depth);
|
||||||
|
z_window=czm_reverseLogDepth(z_window);
|
||||||
|
float n_range=czm_depthRange.near;
|
||||||
|
float f_range=czm_depthRange.far;
|
||||||
|
return(2.*z_window-n_range-f_range)/(f_range-n_range);
|
||||||
|
}
|
||||||
|
|
||||||
|
float shadow(in vec4 positionEC){
|
||||||
|
vec3 normalEC=getNormalEC();
|
||||||
|
zx_shadowParameters shadowParameters;
|
||||||
|
shadowParameters.texelStepSize=shadowMap_texelSizeDepthBiasAndNormalShadingSmooth.xy;
|
||||||
|
shadowParameters.depthBias=shadowMap_texelSizeDepthBiasAndNormalShadingSmooth.z;
|
||||||
|
shadowParameters.normalShadingSmooth=shadowMap_texelSizeDepthBiasAndNormalShadingSmooth.w;
|
||||||
|
shadowParameters.darkness=shadowMap_normalOffsetScaleDistanceMaxDistanceAndDarkness.w;
|
||||||
|
vec3 directionEC=positionEC.xyz-shadowMap_lightPositionEC.xyz;
|
||||||
|
float distance=length(directionEC);
|
||||||
|
directionEC=normalize(directionEC);
|
||||||
|
float radius=shadowMap_lightPositionEC.w;
|
||||||
|
if(distance>radius)
|
||||||
|
{
|
||||||
|
return 2.0;
|
||||||
|
}
|
||||||
|
vec3 directionWC=czm_inverseViewRotation*directionEC;
|
||||||
|
shadowParameters.depth=distance/radius-0.0003;
|
||||||
|
shadowParameters.nDotL=clamp(dot(normalEC,-directionEC),0.,1.);
|
||||||
|
shadowParameters.texCoords=directionWC;
|
||||||
|
float visibility=czm_shadowVisibility(shadowMap_textureCube,shadowParameters);
|
||||||
|
return visibility;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool visible(in vec4 result)
|
||||||
|
{
|
||||||
|
result.x/=result.w;
|
||||||
|
result.y/=result.w;
|
||||||
|
result.z/=result.w;
|
||||||
|
return result.x>=-1.&&result.x<=1.
|
||||||
|
&&result.y>=-1.&&result.y<=1.
|
||||||
|
&&result.z>=-1.&&result.z<=1.;
|
||||||
|
}
|
||||||
|
|
||||||
|
void main(){
|
||||||
|
// 釉色 = 结构二维(颜色纹理, 纹理坐标)
|
||||||
|
gl_FragColor = texture2D(colorTexture, v_textureCoordinates);
|
||||||
|
// 深度 = 获取深度(结构二维(深度纹理, 纹理坐标))
|
||||||
|
float depth = getDepth(texture2D(depthTexture, v_textureCoordinates));
|
||||||
|
// 视角 = (纹理坐标, 深度)
|
||||||
|
vec4 viewPos = toEye(v_textureCoordinates, depth);
|
||||||
|
// 世界坐标
|
||||||
|
vec4 wordPos = czm_inverseView * viewPos;
|
||||||
|
// 虚拟相机中坐标
|
||||||
|
vec4 vcPos = camera_view_matrix * wordPos;
|
||||||
|
float near = .001 * helsing_viewDistance;
|
||||||
|
float dis = length(vcPos.xyz);
|
||||||
|
if(dis > near && dis < helsing_viewDistance){
|
||||||
|
// 透视投影
|
||||||
|
vec4 posInEye = camera_projection_matrix * vcPos;
|
||||||
|
// 可视区颜色
|
||||||
|
// vec4 helsing_visibleAreaColor=vec4(0.,1.,0.,.5);
|
||||||
|
// vec4 helsing_invisibleAreaColor=vec4(1.,0.,0.,.5);
|
||||||
|
if(visible(posInEye)){
|
||||||
|
float vis = shadow(viewPos);
|
||||||
|
if(vis > 0.3){
|
||||||
|
// gl_FragColor = mix(gl_FragColor,helsing_visibleAreaColor,.5);
|
||||||
|
} else {
|
||||||
|
gl_FragColor = mix(gl_FragColor,helsing_invisibleAreaColor,.5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}`;
|
||||||
380
src/Obj/Analysis/CircleViewShed/index.js
Normal file
380
src/Obj/Analysis/CircleViewShed/index.js
Normal file
@ -0,0 +1,380 @@
|
|||||||
|
// ViewShed.js
|
||||||
|
import Event from '../../../Event'
|
||||||
|
import MouseTip from '../../../MouseTip'
|
||||||
|
import Tools from '../../../Tools'
|
||||||
|
import EventBinding from '../../Element/Dialog/eventBinding'
|
||||||
|
import Dialog from '../../../BaseDialog'
|
||||||
|
import { html } from './_element'
|
||||||
|
/**
|
||||||
|
* @constructor
|
||||||
|
* @description 可视域分析
|
||||||
|
* @param sdk
|
||||||
|
* @param {Object} options 选项。
|
||||||
|
* @param {Number} options.viewPointHeight=1.8 视点高度(m)。
|
||||||
|
* @param {Number} options.precision=20 精度。
|
||||||
|
* @param {String} options.visibleAreaColor=#008000 可视区域颜色。
|
||||||
|
* @param {String} options.invisibleAreaColor=#FF0000 不可视区域颜色。
|
||||||
|
*/
|
||||||
|
class CircleViewShed extends Tools {
|
||||||
|
#intervalEvents = new Map()
|
||||||
|
|
||||||
|
constructor(sdk, options = {}, _Dialog = {}) {
|
||||||
|
super(sdk, options)
|
||||||
|
|
||||||
|
this.viewer = sdk.viewer
|
||||||
|
this.options = {}
|
||||||
|
this.options.visibleAreaColor = options.visibleAreaColor || '#008000'
|
||||||
|
this.options.invisibleAreaColor = options.invisibleAreaColor || '#FF0000'
|
||||||
|
this.ids = []
|
||||||
|
this.primitives = []
|
||||||
|
this.viewpointPrimitive = null
|
||||||
|
|
||||||
|
this._elms = {}
|
||||||
|
this.precision = options.precision
|
||||||
|
this.viewPointHeight = options.viewPointHeight
|
||||||
|
this.Dialog = _Dialog
|
||||||
|
this._EventBinding = new EventBinding()
|
||||||
|
this.html = null
|
||||||
|
YJ.Analysis.Analyses.push(this)
|
||||||
|
CircleViewShed.edit(this)
|
||||||
|
// CircleViewShed.create(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
get viewPointHeight() {
|
||||||
|
return this.options.viewPointHeight
|
||||||
|
}
|
||||||
|
|
||||||
|
set viewPointHeight(v) {
|
||||||
|
let viewPointHeight = Math.floor(Number(v) * 10) / 10
|
||||||
|
if (isNaN(viewPointHeight)) {
|
||||||
|
viewPointHeight = 1.8
|
||||||
|
}
|
||||||
|
if (viewPointHeight < 0) {
|
||||||
|
viewPointHeight = 0
|
||||||
|
}
|
||||||
|
this.options.viewPointHeight = viewPointHeight
|
||||||
|
this._elms.viewPointHeight &&
|
||||||
|
this._elms.viewPointHeight.forEach(item => {
|
||||||
|
item.value = viewPointHeight
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
get precision() {
|
||||||
|
return this.options.precision
|
||||||
|
}
|
||||||
|
|
||||||
|
set precision(v) {
|
||||||
|
let precision = Math.floor(Number(v))
|
||||||
|
if (isNaN(precision)) {
|
||||||
|
precision = 20
|
||||||
|
} else if (precision < 1) {
|
||||||
|
precision = 1
|
||||||
|
}
|
||||||
|
this.options.precision = precision
|
||||||
|
this._elms.precision &&
|
||||||
|
this._elms.precision.forEach(item => {
|
||||||
|
item.value = precision
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
static create(that) {
|
||||||
|
let count = 0
|
||||||
|
if (!YJ.Measure.GetMeasureStatus()) {
|
||||||
|
if (that._DialogObject && that._DialogObject.close) {
|
||||||
|
that._DialogObject.close()
|
||||||
|
that._DialogObject = null
|
||||||
|
}
|
||||||
|
let Draw = new YJ.Draw.DrawCircle(that.sdk)
|
||||||
|
Draw.start(async (a, options) => {
|
||||||
|
// that.center = options.center
|
||||||
|
if(!options) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
that.radius = options.radius
|
||||||
|
let positions = await Cesium.sampleTerrainMostDetailed(
|
||||||
|
that.sdk.viewer.terrainProvider,
|
||||||
|
[Cesium.Cartographic.fromDegrees(options.center.lng, options.center.lat)]
|
||||||
|
);
|
||||||
|
that.center = {
|
||||||
|
lng: options.center.lng,
|
||||||
|
lat: options.center.lat,
|
||||||
|
alt: positions[0].height
|
||||||
|
}
|
||||||
|
await that.analyse()
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
console.log('上一次测量未结束')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static async edit(that) {
|
||||||
|
if (that._DialogObject && that._DialogObject.close) {
|
||||||
|
that._DialogObject.close()
|
||||||
|
that._DialogObject = null
|
||||||
|
}
|
||||||
|
that._DialogObject = await new Dialog(that.sdk.viewer._container, {
|
||||||
|
title: '圆形视域分析',
|
||||||
|
left: '180px',
|
||||||
|
top: '100px',
|
||||||
|
closeCallBack: () => {
|
||||||
|
that.Dialog.closeCallBack && that.Dialog.closeCallBack()
|
||||||
|
YJ.Measure.SetMeasureStatus(false)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
await that._DialogObject.init()
|
||||||
|
that._DialogObject._element.body.className =
|
||||||
|
that._DialogObject._element.body.className + ' circle-view-shed'
|
||||||
|
let contentElm = document.createElement('div')
|
||||||
|
contentElm.innerHTML = html()
|
||||||
|
that._DialogObject.contentAppChild(contentElm)
|
||||||
|
|
||||||
|
let drawElm = document.createElement('button')
|
||||||
|
drawElm.innerHTML = '绘制'
|
||||||
|
drawElm.addEventListener('click', () => {
|
||||||
|
let terrainAvailability = that.viewer.terrainProvider.availability;
|
||||||
|
if (!terrainAvailability) {
|
||||||
|
window.ELEMENT && window.ELEMENT.Message({
|
||||||
|
message: '未加载地形数据!',
|
||||||
|
type: 'warning',
|
||||||
|
duration: 1500
|
||||||
|
});
|
||||||
|
return
|
||||||
|
}
|
||||||
|
CircleViewShed.create(that)
|
||||||
|
})
|
||||||
|
that._DialogObject.footAppChild(drawElm)
|
||||||
|
|
||||||
|
let all_elm = contentElm.getElementsByTagName('*')
|
||||||
|
that._EventBinding.on(that, all_elm)
|
||||||
|
that._elms = that._EventBinding.element
|
||||||
|
}
|
||||||
|
|
||||||
|
analyse() {
|
||||||
|
// this.destroy()
|
||||||
|
let center = [this.center.lng, this.center.lat]
|
||||||
|
let radius = this.radius / 1000
|
||||||
|
let circle = turf.circle(center, radius, {
|
||||||
|
steps: 180,
|
||||||
|
units: 'kilometers',
|
||||||
|
properties: { foo: 'bar' }
|
||||||
|
})
|
||||||
|
if (!this.viewpointPrimitive) {
|
||||||
|
this.viewpointPrimitive = this.viewer.scene.primitives.add(
|
||||||
|
new Cesium.PointPrimitiveCollection()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if (!this.viewBillboardPrimitive) {
|
||||||
|
this.viewBillboardPrimitive = this.viewer.scene.primitives.add(
|
||||||
|
new Cesium.BillboardCollection()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
let array = []
|
||||||
|
let distance = radius / this.precision
|
||||||
|
for (let i = 1; i < circle.geometry.coordinates[0].length; i++) {
|
||||||
|
let line = turf.lineString([center, circle.geometry.coordinates[0][i]])
|
||||||
|
let array2 = []
|
||||||
|
for (let j = 1; j <= this.precision; j++) {
|
||||||
|
let sliced = turf.lineSliceAlong(line, 0, distance * j, {
|
||||||
|
units: 'kilometers'
|
||||||
|
})
|
||||||
|
array2.push([
|
||||||
|
sliced.geometry.coordinates[1][0],
|
||||||
|
sliced.geometry.coordinates[1][1]
|
||||||
|
])
|
||||||
|
}
|
||||||
|
array.push(array2)
|
||||||
|
}
|
||||||
|
|
||||||
|
let viewPoint = Cesium.Cartesian3.fromDegrees(
|
||||||
|
this.center.lng,
|
||||||
|
this.center.lat,
|
||||||
|
this.center.alt + this.viewPointHeight
|
||||||
|
)
|
||||||
|
let instances = []
|
||||||
|
CircleViewShed.getcanvas(this).then(canvas =>
|
||||||
|
this.viewBillboardPrimitive.add({
|
||||||
|
position: viewPoint,
|
||||||
|
image: canvas,
|
||||||
|
width: 200,
|
||||||
|
height: 140,
|
||||||
|
verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
|
||||||
|
disableDepthTestDistance: Number.POSITIVE_INFINITY
|
||||||
|
})
|
||||||
|
)
|
||||||
|
this.viewpointPrimitive.add({
|
||||||
|
position: viewPoint,
|
||||||
|
color: Cesium.Color.AQUA.withAlpha(1),
|
||||||
|
pixelSize: 6
|
||||||
|
})
|
||||||
|
|
||||||
|
let m = 0
|
||||||
|
let _this = this
|
||||||
|
let key = this.randomString()
|
||||||
|
let intervalEvent = setInterval(() => {
|
||||||
|
if (m >= array.length) {
|
||||||
|
let item = this.#intervalEvents.get(key)
|
||||||
|
item && clearInterval(item.event)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
InBatches(m)
|
||||||
|
m += 1
|
||||||
|
}, 0)
|
||||||
|
this.#intervalEvents.set(key, { event: intervalEvent })
|
||||||
|
|
||||||
|
function InBatches(k) {
|
||||||
|
let instances = []
|
||||||
|
let i = k
|
||||||
|
for (let j = 0; j < array[i].length; j++) {
|
||||||
|
let pt1 = array[i][j]
|
||||||
|
let pt2
|
||||||
|
let pt3
|
||||||
|
let pt4 = array[i][j - 1]
|
||||||
|
if (i == array.length - 1) {
|
||||||
|
pt2 = array[0][j]
|
||||||
|
pt3 = array[0][j - 1]
|
||||||
|
} else {
|
||||||
|
pt2 = array[i + 1][j]
|
||||||
|
pt3 = array[i + 1][j - 1]
|
||||||
|
}
|
||||||
|
if (j == 0) {
|
||||||
|
pt3 = [...center]
|
||||||
|
pt4 = []
|
||||||
|
}
|
||||||
|
let cpt = [(pt1[0] + pt3[0]) / 2, (pt1[1] + pt3[1]) / 2]
|
||||||
|
let cartographic = Cesium.Cartographic.fromDegrees(cpt[0], cpt[1])
|
||||||
|
let height = _this.viewer.scene.globe.getHeight(cartographic)
|
||||||
|
let targetPoint = Cesium.Cartesian3.fromDegrees(cpt[0], cpt[1], height)
|
||||||
|
|
||||||
|
let direction = Cesium.Cartesian3.normalize(
|
||||||
|
Cesium.Cartesian3.subtract(
|
||||||
|
targetPoint,
|
||||||
|
viewPoint,
|
||||||
|
new Cesium.Cartesian3()
|
||||||
|
),
|
||||||
|
new Cesium.Cartesian3()
|
||||||
|
)
|
||||||
|
let ray = new Cesium.Ray(viewPoint, direction)
|
||||||
|
let pickedObjects = _this.viewer.scene.drillPickFromRay(
|
||||||
|
ray,
|
||||||
|
_this.primitives
|
||||||
|
)
|
||||||
|
let result
|
||||||
|
for (let i = 0; i < pickedObjects.length; i++) {
|
||||||
|
if (pickedObjects[i].position) {
|
||||||
|
result = pickedObjects[i]
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let color = Cesium.Color.LIME
|
||||||
|
if (
|
||||||
|
result &&
|
||||||
|
Math.abs(result.position.x - targetPoint.x) > 0.01 &&
|
||||||
|
Math.abs(result.position.y - targetPoint.y) > 0.01 &&
|
||||||
|
Math.abs(result.position.z - targetPoint.z) > 0.01
|
||||||
|
) {
|
||||||
|
color = Cesium.Color.RED
|
||||||
|
}
|
||||||
|
let polyline = new Cesium.GroundPolylineGeometry({
|
||||||
|
positions: Cesium.Cartesian3.fromDegreesArray([
|
||||||
|
...pt1,
|
||||||
|
...pt2,
|
||||||
|
...pt3,
|
||||||
|
...pt4,
|
||||||
|
...pt1
|
||||||
|
]),
|
||||||
|
width: 2
|
||||||
|
})
|
||||||
|
|
||||||
|
let polygonInstance = new Cesium.GeometryInstance({
|
||||||
|
geometry: polyline,
|
||||||
|
name: 'ViewershedPolygon',
|
||||||
|
attributes: {
|
||||||
|
color: Cesium.ColorGeometryInstanceAttribute.fromColor(color),
|
||||||
|
show: new Cesium.ShowGeometryInstanceAttribute(true) //显示或者隐藏
|
||||||
|
}
|
||||||
|
})
|
||||||
|
instances.push(polygonInstance)
|
||||||
|
}
|
||||||
|
|
||||||
|
_this.primitives.push(
|
||||||
|
_this.viewer.scene.primitives.add(
|
||||||
|
new Cesium.GroundPolylinePrimitive({
|
||||||
|
geometryInstances: instances,
|
||||||
|
appearance: new Cesium.PolylineColorAppearance()
|
||||||
|
})
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static getcanvas(that) {
|
||||||
|
const canvas = document.createElement('canvas')
|
||||||
|
const ctx = canvas.getContext('2d')
|
||||||
|
canvas.width = 220
|
||||||
|
canvas.height = 140
|
||||||
|
canvas.style.background = '#000000'
|
||||||
|
let img = new Image()
|
||||||
|
const data = [
|
||||||
|
{
|
||||||
|
images: that.getSourceRootPath() + '/img/bubble/lng.png',
|
||||||
|
text: '经度:' + parseFloat(that.center.lng.toFixed(10)) + '°'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
images: that.getSourceRootPath() + '/img/bubble/lat.png',
|
||||||
|
text: '纬度:' + parseFloat(that.center.lat.toFixed(10)) + '°'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
images: that.getSourceRootPath() + '/img/bubble/h.png',
|
||||||
|
text: '视高:' + that.viewPointHeight + ' m'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
images: that.getSourceRootPath() + '/img/bubble/radius.png',
|
||||||
|
text: '半径:' + that.radius + ' m'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
img.src = that.getSourceRootPath() + '/img/bubble/bubble.png'
|
||||||
|
let imagesLoaded = 0
|
||||||
|
return new Promise(async (resolve, reject) => {
|
||||||
|
img.onload = () => {
|
||||||
|
ctx.drawImage(img, 0, 0, canvas.width, canvas.height)
|
||||||
|
data.forEach((item, index) => {
|
||||||
|
const img = new Image()
|
||||||
|
img.src = item.images
|
||||||
|
img.onload = () => {
|
||||||
|
ctx.drawImage(img, 12, 12 + index * 26)
|
||||||
|
ctx.fillStyle = '#fff'
|
||||||
|
ctx.font = '12px Arial'
|
||||||
|
ctx.fillText(item.text, 44, 28 + index * 26)
|
||||||
|
imagesLoaded++
|
||||||
|
if (imagesLoaded === data.length) {
|
||||||
|
resolve(canvas)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
destroy() {
|
||||||
|
for (const [key, value] of this.#intervalEvents) {
|
||||||
|
clearInterval(value.event)
|
||||||
|
}
|
||||||
|
this.#intervalEvents = new Map()
|
||||||
|
for (let i = 0; i < this.primitives.length; i++) {
|
||||||
|
this.viewer.scene.primitives.remove(this.primitives[i])
|
||||||
|
}
|
||||||
|
this.primitives = []
|
||||||
|
if (this.viewpointPrimitive) {
|
||||||
|
this.viewer.scene.primitives.remove(this.viewpointPrimitive)
|
||||||
|
this.viewpointPrimitive = null
|
||||||
|
}
|
||||||
|
if (this.viewBillboardPrimitive) {
|
||||||
|
this.viewer.scene.primitives.remove(this.viewBillboardPrimitive)
|
||||||
|
this.viewBillboardPrimitive = null
|
||||||
|
}
|
||||||
|
YJ.Measure.SetMeasureStatus(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default CircleViewShed
|
||||||
208
src/Obj/Analysis/Contour/index.js
Normal file
208
src/Obj/Analysis/Contour/index.js
Normal file
@ -0,0 +1,208 @@
|
|||||||
|
|
||||||
|
|
||||||
|
import Tools from '../../../Tools';
|
||||||
|
class ContourAnalysis {
|
||||||
|
/**
|
||||||
|
* @constructor 等高线分析
|
||||||
|
* @param sdk
|
||||||
|
* **/
|
||||||
|
constructor(sdk, options = {}) {
|
||||||
|
this.viewer = sdk.viewer
|
||||||
|
let terrainAvailability = this.viewer.terrainProvider.availability;
|
||||||
|
if (!terrainAvailability) {
|
||||||
|
this.error = '未加载地形数据!'
|
||||||
|
window.ELEMENT && window.ELEMENT.Message({
|
||||||
|
message: '未加载地形数据!',
|
||||||
|
type: 'warning',
|
||||||
|
duration: 1500
|
||||||
|
});
|
||||||
|
console.warn(this.error)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.positions = options.positions
|
||||||
|
this.interfaceNum = options.interfaceNum || 25 //内插时均分的数量,即沿着边界长或宽均分成n分进行插点,默认值25
|
||||||
|
this.colorFill = options.colorFill || [
|
||||||
|
"#8CEA00",
|
||||||
|
"#B7FF4A",
|
||||||
|
"#FFFF37",
|
||||||
|
"#FFE66F",
|
||||||
|
"#FFD1A4",
|
||||||
|
"#FFCBB3",
|
||||||
|
"#FFBD9D",
|
||||||
|
"#FFAD86",
|
||||||
|
"#FF9D6F",
|
||||||
|
"#FF8F59",
|
||||||
|
"#FF8040",
|
||||||
|
"#FF5809",
|
||||||
|
"#F75000",
|
||||||
|
"#D94600",
|
||||||
|
"#BB3D00",
|
||||||
|
"#A23400",
|
||||||
|
"#842B00",
|
||||||
|
"#642100",
|
||||||
|
"#4D0000",
|
||||||
|
"#2F0000",
|
||||||
|
]; //等高线赋值颜色,内含default值
|
||||||
|
this.countorLineList = Cesium.defaultValue(options.countorLineList, []);
|
||||||
|
YJ.Analysis.Analyses.push(this)
|
||||||
|
this.createNewLine();
|
||||||
|
}
|
||||||
|
createNewLine() {
|
||||||
|
ContourAnalysis.interpolatePoint(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
//利用turf在box内进行插点
|
||||||
|
static interpolatePoint(that) {
|
||||||
|
let curPoints = that.positions
|
||||||
|
let features = [];
|
||||||
|
const boundaryCoord = {
|
||||||
|
minX: 360,
|
||||||
|
maxX: -360,
|
||||||
|
minY: 180,
|
||||||
|
maxY: -180,
|
||||||
|
}; //绘制几何图形的外围矩形box
|
||||||
|
for (let index = 0; index < curPoints.length; index++) {
|
||||||
|
const element = Cesium.Cartesian3.fromDegrees(curPoints[index].lng, curPoints[index].lat, curPoints[index].alt);
|
||||||
|
let ellipsoid = that.viewer.scene.globe.ellipsoid;
|
||||||
|
let cartographic = ellipsoid.cartesianToCartographic(element);
|
||||||
|
let lat = Cesium.Math.toDegrees(cartographic.latitude);
|
||||||
|
let lng = Cesium.Math.toDegrees(cartographic.longitude);
|
||||||
|
boundaryCoord.maxY = Math.max(lat, boundaryCoord.maxY);
|
||||||
|
boundaryCoord.minY = Math.min(lat, boundaryCoord.minY);
|
||||||
|
boundaryCoord.maxX = Math.max(lng, boundaryCoord.maxX);
|
||||||
|
boundaryCoord.minX = Math.min(lng, boundaryCoord.minX);
|
||||||
|
|
||||||
|
let curFeature = {
|
||||||
|
type: "Feature",
|
||||||
|
properties: {},
|
||||||
|
geometry: {
|
||||||
|
type: "Point",
|
||||||
|
coordinates: [lng, lat],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
features.push(curFeature);
|
||||||
|
}
|
||||||
|
let boundaryJson = {
|
||||||
|
type: "FeatureCollection",
|
||||||
|
features: features,
|
||||||
|
};
|
||||||
|
turf.featureEach(boundaryJson, function (point) {
|
||||||
|
point.properties.height = 0;
|
||||||
|
});
|
||||||
|
let options = {
|
||||||
|
gridType: "points",
|
||||||
|
property: "height",
|
||||||
|
units: "kilometers",
|
||||||
|
};
|
||||||
|
let from = turf.point([boundaryCoord.minX, boundaryCoord.minY]);
|
||||||
|
let to = turf.point([boundaryCoord.maxX, boundaryCoord.maxY]);
|
||||||
|
let diagonalDistance = turf.rhumbDistance(from, to, {
|
||||||
|
units: "kilometers",
|
||||||
|
});
|
||||||
|
let grid = turf.interpolate(
|
||||||
|
boundaryJson,
|
||||||
|
diagonalDistance / that.interfaceNum,
|
||||||
|
options
|
||||||
|
);
|
||||||
|
let minHeight = 10000000; //最低点高程值
|
||||||
|
let maxHeight = -100000000; //最高点高程值
|
||||||
|
turf.featureEach(grid, function (point) {
|
||||||
|
let pos = point.geometry.coordinates;
|
||||||
|
let cartographic = Cesium.Cartographic.fromDegrees(pos[0], pos[1]);
|
||||||
|
let height = that.viewer.scene.globe.getHeight(cartographic);
|
||||||
|
maxHeight = Math.max(height, maxHeight);
|
||||||
|
minHeight = Math.min(height, minHeight);
|
||||||
|
point.properties.height = height;
|
||||||
|
});
|
||||||
|
let breaks = [];
|
||||||
|
let stepCount = that.colorFill.length - 1;
|
||||||
|
let step = (maxHeight - minHeight) / stepCount;
|
||||||
|
for (let index = 0; index < stepCount + 1; index++) {
|
||||||
|
breaks.push(Math.ceil(minHeight + step * index));
|
||||||
|
}
|
||||||
|
// console.log('grid', grid)
|
||||||
|
let linesJson = turf.isolines(grid, breaks, { zProperty: "height" });
|
||||||
|
let _countorLine = Cesium.GeoJsonDataSource.load(linesJson, {
|
||||||
|
clampToGround: true,
|
||||||
|
});
|
||||||
|
// console.log(linesJson)
|
||||||
|
_countorLine.then(function (dataSource) {
|
||||||
|
console.log(dataSource)
|
||||||
|
that.countorLine = dataSource; //最终计算生成的等高线对象,GeoJsonDataSource
|
||||||
|
that.countorLineList.push(dataSource); //等高线数组
|
||||||
|
that.viewer.dataSources.add(dataSource);
|
||||||
|
let entities = dataSource.entities.values;
|
||||||
|
for (let index = 0; index < entities.length; index++) {
|
||||||
|
const element = entities[index];
|
||||||
|
let center = getPolylineCenter(element.polyline);
|
||||||
|
element.position = center;
|
||||||
|
// dataSource.entities.add(new Cesium.Entity({
|
||||||
|
// position: center,
|
||||||
|
// label: {
|
||||||
|
// text: element.properties.height._value + '',
|
||||||
|
// font: '20px Microsoft YaHei',
|
||||||
|
// fillColor: Cesium.Color.fromCssColorString('#f1d20c'),
|
||||||
|
// style: Cesium.LabelStyle.FILL_AND_OUTLINE,
|
||||||
|
// disableDepthTestDistance: Number.POSITIVE_INFINITY,
|
||||||
|
// heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
|
||||||
|
// },
|
||||||
|
// }))
|
||||||
|
// element.label = new Cesium.LabelGraphics({
|
||||||
|
|
||||||
|
// })
|
||||||
|
let cur_index = that.getObjectIndex(
|
||||||
|
breaks,
|
||||||
|
element.properties.height._value
|
||||||
|
);
|
||||||
|
if (cur_index) {
|
||||||
|
element.polyline.material = Cesium.Color.fromCssColorString(
|
||||||
|
that.colorFill[cur_index - 1]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function getPolylineCenter(polyline) {
|
||||||
|
let tools = new Tools()
|
||||||
|
let positions = polyline.positions;
|
||||||
|
let length = positions._value.length;
|
||||||
|
let array = []
|
||||||
|
for (let i = 0; i < length; i++) {
|
||||||
|
let pos = tools.cartesian3Towgs84(positions._value[i], that.viewer)
|
||||||
|
array.push([pos.lng, pos.lat])
|
||||||
|
}
|
||||||
|
let line = turf.lineString(array);
|
||||||
|
let distance = turf.length(line, { units: "kilometers" });
|
||||||
|
let along = turf.along(line, distance/2, { units: "kilometers" });
|
||||||
|
return Cesium.Cartesian3.fromDegrees(along.geometry.coordinates[0], along.geometry.coordinates[1], 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 返回随机插入的数在数组中的位置
|
||||||
|
* @param {*} arr 元数组
|
||||||
|
* @param {*} num 随机数
|
||||||
|
* @returns 序号
|
||||||
|
* @example getObjectIndex([0,218,325,333,444],354)=>4;
|
||||||
|
*/
|
||||||
|
getObjectIndex(arr, num) {
|
||||||
|
for (let i = 0; i < arr.length; i++) {
|
||||||
|
if (arr[i] > num) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
clear(countorLine) {
|
||||||
|
if (countorLine) {
|
||||||
|
this.viewer.dataSources.remove(countorLine);
|
||||||
|
let index = this.countorLineList.indexOf(countorLine);
|
||||||
|
this.countorLineList.splice(index, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
destroy() {
|
||||||
|
this.countorLineList.forEach((element) => {
|
||||||
|
this.viewer.dataSources.remove(element);
|
||||||
|
});
|
||||||
|
this.countorLineList = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export default ContourAnalysis;
|
||||||
125
src/Obj/Analysis/CutFill/CreatePolygon.js
Normal file
125
src/Obj/Analysis/CutFill/CreatePolygon.js
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
class CreatePolygon {
|
||||||
|
constructor(viewer) {
|
||||||
|
if (!viewer) throw new Error("no viewer object!");
|
||||||
|
this.activePoints = [];
|
||||||
|
this.viewer = viewer;
|
||||||
|
this.handler = undefined;
|
||||||
|
this.init();
|
||||||
|
}
|
||||||
|
init() {
|
||||||
|
this.activeShapePoints = [];
|
||||||
|
this.floatingPoint = undefined;
|
||||||
|
this.activeShape = undefined;
|
||||||
|
this.activePoints.forEach((element) => {
|
||||||
|
this.viewer.entities.remove(element);
|
||||||
|
});
|
||||||
|
this.activePoints = [];
|
||||||
|
this.initHandler();
|
||||||
|
}
|
||||||
|
start(callback) {
|
||||||
|
const $this = this;
|
||||||
|
$this.keyDownStatus(true);
|
||||||
|
$this.init();
|
||||||
|
$this.handler = new Cesium.ScreenSpaceEventHandler($this.viewer.canvas);
|
||||||
|
$this.handler.setInputAction(function (event) {
|
||||||
|
let earthPosition = $this.viewer.scene.pickPosition(event.position);
|
||||||
|
if (Cesium.defined(earthPosition)) {
|
||||||
|
if ($this.activeShapePoints.length === 0) {
|
||||||
|
$this.floatingPoint = $this.createPoint(earthPosition);
|
||||||
|
$this.activeShapePoints.push(earthPosition);
|
||||||
|
let dynamicPositions = new Cesium.CallbackProperty(function () {
|
||||||
|
return new Cesium.PolygonHierarchy($this.activeShapePoints);
|
||||||
|
}, false);
|
||||||
|
$this.activeShape = $this.drawShape(dynamicPositions); //绘制动态图
|
||||||
|
}
|
||||||
|
$this.activeShapePoints.push(earthPosition);
|
||||||
|
$this.createPoint(earthPosition);
|
||||||
|
}
|
||||||
|
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
|
||||||
|
$this.handler.setInputAction(function (event) {
|
||||||
|
if (Cesium.defined($this.floatingPoint)) {
|
||||||
|
let newPosition = $this.viewer.scene.pickPosition(event.endPosition);
|
||||||
|
if (Cesium.defined(newPosition)) {
|
||||||
|
$this.floatingPoint.position.setValue(newPosition);
|
||||||
|
$this.activeShapePoints.pop();
|
||||||
|
$this.activeShapePoints.push(newPosition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
|
||||||
|
$this.handler.setInputAction(function () {
|
||||||
|
$this.activeShapePoints.pop(); //去除最后一个动态点
|
||||||
|
if ($this.activeShapePoints.length) {
|
||||||
|
$this.polygon = $this.drawShape($this.activeShapePoints); //绘制最终图
|
||||||
|
}
|
||||||
|
$this.viewer.entities.remove($this.floatingPoint); //去除动态点图形(当前鼠标点)
|
||||||
|
$this.viewer.entities.remove($this.activeShape); //去除动态图形
|
||||||
|
$this.activePoints.forEach((element) => {
|
||||||
|
$this.viewer.entities.remove(element);
|
||||||
|
});
|
||||||
|
$this.handler.destroy();
|
||||||
|
setTimeout(() => {
|
||||||
|
if (typeof callback == "function") callback();
|
||||||
|
}, 1000);
|
||||||
|
}, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
|
||||||
|
}
|
||||||
|
initHandler() {
|
||||||
|
if (this.handler) {
|
||||||
|
this.handler.destroy();
|
||||||
|
this.handler = undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
createPoint(worldPosition) {
|
||||||
|
let point = this.viewer.entities.add({
|
||||||
|
position: worldPosition,
|
||||||
|
point: {
|
||||||
|
color: Cesium.Color.SKYBLUE,
|
||||||
|
pixelSize: 5,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
this.activePoints.push(point);
|
||||||
|
return point;
|
||||||
|
}
|
||||||
|
drawShape(positionData) {
|
||||||
|
let shape = this.viewer.entities.add({
|
||||||
|
polygon: {
|
||||||
|
hierarchy: positionData,
|
||||||
|
material: new Cesium.ColorMaterialProperty(
|
||||||
|
Cesium.Color.BLUE.withAlpha(0.4)
|
||||||
|
),
|
||||||
|
zIndex: 99999999
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return shape;
|
||||||
|
}
|
||||||
|
//快捷键//Ctrl + Z
|
||||||
|
keyDownStatus(bool) {
|
||||||
|
const $this = this;
|
||||||
|
document.onkeydown = function (event) {
|
||||||
|
if (event.ctrlKey && window.event.keyCode == 90) {
|
||||||
|
if (!bool) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$this.activeShapePoints.pop();
|
||||||
|
$this.viewer.entities.remove(
|
||||||
|
$this.activePoints[$this.activePoints.length - 1]
|
||||||
|
);
|
||||||
|
$this.activePoints.pop();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Cesium中世界坐标系(笛卡尔)转经纬度
|
||||||
|
* @param {*} cartesian3
|
||||||
|
* @returns 经纬度
|
||||||
|
*/
|
||||||
|
Cartesian3ToDgrees(cartesian3) {
|
||||||
|
let cartographic =
|
||||||
|
window.viewer.scene.globe.ellipsoid.cartesianToCartographic(cartesian3);
|
||||||
|
let lat = Cesium.Math.toDegrees(cartographic.latitude);
|
||||||
|
let lng = Cesium.Math.toDegrees(cartographic.longitude);
|
||||||
|
let alt = cartographic.height;
|
||||||
|
return { lng: lng, lat: lat, alt: alt };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default CreatePolygon;
|
||||||
75
src/Obj/Analysis/CutFill/_element.js
Normal file
75
src/Obj/Analysis/CutFill/_element.js
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
function html() {
|
||||||
|
return `
|
||||||
|
<span class="custom-divider"></span>
|
||||||
|
<div class="div-item">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<span class="label" style="flex: 0 0 70px;">绘制分析区域</span>
|
||||||
|
<button class="draw-btn"><svg class="icon-edit"><use xlink:href="#yj-icon-edit"></use></svg>开始绘制</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<span class="custom-divider"></span>
|
||||||
|
<div class="div-item">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<span class="label">基准高度</span>
|
||||||
|
<div class="input-number input-number-unit-1">
|
||||||
|
<input class="input" type="number" title="" min="-999999" max="999999" name="height">
|
||||||
|
<span class="unit">m</span>
|
||||||
|
<span class="arrow"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<span class="label">精度</span>
|
||||||
|
<div class="input-number input-number-unit">
|
||||||
|
<input class="input" type="number" title="" min="1" max="1250" name="precision">
|
||||||
|
<span class="arrow"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<span class="custom-divider"></span>
|
||||||
|
<div class="div-item">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<span class="label" style="flex: 0 0 74px;">总分析面积:</span>
|
||||||
|
<span class="text-number" name="allArea">0</span>
|
||||||
|
<span class="unit text-number">m²</span>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<span class="label" style="flex: 0 0 90px;">无须填挖面积:</span>
|
||||||
|
<span class="text-number" name="noArea">0</span>
|
||||||
|
<span class="unit text-number">m²</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<span class="label" style="flex: 0 0 74px;">填方面积:</span>
|
||||||
|
<span class="text-number" name="fillArea">0</span>
|
||||||
|
<span class="unit text-number">m²</span>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<span class="label" style="flex: 0 0 90px;">挖方面积:</span>
|
||||||
|
<span class="text-number" name="cutArea">0</span>
|
||||||
|
<span class="unit text-number">m²</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<span class="label" style="flex: 0 0 74px;">填方体积:</span>
|
||||||
|
<span class="text-number" name="fillVolume">0</span>
|
||||||
|
<span class="unit text-number">m³</span>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<span class="label" style="flex: 0 0 90px;">挖方体积:</span>
|
||||||
|
<span class="text-number" name="cutVolume">0</span>
|
||||||
|
<span class="unit text-number">m³</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<span class="custom-divider"></span>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
|
export { html }
|
||||||
354
src/Obj/Analysis/CutFill/index.js
Normal file
354
src/Obj/Analysis/CutFill/index.js
Normal file
@ -0,0 +1,354 @@
|
|||||||
|
import Dialog from '../../../BaseDialog';
|
||||||
|
import { html } from "./_element";
|
||||||
|
// import CreatePolygon from "./CreatePolygon";
|
||||||
|
import DrawPolygon from "../../../Draw/drawPolygon"
|
||||||
|
|
||||||
|
class CutFillAnalysis {
|
||||||
|
/**
|
||||||
|
* @constructor 填挖方分析
|
||||||
|
* @param sdk
|
||||||
|
* **/
|
||||||
|
constructor(sdk, options = {}, _Dialog = {}) {
|
||||||
|
this.sdk = sdk;
|
||||||
|
this.viewer = sdk.viewer;
|
||||||
|
// if (!positions) throw new Error("no positions object!");
|
||||||
|
// this.positions = positions;
|
||||||
|
this.height = options.height || 70
|
||||||
|
this.maxHeigh = -1000000;
|
||||||
|
this.precision = options.precision || 125
|
||||||
|
this.Dialog = _Dialog
|
||||||
|
this.result = {
|
||||||
|
allArea: "",
|
||||||
|
cutArea: "",
|
||||||
|
cutVolume: "",
|
||||||
|
fillArea: "",
|
||||||
|
fillVolume: "",
|
||||||
|
noArea: "",
|
||||||
|
}
|
||||||
|
this.entities = []
|
||||||
|
this.Draw = new DrawPolygon(this.sdk)
|
||||||
|
YJ.Analysis.Analyses.push(this)
|
||||||
|
CutFillAnalysis.EditBox(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
create() {
|
||||||
|
this.clean()
|
||||||
|
this.Draw.start((a, positions) => {
|
||||||
|
if(!positions || positions.length<3) {
|
||||||
|
let _error = '最少需要三个坐标!'
|
||||||
|
console.warn(_error)
|
||||||
|
window.ELEMENT && window.ELEMENT.Message({
|
||||||
|
message: _error,
|
||||||
|
type: 'warning',
|
||||||
|
duration: 1500
|
||||||
|
});
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let fromDegreesArray = []
|
||||||
|
for (let i = 0; i < positions.length; i++) {
|
||||||
|
fromDegreesArray.push(positions[i].lng, positions[i].lat, positions[i].alt)
|
||||||
|
}
|
||||||
|
this.positions = Cesium.Cartesian3.fromDegreesArrayHeights(fromDegreesArray)
|
||||||
|
this.createPolygonGeo(this.positions);
|
||||||
|
this.result = this.VolumeAnalysis();
|
||||||
|
this.viewer.scene.screenSpaceCameraController.enableCollisionDetection = false; //允许相机进入地下
|
||||||
|
})
|
||||||
|
// const $this = this;
|
||||||
|
// if (!this.cp) {
|
||||||
|
// this.cp = new CreatePolygon(this.viewer)
|
||||||
|
// }
|
||||||
|
// this.cp.start(function () {
|
||||||
|
// console.log($this.cp.activeShapePoints)
|
||||||
|
// $this.positions = $this.cp.activeShapePoints;
|
||||||
|
// $this.createPolygonGeo($this.positions);
|
||||||
|
// $this.result = $this.VolumeAnalysis();
|
||||||
|
// $this.viewer.entities.remove($this.cp.polygon);
|
||||||
|
// $this.viewer.scene.screenSpaceCameraController.enableCollisionDetection = false; //允许相机进入地下
|
||||||
|
|
||||||
|
// });
|
||||||
|
}
|
||||||
|
createPolygonGeo(points) {
|
||||||
|
//计算网格粒度-精度
|
||||||
|
let granularity = Math.PI / Math.pow(2, 11);
|
||||||
|
granularity = granularity / this.precision;
|
||||||
|
let polygonGeometry = new Cesium.PolygonGeometry.fromPositions({
|
||||||
|
positions: points,
|
||||||
|
vertexFormat: Cesium.PerInstanceColorAppearance.FLAT_VERTEX_FORMAT,
|
||||||
|
granularity: granularity,
|
||||||
|
});
|
||||||
|
//创建自定义平面几何体
|
||||||
|
this.geom = new Cesium.PolygonGeometry.createGeometry(polygonGeometry);
|
||||||
|
}
|
||||||
|
VolumeAnalysis() {
|
||||||
|
let cutArea = 0,
|
||||||
|
cutVolume = 0,
|
||||||
|
fillArea = 0,
|
||||||
|
fillVolume = 0,
|
||||||
|
noArea = 0;
|
||||||
|
const indices = this.geom.indices; //获取顶点索引数据
|
||||||
|
if (!this.geom || !this.geom.attributes || !this.geom.attributes.position) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const positions = this.geom.attributes.position.values;
|
||||||
|
for (let index = 0; index < indices.length; index += 3) {
|
||||||
|
const pos0 = this.returnPosition(positions, indices[index]);
|
||||||
|
const pos1 = this.returnPosition(positions, indices[index + 1]);
|
||||||
|
const pos2 = this.returnPosition(positions, indices[index + 2]);
|
||||||
|
let entity = this.viewer.entities.add({
|
||||||
|
name: "三角面",
|
||||||
|
polygon: {
|
||||||
|
hierarchy: [pos0.heightPos, pos1.heightPos, pos2.heightPos],
|
||||||
|
perPositionHeight: true,
|
||||||
|
material: Cesium.Color.fromRandom(),
|
||||||
|
extrudedHeight: this.height,
|
||||||
|
outline: true,
|
||||||
|
outlineColor: Cesium.Color.BLACK,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
this.entities.push(entity)
|
||||||
|
//水平状态下三角形面积
|
||||||
|
const area = this.computeArea4Triangle(
|
||||||
|
pos0.noHeightPos,
|
||||||
|
pos1.noHeightPos,
|
||||||
|
pos2.noHeightPos
|
||||||
|
);
|
||||||
|
//计算三个点的均高
|
||||||
|
const height = (pos0.height + pos1.height + pos2.height) / 3;
|
||||||
|
if (height < this.height) {
|
||||||
|
// 需要填方的部分
|
||||||
|
fillArea += area;
|
||||||
|
const volume = area * (this.height - height);
|
||||||
|
fillVolume += volume;
|
||||||
|
} else if (height == this.height) {
|
||||||
|
noArea += area;
|
||||||
|
} else {
|
||||||
|
// 需要挖方的部分
|
||||||
|
cutArea += area;
|
||||||
|
const volume = area * (height - this.height);
|
||||||
|
cutVolume += volume;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const allArea = cutArea + fillArea + noArea;
|
||||||
|
// this.result = {
|
||||||
|
// allArea,
|
||||||
|
// cutArea,
|
||||||
|
// cutVolume,
|
||||||
|
// fillArea,
|
||||||
|
// fillVolume,
|
||||||
|
// noArea,
|
||||||
|
// };
|
||||||
|
this.result.allArea = allArea
|
||||||
|
this.result.cutArea = cutArea
|
||||||
|
this.result.cutVolume = cutVolume
|
||||||
|
this.result.fillArea = fillArea
|
||||||
|
this.result.fillVolume = fillVolume
|
||||||
|
this.result.noArea = noArea
|
||||||
|
return this.result;
|
||||||
|
}
|
||||||
|
computeCentroid4Polygon(positions) {
|
||||||
|
let x = [],
|
||||||
|
y = [];
|
||||||
|
let allX = 0,
|
||||||
|
allY = 0;
|
||||||
|
for (let i = 0; i < positions.length; i++) {
|
||||||
|
let cartographic = Cesium.Cartographic.fromCartesian(positions[i]);
|
||||||
|
allX += cartographic.longitude;
|
||||||
|
allY += cartographic.latitude;
|
||||||
|
x.push(cartographic.longitude);
|
||||||
|
y.push(cartographic.latitude);
|
||||||
|
}
|
||||||
|
let centroidx = allX / positions.length;
|
||||||
|
let centroidy = allY / positions.length;
|
||||||
|
const Cartographic = new Cesium.Cartographic(centroidx, centroidy);
|
||||||
|
return Cesium.Cartesian3.fromRadians(
|
||||||
|
Cartographic.longitude,
|
||||||
|
Cartographic.latitude,
|
||||||
|
this.maxHeigh + 30
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 海伦公式求取三角形面积
|
||||||
|
* @param {*} pos1
|
||||||
|
* @param {*} pos2
|
||||||
|
* @param {*} pos3
|
||||||
|
* @returns 三角形面积㎡
|
||||||
|
*/
|
||||||
|
computeArea4Triangle(pos1, pos2, pos3) {
|
||||||
|
let a = Cesium.Cartesian3.distance(pos1, pos2);
|
||||||
|
let b = Cesium.Cartesian3.distance(pos2, pos3);
|
||||||
|
let c = Cesium.Cartesian3.distance(pos3, pos1);
|
||||||
|
let S = (a + b + c) / 2;
|
||||||
|
return Math.sqrt(S * (S - a) * (S - b) * (S - c));
|
||||||
|
}
|
||||||
|
returnPosition(positions, index) {
|
||||||
|
let cartesian = new Cesium.Cartesian3(
|
||||||
|
positions[index * 3],
|
||||||
|
positions[index * 3 + 1],
|
||||||
|
positions[index * 3 + 2]
|
||||||
|
);
|
||||||
|
let cartographic = Cesium.Cartographic.fromCartesian(cartesian);
|
||||||
|
let height = this.viewer.scene.sampleHeightSupported
|
||||||
|
? this.viewer.scene.sampleHeight(cartographic)
|
||||||
|
: this.viewer.scene.globe.getHeight(cartographic);
|
||||||
|
if (height > this.maxHeigh) {
|
||||||
|
this.maxHeigh = height;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
heightPos: Cesium.Cartesian3.fromRadians(
|
||||||
|
cartographic.longitude,
|
||||||
|
cartographic.latitude,
|
||||||
|
height
|
||||||
|
),
|
||||||
|
noHeightPos: Cesium.Cartesian3.fromRadians(
|
||||||
|
cartographic.longitude,
|
||||||
|
cartographic.latitude,
|
||||||
|
0
|
||||||
|
),
|
||||||
|
height: height,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static async EditBox(that) {
|
||||||
|
if (that._DialogObject && that._DialogObject.close) {
|
||||||
|
that._DialogObject.close()
|
||||||
|
that._DialogObject = null
|
||||||
|
}
|
||||||
|
that._DialogObject = await new Dialog(that.sdk.viewer._container, {
|
||||||
|
title: '土方分析', left: '180px', top: '100px',
|
||||||
|
closeCallBack: () => {
|
||||||
|
that.clean()
|
||||||
|
that.Dialog.closeCallBack && that.Dialog.closeCallBack()
|
||||||
|
},
|
||||||
|
})
|
||||||
|
await that._DialogObject.init()
|
||||||
|
let contentElm = document.createElement('div');
|
||||||
|
contentElm.innerHTML = html()
|
||||||
|
that._DialogObject.contentAppChild(contentElm)
|
||||||
|
that._DialogObject._element.body.className = that._DialogObject._element.body.className + ' cut-fill'
|
||||||
|
|
||||||
|
// 高度值
|
||||||
|
let e_height = contentElm.querySelector("input[name='height']")
|
||||||
|
e_height.value = that.height
|
||||||
|
e_height.addEventListener('blur', (e) => {
|
||||||
|
let value = e.target.value
|
||||||
|
if (e.data != '.' && (e.data != '-' || e.target.value)) {
|
||||||
|
value = Number(value)
|
||||||
|
if ((e.target.max) && value > Number(e.target.max)) {
|
||||||
|
value = Number(e.target.max)
|
||||||
|
}
|
||||||
|
if ((e.target.min) && value < Number(e.target.min)) {
|
||||||
|
value = Number(e.target.min)
|
||||||
|
}
|
||||||
|
e_height.value = value
|
||||||
|
that.height = e_height.value;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 精度值
|
||||||
|
let e_precision = contentElm.querySelector("input[name='precision']")
|
||||||
|
e_precision.value = that.precision
|
||||||
|
e_precision.addEventListener('blur', (e) => {
|
||||||
|
let value = Number(e.target.value)
|
||||||
|
if ((e.target.max) && value > Number(e.target.max)) {
|
||||||
|
value = Number(e.target.max)
|
||||||
|
}
|
||||||
|
if ((e.target.min) && value < Number(e.target.min)) {
|
||||||
|
value = Number(e.target.min)
|
||||||
|
}
|
||||||
|
e_precision.value = value
|
||||||
|
that.precision = e_precision.value;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 总分析面积
|
||||||
|
let e_allArea = contentElm.querySelector("span[name='allArea']")
|
||||||
|
e_allArea.innerHTML = that.result.allArea || 0
|
||||||
|
Object.defineProperty(that.result, 'allArea', {
|
||||||
|
get() {
|
||||||
|
return e_allArea.innerHTML
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
e_allArea.innerHTML = Number(value.toFixed(4))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// 填方面积
|
||||||
|
let e_fillArea = contentElm.querySelector("span[name='fillArea']")
|
||||||
|
e_fillArea.innerHTML = that.result.fillArea || 0
|
||||||
|
Object.defineProperty(that.result, 'fillArea', {
|
||||||
|
get() {
|
||||||
|
return e_fillArea.innerHTML
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
e_fillArea.innerHTML = Number(value.toFixed(4))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 填方体积
|
||||||
|
let e_fillVolume = contentElm.querySelector("span[name='fillVolume']")
|
||||||
|
e_fillVolume.innerHTML = that.result.fillVolume || 0
|
||||||
|
Object.defineProperty(that.result, 'fillVolume', {
|
||||||
|
get() {
|
||||||
|
return e_fillVolume.innerHTML
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
e_fillVolume.innerHTML = Number(value.toFixed(4))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 挖方面积
|
||||||
|
let e_cutArea = contentElm.querySelector("span[name='cutArea']")
|
||||||
|
e_cutArea.innerHTML = that.result.cutArea || 0
|
||||||
|
Object.defineProperty(that.result, 'cutArea', {
|
||||||
|
get() {
|
||||||
|
return e_cutArea.innerHTML
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
e_cutArea.innerHTML = Number(value.toFixed(4))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 挖方体积
|
||||||
|
let e_cutVolume = contentElm.querySelector("span[name='cutVolume']")
|
||||||
|
e_cutVolume.innerHTML = that.result.cutVolume || 0
|
||||||
|
Object.defineProperty(that.result, 'cutVolume', {
|
||||||
|
get() {
|
||||||
|
return e_cutVolume.innerHTML
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
e_cutVolume.innerHTML = Number(value.toFixed(4))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 无须填挖面积
|
||||||
|
let e_noArea = contentElm.querySelector("span[name='noArea']")
|
||||||
|
e_noArea.innerHTML = that.result.noArea || 0
|
||||||
|
Object.defineProperty(that.result, 'noArea', {
|
||||||
|
get() {
|
||||||
|
return e_noArea.innerHTML
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
e_noArea.innerHTML = Number(value.toFixed(4))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
let newDivBtn = contentElm.getElementsByClassName('draw-btn')[0];
|
||||||
|
newDivBtn.addEventListener('click', () => {
|
||||||
|
that.create()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
clean() {
|
||||||
|
this.Draw && this.Draw.end()
|
||||||
|
for (let i = 0; i < this.entities.length; i++) {
|
||||||
|
this.viewer.entities.remove(this.entities[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
destroy() {
|
||||||
|
this.clean()
|
||||||
|
if (this._DialogObject && this._DialogObject.close) {
|
||||||
|
this._DialogObject.close()
|
||||||
|
this._DialogObject = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export default CutFillAnalysis;
|
||||||
483
src/Obj/Analysis/Flat/index.js
Normal file
483
src/Obj/Analysis/Flat/index.js
Normal file
@ -0,0 +1,483 @@
|
|||||||
|
import Base from "../../Base/index";
|
||||||
|
import Dialog from '../../../BaseDialog'
|
||||||
|
import { setActiveViewer, closeRotateAround, closeViewFollow} from '../../../Global/global'
|
||||||
|
|
||||||
|
let FlatList = {}
|
||||||
|
class Flat extends Base {
|
||||||
|
/**
|
||||||
|
* @constructor
|
||||||
|
* @description 模型压平
|
||||||
|
* @param sdk
|
||||||
|
* @param {Cesium.Cesium3DTileset} tileset 三维模型
|
||||||
|
* @param {Object} options
|
||||||
|
* @param {string} attr.id id
|
||||||
|
* @param {Cesium.Cartesian3[]} attr.positions 压平面坐标
|
||||||
|
*/
|
||||||
|
constructor(sdk, tileset, options = {}, _Dialog = {}) {
|
||||||
|
super(sdk)
|
||||||
|
if (!tileset || !this.sdk || !this.sdk.viewer) return;
|
||||||
|
this.options = { ...options }
|
||||||
|
this.options.id = options.id || this.randomString()
|
||||||
|
this.options.name = options.name || '压平面'
|
||||||
|
this.options.positions = options.positions || []
|
||||||
|
this.options.show = (options.show || options.show === false) ? options.show : true
|
||||||
|
this.tileset = tileset;
|
||||||
|
this.Dialog = _Dialog
|
||||||
|
|
||||||
|
if (!this.options.height && this.options.height !== 0) {
|
||||||
|
let height = this.options.positions[0].alt
|
||||||
|
for (let i = 0; i < this.options.positions.length; i++) {
|
||||||
|
if (height > this.options.positions[i].alt) {
|
||||||
|
height = this.options.positions[i].alt
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.options.height = height
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FlatList[this.tileset.id]) {
|
||||||
|
FlatList[this.tileset.id].push({ ...this.options })
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
FlatList[this.tileset.id] = [{ ...this.options }]
|
||||||
|
}
|
||||||
|
|
||||||
|
this.center = tileset.boundingSphere.center.clone();
|
||||||
|
this.center84 = this.cartesian3Towgs84(this.center, this.sdk.viewer)
|
||||||
|
this.matrix = Cesium.Transforms.eastNorthUpToFixedFrame(this.center.clone());
|
||||||
|
this.localMatrix = Cesium.Matrix4.inverse(this.matrix, new Cesium.Matrix4());
|
||||||
|
// this.entity = {
|
||||||
|
// id: this.options.id
|
||||||
|
// }
|
||||||
|
this.addFlat()
|
||||||
|
// Flat.createPolygon(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
get show() {
|
||||||
|
return this.options.show
|
||||||
|
}
|
||||||
|
|
||||||
|
set show(v) {
|
||||||
|
this.options.show = v
|
||||||
|
for (let i = 0; i < FlatList[this.tileset.id].length; i++) {
|
||||||
|
if (FlatList[this.tileset.id][i].id == this.options.id) {
|
||||||
|
FlatList[this.tileset.id][i].show = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.addFlat()
|
||||||
|
}
|
||||||
|
|
||||||
|
get height() {
|
||||||
|
return this.options.height
|
||||||
|
}
|
||||||
|
|
||||||
|
set height(v) {
|
||||||
|
this.options.height = Number(v)
|
||||||
|
for (let i = 0; i < FlatList[this.tileset.id].length; i++) {
|
||||||
|
if (FlatList[this.tileset.id][i].id == this.options.id) {
|
||||||
|
FlatList[this.tileset.id][i].height = Number(v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.addFlat()
|
||||||
|
}
|
||||||
|
|
||||||
|
get name() {
|
||||||
|
return this.options.name
|
||||||
|
}
|
||||||
|
|
||||||
|
set name(v) {
|
||||||
|
this.options.name = v
|
||||||
|
for (let i = 0; i < FlatList[this.tileset.id].length; i++) {
|
||||||
|
if (FlatList[this.tileset.id][i].id == this.options.id) {
|
||||||
|
FlatList[this.tileset.id][i].name = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
addFlat() {
|
||||||
|
let localPositionsArr = []
|
||||||
|
for (let i = 0; i < FlatList[this.tileset.id].length; i++) {
|
||||||
|
let item = FlatList[this.tileset.id][i];
|
||||||
|
if (item.show) {
|
||||||
|
const positions = item.positions;
|
||||||
|
let height = item.height
|
||||||
|
let fromDegreesArray = []
|
||||||
|
for (let i = 0; i < positions.length; i++) {
|
||||||
|
fromDegreesArray.push(positions[i].lng, positions[i].lat)
|
||||||
|
}
|
||||||
|
FlatList[this.tileset.id][i].flatHeight = height - this.center84.alt
|
||||||
|
let localCoor = this.cartesiansToLocal(Cesium.Cartesian3.fromDegreesArray(fromDegreesArray));
|
||||||
|
localPositionsArr.push(localCoor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const funstr = this.getIsinPolygonFun(localPositionsArr);
|
||||||
|
let str = ``;
|
||||||
|
for (let i = 0; i < localPositionsArr.length; i++) {
|
||||||
|
const coors = localPositionsArr[i];
|
||||||
|
const n = coors.length;
|
||||||
|
let instr = ``;
|
||||||
|
coors.forEach((coordinate, index) => {
|
||||||
|
instr += `points_${n}[${index}] = vec2(${coordinate[0]}, ${coordinate[1]});\n`;
|
||||||
|
})
|
||||||
|
str += `
|
||||||
|
${instr}
|
||||||
|
if(isPointInPolygon_${n}(position2D)){
|
||||||
|
vec4 tileset_local_position_transformed = vec4(tileset_local_position.x, tileset_local_position.y, ground_z + ${FlatList[this.tileset.id][i].flatHeight}, 1.0);
|
||||||
|
vec4 model_local_position_transformed = czm_inverseModel * u_tileset_localToWorldMatrix * tileset_local_position_transformed;
|
||||||
|
|
||||||
|
vsOutput.positionMC.xy = model_local_position_transformed.xy;
|
||||||
|
vsOutput.positionMC.z = model_local_position_transformed.z+ modelMC.z*0.002;
|
||||||
|
return;
|
||||||
|
}`;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
this.updateShader(funstr, str);
|
||||||
|
}
|
||||||
|
|
||||||
|
// static createPolygon(that) {
|
||||||
|
// let color = '#ffffff'
|
||||||
|
// let linecolor = '#000000'
|
||||||
|
// let positions = that.options.positions
|
||||||
|
// let fromDegreesArray = []
|
||||||
|
// for (let i = 0; i < positions.length; i++) {
|
||||||
|
// fromDegreesArray.push(positions[i].lng, positions[i].lat, that.options.height)
|
||||||
|
// }
|
||||||
|
// that.positions = Cesium.Cartesian3.fromDegreesArrayHeights(fromDegreesArray)
|
||||||
|
// that.entity = that.sdk.viewer.entities.add({
|
||||||
|
// show: that.options.show,
|
||||||
|
// id: that.options.id,
|
||||||
|
// polyline: {
|
||||||
|
// positions: [...that.positions, that.positions[0], that.positions[1]],
|
||||||
|
// width: 2,
|
||||||
|
// material: Cesium.Color.fromCssColorString(linecolor),
|
||||||
|
// depthFailMaterial: new Cesium.PolylineDashMaterialProperty({
|
||||||
|
// color: Cesium.Color.YELLOW
|
||||||
|
// }),
|
||||||
|
// clampToGround: false,
|
||||||
|
// zIndex: that.sdk._entityZIndex
|
||||||
|
// },
|
||||||
|
// })
|
||||||
|
// that.sdk._entityZIndex++
|
||||||
|
// }
|
||||||
|
|
||||||
|
remove() {
|
||||||
|
FlatList[this.tileset.id] = FlatList[this.tileset.id].filter((attr) => {
|
||||||
|
return attr.id != this.options.id;
|
||||||
|
})
|
||||||
|
|
||||||
|
let localPositionsArr = [];
|
||||||
|
for (let i = 0; i < FlatList[this.tileset.id].length; i++) {
|
||||||
|
let item = FlatList[this.tileset.id][i];
|
||||||
|
if (item.show) {
|
||||||
|
const positions = item.positions;
|
||||||
|
let height = item.height
|
||||||
|
let fromDegreesArray = []
|
||||||
|
for (let i = 0; i < positions.length; i++) {
|
||||||
|
fromDegreesArray.push(positions[i].lng, positions[i].lat)
|
||||||
|
}
|
||||||
|
FlatList[this.tileset.id][i].flatHeight = height - this.center84.alt
|
||||||
|
let localCoor = this.cartesiansToLocal(Cesium.Cartesian3.fromDegreesArray(fromDegreesArray));
|
||||||
|
localPositionsArr.push(localCoor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const funstr = this.getIsinPolygonFun(localPositionsArr);
|
||||||
|
let str = ``;
|
||||||
|
for (let i = 0; i < localPositionsArr.length; i++) {
|
||||||
|
const coors = localPositionsArr[i];
|
||||||
|
const n = coors.length;
|
||||||
|
let instr = ``;
|
||||||
|
coors.forEach((coordinate, index) => {
|
||||||
|
instr += `points_${n}[${index}] = vec2(${coordinate[0]}, ${coordinate[1]});\n`;
|
||||||
|
})
|
||||||
|
str += `
|
||||||
|
${instr}
|
||||||
|
if(isPointInPolygon_${n}(position2D)){
|
||||||
|
vec4 tileset_local_position_transformed = vec4(tileset_local_position.x, tileset_local_position.y, ground_z + ${FlatList[this.tileset.id][i].flatHeight}, 1.0);
|
||||||
|
vec4 model_local_position_transformed = czm_inverseModel * u_tileset_localToWorldMatrix * tileset_local_position_transformed;
|
||||||
|
vsOutput.positionMC.xy = model_local_position_transformed.xy;
|
||||||
|
vsOutput.positionMC.z = model_local_position_transformed.z+ modelMC.z*0.002;
|
||||||
|
return;
|
||||||
|
}`;
|
||||||
|
|
||||||
|
}
|
||||||
|
this.updateShader(funstr, str);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 根据数组长度,构建 判断点是否在面内 的压平函数
|
||||||
|
getIsinPolygonFun(polygons) {
|
||||||
|
let pmap = polygons.map((polygon) => polygon.length);
|
||||||
|
let uniqueArray = this.getUniqueArray(pmap);
|
||||||
|
let str = ``;
|
||||||
|
uniqueArray.forEach(length => {
|
||||||
|
str += `
|
||||||
|
vec2 points_${length}[${length}];
|
||||||
|
bool isPointInPolygon_${length}(vec2 point){
|
||||||
|
int nCross = 0; // 交点数
|
||||||
|
const int n = ${length};
|
||||||
|
for(int i = 0; i < n; i++){
|
||||||
|
vec2 p1 = points_${length}[i];
|
||||||
|
vec2 p2 = points_${length}[int(mod(float(i+1),float(n)))];
|
||||||
|
if(p1[1] == p2[1]){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(point[1] < min(p1[1], p2[1])){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(point[1] >= max(p1[1], p2[1])){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
float x = p1[0] + ((point[1] - p1[1]) * (p2[0] - p1[0])) / (p2[1] - p1[1]);
|
||||||
|
if(x > point[0]){
|
||||||
|
nCross++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return int(mod(float(nCross), float(2))) == 1;
|
||||||
|
}
|
||||||
|
`
|
||||||
|
})
|
||||||
|
return str
|
||||||
|
}
|
||||||
|
|
||||||
|
updateShader(vtx1, vtx2) {
|
||||||
|
let flatCustomShader = new Cesium.CustomShader({
|
||||||
|
uniforms: {
|
||||||
|
u_tileset_localToWorldMatrix: {
|
||||||
|
type: Cesium.UniformType.MAT4,
|
||||||
|
value: this.matrix,
|
||||||
|
},
|
||||||
|
u_tileset_worldToLocalMatrix: {
|
||||||
|
type: Cesium.UniformType.MAT4,
|
||||||
|
value: this.localMatrix,
|
||||||
|
},
|
||||||
|
u_flatHeight: {
|
||||||
|
type: Cesium.UniformType.FLOAT,
|
||||||
|
value: this.flatHeight,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
vertexShaderText: `
|
||||||
|
// 所有isPointInPolygon函数
|
||||||
|
${vtx1}
|
||||||
|
void vertexMain(VertexInput vsInput, inout czm_modelVertexOutput vsOutput){
|
||||||
|
vec3 modelMC = vsInput.attributes.positionMC;
|
||||||
|
vec4 model_local_position = vec4(modelMC.x, modelMC.y, modelMC.z, 1.0);
|
||||||
|
vec4 tileset_local_position = u_tileset_worldToLocalMatrix * czm_model * model_local_position;
|
||||||
|
vec2 position2D = vec2(tileset_local_position.x,tileset_local_position.y);
|
||||||
|
float ground_z = 0.0;
|
||||||
|
// 多个多边形区域
|
||||||
|
${vtx2}
|
||||||
|
}`,
|
||||||
|
});
|
||||||
|
this.tileset.customShader = flatCustomShader;
|
||||||
|
this.sdk.viewer.scene.requestRender();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// 数组去重,不能处理嵌套的数组
|
||||||
|
getUniqueArray = (arr) => {
|
||||||
|
return arr.filter(function (item, index, arr) {
|
||||||
|
//当前元素,在原始数组中的第一个索引==当前索引值,否则返回当前元素
|
||||||
|
return arr.indexOf(item, 0) === index;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 世界坐标转数组局部坐标
|
||||||
|
cartesiansToLocal(positions) {
|
||||||
|
let arr = [];
|
||||||
|
for (let i = 0; i < positions.length; i++) {
|
||||||
|
let position = positions[i];
|
||||||
|
let localp = Cesium.Matrix4.multiplyByPoint(
|
||||||
|
this.localMatrix,
|
||||||
|
position.clone(),
|
||||||
|
new Cesium.Cartesian3()
|
||||||
|
)
|
||||||
|
arr.push([localp.x, localp.y]);
|
||||||
|
}
|
||||||
|
return arr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 飞到
|
||||||
|
*/
|
||||||
|
async flyTo() {
|
||||||
|
setActiveViewer(0)
|
||||||
|
closeRotateAround(this.sdk)
|
||||||
|
closeViewFollow(this.sdk)
|
||||||
|
|
||||||
|
if (this.options.customView && this.options.customView.relativePosition && this.options.customView.orientation) {
|
||||||
|
let orientation = {
|
||||||
|
heading: Cesium.Math.toRadians(this.options.customView.orientation.heading || 0.0),
|
||||||
|
pitch: Cesium.Math.toRadians(this.options.customView.orientation.pitch || -60.0),
|
||||||
|
roll: Cesium.Math.toRadians(this.options.customView.orientation.roll || 0.0)
|
||||||
|
}
|
||||||
|
|
||||||
|
let lng = this.options.customView.relativePosition.lng
|
||||||
|
let lat = this.options.customView.relativePosition.lat
|
||||||
|
let alt = this.options.customView.relativePosition.alt
|
||||||
|
let destination = Cesium.Cartesian3.fromDegrees(lng, lat, alt)
|
||||||
|
|
||||||
|
let position = { lng: 0, lat: 0 }
|
||||||
|
if (this.options.position) {
|
||||||
|
position = { ...this.options.position }
|
||||||
|
}
|
||||||
|
else if (this.options.positions) {
|
||||||
|
position = { ...this.options.positions[0] }
|
||||||
|
}
|
||||||
|
else if (this.options.line && this.options.line.positions) {
|
||||||
|
position = { ...this.options.line.positions[0] }
|
||||||
|
}
|
||||||
|
else if (this.options.center) {
|
||||||
|
position = { ...this.options.center }
|
||||||
|
}
|
||||||
|
else if (this.options.start) {
|
||||||
|
position = { ...this.options.start }
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (this.options.hasOwnProperty('lng')) {
|
||||||
|
position.lng = this.options.lng
|
||||||
|
}
|
||||||
|
if (this.options.hasOwnProperty('lat')) {
|
||||||
|
position.lat = this.options.lat
|
||||||
|
}
|
||||||
|
if (this.options.hasOwnProperty('alt')) {
|
||||||
|
position.alt = this.options.alt
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 如果没有高度值,则获取紧贴高度计算
|
||||||
|
if (!position.hasOwnProperty('alt')) {
|
||||||
|
position.alt = await this.getClampToHeight(position)
|
||||||
|
}
|
||||||
|
lng = this.options.customView.relativePosition.lng + position.lng
|
||||||
|
lat = this.options.customView.relativePosition.lat + position.lat
|
||||||
|
alt = this.options.customView.relativePosition.alt + position.alt
|
||||||
|
destination = Cesium.Cartesian3.fromDegrees(lng, lat, alt)
|
||||||
|
this.sdk.viewer.camera.flyTo({
|
||||||
|
destination: destination,
|
||||||
|
orientation: orientation
|
||||||
|
})
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
let positionArray = []
|
||||||
|
for (let i = 0; i < this.options.positions.length; i++) {
|
||||||
|
let a = Cesium.Cartesian3.fromDegrees(this.options.positions[i].lng, this.options.positions[i].lat, this.center84.alt)
|
||||||
|
positionArray.push(a.x, a.y, a.z)
|
||||||
|
}
|
||||||
|
let BoundingSphere = Cesium.BoundingSphere.fromVertices(positionArray)
|
||||||
|
this.sdk.viewer.camera.flyToBoundingSphere(BoundingSphere, {
|
||||||
|
offset: {
|
||||||
|
heading: Cesium.Math.toRadians(0.0),
|
||||||
|
pitch: Cesium.Math.toRadians(-90.0),
|
||||||
|
roll: Cesium.Math.toRadians(0.0)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async edit(state) {
|
||||||
|
if (state) {
|
||||||
|
this.originalOptions = this.deepCopyObj(this.options)
|
||||||
|
this._DialogObject = await new Dialog(this.sdk.viewer._container, {
|
||||||
|
title: '压平面属性', left: '180px', top: '100px',
|
||||||
|
removeCallBack: () => {
|
||||||
|
this.Dialog.removeCallBack && this.Dialog.removeCallBack()
|
||||||
|
},
|
||||||
|
closeCallBack: () => {
|
||||||
|
this.reset()
|
||||||
|
this.Dialog.closeCallBack && this.Dialog.closeCallBack()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
await this._DialogObject.init()
|
||||||
|
// 内容部分
|
||||||
|
let contentElm = document.createElement('div');
|
||||||
|
contentElm.innerHTML = `
|
||||||
|
<span class="custom-divider"></span>
|
||||||
|
<div class="div-item">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<span class="label" style="width: 56px;flex: 0 0 56px;">名称</span>
|
||||||
|
<input class="input input-name">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<span class="label" style="width: 56px;flex: 0 0 56px;">压平高度</span>
|
||||||
|
<div class="input-number input-number-unit-1">
|
||||||
|
<input class="input flat-height" type="number" title="" min="-9999999" max="999999999">
|
||||||
|
<span class="unit">m</span>
|
||||||
|
<span class="arrow"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
this._DialogObject.contentAppChild(contentElm)
|
||||||
|
let name_elm = contentElm.getElementsByClassName('input-name')[0]
|
||||||
|
name_elm.value = this.options.name
|
||||||
|
name_elm.addEventListener('input', () => {
|
||||||
|
this.name = name_elm.value
|
||||||
|
})
|
||||||
|
|
||||||
|
let height_elm = contentElm.getElementsByClassName('flat-height')[0]
|
||||||
|
height_elm.value = this.options.height
|
||||||
|
height_elm.addEventListener('input', () => {
|
||||||
|
this.height = Number(height_elm.value)
|
||||||
|
this.addFlat()
|
||||||
|
})
|
||||||
|
|
||||||
|
let confirmElm = document.createElement('button');
|
||||||
|
confirmElm.className = 'btn'
|
||||||
|
confirmElm.innerHTML = '确认'
|
||||||
|
this._DialogObject.footAppChild(confirmElm)
|
||||||
|
confirmElm.addEventListener('click', () => {
|
||||||
|
if (!this.options.name) {
|
||||||
|
this.options.name = '压平面'
|
||||||
|
}
|
||||||
|
this.originalOptions = this.deepCopyObj(this.options)
|
||||||
|
this._DialogObject.close()
|
||||||
|
this.Dialog.confirmCallBack && this.Dialog.confirmCallBack(this.options)
|
||||||
|
})
|
||||||
|
|
||||||
|
// let flatElm = document.createElement('button');
|
||||||
|
// flatElm.className = 'btn'
|
||||||
|
// flatElm.innerHTML = '<svg class="icon-edit"><use xlink:href="#yj-icon-edit"></use></svg>二次编辑'
|
||||||
|
// flatElm.style.width = 'auto'
|
||||||
|
// flatElm.style.position = 'absolute'
|
||||||
|
// flatElm.style.left = '10px'
|
||||||
|
// this._DialogObject.footAppChild(flatElm)
|
||||||
|
// flatElm.addEventListener('click', () => {
|
||||||
|
// console.log('二次编辑')
|
||||||
|
// })
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (this._DialogObject && this._DialogObject.close) {
|
||||||
|
this._DialogObject.close()
|
||||||
|
this._DialogObject = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
reset() {
|
||||||
|
this.options = this.deepCopyObj(this.originalOptions)
|
||||||
|
this.name = this.options.name
|
||||||
|
this.height = this.options.height
|
||||||
|
this.addFlat()
|
||||||
|
}
|
||||||
|
|
||||||
|
flatEdit(state) {
|
||||||
|
if (state) {
|
||||||
|
let positions = that.options.positions
|
||||||
|
let fromDegreesArray = []
|
||||||
|
for (let i = 0; i < positions.length; i++) {
|
||||||
|
fromDegreesArray.push(positions[i].lng, positions[i].lat, FlatList[this.tileset.id])
|
||||||
|
}
|
||||||
|
that.positions = Cesium.Cartesian3.fromDegreesArrayHeights(fromDegreesArray)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
flicker() { }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Flat;
|
||||||
227
src/Obj/Analysis/Flat/index1.js
Normal file
227
src/Obj/Analysis/Flat/index1.js
Normal file
@ -0,0 +1,227 @@
|
|||||||
|
import Tools from "../../../Tools";
|
||||||
|
class Flat extends Tools {
|
||||||
|
/**
|
||||||
|
* @constructor
|
||||||
|
* @description 模型压平
|
||||||
|
* @param sdk
|
||||||
|
* @param {Cesium.Cesium3DTileset} tileset 三维模型
|
||||||
|
* @param {Object} options
|
||||||
|
* @param {string} attr.id id
|
||||||
|
* @param {Number} options.height 压平高度
|
||||||
|
* @param {Cesium.Cartesian3[]} attr.positions 压平面坐标
|
||||||
|
*/
|
||||||
|
constructor(sdk, tileset, options = {}) {
|
||||||
|
super(sdk)
|
||||||
|
if (!tileset) return;
|
||||||
|
this.options = { ...options }
|
||||||
|
this.options.id = options.id || this.randomString()
|
||||||
|
this.options.positions = options.positions || []
|
||||||
|
this.tileset = tileset;
|
||||||
|
this.height = options.height;
|
||||||
|
this.center = tileset.boundingSphere.center.clone();
|
||||||
|
this.matrix = Cesium.Transforms.eastNorthUpToFixedFrame(this.center.clone());
|
||||||
|
this.localMatrix = Cesium.Matrix4.inverse(this.matrix, new Cesium.Matrix4());
|
||||||
|
// 多面的坐标数组
|
||||||
|
this.regionList = [];
|
||||||
|
// 多个面坐标转为局部模型坐标
|
||||||
|
this.localPositionsArr = [];
|
||||||
|
this.addRegion()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加压平面
|
||||||
|
* @param {Object} attr 参数
|
||||||
|
* @param {Cesium.Cartesian3[]} attr.positions 压平面坐标
|
||||||
|
* @param {Number} attr.height 压平深度,当前不支持单独设置
|
||||||
|
* @param {Number} attr.id 唯一标识
|
||||||
|
*/
|
||||||
|
addRegion(attr) {
|
||||||
|
// let { positions, height, id } = attr || {};
|
||||||
|
// // this.flatHeight = height;
|
||||||
|
// if (!id) id = (new Date()).getTime() + "" + Number(Math.random() * 1000).toFixed(0);
|
||||||
|
// this.regionList.push(attr);
|
||||||
|
// for (let i = 0; i < this.regionList.length; i++) {
|
||||||
|
// let item = this.regionList[i];
|
||||||
|
// const positions = item.positions;
|
||||||
|
// let localCoor = this.cartesiansToLocal(positions);
|
||||||
|
// this.localPositionsArr.push(localCoor);
|
||||||
|
// }
|
||||||
|
let positions = this.options.positions
|
||||||
|
let fromDegreesArray = []
|
||||||
|
for (let i = 0; i < positions.length; i++) {
|
||||||
|
fromDegreesArray.push(positions[i].lng, positions[i].lat)
|
||||||
|
}
|
||||||
|
let localCoor = this.cartesiansToLocal(Cesium.Cartesian3.fromDegreesArray(fromDegreesArray));
|
||||||
|
this.localPositionsArr.push(localCoor);
|
||||||
|
|
||||||
|
const funstr = this.getIsinPolygonFun(this.localPositionsArr);
|
||||||
|
let str = ``;
|
||||||
|
for (let i = 0; i < this.localPositionsArr.length; i++) {
|
||||||
|
const coors = this.localPositionsArr[i];
|
||||||
|
const n = coors.length;
|
||||||
|
let instr = ``;
|
||||||
|
coors.forEach((coordinate, index) => {
|
||||||
|
instr += `points_${n}[${index}] = vec2(${coordinate[0]}, ${coordinate[1]});\n`;
|
||||||
|
})
|
||||||
|
str += `
|
||||||
|
${instr}
|
||||||
|
if(isPointInPolygon_${n}(position2D)){
|
||||||
|
vec4 tileset_local_position_transformed = vec4(tileset_local_position.x, tileset_local_position.y, ground_z, 1.0);
|
||||||
|
vec4 model_local_position_transformed = czm_inverseModel * u_tileset_localToWorldMatrix * tileset_local_position_transformed;
|
||||||
|
vsOutput.positionMC.xy = model_local_position_transformed.xy;
|
||||||
|
vsOutput.positionMC.z = model_local_position_transformed.z+ modelMC.z*0.002;
|
||||||
|
return;
|
||||||
|
}`;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
this.updateShader(funstr, str);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据id删除压平的面
|
||||||
|
* @param {String} id 唯一标识
|
||||||
|
*/
|
||||||
|
removeRegionById(id) {
|
||||||
|
if (!id) return;
|
||||||
|
|
||||||
|
this.regionList = this.regionList.filter((attr) => {
|
||||||
|
return attr.id != id;
|
||||||
|
})
|
||||||
|
|
||||||
|
this.localPositionsArr = [];
|
||||||
|
for (let i = 0; i < this.regionList.length; i++) {
|
||||||
|
let item = this.regionList[i];
|
||||||
|
const positions = item.positions;
|
||||||
|
let localCoor = this.cartesiansToLocal(positions);
|
||||||
|
this.localPositionsArr.push(localCoor);
|
||||||
|
}
|
||||||
|
|
||||||
|
const funstr = this.getIsinPolygonFun(this.localPositionsArr);
|
||||||
|
let str = ``;
|
||||||
|
for (let i = 0; i < this.localPositionsArr.length; i++) {
|
||||||
|
const coors = this.localPositionsArr[i];
|
||||||
|
const n = coors.length;
|
||||||
|
let instr = ``;
|
||||||
|
coors.forEach((coordinate, index) => {
|
||||||
|
instr += `points_${n}[${index}] = vec2(${coordinate[0]}, ${coordinate[1]});\n`;
|
||||||
|
})
|
||||||
|
str += `
|
||||||
|
${instr}
|
||||||
|
if(isPointInPolygon_${n}(position2D)){
|
||||||
|
vec4 tileset_local_position_transformed = vec4(tileset_local_position.x, tileset_local_position.y, ground_z, 1.0);
|
||||||
|
vec4 model_local_position_transformed = czm_inverseModel * u_tileset_localToWorldMatrix * tileset_local_position_transformed;
|
||||||
|
vsOutput.positionMC.xy = model_local_position_transformed.xy;
|
||||||
|
vsOutput.positionMC.z = model_local_position_transformed.z+ modelMC.z*0.002;
|
||||||
|
return;
|
||||||
|
}`;
|
||||||
|
|
||||||
|
}
|
||||||
|
this.updateShader(funstr, str);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 销毁
|
||||||
|
*/
|
||||||
|
destroy() {
|
||||||
|
this.tileset.customShader = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据数组长度,构建 判断点是否在面内 的压平函数
|
||||||
|
*/
|
||||||
|
getIsinPolygonFun(polygons) {
|
||||||
|
let pmap = polygons.map((polygon) => polygon.length);
|
||||||
|
let uniqueArray = this.getUniqueArray(pmap);
|
||||||
|
let str = ``;
|
||||||
|
uniqueArray.forEach(length => {
|
||||||
|
str += `
|
||||||
|
vec2 points_${length}[${length}];
|
||||||
|
bool isPointInPolygon_${length}(vec2 point){
|
||||||
|
int nCross = 0; // 交点数
|
||||||
|
const int n = ${length};
|
||||||
|
for(int i = 0; i < n; i++){
|
||||||
|
vec2 p1 = points_${length}[i];
|
||||||
|
vec2 p2 = points_${length}[int(mod(float(i+1),float(n)))];
|
||||||
|
if(p1[1] == p2[1]){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(point[1] < min(p1[1], p2[1])){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(point[1] >= max(p1[1], p2[1])){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
float x = p1[0] + ((point[1] - p1[1]) * (p2[0] - p1[0])) / (p2[1] - p1[1]);
|
||||||
|
if(x > point[0]){
|
||||||
|
nCross++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return int(mod(float(nCross), float(2))) == 1;
|
||||||
|
}
|
||||||
|
`
|
||||||
|
})
|
||||||
|
return str
|
||||||
|
}
|
||||||
|
|
||||||
|
updateShader(vtx1, vtx2) {
|
||||||
|
let flatCustomShader = new Cesium.CustomShader({
|
||||||
|
uniforms: {
|
||||||
|
u_tileset_localToWorldMatrix: {
|
||||||
|
type: Cesium.UniformType.MAT4,
|
||||||
|
value: this.matrix,
|
||||||
|
},
|
||||||
|
u_tileset_worldToLocalMatrix: {
|
||||||
|
type: Cesium.UniformType.MAT4,
|
||||||
|
value: this.localMatrix,
|
||||||
|
},
|
||||||
|
u_flatHeight: {
|
||||||
|
type: Cesium.UniformType.FLOAT,
|
||||||
|
value: this.height,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
vertexShaderText: `
|
||||||
|
// 所有isPointInPolygon函数
|
||||||
|
${vtx1}
|
||||||
|
void vertexMain(VertexInput vsInput, inout czm_modelVertexOutput vsOutput){
|
||||||
|
vec3 modelMC = vsInput.attributes.positionMC;
|
||||||
|
vec4 model_local_position = vec4(modelMC.x, modelMC.y, modelMC.z, 1.0);
|
||||||
|
vec4 tileset_local_position = u_tileset_worldToLocalMatrix * czm_model * model_local_position;
|
||||||
|
vec2 position2D = vec2(tileset_local_position.x,tileset_local_position.y);
|
||||||
|
float ground_z = 0.0 + u_flatHeight;
|
||||||
|
// 多个多边形区域
|
||||||
|
${vtx2}
|
||||||
|
}`,
|
||||||
|
});
|
||||||
|
this.tileset.customShader = flatCustomShader;
|
||||||
|
this.sdk.viewer.scene.requestRender();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 数组去重,不能处理嵌套的数组
|
||||||
|
getUniqueArray = (arr) => {
|
||||||
|
return arr.filter(function (item, index, arr) {
|
||||||
|
//当前元素,在原始数组中的第一个索引==当前索引值,否则返回当前元素
|
||||||
|
return arr.indexOf(item, 0) === index;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 世界坐标转数组局部坐标
|
||||||
|
cartesiansToLocal(positions) {
|
||||||
|
let arr = [];
|
||||||
|
for (let i = 0; i < positions.length; i++) {
|
||||||
|
let position = positions[i];
|
||||||
|
let localp = Cesium.Matrix4.multiplyByPoint(
|
||||||
|
this.localMatrix,
|
||||||
|
position.clone(),
|
||||||
|
new Cesium.Cartesian3()
|
||||||
|
)
|
||||||
|
arr.push([localp.x, localp.y]);
|
||||||
|
}
|
||||||
|
return arr;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Flat;
|
||||||
8
src/Obj/Analysis/Profile/_element.js
Normal file
8
src/Obj/Analysis/Profile/_element.js
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
function html() {
|
||||||
|
return `
|
||||||
|
<span class="custom-divider"></span>
|
||||||
|
<div class="profile-echarts"></div>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
|
export { html }
|
||||||
637
src/Obj/Analysis/Profile/index.js
Normal file
637
src/Obj/Analysis/Profile/index.js
Normal file
@ -0,0 +1,637 @@
|
|||||||
|
import Draw from "../../../Draw/draw";
|
||||||
|
import MouseEvent from "../../../Event";
|
||||||
|
import MouseTip from "../../../MouseTip";
|
||||||
|
import Dialog from '../../../BaseDialog';
|
||||||
|
import { html } from "./_element";
|
||||||
|
class Profile extends Draw {
|
||||||
|
/**
|
||||||
|
* @constructor 剖面分析
|
||||||
|
* @param sdk
|
||||||
|
**/
|
||||||
|
constructor(sdk, _Dialog = {}) {
|
||||||
|
window.addEventListener("resize", () => {
|
||||||
|
this.echartsObject && this.echartsObject.resize();
|
||||||
|
});
|
||||||
|
super(sdk)
|
||||||
|
this.viewer = sdk.viewer;
|
||||||
|
this.Dialog = _Dialog
|
||||||
|
YJ.Analysis.Analyses.push(this)
|
||||||
|
Profile.create(this)
|
||||||
|
}
|
||||||
|
static create(that) {
|
||||||
|
this._currentId = Cesium.createGuid()
|
||||||
|
let id = this._currentId
|
||||||
|
that.clean()
|
||||||
|
if (YJ.Measure.GetMeasureStatus()) {
|
||||||
|
console.warn('上一次测量未结束')
|
||||||
|
} else {
|
||||||
|
YJ.Measure.SetMeasureStatus(true)
|
||||||
|
that.tip = new MouseTip('左键确定,右键取消', that.sdk)
|
||||||
|
that.event = new MouseEvent(that.sdk)
|
||||||
|
that.positions = []
|
||||||
|
that.points_ids = [] //存放左键点击时临时添加的point的id
|
||||||
|
|
||||||
|
let cache_positions = []
|
||||||
|
let car = undefined
|
||||||
|
that.event.mouse_left(async (movement, cartesian) => {
|
||||||
|
try {
|
||||||
|
if (!that.entityHasCreated) {
|
||||||
|
Profile.create_polyline(that)
|
||||||
|
}
|
||||||
|
cache_positions.push(cartesian)
|
||||||
|
that.points_ids.push(that.create_point(cartesian,))
|
||||||
|
if (cache_positions.length == 2) {
|
||||||
|
that.end()
|
||||||
|
let positions = []
|
||||||
|
cache_positions.forEach((item) => {
|
||||||
|
positions.push(that.cartesian3Towgs84(item, that.viewer))
|
||||||
|
})
|
||||||
|
Profile.interPoints(that).then((points) => {
|
||||||
|
if (this._currentId && this._currentId === id) {
|
||||||
|
that._DialogObject ? Profile.initEcharts(that, points) : Profile.edit(that, points)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error)
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
that.event.mouse_right((movement, cartesian) => {
|
||||||
|
let positions = []
|
||||||
|
cache_positions = []
|
||||||
|
that.clean()
|
||||||
|
})
|
||||||
|
that.event.mouse_move((movement, cartesian) => {
|
||||||
|
that.positions = cache_positions.concat(cartesian)
|
||||||
|
that.tip.setPosition(
|
||||||
|
cartesian,
|
||||||
|
movement.endPosition.x,
|
||||||
|
movement.endPosition.y
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
that.event.gesture_pinck_start((movement, cartesian) => {
|
||||||
|
let startTime = new Date()
|
||||||
|
that.event.gesture_pinck_end(() => {
|
||||||
|
let endTime = new Date()
|
||||||
|
if (endTime - startTime >= 500) {
|
||||||
|
let positions = []
|
||||||
|
cache_positions = []
|
||||||
|
that.end()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static create_polyline(that) {
|
||||||
|
that.entityHasCreated = true
|
||||||
|
let id = that.randomString()
|
||||||
|
that.polyline = that.viewer.entities.add(
|
||||||
|
new Cesium.Entity({
|
||||||
|
id: id,
|
||||||
|
polyline: {
|
||||||
|
positions: new Cesium.CallbackProperty(() => {
|
||||||
|
return that.positions
|
||||||
|
}, false),
|
||||||
|
width: 5,
|
||||||
|
material: Cesium.Color.fromCssColorString(that.color),
|
||||||
|
clampToGround: true,
|
||||||
|
zIndex: 99999999
|
||||||
|
},
|
||||||
|
})
|
||||||
|
)
|
||||||
|
return id
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 线段插值点
|
||||||
|
*/
|
||||||
|
static async interPoints(that) {
|
||||||
|
let viewer = that.viewer
|
||||||
|
let positions = that.positions
|
||||||
|
let positionsCartographic = []
|
||||||
|
let positions84 = [];
|
||||||
|
for (let index = 0; index < positions.length; index++) {
|
||||||
|
const element = positions[index];
|
||||||
|
let cartographic = viewer.scene.globe.ellipsoid.cartesianToCartographic(element);
|
||||||
|
positionsCartographic.push(cartographic);
|
||||||
|
let pos84 = that.cartesian3Towgs84(element, viewer)
|
||||||
|
positions84.push(pos84);
|
||||||
|
}
|
||||||
|
let positions_Inter = [];
|
||||||
|
let height = await that.getClampToHeight({ lng: positions84[0].lng, lat: positions84[0].lat });
|
||||||
|
positions_Inter.push({
|
||||||
|
position: { lng: positions84[0].lng, lat: positions84[0].lat, height: height },
|
||||||
|
distance: 0,
|
||||||
|
});
|
||||||
|
for (let i = 0; i < positionsCartographic.length - 1; i++) {
|
||||||
|
let line = turf.lineString([[positions84[i].lng, positions84[i].lat], [positions84[i + 1].lng, positions84[i + 1].lat]]);
|
||||||
|
let totalDistance = turf.length(line, { units: 'kilometers' });
|
||||||
|
|
||||||
|
const m_Cartographic0 = positionsCartographic[i];
|
||||||
|
const m_Cartographic1 = positionsCartographic[i + 1];
|
||||||
|
let a =
|
||||||
|
Math.abs(m_Cartographic0.longitude - m_Cartographic1.longitude) *
|
||||||
|
10000000;
|
||||||
|
let b =
|
||||||
|
Math.abs(m_Cartographic0.latitude - m_Cartographic1.latitude) *
|
||||||
|
10000000;
|
||||||
|
//等距采样
|
||||||
|
if (a > b) b = a;
|
||||||
|
let length = parseInt(b / 2);
|
||||||
|
if (length > 150) length = 150;
|
||||||
|
if (length < 2) length = 2;
|
||||||
|
let distance = totalDistance / (length - 1)
|
||||||
|
for (let j = 0; j < length - 1; j++) {
|
||||||
|
let start = j * distance
|
||||||
|
let stop = (j + 1) * distance
|
||||||
|
let sliced = await turf.lineSliceAlong(line, start, stop, { units: 'kilometers' });
|
||||||
|
let lng = sliced.geometry.coordinates[sliced.geometry.coordinates.length - 1][0]
|
||||||
|
let lat = sliced.geometry.coordinates[sliced.geometry.coordinates.length - 1][1]
|
||||||
|
let height = await that.getClampToHeight({ lng: lng, lat: lat });
|
||||||
|
positions_Inter.push({
|
||||||
|
position: { lng: lng, lat: lat, height: height },
|
||||||
|
distance: stop * 1000,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return positions_Inter
|
||||||
|
}
|
||||||
|
|
||||||
|
static async edit(that, points) {
|
||||||
|
if (that._DialogObject && that._DialogObject.close) {
|
||||||
|
that._DialogObject.close()
|
||||||
|
that._DialogObject = null
|
||||||
|
}
|
||||||
|
that._DialogObject = await new Dialog(that.sdk.viewer._container, {
|
||||||
|
title: '剖面分析', left: '180px', top: '100px',
|
||||||
|
closeCallBack: () => {
|
||||||
|
that.clean()
|
||||||
|
that.Dialog.closeCallBack && that.Dialog.closeCallBack()
|
||||||
|
},
|
||||||
|
})
|
||||||
|
await that._DialogObject.init()
|
||||||
|
that._DialogObject._element.body.className = that._DialogObject._element.body.className + ' profile'
|
||||||
|
let contentElm = document.createElement('div');
|
||||||
|
contentElm.innerHTML = html()
|
||||||
|
that._DialogObject.contentAppChild(contentElm)
|
||||||
|
let resetBtn = document.createElement('button');
|
||||||
|
resetBtn.innerHTML = '<svg class="icon-edit"><use xlink:href="#yj-icon-edit"></use></svg>重新绘制'
|
||||||
|
resetBtn.style.width = 'auto'
|
||||||
|
resetBtn.addEventListener('click', () => {
|
||||||
|
Profile.create(that)
|
||||||
|
Profile.initEcharts(that)
|
||||||
|
})
|
||||||
|
that._DialogObject.footAppChild(resetBtn)
|
||||||
|
Profile.initEcharts(that, points)
|
||||||
|
}
|
||||||
|
|
||||||
|
static initEcharts(that, points) {
|
||||||
|
let datas = [],
|
||||||
|
coords = [];
|
||||||
|
const pointsData = points;
|
||||||
|
|
||||||
|
let option
|
||||||
|
if (pointsData) {
|
||||||
|
const maxDistance = pointsData[pointsData.length - 1].distance;
|
||||||
|
let xAixMax = Math.ceil(maxDistance);
|
||||||
|
for (let index = 0; index < pointsData.length; index++) {
|
||||||
|
const element = pointsData[index];
|
||||||
|
if (element.position.height === void 0) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
const curData = [
|
||||||
|
element.distance.toFixed(2),
|
||||||
|
element.position.height.toFixed(2),
|
||||||
|
];
|
||||||
|
datas.push(curData);
|
||||||
|
const curCoords = [element.position.lng, element.position.lat];
|
||||||
|
coords.push(curCoords);
|
||||||
|
}
|
||||||
|
const pointOption = {
|
||||||
|
show: true,
|
||||||
|
pixelSize: 10,
|
||||||
|
color: Cesium.Color.GREEN,
|
||||||
|
outlineColor: Cesium.Color.SKYBLUE,
|
||||||
|
outlineWidth: 3,
|
||||||
|
disableDepthTestDistance: Number.POSITIVE_INFINITY
|
||||||
|
};
|
||||||
|
const ele = that._DialogObject._element.content.getElementsByClassName("profile-echarts")[0];
|
||||||
|
that.echartsObject = echarts.init(ele);
|
||||||
|
option = {
|
||||||
|
tooltip: {
|
||||||
|
trigger: "axis",
|
||||||
|
textStyle: {
|
||||||
|
align: "left",
|
||||||
|
},
|
||||||
|
formatter(params) {
|
||||||
|
const xy = coords[params[0].dataIndex];
|
||||||
|
const tipData = params[0]["data"];
|
||||||
|
if (!that.tipEntity) {
|
||||||
|
that.tipEntity = that.sdk.viewer.entities.add({
|
||||||
|
position: Cesium.Cartesian3.fromDegrees(
|
||||||
|
xy[0],
|
||||||
|
xy[1],
|
||||||
|
Number(tipData[1])
|
||||||
|
),
|
||||||
|
point: pointOption,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
that.tipEntity.position = Cesium.Cartesian3.fromDegrees(
|
||||||
|
xy[0],
|
||||||
|
xy[1],
|
||||||
|
Number(tipData[1])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
"距离:" +
|
||||||
|
tipData[0] +
|
||||||
|
"m<br>" +
|
||||||
|
"高度:" +
|
||||||
|
tipData[1] +
|
||||||
|
"m<br>" +
|
||||||
|
"坐标:" +
|
||||||
|
xy[0].toFixed(5) +
|
||||||
|
"," +
|
||||||
|
xy[1].toFixed(5)
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
grid: {
|
||||||
|
top: 40,
|
||||||
|
bottom: 20,
|
||||||
|
left: 55,
|
||||||
|
right: 30
|
||||||
|
},
|
||||||
|
calculable: true,
|
||||||
|
xAxis: [
|
||||||
|
{
|
||||||
|
type: "value",
|
||||||
|
max: xAixMax,
|
||||||
|
scale: true,
|
||||||
|
axisLabel: {
|
||||||
|
color: '#ffffff'
|
||||||
|
},
|
||||||
|
axisLine: {
|
||||||
|
lineStyle: {
|
||||||
|
color: "#ffffff"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
],
|
||||||
|
yAxis: [
|
||||||
|
{
|
||||||
|
type: "value",
|
||||||
|
scale: true,
|
||||||
|
axisLabel: {
|
||||||
|
color: '#ffffff'
|
||||||
|
},
|
||||||
|
axisLine: {
|
||||||
|
lineStyle: {
|
||||||
|
color: "#ffffff"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
],
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
name: "ProfileLine",
|
||||||
|
type: "line",
|
||||||
|
data: datas,
|
||||||
|
smooth: true,
|
||||||
|
itemStyle: {
|
||||||
|
normal: {
|
||||||
|
color: "#39FDA1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
lineStyle: {
|
||||||
|
normal: {
|
||||||
|
width: 3,
|
||||||
|
color: {
|
||||||
|
type: "linear",
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
x2: 1,
|
||||||
|
y2: 0,
|
||||||
|
colorStops: [
|
||||||
|
{
|
||||||
|
offset: 0,
|
||||||
|
color: "rgba(85,254,139,1)", // 0% 处的颜色
|
||||||
|
},
|
||||||
|
{
|
||||||
|
offset: 0.5,
|
||||||
|
color: "rgba(7,252,202,1)", // 100% 处的颜色
|
||||||
|
},
|
||||||
|
{
|
||||||
|
offset: 1,
|
||||||
|
color: "rgba(14,245,210,1)", // 100% 处的颜色
|
||||||
|
},
|
||||||
|
],
|
||||||
|
globalCoord: false, // 缺省为 false
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
areaStyle: {
|
||||||
|
normal: {
|
||||||
|
color: new echarts.graphic.LinearGradient(
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
[
|
||||||
|
{
|
||||||
|
offset: 0,
|
||||||
|
color: "rgba(102,153,255,1)",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
offset: 0.8,
|
||||||
|
color: "rgba(102,153,255,0.08)",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
offset: 1,
|
||||||
|
color: "rgba(9,173,208,0.15)",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
false
|
||||||
|
),
|
||||||
|
shadowColor: "rgba(14,245,210,1)", //阴影颜色
|
||||||
|
shadowBlur: 20,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
markPoint: {
|
||||||
|
data: [
|
||||||
|
{
|
||||||
|
type: "max",
|
||||||
|
name: "最高点",
|
||||||
|
label: {
|
||||||
|
color: '#ffffff',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "min",
|
||||||
|
name: "最低点",
|
||||||
|
label: {
|
||||||
|
color: '#ffffff',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const ele = that._DialogObject._element.content.getElementsByClassName("profile-echarts")[0];
|
||||||
|
that.echartsObject = echarts.init(ele);
|
||||||
|
option = {
|
||||||
|
tooltip: {
|
||||||
|
trigger: "axis",
|
||||||
|
textStyle: {
|
||||||
|
align: "left",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
grid: {
|
||||||
|
top: 40,
|
||||||
|
bottom: 20,
|
||||||
|
left: 55,
|
||||||
|
right: 30
|
||||||
|
},
|
||||||
|
calculable: true,
|
||||||
|
xAxis: [
|
||||||
|
{
|
||||||
|
type: "value",
|
||||||
|
scale: true,
|
||||||
|
axisLabel: {
|
||||||
|
color: '#ffffff'
|
||||||
|
},
|
||||||
|
axisLine: {
|
||||||
|
lineStyle: {
|
||||||
|
color: "#ffffff"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
],
|
||||||
|
yAxis: [
|
||||||
|
{
|
||||||
|
type: "value",
|
||||||
|
scale: true,
|
||||||
|
axisLabel: {
|
||||||
|
color: '#ffffff'
|
||||||
|
},
|
||||||
|
axisLine: {
|
||||||
|
lineStyle: {
|
||||||
|
color: "#ffffff"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
],
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
name: "ProfileLine",
|
||||||
|
type: "line",
|
||||||
|
data: [],
|
||||||
|
smooth: true,
|
||||||
|
itemStyle: {
|
||||||
|
normal: {
|
||||||
|
color: "#39FDA1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
lineStyle: {
|
||||||
|
normal: {
|
||||||
|
width: 3,
|
||||||
|
color: {
|
||||||
|
type: "linear",
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
x2: 1,
|
||||||
|
y2: 0,
|
||||||
|
colorStops: [
|
||||||
|
{
|
||||||
|
offset: 0,
|
||||||
|
color: "rgba(85,254,139,1)", // 0% 处的颜色
|
||||||
|
},
|
||||||
|
{
|
||||||
|
offset: 0.5,
|
||||||
|
color: "rgba(7,252,202,1)", // 100% 处的颜色
|
||||||
|
},
|
||||||
|
{
|
||||||
|
offset: 1,
|
||||||
|
color: "rgba(14,245,210,1)", // 100% 处的颜色
|
||||||
|
},
|
||||||
|
],
|
||||||
|
globalCoord: false, // 缺省为 false
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
areaStyle: {
|
||||||
|
normal: {
|
||||||
|
color: new echarts.graphic.LinearGradient(
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
[
|
||||||
|
{
|
||||||
|
offset: 0,
|
||||||
|
color: "rgba(102,153,255,1)",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
offset: 0.8,
|
||||||
|
color: "rgba(102,153,255,0.08)",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
offset: 1,
|
||||||
|
color: "rgba(9,173,208,0.15)",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
false
|
||||||
|
),
|
||||||
|
shadowColor: "rgba(14,245,210,1)", //阴影颜色
|
||||||
|
shadowBlur: 20,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
markPoint: {
|
||||||
|
data: [
|
||||||
|
{
|
||||||
|
type: "max",
|
||||||
|
name: "最高点",
|
||||||
|
label: {
|
||||||
|
color: '#ffffff',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: "min",
|
||||||
|
name: "最低点",
|
||||||
|
label: {
|
||||||
|
color: '#ffffff',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
that.echartsObject.setOption(option);
|
||||||
|
}
|
||||||
|
|
||||||
|
clean() {
|
||||||
|
this.end()
|
||||||
|
this._currentId = null
|
||||||
|
this.entityHasCreated = false
|
||||||
|
this.polyline && this.viewer.entities.remove(this.polyline)
|
||||||
|
this.tipEntity && this.viewer.entities.remove(this.tipEntity)
|
||||||
|
this.polyline = null
|
||||||
|
this.tipEntity = null
|
||||||
|
}
|
||||||
|
|
||||||
|
destroy() {
|
||||||
|
this.clean()
|
||||||
|
if (this._DialogObject && this._DialogObject.close) {
|
||||||
|
this._DialogObject.close()
|
||||||
|
this._DialogObject = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// const Profile = function (viewer, callback) {
|
||||||
|
// if (!viewer) throw new Error("no viewer object!");
|
||||||
|
// if (window.profileEntities && window.profileEntities.length > 0) {
|
||||||
|
// window.profileEntities.forEach((element) => {
|
||||||
|
// window.viewer.entities.remove(element);
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// window.profileEntities = [];
|
||||||
|
// CreatePolyline(
|
||||||
|
// viewer,
|
||||||
|
// window.profileEntities,
|
||||||
|
// { color: Cesium.Color.RED, width: 2 },
|
||||||
|
// function (e) {
|
||||||
|
// e.polyline.clampToGround = true;
|
||||||
|
// console.log(e.pottingPoint);
|
||||||
|
// let points = interPoints(viewer, e.pottingPoint, [e]);
|
||||||
|
// console.log(points);
|
||||||
|
// if (typeof callback == "function") callback(points);
|
||||||
|
// }
|
||||||
|
// );
|
||||||
|
// };
|
||||||
|
// /**
|
||||||
|
// * 线段插值点
|
||||||
|
// * @param {*} viewer
|
||||||
|
// * @param {*} positions 线段节点集合
|
||||||
|
// * @param {*} objectsToExclude 高度采集时排除的对象集合
|
||||||
|
// * @returns 经纬度点集合,包含距离值
|
||||||
|
// */
|
||||||
|
// function interPoints(viewer, positions, objectsToExclude) {
|
||||||
|
// let positionsCartographic = [];
|
||||||
|
// let terrainSamplePositions = [];
|
||||||
|
// for (let index = 0; index < positions.length; index++) {
|
||||||
|
// const element = positions[index];
|
||||||
|
// let ellipsoid = viewer.scene.globe.ellipsoid;
|
||||||
|
// let cartographic = ellipsoid.cartesianToCartographic(element);
|
||||||
|
// positionsCartographic.push(cartographic);
|
||||||
|
// }
|
||||||
|
// for (let i = 0; i < positionsCartographic.length; i++) {
|
||||||
|
// const m_Cartographic0 = positionsCartographic[i];
|
||||||
|
// const m_Cartographic1 = positionsCartographic[i + 1];
|
||||||
|
// if (m_Cartographic1) {
|
||||||
|
// let a =
|
||||||
|
// Math.abs(m_Cartographic0.longitude - m_Cartographic1.longitude) *
|
||||||
|
// 10000000;
|
||||||
|
// let b =
|
||||||
|
// Math.abs(m_Cartographic0.latitude - m_Cartographic1.latitude) *
|
||||||
|
// 10000000;
|
||||||
|
// //等距采样
|
||||||
|
// if (a > b) b = a;
|
||||||
|
// let length = parseInt(b / 2);
|
||||||
|
// if (length > 1000) length = 1000;
|
||||||
|
// if (length < 2) length = 2;
|
||||||
|
// for (let j = 0; j < length; j++) {
|
||||||
|
// terrainSamplePositions.push(
|
||||||
|
// new Cesium.Cartographic(
|
||||||
|
// Cesium.Math.lerp(
|
||||||
|
// m_Cartographic0.longitude,
|
||||||
|
// m_Cartographic1.longitude,
|
||||||
|
// j / (length - 1)
|
||||||
|
// ),
|
||||||
|
// Cesium.Math.lerp(
|
||||||
|
// m_Cartographic0.latitude,
|
||||||
|
// m_Cartographic1.latitude,
|
||||||
|
// j / (length - 1)
|
||||||
|
// )
|
||||||
|
// )
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// terrainSamplePositions.pop();
|
||||||
|
// } else {
|
||||||
|
// terrainSamplePositions.push(m_Cartographic0);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// let positions_Inter = [];
|
||||||
|
// let distance = 0;
|
||||||
|
// for (let n = 0; n < terrainSamplePositions.length; n++) {
|
||||||
|
// //地理坐标(弧度)转经纬度坐标
|
||||||
|
// let curCartographic = terrainSamplePositions[n];
|
||||||
|
// let height = viewer.scene.sampleHeight(curCartographic, objectsToExclude);
|
||||||
|
// const lon = (curCartographic.longitude / Math.PI) * 180;
|
||||||
|
// const lat = (curCartographic.latitude / Math.PI) * 180;
|
||||||
|
// let point = Cesium.Cartesian3.fromDegrees(lon, lat, height);
|
||||||
|
// let preCartographic = terrainSamplePositions[n - 1];
|
||||||
|
// if (preCartographic) {
|
||||||
|
// const lon1 = (preCartographic.longitude / Math.PI) * 180;
|
||||||
|
// const lat1 = (preCartographic.latitude / Math.PI) * 180;
|
||||||
|
// let point1 = Cesium.Cartesian3.fromDegrees(lon1, lat1, height);
|
||||||
|
// let curDis = Cesium.Cartesian3.distance(point1, point);
|
||||||
|
// distance += curDis;
|
||||||
|
// }
|
||||||
|
// positions_Inter.push({
|
||||||
|
// position: { lon: lon, lat: lat, height: height },
|
||||||
|
// distance: distance,
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// return positions_Inter;
|
||||||
|
// }
|
||||||
|
export default Profile;
|
||||||
145
src/Obj/Analysis/Section/index.js
Normal file
145
src/Obj/Analysis/Section/index.js
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
import Tools from "../../../Tools";
|
||||||
|
class Section extends Tools {
|
||||||
|
/**
|
||||||
|
* @constructor 剖切
|
||||||
|
* @param sdk
|
||||||
|
* @param tiles3d {object} 3dtiles对象
|
||||||
|
* @param {Array.<object>} options.positions 经纬度[{lon,lat,alt},...]
|
||||||
|
* @param options.regionsType=false 裁剪类型 false:裁剪内部,true:裁剪外部
|
||||||
|
* **/
|
||||||
|
constructor(sdk, tiles3d, options = {}) {
|
||||||
|
|
||||||
|
|
||||||
|
super(sdk, options)
|
||||||
|
this.viewer = sdk.viewer
|
||||||
|
this.tiles3d = tiles3d
|
||||||
|
this.options = { ...options }
|
||||||
|
this.options.regionsType = this.options.regionsType || false
|
||||||
|
// YJ.Analysis.Analyses.push(this)
|
||||||
|
this.Planes = []
|
||||||
|
Section.start(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
get regionsType() {
|
||||||
|
return this.options.regionsType
|
||||||
|
}
|
||||||
|
set regionsType(v) {
|
||||||
|
this.options.regionsType = v
|
||||||
|
if (this.Planes.length > 0) {
|
||||||
|
this.Planes = []
|
||||||
|
Section.planeCollection(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static start(that) {
|
||||||
|
let positions = that.options.positions || []
|
||||||
|
if(!that.isConvex(positions)) {
|
||||||
|
window.ELEMENT && window.ELEMENT.Message({
|
||||||
|
message: '不支持凹多边形',
|
||||||
|
type: 'warning',
|
||||||
|
duration: 1500
|
||||||
|
});
|
||||||
|
console.log('不支持凹多边形')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
that.inverseTransform = getInverseTransform(that.tiles3d)
|
||||||
|
that.Planes = []
|
||||||
|
let array = []
|
||||||
|
if (positions.length > 0) {
|
||||||
|
for (let i = 0; i < positions.length; i++) {
|
||||||
|
array.push([positions[i].lng, positions[i].lat])
|
||||||
|
}
|
||||||
|
array.push([positions[0].lng, positions[0].lat])
|
||||||
|
that.isClockwise = turf.booleanClockwise(turf.lineString(array));
|
||||||
|
}
|
||||||
|
Section.planeCollection(that)
|
||||||
|
|
||||||
|
function getInverseTransform(tileSet) {
|
||||||
|
let transform
|
||||||
|
const tmp = tileSet.root.transform
|
||||||
|
if ((tmp && tmp.equals(Cesium.Matrix4.IDENTITY)) || !tmp) {
|
||||||
|
transform = Cesium.Transforms.eastNorthUpToFixedFrame(tileSet.boundingSphere.center)
|
||||||
|
} else {
|
||||||
|
transform = Cesium.Matrix4.fromArray(tileSet.root.transform)
|
||||||
|
}
|
||||||
|
return Cesium.Matrix4.inverseTransformation(transform, new Cesium.Matrix4())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static planeCollection(that) {
|
||||||
|
let positions = that.options.positions || []
|
||||||
|
if (that.regionsType == that.isClockwise) {
|
||||||
|
for (let i = 0; i < positions.length; i++) {
|
||||||
|
if (i === (positions.length - 1)) {
|
||||||
|
that.Planes.push(createPlane(positions[i], positions[0], that.inverseTransform))
|
||||||
|
} else {
|
||||||
|
that.Planes.push(createPlane(positions[i], positions[i + 1], that.inverseTransform))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for (let i = positions.length - 1; i >= 0; i--) {
|
||||||
|
if (i === 0) {
|
||||||
|
that.Planes.push(createPlane(positions[i], positions[positions.length - 1], that.inverseTransform))
|
||||||
|
} else {
|
||||||
|
that.Planes.push(createPlane(positions[i], positions[i - 1], that.inverseTransform))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(that.tiles3d.clippingPlanes) {
|
||||||
|
that.tiles3d.clippingPlanes.removeAll()
|
||||||
|
for(let i=0;i<that.Planes.length;i++) {
|
||||||
|
that.tiles3d.clippingPlanes.add(that.Planes[i])
|
||||||
|
}
|
||||||
|
that.tiles3d.clippingPlanes.enabled = true
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const PlaneCollection = new Cesium.ClippingPlaneCollection({
|
||||||
|
planes: that.Planes,
|
||||||
|
enabled: true,
|
||||||
|
unionClippingRegions: that.regionsType,
|
||||||
|
edgeColor: Cesium.Color.WHITE,
|
||||||
|
edgeWidth: 1,
|
||||||
|
})
|
||||||
|
that.tiles3d.clippingPlanes = PlaneCollection
|
||||||
|
}
|
||||||
|
|
||||||
|
function createPlane(p1, p2, inverseTransform) {
|
||||||
|
// 将仅包含经纬度信息的p1,p2,转换为相应坐标系的cartesian3对象
|
||||||
|
const p1C3 = getOriginCoordinateSystemPoint(p1, inverseTransform)
|
||||||
|
const p2C3 = getOriginCoordinateSystemPoint(p2, inverseTransform)
|
||||||
|
|
||||||
|
// 定义一个垂直向上的向量up
|
||||||
|
const up = new Cesium.Cartesian3(0, 0, 10)
|
||||||
|
// right 实际上就是由p1指向p2的向量
|
||||||
|
const right = Cesium.Cartesian3.subtract(p2C3, p1C3, new Cesium.Cartesian3())
|
||||||
|
|
||||||
|
// 计算normal, right叉乘up,得到平面法向量,这个法向量指向right的右侧
|
||||||
|
let normal = Cesium.Cartesian3.cross(right, up, new Cesium.Cartesian3())
|
||||||
|
normal = Cesium.Cartesian3.normalize(normal, normal)
|
||||||
|
|
||||||
|
// 由于已经获得了法向量和过平面的一点,因此可以直接构造Plane,并进一步构造ClippingPlane
|
||||||
|
const planeTmp = Cesium.Plane.fromPointNormal(p1C3, normal)
|
||||||
|
return Cesium.ClippingPlane.fromPlane(planeTmp)
|
||||||
|
}
|
||||||
|
|
||||||
|
function getOriginCoordinateSystemPoint(point, inverseTransform) {
|
||||||
|
const val = Cesium.Cartesian3.fromDegrees(point.lng, point.lat)
|
||||||
|
return Cesium.Matrix4.multiplyByPoint(
|
||||||
|
inverseTransform, val, new Cesium.Cartesian3(0, 0, 0))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
destroy() {
|
||||||
|
this.Planes = []
|
||||||
|
// this.tiles3d.clippingPlanes = new Cesium.ClippingPlaneCollection()
|
||||||
|
if(this.tiles3d.clippingPlanes) {
|
||||||
|
this.tiles3d.clippingPlanes.enabled = false
|
||||||
|
this.tiles3d.clippingPlanes.removeAll()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Section;
|
||||||
517
src/Obj/Analysis/SlopeAspect/index.js
Normal file
517
src/Obj/Analysis/SlopeAspect/index.js
Normal file
@ -0,0 +1,517 @@
|
|||||||
|
|
||||||
|
import Tools from "../../../Tools";
|
||||||
|
import DrawPolygon from "../../../Draw/drawPolygon"
|
||||||
|
import MouseEvent from '../../../Event/index'
|
||||||
|
class SlopeAspect extends Tools {
|
||||||
|
/**
|
||||||
|
* @constructor 坡度坡向分析
|
||||||
|
* @param sdk
|
||||||
|
* **/
|
||||||
|
constructor(sdk) {
|
||||||
|
super(sdk)
|
||||||
|
this.viewer = sdk.viewer;
|
||||||
|
let terrainAvailability = this.viewer.terrainProvider.availability;
|
||||||
|
if (!terrainAvailability) {
|
||||||
|
this.error = '未加载地形数据!'
|
||||||
|
window.ELEMENT && window.ELEMENT.Message({
|
||||||
|
message: '未加载地形数据!',
|
||||||
|
type: 'warning',
|
||||||
|
duration: 1500
|
||||||
|
});
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.event
|
||||||
|
this.result = []; //存储创建的坡度分析结果,primitive集合
|
||||||
|
this.handler = undefined;
|
||||||
|
this.toolTip = "";
|
||||||
|
YJ.Analysis.Analyses.push(this)
|
||||||
|
this.Draw = new DrawPolygon(this.sdk)
|
||||||
|
// this.createNew4Distance()
|
||||||
|
this.createNew4Num(50)
|
||||||
|
}
|
||||||
|
|
||||||
|
//等距离切分网格
|
||||||
|
createNew4Distance(distance) {
|
||||||
|
distance = distance || 0.1; //默认0.1km精度
|
||||||
|
let width = distance * 200 > 35 ? 35 : distance * 200;
|
||||||
|
this.arrowWidth = width < 15 ? 15 : width;
|
||||||
|
const $this = this;
|
||||||
|
const viewer = this.viewer;
|
||||||
|
this.Draw.start((e, positions) => {
|
||||||
|
if (!positions || positions.length <= 2) {
|
||||||
|
window.ELEMENT && window.ELEMENT.Message({
|
||||||
|
message: '至少拥有三个坐标位置!',
|
||||||
|
type: 'warning',
|
||||||
|
duration: 1500
|
||||||
|
});
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let boundary = [];
|
||||||
|
let minX = 10000,
|
||||||
|
minY = 10000,
|
||||||
|
maxX = -10000,
|
||||||
|
maxY = -1000;
|
||||||
|
for (let index = 0; index < positions.length; index++) {
|
||||||
|
const element = positions[index];
|
||||||
|
const x = element.lng;
|
||||||
|
const y = element.lat;
|
||||||
|
boundary.push([x, y]);
|
||||||
|
minX = x < minX ? x : minX;
|
||||||
|
minY = y < minY ? y : minY;
|
||||||
|
maxX = x > maxX ? x : maxX;
|
||||||
|
maxY = y > maxY ? y : maxY;
|
||||||
|
}
|
||||||
|
boundary.push(boundary[0]);
|
||||||
|
let bbox = [minX, minY, maxX, maxY];
|
||||||
|
let mask = turf.polygon([boundary]);
|
||||||
|
let gridSquare = turf.squareGrid(bbox, distance, { mask: mask });
|
||||||
|
this.createEllipse(gridSquare);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 等分切分网格,切分成一个num*num的网格
|
||||||
|
createNew4Num(n) {
|
||||||
|
let num = n
|
||||||
|
this.Draw.start((e, positions) => {
|
||||||
|
if (!positions || positions.length <= 2) {
|
||||||
|
console.warn('至少拥有三个坐标位置!')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let boundary = [];
|
||||||
|
let minX = 10000,
|
||||||
|
minY = 10000,
|
||||||
|
maxX = -10000,
|
||||||
|
maxY = -1000;
|
||||||
|
for (let index = 0; index < positions.length; index++) {
|
||||||
|
const element = positions[index];
|
||||||
|
const x = element.lng;
|
||||||
|
const y = element.lat;
|
||||||
|
boundary.push([x, y]);
|
||||||
|
minX = x < minX ? x : minX;
|
||||||
|
minY = y < minY ? y : minY;
|
||||||
|
maxX = x > maxX ? x : maxX;
|
||||||
|
maxY = y > maxY ? y : maxY;
|
||||||
|
}
|
||||||
|
boundary.push(boundary[0]);
|
||||||
|
let bbox = [minX, minY, maxX, maxY];
|
||||||
|
let a = maxX - minX;
|
||||||
|
let b = maxY - minY;
|
||||||
|
b = b > a ? b : a;
|
||||||
|
|
||||||
|
// 根据面积修改网格数
|
||||||
|
let mask = turf.polygon([boundary]);
|
||||||
|
let area = turf.area(mask);
|
||||||
|
if (area > 5000000000000) {
|
||||||
|
num = num - 25;
|
||||||
|
}
|
||||||
|
else if (area > 1000000000000) {
|
||||||
|
num = num - 20;
|
||||||
|
}
|
||||||
|
else if (area > 500000000000) {
|
||||||
|
num = num - 15;
|
||||||
|
}
|
||||||
|
else if (area > 100000000000) {
|
||||||
|
num = num - 10;
|
||||||
|
}
|
||||||
|
else if (area > 60000000000) {
|
||||||
|
num = num - 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
const step = b / num;
|
||||||
|
let width = step * 2000 > 35 ? 35 : step * 2000;
|
||||||
|
this.arrowWidth = width < 15 ? 15 : width;
|
||||||
|
|
||||||
|
let gridSquare = turf.squareGrid(bbox, step, {
|
||||||
|
units: "degrees",
|
||||||
|
mask: mask,
|
||||||
|
});
|
||||||
|
this.createEllipse(gridSquare);
|
||||||
|
})
|
||||||
|
// CreatePolygonOnGround(
|
||||||
|
// viewer,
|
||||||
|
// [],
|
||||||
|
// {
|
||||||
|
// color: Cesium.Color.RED.withAlpha(0.1),
|
||||||
|
// outlineColor: Cesium.Color.YELLOW,
|
||||||
|
// outlineWidth: 2,
|
||||||
|
// },
|
||||||
|
// function (polygon) {
|
||||||
|
// let degrees = $this.Cartesian3ListToWGS84(polygon.pottingPoint);
|
||||||
|
// viewer.entities.remove(polygon);
|
||||||
|
// let boundary = [];
|
||||||
|
// let minX = 10000,
|
||||||
|
// minY = 10000,
|
||||||
|
// maxX = -10000,
|
||||||
|
// maxY = -1000;
|
||||||
|
// for (let index = 0; index < degrees.length; index++) {
|
||||||
|
// const element = degrees[index];
|
||||||
|
// const x = element.lng;
|
||||||
|
// const y = element.lat;
|
||||||
|
// boundary.push([x, y]);
|
||||||
|
// minX = x < minX ? x : minX;
|
||||||
|
// minY = y < minY ? y : minY;
|
||||||
|
// maxX = x > maxX ? x : maxX;
|
||||||
|
// maxY = y > maxY ? y : maxY;
|
||||||
|
// }
|
||||||
|
// boundary.push(boundary[0]);
|
||||||
|
// let bbox = [minX, minY, maxX, maxY];
|
||||||
|
// let a = maxX - minX;
|
||||||
|
// let b = maxY - minY;
|
||||||
|
// b = b > a ? b : a;
|
||||||
|
// const step = b / num;
|
||||||
|
// let width = step * 2000 > 35 ? 35 : step * 2000;
|
||||||
|
// this.arrowWidth = width < 15 ? 15 : width;
|
||||||
|
// let mask = turf.polygon([boundary]);
|
||||||
|
// let gridSquare = turf.squareGrid(bbox, step, {
|
||||||
|
// units: "degrees",
|
||||||
|
// mask: mask,
|
||||||
|
// });
|
||||||
|
// this.createEllipse(gridSquare);
|
||||||
|
// }
|
||||||
|
// );
|
||||||
|
}
|
||||||
|
createEllipse(gridSquare) {
|
||||||
|
let boxResults = [];
|
||||||
|
for (let index = 0; index < gridSquare.features.length; index++) {
|
||||||
|
const feature = gridSquare.features[index];
|
||||||
|
const coordinates = feature.geometry.coordinates[0];
|
||||||
|
const centerdegree = [
|
||||||
|
(coordinates[0][0] + coordinates[2][0]) / 2,
|
||||||
|
(coordinates[0][1] + coordinates[2][1]) / 2,
|
||||||
|
];
|
||||||
|
let centerCartographic = Cesium.Cartographic.fromDegrees(
|
||||||
|
centerdegree[0],
|
||||||
|
centerdegree[1]
|
||||||
|
);
|
||||||
|
boxResults.push(centerCartographic);
|
||||||
|
for (let i = 0; i < coordinates.length; i++) {
|
||||||
|
const coord = coordinates[i];
|
||||||
|
let cartographic = Cesium.Cartographic.fromDegrees(coord[0], coord[1]);
|
||||||
|
boxResults.push(cartographic);
|
||||||
|
const coord1 = coordinates[i + 1];
|
||||||
|
if (coord1) {
|
||||||
|
let newCoord = [
|
||||||
|
(coord[0] + coord1[0]) / 2,
|
||||||
|
(coord[1] + coord1[1]) / 2,
|
||||||
|
];
|
||||||
|
let newCartographic = Cesium.Cartographic.fromDegrees(
|
||||||
|
newCoord[0],
|
||||||
|
newCoord[1]
|
||||||
|
);
|
||||||
|
boxResults.push(newCartographic);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let _this = this
|
||||||
|
// 点位过多,分为三份计算
|
||||||
|
let num = (Math.floor(boxResults.length / 3) + '')
|
||||||
|
num = Number(num.substring(0, num.length - 1))*10
|
||||||
|
let i=0
|
||||||
|
let points = boxResults.slice(i * num, (i + 1) * num)
|
||||||
|
if (points.length > 0) {
|
||||||
|
sampleTerrainMostDetailed(points)
|
||||||
|
}
|
||||||
|
function sampleTerrainMostDetailed(ps) {
|
||||||
|
Cesium.sampleTerrainMostDetailed(
|
||||||
|
_this.viewer.scene.terrainProvider,
|
||||||
|
ps
|
||||||
|
).then((updatePositions) => {
|
||||||
|
i++
|
||||||
|
let points = boxResults.slice(i * num, (i + 1) * num)
|
||||||
|
if (points.length > 0) {
|
||||||
|
sampleTerrainMostDetailed(points)
|
||||||
|
}
|
||||||
|
let arrr = [];
|
||||||
|
let ellipseResults = updatePositions.reduce(function (
|
||||||
|
pre,
|
||||||
|
item,
|
||||||
|
index,
|
||||||
|
updatePositions
|
||||||
|
) {
|
||||||
|
var begin = index * 10;
|
||||||
|
var end = begin + 10;
|
||||||
|
var res = updatePositions.slice(begin, end);
|
||||||
|
if (res.length != 0) {
|
||||||
|
arrr[index] = res;
|
||||||
|
}
|
||||||
|
return arrr;
|
||||||
|
},
|
||||||
|
[]);
|
||||||
|
_this.calculateSlope(ellipseResults);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
createPolygonInsrance(points, color, curSlope) {
|
||||||
|
let positions = [];
|
||||||
|
for (let index = 1; index < points.length - 1; index++) {
|
||||||
|
const element = points[index];
|
||||||
|
positions.push(Cesium.Cartographic.toCartesian(element));
|
||||||
|
}
|
||||||
|
let polygon = new Cesium.PolygonGeometry({
|
||||||
|
polygonHierarchy: new Cesium.PolygonHierarchy(positions),
|
||||||
|
});
|
||||||
|
|
||||||
|
let polygonInstance = new Cesium.GeometryInstance({
|
||||||
|
id: {
|
||||||
|
type: "SlopeAspect",
|
||||||
|
value: curSlope
|
||||||
|
},
|
||||||
|
geometry: polygon,
|
||||||
|
attributes: {
|
||||||
|
color: Cesium.ColorGeometryInstanceAttribute.fromColor(
|
||||||
|
Cesium.Color.fromCssColorString(color)
|
||||||
|
),
|
||||||
|
show: new Cesium.ShowGeometryInstanceAttribute(true), //显示或者隐藏
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return polygonInstance;
|
||||||
|
}
|
||||||
|
createArrowInstance(
|
||||||
|
targetPoint,
|
||||||
|
center,
|
||||||
|
diagonalPoint,
|
||||||
|
heightDifference,
|
||||||
|
curSlope
|
||||||
|
) {
|
||||||
|
let cartographic_0 = new Cesium.Cartographic(
|
||||||
|
(targetPoint.longitude + center.longitude) / 2,
|
||||||
|
(targetPoint.latitude + center.latitude) / 2,
|
||||||
|
(targetPoint.height + center.height) / 2
|
||||||
|
);
|
||||||
|
let cartographic_1 = new Cesium.Cartographic(
|
||||||
|
(diagonalPoint.longitude + center.longitude) / 2,
|
||||||
|
(diagonalPoint.latitude + center.latitude) / 2,
|
||||||
|
(diagonalPoint.height + center.height) / 2
|
||||||
|
);
|
||||||
|
//偏移的
|
||||||
|
let positions1 =
|
||||||
|
heightDifference > 0
|
||||||
|
? [
|
||||||
|
Cesium.Cartographic.toCartesian(cartographic_0),
|
||||||
|
Cesium.Cartographic.toCartesian(cartographic_1),
|
||||||
|
]
|
||||||
|
: [
|
||||||
|
Cesium.Cartographic.toCartesian(cartographic_1),
|
||||||
|
Cesium.Cartographic.toCartesian(cartographic_0),
|
||||||
|
];
|
||||||
|
//箭头线
|
||||||
|
const instance = new Cesium.GeometryInstance({
|
||||||
|
id: {
|
||||||
|
type: "SlopeAspect",
|
||||||
|
value: curSlope,
|
||||||
|
},
|
||||||
|
geometry: new Cesium.GroundPolylineGeometry({
|
||||||
|
positions: positions1,
|
||||||
|
width: this.arrowWidth,
|
||||||
|
}),
|
||||||
|
attributes: {
|
||||||
|
color: Cesium.ColorGeometryInstanceAttribute.fromColor(
|
||||||
|
Cesium.Color.BLUE.withAlpha(0.6)
|
||||||
|
),
|
||||||
|
show: new Cesium.ShowGeometryInstanceAttribute(true), //显示或者隐藏
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
calculateSlope(ellipseResults) {
|
||||||
|
let instances = [];
|
||||||
|
let polygonInstance = [];
|
||||||
|
for (let index = 0; index < ellipseResults.length; index++) {
|
||||||
|
const ellipse = ellipseResults[index];
|
||||||
|
|
||||||
|
const center = ellipse[0];
|
||||||
|
let heightDifference = 0;
|
||||||
|
let maxIndex = 0;
|
||||||
|
for (let i = 1; i < ellipse.length - 1; i++) {
|
||||||
|
const point = ellipse[i];
|
||||||
|
let curHD = point.height - center.height;
|
||||||
|
if (Math.abs(curHD) > heightDifference) {
|
||||||
|
heightDifference = curHD;
|
||||||
|
maxIndex = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let pos0 = new Cesium.Cartographic(center.longitude, center.latitude, 0);
|
||||||
|
let pos1 = new Cesium.Cartographic(
|
||||||
|
ellipse[maxIndex].longitude,
|
||||||
|
ellipse[maxIndex].latitude,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
let distance = Cesium.Cartesian3.distance(
|
||||||
|
Cesium.Cartographic.toCartesian(pos0),
|
||||||
|
Cesium.Cartographic.toCartesian(pos1)
|
||||||
|
);
|
||||||
|
let curSlope = Math.abs(heightDifference / distance); //坡度的tan值
|
||||||
|
let curColor = this.calculateSlopeColor(curSlope, 0.4);
|
||||||
|
const curPolygonInstance = this.createPolygonInsrance(ellipse, curColor, curSlope);
|
||||||
|
polygonInstance.push(curPolygonInstance);
|
||||||
|
|
||||||
|
let diagonalPoint =
|
||||||
|
maxIndex > 4 ? ellipse[maxIndex - 4] : ellipse[maxIndex + 4]; //对角点
|
||||||
|
let targetPoint = ellipse[maxIndex];
|
||||||
|
const arrowInstance = this.createArrowInstance(
|
||||||
|
targetPoint,
|
||||||
|
center,
|
||||||
|
diagonalPoint,
|
||||||
|
heightDifference,
|
||||||
|
curSlope
|
||||||
|
);
|
||||||
|
instances.push(arrowInstance);
|
||||||
|
}
|
||||||
|
const mapPrimitive = this.viewer.scene.primitives.add(
|
||||||
|
new Cesium.GroundPrimitive({
|
||||||
|
geometryInstances: polygonInstance,
|
||||||
|
appearance: new Cesium.PerInstanceColorAppearance({
|
||||||
|
translucent: true, //false时透明度无效
|
||||||
|
closed: false,
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
);
|
||||||
|
const arrowPrimitive = this.viewer.scene.primitives.add(
|
||||||
|
new Cesium.GroundPolylinePrimitive({
|
||||||
|
geometryInstances: instances,
|
||||||
|
appearance: new Cesium.PolylineMaterialAppearance({
|
||||||
|
material: new Cesium.Material({
|
||||||
|
fabric: {
|
||||||
|
type: "PolylineArrow",
|
||||||
|
uniforms: {
|
||||||
|
color: new Cesium.Color(1.0, 1.0, 0.0, 0.8),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
);
|
||||||
|
this.result.push(arrowPrimitive, mapPrimitive);
|
||||||
|
|
||||||
|
this.event = new MouseEvent(this.sdk)
|
||||||
|
let mouseEvent = (movement, cartesian) => {
|
||||||
|
// console.log(movement, cartesian)
|
||||||
|
let infoBox = document.getElementById('SlopeAspect-box')
|
||||||
|
if (!infoBox) {
|
||||||
|
infoBox = document.createElement('div')
|
||||||
|
infoBox.id = 'SlopeAspect-box'
|
||||||
|
infoBox.style.pointerEvents = 'none'
|
||||||
|
infoBox.style.display = 'none'
|
||||||
|
infoBox.style.position = 'absolute'
|
||||||
|
infoBox.style.background = '#333333'
|
||||||
|
infoBox.style.color = '#fff'
|
||||||
|
infoBox.style.color = '#fff'
|
||||||
|
infoBox.style.padding = '5px'
|
||||||
|
infoBox.style.fontSize = '12px'
|
||||||
|
infoBox.style.borderRadius = '5px'
|
||||||
|
infoBox.style.transform = 'translate(-50%, -10px)'
|
||||||
|
infoBox.innerHTML = `
|
||||||
|
<div class="value">坡度:</div>
|
||||||
|
<span style="
|
||||||
|
position: absolute;
|
||||||
|
border: 4px solid;
|
||||||
|
border-color: #fff0 #fff0 #333333 #333333;
|
||||||
|
transform: rotate(-45deg);
|
||||||
|
left: calc(50% - 5px);
|
||||||
|
"></span>
|
||||||
|
`
|
||||||
|
document.body.appendChild(infoBox)
|
||||||
|
}
|
||||||
|
let vlaElm = infoBox.getElementsByClassName('value')[0]
|
||||||
|
let position = { ...movement.position }
|
||||||
|
let pickedObject = this.sdk.viewer.scene.pick(position);
|
||||||
|
if (pickedObject && pickedObject.id && pickedObject.id.type && pickedObject.id.type === "SlopeAspect") {
|
||||||
|
let top = 0
|
||||||
|
let left = 0
|
||||||
|
|
||||||
|
if (this.sdk.viewer && this.sdk.viewer._element) {
|
||||||
|
let element = this.sdk.viewer._element.getElementsByClassName('cesium-widget')[0].getElementsByTagName('canvas')[0]
|
||||||
|
top = element.getBoundingClientRect().top + window.scrollY
|
||||||
|
left = element.getBoundingClientRect().left + window.scrollX
|
||||||
|
}
|
||||||
|
infoBox.style.display = 'block'
|
||||||
|
infoBox.style.left = position.x + 2 + left + 'px'
|
||||||
|
infoBox.style.top = position.y - 20 + top + 'px'
|
||||||
|
vlaElm.innerHTML = '坡度:' + Number(Cesium.Math.toDegrees(pickedObject.id.value || 0).toFixed(2)) + '°'
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
infoBox.style.display = 'none'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.event.mouse_move((movement, cartesian) => {
|
||||||
|
let newMovement = {
|
||||||
|
position: { ...movement.endPosition }
|
||||||
|
}
|
||||||
|
mouseEvent(newMovement, cartesian)
|
||||||
|
})
|
||||||
|
this.event.mouse_left(mouseEvent)
|
||||||
|
|
||||||
|
this._camera = {
|
||||||
|
position: this.sdk.viewer.camera.position,
|
||||||
|
heading: this.sdk.viewer.camera.heading,
|
||||||
|
pitch: this.sdk.viewer.camera.pitch,
|
||||||
|
roll: this.sdk.viewer.camera.roll
|
||||||
|
}
|
||||||
|
this.sdk.viewer.scene.preRender.addEventListener(this._watchEvent, this)
|
||||||
|
// this.sdk.viewer.clock.onTick.addEventListener(() => {
|
||||||
|
// console.log(111111)
|
||||||
|
// let infoBox = document.getElementById('SlopeAspect-box')
|
||||||
|
// if(infoBox) {
|
||||||
|
// infoBox.style.display = 'none'
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
}
|
||||||
|
|
||||||
|
_watchEvent() {
|
||||||
|
if (
|
||||||
|
this._camera.position.x.toFixed(8) !== this.sdk.viewer.camera.position.x.toFixed(8) ||
|
||||||
|
this._camera.position.y.toFixed(8) !== this.sdk.viewer.camera.position.y.toFixed(8) ||
|
||||||
|
this._camera.position.z.toFixed(8) !== this.sdk.viewer.camera.position.z.toFixed(8) ||
|
||||||
|
this._camera.heading.toFixed(8) !== this.sdk.viewer.camera.heading.toFixed(8) ||
|
||||||
|
this._camera.pitch.toFixed(8) !== this.sdk.viewer.camera.pitch.toFixed(8) ||
|
||||||
|
this._camera.roll.toFixed(8) !== this.sdk.viewer.camera.roll.toFixed(8)
|
||||||
|
) {
|
||||||
|
let infoBox = document.getElementById('SlopeAspect-box')
|
||||||
|
if (infoBox) {
|
||||||
|
infoBox.style.display = 'none'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this._camera = {
|
||||||
|
position: this.sdk.viewer.camera.position,
|
||||||
|
heading: this.sdk.viewer.camera.heading,
|
||||||
|
pitch: this.sdk.viewer.camera.pitch,
|
||||||
|
roll: this.sdk.viewer.camera.roll
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//根据坡度值赋值颜色
|
||||||
|
calculateSlopeColor(value, alpha) {
|
||||||
|
// 0°~0.5°为平原0.00872686779075879,rgb(85,182,43)
|
||||||
|
// 0.5°~2°为微斜坡0.03492076949174773,rgb(135,211,43)
|
||||||
|
// 2°~5°为缓斜坡0.08748866352592401,rgb(204,244,44)
|
||||||
|
// 5°~15°为斜坡0.2679491924311227,rgb(245,233,44)
|
||||||
|
// 15°~35°为陡坡0.7002075382097097,rgb(255,138,43)
|
||||||
|
// 35°~55°为峭坡1.4281480067421144,rgb(255,84,43)
|
||||||
|
// 55°~90°为垂直壁,rgb(255,32,43)
|
||||||
|
if (value < 0.00872686779075879) {
|
||||||
|
return "rgba(85,182,43," + alpha + ")";
|
||||||
|
} else if (value < 0.03492076949174773) {
|
||||||
|
return "rgba(135,211,43," + alpha + ")";
|
||||||
|
} else if (value < 0.08748866352592401) {
|
||||||
|
return "rgba(204,244,44," + alpha + ")";
|
||||||
|
} else if (value < 0.2679491924311227) {
|
||||||
|
return "rgba(245,233,44," + alpha + ")";
|
||||||
|
} else if (value < 0.7002075382097097) {
|
||||||
|
return "rgba(255,138,43," + alpha + ")";
|
||||||
|
} else if (value < 1.4281480067421144) {
|
||||||
|
return "rgba(255,84,43," + alpha + ")";
|
||||||
|
} else {
|
||||||
|
return "rgba(255,32,43," + alpha + ")";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
destroy() {
|
||||||
|
this.result && this.result.forEach((element) => {
|
||||||
|
this.viewer.scene.primitives.remove(element);
|
||||||
|
});
|
||||||
|
this.result = [];
|
||||||
|
this.sdk.viewer.scene.preRender.removeEventListener(this._watchEvent, this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export default SlopeAspect;
|
||||||
92
src/Obj/Analysis/Submerge/_element.js
Normal file
92
src/Obj/Analysis/Submerge/_element.js
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
function html() {
|
||||||
|
return `
|
||||||
|
<span class="custom-divider"></span>
|
||||||
|
<div class="div-item">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<span class="label">水量</span>
|
||||||
|
<div class="input-number input-number-unit-3">
|
||||||
|
<input class="input" type="number" title="" name="waterVolume">
|
||||||
|
<span class="unit">m³</span>
|
||||||
|
<span class="arrow"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<span class="label">最小水位</span>
|
||||||
|
<div class="input-number input-number-unit-3">
|
||||||
|
<input class="input" type="number" title="" name="minWaterLevel">
|
||||||
|
<span class="unit">m</span>
|
||||||
|
<span class="arrow"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<span class="label">水面面积</span>
|
||||||
|
<div class="input-number input-number-unit-3">
|
||||||
|
<input class="input area" type="number" readonly="readonly" type="text">
|
||||||
|
<span class="unit">㎡</span>
|
||||||
|
<span class="arrow"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<span class="label">最大水位</span>
|
||||||
|
<div class="input-number input-number-unit-3">
|
||||||
|
<input class="input" type="number" title="" name="maxWaterLevel">
|
||||||
|
<span class="unit">m</span>
|
||||||
|
<span class="arrow"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<span class="custom-divider"></span>
|
||||||
|
<div class="div-item">
|
||||||
|
<div class="row subtitle-box">
|
||||||
|
<span class="subtitle">上升速度</span>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<input type="range" max="50" min="0" step="0.01" name="risingSpeed">
|
||||||
|
<div class="input-number input-number-unit-3" style="flex: 0 0 110px;margin-left: 10px;">
|
||||||
|
<input class="input" type="number" title="" name="risingSpeed">
|
||||||
|
<span class="unit">m/s</span>
|
||||||
|
<span class="arrow"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<span class="custom-divider"></span>
|
||||||
|
<div class="div-item">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col operate-btn-box">
|
||||||
|
<button class="draw"><svg class="icon-draw"><use xlink:href="#yj-icon-draw"></use></svg>绘制范围</button>
|
||||||
|
<button class="flyto"><svg class="icon-positions"><use xlink:href="#yj-icon-positions"></use></svg>定位</button>
|
||||||
|
<button class="reset"><svg class="icon-reset"><use xlink:href="#yj-icon-reset"></use></svg>重置</button>
|
||||||
|
<button class="analog"><svg class="icon-play"><use xlink:href="#yj-icon-play"></use></svg>开始模拟</button>
|
||||||
|
<button class="pause" style="margin-right: 0px;"><svg class="icon-pause"><use xlink:href="#yj-icon-pause"></use></svg>暂停</button>
|
||||||
|
<button class="start" style="display: none;margin-right: 0px;"><svg class="icon-play"><use xlink:href="#yj-icon-play"></use></svg>播放</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="table">
|
||||||
|
<div class="table-head">
|
||||||
|
<div class="tr">
|
||||||
|
<div class="th">序号</div>
|
||||||
|
<div class="th">经度</div>
|
||||||
|
<div class="th">纬度</div>
|
||||||
|
<div class="th">高程</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="table-body">
|
||||||
|
</div>
|
||||||
|
<div class="table-empty">
|
||||||
|
<div class="empty-img"></div>
|
||||||
|
<p>暂无数据</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<span class="custom-divider" style="margin-top: 20px;"></span>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
|
export { html }
|
||||||
484
src/Obj/Analysis/Submerge/index.js
Normal file
484
src/Obj/Analysis/Submerge/index.js
Normal file
@ -0,0 +1,484 @@
|
|||||||
|
import Dialog from '../../../BaseDialog';
|
||||||
|
import { html } from "./_element";
|
||||||
|
import DrawPolygon from "../../../Draw/drawPolygon"
|
||||||
|
import Tools from "../../../Tools";
|
||||||
|
import { closeRotateAround, closeViewFollow} from '../../../Global/global'
|
||||||
|
class Submerge extends Tools {
|
||||||
|
/**
|
||||||
|
* @constructor
|
||||||
|
* @param sdk
|
||||||
|
* @description 淹没效果
|
||||||
|
* */
|
||||||
|
constructor(sdk, options = {}, _Dialog = {}) {
|
||||||
|
super(sdk, options);
|
||||||
|
this.sdk = sdk
|
||||||
|
this.options = {}
|
||||||
|
this.options.name = options.name
|
||||||
|
this.options.risingSpeed = 1
|
||||||
|
this.options.minWaterLevel = 0
|
||||||
|
this.options.maxWaterLevel = 0
|
||||||
|
this.options.waterVolume = 0
|
||||||
|
this.currentWaterLaver
|
||||||
|
this.color = '#00d9ff66'
|
||||||
|
this.Dialog = _Dialog
|
||||||
|
this.Draw = new DrawPolygon(this.sdk)
|
||||||
|
this.positions
|
||||||
|
this.status = true
|
||||||
|
this.area = 0
|
||||||
|
this._elms = {};
|
||||||
|
YJ.Analysis.Analyses.push(this)
|
||||||
|
Submerge.EditBox(this)
|
||||||
|
// Submerge.create(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
static create(that) {
|
||||||
|
that.Draw.start((a, positions) => {
|
||||||
|
if (!positions || positions.length < 3) {
|
||||||
|
let _error = '至少需要三个坐标!'
|
||||||
|
console.warn(_error)
|
||||||
|
window.ELEMENT &&
|
||||||
|
window.ELEMENT.Message({
|
||||||
|
message: _error,
|
||||||
|
type: 'warning',
|
||||||
|
duration: 1500
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
that.destroy()
|
||||||
|
if (!positions || positions.length == 0) {
|
||||||
|
that.positions = []
|
||||||
|
that._positions = []
|
||||||
|
that.options.minWaterLevel = 0
|
||||||
|
that.options.maxWaterLevel = 0
|
||||||
|
that.options.waterVolume = 0
|
||||||
|
that.area = 0
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let fromDegreesArray = []
|
||||||
|
that.positions = positions
|
||||||
|
that._positions = positions
|
||||||
|
that.options.minWaterLevel = positions[0].alt
|
||||||
|
for (let i = 0; i < positions.length; i++) {
|
||||||
|
if (that.options.minWaterLevel > positions[i].alt) {
|
||||||
|
that.options.minWaterLevel = positions[i].alt
|
||||||
|
}
|
||||||
|
fromDegreesArray.push(positions[i].lng, positions[i].lat)
|
||||||
|
}
|
||||||
|
// for (let i = 0; i < positions.length; i++) {
|
||||||
|
// fromDegreesArray.push(positions[i].lng, positions[i].lat, that.options.minWaterLevel)
|
||||||
|
// }
|
||||||
|
let pos = Cesium.Cartesian3.fromDegreesArray(fromDegreesArray)
|
||||||
|
that.currentWaterLaver = that.options.minWaterLevel
|
||||||
|
that.entity = that.sdk.viewer.entities.add({
|
||||||
|
polygon: {
|
||||||
|
hierarchy: new Cesium.PolygonHierarchy(pos),
|
||||||
|
height: new Cesium.CallbackProperty(function () {
|
||||||
|
return that.options.minWaterLevel
|
||||||
|
}, false),
|
||||||
|
extrudedHeight: new Cesium.CallbackProperty(function () {
|
||||||
|
return that.currentWaterLaver
|
||||||
|
}, false),
|
||||||
|
material: Cesium.Color.fromCssColorString(that.color),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
that.area = that.computeArea(positions)
|
||||||
|
if (that.TweenAnimate) {
|
||||||
|
TWEEN.remove(that.TweenAnimate)
|
||||||
|
that.TweenAnimate = null
|
||||||
|
}
|
||||||
|
let contentElm = that._DialogObject._element.body
|
||||||
|
let pauseBtn = contentElm.getElementsByClassName('pause')[0];
|
||||||
|
let startBtn = contentElm.getElementsByClassName('start')[0];
|
||||||
|
startBtn.style.display = 'flex'
|
||||||
|
pauseBtn.style.display = 'none'
|
||||||
|
// that.move()
|
||||||
|
// Submerge.EditBox(that)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
static async EditBox(that) {
|
||||||
|
if (that._DialogObject && that._DialogObject.close) {
|
||||||
|
that._DialogObject.close()
|
||||||
|
that._DialogObject = null
|
||||||
|
}
|
||||||
|
that._DialogObject = await new Dialog(that.sdk.viewer._container, {
|
||||||
|
title: '淹没分析', left: '180px', top: '100px',
|
||||||
|
closeCallBack: () => {
|
||||||
|
that.destroy()
|
||||||
|
that.Dialog.closeCallBack && that.Dialog.closeCallBack()
|
||||||
|
},
|
||||||
|
})
|
||||||
|
await that._DialogObject.init()
|
||||||
|
that._DialogObject._element.body.className = that._DialogObject._element.body.className + ' submerge'
|
||||||
|
let contentElm = document.createElement('div');
|
||||||
|
contentElm.innerHTML = html()
|
||||||
|
that._DialogObject.contentAppChild(contentElm)
|
||||||
|
let stopBtn = document.createElement('button');
|
||||||
|
stopBtn.className = 'el-button'
|
||||||
|
stopBtn.innerHTML = '暂停'
|
||||||
|
stopBtn.style.width = '80px'
|
||||||
|
|
||||||
|
let drawBtn = contentElm.getElementsByClassName('draw')[0]
|
||||||
|
drawBtn.addEventListener('click', () => {
|
||||||
|
Submerge.create(that)
|
||||||
|
})
|
||||||
|
let analogBtn = contentElm.getElementsByClassName('analog')[0];
|
||||||
|
analogBtn.addEventListener('click', () => {
|
||||||
|
that.move()
|
||||||
|
})
|
||||||
|
let flytoBtn = contentElm.getElementsByClassName('flyto')[0];
|
||||||
|
flytoBtn.addEventListener('click', () => {
|
||||||
|
that.flyTo()
|
||||||
|
})
|
||||||
|
let resetBtn = contentElm.getElementsByClassName('reset')[0];
|
||||||
|
resetBtn.addEventListener('click', () => {
|
||||||
|
that.restart()
|
||||||
|
})
|
||||||
|
let pauseBtn = contentElm.getElementsByClassName('pause')[0];
|
||||||
|
let startBtn = contentElm.getElementsByClassName('start')[0];
|
||||||
|
pauseBtn.addEventListener('click', () => {
|
||||||
|
that.pause()
|
||||||
|
pauseBtn.style.display = 'none'
|
||||||
|
startBtn.style.display = 'flex'
|
||||||
|
})
|
||||||
|
startBtn.addEventListener('click', () => {
|
||||||
|
that.start()
|
||||||
|
startBtn.style.display = 'none'
|
||||||
|
pauseBtn.style.display = 'flex'
|
||||||
|
})
|
||||||
|
|
||||||
|
// that._DialogObject.footAppChild(stopBtn)
|
||||||
|
// that._DialogObject.footAppChild(resetBtn)
|
||||||
|
// that._DialogObject.footAppChild(flytoBtn)
|
||||||
|
// that._DialogObject.footAppChild(analogBtn)
|
||||||
|
// that._DialogObject.footAppChild(drawBtn)
|
||||||
|
|
||||||
|
// 速度
|
||||||
|
let e_risingSpeed = contentElm.querySelectorAll("input[name='risingSpeed']")
|
||||||
|
e_risingSpeed[0].value = that.options.risingSpeed
|
||||||
|
e_risingSpeed[1].value = that.options.risingSpeed
|
||||||
|
e_risingSpeed[0].addEventListener('input', e => {
|
||||||
|
that.options.risingSpeed = Number(e.target.value);
|
||||||
|
});
|
||||||
|
e_risingSpeed[1].addEventListener('input', e => {
|
||||||
|
if (e.data != '.') {
|
||||||
|
let value = Number(e.target.value)
|
||||||
|
let max = Number(e_risingSpeed[0].max)
|
||||||
|
let min = Number(e_risingSpeed[0].min)
|
||||||
|
if (value > max) {
|
||||||
|
that.options.risingSpeed = max;
|
||||||
|
}
|
||||||
|
else if (value < min) {
|
||||||
|
that.options.risingSpeed = min;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
that.options.risingSpeed = Math.floor(value * 100) / 100;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Object.defineProperty(that.options, 'risingSpeed', {
|
||||||
|
get() {
|
||||||
|
return e_risingSpeed[0].value
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
e_risingSpeed[0].value = value
|
||||||
|
e_risingSpeed[1].value = value
|
||||||
|
}
|
||||||
|
})
|
||||||
|
that.waterLevel = that.options.maxWaterLevel - that.options.minWaterLevel
|
||||||
|
// 最低水位
|
||||||
|
let e_minWaterLevel = contentElm.querySelector("input[name='minWaterLevel']")
|
||||||
|
e_minWaterLevel.value = that.options.minWaterLevel
|
||||||
|
e_minWaterLevel.addEventListener('input', e => {
|
||||||
|
if (e.data != '.') {
|
||||||
|
let value = Number(e.target.value)
|
||||||
|
if (value > 999999999) {
|
||||||
|
value = 999999999
|
||||||
|
}
|
||||||
|
if (value < 0) {
|
||||||
|
value = 0
|
||||||
|
}
|
||||||
|
that.options.minWaterLevel = Math.floor(value * 10000) / 10000;
|
||||||
|
that.options.maxWaterLevel = that.options.minWaterLevel + that.waterLevel;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Object.defineProperty(that.options, 'minWaterLevel', {
|
||||||
|
get() {
|
||||||
|
return Number(e_minWaterLevel.value)
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
e_minWaterLevel.value = Math.floor(Number(value) * 10000) / 10000;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 最高水位
|
||||||
|
let e_maxWaterLevel = contentElm.querySelector("input[name='maxWaterLevel']")
|
||||||
|
e_maxWaterLevel.value = that.options.maxWaterLevel
|
||||||
|
e_maxWaterLevel.addEventListener('input', e => {
|
||||||
|
if (e.data != '.') {
|
||||||
|
let value = Number(e.target.value)
|
||||||
|
if (value > 999999999) {
|
||||||
|
value = 999999999
|
||||||
|
}
|
||||||
|
if (value < 0) {
|
||||||
|
value = 0
|
||||||
|
}
|
||||||
|
if (value < that.options.minWaterLevel) {
|
||||||
|
that.options.maxWaterLevel = that.options.minWaterLevel;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
that.options.maxWaterLevel = Math.floor(value * 10000) / 10000;
|
||||||
|
}
|
||||||
|
that.waterLevel = that.options.maxWaterLevel - that.options.minWaterLevel
|
||||||
|
that.options.waterVolume = Number((that.waterLevel * that.area).toFixed(4))
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Object.defineProperty(that.options, 'maxWaterLevel', {
|
||||||
|
get() {
|
||||||
|
return Number(e_maxWaterLevel.value)
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
if (isNaN(value)) {
|
||||||
|
value = 0
|
||||||
|
}
|
||||||
|
e_maxWaterLevel.value = Math.floor(Number(value) * 10000) / 10000;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 水量
|
||||||
|
let e_waterVolume = contentElm.querySelector("input[name='waterVolume']")
|
||||||
|
e_waterVolume.value = that.options.waterVolume
|
||||||
|
e_waterVolume.addEventListener('input', e => {
|
||||||
|
if (e.data != '.') {
|
||||||
|
let value = Number(e.target.value)
|
||||||
|
if (value > 99999999999999) {
|
||||||
|
value = 99999999999999
|
||||||
|
}
|
||||||
|
if (value < 0) {
|
||||||
|
value = 0
|
||||||
|
}
|
||||||
|
that.options.waterVolume = Math.floor(value * 10000) / 10000;
|
||||||
|
if (that.area) {
|
||||||
|
that.waterLevel = Number((that.options.waterVolume / that.area).toFixed(4))
|
||||||
|
that.options.maxWaterLevel = that.options.minWaterLevel + that.waterLevel
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Object.defineProperty(that.options, 'waterVolume', {
|
||||||
|
get() {
|
||||||
|
return Number(e_waterVolume.value)
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
e_waterVolume.value = value
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 面积
|
||||||
|
let e_area = contentElm.getElementsByClassName('area')[0]
|
||||||
|
e_area.value = that.area
|
||||||
|
Object.defineProperty(that, 'area', {
|
||||||
|
get() {
|
||||||
|
return Number(e_area.value)
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
e_area.value = value
|
||||||
|
that.waterLevel = Number((that.options.waterVolume / that.area).toFixed(4))
|
||||||
|
that.options.maxWaterLevel = that.options.minWaterLevel + that.waterLevel
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// 表格
|
||||||
|
let e_tableBody = contentElm.getElementsByClassName('table-body')[0]
|
||||||
|
let e_tableEmpty = contentElm.getElementsByClassName('table-empty')[0]
|
||||||
|
Object.defineProperty(that, 'positions', {
|
||||||
|
get() {
|
||||||
|
return that._positions
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
if (value && value.length > 0) {
|
||||||
|
e_tableEmpty.style.display = 'none'
|
||||||
|
let tr = ''
|
||||||
|
for (let i = 0; i < value.length; i++) {
|
||||||
|
tr = tr + `<div class="tr">
|
||||||
|
<div class="td">${i + 1}</div>
|
||||||
|
<div class="td">${Number(value[i].lng.toFixed(10))}</div>
|
||||||
|
<div class="td">${Number(value[i].lat.toFixed(10))}</div>
|
||||||
|
<div class="td">${Number(value[i].alt.toFixed(4))}</div>
|
||||||
|
</div>`
|
||||||
|
}
|
||||||
|
e_tableBody.innerHTML = tr
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
e_tableBody.innerHTML = ''
|
||||||
|
e_tableEmpty.style.display = 'flex'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
move() {
|
||||||
|
if (this.TweenAnimate) {
|
||||||
|
TWEEN.remove(this.TweenAnimate)
|
||||||
|
}
|
||||||
|
let totalTime = ((this.options.maxWaterLevel - this.options.minWaterLevel) / this.options.risingSpeed) * 1000
|
||||||
|
this.TweenAnimate = new TWEEN.Tween({ waterLevel: this.options.minWaterLevel }).to({ waterLevel: this.options.maxWaterLevel }, totalTime).delay(this.delay).easing(TWEEN.Easing.Linear.None).onUpdate(async (r, a) => {
|
||||||
|
this.currentWaterLaver = r.waterLevel
|
||||||
|
}).start()
|
||||||
|
let contentElm = this._DialogObject._element.body
|
||||||
|
let pauseBtn = contentElm.getElementsByClassName('pause')[0];
|
||||||
|
let startBtn = contentElm.getElementsByClassName('start')[0];
|
||||||
|
startBtn.style.display = 'none'
|
||||||
|
pauseBtn.style.display = 'flex'
|
||||||
|
}
|
||||||
|
|
||||||
|
restart() {
|
||||||
|
this.currentWaterLaver = this.options.minWaterLevel
|
||||||
|
let isPaused = false
|
||||||
|
if (this.TweenAnimate) {
|
||||||
|
isPaused = this.TweenAnimate._isPaused
|
||||||
|
TWEEN.remove(this.TweenAnimate)
|
||||||
|
}
|
||||||
|
let totalTime = ((this.options.maxWaterLevel - this.options.minWaterLevel) / this.options.risingSpeed) * 1000
|
||||||
|
this.TweenAnimate = new TWEEN.Tween({ waterLevel: this.options.minWaterLevel }).to({ waterLevel: this.options.maxWaterLevel }, totalTime).delay(this.delay).easing(TWEEN.Easing.Linear.None).onUpdate(async (r, a) => {
|
||||||
|
this.currentWaterLaver = r.waterLevel
|
||||||
|
}).start()
|
||||||
|
if (isPaused) {
|
||||||
|
this.pause()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
start() {
|
||||||
|
if (this.TweenAnimate) {
|
||||||
|
this.TweenAnimate.resume()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pause() {
|
||||||
|
if (this.TweenAnimate) {
|
||||||
|
this.TweenAnimate.pause()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
calculateVolumeHeight() {
|
||||||
|
that.options.maxWaterLevel
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 飞到
|
||||||
|
*/
|
||||||
|
flyTo() {
|
||||||
|
if (!this.positions || this.positions.length === 0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
closeRotateAround(this.sdk)
|
||||||
|
closeViewFollow(this.sdk)
|
||||||
|
|
||||||
|
let positionArray = []
|
||||||
|
for (let i = 0; i < this.positions.length; i++) {
|
||||||
|
let fromDegrees = Cesium.Cartesian3.fromDegrees(this.positions[i].lng, this.positions[i].lat, this.options.maxWaterLevel)
|
||||||
|
positionArray.push(fromDegrees.x, fromDegrees.y, fromDegrees.z)
|
||||||
|
}
|
||||||
|
let BoundingSphere = Cesium.BoundingSphere.fromVertices(positionArray)
|
||||||
|
this.sdk.viewer.camera.flyToBoundingSphere(BoundingSphere, {
|
||||||
|
offset: {
|
||||||
|
heading: Cesium.Math.toRadians(0.0),
|
||||||
|
pitch: Cesium.Math.toRadians(-90.0),
|
||||||
|
roll: Cesium.Math.toRadians(0.0)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
destroy() {
|
||||||
|
if (this.TweenAnimate) {
|
||||||
|
TWEEN.remove(this.TweenAnimate)
|
||||||
|
}
|
||||||
|
this.Draw.end()
|
||||||
|
this.sdk.viewer.entities.remove(this.entity)
|
||||||
|
this.entity = null
|
||||||
|
}
|
||||||
|
|
||||||
|
static EventBinding(that, elements) {
|
||||||
|
for (let i = 0; i < elements.length; i++) {
|
||||||
|
let Event = []
|
||||||
|
let isEvent = false
|
||||||
|
let removeName = []
|
||||||
|
if (!elements[i] || !elements[i].attributes) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (let m of elements[i].attributes) {
|
||||||
|
switch (m.name) {
|
||||||
|
case '@model': {
|
||||||
|
isEvent = true
|
||||||
|
if (elements[i].type == 'checkbox') {
|
||||||
|
Event.push((e) => { that[m.value] = e.target.checked })
|
||||||
|
elements[i].checked = that[m.value]
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Event.push((e) => {
|
||||||
|
let value = e.target.value
|
||||||
|
if (e.target.type == 'number') {
|
||||||
|
value = Number(value)
|
||||||
|
}
|
||||||
|
that[m.value] = value
|
||||||
|
})
|
||||||
|
if (elements[i].nodeName == 'IMG') {
|
||||||
|
elements[i].src = that[m.value]
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
elements[i].value = that[m.value]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (that._elms[m.value]) {
|
||||||
|
that._elms[m.value].push(elements[i])
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
that._elms[m.value] = [elements[i]]
|
||||||
|
}
|
||||||
|
removeName.push(m.name)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case '@click': {
|
||||||
|
elements[i].addEventListener('click', (e) => {
|
||||||
|
if (typeof (that[m.value]) === 'function') {
|
||||||
|
that[m.value](e)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
removeName.push(m.name)
|
||||||
|
// elements[i].attributes.removeNamedItem(m.name)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case '@change': {
|
||||||
|
isEvent = true
|
||||||
|
Event.push((e) => {
|
||||||
|
let value = e.target.value
|
||||||
|
if (e.target.type == 'number' && value != '') {
|
||||||
|
value = Number(value)
|
||||||
|
e.target.value = value
|
||||||
|
}
|
||||||
|
if (typeof (that[m.value]) === 'function') {
|
||||||
|
that[m.value](e, value)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// elements[i].attributes[m] = undefined
|
||||||
|
}
|
||||||
|
for (let n = 0; n < removeName.length; n++) {
|
||||||
|
elements[i].attributes.removeNamedItem(removeName[n])
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isEvent) {
|
||||||
|
let ventType = 'input'
|
||||||
|
if (elements[i].tagName != 'INPUT' || elements[i].type == 'checkbox') {
|
||||||
|
ventType = 'change'
|
||||||
|
}
|
||||||
|
elements[i].addEventListener(ventType, (e) => {
|
||||||
|
for (let t = 0; t < Event.length; t++) {
|
||||||
|
Event[t](e)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Submerge
|
||||||
32
src/Obj/Analysis/TerrainExcavation/_element.js
Normal file
32
src/Obj/Analysis/TerrainExcavation/_element.js
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
function html() {
|
||||||
|
return `
|
||||||
|
<span class="custom-divider"></span>
|
||||||
|
<div class="div-item">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<span class="label" style="flex: 0 0 70px;">挖掘高度</span>
|
||||||
|
<div class="input-number input-number-unit-1">
|
||||||
|
<input class="input" type="number" title="" min="0" max="5000000" name="height">
|
||||||
|
<span class="unit">m</span>
|
||||||
|
<span class="arrow"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<span class="custom-divider"></span>
|
||||||
|
<div class="div-item">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<span class="label">绘制开挖区域</span>
|
||||||
|
<button class="start-excavation"><svg class="icon-edit"><use xlink:href="#yj-icon-edit"></use></svg>绘制</button>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<span class="label">清除开挖区域</span>
|
||||||
|
<button class="clean-excavation"><svg class="icon-close"><use xlink:href="#yj-icon-close"></use></svg>清除</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
|
export { html }
|
||||||
459
src/Obj/Analysis/TerrainExcavation/index.js
Normal file
459
src/Obj/Analysis/TerrainExcavation/index.js
Normal file
@ -0,0 +1,459 @@
|
|||||||
|
import Tools from "../../../Tools";
|
||||||
|
import DrawPolygon from "../../../Draw/drawPolygon"
|
||||||
|
import Dialog from '../../../BaseDialog';
|
||||||
|
import { html } from "./_element";
|
||||||
|
|
||||||
|
let ExcavationFaces = []
|
||||||
|
class TerrainExcavation extends Tools {
|
||||||
|
/**
|
||||||
|
* @constructor
|
||||||
|
* @description 地形开挖
|
||||||
|
* @param sdk
|
||||||
|
* */
|
||||||
|
constructor(sdk, options = {}) {
|
||||||
|
super(sdk)
|
||||||
|
this.viewer = sdk.viewer
|
||||||
|
this.options = options || {};
|
||||||
|
this.options.height = (this.options.height || this.options.height === 0) ? this.options.height : 10;
|
||||||
|
this.options.show = (this.options.show || this.options.show === false) ? this.options.show : true;
|
||||||
|
this.bottomImg = this.getSourceRootPath() + '/img/excavationregion_top.jpg';
|
||||||
|
this.wallImg = this.getSourceRootPath() + '/img/excavationregion_side.jpg';
|
||||||
|
this.splitNum = Cesium.defaultValue(options.splitNum, 50);
|
||||||
|
this.Draw = new DrawPolygon(this.sdk)
|
||||||
|
this.bottomMaterial = Cesium.Material.fromType('Color', {
|
||||||
|
color: Cesium.Color.fromAlpha(Cesium.Color.fromCssColorString('#735d4f'))
|
||||||
|
})
|
||||||
|
this.wallMaterial = Cesium.Material.fromType('Color', {
|
||||||
|
color: Cesium.Color.fromAlpha(Cesium.Color.fromCssColorString('#976b4e'))
|
||||||
|
})
|
||||||
|
let imageBottom = new Image();
|
||||||
|
let wallBottom = new Image();
|
||||||
|
imageBottom.src = this.bottomImg;
|
||||||
|
wallBottom.src = this.wallImg;
|
||||||
|
imageBottom.crossOrigin = "Anonymous";
|
||||||
|
wallBottom.crossOrigin = "Anonymous";
|
||||||
|
imageBottom.onload = () => {
|
||||||
|
const canvas = document.createElement('canvas');
|
||||||
|
canvas.width = imageBottom.width;
|
||||||
|
canvas.height = imageBottom.height;
|
||||||
|
const context = canvas.getContext('2d');
|
||||||
|
context.drawImage(imageBottom, 0, 0, imageBottom.width, imageBottom.height);
|
||||||
|
const base64 = canvas.toDataURL('image/jpg');
|
||||||
|
this.bottomMaterial = new Cesium.Material({
|
||||||
|
fabric: {
|
||||||
|
type: "Image",
|
||||||
|
uniforms: {
|
||||||
|
image: base64,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (this.bottomSurface) {
|
||||||
|
this.bottomSurface.appearance.material = this.bottomMaterial;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
wallBottom.onload = () => {
|
||||||
|
const canvas = document.createElement('canvas');
|
||||||
|
canvas.width = wallBottom.width;
|
||||||
|
canvas.height = wallBottom.height;
|
||||||
|
const context = canvas.getContext('2d');
|
||||||
|
context.drawImage(wallBottom, 0, 0, wallBottom.width, wallBottom.height);
|
||||||
|
const base64 = canvas.toDataURL('image/jpg');
|
||||||
|
this.wallMaterial = new Cesium.Material({
|
||||||
|
fabric: {
|
||||||
|
type: "Image",
|
||||||
|
uniforms: {
|
||||||
|
image: base64,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (this.wellWall) {
|
||||||
|
this.wellWall.appearance.material = this.wallMaterial;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.init();
|
||||||
|
}
|
||||||
|
get show() {
|
||||||
|
return this.options.show
|
||||||
|
}
|
||||||
|
set show(v) {
|
||||||
|
this.options.show = v;
|
||||||
|
this.switchExcavate(v);
|
||||||
|
}
|
||||||
|
get height() {
|
||||||
|
return this.options.height
|
||||||
|
}
|
||||||
|
set height(v) {
|
||||||
|
this.options.height = v;
|
||||||
|
// this.updateExcavateDepth(v);
|
||||||
|
}
|
||||||
|
init() {
|
||||||
|
TerrainExcavation.edit(this, true)
|
||||||
|
}
|
||||||
|
static async edit(that, state) {
|
||||||
|
if (that._DialogObject && that._DialogObject.close) {
|
||||||
|
that._DialogObject.close()
|
||||||
|
that._DialogObject = null
|
||||||
|
}
|
||||||
|
if (state) {
|
||||||
|
that._DialogObject = await new Dialog(that.sdk.viewer._container, {
|
||||||
|
title: '地形开挖',
|
||||||
|
closeCallBack: () => {
|
||||||
|
},
|
||||||
|
})
|
||||||
|
await that._DialogObject.init()
|
||||||
|
that._DialogObject._element.body.className = that._DialogObject._element.body.className + ' terrain-excavation'
|
||||||
|
let contentElm = document.createElement('div');
|
||||||
|
contentElm.innerHTML = html()
|
||||||
|
that._DialogObject.contentAppChild(contentElm)
|
||||||
|
|
||||||
|
// 开始
|
||||||
|
let e_start = contentElm.getElementsByClassName('start-excavation')[0]
|
||||||
|
e_start.addEventListener('click', () => {
|
||||||
|
that.startCreate()
|
||||||
|
});
|
||||||
|
// 清除
|
||||||
|
let e_clean = contentElm.getElementsByClassName('clean-excavation')[0]
|
||||||
|
e_clean.addEventListener('click', () => {
|
||||||
|
that.clear()
|
||||||
|
});
|
||||||
|
|
||||||
|
// 高度值
|
||||||
|
let e_height = contentElm.querySelector("input[name='height']")
|
||||||
|
e_height.value = that.height
|
||||||
|
e_height.addEventListener('change', (e) => {
|
||||||
|
let value = e.target.value
|
||||||
|
value = Number(value)
|
||||||
|
if (value < 0.01) {
|
||||||
|
value = 0.01
|
||||||
|
e.target.value = value
|
||||||
|
that.height = value;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
e_height.addEventListener('blur', (e) => {
|
||||||
|
let value = e.target.value
|
||||||
|
value = Number(value)
|
||||||
|
if ((e.target.max) && value > Number(e.target.max)) {
|
||||||
|
value = Number(e.target.max)
|
||||||
|
}
|
||||||
|
if (value < 0.01) {
|
||||||
|
value = 0.01
|
||||||
|
}
|
||||||
|
e.target.value = value
|
||||||
|
that.height = value;
|
||||||
|
});
|
||||||
|
|
||||||
|
} else {
|
||||||
|
if (that._DialogObject && that._DialogObject.close) {
|
||||||
|
that._DialogObject.close()
|
||||||
|
that._DialogObject = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
startCreate() {
|
||||||
|
this.Draw.start((e, positions) => {
|
||||||
|
if (!positions || positions.length <= 2) {
|
||||||
|
window.ELEMENT && window.ELEMENT.Message({
|
||||||
|
message: '至少拥有三个坐标位置!',
|
||||||
|
type: 'warning',
|
||||||
|
duration: 1500
|
||||||
|
});
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if(!this.isConvex(positions)) {
|
||||||
|
window.ELEMENT && window.ELEMENT.Message({
|
||||||
|
message: '不支持凹多边形',
|
||||||
|
type: 'warning',
|
||||||
|
duration: 1500
|
||||||
|
});
|
||||||
|
console.log('不支持凹多边形')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.updateData(positions)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
updateData(activePoints) {
|
||||||
|
let viewer = this.viewer;
|
||||||
|
this.clear();
|
||||||
|
let clippingPlanesList = [];
|
||||||
|
let array = []
|
||||||
|
for (let i = 0; i < activePoints.length; i++) {
|
||||||
|
array.push([activePoints[i].lng, activePoints[i].lat])
|
||||||
|
}
|
||||||
|
array.push([activePoints[0].lng, activePoints[0].lat])
|
||||||
|
let clockwiseRing = turf.lineString(array);
|
||||||
|
// 是否顺时针
|
||||||
|
let boolDiff = turf.booleanClockwise(clockwiseRing);
|
||||||
|
this.excavateMinHeight = 9999;
|
||||||
|
for (let index = 0; index < activePoints.length; ++index) {
|
||||||
|
let s = (index + 1) % activePoints.length;
|
||||||
|
let position1 = Cesium.Cartesian3.fromDegrees(activePoints[index].lng, activePoints[index].lat, activePoints[index].alt)
|
||||||
|
let position2 = Cesium.Cartesian3.fromDegrees(activePoints[s].lng, activePoints[s].lat, activePoints[s].alt)
|
||||||
|
let curMidPoint = Cesium.Cartesian3.midpoint(
|
||||||
|
position1,
|
||||||
|
position2,
|
||||||
|
new Cesium.Cartesian3()
|
||||||
|
);
|
||||||
|
let cartographic = Cesium.Cartographic.fromCartesian(position1);
|
||||||
|
let curHeight =
|
||||||
|
viewer.scene.globe.getHeight(cartographic) || cartographic.height;
|
||||||
|
if (curHeight < this.excavateMinHeight) {
|
||||||
|
this.excavateMinHeight = curHeight;
|
||||||
|
}
|
||||||
|
let curMidPointNormal = Cesium.Cartesian3.normalize(
|
||||||
|
curMidPoint,
|
||||||
|
new Cesium.Cartesian3()
|
||||||
|
);
|
||||||
|
let curMidPointDifference = boolDiff
|
||||||
|
? Cesium.Cartesian3.subtract(
|
||||||
|
position1,
|
||||||
|
curMidPoint,
|
||||||
|
new Cesium.Cartesian3()
|
||||||
|
)
|
||||||
|
: Cesium.Cartesian3.subtract(
|
||||||
|
position2,
|
||||||
|
curMidPoint,
|
||||||
|
new Cesium.Cartesian3()
|
||||||
|
);
|
||||||
|
curMidPointDifference = Cesium.Cartesian3.normalize(
|
||||||
|
curMidPointDifference,
|
||||||
|
curMidPointDifference
|
||||||
|
);
|
||||||
|
let curMidPointCross = Cesium.Cartesian3.cross(
|
||||||
|
curMidPointDifference,
|
||||||
|
curMidPointNormal,
|
||||||
|
new Cesium.Cartesian3()
|
||||||
|
);
|
||||||
|
curMidPointCross = Cesium.Cartesian3.normalize(
|
||||||
|
curMidPointCross,
|
||||||
|
curMidPointCross
|
||||||
|
);
|
||||||
|
let plane = new Cesium.Plane(curMidPointCross, 0);
|
||||||
|
let distance = Cesium.Plane.getPointDistance(plane, curMidPoint);
|
||||||
|
clippingPlanesList.push(
|
||||||
|
new Cesium.ClippingPlane(curMidPointCross, distance)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
this.viewer.scene.globe.clippingPlanes = new Cesium.ClippingPlaneCollection(
|
||||||
|
{
|
||||||
|
planes: clippingPlanesList,
|
||||||
|
edgeWidth: 1,
|
||||||
|
edgeColor: Cesium.Color.WHITE,
|
||||||
|
enabled: true,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
this.prepareWell(activePoints);
|
||||||
|
this.createWell(this.wellData);
|
||||||
|
// this.viewer.entities.remove(this.drawGeomtry);
|
||||||
|
}
|
||||||
|
|
||||||
|
clear() {
|
||||||
|
if (this.viewer.scene.globe.clippingPlanes) {
|
||||||
|
this.viewer.scene.globe.clippingPlanes.removeAll();
|
||||||
|
this.viewer.scene.primitives.remove(this.bottomSurface);
|
||||||
|
this.viewer.scene.primitives.remove(this.wellWall);
|
||||||
|
this.viewer.scene.render();
|
||||||
|
}
|
||||||
|
for (let i = ExcavationFaces.length - 1; i >= 0; i--) {
|
||||||
|
this.viewer.scene.primitives.remove(ExcavationFaces[i]);
|
||||||
|
}
|
||||||
|
ExcavationFaces = []
|
||||||
|
this.Draw && this.Draw.end()
|
||||||
|
}
|
||||||
|
destroy() {
|
||||||
|
this.clear()
|
||||||
|
}
|
||||||
|
//计算并更新wellData
|
||||||
|
prepareWell(activePoints) {
|
||||||
|
let pointLength = activePoints.length;
|
||||||
|
let heightDiff = this.excavateMinHeight - this.height;
|
||||||
|
let no_height_top = [],
|
||||||
|
bottom_pos = [],
|
||||||
|
lerp_pos = [];
|
||||||
|
for (let l = 0; l < pointLength; l++) {
|
||||||
|
let u = l == pointLength - 1 ? 0 : l + 1;
|
||||||
|
let point0 = [
|
||||||
|
Cesium.Cartographic.fromDegrees(activePoints[l].lng, activePoints[l].lat, activePoints[l].alt).longitude,
|
||||||
|
Cesium.Cartographic.fromDegrees(activePoints[l].lng, activePoints[l].lat, activePoints[l].alt).latitude,
|
||||||
|
];
|
||||||
|
let point1 = [
|
||||||
|
Cesium.Cartographic.fromDegrees(activePoints[u].lng, activePoints[u].lat, activePoints[u].alt).longitude,
|
||||||
|
Cesium.Cartographic.fromDegrees(activePoints[u].lng, activePoints[u].lat, activePoints[u].alt).latitude,
|
||||||
|
];
|
||||||
|
if (0 == l) {
|
||||||
|
lerp_pos.push(new Cesium.Cartographic(point0[0], point0[1]));
|
||||||
|
bottom_pos.push(
|
||||||
|
Cesium.Cartesian3.fromRadians(point0[0], point0[1], heightDiff)
|
||||||
|
);
|
||||||
|
no_height_top.push(
|
||||||
|
Cesium.Cartesian3.fromRadians(point0[0], point0[1], 0)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
for (let p = 1; p <= this.splitNum; p++) {
|
||||||
|
let m = Cesium.Math.lerp(point0[0], point1[0], p / this.splitNum);
|
||||||
|
let g = Cesium.Math.lerp(point0[1], point1[1], p / this.splitNum);
|
||||||
|
(l == pointLength - 1 && p == this.splitNum) ||
|
||||||
|
(lerp_pos.push(new Cesium.Cartographic(m, g)),
|
||||||
|
bottom_pos.push(Cesium.Cartesian3.fromRadians(m, g, heightDiff)),
|
||||||
|
no_height_top.push(Cesium.Cartesian3.fromRadians(m, g, 0)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.wellData = {
|
||||||
|
lerp_pos: lerp_pos,
|
||||||
|
bottom_pos: bottom_pos,
|
||||||
|
no_height_top: no_height_top,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
//开始创建底面和侧面
|
||||||
|
createWell(wallData) {
|
||||||
|
let $this = this;
|
||||||
|
if (this.viewer.terrainProvider._layers) {
|
||||||
|
this.createBottomSurface(wallData.bottom_pos);
|
||||||
|
let positions = Cesium.sampleTerrainMostDetailed(
|
||||||
|
this.viewer.terrainProvider,
|
||||||
|
wallData.lerp_pos
|
||||||
|
);
|
||||||
|
positions.then((pos) => {
|
||||||
|
let positionList = [];
|
||||||
|
for (let index = 0; index < pos.length; index++) {
|
||||||
|
const element = pos[index];
|
||||||
|
let curPos = Cesium.Cartesian3.fromRadians(
|
||||||
|
element.longitude,
|
||||||
|
element.latitude,
|
||||||
|
element.height
|
||||||
|
);
|
||||||
|
positionList.push(curPos);
|
||||||
|
}
|
||||||
|
$this.createWellWall(wallData.bottom_pos, positionList);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.createBottomSurface(wallData.bottom_pos);
|
||||||
|
this.createWellWall(wallData.bottom_pos, wallData.no_height_top);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//坐标转换,转出经纬度格式
|
||||||
|
ellipsoidToDegree(pos) {
|
||||||
|
let cartesian3 = new Cesium.Cartesian3(pos.x, pos.y, pos.z);
|
||||||
|
let cartographic =
|
||||||
|
this.viewer.scene.globe.ellipsoid.cartesianToCartographic(cartesian3);
|
||||||
|
return {
|
||||||
|
longitude: Cesium.Math.toDegrees(cartographic.longitude),
|
||||||
|
latitude: Cesium.Math.toDegrees(cartographic.latitude),
|
||||||
|
altitude: cartographic.height,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
//创建地形开挖的底面对象
|
||||||
|
createBottomSurface(points) {
|
||||||
|
if (points.length) {
|
||||||
|
let minHeight = this.getMinHeight(points);
|
||||||
|
let positions = [];
|
||||||
|
for (let i = 0; i < points.length; i++) {
|
||||||
|
let curPoint = this.ellipsoidToDegree(points[i]);
|
||||||
|
positions.push(curPoint.longitude, curPoint.latitude, minHeight);
|
||||||
|
}
|
||||||
|
let polygon = new Cesium.PolygonGeometry({
|
||||||
|
polygonHierarchy: new Cesium.PolygonHierarchy(
|
||||||
|
Cesium.Cartesian3.fromDegreesArrayHeights(positions)
|
||||||
|
),
|
||||||
|
perPositionHeight: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
let appearance = new Cesium.MaterialAppearance({
|
||||||
|
translucent: false,
|
||||||
|
flat: true,
|
||||||
|
material: this.bottomMaterial,
|
||||||
|
});
|
||||||
|
this.bottomSurface = new Cesium.Primitive({
|
||||||
|
geometryInstances: new Cesium.GeometryInstance({
|
||||||
|
geometry: Cesium.PolygonGeometry.createGeometry(polygon),
|
||||||
|
}),
|
||||||
|
appearance: appearance,
|
||||||
|
asynchronous: false,
|
||||||
|
});
|
||||||
|
ExcavationFaces.push(this.bottomSurface);
|
||||||
|
this.viewer.scene.primitives.add(this.bottomSurface);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 创建地形开挖的侧面墙对象
|
||||||
|
createWellWall(bottomPos, positionList) {
|
||||||
|
let minHeight = this.getMinHeight(bottomPos);
|
||||||
|
let maxHeights = [],
|
||||||
|
minHeights = [];
|
||||||
|
for (let i = 0; i < positionList.length; i++) {
|
||||||
|
maxHeights.push(this.ellipsoidToDegree(positionList[i]).altitude);
|
||||||
|
minHeights.push(minHeight);
|
||||||
|
}
|
||||||
|
let wall = new Cesium.WallGeometry({
|
||||||
|
positions: positionList,
|
||||||
|
maximumHeights: maxHeights,
|
||||||
|
minimumHeights: minHeights,
|
||||||
|
});
|
||||||
|
let geometry = Cesium.WallGeometry.createGeometry(wall);
|
||||||
|
let appearance = new Cesium.MaterialAppearance({
|
||||||
|
translucent: false,
|
||||||
|
flat: true,
|
||||||
|
material: this.wallMaterial,
|
||||||
|
});
|
||||||
|
this.wellWall = new Cesium.Primitive({
|
||||||
|
geometryInstances: new Cesium.GeometryInstance({
|
||||||
|
geometry: geometry,
|
||||||
|
attributes: {
|
||||||
|
color: Cesium.ColorGeometryInstanceAttribute.fromColor(
|
||||||
|
Cesium.Color.GREY
|
||||||
|
),
|
||||||
|
},
|
||||||
|
id: "PitWall",
|
||||||
|
}),
|
||||||
|
appearance: appearance,
|
||||||
|
asynchronous: false,
|
||||||
|
});
|
||||||
|
ExcavationFaces.push(this.wellWall);
|
||||||
|
this.viewer.scene.primitives.add(this.wellWall);
|
||||||
|
}
|
||||||
|
//获取地形开挖最低点高程值
|
||||||
|
getMinHeight(points) {
|
||||||
|
let minHeight = 5000000;
|
||||||
|
let minPoint = null;
|
||||||
|
for (let i = 0; i < points.length; i++) {
|
||||||
|
let height = points[i]["z"];
|
||||||
|
if (height < minHeight) {
|
||||||
|
minHeight = height;
|
||||||
|
minPoint = this.ellipsoidToDegree(points[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return minPoint.altitude;
|
||||||
|
}
|
||||||
|
switchExcavate(show) {
|
||||||
|
if (show) {
|
||||||
|
this.viewer.scene.globe.material = null;
|
||||||
|
this.wellWall.show = true;
|
||||||
|
this.bottomSurface.show = true;
|
||||||
|
} else {
|
||||||
|
this.viewer.scene.globe.material = null;
|
||||||
|
this.wellWall.show = false;
|
||||||
|
this.bottomSurface.show = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
updateExcavateDepth(height) {
|
||||||
|
this.viewer.scene.primitives.remove(this.bottomSurface);
|
||||||
|
this.viewer.scene.primitives.remove(this.wellWall);
|
||||||
|
if (!this.wellData) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let lerp_pos = this.wellData.lerp_pos;
|
||||||
|
let posList = [];
|
||||||
|
for (let n = 0; n < lerp_pos.length; n++) {
|
||||||
|
posList.push(
|
||||||
|
Cesium.Cartesian3.fromRadians(
|
||||||
|
lerp_pos[n].longitude,
|
||||||
|
lerp_pos[n].latitude,
|
||||||
|
this.excavateMinHeight - height
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
this.wellData.bottom_pos = posList;
|
||||||
|
this.createWell(this.wellData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export default TerrainExcavation;
|
||||||
54
src/Obj/Analysis/ViewShed/_element.js
Normal file
54
src/Obj/Analysis/ViewShed/_element.js
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
function html() {
|
||||||
|
return `
|
||||||
|
<span class="custom-divider"></span>
|
||||||
|
<div class="div-item">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<span class="label">位置拾取(起点、终点)</span>
|
||||||
|
<button class="edit"><svg class="icon-edit"><use xlink:href="#yj-icon-edit"></use></svg>拾取</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<span class="custom-divider"></span>
|
||||||
|
<div class="div-item">
|
||||||
|
<div class="row" style="margin-bottom: 25px;">
|
||||||
|
<div class="col">
|
||||||
|
<span class="label">视点高度</span>
|
||||||
|
<div class="input-number input-number-unit-1">
|
||||||
|
<input class="input" type="number" title="" min="0" max="999999" step="0.1" @model="viewPointHeight">
|
||||||
|
<span class="unit">m</span>
|
||||||
|
<span class="arrow"></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row subtitle-box">
|
||||||
|
<span class="subtitle">视域夹角</span>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<div class="range-box">
|
||||||
|
<div class="range-bg">
|
||||||
|
<div class="range-process-box">
|
||||||
|
<div class="range-process"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="range-node-box">
|
||||||
|
<span class="range-node-text">0°</span>
|
||||||
|
<span class="range-node-text">45°</span>
|
||||||
|
<span class="range-node-text">90°</span>
|
||||||
|
<span class="range-node-text">135°</span>
|
||||||
|
<span class="range-node-text">180°</span>
|
||||||
|
<div class="range-node-active"><span class="range-node-active-text">0°</span></div>
|
||||||
|
</div>
|
||||||
|
<input type="range" max="180" min="0" step="1" name="horizontalViewAngle">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<span class="custom-divider"></span>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
|
export { html }
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user