@jorgmoritz/gis-manager 0.1.27 → 0.1.29

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
@@ -1183,6 +1183,7 @@ var SceneManager = class {
1183
1183
  const tileset = await this.apply3Dtiles(url);
1184
1184
  if (tileset) {
1185
1185
  tileset._customId = layer_id;
1186
+ tileset._url = url;
1186
1187
  this.viewer.scene.primitives.add(tileset);
1187
1188
  console.log(`[SceneManager] \u65B0\u5EFA 3DTiles_id`, tileset._customId);
1188
1189
  }
@@ -1914,6 +1915,8 @@ var PathPreview = class {
1914
1915
  __publicField(this, "fovController");
1915
1916
  // FOV 控制器
1916
1917
  __publicField(this, "currentFOV");
1918
+ /** 已加载的 3D Tiles 实例(预览窗口独立的) */
1919
+ __publicField(this, "tilesets", /* @__PURE__ */ new Map());
1917
1920
  this.currentFOV = opts.fov ?? 50;
1918
1921
  this.ensureViewer();
1919
1922
  this.ensureFOVController();
@@ -1968,8 +1971,201 @@ var PathPreview = class {
1968
1971
  }
1969
1972
  } catch {
1970
1973
  }
1971
- v.scene;
1972
1974
  this.overlayViewer = v;
1975
+ this.syncFromMainViewer();
1976
+ this.disableUserInteraction();
1977
+ }
1978
+ /**
1979
+ * 从主 viewer 同步配置
1980
+ * 共享 Provider(安全)而非 DataSource
1981
+ */
1982
+ syncFromMainViewer() {
1983
+ if (!this.overlayViewer) return;
1984
+ this.syncImageryLayers();
1985
+ this.syncTerrainProvider();
1986
+ this.syncSceneSettings();
1987
+ this.sync3DTiles();
1988
+ }
1989
+ /**
1990
+ * 同步影像图层(共享 ImageryProvider)
1991
+ */
1992
+ syncImageryLayers() {
1993
+ const v = this.overlayViewer;
1994
+ if (!v) return;
1995
+ try {
1996
+ v.imageryLayers?.removeAll?.();
1997
+ const mainImageryLayers = this.mainViewer.imageryLayers;
1998
+ for (let i = 0; i < mainImageryLayers.length; i++) {
1999
+ const layer = mainImageryLayers.get(i);
2000
+ try {
2001
+ v.imageryLayers?.addImageryProvider?.(layer.imageryProvider);
2002
+ } catch {
2003
+ }
2004
+ }
2005
+ } catch (e) {
2006
+ console.warn("[PathPreview] Failed to sync imagery layers:", e);
2007
+ }
2008
+ }
2009
+ /**
2010
+ * 同步地形提供者(共享 TerrainProvider)
2011
+ */
2012
+ syncTerrainProvider() {
2013
+ const v = this.overlayViewer;
2014
+ if (!v) return;
2015
+ try {
2016
+ if (this.mainViewer.terrainProvider) {
2017
+ v.terrainProvider = this.mainViewer.terrainProvider;
2018
+ }
2019
+ } catch (e) {
2020
+ console.warn("[PathPreview] Failed to sync terrain provider:", e);
2021
+ }
2022
+ }
2023
+ /**
2024
+ * 同步 3D Tiles(点云、倾斜摄影等)
2025
+ * 注意:Primitive 不能直接共享,需要创建独立实例
2026
+ * 此方法查找主 viewer 中的 tileset 并尝试使用相同 URL 创建新实例
2027
+ */
2028
+ sync3DTiles() {
2029
+ const v = this.overlayViewer;
2030
+ if (!v) return;
2031
+ const C = this.CesiumNS;
2032
+ const mainPrimitives = this.mainViewer.scene.primitives;
2033
+ try {
2034
+ for (let i = 0; i < mainPrimitives.length; i++) {
2035
+ const primitive = mainPrimitives.get(i);
2036
+ if (primitive && primitive instanceof C.Cesium3DTileset) {
2037
+ const customId = primitive._customId;
2038
+ const url = primitive._url || primitive.resource?.url;
2039
+ if (url && customId && !this.tilesets.has(customId)) {
2040
+ this.add3DTiles(url, customId);
2041
+ }
2042
+ }
2043
+ }
2044
+ } catch (e) {
2045
+ console.warn("[PathPreview] Failed to sync 3DTiles:", e);
2046
+ }
2047
+ }
2048
+ /**
2049
+ * 手动添加 3D Tiles 到预览窗口
2050
+ * @param url 3D Tiles URL
2051
+ * @param id 唯一标识符
2052
+ */
2053
+ async add3DTiles(url, id) {
2054
+ const v = this.overlayViewer;
2055
+ if (!v) return void 0;
2056
+ if (this.tilesets.has(id)) {
2057
+ return this.tilesets.get(id);
2058
+ }
2059
+ const C = this.CesiumNS;
2060
+ try {
2061
+ const tileset = await C.Cesium3DTileset.fromUrl(url, {
2062
+ maximumScreenSpaceError: 16
2063
+ });
2064
+ if (tileset) {
2065
+ tileset._customId = id;
2066
+ tileset._url = url;
2067
+ v.scene.primitives.add(tileset);
2068
+ this.tilesets.set(id, tileset);
2069
+ console.log("[PathPreview] Added 3DTiles:", id);
2070
+ }
2071
+ return tileset;
2072
+ } catch (e) {
2073
+ console.warn("[PathPreview] Failed to add 3DTiles:", url, e);
2074
+ return void 0;
2075
+ }
2076
+ }
2077
+ /**
2078
+ * 移除 3D Tiles
2079
+ */
2080
+ remove3DTiles(id) {
2081
+ const v = this.overlayViewer;
2082
+ if (!v) return;
2083
+ const tileset = this.tilesets.get(id);
2084
+ if (tileset) {
2085
+ try {
2086
+ v.scene.primitives.remove(tileset);
2087
+ } catch {
2088
+ }
2089
+ this.tilesets.delete(id);
2090
+ }
2091
+ }
2092
+ /**
2093
+ * 同步场景设置(Globe、天空、雾效等)
2094
+ */
2095
+ syncSceneSettings() {
2096
+ const v = this.overlayViewer;
2097
+ if (!v) return;
2098
+ const s = v.scene;
2099
+ const mainScene = this.mainViewer.scene;
2100
+ try {
2101
+ if (s.globe && mainScene.globe) {
2102
+ s.globe.show = mainScene.globe.show;
2103
+ s.globe.enableLighting = mainScene.globe.enableLighting;
2104
+ s.globe.baseColor = mainScene.globe.baseColor;
2105
+ s.globe.showGroundAtmosphere = mainScene.globe.showGroundAtmosphere;
2106
+ s.globe.depthTestAgainstTerrain = mainScene.globe.depthTestAgainstTerrain;
2107
+ }
2108
+ if (mainScene.skyBox) {
2109
+ s.skyBox = mainScene.skyBox;
2110
+ } else {
2111
+ s.skyBox = void 0;
2112
+ }
2113
+ if (mainScene.skyAtmosphere) {
2114
+ s.skyAtmosphere.show = mainScene.skyAtmosphere.show;
2115
+ }
2116
+ if (s.fog && mainScene.fog) {
2117
+ s.fog.enabled = mainScene.fog.enabled;
2118
+ s.fog.density = mainScene.fog.density;
2119
+ }
2120
+ v.shadows = this.mainViewer.shadows;
2121
+ if (s.postProcessStages?.fxaa && mainScene.postProcessStages?.fxaa) {
2122
+ s.postProcessStages.fxaa.enabled = mainScene.postProcessStages.fxaa.enabled;
2123
+ }
2124
+ } catch (e) {
2125
+ console.warn("[PathPreview] Failed to sync scene settings:", e);
2126
+ }
2127
+ }
2128
+ /**
2129
+ * 禁用用户交互,相机仅通过 setPose() 控制
2130
+ */
2131
+ disableUserInteraction() {
2132
+ const v = this.overlayViewer;
2133
+ if (!v) return;
2134
+ const s = v.scene;
2135
+ try {
2136
+ const scc = s.screenSpaceCameraController;
2137
+ if (scc) {
2138
+ scc.enableInputs = false;
2139
+ scc.enableRotate = false;
2140
+ scc.enableTranslate = false;
2141
+ scc.enableZoom = false;
2142
+ scc.enableTilt = false;
2143
+ scc.enableLook = false;
2144
+ scc.inertiaSpin = 0;
2145
+ scc.inertiaZoom = 0;
2146
+ scc.inertiaTranslate = 0;
2147
+ }
2148
+ const canvas = s?.canvas ?? v.scene?.canvas;
2149
+ if (canvas && canvas.style) {
2150
+ canvas.style.pointerEvents = "none";
2151
+ try {
2152
+ canvas.setAttribute("tabindex", "-1");
2153
+ } catch {
2154
+ }
2155
+ }
2156
+ v.trackedEntity = void 0;
2157
+ if (v.clock) {
2158
+ v.clock.shouldAnimate = false;
2159
+ }
2160
+ } catch (e) {
2161
+ console.warn("[PathPreview] Failed to disable user interaction:", e);
2162
+ }
2163
+ }
2164
+ /**
2165
+ * 刷新同步(运行时更新)
2166
+ */
2167
+ refresh() {
2168
+ this.syncFromMainViewer();
1973
2169
  }
1974
2170
  /**
1975
2171
  * 创建 FOV 控制器
@@ -2131,30 +2327,63 @@ var PathPreview = class {
2131
2327
  this.fovController.hide();
2132
2328
  }
2133
2329
  }
2134
- // destroy(): void {
2135
- // if (this.destroyed) return;
2136
- // this.destroyed = true;
2137
- // // try {
2138
- // // if (this.footprintEntity) (this.layer.entities as any).remove(this.footprintEntity);
2139
- // // } catch {}
2140
- // this.footprintEntity = undefined;
2141
- //
2142
- // // 销毁 FOV 控制器
2143
- // try {
2144
- // this.fovController?.destroy();
2145
- // } catch {}
2146
- // this.fovController = undefined;
2147
- //
2148
- // try {
2149
- // (this.overlayViewer as any)?.destroy?.();
2150
- // } catch {}
2151
- // this.overlayViewer = undefined;
2152
- // try {
2153
- // if (this.containerEl && this.containerEl.parentElement)
2154
- // this.containerEl.parentElement.removeChild(this.containerEl);
2155
- // } catch {}
2156
- // this.containerEl = undefined;
2157
- // }
2330
+ /**
2331
+ * 显示预览窗口
2332
+ */
2333
+ show() {
2334
+ if (this.containerEl) {
2335
+ this.containerEl.style.display = "block";
2336
+ }
2337
+ }
2338
+ /**
2339
+ * 隐藏预览窗口
2340
+ */
2341
+ hide() {
2342
+ if (this.containerEl) {
2343
+ this.containerEl.style.display = "none";
2344
+ }
2345
+ }
2346
+ /**
2347
+ * 获取预览 viewer 实例
2348
+ */
2349
+ getOverlayViewer() {
2350
+ return this.overlayViewer;
2351
+ }
2352
+ /**
2353
+ * 销毁预览窗口,释放所有资源
2354
+ */
2355
+ destroy() {
2356
+ if (this.destroyed) return;
2357
+ this.destroyed = true;
2358
+ try {
2359
+ this.fovController?.destroy();
2360
+ } catch {
2361
+ }
2362
+ this.fovController = void 0;
2363
+ this.footprintEntity = void 0;
2364
+ try {
2365
+ this.tilesets.forEach((tileset) => {
2366
+ try {
2367
+ this.overlayViewer?.scene?.primitives?.remove?.(tileset);
2368
+ } catch {
2369
+ }
2370
+ });
2371
+ this.tilesets.clear();
2372
+ } catch {
2373
+ }
2374
+ try {
2375
+ this.overlayViewer?.destroy?.();
2376
+ } catch {
2377
+ }
2378
+ this.overlayViewer = void 0;
2379
+ try {
2380
+ if (this.containerEl && this.containerEl.parentElement) {
2381
+ this.containerEl.parentElement.removeChild(this.containerEl);
2382
+ }
2383
+ } catch {
2384
+ }
2385
+ this.containerEl = void 0;
2386
+ }
2158
2387
  };
2159
2388
 
2160
2389
  // src/core/path-manager/FrustumPyramid.ts
@@ -4042,6 +4271,7 @@ var PathEditingEventHandler = class {
4042
4271
  __publicField(this, "contextMenuManager");
4043
4272
  __publicField(this, "vertexDragHandler");
4044
4273
  __publicField(this, "callbacks");
4274
+ __publicField(this, "keydownListener");
4045
4275
  this.CesiumNS = options.CesiumNS;
4046
4276
  this.viewer = options.viewer;
4047
4277
  this.hiddenClimbIndex = options.hiddenClimbIndex;
@@ -4166,6 +4396,37 @@ var PathEditingEventHandler = class {
4166
4396
  }
4167
4397
  this.handleRightClick(movement);
4168
4398
  }, C.ScreenSpaceEventType.RIGHT_CLICK);
4399
+ this.keydownListener = (e) => {
4400
+ if (e.code !== "Space") return;
4401
+ const target = e.target;
4402
+ if (target.tagName === "INPUT" || target.tagName === "TEXTAREA" || target.isContentEditable) {
4403
+ return;
4404
+ }
4405
+ if (this.vertexDragHandler.isDragging()) return;
4406
+ e.preventDefault();
4407
+ this.handleSpaceKeyInsert();
4408
+ };
4409
+ document.addEventListener("keydown", this.keydownListener);
4410
+ }
4411
+ /**
4412
+ * 处理空格键快捷插入航点
4413
+ * 在飞机游标当前位置,将航点添加到所有航点末尾
4414
+ */
4415
+ handleSpaceKeyInsert() {
4416
+ const airplaneCursor = this.callbacks.getAirplaneCursor?.();
4417
+ if (!airplaneCursor) {
4418
+ console.warn("[PathEditingEventHandler] \u7A7A\u683C\u952E\u63D2\u5165\uFF1A\u98DE\u673A\u6E38\u6807\u4E0D\u5B58\u5728");
4419
+ return;
4420
+ }
4421
+ const pose = airplaneCursor.getPose();
4422
+ if (!pose || !pose.position) {
4423
+ console.warn("[PathEditingEventHandler] \u7A7A\u683C\u952E\u63D2\u5165\uFF1A\u65E0\u6CD5\u83B7\u53D6\u6E38\u6807\u59FF\u6001");
4424
+ return;
4425
+ }
4426
+ const positions = this.callbacks.getPositions?.() || [];
4427
+ const insertAt = positions.length;
4428
+ console.log("[PathEditingEventHandler] \u7A7A\u683C\u952E\u5FEB\u6377\u63D2\u5165\u822A\u70B9\uFF0C\u4F4D\u7F6E\u7D22\u5F15:", insertAt);
4429
+ this.handleInsertVertex(insertAt, pose, "after");
4169
4430
  }
4170
4431
  /**
4171
4432
  * 处理右键点击事件
@@ -4180,12 +4441,13 @@ var PathEditingEventHandler = class {
4180
4441
  const entity = picked?.id;
4181
4442
  const airplaneCursor = this.callbacks.getAirplaneCursor?.();
4182
4443
  const vertexIndex = pickVertexIndex(this.viewer, movement.position, this.hiddenClimbIndex);
4444
+ const viewportPosition = this.canvasToViewportPosition(movement.position);
4183
4445
  if (typeof vertexIndex === "number") {
4184
4446
  const menuItems = this.buildVertexContextMenuItems(vertexIndex);
4185
- this.contextMenuManager.show(movement.position, menuItems);
4447
+ this.contextMenuManager.show(viewportPosition, menuItems);
4186
4448
  } else if (airplaneCursor && airplaneCursor.containsEntity(entity)) {
4187
4449
  const menuItems = this.buildAirplaneCursorContextMenuItems();
4188
- this.contextMenuManager.show(movement.position, menuItems);
4450
+ this.contextMenuManager.show(viewportPosition, menuItems);
4189
4451
  }
4190
4452
  } catch (error) {
4191
4453
  console.error("Error handling right click:", error);
@@ -4489,6 +4751,18 @@ var PathEditingEventHandler = class {
4489
4751
  return 0;
4490
4752
  }
4491
4753
  }
4754
+ /**
4755
+ * 将 canvas 坐标转换为视口坐标
4756
+ * Cesium 事件返回的坐标是相对于 canvas 的,而菜单需要相对于视口的坐标
4757
+ */
4758
+ canvasToViewportPosition(canvasPosition) {
4759
+ const canvas = this.viewer.scene.canvas;
4760
+ const rect = canvas.getBoundingClientRect();
4761
+ return {
4762
+ x: canvasPosition.x + rect.left,
4763
+ y: canvasPosition.y + rect.top
4764
+ };
4765
+ }
4492
4766
  /**
4493
4767
  * 🆕 从鼠标事件获取位置
4494
4768
  */
@@ -4514,6 +4788,10 @@ var PathEditingEventHandler = class {
4514
4788
  * 销毁事件处理器
4515
4789
  */
4516
4790
  destroy() {
4791
+ if (this.keydownListener) {
4792
+ document.removeEventListener("keydown", this.keydownListener);
4793
+ this.keydownListener = void 0;
4794
+ }
4517
4795
  try {
4518
4796
  this.vertexDragHandler.destroy();
4519
4797
  } catch {
@@ -6396,6 +6674,98 @@ function renderFlightPath(CesiumNS, viewer, options) {
6396
6674
  }
6397
6675
  return entity;
6398
6676
  }
6677
+ function renderFlightPathPreview(CesiumNS, viewer, options) {
6678
+ const C = CesiumNS;
6679
+ const entity = renderFlightPath(CesiumNS, viewer, options);
6680
+ const vertexLabelManager = entity._vertexLabelManager;
6681
+ let selectedWaypointIndex = options.initialSelectedIndex ?? null;
6682
+ const polyline = entity.polyline;
6683
+ let positions = [];
6684
+ if (polyline && polyline.positions) {
6685
+ const posValue = polyline.positions.getValue?.(C.JulianDate.now());
6686
+ if (Array.isArray(posValue)) {
6687
+ positions = posValue;
6688
+ }
6689
+ }
6690
+ let waypointDataArray = [];
6691
+ try {
6692
+ const adapterOptions = {
6693
+ CesiumNS,
6694
+ ...options.adapterOptions
6695
+ };
6696
+ const converted = convertSinoflyWayline(options.data, adapterOptions);
6697
+ if (converted && converted.waypointData) {
6698
+ waypointDataArray = [...converted.waypointData].sort((a, b) => a.index - b.index);
6699
+ }
6700
+ } catch (e) {
6701
+ console.warn("[renderFlightPathPreview] \u65E0\u6CD5\u83B7\u53D6\u822A\u70B9\u6570\u636E:", e);
6702
+ }
6703
+ const hasHiddenClimb = entity.properties?._hasHiddenClimb?.getValue?.() ?? false;
6704
+ const hiddenClimbIndex = hasHiddenClimb ? 1 : void 0;
6705
+ const updateWaypointHighlight = (newIndex) => {
6706
+ if (!vertexLabelManager || positions.length === 0) return;
6707
+ const editedIndices = /* @__PURE__ */ new Set();
6708
+ vertexLabelManager.recreateAllLabels(positions, editedIndices, newIndex ?? void 0);
6709
+ };
6710
+ if (selectedWaypointIndex !== null) {
6711
+ updateWaypointHighlight(selectedWaypointIndex);
6712
+ }
6713
+ const handler = new C.ScreenSpaceEventHandler(viewer.scene.canvas);
6714
+ handler.setInputAction((movement) => {
6715
+ const pickedObject = viewer.scene.pick(movement.position);
6716
+ if (C.defined(pickedObject) && pickedObject.id) {
6717
+ const pickedEntity = pickedObject.id;
6718
+ const properties = pickedEntity.properties;
6719
+ if (properties) {
6720
+ const type = properties._type?.getValue?.(C.JulianDate.now());
6721
+ const ownerId = properties._ownerId?.getValue?.(C.JulianDate.now());
6722
+ const vertexIndex = properties._vertexIndex?.getValue?.(C.JulianDate.now());
6723
+ if (type === "vertex-label" && ownerId === entity.id && vertexIndex !== void 0) {
6724
+ let displayIndex = vertexIndex;
6725
+ if (hiddenClimbIndex === 1) {
6726
+ if (vertexIndex >= 2) {
6727
+ displayIndex = vertexIndex - 2;
6728
+ }
6729
+ } else {
6730
+ displayIndex = vertexIndex;
6731
+ }
6732
+ selectedWaypointIndex = vertexIndex;
6733
+ updateWaypointHighlight(selectedWaypointIndex);
6734
+ if (options.onWaypointClick) {
6735
+ const waypointData = waypointDataArray.find((wp) => wp.index === vertexIndex);
6736
+ options.onWaypointClick(displayIndex, waypointData);
6737
+ }
6738
+ }
6739
+ }
6740
+ }
6741
+ }, C.ScreenSpaceEventType.LEFT_CLICK);
6742
+ const controller = {
6743
+ setSelectedWaypoint: (index) => {
6744
+ if (index === null) {
6745
+ selectedWaypointIndex = null;
6746
+ updateWaypointHighlight(null);
6747
+ return;
6748
+ }
6749
+ let actualIndex = index;
6750
+ if (hiddenClimbIndex === 1) {
6751
+ actualIndex = index + 2;
6752
+ }
6753
+ selectedWaypointIndex = actualIndex;
6754
+ updateWaypointHighlight(selectedWaypointIndex);
6755
+ },
6756
+ getSelectedWaypoint: () => {
6757
+ if (selectedWaypointIndex === null) return null;
6758
+ if (hiddenClimbIndex === 1) {
6759
+ return selectedWaypointIndex >= 2 ? selectedWaypointIndex - 2 : null;
6760
+ }
6761
+ return selectedWaypointIndex;
6762
+ },
6763
+ destroy: () => {
6764
+ handler.destroy();
6765
+ }
6766
+ };
6767
+ return { entity, controller };
6768
+ }
6399
6769
 
6400
6770
  // src/core/CZMLPathManager.ts
6401
6771
  var _CZMLPathManager = class _CZMLPathManager {
@@ -6479,6 +6849,37 @@ var _CZMLPathManager = class _CZMLPathManager {
6479
6849
  renderFlightPath(options) {
6480
6850
  return renderFlightPath(this.CesiumNS, this.viewer, options);
6481
6851
  }
6852
+ /**
6853
+ * 预览模式渲染飞航路线:支持航点点击高亮
6854
+ *
6855
+ * 与 renderFlightPath 不同,此方法返回一个控制器对象,支持:
6856
+ * - 航点点击事件回调
6857
+ * - 程序化设置选中航点(高亮显示)
6858
+ * - 列表与地图双向联动
6859
+ *
6860
+ * @param options 预览选项
6861
+ * @returns 包含实体和控制器的对象
6862
+ *
6863
+ * @example
6864
+ * ```typescript
6865
+ * const { entity, controller } = pathManager.renderFlightPathPreview({
6866
+ * data: sinoflyData,
6867
+ * onWaypointClick: (index, waypoint) => {
6868
+ * console.log('点击了航点', index, waypoint);
6869
+ * },
6870
+ * initialSelectedIndex: 0
6871
+ * });
6872
+ *
6873
+ * // 程序化设置选中航点
6874
+ * controller.setSelectedWaypoint(2);
6875
+ *
6876
+ * // 销毁
6877
+ * controller.destroy();
6878
+ * ```
6879
+ */
6880
+ renderFlightPathPreview(options) {
6881
+ return renderFlightPathPreview(this.CesiumNS, this.viewer, options);
6882
+ }
6482
6883
  resolveEntity(entityOrId) {
6483
6884
  return typeof entityOrId === "string" ? this.viewer.entities.getById(entityOrId) : entityOrId;
6484
6885
  }
@@ -9368,6 +9769,20 @@ var CZMLManager = class {
9368
9769
  renderFlightPath(options) {
9369
9770
  return this.pathMgr.renderFlightPath(options);
9370
9771
  }
9772
+ /**
9773
+ * 预览模式渲染飞航路线:支持航点点击高亮
9774
+ *
9775
+ * 与 renderFlightPath 不同,此方法返回一个控制器对象,支持:
9776
+ * - 航点点击事件回调
9777
+ * - 程序化设置选中航点(高亮显示)
9778
+ * - 列表与地图双向联动
9779
+ *
9780
+ * @param options 预览选项
9781
+ * @returns 包含实体和控制器的对象
9782
+ */
9783
+ renderFlightPathPreview(options) {
9784
+ return this.pathMgr.renderFlightPathPreview(options);
9785
+ }
9371
9786
  addPathSample(entityOrId, sample) {
9372
9787
  return this.pathMgr.addPathSample(entityOrId, sample);
9373
9788
  }