Browse Source

init framework

tags/2.0.0
Caven Chen 4 years ago
commit
862608d191
100 changed files with 6401 additions and 0 deletions
  1. 14
    0
      .babelrc
  2. 2
    0
      .browserslistrc
  3. 12
    0
      .editorconfig
  4. 4
    0
      .eslintignore
  5. 38
    0
      .eslintrc
  6. 15
    0
      .gitignore
  7. 11
    0
      .markdownlintrc
  8. 5
    0
      .prettierrc
  9. 2
    0
      CHANGES_en.md
  10. 2
    0
      CHANGES_zh.md
  11. 203
    0
      LICENSE.MD
  12. 186
    0
      README.md
  13. 193
    0
      README_zh.md
  14. 80
    0
      build/common.js
  15. 71
    0
      build/webpack.base.conf.js
  16. 54
    0
      build/webpack.chart.conf.js
  17. 67
    0
      build/webpack.core.conf.js
  18. 66
    0
      build/webpack.mapv.conf.js
  19. 1
    0
      libs/mapv.min.js
  20. 43
    0
      modules/animation/Animation.js
  21. 16
    0
      modules/animation/index.js
  22. 71
    0
      modules/animation/type/AroundPoint.js
  23. 59
    0
      modules/animation/type/AroundView.js
  24. 81
    0
      modules/animation/type/CircleScan.js
  25. 116
    0
      modules/animation/type/Flying.js
  26. 56
    0
      modules/animation/type/GlobeRotate.js
  27. 97
    0
      modules/animation/type/RadarScan.js
  28. 93
    0
      modules/chart/ChartLayer.js
  29. 14
    0
      modules/chart/extension/ComponentModel.js
  30. 21
    0
      modules/chart/extension/ComponentView.js
  31. 96
    0
      modules/chart/extension/CoordinateSystem.js
  32. 21
    0
      modules/chart/index.js
  33. 30
    0
      modules/copy-right/index.js
  34. 70
    0
      modules/effect/Effect.js
  35. 80
    0
      modules/effect/type/BlackAndWhite.js
  36. 135
    0
      modules/effect/type/Bloom.js
  37. 80
    0
      modules/effect/type/Brightness.js
  38. 123
    0
      modules/effect/type/DepthOfField.js
  39. 116
    0
      modules/effect/type/LensFlare.js
  40. 66
    0
      modules/effect/type/NightVision.js
  41. 99
    0
      modules/effect/type/Silhouette.js
  42. 0
    0
      modules/effect/type/Sun.js
  43. 115
    0
      modules/event/Event.js
  44. 79
    0
      modules/event/EventType.js
  45. 14
    0
      modules/event/index.js
  46. 27
    0
      modules/event/type/LayerEvent.js
  47. 27
    0
      modules/event/type/LayerGroupEvent.js
  48. 307
    0
      modules/event/type/MouseEvent.js
  49. 27
    0
      modules/event/type/OverlayEvent.js
  50. 27
    0
      modules/event/type/RoamingEvent.js
  51. 147
    0
      modules/event/type/SceneEvent.js
  52. 27
    0
      modules/event/type/ViewerEvent.js
  53. 190
    0
      modules/exts/SkyBox.js
  54. 6
    0
      modules/exts/index.js
  55. 7
    0
      modules/global-api/index.js
  56. 30
    0
      modules/global-api/mixin.js
  57. 29
    0
      modules/global-api/use.js
  58. 26
    0
      modules/icons/compass-inner.js
  59. 29
    0
      modules/icons/compass-outer.js
  60. 22
    0
      modules/icons/compass-rotation-marker.js
  61. 14
    0
      modules/icons/decrease.js
  62. 15
    0
      modules/icons/increase.js
  63. 26
    0
      modules/icons/index.js
  64. 9
    0
      modules/icons/logo.js
  65. 15
    0
      modules/icons/refresh.js
  66. 13
    0
      modules/icons/splitter.js
  67. 163
    0
      modules/imagery/ImageryLayerFactory.js
  68. 15
    0
      modules/imagery/ImageryType.js
  69. 7
    0
      modules/imagery/index.js
  70. 498
    0
      modules/imagery/projection/BaiduMercatorProjection.js
  71. 37
    0
      modules/imagery/provider/AmapImageryProvider.js
  72. 176
    0
      modules/imagery/provider/BaiduImageryProvider.js
  73. 33
    0
      modules/imagery/provider/GoogleImageryProvider.js
  74. 28
    0
      modules/imagery/provider/TdtImageryProvider.js
  75. 36
    0
      modules/imagery/provider/TencentImageryProvider.js
  76. 40
    0
      modules/imagery/tiling-scheme/AmapMercatorTilingScheme.js
  77. 102
    0
      modules/imagery/tiling-scheme/BaiduMercatorTilingScheme.js
  78. BIN
      modules/images/circle_blue.png
  79. BIN
      modules/images/circle_red.png
  80. BIN
      modules/images/circle_yellow.png
  81. BIN
      modules/images/cloud.jpg
  82. BIN
      modules/images/fence.png
  83. BIN
      modules/images/lighting.png
  84. BIN
      modules/images/space_line.png
  85. 314
    0
      modules/layer/Layer.js
  86. 8
    0
      modules/layer/LayerType.js
  87. 23
    0
      modules/layer/index.js
  88. 178
    0
      modules/layer/type/ClusterLayer.js
  89. 51
    0
      modules/layer/type/CzmlLayer.js
  90. 130
    0
      modules/layer/type/GeoJsonLayer.js
  91. 282
    0
      modules/layer/type/HeatLayer.js
  92. 87
    0
      modules/layer/type/HtmlLayer.js
  93. 48
    0
      modules/layer/type/KmlLayer.js
  94. 40
    0
      modules/layer/type/LabelLayer.js
  95. 143
    0
      modules/layer/type/LayerGroup.js
  96. 32
    0
      modules/layer/type/PrimitiveLayer.js
  97. 35
    0
      modules/layer/type/TilesetLayer.js
  98. 22
    0
      modules/layer/type/TopoJsonLayer.js
  99. 36
    0
      modules/layer/type/VectorLayer.js
  100. 0
    0
      modules/loader/index.js

+ 14
- 0
.babelrc View File

@@ -0,0 +1,14 @@
{
"presets": [
[
"@babel/preset-env",
{
"modules": false,
"targets": {
"browsers": ["> 1%", "last 2 versions", "ie >= 10"]
}
}
]
],
"plugins": ["@babel/plugin-transform-runtime","@babel/plugin-proposal-class-properties"]
}

+ 2
- 0
.browserslistrc View File

@@ -0,0 +1,2 @@
> 1%
last 2 versions

+ 12
- 0
.editorconfig View 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
- 0
.eslintignore View File

@@ -0,0 +1,4 @@
/libs/
/web/
/pack/


+ 38
- 0
.eslintrc View File

@@ -0,0 +1,38 @@
{
"root": true,
"parser": "babel-eslint",
"parserOptions": {
"sourceType": "module"
},
"env": {
"es6": true,
"node": true,
"browser": true
},
"plugins": ["prettier"],
"extends": ["eslint:recommended", "plugin:prettier/recommended"],
"globals": {
"__VERSION__": false,
"__TIME__": false,
"__AUTHOR__": false,
"__HOME_PAGE__": false,
"__REPOSITORY__": false,
"echarts": false,
"mapv": false,
"DC": false,
"Cesium": false,
"@dc-modules": 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
}
}

+ 15
- 0
.gitignore View File

@@ -0,0 +1,15 @@
node_modules/
npm-debug.log*
yarn-debug.log*
yarn-error.log*
web/
pack/
dist/
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
package-lock.json
.DS_Store

+ 11
- 0
.markdownlintrc View 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
- 0
.prettierrc View File

@@ -0,0 +1,5 @@
{
"eslintIntegration": true,
"singleQuote": true,
"semi": false
}

+ 2
- 0
CHANGES_en.md View File

@@ -0,0 +1,2 @@
# Change Log


+ 2
- 0
CHANGES_zh.md View File

@@ -0,0 +1,2 @@
# Change Log


+ 203
- 0
LICENSE.MD View 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.

+ 186
- 0
README.md View File

@@ -0,0 +1,186 @@
# DC-SDK

<p>
<img src="https://img.shields.io/github/workflow/status/dvgis/dc-sdk/publish"/>
<img src="https://img.shields.io/badge/license-Apache%202-blue"/>
<img src="https://img.shields.io/npm/v/@dvgis/dc-sdk?color=orange&logo=npm" />
<img src="https://img.shields.io/npm/dm/@dvgis/dc-sdk?logo=npm"/>
</p>

[**🇨🇳 中文**](./README_zh.md) | [**🇬🇧English**](./README.md)

> DC-SDK is based on Cesium for secondary development of 2, 3D all-in-one WebGis application framework, the framework optimizes the use of Cesium and add some additional features, designed for developers to quickly build WebGis applications.

## Home

> http://dc.dvgis.cn

```warningH
Tips:This SDK is JS+GIS framework package. Developers need to have some front-end technology and GIS related technology
```

## Installation

`CDN`

```html
<!--Basic Package-->
<script src="libs/dc-sdk/dc.base.min.js"></script>
<!--Core Package-->
<script src="libs/dc-sdk/dc.core.min.js"></script>
<!--Main Style Sheet -->
<link href="libs/dc-sdk/dc.core.min.css" rel="stylesheet" type="text/css" />
```

`NPM / YARN`

```shell
yarn add @dvgis/dc-sdk
npm install @dvgis/dc-sdk
```

```js
import DC from '@dvgis/dc-base' //Basic Package
import DcCore from '@dvgis/dc-core' //Core Package
import '@dvgis/dc-core/dist/dc.core.min.css' // Main Style Sheet
```

## Setting

`Webpack`

```js
// webpack.config.js

const path = require('path')
const CopywebpackPlugin = require('copy-webpack-plugin')
const dvgisDist = './node_modules/@dvgis'

module.exports = {
// other settings
plugins:[
new CopyWebpackPlugin([
{
from: path.join(dvgisDist, 'dc-sdk/dist/resources'),
to: 'libs/dc-sdk/resources'
}
])
]
}
```

`Vue2.x`

```js
// vue.config.js

const path = require('path')
const CopywebpackPlugin = require('copy-webpack-plugin')
const dvgisDist = './node_modules/@dvgis'

module.exports = {
// other settings
chainWebpack: config => {
config.resolve.alias.set('dvgis', path.resolve(__dirname, dvgisDist))
config.plugin('copy').use(CopywebpackPlugin, [
[
{
from: path.join(dvgisDist, 'dc-sdk/dist/resources'),
to: 'libs/dc-sdk/resources'
}
]
])
}
}
```

`Vue3.x`

```js
// vue.config.js

const path = require('path')
const CopywebpackPlugin = require('copy-webpack-plugin')
const dvgisDist = './node_modules/@dvgis'

module.exports = {
// other settings
chainWebpack: config => {
config.resolve.alias.set('dvgis', path.resolve(__dirname, dvgisDist))
config.plugin('copy').use(CopywebpackPlugin, [
{
patterns: [
{
from: path.join(dvgisDist, 'dc-sdk/dist/resources'),
to: path.join(__dirname, 'dist', 'libs/dc-sdk/resources'),
},
],
}
])
}
}
```

## Start

```js
global.DC = DC
DC.use(DcCore) // node
DC.ready(() => {
let viewer = new DC.Viewer(divId) // divId is the Id attribute value of a div node. If it is not passed in, the 3D scene cannot be initialized
})
```

## Documentation

[DC Sdk Api](https://resource.dvgis.cn/dc-api/v2.x)

[Cesium Api](https://cesium.com/docs/cesiumjs-ref-doc/)

## Demo

| ![picture](http://dc.dvgis.cn/examples/images/baselayer/baidu.png?v=1) | ![picture](http://dc.dvgis.cn/examples/images/baselayer/tdt.png?v=1) | ![picture](http://dc.dvgis.cn/examples/images/baselayer/arcgis.png?v=2) | ![picture](http://dc.dvgis.cn/examples/images/mini-scene/china.gif) |
| :-----------------------------------------------------------: | :-----------------------------------------------------------: | :------------------------------------------------------------------: | :--------------------------------------------------------------: |
| ![picture](http://dc.dvgis.cn/examples/images/mini-scene/dfmz.gif) | ![picture](http://dc.dvgis.cn/examples/images/mini-scene/factory.gif?v=1) | ![picture](http://dc.dvgis.cn/examples/images/layer/cluster_circle.gif) | ![picture](http://dc.dvgis.cn/examples/images/model/shp_custom_shader.gif) |
| ![picture](http://dc.dvgis.cn/examples/images/overlay/polyline_image_trail.gif) | ![picture](http://dc.dvgis.cn/examples/images/overlay/wall_trail.gif?v=1) | ![picture](http://dc.dvgis.cn/examples/images/overlay/water.gif?v=2) | ![picture](http://dc.dvgis.cn/examples/images/overlay/plot-overlay.png) |

[More>>](http://dc.dvgis.cn/#/examples)

## Ecosystem

| Module | Status | Description |
| :------ | :------: | :------ |
| [dc-chart](https://github.com/dvgis/dc-chart) | <img src="https://img.shields.io/npm/v/@dvgis/dc-chart?logo=npm" /> | dc chart module for adding ECharts functionality in 3d scenes |
| [dc-mapv](https://github.com/dvgis/dc-mapv) | <img src="https://img.shields.io/npm/v/@dvgis/dc-mapv?logo=npm" /> | dc big-data module for adding MAPV functions in 3d scenes |
| [dc-ui](https://github.com/dvgis/dc-ui) | <img src="https://img.shields.io/npm/v/@dvgis/dc-ui?logo=npm" /> | dc components for Vue2.x |
| dc-analysis | <img src="https://img.shields.io/npm/v/@dvgis/dc-analysis?logo=npm" /> | dc analysis module, including camera-video, position-editor, measure, etc |
| dc-ui-next | <img src="https://img.shields.io/npm/v/@dvgis/dc-ui-next?logo=npm" /> | dc components for Vue3.x |

## QQ Group

<p>
<img src="http://dc.dvgis.cn/examples/images/base/q1.png?v=2" style="width:60px;height:60px" title="数字视觉"/>
<img src="http://dc.dvgis.cn/examples/images/base/q2.png?v=6" style="width:60px;height:60px" title="Cesium开心农场"/>
</p>


## Copyright

```warning
1. The framework is a basic platform, completely open source, which can be modified and reconstructed by any individual or institution without our authorization.
2. We are not responsible for any problems arising from the modification of the framework by individuals and organizations.
3. Some industrial plug-ins and tools will be added in the later stage, and the code will be open source appropriately.
4. The package released by us may be used permanently and free of charge by any person or organization subject to:
1) complete package reference;
2) reserve this copyright information in the console output
We reserve the right of final interpretation of this copyright information.
```

## Support

> if dc-sdk can bring benefits to you, please support it ~
<p>
<img src="http://dc.dvgis.cn/examples/images/base/sponsor.jpg?v=2" style="width:60px;height:60px" title="数字视觉"/>
</p>

## Thanks

+ 193
- 0
README_zh.md View File

@@ -0,0 +1,193 @@
# DC-SDK

<p>
<img src="https://img.shields.io/github/workflow/status/dvgis/dc-sdk/publish"/>
<img src="https://img.shields.io/badge/license-Apache%202-blue"/>
<img src="https://img.shields.io/npm/v/@dvgis/dc-sdk?color=orange&logo=npm" />
<img src="https://img.shields.io/npm/dm/@dvgis/dc-sdk?logo=npm"/>
</p>

[**🇨🇳 中文**](./README_zh.md) | [**🇬🇧English**](./README.md)

> DC-SDK 是基于 Cesium 进行二次开发的2、3D一体 WebGis 应用框架,该框架优化了 Cesium 的使用方式和增添了一些额外功能,旨在为开发者快速构建 WebGis 应用。

##主页

> http://dc.dvgis.cn

```warning
Tips:本框架是 JS+GIS 的框架包。开发者需要有一定的前端技术和 GIS 相关技术
```

## 安装

`CDN`

```html
<!--基础包-->
<script src="libs/dc-sdk/dc.base.min.js"></script>
<!--核心包-->
<script src="libs/dc-sdk/dc.core.min.js"></script>
<!--主要样式-->
<link href="libs/dc-sdk/dc.core.min.css" rel="stylesheet" type="text/css" />
```
`NPM / YARN`

```shell
yarn add @dvgis/dc-sdk
npm install @dvgis/dc-sdk
```

```js
import DC from 'dvgis/dc-sdk/dist/dc.base.min' //基础包
import DcCore from 'dvgis/dc-sdk/dist/dc.core.min' //核心包
import 'dvgis/dc-sdk/dist/dc.core.min.css' // 主要样式
```

## 配置

`Webpack`

```js
// webpack.config.js

const path = require('path')
const CopywebpackPlugin = require('copy-webpack-plugin')
const dvgisDist = './node_modules/@dvgis'

module.exports = {
// 其他配置
resolve: {
alias: {
dvgis: path.resolve(__dirname, dvgisDist)
}
},
plugins:[
new CopyWebpackPlugin([
{
from: path.join(dvgisDist, 'dc-sdk/dist/resources'),
to: 'libs/dc-sdk/resources'
}
])
]
}
```

`Vue2.x`

```js
// vue.config.js

const path = require('path')
const CopywebpackPlugin = require('copy-webpack-plugin')
const dvgisDist = './node_modules/@dvgis'

module.exports = {
// 其他配置
chainWebpack: config => {
config.resolve.alias.set('dvgis', path.resolve(__dirname, dvgisDist))
config.plugin('copy').use(CopywebpackPlugin, [
[
{
from: path.join(dvgisDist, 'dc-sdk/dist/resources'),
to: 'libs/dc-sdk/resources'
}
]
])
}
}
```

`Vue3.x`

```js
// vue.config.js

const path = require('path')
const CopywebpackPlugin = require('copy-webpack-plugin')
const dvgisDist = './node_modules/@dvgis'

module.exports = {
// 其他配置
chainWebpack: config => {
config.resolve.alias.set('dvgis', path.resolve(__dirname, dvgisDist))
config.plugin('copy').use(CopywebpackPlugin, [
{
patterns: [
{
from: path.join(dvgisDist, 'dc-sdk/dist/resources'),
to: path.join(__dirname, 'dist', 'libs/dc-sdk/resources'),
},
],
}
])
}
}
```

## 开始

```js
global.DC = DC
DC.use(DcCore) // Node 方式
DC.ready(() => {
let viewer = new DC.Viewer(divId) // divId 为一个div节点的Id属性值,如果不传入,会无法初始化3D场景
})
```

## 文档

[DC Sdk Api](https://resource.dvgis.cn/dc-api)

[Cesium Api](https://cesium.com/docs/cesiumjs-ref-doc/)

## 示例

| ![picture](http://dc.dvgis.cn/examples/images/baselayer/baidu.png?v=1) | ![picture](http://dc.dvgis.cn/examples/images/baselayer/tdt.png?v=1) | ![picture](http://dc.dvgis.cn/examples/images/baselayer/arcgis.png?v=2) | ![picture](http://dc.dvgis.cn/examples/images/mini-scene/china.gif) |
| :-----------------------------------------------------------: | :-----------------------------------------------------------: | :------------------------------------------------------------------: | :--------------------------------------------------------------: |
| ![picture](http://dc.dvgis.cn/examples/images/mini-scene/dfmz.gif) | ![picture](http://dc.dvgis.cn/examples/images/mini-scene/factory.gif?v=1) | ![picture](http://dc.dvgis.cn/examples/images/layer/cluster_circle.gif) | ![picture](http://dc.dvgis.cn/examples/images/model/shp_custom_shader.gif) |
| ![picture](http://dc.dvgis.cn/examples/images/overlay/polyline_image_trail.gif) | ![picture](http://dc.dvgis.cn/examples/images/overlay/wall_trail.gif?v=1) | ![picture](http://dc.dvgis.cn/examples/images/overlay/water.gif?v=2) | ![picture](http://dc.dvgis.cn/examples/images/overlay/plot-overlay.png) |

[更多>>](http://dc.dvgis.cn/#/examples)

## 生态

| 模块名称 | 状态 | 描述 |
| :------ | :------: | :------ |
| [dc-plugins](https://github.com/dvgis/dc-plugins) | <img src="https://img.shields.io/npm/v/@dvgis/dc-plugins?logo=npm" /> | DC插件模块,包括场景动画、漫游以及一些额外的材质 |
| [dc-overlay](https://github.com/dvgis/dc-overlay) | <img src="https://img.shields.io/npm/v/@dvgis/dc-overlay?logo=npm" /> | DC要素模块,包括球体、柱体、军标、水面等 |
| [dc-plot](https://github.com/dvgis/dc-plot) | <img src="https://img.shields.io/npm/v/@dvgis/dc-plot?logo=npm" /> | DC标绘模块,用于要素的标绘和编辑 |
| [dc-chart](https://github.com/dvgis/dc-chart) | <img src="https://img.shields.io/npm/v/@dvgis/dc-chart?logo=npm" /> | DC图表模块,用于在三维场景中添加Echarts功能 |
| [dc-mapv](https://github.com/dvgis/dc-mapv) | <img src="https://img.shields.io/npm/v/@dvgis/dc-mapv?logo=npm" /> | DC大数据模块,用于在三维场景中添加Mapv功能 |
| [dc-ui](https://github.com/dvgis/dc-ui) | <img src="https://img.shields.io/npm/v/@dvgis/dc-ui?logo=npm" /> | DC基于Vue2.x组件开发框架,将DC功能Vue模块化 |
| dc-analysis | <img src="https://img.shields.io/npm/v/@dvgis/dc-analysis?logo=npm" /> | DC分析模块,包括视频融合,位置编辑、测量等 |
| dc-ui-next | <img src="https://img.shields.io/npm/v/@dvgis/dc-ui-next?logo=npm" /> | DC基于Vue3.x组件开发框架,将DC功能Vue模块化 |

## QQ 群

<p>
<img src="http://dc.dvgis.cn/examples/images/base/q1.png?v=2" style="width:60px;height:60px" title="数字视觉"/>
<img src="http://dc.dvgis.cn/examples/images/base/q2.png?v=6" style="width:60px;height:60px" title="Cesium开心农场"/>
</p>

## 支持

> 如果dc-sdk能够给您带来效益,请支持一下呗~
<p>
<img src="http://dc.dvgis.cn/examples/images/base/sponsor.jpg?v=2" style="width:60px;height:60px" title="数字视觉"/>
</p>

## 版权声明

```warning
1.框架作为一个基础平台,代码开源,任何个人和机构可以修改、重构,无需经过我方授权。
2.任何个人和机构修改框架出现的问题,我方无需负责。
3.后期会添加一些行业性的插件和工具,代码会适量开源。
4.对于我方发布的程序包,任何个人和机构在遵守下列条件的前提下可以永久免费使用:
1)程序包完整引用;
2)保留此版权信息在控制台输出
我方保留对此版权信息的最终解释权。
```

## 谢谢

+ 80
- 0
build/common.js View File

@@ -0,0 +1,80 @@
/**
* @Author: Caven
* @Date: 2021-03-13 12:09:44
*/

'use strict'

const webpack = require('webpack')
const packageInfo = require('../package.json')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')

function getTime() {
let now = new Date()
let m = now.getMonth() + 1
m = m < 10 ? '0' + m : m
let d = now.getDate()
d = d < 10 ? '0' + d : d
return `${now.getFullYear()}-${m}-${d}`
}

module.exports = {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env'],
plugins: ['@babel/transform-runtime'],
compact: false,
ignore: ['checkTree']
}
},
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader'
},
{
loader: 'sass-loader'
}
]
},
{
test: /\.scss$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader'
},
{
loader: 'sass-loader'
}
]
},
{
test: /\.(png|jpg|gif|svg|eot|ttf|woff|woff2)$/,
loader: 'url-loader',
options: {
limit: 20000
}
},
{
test: /\.glsl$/,
loader: 'webpack-glsl-loader'
}
],
plugins: [
new webpack.DefinePlugin({
CESIUM_BASE_URL: JSON.stringify('./libs/dc-sdk/resources/'),
__VERSION__: JSON.stringify(packageInfo.version),
__TIME__: JSON.stringify(getTime()),
__AUTHOR__: JSON.stringify(packageInfo.author),
__REPOSITORY__: JSON.stringify(packageInfo.repository),
__HOME_PAGE__: JSON.stringify(packageInfo.homepage)
})
]
}

+ 71
- 0
build/webpack.base.conf.js View File

@@ -0,0 +1,71 @@
/**
* @Author: Caven
* @Date: 2021-03-13 16:52:10
*/

'use strict'

const path = require('path')
const webpack = require('webpack')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const cesiumBuild = '../node_modules/cesium/Build/Cesium'
const common = require('./common')

let cesiumCopyPlugin = [
new CopyWebpackPlugin([
{
from: path.resolve(__dirname, cesiumBuild, 'Assets'),
to: 'resources/Assets'
},
{
from: path.resolve(__dirname, cesiumBuild, 'Workers'),
to: 'resources/Workers'
},
{
from: path.resolve(__dirname, cesiumBuild, 'ThirdParty'),
to: 'resources/ThirdParty'
}
])
]

module.exports = env => {
const IS_PROD = (env && env.production) || false
const publicPath = IS_PROD ? '/' : '/'
let plugins = [...cesiumCopyPlugin, ...common.plugins]
if (IS_PROD) {
plugins.push(new webpack.NoEmitOnErrorsPlugin())
}
return {
entry: {
'dc.base': [path.resolve(__dirname, '..', 'packages/base/index.js')]
},
devtool: IS_PROD ? false : 'cheap-module-eval-source-map',
output: {
filename: IS_PROD ? '[name].min.js' : '[name].js',
path: path.resolve(__dirname, '..', 'packages/base/dist'),
publicPath: publicPath,
library: 'DC',
libraryExport: 'default',
libraryTarget: 'umd',
umdNamedDefine: true
},
amd: {
toUrlUndefined: true
},
node: {
fs: 'empty'
},
module: {
unknownContextCritical: false,
rules: common.rules
},
resolve: {
extensions: ['.js', '.json', '.css'],
alias: {
'@dc-modules': path.resolve(__dirname, '..', 'modules'),
cesium: path.resolve(__dirname, cesiumBuild)
}
},
plugins
}
}

+ 54
- 0
build/webpack.chart.conf.js View File

@@ -0,0 +1,54 @@
/**
* @Author: Caven
* @Date: 2021-03-14 00:41:29
*/

'use strict'

const path = require('path')
const webpack = require('webpack')
const JavaScriptObfuscator = require('webpack-obfuscator')
const common = require('./common')

module.exports = env => {
const IS_PROD = (env && env.production) || false
const publicPath = IS_PROD ? '/' : '/'
let plugins = [...common.plugins]
if (IS_PROD) {
plugins.push(new webpack.NoEmitOnErrorsPlugin())
plugins.push(
new JavaScriptObfuscator(
{
rotateStringArray: true
},
[]
)
)
}
return {
entry: {
'dc.chart': ['entry']
},
devtool: IS_PROD ? false : 'cheap-module-eval-source-map',
output: {
filename: IS_PROD ? '[name].min.js' : '[name].js',
path: path.resolve(__dirname, '..', 'packages/chart/dist'),
publicPath: publicPath,
library: 'DcChart',
libraryTarget: 'umd',
umdNamedDefine: true
},
module: {
unknownContextCritical: false,
rules: common.rules
},
resolve: {
extensions: ['.js', '.json', '.css'],
alias: {
'@dc-modules': path.resolve(__dirname, '..', 'modules'),
entry: path.resolve(__dirname, '..', 'packages/chart/index.js')
}
},
plugins
}
}

+ 67
- 0
build/webpack.core.conf.js View File

@@ -0,0 +1,67 @@
/**
* @Author: Caven
* @Date: 2020-01-18 19:22:23
*/

const path = require('path')
const webpack = require('webpack')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin')
const JavaScriptObfuscator = require('webpack-obfuscator')
const cesiumBuild = '../node_modules/cesium/Build/Cesium'
const common = require('./common')

module.exports = env => {
const IS_PROD = (env && env.production) || false
const publicPath = IS_PROD ? '/' : '/'
let plugins = [
new MiniCssExtractPlugin({
filename: IS_PROD ? '[name].min.css' : '[name].css',
allChunks: true
}),
...common.plugins
]
if (IS_PROD) {
plugins.push(new OptimizeCssAssetsPlugin())
plugins.push(new webpack.NoEmitOnErrorsPlugin())
plugins.push(
new JavaScriptObfuscator(
{
rotateStringArray: true
},
[]
)
)
}
return {
entry: {
'dc.core': ['theme', 'entry']
},
devtool: IS_PROD ? false : 'cheap-module-eval-source-map',
output: {
filename: IS_PROD ? '[name].min.js' : '[name].js',
path: path.resolve(
__dirname,
path.resolve(__dirname, '..', 'packages/core/dist')
),
publicPath: publicPath,
library: 'DcCore',
libraryTarget: 'umd',
umdNamedDefine: true
},
module: {
unknownContextCritical: false,
rules: common.rules
},
resolve: {
extensions: ['.js', '.json', '.css'],
alias: {
'@dc-modules': path.resolve(__dirname, '..', 'modules'),
entry: path.resolve(__dirname, '..', 'packages/core/index.js'),
theme: path.resolve(__dirname, '..', 'modules/themes/index.js'),
cesium: path.resolve(__dirname, cesiumBuild)
}
},
plugins
}
}

+ 66
- 0
build/webpack.mapv.conf.js View File

@@ -0,0 +1,66 @@
/**
* @Author: Caven
* @Date: 2021-03-14 00:41:29
*/

'use strict'

const path = require('path')
const webpack = require('webpack')
const JavaScriptObfuscator = require('webpack-obfuscator')
const common = require('./common')

module.exports = env => {
const IS_PROD = (env && env.production) || false
const publicPath = IS_PROD ? '/' : '/'
let plugins = [...common.plugins]
if (IS_PROD) {
plugins.push(new webpack.NoEmitOnErrorsPlugin())
plugins.push(
new JavaScriptObfuscator(
{
rotateStringArray: true
},
[]
)
)
}
return {
entry: {
'dc.mapv': ['entry']
},
devtool: IS_PROD ? false : 'cheap-module-eval-source-map',
output: {
filename: IS_PROD ? '[name].min.js' : '[name].js',
path: path.resolve(__dirname, '..', 'packages/mapv/dist'),
publicPath: publicPath,
library: 'DcMapv',
libraryTarget: 'umd',
umdNamedDefine: true
},
module: {
unknownContextCritical: false,
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env'],
compact: false,
ignore: ['checkTree']
}
}
]
},
resolve: {
extensions: ['.js', '.json', '.css'],
alias: {
'@dc-modules': path.resolve(__dirname, '..', 'modules'),
'mapv-lib': path.resolve(__dirname, '..', 'libs/mapv.min.js'),
entry: path.resolve(__dirname, '..', 'packages/mapv/index.js')
}
},
plugins
}
}

+ 1
- 0
libs/mapv.min.js
File diff suppressed because it is too large
View File


+ 43
- 0
modules/animation/Animation.js View File

@@ -0,0 +1,43 @@
/**
* @Author: Caven
* @Date: 2020-12-20 16:32:22
*/

class Animation {
constructor(viewer) {
this._viewer = viewer
this._options = {}
}

_bindEvent() {}

_unbindEvent() {}

/**
* Start globe rotate
* @returns {Animation}
*/
start() {
if (this._options.duration) {
let timer = setTimeout(() => {
this._unbindEvent()
this._options.callback &&
this._options.callback.call(this._options.context || this)
clearTimeout(timer)
}, Number(this._options.duration) * 1e3)
}
this._bindEvent()
return this
}

/**
* Stop globe rotate
* @returns {Animation}
*/
stop() {
this._unbindEvent()
return this
}
}

export default Animation

+ 16
- 0
modules/animation/index.js View File

@@ -0,0 +1,16 @@
/**
* @Author: Caven
* @Date: 2020-03-05 22:15:27
*/

export { default as Animation } from './Animation'

/**
* types
*/
export { default as AroundView } from './type/AroundView'
export { default as AroundPoint } from './type/AroundPoint'
export { default as CircleScan } from './type/CircleScan'
export { default as Flying } from './type/Flying'
export { default as GlobeRotate } from './type/GlobeRotate'
export { default as RadarScan } from './type/RadarScan'

+ 71
- 0
modules/animation/type/AroundPoint.js View File

@@ -0,0 +1,71 @@
/**
* @Author: Caven
* @Date: 2020-03-02 22:38:10
*/

import { Cesium } from '@dc-modules/namespace'
import { Transform } from '@dc-modules/transform'
import Parse from '@dc-modules/parse/Parse'

import Animation from '../Animation'

class AroundPoint extends Animation {
constructor(viewer, position, options = {}) {
super(viewer)
this._position = Parse.parsePosition(position)
this._options = options
this._heading = viewer.camera.heading
this._aroundAmount = 0.2
this.type = 'around_point'
}

set position(position) {
this._position = Parse.parsePosition(position)
return this
}

set aroundAmount(aroundAmount) {
this._aroundAmount = aroundAmount
return this
}

/**
*
* @private
*/
_bindEvent() {
this._viewer.clock.onTick.addEventListener(this._onAround, this)
}

/**
*
* @private
*/
_unbindEvent() {
this._viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY)
this._viewer.clock.onTick.removeEventListener(this._onAround, this)
}

/**
*
* @param scene
* @param time
* @private
*/
_onAround(scene, time) {
this._heading += Cesium.Math.toRadians(this._aroundAmount)
if (this._heading >= Math.PI * 2 || this._heading <= -Math.PI * 2) {
this._heading = 0
}
this._viewer.camera.lookAt(
Transform.transformWGS84ToCartesian(this._position),
new Cesium.HeadingPitchRange(
this._heading,
Cesium.Math.toRadians(this._options.pitch || 0),
this._options.range || 1000
)
)
}
}

export default AroundPoint

+ 59
- 0
modules/animation/type/AroundView.js View File

@@ -0,0 +1,59 @@
/**
* @Author: Caven
* @Date: 2020-03-02 23:14:20
*/

import { Cesium } from '@dc-modules/namespace'
import Animation from '../Animation'

class AroundView extends Animation {
constructor(viewer, options = {}) {
super(viewer)
this._options = options
this._heading = viewer.camera.heading
this._aroundAmount = 0.2
this.type = 'around_view'
}

set aroundAmount(aroundAmount) {
this._aroundAmount = aroundAmount
return this
}

/**
*
* @private
*/
_bindEvent() {
this._viewer.clock.onTick.addEventListener(this._onAround, this)
}

/**
*
* @private
*/
_unbindEvent() {
this._viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY)
this._viewer.clock.onTick.removeEventListener(this._onAround, this)
}

/**
*
* @param scene
* @param time
* @private
*/
_onAround(scene, time) {
this._heading += Cesium.Math.toRadians(this._aroundAmount)
if (this._heading >= Math.PI * 2 || this._heading <= -Math.PI * 2) {
this._heading = 0
}
this._viewer.scene.camera.setView({
orientation: {
heading: this._heading
}
})
}
}

export default AroundView

+ 81
- 0
modules/animation/type/CircleScan.js View File

@@ -0,0 +1,81 @@
/**
* @Author: Caven
* @Date: 2020-12-01 20:26:02
*/

import { Cesium } from '@dc-modules/namespace'
import Parse from '@dc-modules/parse/Parse'
import { Util } from '@dc-modules/utils'
import { Transform } from '@dc-modules/transform'
import Animation from '../Animation'

const CircleScanShader = require('@dc-modules/material/shader/circle/CircleScanShader.glsl')

class CircleScan extends Animation {
constructor(viewer, position, radius, options = {}) {
super(viewer)
this._delegate = undefined
this._position = Parse.parsePosition(position)
this._radius = radius || 100
this._color = options.color || Cesium.Color.RED
this._speed = options.speed || 2
this.type = 'circle_scan'
}

/**
*
* @private
*/
_mountContent() {
let center = Transform.transformWGS84ToCartesian(this._position)
let up = Cesium.Ellipsoid.WGS84.geodeticSurfaceNormal(
center,
new Cesium.Cartesian3()
)
let self = this
this._delegate = new Cesium.PostProcessStage({
name: Util.uuid(),
fragmentShader: CircleScanShader,
uniforms: {
centerWC: function() {
return center
},
normalWC: function() {
return up
},
radius: function() {
return self._radius
},
speed: function() {
return self._speed
},
color: function() {
return self._color
}
}
})
}

/**
*
* @returns {CircleScan}
*/
start() {
!this._delegate && this._mountContent()
this._delegate && this._viewer.scene.postProcessStages.add(this._delegate)
return this
}

/**
*
* @returns {CircleScan}
*/
stop() {
this._delegate &&
this._viewer.scene.postProcessStages.remove(this._delegate)
this._delegate = undefined
return this
}
}

export default CircleScan

+ 116
- 0
modules/animation/type/Flying.js View File

@@ -0,0 +1,116 @@
/**
* @Author: Caven
* @Date: 2021-01-09 20:21:33
*/

import { Cesium } from '@dc-modules/namespace'
import Parse from '@dc-modules/parse/Parse'
import { Transform } from '@dc-modules/transform'
import Animation from '../Animation'

class Flying extends Animation {
constructor(viewer, options = {}) {
super(viewer)
this._options = options
this._positions = []
this._durations = [3]
this._currentIndex = 0

this._timer = undefined
}

set positions(positions) {
this._positions = Parse.parsePositions(positions)
return this
}

get positions() {
return this._positions
}

set durations(durations) {
this._durations = durations
return this
}

get durations() {
return this._durations
}

/**
*
* @private
*/
_cameraFly() {
let self = this
let camera = this._viewer.camera
let position = this._positions[this._currentIndex]
let callback = () => {
let nextPosition = self._positions[self._currentIndex + 1]
if (nextPosition) {
self._currentIndex++
if (self._currentIndex <= self._positions.length - 1) {
self._timer = setTimeout(() => {
self._cameraFly()
}, (self._options.dwellTime || 1) * 1e3)
}
} else if (!nextPosition && self._options.loop) {
self._currentIndex = 0
self._timer = setTimeout(() => {
self._cameraFly()
}, (self._options.dwellTime || 1) * 1e3)
}
self._options.callback && self._options.callback(self._currentIndex)
}
if (position) {
camera.flyTo({
destination: Transform.transformWGS84ToCartesian(position),
orientation: {
heading: Cesium.Math.toRadians(position.heading),
pitch: Cesium.Math.toRadians(position.pitch),
roll: Cesium.Math.toRadians(position.roll)
},
complete: callback,
duration:
this._durations.length === 1
? this._durations[0]
: this._durations[this._currentIndex]
})
}
}

/**
*
* @returns {Flying}
*/
start() {
if (this._positions && this._positions.length) {
this._currentIndex = 0
this._cameraFly()
}
return this
}

/**
*
* @returns {Flying}
*/
pause() {
this._viewer.camera.cancelFlight()
this._timer && clearTimeout(this._timer)
return this
}

/**
*
* @returns {Flying}
*/
restore() {
if (this._positions && this._positions.length) {
this._cameraFly()
}
return this
}
}

export default Flying

+ 56
- 0
modules/animation/type/GlobeRotate.js View File

@@ -0,0 +1,56 @@
/**
* @Author: Caven
* @Date: 2020-01-30 20:47:25
*/

import { Cesium } from '@dc-modules/namespace'
import Animation from '../Animation'

class GlobeRotate extends Animation {
constructor(viewer, options = {}) {
super(viewer)
this._options = options
this.type = 'globe_rotate'
}

/**
* @param scene
* @param time
* @returns {boolean}
* @private
*/
_icrf(scene, time) {
if (scene.mode !== Cesium.SceneMode.SCENE3D) {
return true
}
let icrfToFixed = Cesium.Transforms.computeIcrfToFixedMatrix(time)
if (icrfToFixed) {
let camera = this._viewer.camera
let offset = Cesium.Cartesian3.clone(camera.position)
let transform = Cesium.Matrix4.fromRotationTranslation(icrfToFixed)
camera.lookAtTransform(transform, offset)
}
}

/**
* Bind the Event
* @private
*/
_bindEvent() {
this._viewer.clock.multiplier = this._options.speed || 12 * 1000
this._viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY)
this._viewer.scene.postUpdate.addEventListener(this._icrf, this)
}

/**
* Unbind the Event
* @private
*/
_unbindEvent() {
this._viewer.clock.multiplier = 1
this._viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY)
this._viewer.scene.postUpdate.removeEventListener(this._icrf, this)
}
}

export default GlobeRotate

+ 97
- 0
modules/animation/type/RadarScan.js View File

@@ -0,0 +1,97 @@
/**
* @Author: Caven
* @Date: 2020-12-01 20:40:02
*/

import Parse from '@dc-modules/parse/Parse'
import { Util } from '@dc-modules/utils'
import { Transform } from '@dc-modules/transform'

import Animation from '../Animation'



const RadarScanShader = require('@dc-modules/material/shader/radar/RadarScanShader.glsl')

class RadarScan extends Animation {
constructor(viewer, position, radius, options = {}) {
super(viewer)
this._position = Parse.parsePosition(position)
this._radius = radius || 100
this._color = options.color || Cesium.Color.BLUE
this._speed = options.speed || 3
this._delegate = undefined
this.type = 'radar_scan'
}

/**
*
* @private
*/
_mountContent() {
let center = Transform.transformWGS84ToCartesian(this._position)
let up = Cesium.Ellipsoid.WGS84.geodeticSurfaceNormal(
center,
new Cesium.Cartesian3()
)
let time = new Date().getTime()
let self = this
this._delegate = new Cesium.PostProcessStage({
name: Util.uuid(),
fragmentShader: RadarScanShader,
uniforms: {
centerWC: function() {
return center
},
planeNormalWC: function() {
return up
},
lineNormalWC: function() {
let rotateQ = new Cesium.Quaternion()
let rotateM = new Cesium.Matrix3()
let east = Cesium.Cartesian3.cross(
Cesium.Cartesian3.UNIT_Z,
up,
new Cesium.Cartesian3()
)
let now = new Date().getTime()
let angle = Cesium.Math.PI * 2 * ((now - time) / 1e4) * self._speed
Cesium.Quaternion.fromAxisAngle(up, angle, rotateQ)
Cesium.Matrix3.fromQuaternion(rotateQ, rotateM)
Cesium.Matrix3.multiplyByVector(rotateM, east, east)
Cesium.Cartesian3.normalize(east, east)
return east
},
radius: function() {
return self._radius
},
color: function() {
return self._color
}
}
})
}

/**
*
* @returns {RadarScan}
*/
start() {
!this._delegate && this._mountContent()
this._delegate && this._viewer.scene.postProcessStages.add(this._delegate)
return this
}

/**
*
* @returns {RadarScan}
*/
stop() {
this._delegate &&
this._viewer.scene.postProcessStages.remove(this._delegate)
this._delegate = undefined
return this
}
}

export default RadarScan

+ 93
- 0
modules/chart/ChartLayer.js View File

@@ -0,0 +1,93 @@
/**
* @Author: Caven
* @Date: 2020-02-02 15:59:37
*/

import State from '@dc-modules/state/State'
import { DomUtil } from '@dc-modules/utils'
import { Layer } from '@dc-modules/layer'

class ChartLayer extends Layer {
constructor(id, option) {
super(id)
this._option = option
this._delegate = DomUtil.create('div', 'dc-chart')
this._setWrapperStyle()
this._chart = undefined
this.type = Layer.getLayerType('chart')
this._state = State.INITIALIZED
}

get chart() {
return this._chart
}

set show(show) {
this._show = show
if (this._delegate) {
this._delegate.style.visibility = show ? 'visible' : 'hidden'
}
}

get show() {
return this._show
}

/**
*
* @private
*/
_setWrapperStyle() {
this._delegate.style.position = 'absolute'
this._delegate.style.top = '0px'
this._delegate.style.left = '0px'
this._delegate.style.pointerEvents = 'none'
this._delegate.setAttribute('id', this._id)
}

/**
*
* @param viewer
*/
_onAdd(viewer) {
if (!viewer || !echarts) {
return
}
this._viewer = viewer
this._delegate.style.width = viewer.canvas.width + 'px'
this._delegate.style.height = viewer.canvas.height + 'px'
viewer.dcContainer.appendChild(this._delegate)
echarts.viewer = viewer
viewer.scene.canvas.setAttribute('tabIndex', 0)
this._chart = echarts.init(this._delegate)
this._option && this._chart.setOption(this._option)
this._state = State.ADDED
}

/**
*
* @private
*/
_onRemove() {
if (this._delegate && this._viewer) {
this._viewer.dcContainer.removeChild(this._delegate)
this._chart.dispose()
this._state = State.REMOVED
}
}

/**
*
* @param option
* @returns {ChartLayer}
*/
setOption(option) {
this._option = option
this._chart && this._chart.setOption(this._option)
return this
}
}

Layer.registerType('chart')

export default ChartLayer

+ 14
- 0
modules/chart/extension/ComponentModel.js View File

@@ -0,0 +1,14 @@
/**
* @Author: Caven
* @Date: 2020-02-02 16:35:41
*/

export default echarts.extendComponentModel({
type: 'GLMap',
getViewer: function() {
return echarts.viewer
},
defaultOption: {
roam: false
}
})

+ 21
- 0
modules/chart/extension/ComponentView.js View File

@@ -0,0 +1,21 @@
/**
* @Author: Caven
* @Date: 2020-02-02 16:34:40
*/

export default echarts.extendComponentView({
type: 'GLMap',
init: function(ecModel, api) {
this.api = api
echarts.viewer.scene.postRender.addEventListener(this.moveHandler, this)
},
moveHandler: function(t, e) {
this.api.dispatchAction({
type: 'GLMapRoam'
})
},
render: function(t, e, i) {},
dispose: function(t) {
echarts.viewer.scene.postRender.removeEventListener(this.moveHandler, this)
}
})

+ 96
- 0
modules/chart/extension/CoordinateSystem.js View File

@@ -0,0 +1,96 @@
/**
* @Author: Caven
* @Date: 2020-02-02 16:21:35
*/

import { Cesium } from '@dc-modules/namespace'

class CoordinateSystem {
constructor(viewer, api) {
this._viewer = viewer
this._dimensions = ['lng', 'lat']
this._mapOffset = [0, 0]
this._api = api
}

setMapOffset(mapOffset) {
this._mapOffset = mapOffset
return this
}

getViewer() {
return this._viewer
}

dataToPoint(data) {
let scene = this._viewer.scene
let result = [0, 0]
let cartesian3 = Cesium.Cartesian3.fromDegrees(data[0], data[1])
if (!cartesian3) {
return result
}
if (
scene.mode === Cesium.SceneMode.SCENE3D &&
Cesium.Cartesian3.angleBetween(scene.camera.position, cartesian3) >
Cesium.Math.toRadians(80)
) {
return false
}
let coords = scene.cartesianToCanvasCoordinates(cartesian3)
if (!coords) {
return result
}
return [coords.x - this._mapOffset[0], coords.y - this._mapOffset[1]]
}

pointToData(point) {
let ellipsoid = this._viewer.scene.globe.ellipsoid
let cartesian3 = new Cesium.Cartesian3(
point[0] + this._mapOffset[0],
point[1] + this._mapOffset[1],
0
)
let cartographic = ellipsoid.cartesianToCartographic(cartesian3)
return [
Cesium.Math.toDegrees(cartographic.longitude),
Cesium.Math.toDegrees(cartographic.latitude)
]
}

getViewRect() {
let api = this._api
return new echarts.graphic.BoundingRect(
0,
0,
api.getWidth(),
api.getHeight()
)
}

getRoamTransform() {
return echarts.matrix.create()
}

get dimensions() {
return this._dimensions
}

static get dimensions() {
return ['lng', 'lat']
}

static create(ecModel, api) {
let coordinateSys = undefined
ecModel.eachComponent('GLMap', function(model) {
coordinateSys = new CoordinateSystem(echarts.viewer.delegate, api)
coordinateSys.setMapOffset(model.__mapOffset || [0, 0])
model.coordinateSystem = coordinateSys
})
ecModel.eachSeries(function(model) {
'GLMap' === model.get('coordinateSystem') &&
(model.coordinateSystem = coordinateSys)
})
}
}

export default CoordinateSystem

+ 21
- 0
modules/chart/index.js View File

@@ -0,0 +1,21 @@
/**
* @Author: Caven
* @Date: 2020-02-02 16:20:10
*/

import './extension/ComponentModel'
import './extension/ComponentView'
import CoordinateSystem from './extension/CoordinateSystem'
import ChartLayer from './ChartLayer'

echarts.registerCoordinateSystem('GLMap', CoordinateSystem)
echarts.registerAction(
{
type: 'GLMapRoam',
event: 'GLMapRoam',
update: 'updateLayout'
},
function(payload, ecModel) {}
)

export { ChartLayer }

+ 30
- 0
modules/copy-right/index.js View File

@@ -0,0 +1,30 @@
/**
* @Author: Caven
* @Date: 2020-02-12 18:53:12
*/

// eslint-disable-next-line no-console
console.clear()

// eslint-disable-next-line no-console
console.log(
`%c \n DC-SDK \n %c \n 用数字描绘世界之美 %c \n
版本:${__VERSION__} - ${__TIME__}
Cesium版本:1.79.1
开发作者:${__AUTHOR__}
网站主页: ${__HOME_PAGE__}
github:${__REPOSITORY__}
授权信息:授权-永久使用此软件当前版本。 \n

版权声明:
1.框架作为一个基础平台,代码开源,任何个人和机构可以修改、重构,无需经过我方授权。
2.任何个人和机构修改框架出现的问题,我方无需负责。
3.后期会添加一些行业性的插件和工具,代码会适量开源。
4.对于我方发布的程序包,任何个人和机构在遵守下列条件的前提下可以永久免费使用:
1)程序包完整引用
2)保留此版权信息在控制台输出
我方保留对此版权信息的最终解释权。`,
'font-size:20px;padding-left:70px;color:#EEB422',
'font-size:14px;padding-left:50px;color:#EEB422;font-style:oblique',
'font-size:12px;color:#0865ba'
)

+ 70
- 0
modules/effect/Effect.js View File

@@ -0,0 +1,70 @@
/**
* @Author: Caven
* @Date: 2020-08-14 23:49:14
*/

import BlackAndWhite from './type/BlackAndWhite'
import Bloom from './type/Bloom'
import Brightness from './type/Brightness'
import DepthOfField from './type/DepthOfField'
import LensFlare from './type/LensFlare'
import NightVision from './type/NightVision'
import Silhouette from './type/Silhouette'

class Effect {
constructor() {
this._comps = {
blackAndWhite: new BlackAndWhite(),
bloom: new Bloom(),
brightness: new Brightness(),
depthOfField: new DepthOfField(),
lensFlare: new LensFlare(),
night: new NightVision(),
silhouette: new Silhouette()
}
}

get blackAndWhite() {
return this._comps.blackAndWhite
}

get bloom() {
return this._comps.bloom
}

get brightness() {
return this._comps.brightness
}

get depthOfField() {
return this._comps.depthOfField
}

get lensFlare() {
return this._comps.lensFlare
}

get night() {
return this._comps.night
}

get silhouette() {
return this._comps.silhouette
}

/**
*
* @param viewer
*/
install(viewer) {
Object.keys(this._comps).forEach(key => {
this._comps[key].addTo(viewer)
})
Object.defineProperty(viewer, 'effect', {
value: this,
writable: false
})
}
}

export default Effect

+ 80
- 0
modules/effect/type/BlackAndWhite.js View File

@@ -0,0 +1,80 @@
/**
* @Author: Caven
* @Date: 2020-08-14 23:51:47
*/

import { Cesium } from '@dc-modules/namespace'
import State from '@dc-modules/state/State'

class BlackAndWhite {
constructor() {
this._viewer = undefined
this._delegate = undefined
this._enable = false
this._gradations = 1
this._selected = []
this.type = 'black_and_white'
this._state = State.INITIALIZED
}

set enable(enable) {
this._enable = enable
if (enable && this._viewer && !this._delegate) {
this._createPostProcessStage()
}
this._delegate && (this._delegate.enabled = enable)
return this
}

get enable() {
return this._enable
}

set gradations(gradations) {
this._gradations = gradations
this._delegate && (this._delegate.uniforms.gradations = gradations)
return this
}

get gradations() {
return this._gradations
}

set selected(selected) {
this._selected = selected
this._delegate && (this._delegate.selected = selected)
return this
}

get selected() {
return this._selected
}

/**
*
* @private
*/
_createPostProcessStage() {
this._delegate = Cesium.PostProcessStageLibrary.createBlackAndWhiteStage()
if (this._delegate) {
this._delegate.uniforms.gradations = this._gradations
this._viewer.scene.postProcessStages.add(this._delegate)
}
}

/**
*
* @param viewer
* @returns {BlackAndWhite}
*/
addTo(viewer) {
if (!viewer) {
return this
}
this._viewer = viewer
this._state = State.ADDED
return this
}
}

export default BlackAndWhite

+ 135
- 0
modules/effect/type/Bloom.js View File

@@ -0,0 +1,135 @@
/**
* @Author: Caven
* @Date: 2020-08-14 23:50:27
*/

import State from '@dc-modules/state/State'

class Bloom {
constructor() {
this._viewer = undefined
this._enable = false
this._contrast = 128
this._brightness = -0.3
this._glowOnly = false
this._delta = 1
this._sigma = 3.8
this._stepSize = 5
this._selected = []
this.type = 'bloom'
this._state = State.INITIALIZED
}

set enable(enable) {
this._enable = enable
if (enable && this._viewer && !this._delegate) {
this._createPostProcessStage()
}
this._delegate && (this._delegate.enabled = enable)
return this
}

get enable() {
return this._enable
}

set contrast(contrast) {
this._contrast = contrast
this._delegate && (this._delegate.uniforms.contrast = contrast)
return this
}

get contrast() {
return this._contrast
}

set brightness(brightness) {
this._brightness = brightness
this._delegate && (this._delegate.uniforms.brightness = brightness)
return this
}

get brightness() {
return this._brightness
}

set glowOnly(glowOnly) {
this._glowOnly = glowOnly
this._delegate && (this._delegate.uniforms.glowOnly = glowOnly)
return this
}

get glowOnly() {
return this._glowOnly
}

set delta(delta) {
this._delta = delta
this._delegate && (this._delegate.uniforms.delta = delta)
return this
}

get delta() {
return this._delta
}

set sigma(sigma) {
this._sigma = sigma
this._delegate && (this._delegate.uniforms.sigma = sigma)
return this
}

get sigma() {
return this._sigma
}

set stepSize(stepSize) {
this._stepSize = stepSize
this._delegate && (this._delegate.uniforms.stepSize = stepSize)
return this
}

get stepSize() {
return this._stepSize
}

set selected(selected) {
this._selected = selected
this._delegate && (this._delegate.selected = selected)
return this
}

get selected() {
return this._selected
}

/**
*
* @private
*/
_createPostProcessStage() {
this._delegate = this._viewer.scene.postProcessStages.bloom
this._delegate.uniforms.contrast = this._contrast
this._delegate.uniforms.brightness = this._brightness
this._delegate.uniforms.glowOnly = this._glowOnly
this._delegate.uniforms.delta = this._delta
this._delegate.uniforms.sigma = this._sigma
this._delegate.uniforms.stepSize = this._stepSize
}

/**
*
* @param viewer
* @returns {Bloom}
*/
addTo(viewer) {
if (!viewer) {
return this
}
this._viewer = viewer
this._state = State.ADDED
return this
}
}

export default Bloom

+ 80
- 0
modules/effect/type/Brightness.js View File

@@ -0,0 +1,80 @@
/**
* @Author: Caven
* @Date: 2020-08-14 23:51:47
*/

import { Cesium } from '@dc-modules/namespace'
import State from '@dc-modules/state/State'

class Brightness {
constructor() {
this._viewer = undefined
this._delegate = undefined
this._enable = false
this._intensity = 1
this._selected = []
this.type = 'brightness'
this._state = State.INITIALIZED
}

set enable(enable) {
this._enable = enable
if (enable && this._viewer && !this._delegate) {
this._createPostProcessStage()
}
this._delegate && (this._delegate.enabled = enable)
return this
}

get enable() {
return this._enable
}

set intensity(intensity) {
this._intensity = intensity
this._delegate && (this._delegate.uniforms.brightness = intensity)
return this
}

get intensity() {
return this._intensity
}

set selected(selected) {
this._selected = selected
this._delegate && (this._delegate.selected = selected)
return this
}

get selected() {
return this._selected
}

/**
*
* @private
*/
_createPostProcessStage() {
this._delegate = Cesium.PostProcessStageLibrary.createBrightnessStage()
if (this._delegate) {
this._delegate.uniforms.brightness = this._intensity
this._viewer.scene.postProcessStages.add(this._delegate)
}
}

/**
*
* @param viewer
* @returns {Brightness}
*/
addTo(viewer) {
if (!viewer) {
return this
}
this._viewer = viewer
this._state = State.ADDED
return this
}
}

export default Brightness

+ 123
- 0
modules/effect/type/DepthOfField.js View File

@@ -0,0 +1,123 @@
/**
* @Author: Caven
* @Date: 2020-08-14 23:51:47
*/

import { Cesium } from '@dc-modules/namespace'
import State from '@dc-modules/state/State'

class DepthOfField {
constructor() {
this._viewer = undefined
this._delegate = undefined
this._enable = false
this._focalDistance = 87
this._delta = 1
this._sigma = 3.8
this._stepSize = 2.5
this._selected = []
this.type = 'depth_of_field'
this._state = State.INITIALIZED
}

set enable(enable) {
this._enable = enable
if (
enable &&
this._viewer &&
Cesium.PostProcessStageLibrary.isDepthOfFieldSupported(
this._viewer.scene
) &&
!this._delegate
) {
this._createPostProcessStage()
}
this._delegate && (this._delegate.enabled = enable)
return this
}

get enable() {
return this._enable
}

set focalDistance(focalDistance) {
this._focalDistance = focalDistance
this._delegate && (this._delegate.uniforms.focalDistance = focalDistance)
return this
}

get focalDistance() {
return this._focalDistance
}

set delta(delta) {
this._delta = delta
this._delegate && (this._delegate.uniforms.delta = delta)
return this
}

get delta() {
return this._delta
}

set sigma(sigma) {
this._sigma = sigma
this._delegate && (this._delegate.uniforms.sigma = sigma)
return this
}

get sigma() {
return this._sigma
}

set stepSize(stepSize) {
this._stepSize = stepSize
this._delegate && (this._delegate.uniforms.stepSize = stepSize)
return this
}

get stepSize() {
return this._stepSize
}

set selected(selected) {
this._selected = selected
this._delegate && (this._delegate.selected = selected)
return this
}

get selected() {
return this._selected
}

/**
*
* @private
*/
_createPostProcessStage() {
this._delegate = Cesium.PostProcessStageLibrary.createDepthOfFieldStage()
if (this._delegate) {
this._delegate.uniforms.focalDistance = this._focalDistance
this._delegate.uniforms.delta = this._delta
this._delegate.uniforms.sigma = this._sigma
this._delegate.uniforms.stepSize = this._stepSize
this._viewer.scene.postProcessStages.add(this._delegate)
}
}

/**
*
* @param viewer
* @returns {DepthOfField}
*/
addTo(viewer) {
if (!viewer) {
return this
}
this._viewer = viewer
this._state = State.ADDED
return this
}
}

export default DepthOfField

+ 116
- 0
modules/effect/type/LensFlare.js View File

@@ -0,0 +1,116 @@
/**
* @Author: Caven
* @Date: 2020-08-14 23:51:47
*/

import { Cesium } from '@dc-modules/namespace'
import State from '@dc-modules/state/State'

class LensFlare {
constructor() {
this._viewer = undefined
this._delegate = undefined
this._enable = false
this._intensity = 6
this._distortion = 61
this._dirtAmount = 0.4
this._haloWidth = 0.4
this._selected = []
this.type = 'lens_flare'
this._state = State.INITIALIZED
}

set enable(enable) {
this._enable = enable
if (enable && this._viewer && !this._delegate) {
this._createPostProcessStage()
}
this._delegate && (this._delegate.enabled = enable)
return this
}

get enable() {
return this._enable
}

set intensity(intensity) {
this._intensity = intensity
this._delegate && (this._delegate.uniforms.intensity = intensity)
return this
}

get intensity() {
return this._intensity
}

set distortion(distortion) {
this._distortion = distortion
this._delegate && (this._delegate.uniforms.distortion = distortion)
return this
}

get distortion() {
return this._distortion
}

set dirtAmount(dirtAmount) {
this._dirtAmount = dirtAmount
this._delegate && (this._delegate.uniforms.dirtAmount = dirtAmount)
return this
}

get dirtAmount() {
return this._dirtAmount
}

set haloWidth(haloWidth) {
this._haloWidth = haloWidth
this._delegate && (this._delegate.uniforms.haloWidth = haloWidth)
return this
}

get haloWidth() {
return this._haloWidth
}

set selected(selected) {
this._selected = selected
this._delegate && (this._delegate.selected = selected)
return this
}

get selected() {
return this._selected
}

/**
*
* @private
*/
_createPostProcessStage() {
this._delegate = Cesium.PostProcessStageLibrary.createLensFlareStage()
if (this._delegate) {
this._delegate.uniforms.intensity = this._intensity
this._delegate.uniforms.distortion = this._distortion
this._delegate.uniforms.dirtAmount = this._dirtAmount
this._delegate.uniforms.haloWidth = this._haloWidth
this._viewer.scene.postProcessStages.add(this._delegate)
}
}

/**
*
* @param viewer
* @returns {LensFlare}
*/
addTo(viewer) {
if (!viewer) {
return this
}
this._viewer = viewer
this._state = State.ADDED
return this
}
}

export default LensFlare

+ 66
- 0
modules/effect/type/NightVision.js View File

@@ -0,0 +1,66 @@
/**
* @Author: Caven
* @Date: 2020-08-14 23:10:14
*/

import { Cesium } from '@dc-modules/namespace'
import State from '@dc-modules/state/State'

class NightVision {
constructor() {
this._enable = false
this._selected = []
this.type = 'night'
this._state = State.INITIALIZED
}

set enable(enable) {
this._enable = enable
if (enable && this._viewer && !this._delegate) {
this._createPostProcessStage()
}
this._delegate && (this._delegate.enabled = enable)
return this
}

get enable() {
return this._enable
}

set selected(selected) {
this._selected = selected
this._delegate && (this._delegate.selected = selected)
return this
}

get selected() {
return this._selected
}

/**
*
* @private
*/
_createPostProcessStage() {
this._delegate = Cesium.PostProcessStageLibrary.createNightVisionStage()
if (this._delegate) {
this._viewer.scene.postProcessStages.add(this._delegate)
}
}

/**
*
* @param viewer
* @returns {NightVision}
*/
addTo(viewer) {
if (!viewer) {
return this
}
this._viewer = viewer
this._state = State.ADDED
return this
}
}

export default NightVision

+ 99
- 0
modules/effect/type/Silhouette.js View File

@@ -0,0 +1,99 @@
/**
* @Author: Caven
* @Date: 2020-08-14 23:51:47
*/

import { Cesium } from '@dc-modules/namespace'
import State from '@dc-modules/state/State'

class Silhouette {
constructor() {
this._viewer = undefined
this._delegate = undefined
this._enable = false
this._color = Cesium.Color.GREEN
this._length = 0.5
this._selected = []
this.type = 'silhouette'
this._state = State.INITIALIZED
}

set enable(enable) {
this._enable = enable
if (
enable &&
this._viewer &&
Cesium.PostProcessStageLibrary.isSilhouetteSupported(
this._viewer.scene
) &&
!this._delegate
) {
this._createPostProcessStage()
}
this._delegate && (this._delegate.enabled = enable)
return this
}

get enable() {
return this._enable
}

set color(color) {
this._color = color
this._delegate && (this._delegate.uniforms.color = color)
return this
}

get color() {
return this._color
}

set length(length) {
this._length = length
this._delegate && (this._delegate.uniforms.length = length)
return this
}

get length() {
return this._length
}

set selected(selected) {
this._selected = selected
this._delegate && (this._delegate.selected = selected)
return this
}

get selected() {
return this._selected
}

/**
*
* @private
*/
_createPostProcessStage() {
this._delegate = Cesium.PostProcessStageLibrary.createSilhouetteStage()
if (this._delegate) {
this._delegate.uniforms.color = this._color
this._delegate.uniforms.length = this._length
this._viewer.scene.postProcessStages.add(this._delegate)
}
}

/**
*
* @param viewer
* @returns {Silhouette}
*/
addTo(viewer) {
if (!viewer) {
return this
}
this._viewer = viewer
this._state = State.ADDED
return this
}
}

export default Silhouette

+ 0
- 0
modules/effect/type/Sun.js View File


+ 115
- 0
modules/event/Event.js View File

@@ -0,0 +1,115 @@
/**
* @Author: Caven
* @Date: 2020-01-02 15:24:38
*/

class Event {
constructor() {
this._cache = {}
this._registerEvent()
}

/**
* Event registration
* Subclasses need to override
* @private
*/
_registerEvent() {}

/**
* @param type
* @param callback
* @param context
* @returns {any}
* @private
*/
_on(type, callback, context) {
let event = this.getEvent(type)
let removeCallback = undefined
if (event && callback) {
removeCallback = event.addEventListener(callback, context || this)
}
return removeCallback
}

/**
* @param type
* @param callback
* @param context
* @returns {boolean}
* @private
*/
_off(type, callback, context) {
let event = this.getEvent(type)
let removed = false
if (event && callback) {
removed = event.removeEventListener(callback, context || this)
}
return removed
}

/**
* @param type
* @param params
* @private
*/
_fire(type, params) {
let event = this.getEvent(type)
if (event) {
event.raiseEvent(params)
}
}

/**
* Subscribe event
* @param type
* @param callback
* @param context
* @returns remove callback function
*/
on(type, callback, context) {
return this._on(type, callback, context)
}

/**
* Subscribe once event
* @param type
* @param callback
* @param context
*/
once(type, callback, context) {
let removeCallback = this._on(type, callback, context)
removeCallback && removeCallback()
}

/**
* Unsubscribe event
* @param type
* @param callback
* @param context
* @returns Boolean
*/
off(type, callback, context) {
return this._off(type, callback, context)
}

/**
* Trigger subscription event
* @param type
* @param params
*/
fire(type, params) {
this._fire(type, params)
}

/**
* Returns events by type
* @param type
* @returns Event
*/
getEvent(type) {
return this._cache[type] || undefined
}
}

export default Event

+ 79
- 0
modules/event/EventType.js View File

@@ -0,0 +1,79 @@
/**
* @Author: Caven
* @Date: 2020-04-10 17:02:28
*/

import { Cesium } from '@dc-modules/namespace'

const BaseEventType = {
ADD: 'add',
REMOVE: 'remove'
}

const MouseEventType = {
CLICK: Cesium.ScreenSpaceEventType.LEFT_CLICK,
RIGHT_CLICK: Cesium.ScreenSpaceEventType.RIGHT_CLICK,
DB_CLICK: Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK,
MOUSE_MOVE: Cesium.ScreenSpaceEventType.MOUSE_MOVE,
WHEEL: Cesium.ScreenSpaceEventType.WHEEL,
MOUSE_OVER: 'mouseover',
MOUSE_OUT: 'mouseout'
}

const ViewerEventType = {
ADD_LAYER: 'addLayer',
REMOVE_LAYER: 'removeLayer',
ADD_EFFECT: 'addEffect',
REMOVE_EFFECT: 'removeEffect',
CLICK: Cesium.ScreenSpaceEventType.LEFT_CLICK,
RIGHT_CLICK: Cesium.ScreenSpaceEventType.RIGHT_CLICK,
DB_CLICK: Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK,
MOUSE_MOVE: Cesium.ScreenSpaceEventType.MOUSE_MOVE,
WHEEL: Cesium.ScreenSpaceEventType.WHEEL
}

const SceneEventType = {
CAMERA_MOVE_END: 'cameraMoveEnd',
CAMERA_CHANGED: 'cameraChanged',
PRE_UPDATE: 'preUpdate',
POST_UPDATE: 'postUpdate',
PRE_RENDER: 'preRender',
POST_RENDER: 'postRender',
MORPH_COMPLETE: 'morphComplete',
CLOCK_TICK: 'clockTick'
}

const OverlayEventType = {
...BaseEventType,
CLICK: Cesium.ScreenSpaceEventType.LEFT_CLICK,
RIGHT_CLICK: Cesium.ScreenSpaceEventType.RIGHT_CLICK,
DB_CLICK: Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK,
MOUSE_MOVE: Cesium.ScreenSpaceEventType.MOUSE_MOVE,
MOUSE_OVER: 'mouseover',
MOUSE_OUT: 'mouseout',
POSITION_UPDATE: 'positionUpdate'
}

const LayerGroupEventType = BaseEventType

const LayerEventType = {
...BaseEventType,
CLICK: Cesium.ScreenSpaceEventType.LEFT_CLICK
}

const RoamingEventType = {
...BaseEventType,
POST_UPDATE: 'postUpdate',
ACTIVE: 'active',
RELEASE: 'release'
}

export {
MouseEventType,
ViewerEventType,
SceneEventType,
LayerGroupEventType,
LayerEventType,
OverlayEventType,
RoamingEventType
}

+ 14
- 0
modules/event/index.js View File

@@ -0,0 +1,14 @@
/**
* @Author: Caven
* @Date: 2021-03-13 13:24:24
*/

export * from './EventType'
export { default as Event } from './Event'
export { default as MouseEvent } from './type/MouseEvent'
export { default as ViewerEvent } from './type/ViewerEvent'
export { default as SceneEvent } from './type/SceneEvent'
export { default as LayerGroupEvent } from './type/LayerGroupEvent'
export { default as LayerEvent } from './type/LayerEvent'
export { default as OverlayEvent } from './type/OverlayEvent'
export { default as RoamingEvent } from './type/RoamingEvent'

+ 27
- 0
modules/event/type/LayerEvent.js View File

@@ -0,0 +1,27 @@
/**
* @Author: Caven
* @Date: 2020-01-02 14:26:35
*/

import { Cesium } from '@dc-modules/namespace'
import { LayerEventType } from '../EventType'
import Event from '../Event'

class LayerEvent extends Event {
constructor() {
super()
}

/**
* Register event for layer
* @private
*/
_registerEvent() {
Object.keys(LayerEventType).forEach(key => {
let type = LayerEventType[key]
this._cache[type] = new Cesium.Event()
})
}
}

export default LayerEvent

+ 27
- 0
modules/event/type/LayerGroupEvent.js View File

@@ -0,0 +1,27 @@
/**
* @Author: Caven
* @Date: 2020-08-28 20:18:04
*/

import { Cesium } from '@dc-modules/namespace'
import { LayerGroupEventType } from '../EventType'
import Event from '../Event'

class LayerGroupEvent extends Event {
constructor() {
super()
}

/**
* Register event for layer group
* @private
*/
_registerEvent() {
Object.keys(LayerGroupEventType).forEach(key => {
let type = LayerGroupEventType[key]
this._cache[type] = new Cesium.Event()
})
}
}

export default LayerGroupEvent

+ 307
- 0
modules/event/type/MouseEvent.js View File

@@ -0,0 +1,307 @@
/**
* @Author: Caven
* @Date: 2019-12-31 16:58:31
*/

import { Cesium } from '@dc-modules/namespace'
import { MouseEventType } from '../EventType'
import Event from '../Event'

/**
* Mouse events in 3D scene, optimized Cesium event model
*/
class MouseEvent extends Event {
constructor(viewer) {
super()
this._viewer = viewer
this._selected = undefined
this._setInputAction()
this.on(MouseEventType.CLICK, this._clickHandler, this)
this.on(MouseEventType.DB_CLICK, this._dbClickHandler, this)
this.on(MouseEventType.RIGHT_CLICK, this._rightClickHandler, this)
this.on(MouseEventType.MOUSE_MOVE, this._mouseMoveHandler, this)
this.on(MouseEventType.WHEEL, this._mouseWheelHandler, this)
}

/**
* Register Cesium mouse events
* @private
*/
_setInputAction() {
let handler = new Cesium.ScreenSpaceEventHandler(this._viewer.canvas)
Object.keys(Cesium.ScreenSpaceEventType).forEach(key => {
let type = Cesium.ScreenSpaceEventType[key]
this._cache[type] = new Cesium.Event()
handler.setInputAction(movement => {
this._cache[type].raiseEvent(movement)
}, type)
})
}

/**
*
* Gets the mouse information for the mouse event
* @param position
* @private
*
*/
_getMouseInfo(position) {
let scene = this._viewer.scene
let target = scene.pick(position)
let cartesian = undefined
let surfaceCartesian = undefined
let wgs84Position = undefined
let wgs84SurfacePosition = undefined
if (scene.pickPositionSupported) {
cartesian = scene.pickPosition(position)
}
if (cartesian) {
let c = Cesium.Ellipsoid.WGS84.cartesianToCartographic(cartesian)
if (c) {
wgs84Position = {
lng: Cesium.Math.toDegrees(c.longitude),
lat: Cesium.Math.toDegrees(c.latitude),
alt: c.height
}
}
}
if (
scene.mode === Cesium.SceneMode.SCENE3D &&
!(this._viewer.terrainProvider instanceof Cesium.EllipsoidTerrainProvider)
) {
let ray = scene.camera.getPickRay(position)
surfaceCartesian = scene.globe.pick(ray, scene)
} else {
surfaceCartesian = scene.camera.pickEllipsoid(
position,
Cesium.Ellipsoid.WGS84
)
}
if (surfaceCartesian) {
let c = Cesium.Ellipsoid.WGS84.cartesianToCartographic(surfaceCartesian)
if (c) {
wgs84SurfacePosition = {
lng: Cesium.Math.toDegrees(c.longitude),
lat: Cesium.Math.toDegrees(c.latitude),
alt: c.height
}
}
}

return {
target: target,
windowPosition: position,
position: cartesian,
wgs84Position: wgs84Position,
surfacePosition: surfaceCartesian,
wgs84SurfacePosition: wgs84SurfacePosition
}
}

/**
* Gets the drill pick overlays for the mouse event
* @param position
* @returns {[]}
* @private
*/
_getDrillInfos(position) {
let drillInfos = []
let scene = this._viewer.scene
let targets = scene.drillPick(position)
if (targets && targets.length) {
targets.forEach(target => {
drillInfos.push(this._getTargetInfo(target))
})
}
return drillInfos
}

/**
* Return the Overlay id
* @param target
* @returns {any}
* @private
*/
_getOverlayId(target) {
let overlayId = undefined

// for Entity
if (target && target.id && target.id instanceof Cesium.Entity) {
overlayId = target.id.overlayId
}

// for Cesium3DTileFeature
if (target && target instanceof Cesium.Cesium3DTileFeature) {
overlayId = target.tileset.overlayId
}

return overlayId
}

/**
* Returns the target information for the mouse event
* @param target
* @returns {{overlay: any, feature: any, layer: any}}
* @private
*/
_getTargetInfo(target) {
let overlay = undefined
let layer = undefined
let feature = undefined

// for Entity
if (target && target.id && target.id instanceof Cesium.Entity) {
layer = this._viewer
.getLayers()
.filter(item => item.layerId === target.id.layerId)[0]
if (layer && layer.getOverlay) {
overlay = layer.getOverlay(target.id.overlayId)
}
}

// for Cesium3DTileFeature
if (target && target instanceof Cesium.Cesium3DTileFeature) {
layer = this._viewer
.getLayers()
.filter(item => item.layerId === target.tileset.layerId)[0]
feature = target
if (layer && layer.getOverlay) {
overlay = layer.getOverlay(target.tileset.overlayId)
if (feature && feature.getPropertyNames) {
let propertyNames = feature.getPropertyNames()
propertyNames.forEach(item => {
overlay.attr[item] = feature.getProperty(item)
})
}
}
}

return { layer: layer, overlay: overlay, feature: feature }
}

/**
* Trigger subscription event
* @param type
* @param mouseInfo
* @private
*/
_raiseEvent(type, mouseInfo = {}) {
let event = undefined
let targetInfo = this._getTargetInfo(mouseInfo.target)
let overlay = targetInfo?.overlay
// get Overlay Event
if (overlay && overlay.overlayEvent) {
event = overlay.overlayEvent.getEvent(type)
}

// get Viewer Event
if (!event || event.numberOfListeners === 0) {
event = this._viewer.viewerEvent.getEvent(type)
}
event &&
event.numberOfListeners > 0 &&
event.raiseEvent({
...targetInfo,
...mouseInfo
})

// get Drill Pick Event
if (overlay && overlay.allowDrillPicking) {
let drillInfos = this._getDrillInfos(mouseInfo.windowPosition)
drillInfos.forEach(drillInfo => {
let dillOverlay = drillInfo?.overlay
if (
dillOverlay?.overlayId !== overlay.overlayId &&
dillOverlay?.overlayEvent
) {
event = dillOverlay.overlayEvent.getEvent(type)
event &&
event.numberOfListeners > 0 &&
event.raiseEvent({
...drillInfo,
...mouseInfo
})
}
})
}
}

/**
* Default click event handler
* @param movement
* @returns {boolean}
* @private
*/
_clickHandler(movement) {
if (!movement || !movement.position) {
return false
}
let mouseInfo = this._getMouseInfo(movement.position)
this._raiseEvent(MouseEventType.CLICK, mouseInfo)
}

/**
* Default dbClick event handler
* @param movement
* @returns {boolean}
* @private
*/
_dbClickHandler(movement) {
if (!movement || !movement.position) {
return false
}
let mouseInfo = this._getMouseInfo(movement.position)
this._raiseEvent(MouseEventType.DB_CLICK, mouseInfo)
}

/**
* Default rightClick event handler
* @param movement
* @returns {boolean}
* @private
*/
_rightClickHandler(movement) {
if (!movement || !movement.position) {
return false
}
let mouseInfo = this._getMouseInfo(movement.position)
this._raiseEvent(MouseEventType.RIGHT_CLICK, mouseInfo)
}

/**
* Default mousemove event handler
* @param movement
* @returns {boolean}
* @private
*/
_mouseMoveHandler(movement) {
if (!movement || !movement.endPosition) {
return false
}
let mouseInfo = this._getMouseInfo(movement.endPosition)
this._viewer.canvas.style.cursor = mouseInfo.target ? 'pointer' : 'default'
this._raiseEvent(MouseEventType.MOUSE_MOVE, mouseInfo)

// add event for overlay
if (
!this._selected ||
this._getOverlayId(this._selected.target) !==
this._getOverlayId(mouseInfo.target)
) {
this._raiseEvent(MouseEventType.MOUSE_OUT, this._selected)
this._raiseEvent(MouseEventType.MOUSE_OVER, mouseInfo)
this._selected = mouseInfo
}
}

/**
* Default mouse wheel event handler
* @param movement
* @private
*/
_mouseWheelHandler(movement) {
this._raiseEvent(MouseEventType.WHEEL, { movement })
}
}

export default MouseEvent

+ 27
- 0
modules/event/type/OverlayEvent.js View File

@@ -0,0 +1,27 @@
/**
* @Author: Caven
* @Date: 2020-01-02 14:26:35
*/

import { Cesium } from '@dc-modules/namespace'
import { OverlayEventType } from '../EventType'
import Event from '../Event'

class OverlayEvent extends Event {
constructor() {
super()
}

/**
* Register event for overlay
* @private
*/
_registerEvent() {
Object.keys(OverlayEventType).forEach(key => {
let type = OverlayEventType[key]
this._cache[type] = new Cesium.Event()
})
}
}

export default OverlayEvent

+ 27
- 0
modules/event/type/RoamingEvent.js View File

@@ -0,0 +1,27 @@
/**
* @Author: Caven
* @Date: 2020-05-11 23:28:13
*/

import { Cesium } from '@dc-modules/namespace'
import { RoamingEventType } from '../EventType'
import Event from '../Event'

class RoamingEvent extends Event {
constructor() {
super()
}

/**
*
* @private
*/
_registerEvent() {
Object.keys(RoamingEventType).forEach(key => {
let type = RoamingEventType[key]
this._cache[type] = new Cesium.Event()
})
}
}

export default RoamingEvent

+ 147
- 0
modules/event/type/SceneEvent.js View File

@@ -0,0 +1,147 @@
/**
* @Author: Caven
* @Date: 2020-03-02 21:32:43
*/

import { SceneEventType } from '../EventType'
import Event from '../Event'

class SceneEvent extends Event {
constructor(viewer) {
super()
this._camera = viewer.camera
this._scene = viewer.scene
this._clock = viewer.clock
}

/**
* Subscribe event
* @param type
* @param callback
* @param context
* @returns {any}
*/
on(type, callback, context) {
let removeCallback = undefined
switch (type) {
case SceneEventType.CAMERA_MOVE_END:
removeCallback = this._camera.moveEnd.addEventListener(
callback,
context || this
)
break
case SceneEventType.CAMERA_CHANGED:
removeCallback = this._camera.changed.addEventListener(
callback,
context || this
)
break
case SceneEventType.PRE_UPDATE:
removeCallback = this._scene.preUpdate.addEventListener(
callback,
context || this
)
break
case SceneEventType.POST_UPDATE:
removeCallback = this._scene.postUpdate.addEventListener(
callback,
context || this
)
break
case SceneEventType.PRE_RENDER:
removeCallback = this._scene.preRender.addEventListener(
callback,
context || this
)
break
case SceneEventType.POST_RENDER:
removeCallback = this._scene.postRender.addEventListener(
callback,
context || this
)
break
case SceneEventType.MORPH_COMPLETE:
removeCallback = this._scene.morphComplete.addEventListener(
callback,
context || this
)
break
case SceneEventType.CLOCK_TICK:
removeCallback = this._clock.onTick.addEventListener(
callback,
context || this
)
break
default:
break
}
return removeCallback
}

/**
* Unsubscribe event
* @param type
* @param callback
* @param context
* @returns {boolean}
*/
off(type, callback, context) {
let removed = false
switch (type) {
case SceneEventType.CAMERA_MOVE_END:
removed = this._camera.moveEnd.removeEventListener(
callback,
context || this
)
break
case SceneEventType.CAMERA_CHANGED:
removed = this._camera.changed.removeEventListener(
callback,
context || this
)
break
case SceneEventType.PRE_UPDATE:
removed = this._scene.preUpdate.removeEventListener(
callback,
context || this
)
break
case SceneEventType.POST_UPDATE:
removed = this._scene.postUpdate.removeEventListener(
callback,
context || this
)
break
case SceneEventType.PRE_RENDER:
removed = this._scene.preRender.removeEventListener(
callback,
context || this
)
break
case SceneEventType.POST_RENDER:
removed = this._scene.postRender.removeEventListener(
callback,
context || this
)
break
case SceneEventType.MORPH_COMPLETE:
removed = this._scene.morphComplete.removeEventListener(
callback,
context || this
)
break
case SceneEventType.CLOCK_TICK:
removed = this._clock.onTick.removeEventListener(
callback,
context || this
)
break
default:
break
}

return removed
}
}

export default SceneEvent

+ 27
- 0
modules/event/type/ViewerEvent.js View File

@@ -0,0 +1,27 @@
/**
* @Author: Caven
* @Date: 2020-01-02 14:26:35
*/

import { Cesium } from '@dc-modules/namespace'
import { ViewerEventType } from '../EventType'
import Event from '../Event'

class ViewerEvent extends Event {
constructor() {
super()
}

/**
* Register event for viewer
* @private
*/
_registerEvent() {
Object.keys(ViewerEventType).forEach(key => {
let type = ViewerEventType[key]
this._cache[type] = new Cesium.Event()
})
}
}

export default ViewerEvent

+ 190
- 0
modules/exts/SkyBox.js View File

@@ -0,0 +1,190 @@
/**
* @Author: Caven
* @Date: 2021-02-21 17:50:31
*/

import { Cesium } from '@dc-modules/namespace'

const {
BoxGeometry,
Cartesian3,
defined,
DeveloperError,
GeometryPipeline,
Matrix3,
Matrix4,
Transforms,
VertexFormat,
BufferUsage,
CubeMap,
loadCubeMap,
RenderState,
VertexArray,
BlendingState,
SceneMode,
ShaderProgram,
ShaderSource
} = Cesium

const SkyBoxFS = `
uniform samplerCube u_cubeMap;
varying vec3 v_texCoord;
void main()
{
vec4 color = textureCube(u_cubeMap, normalize(v_texCoord));
gl_FragColor = vec4(czm_gammaCorrect(color).rgb, czm_morphTime);
}
`

const SkyBoxVS = `
attribute vec3 position;
varying vec3 v_texCoord;
uniform mat3 u_rotateMatrix;
void main()
{
vec3 p = czm_viewRotation * u_rotateMatrix * (czm_temeToPseudoFixed * (czm_entireFrustum.y * position));
gl_Position = czm_projection * vec4(p, 1.0);
v_texCoord = position.xyz;
}
`

class SkyBox extends Cesium.SkyBox {
constructor(options = {}) {
super(options)
this.offsetAngle = options?.offsetAngle || 90
}

update(frameState, useHdr) {
const that = this

if (!this.show) {
return undefined
}

if (
frameState.mode !== SceneMode.SCENE3D &&
frameState.mode !== SceneMode.MORPHING
) {
return undefined
}

if (!frameState.passes.render) {
return undefined
}

const context = frameState.context

if (this._sources !== this.sources) {
this._sources = this.sources
const sources = this.sources

if (
!defined(sources.positiveX) ||
!defined(sources.negativeX) ||
!defined(sources.positiveY) ||
!defined(sources.negativeY) ||
!defined(sources.positiveZ) ||
!defined(sources.negativeZ)
) {
throw new DeveloperError(
'this.sources is required and must have positiveX, negativeX, positiveY, negativeY, positiveZ, and negativeZ properties.'
)
}

if (
typeof sources.positiveX !== typeof sources.negativeX ||
typeof sources.positiveX !== typeof sources.positiveY ||
typeof sources.positiveX !== typeof sources.negativeY ||
typeof sources.positiveX !== typeof sources.positiveZ ||
typeof sources.positiveX !== typeof sources.negativeZ
) {
throw new DeveloperError(
'this.sources properties must all be the same type.'
)
}

if (typeof sources.positiveX === 'string') {
// Given urls for cube-map images. Load them.
loadCubeMap(context, this._sources).then(function(cubeMap) {
that._cubeMap = that._cubeMap && that._cubeMap.destroy()
that._cubeMap = cubeMap
})
} else {
this._cubeMap = this._cubeMap && this._cubeMap.destroy()
this._cubeMap = new CubeMap({
context: context,
source: sources
})
}
}

const command = this._command

command.modelMatrix = Transforms.eastNorthUpToFixedFrame(
frameState.camera.positionWC
)

if (this.offsetAngle !== 0) {
Matrix4.multiply(
command.modelMatrix,
Matrix4.fromRotationTranslation(
Matrix3.fromRotationZ((this.offsetAngle / 180) * Math.PI)
),
command.modelMatrix
)
}

if (!defined(command.vertexArray)) {
command.uniformMap = {
u_cubeMap: function() {
return that._cubeMap
},
u_rotateMatrix: function() {
return Matrix4.getMatrix3(command.modelMatrix, new Matrix3())
}
}

const geometry = BoxGeometry.createGeometry(
BoxGeometry.fromDimensions({
dimensions: new Cartesian3(2.0, 2.0, 2.0),
vertexFormat: VertexFormat.POSITION_ONLY
})
)
const attributeLocations = (this._attributeLocations = GeometryPipeline.createAttributeLocations(
geometry
))

command.vertexArray = VertexArray.fromGeometry({
context: context,
geometry: geometry,
attributeLocations: attributeLocations,
bufferUsage: BufferUsage._DRAW
})

command.renderState = RenderState.fromCache({
blending: BlendingState.ALPHA_BLEND
})
}

if (!defined(command.shaderProgram) || this._useHdr !== useHdr) {
const fs = new ShaderSource({
defines: [useHdr ? 'HDR' : ''],
sources: [SkyBoxFS]
})
command.shaderProgram = ShaderProgram.fromCache({
context: context,
vertexShaderSource: SkyBoxVS,
fragmentShaderSource: fs,
attributeLocations: this._attributeLocations
})
this._useHdr = useHdr
}

if (!defined(this._cubeMap)) {
return undefined
}
return command
}
}

export default SkyBox

+ 6
- 0
modules/exts/index.js View File

@@ -0,0 +1,6 @@
/**
* @Author: Caven
* @Date: 2021-02-21 17:51:00
*/

export { default as SkyBox } from './SkyBox'

+ 7
- 0
modules/global-api/index.js View File

@@ -0,0 +1,7 @@
/**
* @Author: Caven
* @Date: 2020-05-09 23:09:42
*/

export * from './mixin'
export * from './use'

+ 30
- 0
modules/global-api/mixin.js View File

@@ -0,0 +1,30 @@
/**
* @Author: Caven
* @Date: 2020-05-09 23:00:54
*/

const ignores = [
'version',
'author',
'home_page',
'init',
'ready',
'use',
'mixin',
'Namespace',
'Initialized'
]

/**
* Mix other plug-in attributes to DC
* @param DC
* @returns this
*/
export function initMixin(DC) {
DC.mixin = function(mixin) {
for (let key in mixin) {
ignores.indexOf(key) < 0 && (DC[key] = mixin[key])
}
return this
}
}

+ 29
- 0
modules/global-api/use.js View File

@@ -0,0 +1,29 @@
/**
* @Author: Caven
* @Date: 2020-05-09 23:01:21
*/

/**
* Using other custom plug-ins in DC
* @param DC
* @returns this
*/
export function initUse(DC) {
DC.use = function(plugin) {
const installedPlugins =
this._installedPlugins || (this._installedPlugins = [])
if (installedPlugins.indexOf(plugin) > -1) {
return this
}
// additional parameters
const args = []
args.unshift(this)
if (typeof plugin.install === 'function') {
plugin.install.apply(plugin, args)
} else if (typeof plugin === 'function') {
plugin.apply(null, args)
}
installedPlugins.push(plugin)
return this
}
}

+ 26
- 0
modules/icons/compass-inner.js View File

@@ -0,0 +1,26 @@
/**
* @Author: Caven
* @Date: 2020-06-06 14:05:25
*/

const compass_inner = `
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="17px" height="17px" viewBox="0 0 17 17" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 43.2 (39069) - http://www.bohemiancoding.com/sketch -->
<title>compass-inner</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Page-1" stroke="none" stroke-width="1" fill-rule="evenodd">
<g id="compass-inner" fill-rule="nonzero">
<path d="M8.5,16.5 C4.081722,16.5 0.5,12.918278 0.5,8.5 C0.5,4.081722 4.081722,0.5 8.5,0.5 C12.918278,0.5 16.5,4.081722 16.5,8.5 C16.5,12.918278 12.918278,16.5 8.5,16.5 Z M8.5,15.5 C12.3659932,15.5 15.5,12.3659932 15.5,8.5 C15.5,4.63400675 12.3659932,1.5 8.5,1.5 C4.63400675,1.5 1.5,4.63400675 1.5,8.5 C1.5,12.3659932 4.63400675,15.5 8.5,15.5 Z" id="Oval-96"></path>
<path d="M9.92599835,7.09066832 C12.7122872,9.87695712 14.3709388,12.5452228 13.4497471,13.4664145 C12.5285555,14.3876061 9.86028979,12.7289545 7.074001,9.94266568 C4.2877122,7.15637688 2.62906055,4.48811119 3.55025221,3.56691953 C4.47144386,2.64572788 7.13970955,4.30437952 9.92599835,7.09066832 Z M9.21889157,7.7977751 C6.92836458,5.50724811 4.52075769,4.01062761 4.25735899,4.27402631 C3.99396029,4.53742501 5.49058078,6.9450319 7.78110778,9.2355589 C10.0716348,11.5260859 12.4792417,13.0227064 12.7426404,12.7593077 C13.0060391,12.495909 11.5094186,10.0883021 9.21889157,7.7977751 Z" id="Oval-96-Copy-2"></path>
<path d="M9.92599835,9.94266568 C7.13970955,12.7289545 4.47144386,14.3876061 3.55025221,13.4664145 C2.62906055,12.5452228 4.2877122,9.87695712 7.074001,7.09066832 C9.86028979,4.30437952 12.5285555,2.64572788 13.4497471,3.56691953 C14.3709388,4.48811119 12.7122872,7.15637688 9.92599835,9.94266568 Z M9.21889157,9.2355589 C11.5094186,6.9450319 13.0060391,4.53742501 12.7426404,4.27402631 C12.4792417,4.01062761 10.0716348,5.50724811 7.78110778,7.7977751 C5.49058078,10.0883021 3.99396029,12.495909 4.25735899,12.7593077 C4.52075769,13.0227064 6.92836458,11.5260859 9.21889157,9.2355589 Z" id="Oval-96-Copy-3"></path>
<path d="M15.1464466,1.1464466 L14.3453364,1.94755684 L13.9608692,2.33202401 L14.667976,3.03913077 L15.0524431,2.65466362 L15.8535534,1.8535534 L15.1464466,1.1464466 Z M2.29760014,13.995293 L1.85311902,14.4397742 L1.004311,15.2885822 L1.71141776,15.995689 L2.56022581,15.146881 L3.00470698,14.7023998 L2.29760014,13.995293 Z" id="Line"></path>
<circle id="Oval-432" cx="16" cy="1" r="1"></circle>
<circle id="Oval-432-Copy" cx="1" cy="16" r="1"></circle>
</g>
</g>
</svg>
`

export default compass_inner

+ 29
- 0
modules/icons/compass-outer.js View File

@@ -0,0 +1,29 @@
/**
* @Author: Caven
* @Date: 2020-06-05 16:01:22
*/

const compass_outer = `
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="162px" height="162px" viewBox="0 0 162 162" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 43.2 (39069) - http://www.bohemiancoding.com/sketch -->
<title>compass-outer</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Page-1" stroke="none" stroke-width="1" fill-rule="evenodd">
<g id="compass-outer" fill-rule="nonzero">
<path d="M80.8410544,161.682109 C36.1937731,161.682109 0,125.488336 0,80.8410544 C0,36.1937731 36.1937731,0 80.8410544,0 C125.488336,0 161.682109,36.1937731 161.682109,80.8410544 C161.682109,125.488336 125.488336,161.682109 80.8410544,161.682109 Z M81.1836011,134.620909 C110.696211,134.620909 134.620909,110.696211 134.620909,81.1836011 C134.620909,51.6709916 110.696211,27.7462941 81.1836011,27.7462941 C51.6709916,27.7462941 27.7462941,51.6709916 27.7462941,81.1836011 C27.7462941,110.696211 51.6709916,134.620909 81.1836011,134.620909 Z" id="Oval-108"></path>
<circle id="Oval-74" fill="#FFFFFF" cx="129.493683" cy="127.952092" r="1.54159147"></circle>
<circle id="Oval-74-Copy-3" fill="#FFFFFF" cx="129.493683" cy="35.4566038" r="1.54159147"></circle>
<circle id="Oval-74-Copy-5" fill="#FFFFFF" cx="30.8318294" cy="127.952092" r="1.54159147"></circle>
<circle id="Oval-74-Copy-4" fill="#FFFFFF" cx="30.8318294" cy="35.4566038" r="1.54159147"></circle>
<polygon id="N" fill="#FFFFFF" points="84.9318072 23.1238721 84.9318072 13.1321362 82.5623385 13.1321362 82.5623385 19.2984646 77.951866 13.1321362 75.7108625 13.1321362 75.7108625 23.1238721 78.0946053 23.1238721 78.0946053 16.9718176 82.6908037 23.1238721"></polygon>
<polygon id="Line" fill="#FFFFFF" points="143.368007 82.1093476 152.617555 82.1093476 152.617555 81.2993476 143.368007 81.2993476"></polygon>
<polygon id="Line-Copy-8" fill="#FFFFFF" points="9.24954884 82.1093476 18.4990976 82.1093476 18.4990976 81.2993476 9.24954884 81.2993476"></polygon>
<polygon id="Line" fill="#FFFFFF" points="81.2993476 143.368007 81.2993476 152.617555 82.1093476 152.617555 82.1093476 143.368007"></polygon>
</g>
</g>
</svg>
`

export default compass_outer

+ 22
- 0
modules/icons/compass-rotation-marker.js View File

@@ -0,0 +1,22 @@
/**
* @Author: Caven
* @Date: 2020-06-06 14:11:56
*/

const compass_rotation_marker = `
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="53px" height="53px" viewBox="0 0 53 53" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
<!-- Generator: Sketch 3.4.3 (16044) - http://www.bohemiancoding.com/sketch -->
<title>compass-rotation-marker</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="compass-rotation-marker">
<path d="M52.4399986,26.2199993 C52.4399986,11.7390936 40.7009051,0 26.2199993,0 C11.7390936,0 0,11.7390936 0,26.2199993 C0,40.7009051 11.7390936,52.4399986 26.2199993,52.4399986 C40.7009051,52.4399986 52.4399986,40.7009051 52.4399986,26.2199993 Z" id="rotator" stroke-opacity="0.135841259" stroke="#E2A549" stroke-width="9" opacity="0.201434235"></path>
<path d="M0,26.2199993 C0,11.7390936 11.7390936,0 26.2199993,0 L26.2199993,9 C16.7096563,9 9,16.7096563 9,26.2199993" id="Shape" opacity="0.634561567" fill="#4990E2"></path>
</g>
</g>
</svg>
`

export default compass_rotation_marker

+ 14
- 0
modules/icons/decrease.js View File

@@ -0,0 +1,14 @@
/**
* @Author: Caven
* @Date: 2020-06-06 14:18:00
*/

const decrease = `
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="50px" height="6px" viewBox="0 0 50 6" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
<!-- Generator: Sketch 3.4.3 (16044) - http://www.bohemiancoding.com/sketch -->
<title>decrease</title>
<path d="M46.6183575,0.657894737 L3.30112724,0.657894737 C1.44927539,0.657894737 0,1.66880618 0,2.96052632 C0,4.25224645 1.44927539,5.26315789 3.30112724,5.26315789 L46.6988728,5.26315789 C48.5507246,5.26315789 50,4.25224645 50,2.96052632 C49.9194847,1.66880618 48.4702093,0.657894737 46.6183575,0.657894737 L46.6183575,0.657894737 L46.6183575,0.657894737 Z" id="Shape"></path>
</svg>
`
export default decrease

+ 15
- 0
modules/icons/increase.js View File

@@ -0,0 +1,15 @@
/**
* @Author: Caven
* @Date: 2020-06-06 14:18:00
*/

const increase = `
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="50px" height="50px" viewBox="0 0 50 50" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
<!-- Generator: Sketch 3.4.3 (16044) - http://www.bohemiancoding.com/sketch -->
<title>increase</title>
<path d="M0,25 C0,25.3514939 0.131810207,25.659051 0.373462207,25.900703 C0.615114207,26.142355 0.922671379,26.2741652 1.27416517,26.2741652 L23.7258348,26.2741652 L23.7258348,48.7258348 C23.7258348,49.0773286 23.857645,49.3848858 24.099297,49.6265378 C24.3189807,49.8462214 24.6485061,50 25,50 C25.7029877,50 26.2741652,49.4288225 26.2741652,48.7258348 L26.2741652,26.2741652 L48.7258348,26.2741652 C49.4288225,26.2741652 50,25.7029877 50,25 C50,24.2970123 49.4288225,23.7258348 48.7258348,23.7258348 L26.2741652,23.7258348 L26.2741652,1.27416517 C26.2741652,0.571177517 25.7029877,0 25,0 C24.2970123,0 23.7258348,0.571177517 23.7258348,1.27416517 L23.7258348,23.7258348 L1.27416517,23.7258348 C0.571177517,23.7258348 0,24.2970123 0,25 L0,25 L0,25 L0,25 Z" id="Shape"></path>
</svg>
`

export default increase

+ 26
- 0
modules/icons/index.js View File

@@ -0,0 +1,26 @@
/**
* @Author: Caven
* @Date: 2020-06-05 16:35:22
*/

import logo from './logo'
import compass_outer from './compass-outer'
import compass_inner from './compass-inner'
import compass_rotation_marker from './compass-rotation-marker'
import decrease from './decrease'
import increase from './increase'
import refresh from './refresh'
import splitter from './splitter'

const Icons = {
logo,
compass_outer,
compass_inner,
compass_rotation_marker,
decrease,
increase,
refresh,
splitter
}

export default Icons

+ 9
- 0
modules/icons/logo.js View File

@@ -0,0 +1,9 @@
/**
* @Author: Caven
* @Date: 2020-12-02 19:59:35
*/

const logo = `
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAG5ElEQVRoQ+2Yf2xVZxnHP89py9qliPe0BUTqBrunuDEBx8QfcxuwRYcxM3HO7Y8JZUNKTweKmWyaGDBZYtwSMmnvuXRKcEMzt0WmwdllE1nclkgsyUaIUM4ZNmKihfbcDjbCpPc85rT3QG1677ltb5UlPf+e932e7/f5vu/zPO8jfMA/+YDjZ4rA/1vBKQWmFBgWAXOnex0Bu4FPAf8Evu3b1vOFgnTZHKHa1LEVgZTtEoLv9NkLfpMjs03hfMa2VucjcdkQSKTdVkGq/ebk2ghswjmxSMh2+Lb10cufgOO9AHRk7OSTw8Gajqu+beUN9GWjgJnq2qZi3JqxrRURATPtbka5w7etL066AjXprmUaGDdhyCI0WAhyHeAjHFPoMgI9lDWyr/Y3X9udD4yZcg8j2qMiewVZhmpjoeiHdiakgJny6tXQLaJ8FZiTA/auCD2q9IBWozILYdZF0KoHBXb2tTT8fDQiNanjjSpyCxr83W9ZsC0uTY+bQE3Ke1BFtwD14dkVpMNQOk63JL1RgbV13RYYxkqEO0S5AfQPasiOzAZrXxzIkqfR8LwixlaBfYEYT2aar/ld0SC2HplmzqzchKHfQpkLfD0u15eUgOl4z4DeiwY/LCSxmXIf8FusXXnP+1DReg5YCGz2beuJooMwbOGYjpDpuPuBlSrcl2m2fjncYV3KS2bJ3heSSqRcW4QUBgv9DdZfCwEzHffPwKfjAjLhLJRw3DaBltEkr3G8jYp+H5gdZFnRv9F6NZH2bso0J98oJqoJxz0gsFyRppF1IG5/UQok0t69ovoMsNu3rfsvVcqumwXje8AqlFcC1Uf7H2z4U5zTkf9n/vTErIELAy+D1BplFTf2Nl0d9kFFfbEE5rR3Xvl+dsbrCvUGZZ/vted3hZYTjrdK0N8DZxR5NGMnHy/KY55FCcdbL2j7WI9SLIEo46jqw5mWhsdC/2bK+xwS7BMkm1X9Qn9Lw5sTAX9JUbdT0HmixvasBq8FlVVHzqyr9yeUhUzHC1Pk9b6dvHow8mnvelRfEEgi+jW/ueHXpQAf2sjVltb/tqdvgfEySqvfkjw50ldhBQ5ouXnMe0+U5/ps6xuD0XeOt4OsV3gkY1s/LhX4Qds73A9Rxr8QeUNEn1aoRfkscLcKbZlma+OYCHy41V1ulHEgyjy1jrc0QDtBXvPt5C2lBB/ZMh33Z8ADw3ugMEsZQn1fs5UcE4EonytlizP2/MNR9Et9dIaDqkl7m1T1J/8eYOa7m6zTQ6q7YeKo8m3rY2MlkBLBLq8om33qm/N7wt4cOOjb1mcmI/q5BHEPor+KimBN2v2RKo+Iysa+lmTb2AjkCkwkp5k6/oML5Zo+27Sgd7IIRMc2LIiGESwPe65CqbXgJTZT3k5EmyIFJgv0cLtmyhtSAMK7sA70dd9uuDmf7xgC7maE7dEd+J8QyF3iQV8i+/3m5O3jrgOJtq4viWG8OJmX9mIRaz36CcrKHxLITSB0t283XGxbxqdAmJfLeQfY5dvWuslQYO72k1Xnqt5/CA2+CzId9ALIId+2wvwf+8W3Eo7bA1T4tmXGWhvDgrrUkeqAikbEuF/hk8CbKnJQVJtGa9fHp4Dj/gMYnMmI6tp879gx4A6r7Vwp18YAWTPYjsBJgXTV+dNPnKus2wuyZGDaFQvjeqDIZ14FEk7YWLFUIWwX7hKkPJALKwpNFQoRCXsoUdaANjLUInSKIXsGtGLPO/ZVmZqUt1pFnxKRx/qakw8XG5RRCSRS7mABi/Jv7sGyY+R7IM5JTXvXx4MBY6UIYdtxF1AO+iJq7PFbks9G+4e9B67FYEncK26433wETolQN7wfMR33JSAcMBV8hNc4b9+uol9G9VZgSc7ZKcIBQJZfhK+1kcSjFxno477dEE46iv5GJWA67pHQgoGs6bWThyJrpuN1g14VXbLa9u6PZIPsUgkGbhQxblDkNtArh9ZLN8JvA9U/XlE9fX/P6tnvjYYqehOHE44+27qzaOS5hXkUOL5FRIZaZeUVhDOonkWkH9gAVAJngekjHB5V0b2GUbGvr2newUJgctPnaCrxkm9bq8YKfjBM+TaZjnu3CMtVWQwsC1PppbVyLhfpEwodUPbsQFnl0bNNc+J7pJFzoZjxTByp2DowaGDrgfLaurmLVINz06undXevnXf+Yms95GEckzn+hgZPFzM+LESiOAJ5LAw9cIL1IPcAM3JHrgfhLdDDiswSdDHIoksm9C8Ce3RAnvI3WWfiIhz3f0IEIuOJ9rdnGEFwp6p+BeQaoA50JoRHjT6gV5VODXh+tCwUB3LSFJiI41LtLYkCpQIzHjtTBMYTtVLumVKglNEcj63/AIrz7E/FBbRAAAAAAElFTkSuQmCC
`
export default logo

+ 15
- 0
modules/icons/refresh.js View File

@@ -0,0 +1,15 @@
/**
* @Author: Caven
* @Date: 2020-06-06 14:18:00
*/

const refresh = `
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="50px" height="50px" viewBox="0 0 50 50" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
<!-- Generator: Sketch 3.4.3 (16044) - http://www.bohemiancoding.com/sketch -->
<title>refresh</title>
<path d="M48.2758621,0 C47.2844828,0 46.5086207,0.775193846 46.5086207,1.76571923 L46.5086207,12.2308355 C42.0689655,4.78036173 34.0086207,0 25,0 C11.2068965,0 0,11.1972438 0,25.0215332 C0,38.8458226 11.2068965,50 25,50 C38.7931035,50 50,38.8027562 50,25.0215332 C50,24.0310078 49.2241379,23.2558139 48.2327587,23.2558139 C47.2413793,23.2558139 46.4655172,24.0310078 46.4655172,25.0215332 C46.4655172,36.8647717 36.8103448,46.5116279 24.9568965,46.5116279 C13.1034483,46.5116279 3.49137933,36.8217054 3.49137933,24.9784668 C3.49137933,13.1352283 13.1465517,3.48837212 25,3.48837212 C33.4913793,3.48837212 41.0775862,8.44099913 44.5258621,16.0206718 L32.1551724,16.0206718 C31.1637931,16.0206718 30.3879311,16.7958657 30.3879311,17.7863911 C30.3879311,18.7769164 31.1637931,19.5521103 32.1551724,19.5521103 L48.2327587,19.5521103 C49.2241379,19.5521103 50,18.7769164 50,17.7863911 L50,1.72265288 C50,0.775193846 49.2241379,0 48.2758621,0 L48.2758621,0 L48.2758621,0 Z" id="Shape"></path>
</svg>
`

export default refresh

+ 13
- 0
modules/icons/splitter.js View File

@@ -0,0 +1,13 @@
/**
* @Author: Caven
* @Date: 2020-06-06 14:18:00
*/

const splitter = `
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="19px" height="28px" viewBox="0 0 19 28" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<path d="M0.6551724,2.3448276 L0.6551724,25.6551724 C0.6551724,26.6454761 1.4579722,27.4482759 2.4482759,27.4482759 C3.4385796,27.4482759 4.2413793,26.6454761 4.2413793,25.6551724 L4.2413793,2.3448276 C4.2413793,1.3545239 3.4385796,0.5517241 2.4482759,0.5517241 C1.4579722,0.5517241 0.6551724,1.3545239 0.6551724,2.3448276 L0.6551724,2.3448276 Z M7.6551724,2.3448276 L7.6551724,25.6551724 C7.6551724,26.6454761 8.4579722,27.4482759 9.4482759,27.4482759 C10.4385796,27.4482759 11.2413793,26.6454761 11.2413793,25.6551724 L11.2413793,2.3448276 C11.2413793,1.3545239 10.4385796,0.5517241 9.4482759,0.5517241 C8.4579722,0.5517241 7.6551724,1.3545239 7.6551724,2.3448276 L7.6551724,2.3448276 Z M14.6551724,2.3448276 L14.6551724,25.6551724 C14.6551724,26.6454761 15.4579722,27.4482759 16.4482759,27.4482759 C17.4385796,27.4482759 18.2413793,26.6454761 18.2413793,25.6551724 L18.2413793,2.3448276 C18.2413793,1.3545239 17.4385796,0.5517241 16.4482759,0.5517241 C15.4579722,0.5517241 14.6551724,1.3545239 14.6551724,2.3448276 L14.6551724,2.3448276 Z" id="splitter"></path>
</svg>
`

export default splitter

+ 163
- 0
modules/imagery/ImageryLayerFactory.js View File

@@ -0,0 +1,163 @@
/**
* @Author: Caven
* @Date: 2020-01-21 15:54:56
*/

import { Cesium } from '@dc-modules/namespace'
import ImageryType from './ImageryType'
import AmapImageryProvider from './provider/AmapImageryProvider'
import BaiduImageryProvider from './provider/BaiduImageryProvider'
import GoogleImageryProvider from './provider/GoogleImageryProvider'
import TdtImageryProvider from './provider/TdtImageryProvider'
import TencentImageryProvider from './provider/TencentImageryProvider'

class ImageryLayerFactory {
/**
* Create amap image layer
* @param options
* @returns {AmapImageryProvider}
*/
static createAmapImageryLayer(options) {
return new AmapImageryProvider(options)
}

/**
* Create baidu image layer
* @param options
* @returns {BaiduImageryProvider}
*/
static createBaiduImageryLayer(options) {
return new BaiduImageryProvider(options)
}

/**
* Create google image layer
* @param options
* @returns {GoogleImageryProvider}
*/
static createGoogleImageryLayer(options) {
return new GoogleImageryProvider(options)
}

/**
* Create tdt image layer
* @param options
* @returns {TdtImageryProvider}
*/
static createTdtImageryLayer(options) {
return new TdtImageryProvider(options)
}

/**
* Create tencent image layer
* @param options
* @returns {TencentImageryProvider}
*/
static createTencentImageryLayer(options) {
return new TencentImageryProvider(options)
}

/**
* Create arcgis image layer
* @param options
* @returns {module:cesium.ArcGisMapServerImageryProvider}
*/
static createArcGisImageryLayer(options) {
return new Cesium.ArcGisMapServerImageryProvider(options)
}

/**
* Create single tile image layer
* @param options
* @returns {module:cesium.SingleTileImageryProvider}
*/
static createSingleTileImageryLayer(options) {
return new Cesium.SingleTileImageryProvider(options)
}

/**
* Create WMS image layer
* @param options
* @returns {module:cesium.WebMapServiceImageryProvider}
*/
static createWMSImageryLayer(options) {
return new Cesium.WebMapServiceImageryProvider(options)
}

/**
* Create WMTS image layer
* @param options
* @returns {module:cesium.WebMapTileServiceImageryProvider}
*/
static createWMTSImageryLayer(options) {
return new Cesium.WebMapTileServiceImageryProvider(options)
}

/**
* Create xyz image layer
* @param options
* @returns {module:cesium.UrlTemplateImageryProvider}
*/
static createXYZImageryLayer(options) {
return new Cesium.UrlTemplateImageryProvider(options)
}

/**
* Create coord image layer
* @param options
* @returns {module:cesium.TileCoordinatesImageryProvider}
*/
static createCoordImageryLayer(options) {
return new Cesium.TileCoordinatesImageryProvider(options)
}

/**
* Create Imagery Layer
* @param type
* @param options
* @returns {any}
*/
static createImageryLayer(type, options) {
let imageryLayer = undefined
switch (type) {
case ImageryType.AMAP:
imageryLayer = this.createAmapImageryLayer(options)
break
case ImageryType.BAIDU:
imageryLayer = this.createBaiduImageryLayer(options)
break
case ImageryType.GOOGLE:
imageryLayer = this.createGoogleImageryLayer(options)
break
case ImageryType.TDT:
imageryLayer = this.createTdtImageryLayer(options)
break
case ImageryType.TENCENT:
imageryLayer = this.createTencentImageryLayer(options)
break
case ImageryType.ARCGIS:
imageryLayer = this.createArcGisImageryLayer(options)
break
case ImageryType.SINGLE_TILE:
imageryLayer = this.createSingleTileImageryLayer(options)
break
case ImageryType.WMS:
imageryLayer = this.createWMSImageryLayer(options)
break
case ImageryType.WMTS:
imageryLayer = this.createWMTSImageryLayer(options)
break
case ImageryType.XYZ:
imageryLayer = this.createXYZImageryLayer(options)
break
case ImageryType.COORD:
imageryLayer = this.createCoordImageryLayer(options)
break
default:
break
}
return imageryLayer
}
}

export default ImageryLayerFactory

+ 15
- 0
modules/imagery/ImageryType.js View File

@@ -0,0 +1,15 @@
/**
* @Author: Caven
* @Date: 2020-05-10 08:15:36
*/

let ImageryType = {
ARCGIS: 'arcgis',
SINGLE_TILE: 'single_tile',
WMS: 'wms',
WMTS: 'wmts',
XYZ: 'xyz',
COORD: 'coord'
}

export default ImageryType

+ 7
- 0
modules/imagery/index.js View File

@@ -0,0 +1,7 @@
/**
* @Author: Caven
* @Date: 2021-03-14 00:31:46
*/

export { default as ImageryType } from './ImageryType'
export { default as ImageryLayerFactory } from './ImageryLayerFactory'

+ 498
- 0
modules/imagery/projection/BaiduMercatorProjection.js View File

@@ -0,0 +1,498 @@
/**
* @Author: Caven
* @Date: 2021-01-30 22:41:41
*/

const EARTH_RADIUS = 6370996.81
const MC_BAND = [12890594.86, 8362377.87, 5591021, 3481989.83, 1678043.12, 0]
const LL_BAND = [75, 60, 45, 30, 15, 0]
const MC2LL = [
[
1.410526172116255e-8,
8.98305509648872e-6,
-1.9939833816331,
2.009824383106796e2,
-1.872403703815547e2,
91.6087516669843,
-23.38765649603339,
2.57121317296198,
-0.03801003308653,
1.73379812e7
],
[
-7.435856389565537e-9,
8.983055097726239e-6,
-0.78625201886289,
96.32687599759846,
-1.85204757529826,
-59.36935905485877,
47.40033549296737,
-16.50741931063887,
2.28786674699375,
1.026014486e7
],
[
-3.030883460898826e-8,
8.98305509983578e-6,
0.30071316287616,
59.74293618442277,
7.357984074871,
-25.38371002664745,
13.45380521110908,
-3.29883767235584,
0.32710905363475,
6.85681737e6
],
[
-1.981981304930552e-8,
8.983055099779535e-6,
0.03278182852591,
40.31678527705744,
0.65659298677277,
-4.44255534477492,
0.85341911805263,
0.12923347998204,
-0.04625736007561,
4.48277706e6
],
[
3.09191371068437e-9,
8.983055096812155e-6,
0.00006995724062,
23.10934304144901,
-0.00023663490511,
-0.6321817810242,
-0.00663494467273,
0.03430082397953,
-0.00466043876332,
2.5551644e6
],
[
2.890871144776878e-9,
8.983055095805407e-6,
-0.00000003068298,
7.47137025468032,
-0.00000353937994,
-0.02145144861037,
-0.00001234426596,
0.00010322952773,
-0.00000323890364,
8.260885e5
]
]
const LL2MC = [
[
-0.0015702102444,
1.113207020616939e5,
1.704480524535203e15,
-1.033898737604234e16,
2.611266785660388e16,
-3.51496691766537e16,
2.659570071840392e16,
-1.072501245418824e16,
1.800819912950474e15,
82.5
],
[
8.277824516172526e-4,
1.113207020463578e5,
6.477955746671608e8,
-4.082003173641316e9,
1.077490566351142e10,
-1.517187553151559e10,
1.205306533862167e10,
-5.124939663577472e9,
9.133119359512032e8,
67.5
],
[
0.00337398766765,
1.113207020202162e5,
4.481351045890365e6,
-2.339375119931662e7,
7.968221547186455e7,
-1.159649932797253e8,
9.723671115602145e7,
-4.366194633752821e7,
8.477230501135234e6,
52.5
],
[
0.00220636496208,
1.113207020209128e5,
5.175186112841131e4,
3.796837749470245e6,
9.920137397791013e5,
-1.22195221711287e6,
1.340652697009075e6,
-6.209436990984312e5,
1.444169293806241e5,
37.5
],
[
-3.441963504368392e-4,
1.113207020576856e5,
2.782353980772752e2,
2.485758690035394e6,
6.070750963243378e3,
5.482118345352118e4,
9.540606633304236e3,
-2.71055326746645e3,
1.405483844121726e3,
22.5
],
[
-3.218135878613132e-4,
1.113207020701615e5,
0.00369383431289,
8.237256402795718e5,
0.46104986909093,
2.351343141331292e3,
1.58060784298199,
8.77738589078284,
0.37238884252424,
7.45
]
]

class BaiduMercatorProjection {
constructor() {
this.isWgs84 = false
}

/**
*
* @param point1
* @param point2
* @returns {number}
*/
getDistanceByMC(point1, point2) {
if (!point1 || !point2) {
return 0
}
point1 = this.convertMC2LL(point1)
if (!point1) {
return 0
}
let x1 = this.toRadians(point1['lng'])
let y1 = this.toRadians(point1['lat'])
point2 = this.convertMC2LL(point2)
if (!point2) {
return 0
}
let x2 = this.toRadians(point2['lng'])
let y2 = this.toRadians(point2['lat'])
return this.getDistance(x1, x2, y1, y2)
}

/**
* Calculate the distance between two points according to the latitude and longitude coordinates
* @param point1
* @param point2
* @returns {number|*}
*/
getDistanceByLL(point1, point2) {
if (!point1 || !point2) {
return 0
}
point1['lng'] = this.getLoop(point1['lng'], -180, 180)
point1['lat'] = this.getRange(point1['lat'], -74, 74)
point2['lng'] = this.getLoop(point2['lng'], -180, 180)
point2['lat'] = this.getRange(point2['lat'], -74, 74)
let x1 = this.toRadians(point1['lng'])
let y1 = this.toRadians(point1['lat'])
let x2 = this.toRadians(point2['lng'])
let y2 = this.toRadians(point2['lat'])
return this.getDistance(x1, x2, y1, y2)
}

/**
* The plane cartesian coordinates are converted to latitude and longitude coordinates
* @param point
* @returns {Point|{lng: number, lat: number}}
*/
convertMC2LL(point) {
if (!point) {
return { lng: 0, lat: 0 }
}
let lnglat = {}
if (this.isWgs84) {
lnglat.lng = (point.lng / 20037508.34) * 180
let mmy = (point.lat / 20037508.34) * 180
lnglat.lat =
(180 / Math.PI) *
(2 * Math.atan(Math.exp((mmy * Math.PI) / 180)) - Math.PI / 2)
return {
lng: lnglat['lng'].toFixed(6),
lat: lnglat['lat'].toFixed(6)
}
}

let temp = {
lng: Math.abs(point['lng']),
lat: Math.abs(point['lat'])
}

let factor = undefined
for (let i = 0; i < MC_BAND.length; i++) {
if (temp['lat'] >= MC_BAND[i]) {
factor = MC2LL[i]
break
}
}
lnglat = this.convertor(point, factor)
return {
lng: lnglat['lng'].toFixed(6),
lat: lnglat['lat'].toFixed(6)
}
}

/**
* The latitude and longitude coordinates are converted to plane cartesian coordinates
* @param point
* @returns {{lng: number, lat: number}|*}
*/
convertLL2MC(point) {
if (!point) {
return { lng: 0, lat: 0 }
}
if (
point['lng'] > 180 ||
point['lng'] < -180 ||
point['lat'] > 90 ||
point['lat'] < -90
) {
return point
}

if (this.isWgs84) {
let mercator = {}
let earthRad = 6378137.0
mercator.lng = ((point.lng * Math.PI) / 180) * earthRad
let a = (point.lat * Math.PI) / 180
mercator.lat =
(earthRad / 2) * Math.log((1.0 + Math.sin(a)) / (1.0 - Math.sin(a)))

return {
lng: parseFloat(mercator['lng'].toFixed(2)),
lat: parseFloat(mercator['lat'].toFixed(2))
}
}

point['lng'] = this.getLoop(point['lng'], -180, 180)
point['lat'] = this.getRange(point['lat'], -74, 74)
let temp = { lng: point['lng'], lat: point['lat'] }
let factor = undefined
for (let i = 0; i < LL_BAND.length; i++) {
if (temp['lat'] >= LL_BAND[i]) {
factor = LL2MC[i]
break
}
}
if (!factor) {
for (let i = 0; i < LL_BAND.length; i++) {
if (temp['lat'] <= -LL_BAND[i]) {
factor = LL2MC[i]
break
}
}
}
let mc = this.convertor(point, factor)
return {
lng: parseFloat(mc['lng'].toFixed(2)),
lat: parseFloat(mc['lat'].toFixed(2))
}
}

/**
*
* @param fromPoint
* @param factor
* @returns {{lng: *, lat: *}}
*/
convertor(fromPoint, factor) {
if (!fromPoint || !factor) {
return { lng: 0, lat: 0 }
}
let x = factor[0] + factor[1] * Math.abs(fromPoint['lng'])
let temp = Math.abs(fromPoint['lat']) / factor[9]
let y =
factor[2] +
factor[3] * temp +
factor[4] * temp * temp +
factor[5] * temp * temp * temp +
factor[6] * temp * temp * temp * temp +
factor[7] * temp * temp * temp * temp * temp +
factor[8] * temp * temp * temp * temp * temp * temp
x *= fromPoint['lng'] < 0 ? -1 : 1
y *= fromPoint['lat'] < 0 ? -1 : 1
return {
lng: x,
lat: y
}
}

/**
*
* @param x1
* @param x2
* @param y1
* @param y2
* @returns {number}
*/
getDistance(x1, x2, y1, y2) {
return (
EARTH_RADIUS *
Math.acos(
Math.sin(y1) * Math.sin(y2) +
Math.cos(y1) * Math.cos(y2) * Math.cos(x2 - x1)
)
)
}

/**
*
* @param deg
* @returns {number}
*/
toRadians(deg) {
return (Math.PI * deg) / 180
}

/**
*
* @param rad
* @returns {number}
*/
toDegrees(rad) {
return (180 * rad) / Math.PI
}

/**
*
* @param v
* @param a
* @param b
* @returns {number}
*/
getRange(v, a, b) {
if (a != null) {
v = Math.max(v, a)
}
if (b != null) {
v = Math.min(v, b)
}
return v
}

/**
*
* @param v
* @param a
* @param b
* @returns {*}
*/
getLoop(v, a, b) {
while (v > b) {
v -= b - a
}
while (v < a) {
v += b - a
}
return v
}

/**
*
* @param point
* @returns {{lng: number, lat: number}|*}
*/
lngLatToMercator(point) {
return this.convertLL2MC(point)
}

/**
*
* @param point
* @returns {{x: (number|*), y: (number|*)}}
*/
lngLatToPoint(point) {
let mercator = this.convertLL2MC(point)
return {
x: mercator['lng'],
y: mercator['lat']
}
}

/**
* WebMercator transforms to latitude and longitude
* @param point
* @returns {Point|{lng: number, lat: number}}
*/
mercatorToLngLat(point) {
return this.convertMC2LL(point)
}

/**
*
* @param point
* @returns {Point|{lng: number, lat: number}}
*/
pointToLngLat(point) {
let mercator = { lng: point.x, lat: point.y }
return this.convertMC2LL(mercator)
}

/**
* Latitude and longitude coordinates transforms to pixel coordinates
* @param point
* @param zoom
* @param mapCenter
* @param mapSize
* @returns {{x: number, y: number}}
*/
pointToPixel(point, zoom, mapCenter, mapSize) {
if (!point) {
return { x: 0, y: 0 }
}
point = this.lngLatToMercator(point)
let zoomUnits = this.getZoomUnits(zoom)
let x = Math.round(
(point['lng'] - mapCenter['lng']) / zoomUnits + mapSize.width / 2
)
let y = Math.round(
(mapCenter['lat'] - point['lat']) / zoomUnits + mapSize.height / 2
)
return { x, y }
}

/**
* Pixel coordinates transforms to latitude and longitude coordinates
* @param pixel
* @param zoom
* @param mapCenter
* @param mapSize
* @returns {Point|{lng: number, lat: number}}
*/
pixelToPoint(pixel, zoom, mapCenter, mapSize) {
if (!pixel) {
return { lng: 0, lat: 0 }
}
let zoomUnits = this.getZoomUnits(zoom)
let lng = mapCenter['lng'] + zoomUnits * (pixel.x - mapSize.width / 2)
let lat = mapCenter['lat'] - zoomUnits * (pixel.y - mapSize.height / 2)
let point = { lng, lat }
return this.mercatorToLngLat(point)
}

/**
*
* @param zoom
* @returns {number}
*/
getZoomUnits(zoom) {
return Math.pow(2, 18 - zoom)
}
}

export default BaiduMercatorProjection

+ 37
- 0
modules/imagery/provider/AmapImageryProvider.js View File

@@ -0,0 +1,37 @@
/**
* @Author: Caven
* @Date: 2020-01-15 20:31:28
*/

import { Cesium } from '@dc-modules/namespace'
import ImageryType from '../ImageryType'
import AmapMercatorTilingScheme from '../tiling-scheme/AmapMercatorTilingScheme'

const IMG_URL =
'https://webst{s}.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}'

const ELEC_URL =
'http://webrd{s}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}'

const LOAD_MARK_URL =
'https://webst{s}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}'

class AmapImageryProvider extends Cesium.UrlTemplateImageryProvider {
constructor(options = {}) {
options['url'] =
options.style === 'img'
? IMG_URL
: options.style === 'load'
? LOAD_MARK_URL
: ELEC_URL
options['subdomains'] = options.subdomains || ['01', '02', '03', '04']
if (options.crs === 'WGS84') {
options['tilingScheme'] = new AmapMercatorTilingScheme()
}
super(options)
}
}

ImageryType.AMAP = 'amap'

export default AmapImageryProvider

+ 176
- 0
modules/imagery/provider/BaiduImageryProvider.js View File

@@ -0,0 +1,176 @@
/**
* @Author: Caven
* @Date: 2020-01-15 20:27:27
*/

import { Cesium } from '@dc-modules/namespace'
import ImageryType from '../ImageryType'
import BaiduMercatorTilingScheme from '../tiling-scheme/BaiduMercatorTilingScheme'

const IMG_URL =
'http://shangetu{s}.map.bdimg.com/it/u=x={x};y={y};z={z};v=009;type=sate&fm=46'

const VEC_URL =
'http://online{s}.map.bdimg.com/tile/?qt=tile&x={x}&y={y}&z={z}&styles=sl&v=020'

const CUSTOM_URL =
'http://api{s}.map.bdimg.com/customimage/tile?&x={x}&y={y}&z={z}&scale=1&customid={style}'

const TRAFFIC_URL =
'http://its.map.baidu.com:8002/traffic/TrafficTileService?time={time}&label={labelStyle}&v=016&level={z}&x={x}&y={y}&scaler=2'

class BaiduImageryProvider {
constructor(options = {}) {
this._url =
options.style === 'img'
? IMG_URL
: options.style === 'vec'
? VEC_URL
: options.style === 'traffic'
? TRAFFIC_URL
: CUSTOM_URL
this._labelStyle = options.labelStyle || 'web2D'
this._tileWidth = 256
this._tileHeight = 256
this._maximumLevel = 18
this._crs = options.crs || 'BD09'
if (options.crs === 'WGS84') {
let resolutions = []
for (let i = 0; i < 19; i++) {
resolutions[i] = 256 * Math.pow(2, 18 - i)
}
this._tilingScheme = new BaiduMercatorTilingScheme({
resolutions,
rectangleSouthwestInMeters: new Cesium.Cartesian2(
-20037726.37,
-12474104.17
),
rectangleNortheastInMeters: new Cesium.Cartesian2(
20037726.37,
12474104.17
)
})
} else {
this._tilingScheme = new Cesium.WebMercatorTilingScheme({
rectangleSouthwestInMeters: new Cesium.Cartesian2(-33554054, -33746824),
rectangleNortheastInMeters: new Cesium.Cartesian2(33554054, 33746824)
})
}
this._rectangle = this._tilingScheme.rectangle
this._credit = undefined
this._token = undefined
this._style = options.style || 'normal'
}

get url() {
return this._url
}

get token() {
return this._token
}

get tileWidth() {
if (!this.ready) {
throw new Cesium.DeveloperError(
'tileWidth must not be called before the imagery provider is ready.'
)
}
return this._tileWidth
}

get tileHeight() {
if (!this.ready) {
throw new Cesium.DeveloperError(
'tileHeight must not be called before the imagery provider is ready.'
)
}
return this._tileHeight
}

get maximumLevel() {
if (!this.ready) {
throw new Cesium.DeveloperError(
'maximumLevel must not be called before the imagery provider is ready.'
)
}
return this._maximumLevel
}

get minimumLevel() {
if (!this.ready) {
throw new Cesium.DeveloperError(
'minimumLevel must not be called before the imagery provider is ready.'
)
}
return 0
}

get tilingScheme() {
if (!this.ready) {
throw new Cesium.DeveloperError(
'tilingScheme must not be called before the imagery provider is ready.'
)
}
return this._tilingScheme
}

get rectangle() {
if (!this.ready) {
throw new Cesium.DeveloperError(
'rectangle must not be called before the imagery provider is ready.'
)
}
return this._rectangle
}

get ready() {
return !!this._url
}

get credit() {
return this._credit
}

get hasAlphaChannel() {
return true
}

getTileCredits(x, y, level) {}

/**
* Request Image
* @param x
* @param y
* @param level
* @returns {Promise<HTMLImageElement | HTMLCanvasElement>}
*/
requestImage(x, y, level) {
if (!this.ready) {
throw new Cesium.DeveloperError(
'requestImage must not be called before the imagery provider is ready.'
)
}
let xTiles = this._tilingScheme.getNumberOfXTilesAtLevel(level)
let yTiles = this._tilingScheme.getNumberOfYTilesAtLevel(level)
let url = this._url
.replace('{z}', level)
.replace('{s}', String(1))
.replace('{style}', this._style)
.replace('{labelStyle}', this._labelStyle)
.replace('{time}', String(new Date().getTime()))

if (this._crs === 'WGS84') {
url = url.replace('{x}', String(x)).replace('{y}', String(-y))
} else {
url = url
.replace('{x}', String(x - xTiles / 2))
.replace('{y}', String(yTiles / 2 - y - 1))
}
return Cesium.ImageryProvider.loadImage(this, url)
}
}

ImageryType.BAIDU = 'baidu'

export default BaiduImageryProvider

+ 33
- 0
modules/imagery/provider/GoogleImageryProvider.js View File

@@ -0,0 +1,33 @@
/**
* @Author: Caven
* @Date: 2020-01-21 16:06:14
*/

import { Cesium } from '@dc-modules/namespace'
import ImageryType from '../ImageryType'

const ELEC_URL =
'http://mt{s}.google.cn/vt/lyrs=m@207000000&hl=zh-CN&gl=CN&src=app&x={x}&y={y}&z={z}&s=Galile'

const IMG_URL =
'http://mt{s}.google.cn/vt/lyrs=s&hl=zh-CN&x={x}&y={y}&z={z}&s=Gali'

const TER_URL =
'http://mt{s}.google.cn/vt/lyrs=t@131,r@227000000&hl=zh-CN&gl=cn&x={x}&y={y}&z={z}&s=Galile'

class GoogleImageryProvider extends Cesium.UrlTemplateImageryProvider {
constructor(options = {}) {
options['url'] =
options.style === 'img'
? IMG_URL
: options.style === 'ter'
? TER_URL
: ELEC_URL
options['subdomains'] = options.subdomains || ['1', '2', '3']
super(options)
}
}

ImageryType.GOOGLE = 'google'

export default GoogleImageryProvider

+ 28
- 0
modules/imagery/provider/TdtImageryProvider.js View File

@@ -0,0 +1,28 @@
/**
* @Author: Caven
* @Date: 2020-01-15 20:31:46
*/

import { Cesium } from '@dc-modules/namespace'
import ImageryType from '../ImageryType'

const MAP_URL =
'https://t{s}.tianditu.gov.cn/DataServer?T={style}_w&x={x}&y={y}&l={z}&tk={key}'

class TdtImageryProvider extends Cesium.UrlTemplateImageryProvider {
constructor(options = {}) {
super({
url: MAP_URL.replace(/\{style\}/g, options.style || 'vec').replace(
/\{key\}/g,
options.key || ''
),
subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'],
tilingScheme: new Cesium.WebMercatorTilingScheme(),
maximumLevel: 18
})
}
}

ImageryType.TDT = 'tdt'

export default TdtImageryProvider

+ 36
- 0
modules/imagery/provider/TencentImageryProvider.js View File

@@ -0,0 +1,36 @@
/**
* @Author: Caven
* @Date: 2020-01-21 18:10:47
*/

import { Cesium } from '@dc-modules/namespace'
import ImageryType from '../ImageryType'

const IMG_URL =
'https://p{s}.map.gtimg.com/sateTiles/{z}/{sx}/{sy}/{x}_{reverseY}.jpg?version=400'

const ELEC_URL =
'https://rt{s}.map.gtimg.com/tile?z={z}&x={x}&y={reverseY}&styleid={style}&scene=0&version=347'

class TencentImageryProvider extends Cesium.UrlTemplateImageryProvider {
constructor(options = {}) {
let url = options.style === 'img' ? IMG_URL : ELEC_URL
options['url'] = url.replace('{style}', options.style || 1)
options['subdomains'] = options.subdomains || ['1', '2', '3']
if (options.style === 'img') {
options['customTags'] = {
sx: (imageryProvider, x, y, level) => {
return x >> 4
},
sy: (imageryProvider, x, y, level) => {
return ((1 << level) - y) >> 4
}
}
}
super(options)
}
}

ImageryType.TENCENT = 'tencent'

export default TencentImageryProvider

+ 40
- 0
modules/imagery/tiling-scheme/AmapMercatorTilingScheme.js View File

@@ -0,0 +1,40 @@
/**
* @Author: Caven
* @Date: 2021-01-31 22:07:05
*/

import { Cesium } from '@dc-modules/namespace'
import { CoordTransform } from '@dc-modules/transform'

class AmapMercatorTilingScheme extends Cesium.WebMercatorTilingScheme {
constructor(options) {
super(options)
let projection = new Cesium.WebMercatorProjection()
this._projection.project = function(cartographic, result) {
result = CoordTransform.WGS84ToGCJ02(
Cesium.Math.toDegrees(cartographic.longitude),
Cesium.Math.toDegrees(cartographic.latitude)
)
result = projection.project(
new Cesium.Cartographic(
Cesium.Math.toRadians(result[0]),
Cesium.Math.toRadians(result[1])
)
)
return new Cesium.Cartesian2(result.x, result.y)
}
this._projection.unproject = function(cartesian, result) {
let cartographic = projection.unproject(cartesian)
result = CoordTransform.GCJ02ToWGS84(
Cesium.Math.toDegrees(cartographic.longitude),
Cesium.Math.toDegrees(cartographic.latitude)
)
return new Cesium.Cartographic(
Cesium.Math.toRadians(result[0]),
Cesium.Math.toRadians(result[1])
)
}
}
}

export default AmapMercatorTilingScheme

+ 102
- 0
modules/imagery/tiling-scheme/BaiduMercatorTilingScheme.js View File

@@ -0,0 +1,102 @@
/**
* @Author: Caven
* @Date: 2021-01-31 19:22:04
*/

import { Cesium } from '@dc-modules/namespace'
import { CoordTransform } from '@dc-modules/transform'
import BaiduMercatorProjection from '../projection/BaiduMercatorProjection'

class BaiduMercatorTilingScheme extends Cesium.WebMercatorTilingScheme {
constructor(options) {
super(options)
let projection = new BaiduMercatorProjection()
this._projection.project = function(cartographic, result) {
result = result || {}
result = CoordTransform.WGS84ToGCJ02(
Cesium.Math.toDegrees(cartographic.longitude),
Cesium.Math.toDegrees(cartographic.latitude)
)
result = CoordTransform.GCJ02ToBD09(result[0], result[1])
result[0] = Math.min(result[0], 180)
result[0] = Math.max(result[0], -180)
result[1] = Math.min(result[1], 74.000022)
result[1] = Math.max(result[1], -71.988531)
result = projection.lngLatToPoint({
lng: result[0],
lat: result[1]
})
return new Cesium.Cartesian2(result.x, result.y)
}
this._projection.unproject = function(cartesian, result) {
result = result || {}
result = projection.mercatorToLngLat({
lng: cartesian.x,
lat: cartesian.y
})
result = CoordTransform.BD09ToGCJ02(result.lng, result.lat)
result = CoordTransform.GCJ02ToWGS84(result[0], result[1])
return new Cesium.Cartographic(
Cesium.Math.toRadians(result[0]),
Cesium.Math.toRadians(result[1])
)
}
this.resolutions = options.resolutions || []
}

/**
*
* @param x
* @param y
* @param level
* @param result
* @returns {module:cesium.Rectangle|*}
*/
tileXYToNativeRectangle(x, y, level, result) {
const tileWidth = this.resolutions[level]
const west = x * tileWidth
const east = (x + 1) * tileWidth
const north = ((y = -y) + 1) * tileWidth
const south = y * tileWidth

if (!Cesium.defined(result)) {
return new Cesium.Rectangle(west, south, east, north)
}

result.west = west
result.south = south
result.east = east
result.north = north
return result
}

/**
*
* @param position
* @param level
* @param result
* @returns {undefined|*}
*/
positionToTileXY(position, level, result) {
const rectangle = this._rectangle
if (!Cesium.Rectangle.contains(rectangle, position)) {
return undefined
}
const projection = this._projection
const webMercatorPosition = projection.project(position)
if (!Cesium.defined(webMercatorPosition)) {
return undefined
}
const tileWidth = this.resolutions[level]
const xTileCoordinate = Math.floor(webMercatorPosition.x / tileWidth)
const yTileCoordinate = -Math.floor(webMercatorPosition.y / tileWidth)
if (!Cesium.defined(result)) {
return new Cesium.Cartesian2(xTileCoordinate, yTileCoordinate)
}
result.x = xTileCoordinate
result.y = yTileCoordinate
return result
}
}

export default BaiduMercatorTilingScheme

BIN
modules/images/circle_blue.png View File


BIN
modules/images/circle_red.png View File


BIN
modules/images/circle_yellow.png View File


BIN
modules/images/cloud.jpg View File


BIN
modules/images/fence.png View File


BIN
modules/images/lighting.png View File


BIN
modules/images/space_line.png View File


+ 314
- 0
modules/layer/Layer.js View File

@@ -0,0 +1,314 @@
/**
* @Author: Caven
* @Date: 2020-01-03 09:38:21
*/

import { Cesium } from '@dc-modules/namespace'
import { Util } from '@dc-modules/utils'
import State from '@dc-modules/state/State'
import { LayerEventType, OverlayEventType, LayerEvent } from '@dc-modules/event'
import LayerType from './LayerType'

class Layer {
constructor(id) {
this._id = Util.uuid()
this._bid = id || Util.uuid()
this._delegate = undefined
this._viewer = undefined
this._state = undefined
this._show = true
this._cache = {}
this._attr = {}
this._layerEvent = new LayerEvent()
this._layerEvent.on(LayerEventType.ADD, this._onAdd, this)
this._layerEvent.on(LayerEventType.REMOVE, this._onRemove, this)
this._state = undefined
this.type = undefined
}

get layerId() {
return this._id
}

get id() {
return this._bid
}

get delegate() {
return this._delegate
}

set show(show) {
this._show = show
this._delegate && (this._delegate.show = this._show)
}

get show() {
return this._show
}

get layerEvent() {
return this._layerEvent
}

set attr(attr) {
this._attr = attr
}

get attr() {
return this._attr
}

get state() {
return this._state
}

/**
* The hook for added
* @private
*/
_addedHook() {}

/**
* The hook for removed
* @private
*/
_removedHook() {}

/**
* The layer added callback function
* Subclasses need to be overridden
* @param viewer
* @private
*/
_onAdd(viewer) {
this._viewer = viewer
if (!this._delegate) {
return
}
if (this._delegate instanceof Cesium.PrimitiveCollection) {
this._viewer.scene.primitives.add(this._delegate)
} else {
this._viewer.dataSources.add(this._delegate)
}
this._addedHook && this._addedHook()
this._state = State.ADDED
}

/**
* The layer added callback function
* Subclasses need to be overridden
* @private
*/
_onRemove() {
if (!this._delegate) {
return
}
if (this._viewer) {
this._cache = {}
if (this._delegate instanceof Cesium.PrimitiveCollection) {
this._delegate.removeAll()
this._viewer.scene.primitives.remove(this._delegate)
} else if (this._delegate.then) {
this._delegate.then(dataSource => {
dataSource.entities.removeAll()
})
this._viewer.dataSources.remove(this._delegate)
} else {
this._delegate.entities && this._delegate.entities.removeAll()
this._viewer.dataSources.remove(this._delegate)
}
this._removedHook && this._removedHook()
this._state = State.REMOVED
}
}

/**
* The layer add overlay
* @param overlay
* @private
*/
_addOverlay(overlay) {
if (
overlay &&
overlay.overlayEvent &&
!this._cache.hasOwnProperty(overlay.overlayId)
) {
overlay.overlayEvent.fire(OverlayEventType.ADD, this)
this._cache[overlay.overlayId] = overlay
if (this._state === State.CLEARED) {
this._state = State.ADDED
}
}
}

/**
* The layer remove overlay
* @param overlay
* @private
*/
_removeOverlay(overlay) {
if (
overlay &&
overlay.overlayEvent &&
this._cache.hasOwnProperty(overlay.overlayId)
) {
overlay.overlayEvent.fire(OverlayEventType.REMOVE, this)
delete this._cache[overlay.overlayId]
}
}

/**
* Add overlay
* @param overlay
* @returns {Layer}
*/
addOverlay(overlay) {
this._addOverlay(overlay)
return this
}

/**
* Add overlays
* @param overlays
* @returns {Layer}
*/
addOverlays(overlays) {
if (Array.isArray(overlays)) {
overlays.forEach(item => {
this._addOverlay(item)
})
}
return this
}

/**
* Remove overlay
* @param overlay
* @returns {Layer}
*/
removeOverlay(overlay) {
this._removeOverlay(overlay)
return this
}

/**
* Returns the overlay by overlayId
* @param overlayId
* @returns {*|undefined}
*/
getOverlay(overlayId) {
return this._cache[overlayId] || undefined
}

/**
* Returns the overlay by bid
* @param id
* @returns {any}
*/
getOverlayById(id) {
let overlay = undefined
Object.keys(this._cache).forEach(key => {
if (this._cache[key].id === id) {
overlay = this._cache[key]
}
})
return overlay
}

/**
* Returns the overlays by attrName and AttrVal
* @param attrName
* @param attrVal
* @returns {[]}
*/
getOverlaysByAttr(attrName, attrVal) {
let result = []
this.eachOverlay(item => {
if (item.attr[attrName] === attrVal) {
result.push(item)
}
}, this)
return result
}

/**
* Iterate through each overlay and pass it as an argument to the callback function
* @param method
* @param context
* @returns {Layer}
*/
eachOverlay(method, context) {
Object.keys(this._cache).forEach(key => {
method && method.call(context || this, this._cache[key])
})
return this
}

/**
* Returns all overlays
* @returns {[]}
*/
getOverlays() {
let result = []
Object.keys(this._cache).forEach(key => {
result.push(this._cache[key])
})
return result
}

/**
* Clears all overlays
* Subclasses need to be overridden
*/
clear() {}

/**
* Removes from the viewer
*/
remove() {
if (this._viewer) {
this._viewer.removeLayer(this)
}
}

/**
* Adds to the viewer
* @param viewer
* @returns {Layer}
*/
addTo(viewer) {
if (viewer && viewer.addLayer) {
viewer.addLayer(this)
}
return this
}

/**
* sets the style, the style will apply to every overlay of the layer
* Subclasses need to be overridden
* @param style
*/
setStyle(style) {}

/**
* Registers Type
* @param type
*/
static registerType(type) {
if (type) {
LayerType[type.toLocaleUpperCase()] = type.toLocaleLowerCase()
}
}

/**
* Returns type
* @param type
* @returns {*|undefined}
*/
static getLayerType(type) {
return LayerType[type.toLocaleUpperCase()] || undefined
}
}

export default Layer

+ 8
- 0
modules/layer/LayerType.js View File

@@ -0,0 +1,8 @@
/**
* @Author: Caven
* @Date: 2020-05-10 08:21:19
*/

let LayerType = {}

export default LayerType

+ 23
- 0
modules/layer/index.js View File

@@ -0,0 +1,23 @@
/**
* @Author: Caven
* @Date: 2021-03-13 13:46:19
*/

export { default as LayerType } from './LayerType'
export { default as Layer } from './Layer'

/**
* types
*/
export { default as ClusterLayer } from './type/ClusterLayer'
export { default as CzmlLayer } from './type/CzmlLayer'
export { default as GeoJsonLayer } from './type/GeoJsonLayer'
export { default as HeatLayer } from './type/HeatLayer'
export { default as HtmlLayer } from './type/HtmlLayer'
export { default as KmlLayer } from './type/KmlLayer'
export { default as LabelLayer } from './type/LabelLayer'
export { default as LayerGroup } from './type/LayerGroup'
export { default as PrimitiveLayer } from './type/PrimitiveLayer'
export { default as TilesetLayer } from './type/TilesetLayer'
export { default as TopoJsonLayer } from './type/TopoJsonLayer'
export { default as VectorLayer } from './type/VectorLayer'

+ 178
- 0
modules/layer/type/ClusterLayer.js View File

@@ -0,0 +1,178 @@
/**
* @Author: Caven
* @Date: 2020-02-10 10:05:41
*/

import { Cesium } from '@dc-modules/namespace'
import State from '@dc-modules/state/State'
import Layer from '../Layer'

const DEF_OPT = {
size: 18,
pixelRange: 40,
gradient: {
0.0001: Cesium.Color.DEEPSKYBLUE,
0.001: Cesium.Color.GREEN,
0.01: Cesium.Color.ORANGE,
0.1: Cesium.Color.RED
},
fontSize: 12,
fontColor: Cesium.Color.BLACK,
style: 'circle'
}

class ClusterLayer extends Layer {
constructor(id, options = {}) {
super(id)
this._delegate = new Cesium.CustomDataSource(id)
this._options = {
...DEF_OPT,
...options
}
this._delegate.clustering.enabled = true
this._delegate.clustering.clusterEvent.addEventListener(
this._clusterEventHandler,
this
)
this._delegate.clustering.pixelRange = this._options.pixelRange
this.type = Layer.getLayerType('cluster')
this._state = State.INITIALIZED
}

set enableCluster(enableCluster) {
this._delegate.clustering.enabled = enableCluster
return this
}

/**
*
* @param color
* @param numLength
* @returns {*}
* @private
*/
_drawCircle(color, numLength) {
let size = this._options.size * (numLength + 1)
let key = color.toCssColorString() + '-' + size
if (!this._cache[key]) {
let canvas = document.createElement('canvas')
canvas.width = size
canvas.height = size
let context2D = canvas.getContext('2d')
context2D.save()
context2D.scale(size / 24, size / 24) //Added to auto-generated code to scale up to desired size.
context2D.fillStyle = color.withAlpha(0.2).toCssColorString() //Modified from auto-generated code.
context2D.beginPath()
context2D.arc(12, 12, 9, 0, 2 * Math.PI)
context2D.closePath()
context2D.fill()
context2D.beginPath()
context2D.arc(12, 12, 6, 0, 2 * Math.PI)
context2D.fillStyle = color.toCssColorString()
context2D.fill()
context2D.closePath()
context2D.restore()
this._cache[key] = canvas.toDataURL()
}
return this._cache[key]
}

/**
*
* @param color
* @param numLength
* @returns {*}
* @private
*/
_drawClustering(color, numLength) {
let size = this._options.size * (numLength + 1)
let key = color.toCssColorString() + '-' + size
let startAngle = -Math.PI / 12
let angle = Math.PI / 2
let intervalAngle = Math.PI / 6
if (!this._cache[key]) {
let canvas = document.createElement('canvas')
canvas.width = size
canvas.height = size
let context2D = canvas.getContext('2d')
context2D.save()
context2D.scale(size / 24, size / 24) //Added to auto-generated code to scale up to desired size.
context2D.beginPath()
context2D.arc(12, 12, 6, 0, 2 * Math.PI)
context2D.fillStyle = color.toCssColorString()
context2D.fill()
context2D.closePath()
context2D.lineWidth = 2
for (let i = 0; i < 3; i++) {
context2D.beginPath()
context2D.arc(12, 12, 8, startAngle, startAngle + angle, false)
context2D.strokeStyle = color.withAlpha(0.4).toCssColorString()
context2D.stroke()
context2D.arc(12, 12, 11, startAngle, startAngle + angle, false)
context2D.strokeStyle = color.withAlpha(0.2).toCssColorString()
context2D.stroke()
context2D.closePath()
startAngle = startAngle + angle + intervalAngle
}
context2D.restore()
this._cache[key] = canvas.toDataURL()
}
return this._cache[key]
}

/**
*
* @param {*} clusteredEntities
* @param {*} cluster
*/
_clusterEventHandler(clusteredEntities, cluster) {
if (!this._delegate.clustering.enabled) {
return
}
cluster.billboard.show = true
cluster.label.font = `bold ${this._options.fontSize}px sans-serif`
cluster.label.fillColor = this._options.fontColor
cluster.label.disableDepthTestDistance = Number.POSITIVE_INFINITY
if (this._delegate.entities.values.length) {
let allCount = this._delegate.entities.values.length || 0
for (let key in this._options.gradient) {
if (clusteredEntities.length >= allCount * key) {
let numLength = String(clusteredEntities.length).length
if (this._options.style === 'circle') {
cluster.billboard.image = this._drawCircle(
this._options.gradient[key],
numLength
)
} else {
cluster.billboard.image = this._drawClustering(
this._options.gradient[key],
numLength
)
}
cluster.label.show = true
if (numLength === 1) {
cluster.label.pixelOffset = new Cesium.Cartesian2(-2, 3)
} else {
cluster.label.pixelOffset = new Cesium.Cartesian2(
-5 * (numLength - 1),
5
)
}
} else if (clusteredEntities.length <= 1) {
cluster.label.show = false
}
}
}
}

clear() {
this._delegate.entities.removeAll()
this._cache = {}
this._state = State.CLEARED
return this
}
}

Layer.registerType('cluster')

export default ClusterLayer

+ 51
- 0
modules/layer/type/CzmlLayer.js View File

@@ -0,0 +1,51 @@
/**
* @Author: Caven
* @Date: 2020-01-19 13:38:48
*/

import { Cesium } from '@dc-modules/namespace'
import State from '@dc-modules/state/State'
import Layer from '../Layer'

class CzmlLayer extends Layer {
constructor(id, url = '', options = {}) {
super(id)
this._delegate = Cesium.CzmlDataSource.load(url, options)
this.type = Layer.getLayerType('czml')
this._state = State.INITIALIZED
}

set show(show) {
this._show = show
this._delegate &&
this._delegate.then(dataSource => {
dataSource.show = this._show
})
}

get show() {
return this._show
}

/**
*
* @param method
* @param context
* @returns {CzmlLayer}
*/
eachOverlay(method, context) {
if (this._delegate) {
this._delegate.then(dataSource => {
let entities = dataSource.entities.values
entities.forEach(item => {
method.call(context, item)
})
})
return this
}
}
}

Layer.registerType('czml')

export default CzmlLayer

+ 130
- 0
modules/layer/type/GeoJsonLayer.js View File

@@ -0,0 +1,130 @@
/**
* @Author: Caven
* @Date: 2020-01-13 10:13:53
*/

import { Cesium } from '@dc-modules/namespace'
import State from '@dc-modules/state/State'
import { Billboard, Polyline, Polygon, Model } from '@dc-modules/overlay'
import Layer from '../Layer'
import VectorLayer from './VectorLayer'

class GeoJsonLayer extends Layer {
constructor(id, url, options = {}) {
if (!url) {
throw new Error('GeoJsonLayer:the url invalid')
}
super(id)
this._delegate = Cesium.GeoJsonDataSource.load(url, options)
this.type = Layer.getLayerType('geojson')
this._state = State.INITIALIZED
}

set show(show) {
this._show = show
this._delegate &&
this._delegate.then(dataSource => {
dataSource.show = this._show
})
}

get show() {
return this._show
}

_createBillboard(entity) {
if (entity.position && entity.billboard) {
return Billboard.fromEntity(entity)
}
}

/**
* Returns polyline Entity
* @param entity
* @returns {any}
* @private
*/
_createPolyline(entity) {
if (entity.polyline) {
return Polyline.fromEntity(entity)
}
}

/**
* Returns polygon Entity
* @param entity
* @returns {any}
* @private
*/
_createPolygon(entity) {
if (entity.polygon) {
return Polygon.fromEntity(entity)
}
}

/**
* Returns model Entity
* @param entity
* @param modelUrl
* @returns {Model}
* @private
*/
_createModel(entity, modelUrl) {
if (entity) {
return Model.fromEntity(entity, modelUrl)
}
}

/**
*
* @param method
* @param context
* @returns {GeoJsonLayer}
*/
eachOverlay(method, context) {
if (this._delegate) {
this._delegate.then(dataSource => {
let entities = dataSource.entities.values
entities.forEach(item => {
method.call(context, item)
})
})
return this
}
}

/**
* Converts to VectorLayer
* @returns {VectorLayer}
*/
toVectorLayer() {
let layer = new VectorLayer(this.id)
this.eachOverlay(item => {
if (item.billboard) {
layer.addOverlay(this._createBillboard(item))
} else if (item.polyline) {
layer.addOverlay(this._createPolyline(item))
} else if (item.polygon) {
layer.addOverlay(this._createPolygon(item))
}
}, this)
return layer
}

/**
* Converts to VectorLayer
* @param modelUrl
* @returns {VectorLayer}
*/
toModelLayer(modelUrl) {
let layer = new VectorLayer(this.id)
this.eachOverlay(item => {
layer.addOverlay(this._createModel(item, modelUrl))
}, this)
return layer
}
}

Layer.registerType('geojson')

export default GeoJsonLayer

+ 282
- 0
modules/layer/type/HeatLayer.js View File

@@ -0,0 +1,282 @@
/**
* @Author: Caven
* @Date: 2020-02-27 00:35:35
*/

import { Cesium } from '@dc-modules/namespace'
import State from '@dc-modules/state/State'
import { SceneEventType } from '@dc-modules/event'
import { Transform } from '@dc-modules/transform'
import Position from '@dc-modules/position/Position'
import { DomUtil, Util } from '@dc-modules/utils'
import Layer from '../Layer'

const h337 = require('heatmap.js/build/heatmap.min')

const DEF_OPTS = {
maxOpacity: 0.8, // the maximum opacity used if not given in the heatmap options object
minOpacity: 0.1, // the minimum opacity used if not given in the heatmap options object
blur: 0.85, // the blur used if not given in the heatmap options object
maxCanvasSize: 2000,
minCanvasSize: 700,
radius: 25,
gradient: {
'0.4': 'blue',
'0.6': 'green',
'0.8': 'yellow',
'0.9': 'red'
}
}

class HeatLayer extends Layer {
constructor(id, options) {
super(id)
this._options = {
...DEF_OPTS,
...options
}
this._heat = undefined
this._bounds = undefined
this._mBounds = undefined
this._scale = 1
this._positions = []
this._options.spacing = this._options.radius * 1.5
this._delegate = new Cesium.CustomDataSource(id)
this._entity = new Cesium.Entity()
this.type = Layer.getLayerType('heat')
this._state = State.INITIALIZED
}

get options() {
return this._options
}

/**
* The hook for added
*/
_addedHook() {
this._redraw()
this._viewer.on(SceneEventType.CAMERA_MOVE_END, this._reset, this)
}

/**
* The hook for removed
*/
_removedHook() {
this._viewer.off(SceneEventType.CAMERA_MOVE_END, this._reset, this)
}

/**
*
* @param {*} position
*/
_transformWGS84ToHeatmap(position) {
position = Transform.transformWGS84ToMercator(position)
let coord = {}
coord.x = Math.round(
(position.lng - this._mBounds.west) / this._scale + this._options.spacing
)
coord.y = Math.round(
(position.lat - this._mBounds.south) / this._scale + this._options.spacing
)
coord.y = this._heat._renderer.canvas.height - coord.y
return coord
}

/**
*
* @returns {{east: *, south: *, north: *, west: *}}
* @private
*/
_getMBounds() {
let mWestSouth = Transform.transformWGS84ToMercator(
new Position(this._bounds.west, this._bounds.south)
)
let mEastNorth = Transform.transformWGS84ToMercator(
new Position(this._bounds.east, this._bounds.north)
)
return {
west: mWestSouth.lng,
south: mWestSouth.lat,
east: mEastNorth.lng,
north: mEastNorth.lat
}
}

/**
*
* @private
*/
_initCanvas() {
let diffLng = Math.abs(this._mBounds.east - this._mBounds.west)
let diffLat = Math.abs(this._mBounds.north - this._mBounds.south)
let max = Math.max(diffLng, diffLat)
let min = Math.min(diffLng, diffLat)
let scale = 1
if (max > this._options.maxCanvasSize) {
scale = max / this._options.maxCanvasSize
if (min / scale < this._options.minCanvasSize) {
scale = min / this._options.minCanvasSize
}
} else if (min < this._options.minCanvasSize) {
scale = min / this._options.minCanvasSize
if (max / scale > this._options.maxCanvasSize) {
scale = max / this._options.maxCanvasSize
}
}
this._scale = scale
if (!this._options.container) {
this._options.container = DomUtil.create(
'div',
'heat-map',
document.getElementsByClassName('dc-container')[0]
)
}
this._options.container.style.cssText = `
width:${diffLng / this._scale}px;
height:${diffLat / this._scale}px;
margin:0;
display:none`
if (!this._heat) {
this._heat = h337.create(this._options)
} else {
this._heat.configure(this._options)
}
}

/**
*
*/
_initEntity() {
let offset = this._options.spacing * this._scale
this._mBounds.west -= offset
this._mBounds.south -= offset
this._mBounds.east += offset
this._mBounds.north += offset
let westSouth = Transform.transformMercatorToWGS84({
lng: this._mBounds.west,
lat: this._mBounds.south
})
let eastNorth = Transform.transformMercatorToWGS84({
lng: this._mBounds.east,
lat: this._mBounds.north
})
let bounds = Cesium.Rectangle.fromDegrees(
westSouth.lng,
westSouth.lat,
eastNorth.lng,
eastNorth.lat
)
this._entity.show = false
this._entity.rectangle = {
coordinates: bounds,
fill: false,
distanceDisplayCondition: this._options.distanceDisplayCondition
}
this._delegate.entities.add(this._entity)
}

_reset() {
let cameraHeight = Math.floor(
this._viewer.camera.positionCartographic.height
)
let radius = (1e4 / cameraHeight) * 60
if (radius < 10) {
radius = 10
}
if (radius > 60) {
radius = 60
}
this._options.radius = radius
this._options.spacing = this._options.radius * 1.5
this._heat && this._heat.configure(this._options)
}

_redraw() {
/** set bounds */
if (!this._bounds) {
return false
}
let mBounds = this._getMBounds()
if (
!this._mBounds ||
mBounds.west !== this._mBounds.west ||
mBounds.south !== this._mBounds.south ||
mBounds.east !== this._mBounds.east ||
mBounds.north !== this._mBounds.north
) {
this._mBounds = mBounds
this._initCanvas()
}
let data = []
this._positions.forEach(item => {
let coord = this._transformWGS84ToHeatmap({
lng: item.lng || item.x,
lat: item.lat || item.y
})
data.push({
x: coord.x,
y: coord.y,
value: item.value || 1
})
})
this._heat.setData({
min: 0,
max: 1,
data
})
this._delegate.entities.remove(this._entity)
this._initEntity()
let material = new Cesium.ImageMaterialProperty({
image: this._heat._renderer.canvas,
transparent: true
})
Util.merge(this._entity.rectangle, {
fill: true,
material: material
})
this._entity.show = true
}

/**
*
* @param {*} positions
*/
setPositions(positions) {
if (!positions || !Array.isArray(positions)) {
return this
}
this._positions = positions
this._bounds = Cesium.Math.bounds(this._positions)
this._redraw()
return this
}

/**
*
* @param {*} position
*/
addPosition(position) {
this._positions.push(position)
this._bounds = Cesium.Math.bounds(this._positions)
this._redraw()
return this
}

/**
*
* @param {*} options
*/
setOptions(options) {
Util.merge(this._options, options)
if (this._heat) {
this._options.spacing = this._options.radius * 1.5
this._heat.configure(this._options)
}
return this
}
}

Layer.registerType('heat')

export default HeatLayer

+ 87
- 0
modules/layer/type/HtmlLayer.js View File

@@ -0,0 +1,87 @@
/**
* @Author: Caven
* @Date: 2020-02-12 21:43:33
*/
import { Cesium } from '@dc-modules/namespace'
import State from '@dc-modules/state/State'
import { DomUtil } from '@dc-modules/utils'
import { Transform } from '@dc-modules/transform'
import Layer from '../Layer'

class HtmlLayer extends Layer {
constructor(id) {
super(id)
this._delegate = DomUtil.create('div', 'html-layer', undefined)
this._delegate.setAttribute('id', this._id)
this._renderRemoveCallback = undefined
this.type = Layer.getLayerType('html')
this._state = State.INITIALIZED
}

set show(show) {
this._show = show
this._delegate.style.visibility = this._show ? 'visible' : 'hidden'
this._cache.keys().forEach(key => {
this._cache[key].show = show
})
return this
}

get show() {
return this._show
}

/**
* add handler
* @param viewer
* @private
*/
_onAdd(viewer) {
this._viewer = viewer
this._viewer.dcContainer.appendChild(this._delegate)
let scene = this._viewer.scene
this._renderRemoveCallback = scene.postRender.addEventListener(() => {
let cameraPosition = this._viewer.camera.positionWC
this.eachOverlay(item => {
if (item && item.position) {
let position = Transform.transformWGS84ToCartesian(item.position)
let windowCoord = Cesium.SceneTransforms.wgs84ToWindowCoordinates(
scene,
position
)
let distance = Cesium.Cartesian3.distance(position, cameraPosition)
item._updateStyle({ transform: windowCoord }, distance)
}
}, this)
}, this)
this._state = State.ADDED
}

/**
* remove handler
* @returns {boolean}
* @private
*/
_onRemove() {
this._renderRemoveCallback && this._renderRemoveCallback()
this._viewer.dcContainer.removeChild(this._delegate)
this._state = State.REMOVED
}

/**
* Clears all divIcons
* @returns {HtmlLayer}
*/
clear() {
while (this._delegate.hasChildNodes()) {
this._delegate.removeChild(this._delegate.firstChild)
}
this._cache = {}
this._state = State.CLEARED
return this
}
}

Layer.registerType('html')

export default HtmlLayer

+ 48
- 0
modules/layer/type/KmlLayer.js View File

@@ -0,0 +1,48 @@
/**
* @Author: Caven
* @Date: 2020-01-19 11:03:17
*/

import { Cesium } from '@dc-modules/namespace'
import State from '@dc-modules/state/State'
import Layer from '../Layer'

class KmlLayer extends Layer {
constructor(id, url, options = {}) {
if (!url) {
throw new Error('KmlLayer: the url is empty')
}
super(id)
this._delegate = Cesium.KmlDataSource.load(url, options)
this.type = Layer.getLayerType('kml')
this._state = State.INITIALIZED
}

set show(show) {
this._show = show
this._delegate &&
this._delegate.then(dataSource => {
dataSource.show = this._show
})
}

get show() {
return this._show
}

eachOverlay(method, context) {
if (this._delegate) {
this._delegate.then(dataSource => {
let entities = dataSource.entities.values
entities.forEach(item => {
method.call(context, item)
})
})
return this
}
}
}

Layer.registerType('kml')

export default KmlLayer

+ 40
- 0
modules/layer/type/LabelLayer.js View File

@@ -0,0 +1,40 @@
/**
* @Author: Caven
* @Date: 2020-03-30 17:14:00
*/

import { Cesium } from '@dc-modules/namespace'
import State from '@dc-modules/state/State'
import { Label } from '@dc-modules/overlay'
import Layer from '../Layer'

class LabelLayer extends Layer {
constructor(id, url = '') {
super(id)
this._dataSource = Cesium.GeoJsonDataSource.load(url)
this._delegate = new Cesium.CustomDataSource(id)
this._initLabel()
this.type = Layer.registerType('label')
this._state = State.INITIALIZED
}

_createLabel(entity) {
if (entity.position && entity.name) {
return Label.fromEntity(entity)
}
}

_initLabel() {
this._dataSource.then(dataSource => {
let entities = dataSource.entities.values
entities.forEach(item => {
let label = this._createLabel(item)
this.addOverlay(label)
})
})
}
}

Layer.registerType('label')

export default LabelLayer

+ 143
- 0
modules/layer/type/LayerGroup.js View File

@@ -0,0 +1,143 @@
/**
* @Author: Caven
* @Date: 2020-08-27 19:50:32
*/

import { Util } from '@dc-modules/utils'
import State from '@dc-modules/state/State'
import { LayerGroupEventType, LayerGroupEvent } from '@dc-modules/event'
import Layer from '../Layer'

class LayerGroup {
constructor(id) {
this._id = id || Util.uuid()
this._cache = {}
this._show = true
this._viewer = undefined
this._layerGroupEvent = new LayerGroupEvent()
this._layerGroupEvent.on(LayerGroupEventType.ADD, this._onAdd, this)
this._layerGroupEvent.on(LayerGroupEventType.REMOVE, this._onRemove, this)
this.type = Layer.getLayerType('layer_group')
this._state = State.INITIALIZED
}

get id() {
return this._id
}

set show(show) {
this._show = show
Object.keys(this._cache).forEach(key => {
this._cache[key].show = this._show
})
}

get show() {
return this._show
}

get layerGroupEvent() {
return this._layerGroupEvent
}

get state() {
return this._state
}

/**
*
* @param viewer
* @private
*/
_onAdd(viewer) {
this._viewer = viewer
Object.keys(this._cache).forEach(key => {
this._viewer.addLayer(this._cache[key])
})
this._state = State.ADDED
}

/**
*
* @private
*/
_onRemove() {
Object.keys(this._cache).forEach(key => {
this._viewer && this._viewer.removeLayer(this._cache[key])
})
this._cache = {}
this._state = State.REMOVED
}

/**
* Adds a layer
* @param layer
* @returns {LayerGroup}
*/
addLayer(layer) {
if (!Object(this._cache).hasOwnProperty(layer.id)) {
this._cache[layer.id] = layer
this._viewer && this._viewer.addLayer(layer)
}
return this
}

/**
* Removes a layer
* @param layer
* @returns {LayerGroup}
*/
removeLayer(layer) {
if (Object(this._cache).hasOwnProperty(layer.id)) {
this._viewer && this._viewer.removeLayer(layer)
delete this._cache[layer.id]
}
return this
}

/**
* Returns a layer by id
* @param id
* @returns {*|undefined}
*/
getLayer(id) {
return this._cache[id] || undefined
}

/**
* Returns all layers
* @returns {[]}
*/
getLayers() {
let result = []
Object.keys(this._cache).forEach(key => {
result.push(this._cache[key])
})
return result
}

/**
* Adds to the viewer
* @param viewer
* @returns {LayerGroup}
*/
addTo(viewer) {
if (viewer && viewer.addLayerGroup) {
viewer.addLayerGroup(this)
}
return this
}

/**
*
* @returns {LayerGroup}
*/
remove() {
this._viewer && this._viewer.removeLayerGroup(this)
return this
}
}

Layer.registerType('layer_group')

export default LayerGroup

+ 32
- 0
modules/layer/type/PrimitiveLayer.js View File

@@ -0,0 +1,32 @@
/**
* @Author: Caven
* @Date: 2020-10-11 18:16:47
*/

import { Cesium } from '@dc-modules/namespace'
import State from '@dc-modules/state/State'
import Layer from '../Layer'

class PrimitiveLayer extends Layer {
constructor(id) {
super(id)
this._delegate = new Cesium.PrimitiveCollection()
this.type = Layer.getLayerType('primitive')
this._state = State.INITIALIZED
}

/**
* Clears all primitives
* @returns {PrimitiveLayer}
*/
clear() {
this._delegate && this._delegate.removeAll()
this._cache = {}
this._state = State.CLEARED
return this
}
}

Layer.registerType('primitive')

export default PrimitiveLayer

+ 35
- 0
modules/layer/type/TilesetLayer.js View File

@@ -0,0 +1,35 @@
/**
* @Author: Caven
* @Date: 2020-01-09 09:16:27
*/

import { Cesium } from '@dc-modules/namespace'
import State from '@dc-modules/state/State'
import Layer from '../Layer'

/**
* TilesetLayer is used to add various tileset
*/
class TilesetLayer extends Layer {
constructor(id) {
super(id)
this._delegate = new Cesium.PrimitiveCollection()
this.type = Layer.getLayerType('tileset')
this._state = State.INITIALIZED
}

/**
* Clear all tileset
* @returns {TilesetLayer}
*/
clear() {
this._delegate.removeAll()
this._cache = {}
this._state = State.CLEARED
return this
}
}

Layer.registerType('tileset')

export default TilesetLayer

+ 22
- 0
modules/layer/type/TopoJsonLayer.js View File

@@ -0,0 +1,22 @@
/**
* @Author: Caven
* @Date: 2020-09-11 19:32:22
*/

import State from '@dc-modules/state/State'
import GeoJsonLayer from './GeoJsonLayer'

class TopoJsonLayer extends GeoJsonLayer {
constructor(id, url, options = {}) {
if (!url) {
throw new Error('TopoJsonLayer:the url invalid')
}
super(id, url, options)
this.type = GeoJsonLayer.getLayerType('topojson')
this._state = State.INITIALIZED
}
}

GeoJsonLayer.registerType('topojson')

export default TopoJsonLayer

+ 36
- 0
modules/layer/type/VectorLayer.js View File

@@ -0,0 +1,36 @@
/**
* @Author: Caven
* @Date: 2020-01-02 16:42:03
*/

import { Cesium } from '@dc-modules/namespace'
import State from '@dc-modules/state/State'
import Layer from '../Layer'

/**
* The vector layer is used to add various entity, which is essentially a CustomDataSource
* that is used to place entities of the same class or business attribute into the same layer
*/
class VectorLayer extends Layer {
constructor(id) {
super(id)
this._delegate = new Cesium.CustomDataSource(id)
this.type = Layer.getLayerType('vector')
this._state = State.INITIALIZED
}

/**
* Clears all entities
* @returns {VectorLayer}
*/
clear() {
this._delegate.entities && this._delegate.entities.removeAll()
this._cache = {}
this._state = State.CLEARED
return this
}
}

Layer.registerType('vector')

export default VectorLayer

+ 0
- 0
modules/loader/index.js View File


Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save