@jorgmoritz/gis-manager 0.1.34 → 0.1.35

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/dist/index.cjs CHANGED
@@ -13,7 +13,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
13
13
  // package.json
14
14
  var package_default = {
15
15
  name: "@jorgmoritz/gis-manager",
16
- version: "0.1.34"};
16
+ version: "0.1.35"};
17
17
 
18
18
  // src/utils/version.ts
19
19
  var version = package_default.version;
@@ -2816,6 +2816,8 @@ var AirplaneCursor = class {
2816
2816
  __publicField(this, "angleStep");
2817
2817
  /** 加速倍率(按住 Shift 生效) */
2818
2818
  __publicField(this, "fastFactor");
2819
+ /** 最小高度(米) */
2820
+ __publicField(this, "minHeight");
2819
2821
  /** 外部传入的行为配置与回调 */
2820
2822
  __publicField(this, "opts");
2821
2823
  // 使用内联的 _FrustumPyramid
@@ -2843,6 +2845,7 @@ var AirplaneCursor = class {
2843
2845
  this.step = opts.stepMeters ?? 2;
2844
2846
  this.angleStep = opts.angleStepDeg ?? 1;
2845
2847
  this.fastFactor = opts.fastFactor ?? 5;
2848
+ this.minHeight = opts.minHeight ?? 0;
2846
2849
  this.currentFOV = opts.fovDeg ?? 50;
2847
2850
  this.ensureEntity(opts.color ?? C.Color.CYAN.withAlpha(0.9));
2848
2851
  this.attachKeyboard(opts);
@@ -3066,8 +3069,12 @@ var AirplaneCursor = class {
3066
3069
  moved = true;
3067
3070
  }
3068
3071
  if (this.keysPressed.has("z")) {
3069
- setPos(addVec(pose.position, C.Cartesian3.multiplyByScalar(u3, -step, new C.Cartesian3())));
3070
- moved = true;
3072
+ const newPos = addVec(pose.position, C.Cartesian3.multiplyByScalar(u3, -step, new C.Cartesian3()));
3073
+ const newCarto = C.Cartographic.fromCartesian(newPos);
3074
+ if (newCarto && newCarto.height >= this.minHeight) {
3075
+ setPos(newPos);
3076
+ moved = true;
3077
+ }
3071
3078
  }
3072
3079
  if (this.keysPressed.has("q")) {
3073
3080
  pose.heading = clampDeg(pose.heading - ang);
@@ -3940,6 +3947,7 @@ var VertexDragHandler = class {
3940
3947
  __publicField(this, "CesiumNS");
3941
3948
  __publicField(this, "viewer");
3942
3949
  __publicField(this, "hiddenClimbIndex");
3950
+ __publicField(this, "minHeight");
3943
3951
  __publicField(this, "callbacks");
3944
3952
  __publicField(this, "dragState", null);
3945
3953
  __publicField(this, "canvas");
@@ -3948,6 +3956,7 @@ var VertexDragHandler = class {
3948
3956
  this.CesiumNS = options.CesiumNS;
3949
3957
  this.viewer = options.viewer;
3950
3958
  this.hiddenClimbIndex = options.hiddenClimbIndex;
3959
+ this.minHeight = options.minHeight ?? 0;
3951
3960
  this.callbacks = callbacks;
3952
3961
  this.canvas = this.viewer.scene.canvas;
3953
3962
  this.setupKeyboardListeners();
@@ -4123,7 +4132,7 @@ var VertexDragHandler = class {
4123
4132
  const cameraHeight = this.viewer.camera.positionCartographic.height;
4124
4133
  const scaleFactor = Math.max(cameraHeight / 1e3, 0.5);
4125
4134
  const heightDelta = -deltaY * scaleFactor;
4126
- const newHeight = Math.max(0, this.dragState.startHeight + heightDelta);
4135
+ const newHeight = Math.max(this.minHeight, this.dragState.startHeight + heightDelta);
4127
4136
  const newPosition = C.Cartesian3.fromDegrees(
4128
4137
  this.dragState.startLonLat.lon,
4129
4138
  this.dragState.startLonLat.lat,
@@ -4230,7 +4239,8 @@ var PathEditingEventHandler = class {
4230
4239
  {
4231
4240
  CesiumNS: this.CesiumNS,
4232
4241
  viewer: this.viewer,
4233
- hiddenClimbIndex: this.hiddenClimbIndex
4242
+ hiddenClimbIndex: this.hiddenClimbIndex,
4243
+ minHeight: options.minHeight
4234
4244
  },
4235
4245
  {
4236
4246
  onDragStart: (index) => {
@@ -5281,7 +5291,9 @@ function startPathEditing(CesiumNS, viewer, entityOrId, options) {
5281
5291
  }
5282
5292
  },
5283
5293
  // frustumLengthFactor: options?.preview?.lengthFactor ?? 0.3,
5284
- fovDeg: options?.preview?.fov ?? 50
5294
+ fovDeg: options?.preview?.fov ?? 50,
5295
+ minHeight: options?.minHeight
5296
+ // 传递最小高度限制
5285
5297
  });
5286
5298
  if (options?.preview?.enabled !== false && airplaneCursor) {
5287
5299
  preview = new PathPreview(CesiumNS, viewer, {
@@ -5325,7 +5337,8 @@ function startPathEditing(CesiumNS, viewer, entityOrId, options) {
5325
5337
  {
5326
5338
  CesiumNS,
5327
5339
  viewer,
5328
- hiddenClimbIndex
5340
+ hiddenClimbIndex,
5341
+ minHeight: options?.minHeight
5329
5342
  },
5330
5343
  {
5331
5344
  onVertexSelect: (index) => setActiveIndex(index),
@@ -10928,6 +10941,21 @@ var PathSafetyChecker = class {
10928
10941
  this.CesiumNS = CesiumNS;
10929
10942
  this.viewer = viewer;
10930
10943
  }
10944
+ /**
10945
+ * 检测场景中是否有3D点云数据(Cesium3DTileset)
10946
+ * @returns 是否存在点云数据
10947
+ */
10948
+ hasPointCloudData() {
10949
+ const primitives = this.viewer.scene.primitives;
10950
+ for (let i = 0; i < primitives.length; i++) {
10951
+ const primitive = primitives.get(i);
10952
+ if (primitive && (primitive.constructor?.name === "Cesium3DTileset" || primitive._url !== void 0 || // 我们自己加载的带 _url 标记
10953
+ primitive.tileset !== void 0)) {
10954
+ return true;
10955
+ }
10956
+ }
10957
+ return false;
10958
+ }
10931
10959
  /**
10932
10960
  * 检测整条路径的安全性
10933
10961
  * @param positions 航点位置数组
@@ -10938,17 +10966,21 @@ var PathSafetyChecker = class {
10938
10966
  const terrainSafetyDistance = options?.terrainSafetyDistance ?? defaultDistance;
10939
10967
  const pointCloudSafetyDistance = options?.pointCloudSafetyDistance ?? defaultDistance;
10940
10968
  const minWaypointDistance = options?.minWaypointDistance ?? 0;
10941
- const sampleInterval = options?.sampleInterval ?? 5;
10969
+ const sampleInterval = options?.sampleInterval ?? 10;
10970
+ const fastMode = options?.fastMode ?? true;
10942
10971
  const results = [];
10943
10972
  const startSegment = 1 ;
10973
+ const hasPointCloud = this.hasPointCloudData();
10974
+ const effectivePointCloudSafetyDistance = hasPointCloud ? pointCloudSafetyDistance : 0;
10944
10975
  console.log("=".repeat(60));
10945
10976
  console.log("[PathSafetyChecker] \u5F00\u59CB\u5B89\u5168\u68C0\u6D4B");
10946
10977
  console.log(` \u5730\u5F62\u5B89\u5168\u8DDD\u79BB: ${terrainSafetyDistance}m`);
10947
- console.log(` \u70B9\u4E91\u5B89\u5168\u8DDD\u79BB: ${pointCloudSafetyDistance}m`);
10978
+ console.log(` \u70B9\u4E91\u5B89\u5168\u8DDD\u79BB: ${pointCloudSafetyDistance}m${!hasPointCloud ? " (\u573A\u666F\u65E0\u70B9\u4E91\u6570\u636E\uFF0C\u8DF3\u8FC7\u68C0\u6D4B)" : ""}`);
10948
10979
  if (minWaypointDistance > 0) {
10949
10980
  console.log(` \u822A\u70B9\u95F4\u6700\u5C0F\u8DDD\u79BB: ${minWaypointDistance}m`);
10950
10981
  }
10951
10982
  console.log(` \u91C7\u6837\u95F4\u9694: ${sampleInterval}m`);
10983
+ console.log(` \u68C0\u6D4B\u6A21\u5F0F: ${fastMode ? "\u5FEB\u901F(8\u65B9\u5411)" : "\u7CBE\u786E(16\u65B9\u5411)"}`);
10952
10984
  console.log(` \u822A\u70B9\u603B\u6570: ${positions.length}`);
10953
10985
  console.log(` \u68C0\u6D4B\u822A\u6BB5: ${startSegment} ~ ${positions.length - 2}`);
10954
10986
  console.log("=".repeat(60));
@@ -10964,9 +10996,11 @@ var PathSafetyChecker = class {
10964
10996
  i,
10965
10997
  i + 1,
10966
10998
  terrainSafetyDistance,
10967
- pointCloudSafetyDistance,
10999
+ effectivePointCloudSafetyDistance,
11000
+ // 使用有效的点云安全距离(无点云时为0,跳过检测)
10968
11001
  minWaypointDistance,
10969
- sampleInterval
11002
+ sampleInterval,
11003
+ fastMode
10970
11004
  );
10971
11005
  results.push(segmentResult);
10972
11006
  const terrainStatus = segmentResult.minTerrainDistance < 0 ? "\u2753" : segmentResult.isTerrainSafe ? "\u2705" : "\u26A0\uFE0F";
@@ -11020,7 +11054,7 @@ var PathSafetyChecker = class {
11020
11054
  * 检测单个航段的安全性
11021
11055
  * 支持多方向检测(上下左右前后6方向)和按间隔采样
11022
11056
  */
11023
- checkSegment(from, to, fromIndex, toIndex, terrainSafetyDistance, pointCloudSafetyDistance, minWaypointDistance, sampleInterval) {
11057
+ checkSegment(from, to, fromIndex, toIndex, terrainSafetyDistance, pointCloudSafetyDistance, minWaypointDistance, sampleInterval, fastMode = true) {
11024
11058
  const C = this.CesiumNS;
11025
11059
  const scene = this.viewer.scene;
11026
11060
  const dangerPoints = [];
@@ -11068,7 +11102,7 @@ var PathSafetyChecker = class {
11068
11102
  }
11069
11103
  const up2 = C.Cartesian3.cross(right, forward, new C.Cartesian3());
11070
11104
  C.Cartesian3.normalize(up2, up2);
11071
- const numDirections = 16;
11105
+ const numDirections = fastMode ? 8 : 16;
11072
11106
  for (let d = 0; d < numDirections; d++) {
11073
11107
  const angle = d / numDirections * Math.PI * 2;
11074
11108
  const outwardDir = new C.Cartesian3();
@@ -11082,40 +11116,37 @@ var PathSafetyChecker = class {
11082
11116
  C.Cartesian3.add(samplePoint, surfacePoint, surfacePoint);
11083
11117
  const inwardDir = C.Cartesian3.negate(outwardDir, new C.Cartesian3());
11084
11118
  const ray = new C.Ray(surfacePoint, inwardDir);
11085
- const intersections = scene.drillPickFromRay(ray, 10);
11086
- for (const intersection of intersections || []) {
11087
- if (!intersection?.position) continue;
11088
- const primitive = intersection.object?.primitive;
11089
- const primitiveName = primitive?.constructor?.name || "";
11090
- if (primitiveName === "Polyline" || primitiveName === "PointPrimitive" || primitiveName === "PointPrimitiveCollection" || primitiveName === "Billboard" || primitiveName === "Label" || primitiveName === "Cylinder" || primitiveName === "Ellipse" || primitiveName === "Model" || primitiveName === "ModelExperimental" || primitiveName === "Globe" || primitiveName === "GlobeSurfaceTile") {
11091
- continue;
11092
- }
11093
- if (primitiveName === "Primitive" && primitive?.appearance) {
11094
- const appearanceName = primitive.appearance?.constructor?.name || "";
11095
- if (appearanceName === "PerInstanceColorAppearance" || appearanceName === "MaterialAppearance" || appearanceName === "EllipsoidSurfaceAppearance") {
11096
- continue;
11097
- }
11098
- }
11099
- const is3DTiles = primitive?.tileset !== void 0 || primitive?._tileset !== void 0 || intersection.object?.content?.tileset !== void 0;
11100
- if (!is3DTiles && primitiveName !== "Cesium3DTilePointFeature") {
11119
+ const intersection = scene.pickFromRay(ray);
11120
+ if (!intersection?.position) continue;
11121
+ const primitive = intersection.object?.primitive;
11122
+ const primitiveName = primitive?.constructor?.name || "";
11123
+ if (primitiveName === "Polyline" || primitiveName === "PointPrimitive" || primitiveName === "PointPrimitiveCollection" || primitiveName === "Billboard" || primitiveName === "Label" || primitiveName === "Cylinder" || primitiveName === "Ellipse" || primitiveName === "Model" || primitiveName === "ModelExperimental" || primitiveName === "Globe" || primitiveName === "GlobeSurfaceTile") {
11124
+ continue;
11125
+ }
11126
+ if (primitiveName === "Primitive" && primitive?.appearance) {
11127
+ const appearanceName = primitive.appearance?.constructor?.name || "";
11128
+ if (appearanceName === "PerInstanceColorAppearance" || appearanceName === "MaterialAppearance" || appearanceName === "EllipsoidSurfaceAppearance") {
11101
11129
  continue;
11102
11130
  }
11103
- if (i === 0 && d === 0) {
11104
- console.log("[\u8C03\u8BD5] \u68C0\u6D4B\u5230\u70B9\u4E91\u5BF9\u8C61:", primitiveName);
11105
- console.log("[\u8C03\u8BD5] primitive:", primitive);
11106
- }
11107
- const distFromCenter = C.Cartesian3.distance(samplePoint, intersection.position);
11108
- minPointCloudDistance = Math.min(minPointCloudDistance, distFromCenter);
11109
- if (distFromCenter < pointCloudSafetyDistance) {
11110
- const alreadyAdded = dangerPoints.some(
11111
- (p) => C.Cartesian3.distance(p, samplePoint) < 0.1
11112
- );
11113
- if (!alreadyAdded) {
11114
- dangerPoints.push(C.Cartesian3.clone(samplePoint));
11115
- console.log(`[\u5371\u9669] \u91C7\u6837\u70B9 ${i}, \u65B9\u5411 ${d}: \u70B9\u4E91(${primitiveName})\u5728\u5706\u67F1\u4F53\u5185\uFF0C\u8DDD\u4E2D\u5FC3 ${distFromCenter.toFixed(1)}m`);
11116
- }
11131
+ }
11132
+ const is3DTiles = primitive?.tileset !== void 0 || primitive?._tileset !== void 0 || intersection.object?.content?.tileset !== void 0;
11133
+ if (!is3DTiles && primitiveName !== "Cesium3DTilePointFeature") {
11134
+ continue;
11135
+ }
11136
+ if (i === 0 && d === 0) {
11137
+ console.log("[\u8C03\u8BD5] \u68C0\u6D4B\u5230\u70B9\u4E91\u5BF9\u8C61:", primitiveName);
11138
+ console.log("[\u8C03\u8BD5] primitive:", primitive);
11139
+ }
11140
+ const distFromCenter = C.Cartesian3.distance(samplePoint, intersection.position);
11141
+ minPointCloudDistance = Math.min(minPointCloudDistance, distFromCenter);
11142
+ if (distFromCenter < pointCloudSafetyDistance) {
11143
+ const alreadyAdded = dangerPoints.some(
11144
+ (p) => C.Cartesian3.distance(p, samplePoint) < 0.1
11145
+ );
11146
+ if (!alreadyAdded) {
11147
+ dangerPoints.push(C.Cartesian3.clone(samplePoint));
11148
+ console.log(`[\u5371\u9669] \u91C7\u6837\u70B9 ${i}, \u65B9\u5411 ${d}: \u70B9\u4E91(${primitiveName})\u5728\u5706\u67F1\u4F53\u5185\uFF0C\u8DDD\u4E2D\u5FC3 ${distFromCenter.toFixed(1)}m`);
11117
11149
  }
11118
- break;
11119
11150
  }
11120
11151
  }
11121
11152
  } catch (e) {