@jorgmoritz/gis-manager 0.1.37 → 0.1.39

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
@@ -1549,7 +1549,7 @@ var CameraFOVController = class {
1549
1549
  this.minFOV = opts.minFOV;
1550
1550
  this.maxFOV = opts.maxFOV;
1551
1551
  }
1552
- this.currentFOV = opts.initialFOV ?? this.focalLengthToFOVDirect(56);
1552
+ this.currentFOV = opts.initialFOV ?? this.focalLengthToFOVDirect(1);
1553
1553
  this.useGlobalEventBus = opts.useGlobalEventBus ?? true;
1554
1554
  this.createUI();
1555
1555
  this.setupExternalFOVListener();
@@ -1899,7 +1899,7 @@ var CameraFOVController = class {
1899
1899
 
1900
1900
  // src/core/path-manager/PathPreview.ts
1901
1901
  var PathPreview = class {
1902
- // 当前 FOV 值
1902
+ // 折叠按钮
1903
1903
  constructor(CesiumNS, mainViewer, opts = {}) {
1904
1904
  this.CesiumNS = CesiumNS;
1905
1905
  this.mainViewer = mainViewer;
@@ -1915,6 +1915,10 @@ var PathPreview = class {
1915
1915
  __publicField(this, "fovController");
1916
1916
  // FOV 控制器
1917
1917
  __publicField(this, "currentFOV");
1918
+ // 当前 FOV 值
1919
+ __publicField(this, "collapsed", false);
1920
+ // 折叠状态
1921
+ __publicField(this, "toggleBtn");
1918
1922
  /** 已加载的 3D Tiles 实例(预览窗口独立的) */
1919
1923
  __publicField(this, "tilesets", /* @__PURE__ */ new Map());
1920
1924
  this.currentFOV = opts.fov ?? 50;
@@ -1929,9 +1933,9 @@ var PathPreview = class {
1929
1933
  host = document.createElement("div");
1930
1934
  host.style.position = "absolute";
1931
1935
  host.style.right = "10px";
1932
- host.style.bottom = "10px";
1933
- host.style.width = "480px";
1934
- host.style.height = "320px";
1936
+ host.style.bottom = "80px";
1937
+ host.style.width = "320px";
1938
+ host.style.height = "200px";
1935
1939
  host.style.border = "1px solid rgba(255, 255, 255, 1)";
1936
1940
  host.style.borderRadius = "6px";
1937
1941
  host.style.overflow = "hidden";
@@ -1941,6 +1945,7 @@ var PathPreview = class {
1941
1945
  parent?.appendChild(host);
1942
1946
  } catch {
1943
1947
  }
1948
+ this.createToggleButton(host);
1944
1949
  }
1945
1950
  this.containerEl = host;
1946
1951
  const v = new C.Viewer(host, {
@@ -1975,6 +1980,157 @@ var PathPreview = class {
1975
1980
  this.syncFromMainViewer();
1976
1981
  this.disableUserInteraction();
1977
1982
  }
1983
+ /**
1984
+ * 创建折叠按钮
1985
+ */
1986
+ createToggleButton(container) {
1987
+ if (typeof document === "undefined") return;
1988
+ this.toggleBtn = document.createElement("div");
1989
+ this.toggleBtn.style.cssText = `
1990
+ position: absolute;
1991
+ top: 6px;
1992
+ left: 6px;
1993
+ width: 24px;
1994
+ height: 24px;
1995
+ background: rgba(0, 0, 0, 0.6);
1996
+ border: 1px solid rgba(255, 255, 255, 0.5);
1997
+ border-radius: 4px;
1998
+ cursor: pointer;
1999
+ z-index: 20;
2000
+ display: flex;
2001
+ align-items: center;
2002
+ justify-content: center;
2003
+ transition: all 0.2s;
2004
+ pointer-events: auto;
2005
+ `;
2006
+ this.toggleBtn.innerHTML = `
2007
+ <svg width="12" height="12" viewBox="0 0 12 12" fill="white" style="transition: transform 0.2s;">
2008
+ <path d="M4 2 L8 6 L4 10" stroke="white" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round"/>
2009
+ </svg>
2010
+ `;
2011
+ this.toggleBtn.addEventListener("mouseenter", () => {
2012
+ if (this.toggleBtn) {
2013
+ this.toggleBtn.style.background = "rgba(47, 119, 251, 0.8)";
2014
+ }
2015
+ });
2016
+ this.toggleBtn.addEventListener("mouseleave", () => {
2017
+ if (this.toggleBtn) {
2018
+ this.toggleBtn.style.background = "rgba(0, 0, 0, 0.6)";
2019
+ }
2020
+ });
2021
+ this.toggleBtn.addEventListener("click", (e) => {
2022
+ e.stopPropagation();
2023
+ this.toggle();
2024
+ });
2025
+ container.appendChild(this.toggleBtn);
2026
+ }
2027
+ /**
2028
+ * 切换折叠状态
2029
+ */
2030
+ toggle() {
2031
+ if (this.collapsed) {
2032
+ this.expand();
2033
+ } else {
2034
+ this.collapse();
2035
+ }
2036
+ }
2037
+ /**
2038
+ * 折叠预览窗口
2039
+ */
2040
+ collapse() {
2041
+ if (this.collapsed || !this.containerEl) return;
2042
+ this.collapsed = true;
2043
+ this.containerEl.dataset.originalWidth = this.containerEl.style.width;
2044
+ this.containerEl.dataset.originalHeight = this.containerEl.style.height;
2045
+ this.containerEl.style.width = "36px";
2046
+ this.containerEl.style.height = "36px";
2047
+ this.containerEl.style.overflow = "hidden";
2048
+ if (this.overlayViewer) {
2049
+ const viewerContainer = this.overlayViewer.container;
2050
+ if (viewerContainer) {
2051
+ viewerContainer.style.display = "none";
2052
+ }
2053
+ }
2054
+ this.hideFOVController();
2055
+ if (this.toggleBtn) {
2056
+ this.toggleBtn.style.cssText = `
2057
+ position: absolute;
2058
+ top: 2px;
2059
+ left: 2px;
2060
+ right: 2px;
2061
+ bottom: 2px;
2062
+ width: auto;
2063
+ height: auto;
2064
+ background: rgba(47, 119, 251, 0.9);
2065
+ border: 1px solid rgba(255, 255, 255, 0.8);
2066
+ border-radius: 4px;
2067
+ cursor: pointer;
2068
+ z-index: 20;
2069
+ display: flex;
2070
+ align-items: center;
2071
+ justify-content: center;
2072
+ transition: all 0.2s;
2073
+ pointer-events: auto;
2074
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
2075
+ `;
2076
+ this.toggleBtn.innerHTML = `
2077
+ <svg width="16" height="16" viewBox="0 0 12 12" fill="white">
2078
+ <path d="M8 2 L4 6 L8 10" stroke="white" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round"/>
2079
+ </svg>
2080
+ `;
2081
+ }
2082
+ this.containerEl.style.display = "block";
2083
+ }
2084
+ /**
2085
+ * 展开预览窗口
2086
+ */
2087
+ expand() {
2088
+ if (!this.collapsed || !this.containerEl) return;
2089
+ this.collapsed = false;
2090
+ this.containerEl.style.width = this.containerEl.dataset.originalWidth || "320px";
2091
+ this.containerEl.style.height = this.containerEl.dataset.originalHeight || "200px";
2092
+ if (this.overlayViewer) {
2093
+ const viewerContainer = this.overlayViewer.container;
2094
+ if (viewerContainer) {
2095
+ viewerContainer.style.display = "block";
2096
+ }
2097
+ }
2098
+ this.showFOVController();
2099
+ if (this.toggleBtn) {
2100
+ this.toggleBtn.style.cssText = `
2101
+ position: absolute;
2102
+ top: 6px;
2103
+ left: 6px;
2104
+ width: 24px;
2105
+ height: 24px;
2106
+ background: rgba(0, 0, 0, 0.6);
2107
+ border: 1px solid rgba(255, 255, 255, 0.5);
2108
+ border-radius: 4px;
2109
+ cursor: pointer;
2110
+ z-index: 20;
2111
+ display: flex;
2112
+ align-items: center;
2113
+ justify-content: center;
2114
+ transition: all 0.2s;
2115
+ pointer-events: auto;
2116
+ `;
2117
+ this.toggleBtn.innerHTML = `
2118
+ <svg width="12" height="12" viewBox="0 0 12 12" fill="white">
2119
+ <path d="M4 2 L8 6 L4 10" stroke="white" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round"/>
2120
+ </svg>
2121
+ `;
2122
+ }
2123
+ try {
2124
+ this.overlayViewer?.scene?.requestRender?.();
2125
+ } catch {
2126
+ }
2127
+ }
2128
+ /**
2129
+ * 获取折叠状态
2130
+ */
2131
+ isCollapsed() {
2132
+ return this.collapsed;
2133
+ }
1978
2134
  /**
1979
2135
  * 从主 viewer 同步配置
1980
2136
  * 共享 Provider(安全)而非 DataSource
@@ -2361,6 +2517,11 @@ var PathPreview = class {
2361
2517
  }
2362
2518
  this.fovController = void 0;
2363
2519
  this.footprintEntity = void 0;
2520
+ try {
2521
+ this.toggleBtn?.remove();
2522
+ } catch {
2523
+ }
2524
+ this.toggleBtn = void 0;
2364
2525
  try {
2365
2526
  this.tilesets.forEach((tileset) => {
2366
2527
  try {
@@ -2797,7 +2958,7 @@ var AirplaneCursor = class {
2797
2958
  this.step = opts.stepMeters ?? 2;
2798
2959
  this.angleStep = opts.angleStepDeg ?? 1;
2799
2960
  this.fastFactor = opts.fastFactor ?? 5;
2800
- this.currentFOV = opts.fovDeg ?? 50;
2961
+ this.currentFOV = opts.fovDeg ?? 172;
2801
2962
  this.ensureEntity(opts.color ?? C.Color.CYAN.withAlpha(0.9));
2802
2963
  this.attachKeyboard(opts);
2803
2964
  this.setupFOVListener();
@@ -3075,7 +3236,8 @@ var AirplaneCursor = class {
3075
3236
  this.viewer.dataSources.add(layer);
3076
3237
  }
3077
3238
  this.frustum = new FrustumPyramid(this.CesiumNS, layer, {
3078
- fov: this.opts.fovDeg ?? 40,
3239
+ fov: this.opts.fovDeg ?? 172,
3240
+ // 默认 1mm 焦距对应的 FOV
3079
3241
  length: 80,
3080
3242
  color: this.opts.color,
3081
3243
  fillAlpha: 0.25,
@@ -8248,7 +8410,9 @@ var PolygonEditor = class {
8248
8410
  polygon: {
8249
8411
  hierarchy: positions,
8250
8412
  material: faceColor,
8251
- outline: false
8413
+ outline: false,
8414
+ // 🔧 修复:设置 heightReference 使多边形贴合地形
8415
+ heightReference: C.HeightReference.CLAMP_TO_GROUND
8252
8416
  }
8253
8417
  });
8254
8418
  const ring = positions.slice();
@@ -8261,15 +8425,51 @@ var PolygonEditor = class {
8261
8425
  width: 1,
8262
8426
  material: lineColor,
8263
8427
  clampToGround: true
8428
+ // 轮廓线已经设置了 clampToGround
8264
8429
  },
8265
8430
  properties: { _ownerId: id, _type: "polygon-outline" }
8266
8431
  });
8267
8432
  this.applyDashedOutlineStyle(outlineEntity, lineColor, 3, 10);
8268
8433
  const displayText = name.includes("_") ? name.split("_")[1] : name;
8434
+ const firstPoint = points[0];
8435
+ this.createLabelWithTerrainHeight(
8436
+ layer,
8437
+ id,
8438
+ displayText,
8439
+ firstPoint.lon,
8440
+ firstPoint.lat,
8441
+ lineColor
8442
+ );
8443
+ return entity;
8444
+ } catch (err) {
8445
+ console.error(`[PolygonEditor] \u521B\u5EFA\u591A\u8FB9\u5F62\u5931\u8D25:`, err);
8446
+ return null;
8447
+ }
8448
+ }
8449
+ /**
8450
+ * 辅助方法:使用地形采样创建标签
8451
+ * 先尝试获取地形高度,如果失败则使用 heightReference
8452
+ */
8453
+ async createLabelWithTerrainHeight(layer, ownerId, displayText, lon, lat, lineColor) {
8454
+ const C = this.CesiumNS;
8455
+ try {
8456
+ let terrainHeight = 0;
8457
+ const terrainProvider = this.viewer.terrainProvider;
8458
+ if (terrainProvider && typeof C.sampleTerrainMostDetailed === "function") {
8459
+ try {
8460
+ const positions = [C.Cartographic.fromDegrees(lon, lat)];
8461
+ const updatedPositions = await C.sampleTerrainMostDetailed(terrainProvider, positions);
8462
+ if (updatedPositions && updatedPositions[0] && updatedPositions[0].height !== void 0) {
8463
+ terrainHeight = updatedPositions[0].height;
8464
+ }
8465
+ } catch (e) {
8466
+ }
8467
+ }
8468
+ const labelPosition = C.Cartesian3.fromDegrees(lon, lat, terrainHeight + 1);
8269
8469
  layer.entities.add({
8270
- id: `${id}-label`,
8470
+ id: `${ownerId}-label`,
8271
8471
  name: "Polygon Label",
8272
- position: positions[0],
8472
+ position: labelPosition,
8273
8473
  label: {
8274
8474
  text: displayText,
8275
8475
  font: "bold 16px Microsoft YaHei, SimHei, sans-serif",
@@ -8279,14 +8479,14 @@ var PolygonEditor = class {
8279
8479
  style: C.LabelStyle.FILL_AND_OUTLINE,
8280
8480
  verticalOrigin: C.VerticalOrigin.BOTTOM,
8281
8481
  pixelOffset: new C.Cartesian2(0, -10),
8282
- disableDepthTestDistance: Number.POSITIVE_INFINITY
8482
+ disableDepthTestDistance: Number.POSITIVE_INFINITY,
8483
+ // 仍然设置 heightReference 作为备用
8484
+ heightReference: C.HeightReference.CLAMP_TO_GROUND
8283
8485
  },
8284
- properties: { _ownerId: id, _type: "polygon-label" }
8486
+ properties: { _ownerId: ownerId, _type: "polygon-label" }
8285
8487
  });
8286
- return entity;
8287
- } catch (err) {
8288
- console.error(`[PolygonEditor] \u521B\u5EFA\u591A\u8FB9\u5F62\u5931\u8D25:`, err);
8289
- return null;
8488
+ } catch (e) {
8489
+ console.warn(`[PolygonEditor] \u521B\u5EFA\u6807\u7B7E\u5931\u8D25:`, e);
8290
8490
  }
8291
8491
  }
8292
8492
  /**