@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/index.d.cts CHANGED
@@ -1376,6 +1376,11 @@ declare class PolygonEditor {
1376
1376
  height?: number;
1377
1377
  }>;
1378
1378
  }): Cesium.Entity | null;
1379
+ /**
1380
+ * 辅助方法:使用地形采样创建标签
1381
+ * 先尝试获取地形高度,如果失败则使用 heightReference
1382
+ */
1383
+ private createLabelWithTerrainHeight;
1379
1384
  /**
1380
1385
  * 辅助方法:从实体中提取经纬度高度数组
1381
1386
  * @param entity 多边形实体
package/dist/index.d.ts CHANGED
@@ -1376,6 +1376,11 @@ declare class PolygonEditor {
1376
1376
  height?: number;
1377
1377
  }>;
1378
1378
  }): Cesium.Entity | null;
1379
+ /**
1380
+ * 辅助方法:使用地形采样创建标签
1381
+ * 先尝试获取地形高度,如果失败则使用 heightReference
1382
+ */
1383
+ private createLabelWithTerrainHeight;
1379
1384
  /**
1380
1385
  * 辅助方法:从实体中提取经纬度高度数组
1381
1386
  * @param entity 多边形实体
package/dist/index.js CHANGED
@@ -11,7 +11,7 @@ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "sy
11
11
  // package.json
12
12
  var package_default = {
13
13
  name: "@jorgmoritz/gis-manager",
14
- version: "0.1.36"};
14
+ version: "0.1.38"};
15
15
 
16
16
  // src/utils/version.ts
17
17
  var version = package_default.version;
@@ -1593,7 +1593,7 @@ var CameraFOVController = class {
1593
1593
  this.minFOV = opts.minFOV;
1594
1594
  this.maxFOV = opts.maxFOV;
1595
1595
  }
1596
- this.currentFOV = opts.initialFOV ?? this.focalLengthToFOVDirect(56);
1596
+ this.currentFOV = opts.initialFOV ?? this.focalLengthToFOVDirect(1);
1597
1597
  this.useGlobalEventBus = opts.useGlobalEventBus ?? true;
1598
1598
  this.createUI();
1599
1599
  this.setupExternalFOVListener();
@@ -1943,7 +1943,7 @@ var CameraFOVController = class {
1943
1943
 
1944
1944
  // src/core/path-manager/PathPreview.ts
1945
1945
  var PathPreview = class {
1946
- // 当前 FOV 值
1946
+ // 折叠按钮
1947
1947
  constructor(CesiumNS, mainViewer, opts = {}) {
1948
1948
  this.CesiumNS = CesiumNS;
1949
1949
  this.mainViewer = mainViewer;
@@ -1959,6 +1959,10 @@ var PathPreview = class {
1959
1959
  __publicField(this, "fovController");
1960
1960
  // FOV 控制器
1961
1961
  __publicField(this, "currentFOV");
1962
+ // 当前 FOV 值
1963
+ __publicField(this, "collapsed", false);
1964
+ // 折叠状态
1965
+ __publicField(this, "toggleBtn");
1962
1966
  /** 已加载的 3D Tiles 实例(预览窗口独立的) */
1963
1967
  __publicField(this, "tilesets", /* @__PURE__ */ new Map());
1964
1968
  this.currentFOV = opts.fov ?? 50;
@@ -1973,9 +1977,9 @@ var PathPreview = class {
1973
1977
  host = document.createElement("div");
1974
1978
  host.style.position = "absolute";
1975
1979
  host.style.right = "10px";
1976
- host.style.bottom = "10px";
1977
- host.style.width = "480px";
1978
- host.style.height = "320px";
1980
+ host.style.bottom = "80px";
1981
+ host.style.width = "320px";
1982
+ host.style.height = "200px";
1979
1983
  host.style.border = "1px solid rgba(255, 255, 255, 1)";
1980
1984
  host.style.borderRadius = "6px";
1981
1985
  host.style.overflow = "hidden";
@@ -1985,6 +1989,7 @@ var PathPreview = class {
1985
1989
  parent?.appendChild(host);
1986
1990
  } catch {
1987
1991
  }
1992
+ this.createToggleButton(host);
1988
1993
  }
1989
1994
  this.containerEl = host;
1990
1995
  const v = new C.Viewer(host, {
@@ -2019,6 +2024,157 @@ var PathPreview = class {
2019
2024
  this.syncFromMainViewer();
2020
2025
  this.disableUserInteraction();
2021
2026
  }
2027
+ /**
2028
+ * 创建折叠按钮
2029
+ */
2030
+ createToggleButton(container) {
2031
+ if (typeof document === "undefined") return;
2032
+ this.toggleBtn = document.createElement("div");
2033
+ this.toggleBtn.style.cssText = `
2034
+ position: absolute;
2035
+ top: 6px;
2036
+ left: 6px;
2037
+ width: 24px;
2038
+ height: 24px;
2039
+ background: rgba(0, 0, 0, 0.6);
2040
+ border: 1px solid rgba(255, 255, 255, 0.5);
2041
+ border-radius: 4px;
2042
+ cursor: pointer;
2043
+ z-index: 20;
2044
+ display: flex;
2045
+ align-items: center;
2046
+ justify-content: center;
2047
+ transition: all 0.2s;
2048
+ pointer-events: auto;
2049
+ `;
2050
+ this.toggleBtn.innerHTML = `
2051
+ <svg width="12" height="12" viewBox="0 0 12 12" fill="white" style="transition: transform 0.2s;">
2052
+ <path d="M4 2 L8 6 L4 10" stroke="white" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round"/>
2053
+ </svg>
2054
+ `;
2055
+ this.toggleBtn.addEventListener("mouseenter", () => {
2056
+ if (this.toggleBtn) {
2057
+ this.toggleBtn.style.background = "rgba(47, 119, 251, 0.8)";
2058
+ }
2059
+ });
2060
+ this.toggleBtn.addEventListener("mouseleave", () => {
2061
+ if (this.toggleBtn) {
2062
+ this.toggleBtn.style.background = "rgba(0, 0, 0, 0.6)";
2063
+ }
2064
+ });
2065
+ this.toggleBtn.addEventListener("click", (e) => {
2066
+ e.stopPropagation();
2067
+ this.toggle();
2068
+ });
2069
+ container.appendChild(this.toggleBtn);
2070
+ }
2071
+ /**
2072
+ * 切换折叠状态
2073
+ */
2074
+ toggle() {
2075
+ if (this.collapsed) {
2076
+ this.expand();
2077
+ } else {
2078
+ this.collapse();
2079
+ }
2080
+ }
2081
+ /**
2082
+ * 折叠预览窗口
2083
+ */
2084
+ collapse() {
2085
+ if (this.collapsed || !this.containerEl) return;
2086
+ this.collapsed = true;
2087
+ this.containerEl.dataset.originalWidth = this.containerEl.style.width;
2088
+ this.containerEl.dataset.originalHeight = this.containerEl.style.height;
2089
+ this.containerEl.style.width = "36px";
2090
+ this.containerEl.style.height = "36px";
2091
+ this.containerEl.style.overflow = "hidden";
2092
+ if (this.overlayViewer) {
2093
+ const viewerContainer = this.overlayViewer.container;
2094
+ if (viewerContainer) {
2095
+ viewerContainer.style.display = "none";
2096
+ }
2097
+ }
2098
+ this.hideFOVController();
2099
+ if (this.toggleBtn) {
2100
+ this.toggleBtn.style.cssText = `
2101
+ position: absolute;
2102
+ top: 2px;
2103
+ left: 2px;
2104
+ right: 2px;
2105
+ bottom: 2px;
2106
+ width: auto;
2107
+ height: auto;
2108
+ background: rgba(47, 119, 251, 0.9);
2109
+ border: 1px solid rgba(255, 255, 255, 0.8);
2110
+ border-radius: 4px;
2111
+ cursor: pointer;
2112
+ z-index: 20;
2113
+ display: flex;
2114
+ align-items: center;
2115
+ justify-content: center;
2116
+ transition: all 0.2s;
2117
+ pointer-events: auto;
2118
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
2119
+ `;
2120
+ this.toggleBtn.innerHTML = `
2121
+ <svg width="16" height="16" viewBox="0 0 12 12" fill="white">
2122
+ <path d="M8 2 L4 6 L8 10" stroke="white" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round"/>
2123
+ </svg>
2124
+ `;
2125
+ }
2126
+ this.containerEl.style.display = "block";
2127
+ }
2128
+ /**
2129
+ * 展开预览窗口
2130
+ */
2131
+ expand() {
2132
+ if (!this.collapsed || !this.containerEl) return;
2133
+ this.collapsed = false;
2134
+ this.containerEl.style.width = this.containerEl.dataset.originalWidth || "320px";
2135
+ this.containerEl.style.height = this.containerEl.dataset.originalHeight || "200px";
2136
+ if (this.overlayViewer) {
2137
+ const viewerContainer = this.overlayViewer.container;
2138
+ if (viewerContainer) {
2139
+ viewerContainer.style.display = "block";
2140
+ }
2141
+ }
2142
+ this.showFOVController();
2143
+ if (this.toggleBtn) {
2144
+ this.toggleBtn.style.cssText = `
2145
+ position: absolute;
2146
+ top: 6px;
2147
+ left: 6px;
2148
+ width: 24px;
2149
+ height: 24px;
2150
+ background: rgba(0, 0, 0, 0.6);
2151
+ border: 1px solid rgba(255, 255, 255, 0.5);
2152
+ border-radius: 4px;
2153
+ cursor: pointer;
2154
+ z-index: 20;
2155
+ display: flex;
2156
+ align-items: center;
2157
+ justify-content: center;
2158
+ transition: all 0.2s;
2159
+ pointer-events: auto;
2160
+ `;
2161
+ this.toggleBtn.innerHTML = `
2162
+ <svg width="12" height="12" viewBox="0 0 12 12" fill="white">
2163
+ <path d="M4 2 L8 6 L4 10" stroke="white" stroke-width="2" fill="none" stroke-linecap="round" stroke-linejoin="round"/>
2164
+ </svg>
2165
+ `;
2166
+ }
2167
+ try {
2168
+ this.overlayViewer?.scene?.requestRender?.();
2169
+ } catch {
2170
+ }
2171
+ }
2172
+ /**
2173
+ * 获取折叠状态
2174
+ */
2175
+ isCollapsed() {
2176
+ return this.collapsed;
2177
+ }
2022
2178
  /**
2023
2179
  * 从主 viewer 同步配置
2024
2180
  * 共享 Provider(安全)而非 DataSource
@@ -2405,6 +2561,11 @@ var PathPreview = class {
2405
2561
  }
2406
2562
  this.fovController = void 0;
2407
2563
  this.footprintEntity = void 0;
2564
+ try {
2565
+ this.toggleBtn?.remove();
2566
+ } catch {
2567
+ }
2568
+ this.toggleBtn = void 0;
2408
2569
  try {
2409
2570
  this.tilesets.forEach((tileset) => {
2410
2571
  try {
@@ -2841,7 +3002,7 @@ var AirplaneCursor = class {
2841
3002
  this.step = opts.stepMeters ?? 2;
2842
3003
  this.angleStep = opts.angleStepDeg ?? 1;
2843
3004
  this.fastFactor = opts.fastFactor ?? 5;
2844
- this.currentFOV = opts.fovDeg ?? 50;
3005
+ this.currentFOV = opts.fovDeg ?? 172;
2845
3006
  this.ensureEntity(opts.color ?? C.Color.CYAN.withAlpha(0.9));
2846
3007
  this.attachKeyboard(opts);
2847
3008
  this.setupFOVListener();
@@ -3119,7 +3280,8 @@ var AirplaneCursor = class {
3119
3280
  this.viewer.dataSources.add(layer);
3120
3281
  }
3121
3282
  this.frustum = new FrustumPyramid(this.CesiumNS, layer, {
3122
- fov: this.opts.fovDeg ?? 40,
3283
+ fov: this.opts.fovDeg ?? 172,
3284
+ // 默认 1mm 焦距对应的 FOV
3123
3285
  length: 80,
3124
3286
  color: this.opts.color,
3125
3287
  fillAlpha: 0.25,
@@ -8314,7 +8476,9 @@ var PolygonEditor = class {
8314
8476
  polygon: {
8315
8477
  hierarchy: positions,
8316
8478
  material: faceColor,
8317
- outline: false
8479
+ outline: false,
8480
+ // 🔧 修复:设置 heightReference 使多边形贴合地形
8481
+ heightReference: C.HeightReference.CLAMP_TO_GROUND
8318
8482
  }
8319
8483
  });
8320
8484
  const ring = positions.slice();
@@ -8327,15 +8491,51 @@ var PolygonEditor = class {
8327
8491
  width: 1,
8328
8492
  material: lineColor,
8329
8493
  clampToGround: true
8494
+ // 轮廓线已经设置了 clampToGround
8330
8495
  },
8331
8496
  properties: { _ownerId: id, _type: "polygon-outline" }
8332
8497
  });
8333
8498
  this.applyDashedOutlineStyle(outlineEntity, lineColor, 3, 10);
8334
8499
  const displayText = name.includes("_") ? name.split("_")[1] : name;
8500
+ const firstPoint = points[0];
8501
+ this.createLabelWithTerrainHeight(
8502
+ layer,
8503
+ id,
8504
+ displayText,
8505
+ firstPoint.lon,
8506
+ firstPoint.lat,
8507
+ lineColor
8508
+ );
8509
+ return entity;
8510
+ } catch (err) {
8511
+ console.error(`[PolygonEditor] \u521B\u5EFA\u591A\u8FB9\u5F62\u5931\u8D25:`, err);
8512
+ return null;
8513
+ }
8514
+ }
8515
+ /**
8516
+ * 辅助方法:使用地形采样创建标签
8517
+ * 先尝试获取地形高度,如果失败则使用 heightReference
8518
+ */
8519
+ async createLabelWithTerrainHeight(layer, ownerId, displayText, lon, lat, lineColor) {
8520
+ const C = this.CesiumNS;
8521
+ try {
8522
+ let terrainHeight = 0;
8523
+ const terrainProvider = this.viewer.terrainProvider;
8524
+ if (terrainProvider && typeof C.sampleTerrainMostDetailed === "function") {
8525
+ try {
8526
+ const positions = [C.Cartographic.fromDegrees(lon, lat)];
8527
+ const updatedPositions = await C.sampleTerrainMostDetailed(terrainProvider, positions);
8528
+ if (updatedPositions && updatedPositions[0] && updatedPositions[0].height !== void 0) {
8529
+ terrainHeight = updatedPositions[0].height;
8530
+ }
8531
+ } catch (e) {
8532
+ }
8533
+ }
8534
+ const labelPosition = C.Cartesian3.fromDegrees(lon, lat, terrainHeight + 1);
8335
8535
  layer.entities.add({
8336
- id: `${id}-label`,
8536
+ id: `${ownerId}-label`,
8337
8537
  name: "Polygon Label",
8338
- position: positions[0],
8538
+ position: labelPosition,
8339
8539
  label: {
8340
8540
  text: displayText,
8341
8541
  font: "bold 16px Microsoft YaHei, SimHei, sans-serif",
@@ -8345,14 +8545,14 @@ var PolygonEditor = class {
8345
8545
  style: C.LabelStyle.FILL_AND_OUTLINE,
8346
8546
  verticalOrigin: C.VerticalOrigin.BOTTOM,
8347
8547
  pixelOffset: new C.Cartesian2(0, -10),
8348
- disableDepthTestDistance: Number.POSITIVE_INFINITY
8548
+ disableDepthTestDistance: Number.POSITIVE_INFINITY,
8549
+ // 仍然设置 heightReference 作为备用
8550
+ heightReference: C.HeightReference.CLAMP_TO_GROUND
8349
8551
  },
8350
- properties: { _ownerId: id, _type: "polygon-label" }
8552
+ properties: { _ownerId: ownerId, _type: "polygon-label" }
8351
8553
  });
8352
- return entity;
8353
- } catch (err) {
8354
- console.error(`[PolygonEditor] \u521B\u5EFA\u591A\u8FB9\u5F62\u5931\u8D25:`, err);
8355
- return null;
8554
+ } catch (e) {
8555
+ console.warn(`[PolygonEditor] \u521B\u5EFA\u6807\u7B7E\u5931\u8D25:`, e);
8356
8556
  }
8357
8557
  }
8358
8558
  /**