easy-three-utils 0.0.336 → 0.0.338
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cesium/components/index.ts +13 -0
- package/cesium/components/react/Timeline/index.tsx +21 -23
- package/cesium/components/react/image/pause.png +0 -0
- package/cesium/components/react/image/play.png +0 -0
- package/cesium/components/react/image/stop.png +0 -0
- package/cesium/index.ts +6 -4
- package/cesium/mars3d/data/militaryList.js +9715 -0
- package/cesium/mars3d/data/militaryTree.js +9141 -0
- package/cesium/mars3d/drawPolygon.d.ts +81 -0
- package/cesium/mars3d/drawPolygon.js +134 -0
- package/cesium/utils/useCloud.ts +113 -0
- package/cesium/utils/useDrawTools.ts +50 -0
- package/package.json +1 -1
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import * as cesium from 'cesium'
|
|
2
|
+
import * as mars3d from "mars3d"
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @param clampToGround 是否贴地
|
|
6
|
+
* @param color 标绘颜色
|
|
7
|
+
* @param fill 是否填充
|
|
8
|
+
* @param chasIntext 是否显示文本
|
|
9
|
+
* @param lineType 线段类型
|
|
10
|
+
* @param lineWidth 线段宽度
|
|
11
|
+
* @param serif 是否显示衬线
|
|
12
|
+
* @param serifColor 衬线颜色
|
|
13
|
+
* @param serifDirect 衬线类型
|
|
14
|
+
* @param serifWidth 衬线类型
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
export interface GraphicStyleOptions {
|
|
18
|
+
clampToGround?: boolean
|
|
19
|
+
color?: string
|
|
20
|
+
fill?: boolean
|
|
21
|
+
chasIntext?: boolean
|
|
22
|
+
lineType?: number
|
|
23
|
+
lineWidth?: number
|
|
24
|
+
serif?: boolean
|
|
25
|
+
serifColor?: string
|
|
26
|
+
serifDirect?: number
|
|
27
|
+
serifWidth?: number
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface FileLike {
|
|
31
|
+
name: string
|
|
32
|
+
originFileObj?: File
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface PolygonUtils {
|
|
36
|
+
/**
|
|
37
|
+
* 初始化工具
|
|
38
|
+
* @param Viewer cesium.Viewer
|
|
39
|
+
*/
|
|
40
|
+
init: (Viewer: cesium.Viewer) => void
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* 销毁工具
|
|
44
|
+
*/
|
|
45
|
+
destroy: () => void
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* 开始绘制
|
|
49
|
+
*/
|
|
50
|
+
startDraw: (options: GraphicStyleOptions) => void
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* 清空图层
|
|
54
|
+
*/
|
|
55
|
+
clearLayer: () => void
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* 读取文件并加载
|
|
59
|
+
*/
|
|
60
|
+
readFileAndload: (file: FileLike | File) => void
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* 保存并导出标注数据
|
|
64
|
+
*/
|
|
65
|
+
saveAndExportFile: () => void
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* 获取指定图形的样式
|
|
69
|
+
*/
|
|
70
|
+
getGraphicStyles: (graphicId: string) => { style: GraphicStyleOptions }
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* 设置当前选中图形的样式
|
|
74
|
+
*/
|
|
75
|
+
setGraphicStyles: (options: { style: GraphicStyleOptions }) => void
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* 标绘工具 hooks
|
|
80
|
+
*/
|
|
81
|
+
export declare function usePolygonUtils(): PolygonUtils
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import * as mars3d from "mars3d"
|
|
2
|
+
import "mars3d-plot"
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* @ClassName mars3d-plotUtils
|
|
6
|
+
* @Author sjq
|
|
7
|
+
* @Date 2025/9/15 17:30
|
|
8
|
+
* @Description 绘制jb工具
|
|
9
|
+
* @Version 1.0
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
const usePolygonUtils = () => {
|
|
13
|
+
|
|
14
|
+
let map;
|
|
15
|
+
let graphicLayer;
|
|
16
|
+
let graphic;
|
|
17
|
+
|
|
18
|
+
const init = (viewer) => {
|
|
19
|
+
if (map) return
|
|
20
|
+
|
|
21
|
+
map = new mars3d.Map(viewer)
|
|
22
|
+
graphicLayer = new mars3d.layer.GraphicLayer({
|
|
23
|
+
hasEdit: true,
|
|
24
|
+
isAutoEditing: true
|
|
25
|
+
})
|
|
26
|
+
map.addLayer(graphicLayer)
|
|
27
|
+
|
|
28
|
+
graphicLayer.on(mars3d.EventType.click, (e) => { graphic = graphicLayer.getGraphicById(e.graphic.options.id) })
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const destroy = () => {
|
|
32
|
+
if (graphicLayer) {
|
|
33
|
+
graphicLayer.destroy()
|
|
34
|
+
graphicLayer = null
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
graphic = null
|
|
38
|
+
map = null
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const startDraw = (options) => {
|
|
42
|
+
let style = {
|
|
43
|
+
color: "#1bca79ff",
|
|
44
|
+
lineWidth: 1.5,
|
|
45
|
+
...options.style
|
|
46
|
+
}
|
|
47
|
+
const graphicOptions = {
|
|
48
|
+
code: options.code,
|
|
49
|
+
name: options.name,
|
|
50
|
+
type: options.type,
|
|
51
|
+
style,
|
|
52
|
+
scaleValues: options.scaleValues
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
graphicLayer.startDraw(graphicOptions)
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const clearLayer = () => {
|
|
59
|
+
graphicLayer.clear()
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const readFileAndload = (file) => {
|
|
63
|
+
const fileName = file.name
|
|
64
|
+
const fileType = fileName?.substring(fileName.lastIndexOf(".") + 1, fileName.length).toLowerCase()
|
|
65
|
+
|
|
66
|
+
if (fileType === "json" || fileType === "geojson") {
|
|
67
|
+
const reader = new FileReader()
|
|
68
|
+
reader.readAsText(file.originFileObj, "UTF-8")
|
|
69
|
+
reader.onloadend = function (e) {
|
|
70
|
+
const json = this.result
|
|
71
|
+
graphicLayer.loadJSON(json, { clear: true, flyTo: true })
|
|
72
|
+
}
|
|
73
|
+
} else {
|
|
74
|
+
throw new Error("暂不支持 " + fileType + " 文件类型的数据!")
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const saveAndExportFile = () => {
|
|
79
|
+
if (graphicLayer.getGraphics().length === 0) {
|
|
80
|
+
throw new Error("当前没有标注任何数据,无需保存!")
|
|
81
|
+
}
|
|
82
|
+
const geojson = graphicLayer.toJSON()
|
|
83
|
+
mars3d.Util.downloadFile("标绘.json", JSON.stringify(geojson))
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* @clampToGround 是否贴地 boolean
|
|
88
|
+
* @color 标绘颜色 string
|
|
89
|
+
* @fill 是否填充 boolean
|
|
90
|
+
* @chasIntext 是否显示文本 boolean
|
|
91
|
+
* @lineType 线段类型 number
|
|
92
|
+
* @lineWidth 线段宽度 number
|
|
93
|
+
* @serif 是否显示衬线 boolean
|
|
94
|
+
* @serifColor 衬线颜色 string
|
|
95
|
+
* @serifDirect 衬线类型 number
|
|
96
|
+
* @serifWidth 衬线类型 number
|
|
97
|
+
*/
|
|
98
|
+
|
|
99
|
+
const getGraphicStyles = (graphicId) => {
|
|
100
|
+
graphic = graphicLayer.getGraphicById(graphicId)
|
|
101
|
+
if (!graphic) {
|
|
102
|
+
throw new Error("没有获取到矢量!")
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const options = graphic.toJSON()
|
|
106
|
+
return options
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const setGraphicStyles = (options) => {
|
|
110
|
+
if (!graphic) {
|
|
111
|
+
return
|
|
112
|
+
}
|
|
113
|
+
graphic.setOptions(options)
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return {
|
|
117
|
+
map,
|
|
118
|
+
graphicLayer,
|
|
119
|
+
graphic,
|
|
120
|
+
|
|
121
|
+
init,
|
|
122
|
+
destroy,
|
|
123
|
+
startDraw,
|
|
124
|
+
clearLayer,
|
|
125
|
+
readFileAndload,
|
|
126
|
+
saveAndExportFile,
|
|
127
|
+
getGraphicStyles,
|
|
128
|
+
setGraphicStyles
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export {
|
|
133
|
+
usePolygonUtils
|
|
134
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import * as Cesium from 'cesium'
|
|
2
|
+
|
|
3
|
+
const useCloud = (viewer: Cesium.Viewer) => {
|
|
4
|
+
|
|
5
|
+
let cloudsCollection = []
|
|
6
|
+
|
|
7
|
+
const getRandomPoints = (polygonCartesian: Cesium.Cartesian3[], numPoints: number, h: number) => {
|
|
8
|
+
|
|
9
|
+
const polygon = polygonCartesian.map(cartesian => {
|
|
10
|
+
const cartographic = Cesium.Cartographic.fromCartesian(cartesian)
|
|
11
|
+
return {
|
|
12
|
+
lon: Cesium.Math.toDegrees(cartographic.longitude),
|
|
13
|
+
lat: Cesium.Math.toDegrees(cartographic.latitude),
|
|
14
|
+
height: cartographic.height + h,
|
|
15
|
+
}
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
const lonArray = polygon.map(p => p.lon)
|
|
19
|
+
const latArray = polygon.map(p => p.lat)
|
|
20
|
+
const minLon = Math.min(...lonArray)
|
|
21
|
+
const maxLon = Math.max(...lonArray)
|
|
22
|
+
const minLat = Math.min(...latArray)
|
|
23
|
+
const maxLat = Math.max(...latArray)
|
|
24
|
+
const heightAvg = polygon.reduce((sum, p) => sum + p.height, 0) / polygon.length
|
|
25
|
+
|
|
26
|
+
const isInside = (
|
|
27
|
+
point: {
|
|
28
|
+
lon: number,
|
|
29
|
+
lat: number
|
|
30
|
+
},
|
|
31
|
+
polygon: {
|
|
32
|
+
lon: number;
|
|
33
|
+
lat: number;
|
|
34
|
+
height: number;
|
|
35
|
+
}[]
|
|
36
|
+
) => {
|
|
37
|
+
let inside = false;
|
|
38
|
+
for (let i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
|
|
39
|
+
const xi = polygon[i].lon, yi = polygon[i].lat
|
|
40
|
+
const xj = polygon[j].lon, yj = polygon[j].lat
|
|
41
|
+
const intersect = ((yi > point.lat) !== (yj > point.lat)) &&
|
|
42
|
+
(point.lon < (xj - xi) * (point.lat - yi) / (yj - yi) + xi)
|
|
43
|
+
if (intersect) inside = !inside
|
|
44
|
+
}
|
|
45
|
+
return inside;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const points = [];
|
|
49
|
+
while (points.length < numPoints) {
|
|
50
|
+
const lon = Math.random() * (maxLon - minLon) + minLon
|
|
51
|
+
const lat = Math.random() * (maxLat - minLat) + minLat
|
|
52
|
+
if (isInside({ lon, lat }, polygon)) {
|
|
53
|
+
points.push(Cesium.Cartesian3.fromDegrees(lon, lat, heightAvg))
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return points;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const activateDrawCloud = (cloudWidth: number, cloudLength: number, density: number, points: Cesium.Cartesian3[]) => {
|
|
61
|
+
const clouds = viewer.scene.primitives.add(new Cesium.CloudCollection())
|
|
62
|
+
|
|
63
|
+
// cloudsCollection.push({
|
|
64
|
+
// id:
|
|
65
|
+
// })
|
|
66
|
+
|
|
67
|
+
const width = Math.max(...points.map(p => p.x)) - Math.min(...points.map(p => p.x))
|
|
68
|
+
const length = Math.max(...points.map(p => p.y)) - Math.min(...points.map(p => p.y))
|
|
69
|
+
const num = Math.floor(width * length / (cloudLength * cloudWidth)) * density
|
|
70
|
+
const _points = getRandomPoints(points, num, 5000 + (cloudLength + cloudWidth) / 2)
|
|
71
|
+
|
|
72
|
+
_points.forEach(point => {
|
|
73
|
+
const r = Math.random();
|
|
74
|
+
clouds.add({
|
|
75
|
+
show: true,
|
|
76
|
+
position: point,
|
|
77
|
+
maximumSize: new Cesium.Cartesian3(
|
|
78
|
+
5 + r * 15,
|
|
79
|
+
4 + r * 10,
|
|
80
|
+
3 + r * 5
|
|
81
|
+
),
|
|
82
|
+
scale: new Cesium.Cartesian2(
|
|
83
|
+
cloudWidth * (0.8 + Math.random() * 0.4),
|
|
84
|
+
cloudLength * (0.8 + Math.random() * 0.4)
|
|
85
|
+
),
|
|
86
|
+
slice: 0.2 + Math.random() * 0.3,
|
|
87
|
+
brightness: 0.8 + Math.random() * 0.4,
|
|
88
|
+
color: new Cesium.Color(
|
|
89
|
+
0.9 + Math.random() * 0.1,
|
|
90
|
+
0.7 + Math.random() * 0.2,
|
|
91
|
+
0.6 + Math.random() * 0.2,
|
|
92
|
+
0.8
|
|
93
|
+
),
|
|
94
|
+
noiseDetail: 3.0 + Math.random(),
|
|
95
|
+
noiseOffset: new Cesium.Cartesian3(
|
|
96
|
+
Math.random() * 100,
|
|
97
|
+
Math.random() * 100,
|
|
98
|
+
Math.random() * 100
|
|
99
|
+
),
|
|
100
|
+
orientation: Cesium.Quaternion.fromAxisAngle(
|
|
101
|
+
Cesium.Cartesian3.UNIT_Z,
|
|
102
|
+
Math.random() * Cesium.Math.TWO_PI
|
|
103
|
+
)
|
|
104
|
+
})
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const clearAll = () => {
|
|
110
|
+
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import * as Cesium from 'cesium'
|
|
2
|
+
|
|
3
|
+
enum ECollectionWhiteListNames {
|
|
4
|
+
POLYGON = 'polygon',
|
|
5
|
+
POLYGON_NODE = 'polygon_node'
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
const useCustomCollection = (viewer: Cesium.Viewer) => {
|
|
9
|
+
|
|
10
|
+
let collectionNames: string[] = ([])
|
|
11
|
+
let whiteList: string[] = ['polygon', 'polygon_node']
|
|
12
|
+
|
|
13
|
+
const addCollection = (name: string) => {
|
|
14
|
+
const index = collectionNames.findIndex(item => item === name)
|
|
15
|
+
if (index !== -1) return
|
|
16
|
+
collectionNames.push(name)
|
|
17
|
+
const dataSource = new Cesium.CustomDataSource(name);
|
|
18
|
+
viewer.dataSources.add(dataSource);
|
|
19
|
+
return dataSource
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const getCollection = (name: ECollectionWhiteListNames | string) => {
|
|
23
|
+
const collection = viewer.dataSources.getByName(name)
|
|
24
|
+
if (collection.length) {
|
|
25
|
+
return collection[0]
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const removeCollection = (name: string) => {
|
|
30
|
+
const collection = viewer.dataSources.getByName(name)
|
|
31
|
+
viewer.dataSources.remove(collection[0], false)
|
|
32
|
+
collectionNames = collectionNames.filter(item => item !== name && !whiteList.includes(item))
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const getCollectionNames = () => {
|
|
36
|
+
return collectionNames.filter(item => !whiteList.includes(item))
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return {
|
|
40
|
+
addCollection,
|
|
41
|
+
getCollection,
|
|
42
|
+
removeCollection,
|
|
43
|
+
getCollectionNames
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export {
|
|
48
|
+
ECollectionWhiteListNames,
|
|
49
|
+
useCustomCollection
|
|
50
|
+
}
|