@jorgmoritz/gis-manager 0.1.38 → 0.1.40

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/vue/index.js CHANGED
@@ -1507,6 +1507,11 @@ var HeightMarker = class {
1507
1507
  }
1508
1508
  };
1509
1509
 
1510
+ // src/core/path-manager/constants.ts
1511
+ var DEFAULT_FOV = 172;
1512
+ var SENSOR_WIDTH = 36;
1513
+ var FOCAL_LENGTH_PRESETS = [112, 56, 14, 7, 3, 1];
1514
+
1510
1515
  // src/core/path-manager/CameraFOVController.ts
1511
1516
  var CameraFOVController = class {
1512
1517
  constructor(opts = {}) {
@@ -1538,8 +1543,8 @@ var CameraFOVController = class {
1538
1543
  this.updateDisplay();
1539
1544
  this.emitChange();
1540
1545
  });
1541
- this.sensorWidth = opts.sensorWidth ?? 36;
1542
- this.focalLengthPresets = opts.focalLengthPresets ?? [112, 56, 14, 7, 3, 1];
1546
+ this.sensorWidth = opts.sensorWidth ?? SENSOR_WIDTH;
1547
+ this.focalLengthPresets = opts.focalLengthPresets ?? FOCAL_LENGTH_PRESETS;
1543
1548
  if (opts.minFOV === void 0 || opts.maxFOV === void 0) {
1544
1549
  const minFocalLength = Math.min(...this.focalLengthPresets);
1545
1550
  const maxFocalLength = Math.max(...this.focalLengthPresets);
@@ -1549,7 +1554,7 @@ var CameraFOVController = class {
1549
1554
  this.minFOV = opts.minFOV;
1550
1555
  this.maxFOV = opts.maxFOV;
1551
1556
  }
1552
- this.currentFOV = opts.initialFOV ?? this.focalLengthToFOVDirect(56);
1557
+ this.currentFOV = opts.initialFOV ?? DEFAULT_FOV;
1553
1558
  this.useGlobalEventBus = opts.useGlobalEventBus ?? true;
1554
1559
  this.createUI();
1555
1560
  this.setupExternalFOVListener();
@@ -1899,7 +1904,7 @@ var CameraFOVController = class {
1899
1904
 
1900
1905
  // src/core/path-manager/PathPreview.ts
1901
1906
  var PathPreview = class {
1902
- // 当前 FOV 值
1907
+ // 折叠按钮
1903
1908
  constructor(CesiumNS, mainViewer, opts = {}) {
1904
1909
  this.CesiumNS = CesiumNS;
1905
1910
  this.mainViewer = mainViewer;
@@ -1908,16 +1913,18 @@ var PathPreview = class {
1908
1913
  // Lightweight overlay viewer
1909
1914
  __publicField(this, "containerEl");
1910
1915
  // Container for the overlay viewer
1911
- __publicField(this, "footprintEntity");
1912
- // Entity for ground footprint polygon
1913
1916
  __publicField(this, "destroyed", false);
1914
1917
  // Track if the instance has been destroyed
1915
1918
  __publicField(this, "fovController");
1916
1919
  // FOV 控制器
1917
1920
  __publicField(this, "currentFOV");
1921
+ // 当前 FOV 值
1922
+ __publicField(this, "collapsed", false);
1923
+ // 折叠状态
1924
+ __publicField(this, "toggleBtn");
1918
1925
  /** 已加载的 3D Tiles 实例(预览窗口独立的) */
1919
1926
  __publicField(this, "tilesets", /* @__PURE__ */ new Map());
1920
- this.currentFOV = opts.fov ?? 50;
1927
+ this.currentFOV = opts.fov ?? DEFAULT_FOV;
1921
1928
  this.ensureViewer();
1922
1929
  this.ensureFOVController();
1923
1930
  }
@@ -1929,9 +1936,9 @@ var PathPreview = class {
1929
1936
  host = document.createElement("div");
1930
1937
  host.style.position = "absolute";
1931
1938
  host.style.right = "10px";
1932
- host.style.bottom = "10px";
1933
- host.style.width = "480px";
1934
- host.style.height = "320px";
1939
+ host.style.bottom = "80px";
1940
+ host.style.width = "320px";
1941
+ host.style.height = "200px";
1935
1942
  host.style.border = "1px solid rgba(255, 255, 255, 1)";
1936
1943
  host.style.borderRadius = "6px";
1937
1944
  host.style.overflow = "hidden";
@@ -1941,6 +1948,7 @@ var PathPreview = class {
1941
1948
  parent?.appendChild(host);
1942
1949
  } catch {
1943
1950
  }
1951
+ this.createToggleButton(host);
1944
1952
  }
1945
1953
  this.containerEl = host;
1946
1954
  const v = new C.Viewer(host, {
@@ -1975,6 +1983,157 @@ var PathPreview = class {
1975
1983
  this.syncFromMainViewer();
1976
1984
  this.disableUserInteraction();
1977
1985
  }
1986
+ /**
1987
+ * 创建折叠按钮
1988
+ */
1989
+ createToggleButton(container) {
1990
+ if (typeof document === "undefined") return;
1991
+ this.toggleBtn = document.createElement("div");
1992
+ this.toggleBtn.style.cssText = `
1993
+ position: absolute;
1994
+ top: 6px;
1995
+ left: 6px;
1996
+ width: 24px;
1997
+ height: 24px;
1998
+ background: rgba(0, 0, 0, 0.6);
1999
+ border: 1px solid rgba(255, 255, 255, 0.5);
2000
+ border-radius: 4px;
2001
+ cursor: pointer;
2002
+ z-index: 20;
2003
+ display: flex;
2004
+ align-items: center;
2005
+ justify-content: center;
2006
+ transition: all 0.2s;
2007
+ pointer-events: auto;
2008
+ `;
2009
+ this.toggleBtn.innerHTML = `
2010
+ <svg width="12" height="12" viewBox="0 0 12 12" fill="white" style="transition: transform 0.2s;">
2011
+ <path d="M4 2 L8 6 L4 10" stroke="white" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round"/>
2012
+ </svg>
2013
+ `;
2014
+ this.toggleBtn.addEventListener("mouseenter", () => {
2015
+ if (this.toggleBtn) {
2016
+ this.toggleBtn.style.background = "rgba(47, 119, 251, 0.8)";
2017
+ }
2018
+ });
2019
+ this.toggleBtn.addEventListener("mouseleave", () => {
2020
+ if (this.toggleBtn) {
2021
+ this.toggleBtn.style.background = "rgba(0, 0, 0, 0.6)";
2022
+ }
2023
+ });
2024
+ this.toggleBtn.addEventListener("click", (e) => {
2025
+ e.stopPropagation();
2026
+ this.toggle();
2027
+ });
2028
+ container.appendChild(this.toggleBtn);
2029
+ }
2030
+ /**
2031
+ * 切换折叠状态
2032
+ */
2033
+ toggle() {
2034
+ if (this.collapsed) {
2035
+ this.expand();
2036
+ } else {
2037
+ this.collapse();
2038
+ }
2039
+ }
2040
+ /**
2041
+ * 折叠预览窗口
2042
+ */
2043
+ collapse() {
2044
+ if (this.collapsed || !this.containerEl) return;
2045
+ this.collapsed = true;
2046
+ this.containerEl.dataset.originalWidth = this.containerEl.style.width;
2047
+ this.containerEl.dataset.originalHeight = this.containerEl.style.height;
2048
+ this.containerEl.style.width = "36px";
2049
+ this.containerEl.style.height = "36px";
2050
+ this.containerEl.style.overflow = "hidden";
2051
+ if (this.overlayViewer) {
2052
+ const viewerContainer = this.overlayViewer.container;
2053
+ if (viewerContainer) {
2054
+ viewerContainer.style.display = "none";
2055
+ }
2056
+ }
2057
+ this.hideFOVController();
2058
+ if (this.toggleBtn) {
2059
+ this.toggleBtn.style.cssText = `
2060
+ position: absolute;
2061
+ top: 2px;
2062
+ left: 2px;
2063
+ right: 2px;
2064
+ bottom: 2px;
2065
+ width: auto;
2066
+ height: auto;
2067
+ background: rgba(47, 119, 251, 0.9);
2068
+ border: 1px solid rgba(255, 255, 255, 0.8);
2069
+ border-radius: 4px;
2070
+ cursor: pointer;
2071
+ z-index: 20;
2072
+ display: flex;
2073
+ align-items: center;
2074
+ justify-content: center;
2075
+ transition: all 0.2s;
2076
+ pointer-events: auto;
2077
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
2078
+ `;
2079
+ this.toggleBtn.innerHTML = `
2080
+ <svg width="16" height="16" viewBox="0 0 12 12" fill="white">
2081
+ <path d="M8 2 L4 6 L8 10" stroke="white" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round"/>
2082
+ </svg>
2083
+ `;
2084
+ }
2085
+ this.containerEl.style.display = "block";
2086
+ }
2087
+ /**
2088
+ * 展开预览窗口
2089
+ */
2090
+ expand() {
2091
+ if (!this.collapsed || !this.containerEl) return;
2092
+ this.collapsed = false;
2093
+ this.containerEl.style.width = this.containerEl.dataset.originalWidth || "320px";
2094
+ this.containerEl.style.height = this.containerEl.dataset.originalHeight || "200px";
2095
+ if (this.overlayViewer) {
2096
+ const viewerContainer = this.overlayViewer.container;
2097
+ if (viewerContainer) {
2098
+ viewerContainer.style.display = "block";
2099
+ }
2100
+ }
2101
+ this.showFOVController();
2102
+ if (this.toggleBtn) {
2103
+ this.toggleBtn.style.cssText = `
2104
+ position: absolute;
2105
+ top: 6px;
2106
+ left: 6px;
2107
+ width: 24px;
2108
+ height: 24px;
2109
+ background: rgba(0, 0, 0, 0.6);
2110
+ border: 1px solid rgba(255, 255, 255, 0.5);
2111
+ border-radius: 4px;
2112
+ cursor: pointer;
2113
+ z-index: 20;
2114
+ display: flex;
2115
+ align-items: center;
2116
+ justify-content: center;
2117
+ transition: all 0.2s;
2118
+ pointer-events: auto;
2119
+ `;
2120
+ this.toggleBtn.innerHTML = `
2121
+ <svg width="12" height="12" viewBox="0 0 12 12" fill="white">
2122
+ <path d="M4 2 L8 6 L4 10" stroke="white" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round"/>
2123
+ </svg>
2124
+ `;
2125
+ }
2126
+ try {
2127
+ this.overlayViewer?.scene?.requestRender?.();
2128
+ } catch {
2129
+ }
2130
+ }
2131
+ /**
2132
+ * 获取折叠状态
2133
+ */
2134
+ isCollapsed() {
2135
+ return this.collapsed;
2136
+ }
1978
2137
  /**
1979
2138
  * 从主 viewer 同步配置
1980
2139
  * 共享 Provider(安全)而非 DataSource
@@ -2230,28 +2389,6 @@ var PathPreview = class {
2230
2389
  console.warn("[PathPreview] Failed to update FOV:", e);
2231
2390
  }
2232
2391
  }
2233
- // private ensureFootprint(): void {
2234
- // const C: any = this.CesiumNS as any;
2235
- // if (this.footprintEntity) return;
2236
- // this.footprintEntity = (this.layer.entities as any).add({
2237
- // polygon: {
2238
- // // Only show when we have at least 3 ground hit points
2239
- // show: new C.CallbackProperty(() => (this._footprintPositions?.length ?? 0) >= 3, false),
2240
- // hierarchy: new C.CallbackProperty(() => {
2241
- // const arr = this._footprintPositions;
2242
- // return arr && arr.length >= 3 ? arr.slice() : undefined;
2243
- // }, false),
2244
- // material: C.Color.CYAN.withAlpha(0.18),
2245
- // outline: true,
2246
- // outlineColor: C.Color.CYAN.withAlpha(0.7),
2247
- // outlineWidth: 1,
2248
- // // Use per-position heights from globe intersections to avoid terrain-ground primitive path
2249
- // perPositionHeight: true,
2250
- // },
2251
- // properties: { _type: 'preview-footprint' },
2252
- // });
2253
- // }
2254
- // private _footprintPositions: any[] | undefined;
2255
2392
  /**
2256
2393
  * Set the camera pose and field of view for the overlay viewer.
2257
2394
  * @param cartesian cartesian position
@@ -2271,29 +2408,6 @@ var PathPreview = class {
2271
2408
  orientation: { heading: h2, pitch: p, roll: r }
2272
2409
  });
2273
2410
  }
2274
- // // Recompute footprint using overlay scene
2275
- // try {
2276
- // const scene: any = v.scene;
2277
- // const w = scene?.canvas?.width ?? 256;
2278
- // const hgt = scene?.canvas?.height ?? 144;
2279
- // const corners = [
2280
- // new C.Cartesian2(2, 2),
2281
- // new C.Cartesian2(w - 2, 2),
2282
- // new C.Cartesian2(w - 2, hgt - 2),
2283
- // new C.Cartesian2(2, hgt - 2),
2284
- // ];
2285
- // const pts: any[] = [];
2286
- // for (const c of corners) {
2287
- // const ray = v.camera.getPickRay(c);
2288
- // if (!ray) continue;
2289
- // const hit = scene.globe?.pick?.(ray, scene);
2290
- // if (hit) pts.push(hit);
2291
- // }
2292
- // // this._footprintPositions = pts.length >= 3 ? pts : undefined;
2293
- // v.scene?.requestRender?.();
2294
- // (this.mainViewer.scene as any)?.requestRender?.();
2295
- // } catch {}
2296
- // }
2297
2411
  /**
2298
2412
  * 设置 FOV(如果启用了 FOV 控制器)
2299
2413
  */
@@ -2360,7 +2474,11 @@ var PathPreview = class {
2360
2474
  } catch {
2361
2475
  }
2362
2476
  this.fovController = void 0;
2363
- this.footprintEntity = void 0;
2477
+ try {
2478
+ this.toggleBtn?.remove();
2479
+ } catch {
2480
+ }
2481
+ this.toggleBtn = void 0;
2364
2482
  try {
2365
2483
  this.tilesets.forEach((tileset) => {
2366
2484
  try {
@@ -2414,7 +2532,7 @@ var FrustumPyramid = class {
2414
2532
  */
2415
2533
  computeFrustumGeometry(apex, headingDeg, pitchDeg, rollDeg, fovDeg, length) {
2416
2534
  const C = this.CesiumNS;
2417
- const fov = Math.max(1, Math.min(120, fovDeg ?? this.opts.fov ?? 50));
2535
+ const fov = Math.max(1, Math.min(120, fovDeg ?? this.opts.fov ?? DEFAULT_FOV));
2418
2536
  const aspectRatio = this.opts.aspectRatio ?? 4 / 3;
2419
2537
  const halfFovH = C.Math.toRadians(fov / 2);
2420
2538
  const halfWidth = Math.tan(halfFovH) * length;
@@ -2593,7 +2711,7 @@ var FrustumPyramid = class {
2593
2711
  const lakeFill = (this.opts.fillColor ?? C.Color.fromCssColorString("#1e90ff")).withAlpha(alpha);
2594
2712
  const width = this.opts.width ?? 3;
2595
2713
  this.ensureEntities(lakeEdge, width, lakeFill);
2596
- const effectiveFov = Math.max(1, Math.min(120, fovDeg ?? this.opts.fov ?? 50));
2714
+ const effectiveFov = Math.max(1, Math.min(120, fovDeg ?? this.opts.fov ?? DEFAULT_FOV));
2597
2715
  const aspectRatio = this.opts.aspectRatio ?? 4 / 3;
2598
2716
  this.logAnglesIfChanged(effectiveFov, aspectRatio, headingDeg, pitchDeg);
2599
2717
  const { apex: apexPos, corners, baseCenter } = this.computeFrustumGeometry(
@@ -2797,7 +2915,7 @@ var AirplaneCursor = class {
2797
2915
  this.step = opts.stepMeters ?? 2;
2798
2916
  this.angleStep = opts.angleStepDeg ?? 1;
2799
2917
  this.fastFactor = opts.fastFactor ?? 5;
2800
- this.currentFOV = opts.fovDeg ?? 50;
2918
+ this.currentFOV = opts.fovDeg ?? DEFAULT_FOV;
2801
2919
  this.ensureEntity(opts.color ?? C.Color.CYAN.withAlpha(0.9));
2802
2920
  this.attachKeyboard(opts);
2803
2921
  this.setupFOVListener();
@@ -3075,7 +3193,8 @@ var AirplaneCursor = class {
3075
3193
  this.viewer.dataSources.add(layer);
3076
3194
  }
3077
3195
  this.frustum = new FrustumPyramid(this.CesiumNS, layer, {
3078
- fov: this.opts.fovDeg ?? 40,
3196
+ fov: this.opts.fovDeg ?? DEFAULT_FOV,
3197
+ // 使用统一的默认 FOV
3079
3198
  length: 80,
3080
3199
  color: this.opts.color,
3081
3200
  fillAlpha: 0.25,
@@ -3084,8 +3203,8 @@ var AirplaneCursor = class {
3084
3203
  logAngles: false,
3085
3204
  logThrottleMs: 300
3086
3205
  });
3087
- const frustumFovScale = 0.6;
3088
- const frustumLengthScale = 0.1;
3206
+ const frustumFovScale = 0.5;
3207
+ const frustumLengthScale = 0.2;
3089
3208
  this.frustum.showAtDynamic(
3090
3209
  () => this.pose.position,
3091
3210
  () => this.pose.heading,
@@ -5166,11 +5285,11 @@ function startPathEditing(CesiumNS, viewer, entityOrId, options) {
5166
5285
  const fArr = getArr("_vertexFov");
5167
5286
  pitches[i] = typeof pArr?.[i] === "number" ? pArr[i] : -10;
5168
5287
  rolls[i] = typeof rArr?.[i] === "number" ? rArr[i] : 0;
5169
- fovs[i] = typeof fArr?.[i] === "number" ? fArr[i] : 50;
5288
+ fovs[i] = typeof fArr?.[i] === "number" ? fArr[i] : DEFAULT_FOV;
5170
5289
  } catch {
5171
5290
  pitches[i] = -10;
5172
5291
  rolls[i] = 0;
5173
- fovs[i] = 50;
5292
+ fovs[i] = DEFAULT_FOV;
5174
5293
  }
5175
5294
  }
5176
5295
  entity.polyline.positions = new C.CallbackProperty(() => positions.slice(), false);
@@ -5199,7 +5318,7 @@ function startPathEditing(CesiumNS, viewer, entityOrId, options) {
5199
5318
  headings[activeIndex] ?? 0,
5200
5319
  pitches[activeIndex] ?? -10,
5201
5320
  0,
5202
- fovs[activeIndex] ?? 50
5321
+ fovs[activeIndex] ?? DEFAULT_FOV
5203
5322
  );
5204
5323
  }
5205
5324
  } catch {
@@ -5375,13 +5494,13 @@ function startPathEditing(CesiumNS, viewer, entityOrId, options) {
5375
5494
  }
5376
5495
  },
5377
5496
  // frustumLengthFactor: options?.preview?.lengthFactor ?? 0.3,
5378
- fovDeg: options?.preview?.fov ?? 50
5497
+ fovDeg: options?.preview?.fov ?? DEFAULT_FOV
5379
5498
  });
5380
5499
  if (options?.preview?.enabled !== false && airplaneCursor) {
5381
5500
  preview = new PathPreview(CesiumNS, viewer, {
5382
5501
  container: options?.preview?.container,
5383
5502
  showFootprint: options?.preview?.showFootprint ?? false,
5384
- fov: options?.preview?.fov ?? 50,
5503
+ fov: options?.preview?.fov ?? DEFAULT_FOV,
5385
5504
  pitch: options?.preview?.pitch ?? -10,
5386
5505
  roll: options?.preview?.roll ?? 0
5387
5506
  });
@@ -5393,7 +5512,7 @@ function startPathEditing(CesiumNS, viewer, entityOrId, options) {
5393
5512
  initialPose.heading,
5394
5513
  initialPose.pitch,
5395
5514
  initialPose.roll,
5396
- options?.preview?.fov ?? 50
5515
+ options?.preview?.fov ?? DEFAULT_FOV
5397
5516
  );
5398
5517
  } catch {
5399
5518
  console.warn("PathEditing: failed to set initial preview pose");
@@ -5651,7 +5770,7 @@ function startPathEditing(CesiumNS, viewer, entityOrId, options) {
5651
5770
  heading: headings[index] ?? 0,
5652
5771
  pitch: pitches[index] ?? 0,
5653
5772
  roll: rolls[index] ?? 0,
5654
- fov: fovs[index] ?? 50
5773
+ fov: fovs[index] ?? DEFAULT_FOV
5655
5774
  };
5656
5775
  const totalVertices = positions.length;
5657
5776
  const totalVisibleVertices = totalVertices;
@@ -5725,7 +5844,7 @@ function startPathEditing(CesiumNS, viewer, entityOrId, options) {
5725
5844
  heading: headings[index] ?? 0,
5726
5845
  pitch: pitches[index] ?? -10,
5727
5846
  roll: rolls[index] ?? 0,
5728
- fov: fovs[index] ?? 50,
5847
+ fov: fovs[index] ?? DEFAULT_FOV,
5729
5848
  index,
5730
5849
  distance: calculatePathDistance(CesiumNS, positions, index),
5731
5850
  ellipsoidHeight,
@@ -6195,7 +6314,7 @@ function startPathDrawing(CesiumNS, viewer, options, onComplete) {
6195
6314
  try {
6196
6315
  const auto = options?.autoStartEditing;
6197
6316
  const editOptions = {
6198
- // 🔧 默认使用自由编辑模式(快速编辑和自由编辑互斥)
6317
+ // 默认使用自由编辑模式(快速编辑和自由编辑互斥)
6199
6318
  quickEdit: false
6200
6319
  };
6201
6320
  if (typeof auto === "object" && auto.preview) {