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