easy-three-utils 0.0.347 → 0.0.348
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/index.ts +8 -2
- package/cesium/utils/index.ts +2 -0
- package/cesium/utils/lib/CreatePolygonOnGround.js +195 -0
- package/cesium/utils/lib/ReminderTip.js +71 -0
- package/cesium/utils/useCustomCollection.ts +13 -2
- package/cesium/utils/useMeasure.ts +72 -4
- package/cesium/utils/useSlope.ts +300 -0
- package/package.json +1 -1
package/cesium/index.ts
CHANGED
|
@@ -13,6 +13,7 @@ type TCesiumUtilsType = {
|
|
|
13
13
|
clipping: ReturnType<typeof hooks.useClipping>;
|
|
14
14
|
weather: ReturnType<typeof hooks.useWeather>;
|
|
15
15
|
measure: ReturnType<typeof hooks.useMeasure>;
|
|
16
|
+
slope: ReturnType<typeof hooks.useSlope>;
|
|
16
17
|
}
|
|
17
18
|
|
|
18
19
|
let config;
|
|
@@ -89,7 +90,11 @@ const useCesium = () => {
|
|
|
89
90
|
const measure = hooks.useMeasure(viewer, {
|
|
90
91
|
distanceCollection: customCollection.addCollection(hooks.dict.ECollectionWhiteListNames.MEASURE_DISTANCE),
|
|
91
92
|
heightCollection: customCollection.addCollection(hooks.dict.ECollectionWhiteListNames.MEASURE_HEIGHT),
|
|
92
|
-
areaCollection: customCollection.addCollection(hooks.dict.ECollectionWhiteListNames.MEASURE_AREA)
|
|
93
|
+
areaCollection: customCollection.addCollection(hooks.dict.ECollectionWhiteListNames.MEASURE_AREA),
|
|
94
|
+
altitudeCollection: customCollection.addCollection(hooks.dict.ECollectionWhiteListNames.MEASURE_ALTITUDE)
|
|
95
|
+
})
|
|
96
|
+
const slope = hooks.useSlope(viewer, {
|
|
97
|
+
collection: customCollection.addCollection(hooks.dict.ECollectionWhiteListNames.SLOPE)
|
|
93
98
|
})
|
|
94
99
|
|
|
95
100
|
if (config.controllerStyle === cesiumConfigDict.EControllerStyle.THREE) {
|
|
@@ -102,7 +107,8 @@ const useCesium = () => {
|
|
|
102
107
|
drawPolygon,
|
|
103
108
|
clipping,
|
|
104
109
|
weather,
|
|
105
|
-
measure
|
|
110
|
+
measure,
|
|
111
|
+
slope
|
|
106
112
|
})
|
|
107
113
|
|
|
108
114
|
handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas)
|
package/cesium/utils/index.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { useDrawPolygon } from './useDrawPolygon'
|
|
|
3
3
|
import { useClipping } from './useClipping'
|
|
4
4
|
import { useWeather, EWeatherType } from './useWeather'
|
|
5
5
|
import { useMeasure } from './useMeasure'
|
|
6
|
+
import { useSlope } from './useSlope'
|
|
6
7
|
|
|
7
8
|
const dict = {
|
|
8
9
|
ECollectionWhiteListNames,
|
|
@@ -15,6 +16,7 @@ export {
|
|
|
15
16
|
useClipping,
|
|
16
17
|
useWeather,
|
|
17
18
|
useMeasure,
|
|
19
|
+
useSlope,
|
|
18
20
|
|
|
19
21
|
dict
|
|
20
22
|
}
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
// import CreateRemindertip from "./ReminderTip";
|
|
2
|
+
import * as Cesium from 'cesium'
|
|
3
|
+
|
|
4
|
+
const CreatePolygonOnGround = function ({ viewer, collection }, resultList, options, callback, cb) {
|
|
5
|
+
if (!viewer) throw new Error("no viewer object!");
|
|
6
|
+
options = options || {};
|
|
7
|
+
let id = options.id || setSessionid(); //Polygon的id
|
|
8
|
+
if (collection.entities.getById(id))
|
|
9
|
+
throw new Error("the id parameter is an unique value");
|
|
10
|
+
let color = options.color || Cesium.Color.RED; //Polygon的填充色
|
|
11
|
+
let outlineColor = options.outlineColor || color.withAlpha(1); //Polygon的轮廓线颜色
|
|
12
|
+
let outlineWidth = options.outlineWidth || 2; //Polygon的轮廓线宽度
|
|
13
|
+
let handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
|
|
14
|
+
cb && cb(handler)
|
|
15
|
+
let toolTip = "左键点击开始绘制";
|
|
16
|
+
let anchorpoints = [];
|
|
17
|
+
let polygon = undefined;
|
|
18
|
+
let drawStatus = true;
|
|
19
|
+
handler.setInputAction(function (event) {
|
|
20
|
+
let pixPos = event.position;
|
|
21
|
+
let cartesian = getCatesian3FromPX(viewer, pixPos);
|
|
22
|
+
if (anchorpoints.length == 0) {
|
|
23
|
+
toolTip = "左键添加第二个点";
|
|
24
|
+
anchorpoints.push(cartesian);
|
|
25
|
+
let linePoints = new Cesium.CallbackProperty(function () {
|
|
26
|
+
let verPoints = anchorpoints.concat([anchorpoints[0]]);
|
|
27
|
+
return verPoints;
|
|
28
|
+
}, false);
|
|
29
|
+
let dynamicPositions = new Cesium.CallbackProperty(function () {
|
|
30
|
+
return new Cesium.PolygonHierarchy(anchorpoints);
|
|
31
|
+
}, false);
|
|
32
|
+
polygon = collection.entities.add({
|
|
33
|
+
name: "Polygon",
|
|
34
|
+
id: id,
|
|
35
|
+
polyline: {
|
|
36
|
+
positions: linePoints,
|
|
37
|
+
width: outlineWidth,
|
|
38
|
+
material: outlineColor,
|
|
39
|
+
clampToGround: true,
|
|
40
|
+
},
|
|
41
|
+
polygon: {
|
|
42
|
+
heightReference: Cesium.HeightReference.None,
|
|
43
|
+
hierarchy: dynamicPositions,
|
|
44
|
+
material: color,
|
|
45
|
+
},
|
|
46
|
+
});
|
|
47
|
+
polygon.GeoType = "Polygon";
|
|
48
|
+
} else {
|
|
49
|
+
toolTip = "左键添加点,Ctrl+Z回退,右键完成绘制";
|
|
50
|
+
}
|
|
51
|
+
anchorpoints.push(cartesian);
|
|
52
|
+
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
|
|
53
|
+
|
|
54
|
+
handler.setInputAction(function (movement) {
|
|
55
|
+
let endPos = movement.endPosition;
|
|
56
|
+
// CreateRemindertip(toolTip, endPos, true);
|
|
57
|
+
if (Cesium.defined(polygon)) {
|
|
58
|
+
anchorpoints.pop();
|
|
59
|
+
let cartesian = getCatesian3FromPX(viewer, endPos);
|
|
60
|
+
anchorpoints.push(cartesian);
|
|
61
|
+
}
|
|
62
|
+
if (anchorpoints.length === 3) {
|
|
63
|
+
polygon.polygon.heightReference = Cesium.HeightReference.CLAMP_TO_GROUND;
|
|
64
|
+
}
|
|
65
|
+
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
|
|
66
|
+
|
|
67
|
+
handler.setInputAction(function (event) {
|
|
68
|
+
anchorpoints.pop();
|
|
69
|
+
polygon.pottingPoint = anchorpoints;
|
|
70
|
+
resultList.push(polygon);
|
|
71
|
+
handler.removeInputAction(Cesium.ScreenSpaceEventType.RIGHT_DOWN)
|
|
72
|
+
handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK)
|
|
73
|
+
handler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE)
|
|
74
|
+
handler.destroy();
|
|
75
|
+
handler = null
|
|
76
|
+
// CreateRemindertip(toolTip, event.position, false);
|
|
77
|
+
drawStatus = false;
|
|
78
|
+
if (typeof callback == "function") callback(polygon);
|
|
79
|
+
}, Cesium.ScreenSpaceEventType.RIGHT_DOWN);
|
|
80
|
+
|
|
81
|
+
//Ctrl + Z回退
|
|
82
|
+
document.onkeydown = function (event) {
|
|
83
|
+
if (event.ctrlKey && window.event.keyCode == 90) {
|
|
84
|
+
if (!drawStatus) {
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
anchorpoints.pop();
|
|
88
|
+
if (anchorpoints.length == 2) {
|
|
89
|
+
toolTip = "左键添加第二个点";
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
};
|
|
94
|
+
function getCatesian3FromPX(viewer, px) {
|
|
95
|
+
let picks = viewer.scene.drillPick(px);
|
|
96
|
+
let cartesian = null;
|
|
97
|
+
let isOn3dtiles = false,
|
|
98
|
+
isOnTerrain = false;
|
|
99
|
+
// drillPick
|
|
100
|
+
for (let i in picks) {
|
|
101
|
+
let pick = picks[i];
|
|
102
|
+
if (
|
|
103
|
+
(pick && pick.primitive instanceof Cesium.Cesium3DTileFeature) ||
|
|
104
|
+
(pick && pick.primitive instanceof Cesium.Cesium3DTileset) ||
|
|
105
|
+
(pick && pick.primitive instanceof Cesium.Model)
|
|
106
|
+
) {
|
|
107
|
+
//模型上拾取
|
|
108
|
+
isOn3dtiles = true;
|
|
109
|
+
}
|
|
110
|
+
// 3dtilset
|
|
111
|
+
if (isOn3dtiles) {
|
|
112
|
+
viewer.scene.pick(px);
|
|
113
|
+
cartesian = viewer.scene.pickPosition(px);
|
|
114
|
+
if (cartesian) {
|
|
115
|
+
let cartographic = Cesium.Cartographic.fromCartesian(cartesian);
|
|
116
|
+
if (cartographic.height < 0) cartographic.height = 0;
|
|
117
|
+
let lon = Cesium.Math.toDegrees(cartographic.longitude),
|
|
118
|
+
lat = Cesium.Math.toDegrees(cartographic.latitude),
|
|
119
|
+
height = cartographic.height;
|
|
120
|
+
cartesian = transformWGS84ToCartesian(viewer, {
|
|
121
|
+
lng: lon,
|
|
122
|
+
lat: lat,
|
|
123
|
+
alt: height,
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
// 地形
|
|
129
|
+
let boolTerrain =
|
|
130
|
+
viewer.terrainProvider instanceof Cesium.EllipsoidTerrainProvider;
|
|
131
|
+
// Terrain
|
|
132
|
+
if (!isOn3dtiles && !boolTerrain) {
|
|
133
|
+
let ray = viewer.scene.camera.getPickRay(px);
|
|
134
|
+
if (!ray) return null;
|
|
135
|
+
cartesian = viewer.scene.globe.pick(ray, viewer.scene);
|
|
136
|
+
isOnTerrain = true;
|
|
137
|
+
}
|
|
138
|
+
// 地球
|
|
139
|
+
if (!isOn3dtiles && !isOnTerrain && boolTerrain) {
|
|
140
|
+
cartesian = viewer.scene.camera.pickEllipsoid(
|
|
141
|
+
px,
|
|
142
|
+
viewer.scene.globe.ellipsoid
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
if (cartesian) {
|
|
146
|
+
let position = transformCartesianToWGS84(viewer, cartesian);
|
|
147
|
+
if (position.alt < 0) {
|
|
148
|
+
cartesian = transformWGS84ToCartesian(viewer, position, 0.1);
|
|
149
|
+
}
|
|
150
|
+
return cartesian;
|
|
151
|
+
}
|
|
152
|
+
return false;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/***
|
|
156
|
+
* 坐标转换 84转笛卡尔
|
|
157
|
+
* @param {Object} {lng,lat,alt} 地理坐标
|
|
158
|
+
* @return {Object} Cartesian3 三维位置坐标
|
|
159
|
+
*/
|
|
160
|
+
function transformWGS84ToCartesian(viewer, position, alt) {
|
|
161
|
+
return position
|
|
162
|
+
? Cesium.Cartesian3.fromDegrees(
|
|
163
|
+
position.lng || position.lon,
|
|
164
|
+
position.lat,
|
|
165
|
+
(position.alt = alt || position.alt),
|
|
166
|
+
Cesium.Ellipsoid.WGS84
|
|
167
|
+
)
|
|
168
|
+
: Cesium.Cartesian3.ZERO;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/***
|
|
172
|
+
* 坐标转换 笛卡尔转84
|
|
173
|
+
* @param {Object} Cartesian3 三维位置坐标
|
|
174
|
+
* @return {Object} {lng,lat,alt} 地理坐标
|
|
175
|
+
*/
|
|
176
|
+
function transformCartesianToWGS84(viewer, cartesian) {
|
|
177
|
+
let ellipsoid = Cesium.Ellipsoid.WGS84;
|
|
178
|
+
let cartographic = ellipsoid.cartesianToCartographic(cartesian);
|
|
179
|
+
return {
|
|
180
|
+
lng: Cesium.Math.toDegrees(cartographic.longitude),
|
|
181
|
+
lat: Cesium.Math.toDegrees(cartographic.latitude),
|
|
182
|
+
alt: cartographic.height,
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
function setSessionid(num) {
|
|
186
|
+
let len = num || 32;
|
|
187
|
+
let chars = "ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678";
|
|
188
|
+
let maxPos = chars.length;
|
|
189
|
+
let pwd = "";
|
|
190
|
+
for (let i = 0; i < len; i++) {
|
|
191
|
+
pwd += chars.charAt(Math.floor(Math.random() * maxPos));
|
|
192
|
+
}
|
|
193
|
+
return pwd;
|
|
194
|
+
}
|
|
195
|
+
export default CreatePolygonOnGround;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
const CreateRemindertip = function (arr, position, show) {
|
|
2
|
+
let tooltip = document.getElementById("toolTip");
|
|
3
|
+
let style, _x, _y, _color;
|
|
4
|
+
if (arr && typeof arr === "object") {
|
|
5
|
+
style = arr;
|
|
6
|
+
}
|
|
7
|
+
if (style && style.origin) {
|
|
8
|
+
style.origin === "center" && ((_x = 15), (_y = -12));
|
|
9
|
+
style.origin === "top" && ((_x = 15), (_y = -44));
|
|
10
|
+
style.origin === "bottom" && ((_x = 15), (_y = 20));
|
|
11
|
+
} else {
|
|
12
|
+
(_x = 15), (_y = 20);
|
|
13
|
+
}
|
|
14
|
+
if (style && style.color) {
|
|
15
|
+
style.color === "white" &&
|
|
16
|
+
(_color = "background: rgba(255, 255, 255, 0.8);color: black;");
|
|
17
|
+
style.color === "black" &&
|
|
18
|
+
(_color = "background: rgba(0, 0, 0, 0.5);color: white;");
|
|
19
|
+
style.color === "yellow" &&
|
|
20
|
+
(_color =
|
|
21
|
+
"color: black;background-color: #ffcc33;border: 1px solid white;");
|
|
22
|
+
} else {
|
|
23
|
+
_color = "background: rgba(0, 0, 0, 0.5);color: white;";
|
|
24
|
+
}
|
|
25
|
+
if (!tooltip) {
|
|
26
|
+
const viewerDom = document.getElementsByClassName("cesium-viewer")[0];
|
|
27
|
+
let elementbottom = document.createElement("div");
|
|
28
|
+
viewerDom.append(elementbottom);
|
|
29
|
+
let html =
|
|
30
|
+
'<div id="toolTip" style="display: none;pointer-events: none;position: absolute;z-index: 1000;opacity: 0.8;border-radius: 4px;padding: 4px 8px;white-space: nowrap;font-family:黑体;color:white;font-weight: bolder;font-size: 14px;' +
|
|
31
|
+
_color +
|
|
32
|
+
'"></div>';
|
|
33
|
+
viewerDom.insertAdjacentHTML("beforeend", html);
|
|
34
|
+
tooltip = document.getElementById("toolTip");
|
|
35
|
+
}
|
|
36
|
+
if (show) {
|
|
37
|
+
tooltip.innerHTML = arr;
|
|
38
|
+
tooltip.style.left = position.x + _x + "px";
|
|
39
|
+
tooltip.style.top = position.y + _y + "px";
|
|
40
|
+
tooltip.style.display = "block";
|
|
41
|
+
} else {
|
|
42
|
+
tooltip.style.display = "none";
|
|
43
|
+
}
|
|
44
|
+
return {
|
|
45
|
+
tooltip: tooltip,
|
|
46
|
+
style: style,
|
|
47
|
+
showAt: function (position, text) {
|
|
48
|
+
this.tooltip.innerHTML = text;
|
|
49
|
+
if (this.style && this.style.origin) {
|
|
50
|
+
this.style.origin === "center" &&
|
|
51
|
+
((_x = 15), (_y = -this.tooltip.offsetHeight / 2));
|
|
52
|
+
this.style.origin === "top" &&
|
|
53
|
+
((_x = 15), (_y = -this.tooltip.offsetHeight - 20));
|
|
54
|
+
this.style.origin === "bottom" && ((_x = 15), (_y = 20));
|
|
55
|
+
} else {
|
|
56
|
+
(_x = 15), (_y = -this.tooltip.offsetHeight / 2);
|
|
57
|
+
}
|
|
58
|
+
this.tooltip.style.left = position.x + _x + "px";
|
|
59
|
+
this.tooltip.style.top = position.y + _y + "px";
|
|
60
|
+
this.tooltip.style.display = "block";
|
|
61
|
+
},
|
|
62
|
+
show: function (show) {
|
|
63
|
+
if (show) {
|
|
64
|
+
this.tooltip.style.display = "block";
|
|
65
|
+
} else {
|
|
66
|
+
this.tooltip.style.display = "none";
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
};
|
|
71
|
+
export default CreateRemindertip;
|
|
@@ -6,13 +6,24 @@ enum ECollectionWhiteListNames {
|
|
|
6
6
|
|
|
7
7
|
MEASURE_DISTANCE = 'measure_distance',
|
|
8
8
|
MEASURE_HEIGHT = 'measure_height',
|
|
9
|
-
MEASURE_AREA = 'measure_area'
|
|
9
|
+
MEASURE_AREA = 'measure_area',
|
|
10
|
+
MEASURE_ALTITUDE = 'measure_altitude',
|
|
11
|
+
|
|
12
|
+
SLOPE = 'slope'
|
|
10
13
|
}
|
|
11
14
|
|
|
12
15
|
const useCustomCollection = (viewer: Cesium.Viewer) => {
|
|
13
16
|
|
|
14
17
|
let collectionNames: string[] = ([])
|
|
15
|
-
let whiteList: string[] = [
|
|
18
|
+
let whiteList: string[] = [
|
|
19
|
+
'polygon',
|
|
20
|
+
'polygon_node',
|
|
21
|
+
'measure_distance',
|
|
22
|
+
'measure_height',
|
|
23
|
+
'measure_area',
|
|
24
|
+
'measure_altitude',
|
|
25
|
+
'slope'
|
|
26
|
+
]
|
|
16
27
|
|
|
17
28
|
const addCollection = (name: string) => {
|
|
18
29
|
const index = collectionNames.findIndex(item => item === name)
|
|
@@ -4,7 +4,8 @@ import * as turf from "@turf/turf"
|
|
|
4
4
|
const useMeasure = (viewer: Cesium.Viewer, options: {
|
|
5
5
|
distanceCollection: Cesium.CustomDataSource,
|
|
6
6
|
heightCollection: Cesium.CustomDataSource,
|
|
7
|
-
areaCollection: Cesium.CustomDataSource
|
|
7
|
+
areaCollection: Cesium.CustomDataSource,
|
|
8
|
+
altitudeCollection: Cesium.CustomDataSource
|
|
8
9
|
}) => {
|
|
9
10
|
|
|
10
11
|
const angleMeasurement = () => {
|
|
@@ -107,7 +108,7 @@ const useMeasure = (viewer: Cesium.Viewer, options: {
|
|
|
107
108
|
position: p2,
|
|
108
109
|
label: {
|
|
109
110
|
text: angleDeg.toFixed(2) + '°',
|
|
110
|
-
font: 'normal
|
|
111
|
+
font: 'normal 28px MicroSoft YaHei',
|
|
111
112
|
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
|
|
112
113
|
fillColor: Cesium.Color.WHITE,
|
|
113
114
|
verticalOrigin: Cesium.VerticalOrigin.CENTER,
|
|
@@ -611,7 +612,7 @@ const useMeasure = (viewer: Cesium.Viewer, options: {
|
|
|
611
612
|
const now = Date.now()
|
|
612
613
|
if (now - lastClickTime < MIN_INTERVAL) return
|
|
613
614
|
lastClickTime = now
|
|
614
|
-
|
|
615
|
+
|
|
615
616
|
let position = viewer.scene.pickPosition(e.position)
|
|
616
617
|
if (!position) {
|
|
617
618
|
const ellipsoid = viewer.scene.globe.ellipsoid
|
|
@@ -737,16 +738,83 @@ const useMeasure = (viewer: Cesium.Viewer, options: {
|
|
|
737
738
|
}
|
|
738
739
|
}
|
|
739
740
|
|
|
741
|
+
const altitudeMeasurement = () => {
|
|
742
|
+
let handler = null
|
|
743
|
+
|
|
744
|
+
const enable = () => {
|
|
745
|
+
disable();
|
|
746
|
+
|
|
747
|
+
(viewer.container as HTMLElement).style.cursor = "crosshair"
|
|
748
|
+
|
|
749
|
+
handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas)
|
|
750
|
+
handler.setInputAction(async (event) => {
|
|
751
|
+
const cartesian = viewer.scene.pickPosition(event.position)
|
|
752
|
+
if (!cartesian) return
|
|
753
|
+
|
|
754
|
+
const cartographic = Cesium.Cartographic.fromCartesian(cartesian)
|
|
755
|
+
const lon = Cesium.Math.toDegrees(cartographic.longitude)
|
|
756
|
+
const lat = Cesium.Math.toDegrees(cartographic.latitude)
|
|
757
|
+
const height = await getHeightFromLonLat(lon, lat)
|
|
758
|
+
|
|
759
|
+
options.altitudeCollection.entities.add({
|
|
760
|
+
position: Cesium.Cartesian3.fromDegrees(lon, lat, height + 2),
|
|
761
|
+
point: {
|
|
762
|
+
color: Cesium.Color.fromCssColorString("rgb(249, 157, 11)"),
|
|
763
|
+
outlineColor: Cesium.Color.WHITE,
|
|
764
|
+
outlineWidth: 2,
|
|
765
|
+
pixelSize: 10,
|
|
766
|
+
heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
|
|
767
|
+
},
|
|
768
|
+
label: {
|
|
769
|
+
text: `${height.toFixed(2)} m`,
|
|
770
|
+
scale: 0.5,
|
|
771
|
+
font: "normal 28px MicroSoft YaHei",
|
|
772
|
+
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
|
|
773
|
+
pixelOffset: new Cesium.Cartesian2(0, -30),
|
|
774
|
+
outlineWidth: 9,
|
|
775
|
+
outlineColor: Cesium.Color.WHITE
|
|
776
|
+
},
|
|
777
|
+
})
|
|
778
|
+
}, Cesium.ScreenSpaceEventType.LEFT_CLICK)
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
const getHeightFromLonLat = async (lon, lat) => {
|
|
782
|
+
const positions = [Cesium.Cartographic.fromDegrees(lon, lat)]
|
|
783
|
+
const updated = await Cesium.sampleTerrainMostDetailed(viewer.terrainProvider, positions)
|
|
784
|
+
return updated[0].height || 0
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
const disable = () => {
|
|
788
|
+
if (handler) {
|
|
789
|
+
handler.destroy()
|
|
790
|
+
handler = null
|
|
791
|
+
}
|
|
792
|
+
(viewer.container as HTMLElement).style.cursor = "default"
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
const removeAll = () => {
|
|
796
|
+
options.altitudeCollection.entities.removeAll()
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
return {
|
|
800
|
+
enable,
|
|
801
|
+
disable,
|
|
802
|
+
removeAll
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
|
|
740
806
|
const angle = angleMeasurement()
|
|
741
807
|
const distance = distanceMeasurement()
|
|
742
808
|
const height = heightMeasurement()
|
|
743
809
|
const area = areaMeasurement()
|
|
810
|
+
const altitude = altitudeMeasurement()
|
|
744
811
|
|
|
745
812
|
return {
|
|
746
813
|
angle,
|
|
747
814
|
distance,
|
|
748
815
|
height,
|
|
749
|
-
area
|
|
816
|
+
area,
|
|
817
|
+
altitude
|
|
750
818
|
}
|
|
751
819
|
}
|
|
752
820
|
|
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
import * as Cesium from "cesium"
|
|
2
|
+
import * as turf from "@turf/turf"
|
|
3
|
+
import CreatePolygonOnGround from "./lib/CreatePolygonOnGround"
|
|
4
|
+
// import CreateRemindertip from "./lib/ReminderTip"
|
|
5
|
+
|
|
6
|
+
const useSlope = (viewer: Cesium.Viewer, options: {
|
|
7
|
+
collection: Cesium.CustomDataSource
|
|
8
|
+
}) => {
|
|
9
|
+
|
|
10
|
+
let result = []
|
|
11
|
+
// let handler = null
|
|
12
|
+
// let toolTip = ""
|
|
13
|
+
let arrowWidth = 20
|
|
14
|
+
|
|
15
|
+
const Cartesian3ListToWGS84 = (cartesianList) => {
|
|
16
|
+
const ellipsoid = Cesium.Ellipsoid.WGS84
|
|
17
|
+
return cartesianList.map((cartesian) => {
|
|
18
|
+
const cartographic = ellipsoid.cartesianToCartographic(cartesian)
|
|
19
|
+
return {
|
|
20
|
+
lng: Cesium.Math.toDegrees(cartographic.longitude),
|
|
21
|
+
lat: Cesium.Math.toDegrees(cartographic.latitude),
|
|
22
|
+
alt: cartographic.height,
|
|
23
|
+
}
|
|
24
|
+
})
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const calculateSlopeColor = (value, alpha) => {
|
|
28
|
+
if (value < 0.0087) return `rgba(85,182,43,${alpha})`
|
|
29
|
+
if (value < 0.0349) return `rgba(135,211,43,${alpha})`
|
|
30
|
+
if (value < 0.0874) return `rgba(204,244,44,${alpha})`
|
|
31
|
+
if (value < 0.2679) return `rgba(245,233,44,${alpha})`
|
|
32
|
+
if (value < 0.7002) return `rgba(255,138,43,${alpha})`
|
|
33
|
+
if (value < 1.4281) return `rgba(255,84,43,${alpha})`
|
|
34
|
+
return `rgba(255,32,43,${alpha})`
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// const openTip = () => {
|
|
38
|
+
// handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas)
|
|
39
|
+
// handler.setInputAction((movement) => {
|
|
40
|
+
// const pick = viewer.scene.pick(movement.endPosition)
|
|
41
|
+
// if (pick && pick.id && pick.id.type === "SlopeAspect") {
|
|
42
|
+
// toolTip = pick.id.value.toFixed(2)
|
|
43
|
+
// CreateRemindertip(toolTip, movement.endPosition, true)
|
|
44
|
+
// } else {
|
|
45
|
+
// toolTip = ""
|
|
46
|
+
// CreateRemindertip(toolTip, movement.endPosition, false)
|
|
47
|
+
// }
|
|
48
|
+
// }, Cesium.ScreenSpaceEventType.MOUSE_MOVE)
|
|
49
|
+
// }
|
|
50
|
+
|
|
51
|
+
// const closeTip = () => {
|
|
52
|
+
// if (handler) {
|
|
53
|
+
// handler.destroy()
|
|
54
|
+
// handler = null
|
|
55
|
+
// }
|
|
56
|
+
// }
|
|
57
|
+
|
|
58
|
+
const drawByDistance = (distance = 0.1, onDrawStart?: (ev: () => void) => void, onComplete?: () => void) => {
|
|
59
|
+
const width = distance * 200 > 35 ? 35 : distance * 200
|
|
60
|
+
arrowWidth = width < 15 ? 15 : width
|
|
61
|
+
|
|
62
|
+
CreatePolygonOnGround({
|
|
63
|
+
viewer,
|
|
64
|
+
collection: options.collection
|
|
65
|
+
}, [],
|
|
66
|
+
{
|
|
67
|
+
color: Cesium.Color.RED.withAlpha(0.1),
|
|
68
|
+
outlineColor: Cesium.Color.YELLOW,
|
|
69
|
+
outlineWidth: 2,
|
|
70
|
+
},
|
|
71
|
+
(polygon) => {
|
|
72
|
+
const degrees = Cartesian3ListToWGS84(polygon.pottingPoint)
|
|
73
|
+
options.collection.entities.remove(polygon)
|
|
74
|
+
|
|
75
|
+
const boundary = degrees.map((p) => [p.lng, p.lat])
|
|
76
|
+
const bbox = turf.bbox(turf.polygon([boundary.concat([boundary[0]])]))
|
|
77
|
+
const mask = turf.polygon([boundary.concat([boundary[0]])])
|
|
78
|
+
const gridSquare = turf.squareGrid(bbox, distance, { mask })
|
|
79
|
+
createEllipse(gridSquare)
|
|
80
|
+
|
|
81
|
+
onComplete && onComplete()
|
|
82
|
+
},
|
|
83
|
+
(drawHandler: () => void) => onDrawStart && onDrawStart(drawHandler)
|
|
84
|
+
)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const drawByNum = (num = 10, onDrawStart?: (ev: () => void) => void, onComplete?: () => void) => {
|
|
88
|
+
CreatePolygonOnGround({
|
|
89
|
+
viewer,
|
|
90
|
+
collection: options.collection
|
|
91
|
+
}, [],
|
|
92
|
+
{
|
|
93
|
+
color: Cesium.Color.RED.withAlpha(0.1),
|
|
94
|
+
outlineColor: Cesium.Color.YELLOW,
|
|
95
|
+
outlineWidth: 2,
|
|
96
|
+
},
|
|
97
|
+
(polygon) => {
|
|
98
|
+
const degrees = Cartesian3ListToWGS84(polygon.pottingPoint)
|
|
99
|
+
options.collection.entities.remove(polygon)
|
|
100
|
+
|
|
101
|
+
const boundary = degrees.map((p) => [p.lng, p.lat])
|
|
102
|
+
const bbox = turf.bbox(turf.polygon([boundary.concat([boundary[0]])]))
|
|
103
|
+
|
|
104
|
+
const [minX, minY, maxX, maxY] = bbox
|
|
105
|
+
const step = Math.max(maxX - minX, maxY - minY) / num
|
|
106
|
+
|
|
107
|
+
const width = step * 2000 > 35 ? 35 : step * 2000
|
|
108
|
+
arrowWidth = width < 15 ? 15 : width
|
|
109
|
+
|
|
110
|
+
const mask = turf.polygon([boundary.concat([boundary[0]])])
|
|
111
|
+
const gridSquare = turf.squareGrid(bbox, step, {
|
|
112
|
+
units: "degrees",
|
|
113
|
+
mask,
|
|
114
|
+
})
|
|
115
|
+
createEllipse(gridSquare)
|
|
116
|
+
|
|
117
|
+
onComplete && onComplete()
|
|
118
|
+
},
|
|
119
|
+
(drawHandler: () => void) => { onDrawStart && onDrawStart(drawHandler) }
|
|
120
|
+
)
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const createEllipse = (gridSquare) => {
|
|
124
|
+
const boxResults = []
|
|
125
|
+
|
|
126
|
+
for (const feature of gridSquare.features) {
|
|
127
|
+
const coordinates = feature.geometry.coordinates[0]
|
|
128
|
+
const centerdegree = [
|
|
129
|
+
(coordinates[0][0] + coordinates[2][0]) / 2,
|
|
130
|
+
(coordinates[0][1] + coordinates[2][1]) / 2,
|
|
131
|
+
]
|
|
132
|
+
const centerCarto = Cesium.Cartographic.fromDegrees(
|
|
133
|
+
centerdegree[0],
|
|
134
|
+
centerdegree[1]
|
|
135
|
+
)
|
|
136
|
+
boxResults.push(centerCarto)
|
|
137
|
+
|
|
138
|
+
for (let i = 0; i < coordinates.length; i++) {
|
|
139
|
+
const coord = coordinates[i]
|
|
140
|
+
const carto = Cesium.Cartographic.fromDegrees(coord[0], coord[1])
|
|
141
|
+
boxResults.push(carto)
|
|
142
|
+
|
|
143
|
+
const next = coordinates[i + 1]
|
|
144
|
+
if (next) {
|
|
145
|
+
const mid = Cesium.Cartographic.fromDegrees(
|
|
146
|
+
(coord[0] + next[0]) / 2,
|
|
147
|
+
(coord[1] + next[1]) / 2
|
|
148
|
+
)
|
|
149
|
+
boxResults.push(mid)
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
Cesium.sampleTerrainMostDetailed(viewer.scene.terrainProvider, boxResults)
|
|
155
|
+
.then((updatePositions) => {
|
|
156
|
+
const group = []
|
|
157
|
+
for (let i = 0; i < updatePositions.length; i += 10) {
|
|
158
|
+
const slice = updatePositions.slice(i, i + 10)
|
|
159
|
+
if (slice.length) group.push(slice)
|
|
160
|
+
}
|
|
161
|
+
calculateSlope(group)
|
|
162
|
+
})
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
const createPolygonInstance = (points, color) => {
|
|
166
|
+
const positions = points
|
|
167
|
+
.slice(1, -1)
|
|
168
|
+
.map((p) => Cesium.Cartographic.toCartesian(p))
|
|
169
|
+
const polygon = new Cesium.PolygonGeometry({
|
|
170
|
+
polygonHierarchy: new Cesium.PolygonHierarchy(positions),
|
|
171
|
+
})
|
|
172
|
+
|
|
173
|
+
return new Cesium.GeometryInstance({
|
|
174
|
+
geometry: polygon,
|
|
175
|
+
attributes: {
|
|
176
|
+
color: Cesium.ColorGeometryInstanceAttribute.fromColor(
|
|
177
|
+
Cesium.Color.fromCssColorString(color)
|
|
178
|
+
),
|
|
179
|
+
show: new Cesium.ShowGeometryInstanceAttribute(true),
|
|
180
|
+
},
|
|
181
|
+
})
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
const createArrowInstance = (target, center, diagonal, heightDiff, slope) => {
|
|
185
|
+
const mid0 = new Cesium.Cartographic(
|
|
186
|
+
(target.longitude + center.longitude) / 2,
|
|
187
|
+
(target.latitude + center.latitude) / 2,
|
|
188
|
+
(target.height + center.height) / 2
|
|
189
|
+
)
|
|
190
|
+
const mid1 = new Cesium.Cartographic(
|
|
191
|
+
(diagonal.longitude + center.longitude) / 2,
|
|
192
|
+
(diagonal.latitude + center.latitude) / 2,
|
|
193
|
+
(diagonal.height + center.height) / 2
|
|
194
|
+
)
|
|
195
|
+
|
|
196
|
+
const positions =
|
|
197
|
+
heightDiff > 0
|
|
198
|
+
? [
|
|
199
|
+
Cesium.Cartographic.toCartesian(mid0),
|
|
200
|
+
Cesium.Cartographic.toCartesian(mid1),
|
|
201
|
+
]
|
|
202
|
+
: [
|
|
203
|
+
Cesium.Cartographic.toCartesian(mid1),
|
|
204
|
+
Cesium.Cartographic.toCartesian(mid0),
|
|
205
|
+
]
|
|
206
|
+
|
|
207
|
+
return new Cesium.GeometryInstance({
|
|
208
|
+
id: { type: "SlopeAspect", value: slope },
|
|
209
|
+
geometry: new Cesium.GroundPolylineGeometry({
|
|
210
|
+
positions,
|
|
211
|
+
width: arrowWidth,
|
|
212
|
+
}),
|
|
213
|
+
attributes: {
|
|
214
|
+
color: Cesium.ColorGeometryInstanceAttribute.fromColor(
|
|
215
|
+
Cesium.Color.BLUE.withAlpha(0.6)
|
|
216
|
+
),
|
|
217
|
+
show: new Cesium.ShowGeometryInstanceAttribute(true),
|
|
218
|
+
},
|
|
219
|
+
})
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
const calculateSlope = (groups) => {
|
|
223
|
+
const polygons = []
|
|
224
|
+
const arrows = []
|
|
225
|
+
|
|
226
|
+
for (const ellipse of groups) {
|
|
227
|
+
const center = ellipse[0]
|
|
228
|
+
let maxHD = 0
|
|
229
|
+
let maxIndex = 0
|
|
230
|
+
|
|
231
|
+
for (let i = 1; i < ellipse.length; i++) {
|
|
232
|
+
const hd = ellipse[i].height - center.height
|
|
233
|
+
if (Math.abs(hd) > Math.abs(maxHD)) {
|
|
234
|
+
maxHD = hd
|
|
235
|
+
maxIndex = i
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
const p0 = new Cesium.Cartographic(center.longitude, center.latitude, 0)
|
|
240
|
+
const p1 = new Cesium.Cartographic(
|
|
241
|
+
ellipse[maxIndex].longitude,
|
|
242
|
+
ellipse[maxIndex].latitude,
|
|
243
|
+
0
|
|
244
|
+
)
|
|
245
|
+
|
|
246
|
+
const dist = Cesium.Cartesian3.distance(
|
|
247
|
+
Cesium.Cartographic.toCartesian(p0),
|
|
248
|
+
Cesium.Cartographic.toCartesian(p1)
|
|
249
|
+
)
|
|
250
|
+
const slope = Math.abs(maxHD / dist)
|
|
251
|
+
const color = calculateSlopeColor(slope, 0.4)
|
|
252
|
+
|
|
253
|
+
polygons.push(createPolygonInstance(ellipse, color))
|
|
254
|
+
|
|
255
|
+
const diag = ellipse[maxIndex > 4 ? maxIndex - 4 : maxIndex + 4]
|
|
256
|
+
arrows.push(createArrowInstance(ellipse[maxIndex], center, diag, maxHD, slope))
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
const polyPrimitive = viewer.scene.primitives.add(
|
|
260
|
+
new Cesium.GroundPrimitive({
|
|
261
|
+
geometryInstances: polygons,
|
|
262
|
+
appearance: new Cesium.PerInstanceColorAppearance({
|
|
263
|
+
translucent: true,
|
|
264
|
+
closed: false,
|
|
265
|
+
}),
|
|
266
|
+
})
|
|
267
|
+
)
|
|
268
|
+
|
|
269
|
+
const arrowPrimitive = viewer.scene.primitives.add(
|
|
270
|
+
new Cesium.GroundPolylinePrimitive({
|
|
271
|
+
geometryInstances: arrows,
|
|
272
|
+
appearance: new Cesium.PolylineMaterialAppearance({
|
|
273
|
+
material: new Cesium.Material({
|
|
274
|
+
fabric: {
|
|
275
|
+
type: "PolylineArrow",
|
|
276
|
+
uniforms: { color: new Cesium.Color(1, 1, 0, 0.8) },
|
|
277
|
+
},
|
|
278
|
+
}),
|
|
279
|
+
}),
|
|
280
|
+
})
|
|
281
|
+
)
|
|
282
|
+
|
|
283
|
+
result.push(polyPrimitive, arrowPrimitive)
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
const removeAll = () => {
|
|
287
|
+
result.forEach((p) => viewer.scene.primitives.remove(p))
|
|
288
|
+
result = []
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
return {
|
|
292
|
+
drawByDistance,
|
|
293
|
+
drawByNum,
|
|
294
|
+
removeAll
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
export {
|
|
299
|
+
useSlope
|
|
300
|
+
}
|