@jorgmoritz/gis-manager 0.1.49 → 0.1.50
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 +1236 -90
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +559 -2
- package/dist/index.d.ts +559 -2
- package/dist/index.js +1234 -91
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
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.
|
|
14
|
+
version: "0.1.50"};
|
|
15
15
|
|
|
16
16
|
// src/utils/version.ts
|
|
17
17
|
var version = package_default.version;
|
|
@@ -1693,6 +1693,765 @@ var CameraManager = class {
|
|
|
1693
1693
|
}
|
|
1694
1694
|
};
|
|
1695
1695
|
|
|
1696
|
+
// src/core/terrain-manager/TerrainManager.ts
|
|
1697
|
+
var TerrainManager = class {
|
|
1698
|
+
constructor(CesiumNS, viewer) {
|
|
1699
|
+
this.CesiumNS = CesiumNS;
|
|
1700
|
+
this.viewer = viewer;
|
|
1701
|
+
/** 已注册的地形源 */
|
|
1702
|
+
__publicField(this, "sources", /* @__PURE__ */ new Map());
|
|
1703
|
+
/** 当前激活的地形源 ID */
|
|
1704
|
+
__publicField(this, "activeSourceId", null);
|
|
1705
|
+
/** 事件发射器 */
|
|
1706
|
+
__publicField(this, "events", new Emitter());
|
|
1707
|
+
}
|
|
1708
|
+
/**
|
|
1709
|
+
* 注册地形源
|
|
1710
|
+
* @param config 地形源配置
|
|
1711
|
+
*/
|
|
1712
|
+
register(config) {
|
|
1713
|
+
if (this.sources.has(config.id)) {
|
|
1714
|
+
console.warn(`[TerrainManager] \u5730\u5F62\u6E90 "${config.id}" \u5DF2\u5B58\u5728\uFF0C\u5C06\u88AB\u8986\u76D6`);
|
|
1715
|
+
}
|
|
1716
|
+
const normalizedConfig = {
|
|
1717
|
+
requestVertexNormals: true,
|
|
1718
|
+
requestWaterMask: true,
|
|
1719
|
+
priority: 0,
|
|
1720
|
+
...config
|
|
1721
|
+
};
|
|
1722
|
+
this.sources.set(config.id, normalizedConfig);
|
|
1723
|
+
this.events.emit({ registered: { config: normalizedConfig } });
|
|
1724
|
+
console.log(`[TerrainManager] \u5DF2\u6CE8\u518C\u5730\u5F62\u6E90: ${config.id}`);
|
|
1725
|
+
}
|
|
1726
|
+
/**
|
|
1727
|
+
* 批量注册地形源
|
|
1728
|
+
* @param configs 地形源配置数组
|
|
1729
|
+
*/
|
|
1730
|
+
registerBatch(configs) {
|
|
1731
|
+
configs.forEach((config) => this.register(config));
|
|
1732
|
+
}
|
|
1733
|
+
/**
|
|
1734
|
+
* 切换到指定地形源
|
|
1735
|
+
* @param sourceId 地形源 ID
|
|
1736
|
+
* @param options 切换选项
|
|
1737
|
+
*/
|
|
1738
|
+
async switchTo(sourceId, options) {
|
|
1739
|
+
const config = this.sources.get(sourceId);
|
|
1740
|
+
if (!config) {
|
|
1741
|
+
const error = `\u5730\u5F62\u6E90 "${sourceId}" \u672A\u6CE8\u518C`;
|
|
1742
|
+
console.error(`[TerrainManager] ${error}`);
|
|
1743
|
+
return { success: false, activeId: this.activeSourceId, error };
|
|
1744
|
+
}
|
|
1745
|
+
try {
|
|
1746
|
+
const provider = await this.createTerrainProvider(config);
|
|
1747
|
+
if (!provider) {
|
|
1748
|
+
throw new Error("\u65E0\u6CD5\u521B\u5EFA\u5730\u5F62\u63D0\u4F9B\u8005");
|
|
1749
|
+
}
|
|
1750
|
+
const previousId = this.activeSourceId;
|
|
1751
|
+
this.viewer.terrainProvider = provider;
|
|
1752
|
+
this.activeSourceId = sourceId;
|
|
1753
|
+
this.events.emit({ switched: { fromId: previousId, toId: sourceId } });
|
|
1754
|
+
console.log(`[TerrainManager] \u5DF2\u5207\u6362\u5730\u5F62: ${previousId} -> ${sourceId}`);
|
|
1755
|
+
if (options?.flyTo && config.bounds) {
|
|
1756
|
+
await this.flyToBounds(config.bounds, options.flyDuration);
|
|
1757
|
+
}
|
|
1758
|
+
return { success: true, activeId: sourceId };
|
|
1759
|
+
} catch (error) {
|
|
1760
|
+
const errMsg = error instanceof Error ? error.message : String(error);
|
|
1761
|
+
console.error(`[TerrainManager] \u5207\u6362\u5730\u5F62\u5931\u8D25:`, error);
|
|
1762
|
+
this.events.emit({ error: { id: sourceId, error } });
|
|
1763
|
+
return { success: false, activeId: this.activeSourceId, error: errMsg };
|
|
1764
|
+
}
|
|
1765
|
+
}
|
|
1766
|
+
/**
|
|
1767
|
+
* 获取当前激活的地形源配置
|
|
1768
|
+
*/
|
|
1769
|
+
getActive() {
|
|
1770
|
+
if (!this.activeSourceId) return null;
|
|
1771
|
+
return this.sources.get(this.activeSourceId) ?? null;
|
|
1772
|
+
}
|
|
1773
|
+
/**
|
|
1774
|
+
* 获取当前激活的地形源 ID
|
|
1775
|
+
*/
|
|
1776
|
+
getActiveId() {
|
|
1777
|
+
return this.activeSourceId;
|
|
1778
|
+
}
|
|
1779
|
+
/**
|
|
1780
|
+
* 获取指定地形源配置
|
|
1781
|
+
* @param sourceId 地形源 ID
|
|
1782
|
+
*/
|
|
1783
|
+
get(sourceId) {
|
|
1784
|
+
return this.sources.get(sourceId);
|
|
1785
|
+
}
|
|
1786
|
+
/**
|
|
1787
|
+
* 获取所有已注册的地形源
|
|
1788
|
+
*/
|
|
1789
|
+
list() {
|
|
1790
|
+
return Array.from(this.sources.values());
|
|
1791
|
+
}
|
|
1792
|
+
/**
|
|
1793
|
+
* 检查地形源是否已注册
|
|
1794
|
+
* @param sourceId 地形源 ID
|
|
1795
|
+
*/
|
|
1796
|
+
has(sourceId) {
|
|
1797
|
+
return this.sources.has(sourceId);
|
|
1798
|
+
}
|
|
1799
|
+
/**
|
|
1800
|
+
* 移除地形源
|
|
1801
|
+
* @param sourceId 地形源 ID
|
|
1802
|
+
*/
|
|
1803
|
+
remove(sourceId) {
|
|
1804
|
+
if (!this.sources.has(sourceId)) {
|
|
1805
|
+
return false;
|
|
1806
|
+
}
|
|
1807
|
+
if (this.activeSourceId === sourceId) {
|
|
1808
|
+
this.reset();
|
|
1809
|
+
}
|
|
1810
|
+
this.sources.delete(sourceId);
|
|
1811
|
+
this.events.emit({ removed: { id: sourceId } });
|
|
1812
|
+
console.log(`[TerrainManager] \u5DF2\u79FB\u9664\u5730\u5F62\u6E90: ${sourceId}`);
|
|
1813
|
+
return true;
|
|
1814
|
+
}
|
|
1815
|
+
/**
|
|
1816
|
+
* 重置为椭球体(无地形)
|
|
1817
|
+
*/
|
|
1818
|
+
reset() {
|
|
1819
|
+
const C = this.CesiumNS;
|
|
1820
|
+
const previousId = this.activeSourceId;
|
|
1821
|
+
this.viewer.terrainProvider = new C.EllipsoidTerrainProvider();
|
|
1822
|
+
this.activeSourceId = null;
|
|
1823
|
+
this.events.emit({ switched: { fromId: previousId, toId: null } });
|
|
1824
|
+
console.log(`[TerrainManager] \u5DF2\u91CD\u7F6E\u5730\u5F62\u4E3A\u692D\u7403\u4F53`);
|
|
1825
|
+
}
|
|
1826
|
+
/**
|
|
1827
|
+
* 清除所有已注册的地形源
|
|
1828
|
+
*/
|
|
1829
|
+
clear() {
|
|
1830
|
+
this.reset();
|
|
1831
|
+
this.sources.clear();
|
|
1832
|
+
console.log(`[TerrainManager] \u5DF2\u6E05\u9664\u6240\u6709\u5730\u5F62\u6E90`);
|
|
1833
|
+
}
|
|
1834
|
+
/**
|
|
1835
|
+
* 销毁管理器
|
|
1836
|
+
*/
|
|
1837
|
+
destroy() {
|
|
1838
|
+
this.clear();
|
|
1839
|
+
}
|
|
1840
|
+
/**
|
|
1841
|
+
* 创建地形提供者
|
|
1842
|
+
*/
|
|
1843
|
+
async createTerrainProvider(config) {
|
|
1844
|
+
const C = this.CesiumNS;
|
|
1845
|
+
switch (config.providerType) {
|
|
1846
|
+
case "ellipsoid":
|
|
1847
|
+
return new C.EllipsoidTerrainProvider();
|
|
1848
|
+
case "cesium-ion": {
|
|
1849
|
+
const assetId = config.ionAssetId ?? 1;
|
|
1850
|
+
const IonResource = C.IonResource ?? C.Resource;
|
|
1851
|
+
if (IonResource?.fromAssetId) {
|
|
1852
|
+
const resource = await IonResource.fromAssetId(assetId);
|
|
1853
|
+
return await C.CesiumTerrainProvider.fromUrl(resource, {
|
|
1854
|
+
requestVertexNormals: config.requestVertexNormals,
|
|
1855
|
+
requestWaterMask: config.requestWaterMask
|
|
1856
|
+
});
|
|
1857
|
+
}
|
|
1858
|
+
if (C.createWorldTerrain) {
|
|
1859
|
+
return C.createWorldTerrain({
|
|
1860
|
+
requestVertexNormals: config.requestVertexNormals,
|
|
1861
|
+
requestWaterMask: config.requestWaterMask
|
|
1862
|
+
});
|
|
1863
|
+
}
|
|
1864
|
+
return void 0;
|
|
1865
|
+
}
|
|
1866
|
+
case "url": {
|
|
1867
|
+
if (!config.url) {
|
|
1868
|
+
throw new Error("URL \u7C7B\u578B\u5730\u5F62\u6E90\u5FC5\u987B\u63D0\u4F9B url");
|
|
1869
|
+
}
|
|
1870
|
+
return await C.CesiumTerrainProvider.fromUrl(config.url, {
|
|
1871
|
+
requestVertexNormals: config.requestVertexNormals,
|
|
1872
|
+
requestWaterMask: config.requestWaterMask
|
|
1873
|
+
});
|
|
1874
|
+
}
|
|
1875
|
+
default:
|
|
1876
|
+
return void 0;
|
|
1877
|
+
}
|
|
1878
|
+
}
|
|
1879
|
+
/**
|
|
1880
|
+
* 飞行到指定范围
|
|
1881
|
+
*/
|
|
1882
|
+
async flyToBounds(bounds, duration = 2) {
|
|
1883
|
+
const C = this.CesiumNS;
|
|
1884
|
+
const [west, south, east, north] = bounds;
|
|
1885
|
+
const centerLon = (west + east) / 2;
|
|
1886
|
+
const centerLat = (south + north) / 2;
|
|
1887
|
+
const lonSpan = Math.abs(east - west);
|
|
1888
|
+
const latSpan = Math.abs(north - south);
|
|
1889
|
+
const maxSpan = Math.max(lonSpan, latSpan);
|
|
1890
|
+
const cameraHeight = Math.max(maxSpan * 111e3 * 1.5, 1e3);
|
|
1891
|
+
let terrainHeight = 0;
|
|
1892
|
+
try {
|
|
1893
|
+
const terrainProvider = this.viewer.terrainProvider;
|
|
1894
|
+
if (terrainProvider && !(terrainProvider instanceof C.EllipsoidTerrainProvider)) {
|
|
1895
|
+
const positions = [C.Cartographic.fromDegrees(centerLon, centerLat)];
|
|
1896
|
+
const sampledPositions = await C.sampleTerrainMostDetailed(terrainProvider, positions);
|
|
1897
|
+
terrainHeight = sampledPositions[0]?.height || 0;
|
|
1898
|
+
}
|
|
1899
|
+
} catch {
|
|
1900
|
+
}
|
|
1901
|
+
this.viewer.camera.flyTo({
|
|
1902
|
+
destination: C.Cartesian3.fromDegrees(centerLon, centerLat, terrainHeight + cameraHeight),
|
|
1903
|
+
orientation: {
|
|
1904
|
+
heading: C.Math.toRadians(0),
|
|
1905
|
+
pitch: C.Math.toRadians(-45),
|
|
1906
|
+
roll: 0
|
|
1907
|
+
},
|
|
1908
|
+
duration
|
|
1909
|
+
});
|
|
1910
|
+
}
|
|
1911
|
+
};
|
|
1912
|
+
|
|
1913
|
+
// src/core/imagery-manager/ImageryManager.ts
|
|
1914
|
+
var ImageryManager = class {
|
|
1915
|
+
constructor(CesiumNS, viewer) {
|
|
1916
|
+
this.CesiumNS = CesiumNS;
|
|
1917
|
+
this.viewer = viewer;
|
|
1918
|
+
/** 已加载的图层 */
|
|
1919
|
+
__publicField(this, "layers", /* @__PURE__ */ new Map());
|
|
1920
|
+
/** 事件发射器 */
|
|
1921
|
+
__publicField(this, "events", new Emitter());
|
|
1922
|
+
}
|
|
1923
|
+
/**
|
|
1924
|
+
* 添加影像图层
|
|
1925
|
+
* @param config 图层配置
|
|
1926
|
+
* @param options 加载选项
|
|
1927
|
+
*/
|
|
1928
|
+
async add(config, options) {
|
|
1929
|
+
if (this.layers.has(config.id)) {
|
|
1930
|
+
console.warn(`[ImageryManager] \u56FE\u5C42 "${config.id}" \u5DF2\u5B58\u5728\uFF0C\u5C06\u88AB\u66FF\u6362`);
|
|
1931
|
+
this.remove(config.id);
|
|
1932
|
+
}
|
|
1933
|
+
try {
|
|
1934
|
+
const provider = this.createImageryProvider(config);
|
|
1935
|
+
if (!provider) {
|
|
1936
|
+
throw new Error("\u65E0\u6CD5\u521B\u5EFA\u5F71\u50CF\u63D0\u4F9B\u8005");
|
|
1937
|
+
}
|
|
1938
|
+
const layer = this.viewer.imageryLayers.addImageryProvider(provider);
|
|
1939
|
+
layer.alpha = config.opacity ?? 1;
|
|
1940
|
+
layer.show = config.show ?? true;
|
|
1941
|
+
layer._customId = config.id;
|
|
1942
|
+
this.layers.set(config.id, { config, layer });
|
|
1943
|
+
this.applyZIndex(config.id, config.zIndex ?? 0);
|
|
1944
|
+
this.events.emit({ added: { config } });
|
|
1945
|
+
console.log(`[ImageryManager] \u5DF2\u6DFB\u52A0\u56FE\u5C42: ${config.id}`);
|
|
1946
|
+
if (options?.flyTo && config.bounds) {
|
|
1947
|
+
await this.flyToBounds(config.bounds, options.flyDuration);
|
|
1948
|
+
}
|
|
1949
|
+
return { id: config.id, success: true };
|
|
1950
|
+
} catch (error) {
|
|
1951
|
+
const errMsg = error instanceof Error ? error.message : String(error);
|
|
1952
|
+
console.error(`[ImageryManager] \u6DFB\u52A0\u56FE\u5C42\u5931\u8D25:`, error);
|
|
1953
|
+
this.events.emit({ error: { id: config.id, error } });
|
|
1954
|
+
return { id: config.id, success: false, error: errMsg };
|
|
1955
|
+
}
|
|
1956
|
+
}
|
|
1957
|
+
/**
|
|
1958
|
+
* 批量添加影像图层
|
|
1959
|
+
* @param configs 图层配置数组
|
|
1960
|
+
* @param options 加载选项
|
|
1961
|
+
*/
|
|
1962
|
+
async addBatch(configs, options) {
|
|
1963
|
+
const sorted = [...configs].sort((a, b) => (a.zIndex ?? 0) - (b.zIndex ?? 0));
|
|
1964
|
+
const results = [];
|
|
1965
|
+
for (const config of sorted) {
|
|
1966
|
+
const result = await this.add(config, options);
|
|
1967
|
+
results.push(result);
|
|
1968
|
+
}
|
|
1969
|
+
return results;
|
|
1970
|
+
}
|
|
1971
|
+
/**
|
|
1972
|
+
* 移除影像图层
|
|
1973
|
+
* @param layerId 图层 ID
|
|
1974
|
+
*/
|
|
1975
|
+
remove(layerId) {
|
|
1976
|
+
const entry = this.layers.get(layerId);
|
|
1977
|
+
if (!entry) {
|
|
1978
|
+
return false;
|
|
1979
|
+
}
|
|
1980
|
+
this.viewer.imageryLayers.remove(entry.layer, true);
|
|
1981
|
+
this.layers.delete(layerId);
|
|
1982
|
+
this.events.emit({ removed: { id: layerId } });
|
|
1983
|
+
console.log(`[ImageryManager] \u5DF2\u79FB\u9664\u56FE\u5C42: ${layerId}`);
|
|
1984
|
+
return true;
|
|
1985
|
+
}
|
|
1986
|
+
/**
|
|
1987
|
+
* 设置图层可见性
|
|
1988
|
+
* @param layerId 图层 ID
|
|
1989
|
+
* @param visible 是否可见
|
|
1990
|
+
*/
|
|
1991
|
+
setVisible(layerId, visible) {
|
|
1992
|
+
const entry = this.layers.get(layerId);
|
|
1993
|
+
if (!entry) {
|
|
1994
|
+
return false;
|
|
1995
|
+
}
|
|
1996
|
+
entry.layer.show = visible;
|
|
1997
|
+
entry.config.show = visible;
|
|
1998
|
+
this.events.emit({ visibilityChanged: { id: layerId, visible } });
|
|
1999
|
+
return true;
|
|
2000
|
+
}
|
|
2001
|
+
/**
|
|
2002
|
+
* 设置图层透明度
|
|
2003
|
+
* @param layerId 图层 ID
|
|
2004
|
+
* @param opacity 透明度 0-1
|
|
2005
|
+
*/
|
|
2006
|
+
setOpacity(layerId, opacity) {
|
|
2007
|
+
const entry = this.layers.get(layerId);
|
|
2008
|
+
if (!entry) {
|
|
2009
|
+
return false;
|
|
2010
|
+
}
|
|
2011
|
+
const clampedOpacity = Math.max(0, Math.min(1, opacity));
|
|
2012
|
+
entry.layer.alpha = clampedOpacity;
|
|
2013
|
+
entry.config.opacity = clampedOpacity;
|
|
2014
|
+
this.events.emit({ opacityChanged: { id: layerId, opacity: clampedOpacity } });
|
|
2015
|
+
return true;
|
|
2016
|
+
}
|
|
2017
|
+
/**
|
|
2018
|
+
* 调整图层顺序
|
|
2019
|
+
* @param layerId 图层 ID
|
|
2020
|
+
* @param zIndex 新的层级
|
|
2021
|
+
*/
|
|
2022
|
+
reorder(layerId, zIndex) {
|
|
2023
|
+
const entry = this.layers.get(layerId);
|
|
2024
|
+
if (!entry) {
|
|
2025
|
+
return false;
|
|
2026
|
+
}
|
|
2027
|
+
entry.config.zIndex = zIndex;
|
|
2028
|
+
this.applyZIndex(layerId, zIndex);
|
|
2029
|
+
this.events.emit({ orderChanged: { id: layerId, zIndex } });
|
|
2030
|
+
return true;
|
|
2031
|
+
}
|
|
2032
|
+
/**
|
|
2033
|
+
* 将图层移到最上层
|
|
2034
|
+
* @param layerId 图层 ID
|
|
2035
|
+
*/
|
|
2036
|
+
bringToTop(layerId) {
|
|
2037
|
+
const entry = this.layers.get(layerId);
|
|
2038
|
+
if (!entry) {
|
|
2039
|
+
return false;
|
|
2040
|
+
}
|
|
2041
|
+
const imageryLayers = this.viewer.imageryLayers;
|
|
2042
|
+
const currentIndex = imageryLayers.indexOf(entry.layer);
|
|
2043
|
+
if (currentIndex >= 0 && currentIndex < imageryLayers.length - 1) {
|
|
2044
|
+
for (let i = currentIndex; i < imageryLayers.length - 1; i++) {
|
|
2045
|
+
imageryLayers.raise(entry.layer);
|
|
2046
|
+
}
|
|
2047
|
+
}
|
|
2048
|
+
const maxZIndex = Math.max(...Array.from(this.layers.values()).map((e) => e.config.zIndex ?? 0));
|
|
2049
|
+
entry.config.zIndex = maxZIndex + 1;
|
|
2050
|
+
this.events.emit({ orderChanged: { id: layerId, zIndex: entry.config.zIndex } });
|
|
2051
|
+
return true;
|
|
2052
|
+
}
|
|
2053
|
+
/**
|
|
2054
|
+
* 将图层移到最下层
|
|
2055
|
+
* @param layerId 图层 ID
|
|
2056
|
+
*/
|
|
2057
|
+
sendToBottom(layerId) {
|
|
2058
|
+
const entry = this.layers.get(layerId);
|
|
2059
|
+
if (!entry) {
|
|
2060
|
+
return false;
|
|
2061
|
+
}
|
|
2062
|
+
const imageryLayers = this.viewer.imageryLayers;
|
|
2063
|
+
const currentIndex = imageryLayers.indexOf(entry.layer);
|
|
2064
|
+
if (currentIndex > 0) {
|
|
2065
|
+
for (let i = currentIndex; i > 0; i--) {
|
|
2066
|
+
imageryLayers.lower(entry.layer);
|
|
2067
|
+
}
|
|
2068
|
+
}
|
|
2069
|
+
const minZIndex = Math.min(...Array.from(this.layers.values()).map((e) => e.config.zIndex ?? 0));
|
|
2070
|
+
entry.config.zIndex = minZIndex - 1;
|
|
2071
|
+
this.events.emit({ orderChanged: { id: layerId, zIndex: entry.config.zIndex } });
|
|
2072
|
+
return true;
|
|
2073
|
+
}
|
|
2074
|
+
/**
|
|
2075
|
+
* 获取图层配置
|
|
2076
|
+
* @param layerId 图层 ID
|
|
2077
|
+
*/
|
|
2078
|
+
get(layerId) {
|
|
2079
|
+
return this.layers.get(layerId)?.config;
|
|
2080
|
+
}
|
|
2081
|
+
/**
|
|
2082
|
+
* 获取底层 Cesium ImageryLayer
|
|
2083
|
+
* @param layerId 图层 ID
|
|
2084
|
+
*/
|
|
2085
|
+
getLayer(layerId) {
|
|
2086
|
+
return this.layers.get(layerId)?.layer;
|
|
2087
|
+
}
|
|
2088
|
+
/**
|
|
2089
|
+
* 获取所有图层配置
|
|
2090
|
+
*/
|
|
2091
|
+
list() {
|
|
2092
|
+
return Array.from(this.layers.values()).map((e) => e.config);
|
|
2093
|
+
}
|
|
2094
|
+
/**
|
|
2095
|
+
* 获取所有底图图层
|
|
2096
|
+
*/
|
|
2097
|
+
listBaseLayers() {
|
|
2098
|
+
return this.list().filter((c) => c.layerType === "base");
|
|
2099
|
+
}
|
|
2100
|
+
/**
|
|
2101
|
+
* 获取所有叠加图层
|
|
2102
|
+
*/
|
|
2103
|
+
listOverlays() {
|
|
2104
|
+
return this.list().filter((c) => c.layerType === "overlay");
|
|
2105
|
+
}
|
|
2106
|
+
/**
|
|
2107
|
+
* 检查图层是否存在
|
|
2108
|
+
* @param layerId 图层 ID
|
|
2109
|
+
*/
|
|
2110
|
+
has(layerId) {
|
|
2111
|
+
return this.layers.has(layerId);
|
|
2112
|
+
}
|
|
2113
|
+
/**
|
|
2114
|
+
* 清除所有叠加层(保留底图)
|
|
2115
|
+
*/
|
|
2116
|
+
clearOverlays() {
|
|
2117
|
+
const overlays = this.listOverlays();
|
|
2118
|
+
overlays.forEach((config) => this.remove(config.id));
|
|
2119
|
+
console.log(`[ImageryManager] \u5DF2\u6E05\u9664 ${overlays.length} \u4E2A\u53E0\u52A0\u5C42`);
|
|
2120
|
+
}
|
|
2121
|
+
/**
|
|
2122
|
+
* 清除所有图层
|
|
2123
|
+
*/
|
|
2124
|
+
clear() {
|
|
2125
|
+
const ids = Array.from(this.layers.keys());
|
|
2126
|
+
ids.forEach((id) => this.remove(id));
|
|
2127
|
+
console.log(`[ImageryManager] \u5DF2\u6E05\u9664\u6240\u6709\u56FE\u5C42`);
|
|
2128
|
+
}
|
|
2129
|
+
/**
|
|
2130
|
+
* 销毁管理器
|
|
2131
|
+
*/
|
|
2132
|
+
destroy() {
|
|
2133
|
+
this.clear();
|
|
2134
|
+
}
|
|
2135
|
+
/**
|
|
2136
|
+
* 创建影像提供者
|
|
2137
|
+
*/
|
|
2138
|
+
createImageryProvider(config) {
|
|
2139
|
+
const C = this.CesiumNS;
|
|
2140
|
+
const autoDetectedConfig = this.autoDetectTiandituWmts(config);
|
|
2141
|
+
let rectangle;
|
|
2142
|
+
if (autoDetectedConfig.bounds) {
|
|
2143
|
+
let bounds = autoDetectedConfig.bounds;
|
|
2144
|
+
if (Math.abs(bounds[1]) > 90 && Math.abs(bounds[2]) <= 90) {
|
|
2145
|
+
bounds = [bounds[0], bounds[2], bounds[1], bounds[3]];
|
|
2146
|
+
}
|
|
2147
|
+
rectangle = C.Rectangle.fromDegrees(bounds[0], bounds[1], bounds[2], bounds[3]);
|
|
2148
|
+
}
|
|
2149
|
+
const minLevel = autoDetectedConfig.zoomRange?.min;
|
|
2150
|
+
const maxLevel = autoDetectedConfig.zoomRange?.max;
|
|
2151
|
+
switch (autoDetectedConfig.provider) {
|
|
2152
|
+
case "urlTemplate":
|
|
2153
|
+
case "tms":
|
|
2154
|
+
return new C.UrlTemplateImageryProvider({
|
|
2155
|
+
url: autoDetectedConfig.url,
|
|
2156
|
+
minimumLevel: minLevel,
|
|
2157
|
+
maximumLevel: maxLevel,
|
|
2158
|
+
rectangle,
|
|
2159
|
+
subdomains: autoDetectedConfig.subdomains
|
|
2160
|
+
});
|
|
2161
|
+
case "wmts":
|
|
2162
|
+
if (!autoDetectedConfig.wmts) {
|
|
2163
|
+
throw new Error("WMTS \u63D0\u4F9B\u8005\u9700\u8981 wmts \u914D\u7F6E");
|
|
2164
|
+
}
|
|
2165
|
+
return new C.WebMapTileServiceImageryProvider({
|
|
2166
|
+
url: autoDetectedConfig.url,
|
|
2167
|
+
layer: autoDetectedConfig.wmts.layer,
|
|
2168
|
+
style: autoDetectedConfig.wmts.style ?? "default",
|
|
2169
|
+
tileMatrixSetID: autoDetectedConfig.wmts.tileMatrixSetID,
|
|
2170
|
+
format: autoDetectedConfig.wmts.format ?? "image/png",
|
|
2171
|
+
subdomains: autoDetectedConfig.subdomains,
|
|
2172
|
+
tilingScheme: new C.WebMercatorTilingScheme(),
|
|
2173
|
+
maximumLevel: maxLevel
|
|
2174
|
+
});
|
|
2175
|
+
case "wms":
|
|
2176
|
+
if (!autoDetectedConfig.wms) {
|
|
2177
|
+
throw new Error("WMS \u63D0\u4F9B\u8005\u9700\u8981 wms \u914D\u7F6E");
|
|
2178
|
+
}
|
|
2179
|
+
return new C.WebMapServiceImageryProvider({
|
|
2180
|
+
url: autoDetectedConfig.url,
|
|
2181
|
+
layers: autoDetectedConfig.wms.layers,
|
|
2182
|
+
parameters: autoDetectedConfig.wms.parameters,
|
|
2183
|
+
rectangle
|
|
2184
|
+
});
|
|
2185
|
+
case "arcgis":
|
|
2186
|
+
return new C.ArcGisMapServerImageryProvider({
|
|
2187
|
+
url: autoDetectedConfig.url
|
|
2188
|
+
});
|
|
2189
|
+
default:
|
|
2190
|
+
return void 0;
|
|
2191
|
+
}
|
|
2192
|
+
}
|
|
2193
|
+
/**
|
|
2194
|
+
* 自动检测天地图 WMTS 服务并补充配置
|
|
2195
|
+
*/
|
|
2196
|
+
autoDetectTiandituWmts(config) {
|
|
2197
|
+
const url = config.url;
|
|
2198
|
+
const isTiandituWmts = url.includes("tianditu.gov.cn") && url.includes("wmts");
|
|
2199
|
+
if (!isTiandituWmts) {
|
|
2200
|
+
return config;
|
|
2201
|
+
}
|
|
2202
|
+
if (config.provider === "wmts" && config.wmts) {
|
|
2203
|
+
return config;
|
|
2204
|
+
}
|
|
2205
|
+
const tk = url.match(/tk=([^&]+)/)?.[1] || "f44fcec420c3eb1c56656e9a22dabb17";
|
|
2206
|
+
let layer = "img";
|
|
2207
|
+
let baseUrl = url;
|
|
2208
|
+
if (url.includes("/img_w/")) {
|
|
2209
|
+
layer = "img";
|
|
2210
|
+
baseUrl = `https://t{s}.tianditu.gov.cn/img_w/wmts?tk=${tk}`;
|
|
2211
|
+
} else if (url.includes("/cia_w/")) {
|
|
2212
|
+
layer = "cia";
|
|
2213
|
+
baseUrl = `https://t{s}.tianditu.gov.cn/cia_w/wmts?tk=${tk}`;
|
|
2214
|
+
} else if (url.includes("/vec_w/")) {
|
|
2215
|
+
layer = "vec";
|
|
2216
|
+
baseUrl = `https://t{s}.tianditu.gov.cn/vec_w/wmts?tk=${tk}`;
|
|
2217
|
+
} else if (url.includes("/cva_w/")) {
|
|
2218
|
+
layer = "cva";
|
|
2219
|
+
baseUrl = `https://t{s}.tianditu.gov.cn/cva_w/wmts?tk=${tk}`;
|
|
2220
|
+
} else if (url.includes("/ter_w/")) {
|
|
2221
|
+
layer = "ter";
|
|
2222
|
+
baseUrl = `https://t{s}.tianditu.gov.cn/ter_w/wmts?tk=${tk}`;
|
|
2223
|
+
} else if (url.includes("/cta_w/")) {
|
|
2224
|
+
layer = "cta";
|
|
2225
|
+
baseUrl = `https://t{s}.tianditu.gov.cn/cta_w/wmts?tk=${tk}`;
|
|
2226
|
+
}
|
|
2227
|
+
console.log(`[ImageryManager] \u81EA\u52A8\u68C0\u6D4B\u5230\u5929\u5730\u56FE WMTS \u670D\u52A1: layer=${layer}`);
|
|
2228
|
+
return {
|
|
2229
|
+
...config,
|
|
2230
|
+
url: baseUrl,
|
|
2231
|
+
provider: "wmts",
|
|
2232
|
+
subdomains: config.subdomains || ["0", "1", "2", "3", "4", "5", "6", "7"],
|
|
2233
|
+
wmts: {
|
|
2234
|
+
layer,
|
|
2235
|
+
style: "default",
|
|
2236
|
+
tileMatrixSetID: "w",
|
|
2237
|
+
format: "tiles"
|
|
2238
|
+
},
|
|
2239
|
+
zoomRange: config.zoomRange || { max: 18 }
|
|
2240
|
+
};
|
|
2241
|
+
}
|
|
2242
|
+
/**
|
|
2243
|
+
* 应用图层顺序
|
|
2244
|
+
*/
|
|
2245
|
+
applyZIndex(layerId, zIndex) {
|
|
2246
|
+
const entry = this.layers.get(layerId);
|
|
2247
|
+
if (!entry) return;
|
|
2248
|
+
const imageryLayers = this.viewer.imageryLayers;
|
|
2249
|
+
const currentIndex = imageryLayers.indexOf(entry.layer);
|
|
2250
|
+
if (currentIndex < 0) return;
|
|
2251
|
+
const sortedEntries = Array.from(this.layers.entries()).map(([id, e]) => ({ id, zIndex: e.config.zIndex ?? 0, layer: e.layer })).sort((a, b) => a.zIndex - b.zIndex);
|
|
2252
|
+
const targetIndex = sortedEntries.findIndex((e) => e.id === layerId);
|
|
2253
|
+
if (targetIndex < 0) return;
|
|
2254
|
+
const diff = targetIndex - currentIndex;
|
|
2255
|
+
if (diff > 0) {
|
|
2256
|
+
for (let i = 0; i < diff; i++) {
|
|
2257
|
+
imageryLayers.raise(entry.layer);
|
|
2258
|
+
}
|
|
2259
|
+
} else if (diff < 0) {
|
|
2260
|
+
for (let i = 0; i < -diff; i++) {
|
|
2261
|
+
imageryLayers.lower(entry.layer);
|
|
2262
|
+
}
|
|
2263
|
+
}
|
|
2264
|
+
}
|
|
2265
|
+
/**
|
|
2266
|
+
* 飞行到指定范围
|
|
2267
|
+
*/
|
|
2268
|
+
async flyToBounds(bounds, duration = 2) {
|
|
2269
|
+
const C = this.CesiumNS;
|
|
2270
|
+
const [west, south, east, north] = bounds;
|
|
2271
|
+
const centerLon = (west + east) / 2;
|
|
2272
|
+
const centerLat = (south + north) / 2;
|
|
2273
|
+
const lonSpan = Math.abs(east - west);
|
|
2274
|
+
const latSpan = Math.abs(north - south);
|
|
2275
|
+
const maxSpan = Math.max(lonSpan, latSpan);
|
|
2276
|
+
const cameraHeight = Math.max(maxSpan * 111e3 * 1.2, 500);
|
|
2277
|
+
this.viewer.camera.flyTo({
|
|
2278
|
+
destination: C.Cartesian3.fromDegrees(centerLon, centerLat, cameraHeight),
|
|
2279
|
+
orientation: {
|
|
2280
|
+
heading: C.Math.toRadians(0),
|
|
2281
|
+
pitch: C.Math.toRadians(-90),
|
|
2282
|
+
roll: 0
|
|
2283
|
+
},
|
|
2284
|
+
duration
|
|
2285
|
+
});
|
|
2286
|
+
}
|
|
2287
|
+
};
|
|
2288
|
+
|
|
2289
|
+
// src/core/tileset-manager/TilesetManager.ts
|
|
2290
|
+
var TilesetManager = class {
|
|
2291
|
+
constructor(CesiumNS, viewer) {
|
|
2292
|
+
this.CesiumNS = CesiumNS;
|
|
2293
|
+
this.viewer = viewer;
|
|
2294
|
+
/** 已加载的 Tileset */
|
|
2295
|
+
__publicField(this, "tilesets", /* @__PURE__ */ new Map());
|
|
2296
|
+
/** 事件发射器 */
|
|
2297
|
+
__publicField(this, "events", new Emitter());
|
|
2298
|
+
}
|
|
2299
|
+
/**
|
|
2300
|
+
* 添加 3D Tiles
|
|
2301
|
+
* @param config Tileset 配置
|
|
2302
|
+
* @param options 加载选项
|
|
2303
|
+
*/
|
|
2304
|
+
async add(config, options) {
|
|
2305
|
+
if (this.tilesets.has(config.id)) {
|
|
2306
|
+
console.log(`[TilesetManager] Tileset "${config.id}" \u5DF2\u5B58\u5728\uFF0C\u8FD4\u56DE\u7F13\u5B58`);
|
|
2307
|
+
return { id: config.id, success: true };
|
|
2308
|
+
}
|
|
2309
|
+
try {
|
|
2310
|
+
const tileset = await this.createTileset(config);
|
|
2311
|
+
if (!tileset) {
|
|
2312
|
+
throw new Error("\u65E0\u6CD5\u521B\u5EFA Tileset");
|
|
2313
|
+
}
|
|
2314
|
+
this.viewer.scene.primitives.add(tileset);
|
|
2315
|
+
tileset._customId = config.id;
|
|
2316
|
+
tileset._url = config.url;
|
|
2317
|
+
this.tilesets.set(config.id, { config, tileset });
|
|
2318
|
+
this.events.emit({ added: { config } });
|
|
2319
|
+
console.log(`[TilesetManager] \u5DF2\u6DFB\u52A0 Tileset: ${config.id}`);
|
|
2320
|
+
if (options?.flyTo) {
|
|
2321
|
+
await this.flyToTileset(tileset, options.flyDuration);
|
|
2322
|
+
}
|
|
2323
|
+
return { id: config.id, success: true };
|
|
2324
|
+
} catch (error) {
|
|
2325
|
+
const errMsg = error instanceof Error ? error.message : String(error);
|
|
2326
|
+
console.error(`[TilesetManager] \u6DFB\u52A0 Tileset \u5931\u8D25:`, error);
|
|
2327
|
+
this.events.emit({ error: { id: config.id, error } });
|
|
2328
|
+
return { id: config.id, success: false, error: errMsg };
|
|
2329
|
+
}
|
|
2330
|
+
}
|
|
2331
|
+
/**
|
|
2332
|
+
* 移除 Tileset
|
|
2333
|
+
* @param tilesetId Tileset ID
|
|
2334
|
+
*/
|
|
2335
|
+
remove(tilesetId) {
|
|
2336
|
+
const entry = this.tilesets.get(tilesetId);
|
|
2337
|
+
if (!entry) {
|
|
2338
|
+
return false;
|
|
2339
|
+
}
|
|
2340
|
+
this.viewer.scene.primitives.remove(entry.tileset);
|
|
2341
|
+
this.tilesets.delete(tilesetId);
|
|
2342
|
+
this.events.emit({ removed: { id: tilesetId } });
|
|
2343
|
+
console.log(`[TilesetManager] \u5DF2\u79FB\u9664 Tileset: ${tilesetId}`);
|
|
2344
|
+
return true;
|
|
2345
|
+
}
|
|
2346
|
+
/**
|
|
2347
|
+
* 设置 Tileset 可见性
|
|
2348
|
+
* @param tilesetId Tileset ID
|
|
2349
|
+
* @param visible 是否可见
|
|
2350
|
+
*/
|
|
2351
|
+
setVisible(tilesetId, visible) {
|
|
2352
|
+
const entry = this.tilesets.get(tilesetId);
|
|
2353
|
+
if (!entry) {
|
|
2354
|
+
return false;
|
|
2355
|
+
}
|
|
2356
|
+
entry.tileset.show = visible;
|
|
2357
|
+
entry.config.show = visible;
|
|
2358
|
+
this.events.emit({ visibilityChanged: { id: tilesetId, visible } });
|
|
2359
|
+
return true;
|
|
2360
|
+
}
|
|
2361
|
+
/**
|
|
2362
|
+
* 获取 Tileset 配置
|
|
2363
|
+
* @param tilesetId Tileset ID
|
|
2364
|
+
*/
|
|
2365
|
+
get(tilesetId) {
|
|
2366
|
+
return this.tilesets.get(tilesetId)?.config;
|
|
2367
|
+
}
|
|
2368
|
+
/**
|
|
2369
|
+
* 获取底层 Cesium Tileset
|
|
2370
|
+
* @param tilesetId Tileset ID
|
|
2371
|
+
*/
|
|
2372
|
+
getTileset(tilesetId) {
|
|
2373
|
+
return this.tilesets.get(tilesetId)?.tileset;
|
|
2374
|
+
}
|
|
2375
|
+
/**
|
|
2376
|
+
* 获取所有 Tileset 配置
|
|
2377
|
+
*/
|
|
2378
|
+
list() {
|
|
2379
|
+
return Array.from(this.tilesets.values()).map((e) => e.config);
|
|
2380
|
+
}
|
|
2381
|
+
/**
|
|
2382
|
+
* 检查 Tileset 是否存在
|
|
2383
|
+
* @param tilesetId Tileset ID
|
|
2384
|
+
*/
|
|
2385
|
+
has(tilesetId) {
|
|
2386
|
+
return this.tilesets.has(tilesetId);
|
|
2387
|
+
}
|
|
2388
|
+
/**
|
|
2389
|
+
* 飞行到指定 Tileset
|
|
2390
|
+
* @param tilesetId Tileset ID
|
|
2391
|
+
* @param duration 飞行时长
|
|
2392
|
+
*/
|
|
2393
|
+
async flyTo(tilesetId, duration) {
|
|
2394
|
+
const entry = this.tilesets.get(tilesetId);
|
|
2395
|
+
if (!entry) {
|
|
2396
|
+
return false;
|
|
2397
|
+
}
|
|
2398
|
+
await this.flyToTileset(entry.tileset, duration);
|
|
2399
|
+
return true;
|
|
2400
|
+
}
|
|
2401
|
+
/**
|
|
2402
|
+
* 清除所有 Tileset
|
|
2403
|
+
*/
|
|
2404
|
+
clear() {
|
|
2405
|
+
const ids = Array.from(this.tilesets.keys());
|
|
2406
|
+
ids.forEach((id) => this.remove(id));
|
|
2407
|
+
console.log(`[TilesetManager] \u5DF2\u6E05\u9664\u6240\u6709 Tileset`);
|
|
2408
|
+
}
|
|
2409
|
+
/**
|
|
2410
|
+
* 销毁管理器
|
|
2411
|
+
*/
|
|
2412
|
+
destroy() {
|
|
2413
|
+
this.clear();
|
|
2414
|
+
}
|
|
2415
|
+
/**
|
|
2416
|
+
* 创建 Tileset
|
|
2417
|
+
*/
|
|
2418
|
+
async createTileset(config) {
|
|
2419
|
+
const C = this.CesiumNS;
|
|
2420
|
+
const pointCloudShading = config.pointCloudShading ?? {
|
|
2421
|
+
attenuation: true,
|
|
2422
|
+
geometricErrorScale: 1,
|
|
2423
|
+
eyeDomeLighting: true,
|
|
2424
|
+
eyeDomeLightingStrength: 1,
|
|
2425
|
+
eyeDomeLightingRadius: 1
|
|
2426
|
+
};
|
|
2427
|
+
const tileset = await C.Cesium3DTileset.fromUrl(config.url, {
|
|
2428
|
+
show: config.show ?? true,
|
|
2429
|
+
maximumScreenSpaceError: config.maximumScreenSpaceError ?? 16,
|
|
2430
|
+
dynamicScreenSpaceError: true,
|
|
2431
|
+
dynamicScreenSpaceErrorDensity: 278e-5,
|
|
2432
|
+
dynamicScreenSpaceErrorFactor: 4,
|
|
2433
|
+
skipLevelOfDetail: false,
|
|
2434
|
+
baseScreenSpaceError: 1024,
|
|
2435
|
+
skipScreenSpaceErrorFactor: 16,
|
|
2436
|
+
skipLevels: 1,
|
|
2437
|
+
immediatelyLoadDesiredLevelOfDetail: false,
|
|
2438
|
+
loadSiblings: false,
|
|
2439
|
+
cullWithChildrenBounds: true,
|
|
2440
|
+
pointCloudShading
|
|
2441
|
+
});
|
|
2442
|
+
return tileset;
|
|
2443
|
+
}
|
|
2444
|
+
/**
|
|
2445
|
+
* 飞行到 Tileset
|
|
2446
|
+
*/
|
|
2447
|
+
async flyToTileset(tileset, duration = 2) {
|
|
2448
|
+
try {
|
|
2449
|
+
await this.viewer.flyTo(tileset, { duration });
|
|
2450
|
+
} catch {
|
|
2451
|
+
}
|
|
2452
|
+
}
|
|
2453
|
+
};
|
|
2454
|
+
|
|
1696
2455
|
// src/core/SceneManager.ts
|
|
1697
2456
|
var SceneManager = class {
|
|
1698
2457
|
constructor(CesiumNS, options) {
|
|
@@ -1700,6 +2459,9 @@ var SceneManager = class {
|
|
|
1700
2459
|
__publicField(this, "viewer");
|
|
1701
2460
|
__publicField(this, "layerManager");
|
|
1702
2461
|
__publicField(this, "cameraManager");
|
|
2462
|
+
__publicField(this, "terrainManager");
|
|
2463
|
+
__publicField(this, "imageryManager");
|
|
2464
|
+
__publicField(this, "tilesetManager");
|
|
1703
2465
|
console.log("SceneManager constructor", options);
|
|
1704
2466
|
assertCesiumAssetsConfigured();
|
|
1705
2467
|
ensureCesiumIonToken(CesiumNS);
|
|
@@ -1707,10 +2469,8 @@ var SceneManager = class {
|
|
|
1707
2469
|
const container = this.resolveContainer(options.container);
|
|
1708
2470
|
this.viewer = new CesiumNS.Viewer(container, {
|
|
1709
2471
|
baseLayer: false,
|
|
1710
|
-
// 时间控制相关
|
|
1711
2472
|
animation: false,
|
|
1712
2473
|
timeline: false,
|
|
1713
|
-
// UI控件
|
|
1714
2474
|
geocoder: false,
|
|
1715
2475
|
homeButton: false,
|
|
1716
2476
|
sceneModePicker: false,
|
|
@@ -1718,15 +2478,11 @@ var SceneManager = class {
|
|
|
1718
2478
|
navigationHelpButton: false,
|
|
1719
2479
|
fullscreenButton: false,
|
|
1720
2480
|
vrButton: false,
|
|
1721
|
-
// 信息框
|
|
1722
2481
|
infoBox: false,
|
|
1723
2482
|
selectionIndicator: false,
|
|
1724
|
-
// 默认数据源
|
|
1725
2483
|
shouldAnimate: false,
|
|
1726
|
-
// 地形和影像
|
|
1727
2484
|
terrainProvider: void 0,
|
|
1728
2485
|
creditContainer: void 0,
|
|
1729
|
-
// 其他
|
|
1730
2486
|
contextOptions: {
|
|
1731
2487
|
webgl: {
|
|
1732
2488
|
alpha: true,
|
|
@@ -1735,7 +2491,6 @@ var SceneManager = class {
|
|
|
1735
2491
|
antialias: true,
|
|
1736
2492
|
powerPreference: "high-performance",
|
|
1737
2493
|
preserveDrawingBuffer: true
|
|
1738
|
-
// 必需:允许 canvas.toDataURL() 截图
|
|
1739
2494
|
}
|
|
1740
2495
|
},
|
|
1741
2496
|
...viewerOptions
|
|
@@ -1747,6 +2502,9 @@ var SceneManager = class {
|
|
|
1747
2502
|
}
|
|
1748
2503
|
});
|
|
1749
2504
|
this.cameraManager = new CameraManager(CesiumNS, this.viewer);
|
|
2505
|
+
this.terrainManager = new TerrainManager(CesiumNS, this.viewer);
|
|
2506
|
+
this.imageryManager = new ImageryManager(CesiumNS, this.viewer);
|
|
2507
|
+
this.tilesetManager = new TilesetManager(CesiumNS, this.viewer);
|
|
1750
2508
|
if (imagery) this.applyImagery(imagery);
|
|
1751
2509
|
if (terrain) this.applyTerrain(terrain);
|
|
1752
2510
|
if (typeof shadows === "boolean") this.setShadows(shadows);
|
|
@@ -1757,7 +2515,7 @@ var SceneManager = class {
|
|
|
1757
2515
|
return this.viewer;
|
|
1758
2516
|
}
|
|
1759
2517
|
/**
|
|
1760
|
-
* Set a black background for areas without imagery.
|
|
2518
|
+
* Set a black background for areas without imagery.
|
|
1761
2519
|
*/
|
|
1762
2520
|
useBlackBackground(removeAllImagery = true) {
|
|
1763
2521
|
const C = this.CesiumNS;
|
|
@@ -1765,6 +2523,9 @@ var SceneManager = class {
|
|
|
1765
2523
|
this.viewer.scene.globe.baseColor = C.Color.BLACK;
|
|
1766
2524
|
}
|
|
1767
2525
|
destroy() {
|
|
2526
|
+
this.terrainManager?.destroy();
|
|
2527
|
+
this.imageryManager?.destroy();
|
|
2528
|
+
this.tilesetManager?.destroy();
|
|
1768
2529
|
this.viewer?.destroy();
|
|
1769
2530
|
this.viewer = void 0;
|
|
1770
2531
|
}
|
|
@@ -1789,6 +2550,18 @@ var SceneManager = class {
|
|
|
1789
2550
|
getLayerManager() {
|
|
1790
2551
|
return this.layerManager;
|
|
1791
2552
|
}
|
|
2553
|
+
getTerrainManager() {
|
|
2554
|
+
return this.terrainManager;
|
|
2555
|
+
}
|
|
2556
|
+
getImageryManager() {
|
|
2557
|
+
return this.imageryManager;
|
|
2558
|
+
}
|
|
2559
|
+
getTilesetManager() {
|
|
2560
|
+
return this.tilesetManager;
|
|
2561
|
+
}
|
|
2562
|
+
/**
|
|
2563
|
+
* @deprecated 请使用 getImageryManager().add() 代替
|
|
2564
|
+
*/
|
|
1792
2565
|
setBaseImagery(url, layer_id, opts) {
|
|
1793
2566
|
for (let i = 0; i < this.viewer.imageryLayers.length; i++) {
|
|
1794
2567
|
const layer2 = this.viewer.imageryLayers.get(i);
|
|
@@ -1811,7 +2584,9 @@ var SceneManager = class {
|
|
|
1811
2584
|
}
|
|
1812
2585
|
return layer;
|
|
1813
2586
|
}
|
|
1814
|
-
|
|
2587
|
+
/**
|
|
2588
|
+
* @deprecated 请使用 getTilesetManager().add() 代替
|
|
2589
|
+
*/
|
|
1815
2590
|
async set3DTiles(url, layer_id) {
|
|
1816
2591
|
const primitives = this.viewer.scene.primitives;
|
|
1817
2592
|
for (let i = primitives.length - 1; i >= 0; i--) {
|
|
@@ -1835,6 +2610,9 @@ var SceneManager = class {
|
|
|
1835
2610
|
return void 0;
|
|
1836
2611
|
}
|
|
1837
2612
|
}
|
|
2613
|
+
/**
|
|
2614
|
+
* @deprecated 请使用 getTerrainManager().switchTo() 代替
|
|
2615
|
+
*/
|
|
1838
2616
|
async setTerrain(options) {
|
|
1839
2617
|
if (this.viewer.scene.skyBox) {
|
|
1840
2618
|
this.viewer.scene.skyBox.show = false;
|
|
@@ -1843,7 +2621,6 @@ var SceneManager = class {
|
|
|
1843
2621
|
this.viewer.scene.globe.baseColor = this.CesiumNS.Color.BLACK;
|
|
1844
2622
|
return this.applyTerrain(options);
|
|
1845
2623
|
}
|
|
1846
|
-
// Expose DSM (3D Tiles) loading for demos and consumers
|
|
1847
2624
|
async addDSM(options) {
|
|
1848
2625
|
const handle = await this.layerManager.addDSM(options);
|
|
1849
2626
|
try {
|
|
@@ -1872,8 +2649,7 @@ var SceneManager = class {
|
|
|
1872
2649
|
try {
|
|
1873
2650
|
const handle = this.layerManager.addDOM(options);
|
|
1874
2651
|
if (!handle) return void 0;
|
|
1875
|
-
|
|
1876
|
-
return layer;
|
|
2652
|
+
return this.layerManager.getImageryLayer(handle.id);
|
|
1877
2653
|
} catch (e) {
|
|
1878
2654
|
console.error("[SceneManager] Failed to apply imagery:", e);
|
|
1879
2655
|
return void 0;
|
|
@@ -1882,7 +2658,6 @@ var SceneManager = class {
|
|
|
1882
2658
|
async apply3Dtiles(url) {
|
|
1883
2659
|
const tileset = await this.CesiumNS.Cesium3DTileset.fromUrl(url, {
|
|
1884
2660
|
maximumScreenSpaceError: 16,
|
|
1885
|
-
// 降低以提高点云质量
|
|
1886
2661
|
dynamicScreenSpaceError: true,
|
|
1887
2662
|
dynamicScreenSpaceErrorDensity: 278e-5,
|
|
1888
2663
|
dynamicScreenSpaceErrorFactor: 4,
|
|
@@ -1893,14 +2668,12 @@ var SceneManager = class {
|
|
|
1893
2668
|
immediatelyLoadDesiredLevelOfDetail: false,
|
|
1894
2669
|
loadSiblings: false,
|
|
1895
2670
|
cullWithChildrenBounds: true,
|
|
1896
|
-
// 点云特定选项
|
|
1897
2671
|
pointCloudShading: {
|
|
1898
2672
|
attenuation: true,
|
|
1899
2673
|
geometricErrorScale: 1,
|
|
1900
2674
|
maximumAttenuation: void 0,
|
|
1901
2675
|
baseResolution: void 0,
|
|
1902
2676
|
eyeDomeLighting: true,
|
|
1903
|
-
// 启用 EDL 可以改善点云视觉效果
|
|
1904
2677
|
eyeDomeLightingStrength: 1,
|
|
1905
2678
|
eyeDomeLightingRadius: 1
|
|
1906
2679
|
}
|
|
@@ -1910,7 +2683,6 @@ var SceneManager = class {
|
|
|
1910
2683
|
async applyTerrain(options) {
|
|
1911
2684
|
try {
|
|
1912
2685
|
const handle = await this.layerManager.addDEM(options);
|
|
1913
|
-
console.log("handle", this.viewer.terrainProvider);
|
|
1914
2686
|
return handle ? this.viewer.terrainProvider : void 0;
|
|
1915
2687
|
} catch (e) {
|
|
1916
2688
|
console.error("[SceneManager] Failed to apply terrain:", e);
|
|
@@ -13335,6 +14107,7 @@ var MassPolygonManager = class {
|
|
|
13335
14107
|
// 事件处理器
|
|
13336
14108
|
__publicField(this, "hoverHandler");
|
|
13337
14109
|
__publicField(this, "clickHandler");
|
|
14110
|
+
__publicField(this, "rightClickHandler");
|
|
13338
14111
|
// 悬停状态
|
|
13339
14112
|
__publicField(this, "highlightedId");
|
|
13340
14113
|
__publicField(this, "originalHighlightFillColor");
|
|
@@ -13343,11 +14116,18 @@ var MassPolygonManager = class {
|
|
|
13343
14116
|
__publicField(this, "selectedId");
|
|
13344
14117
|
__publicField(this, "originalSelectFillColor");
|
|
13345
14118
|
__publicField(this, "originalSelectOutlineColor");
|
|
14119
|
+
// 贴地模式高亮用的独立 Primitive
|
|
14120
|
+
__publicField(this, "highlightPrimitive");
|
|
14121
|
+
__publicField(this, "selectPrimitive");
|
|
14122
|
+
// 贴地模式轮廓线
|
|
14123
|
+
__publicField(this, "groundOutlinePrimitive");
|
|
13346
14124
|
// 节流相关
|
|
13347
14125
|
__publicField(this, "lastPickTime", 0);
|
|
13348
14126
|
__publicField(this, "pickThrottleMs", 50);
|
|
13349
14127
|
// 悬停标签
|
|
13350
14128
|
__publicField(this, "hoverLabel");
|
|
14129
|
+
// 销毁标志
|
|
14130
|
+
__publicField(this, "isDestroyed", false);
|
|
13351
14131
|
// ========== 编辑支持方法 ==========
|
|
13352
14132
|
// 隐藏的多边形原始颜色存储
|
|
13353
14133
|
__publicField(this, "hiddenPolygonColors", /* @__PURE__ */ new Map());
|
|
@@ -13361,6 +14141,7 @@ var MassPolygonManager = class {
|
|
|
13361
14141
|
this.interactionOptions = {
|
|
13362
14142
|
enableHover: false,
|
|
13363
14143
|
enableClick: false,
|
|
14144
|
+
enableRightClick: false,
|
|
13364
14145
|
highlightStyle: {
|
|
13365
14146
|
fillColor: "rgba(255, 255, 0, 0.7)",
|
|
13366
14147
|
outlineColor: "rgba(255, 255, 0, 1)"
|
|
@@ -13380,7 +14161,8 @@ var MassPolygonManager = class {
|
|
|
13380
14161
|
pixelOffset: [0, -20]
|
|
13381
14162
|
},
|
|
13382
14163
|
onHover: void 0,
|
|
13383
|
-
onClick: void 0
|
|
14164
|
+
onClick: void 0,
|
|
14165
|
+
onRightClick: void 0
|
|
13384
14166
|
};
|
|
13385
14167
|
}
|
|
13386
14168
|
/**
|
|
@@ -13412,6 +14194,7 @@ var MassPolygonManager = class {
|
|
|
13412
14194
|
this.interactionOptions = {
|
|
13413
14195
|
enableHover: interaction.enableHover ?? false,
|
|
13414
14196
|
enableClick: interaction.enableClick ?? false,
|
|
14197
|
+
enableRightClick: interaction.enableRightClick ?? false,
|
|
13415
14198
|
highlightStyle: {
|
|
13416
14199
|
fillColor: interaction.highlightStyle?.fillColor ?? this.interactionOptions.highlightStyle.fillColor,
|
|
13417
14200
|
outlineColor: interaction.highlightStyle?.outlineColor ?? this.interactionOptions.highlightStyle.outlineColor
|
|
@@ -13431,7 +14214,8 @@ var MassPolygonManager = class {
|
|
|
13431
14214
|
pixelOffset: interaction.hoverLabelStyle?.pixelOffset ?? this.interactionOptions.hoverLabelStyle.pixelOffset
|
|
13432
14215
|
},
|
|
13433
14216
|
onHover: interaction.onHover,
|
|
13434
|
-
onClick: interaction.onClick
|
|
14217
|
+
onClick: interaction.onClick,
|
|
14218
|
+
onRightClick: interaction.onRightClick
|
|
13435
14219
|
};
|
|
13436
14220
|
}
|
|
13437
14221
|
this.isClampToGround = options?.clampToGround ?? false;
|
|
@@ -13456,46 +14240,98 @@ var MassPolygonManager = class {
|
|
|
13456
14240
|
continue;
|
|
13457
14241
|
}
|
|
13458
14242
|
const positions = this.convertPointsToCartesian(polygon.points);
|
|
13459
|
-
|
|
13460
|
-
|
|
13461
|
-
|
|
13462
|
-
|
|
13463
|
-
|
|
13464
|
-
|
|
13465
|
-
|
|
13466
|
-
|
|
13467
|
-
|
|
13468
|
-
|
|
13469
|
-
|
|
13470
|
-
|
|
13471
|
-
|
|
13472
|
-
|
|
13473
|
-
|
|
13474
|
-
|
|
14243
|
+
if (this.isClampToGround) {
|
|
14244
|
+
const polygonGeometry = new C.PolygonGeometry({
|
|
14245
|
+
polygonHierarchy: new C.PolygonHierarchy(positions)
|
|
14246
|
+
});
|
|
14247
|
+
fillInstances.push(new C.GeometryInstance({
|
|
14248
|
+
geometry: polygonGeometry,
|
|
14249
|
+
id: polygon.id,
|
|
14250
|
+
attributes: {
|
|
14251
|
+
color: C.ColorGeometryInstanceAttribute.fromColor(fillColor)
|
|
14252
|
+
}
|
|
14253
|
+
}));
|
|
14254
|
+
} else {
|
|
14255
|
+
const polygonGeometry = new C.PolygonGeometry({
|
|
14256
|
+
polygonHierarchy: new C.PolygonHierarchy(positions),
|
|
14257
|
+
perPositionHeight: false,
|
|
14258
|
+
height: this.polygonHeight
|
|
14259
|
+
});
|
|
14260
|
+
fillInstances.push(new C.GeometryInstance({
|
|
14261
|
+
geometry: polygonGeometry,
|
|
14262
|
+
id: polygon.id,
|
|
14263
|
+
attributes: {
|
|
14264
|
+
color: C.ColorGeometryInstanceAttribute.fromColor(fillColor),
|
|
14265
|
+
show: new C.ShowGeometryInstanceAttribute(true)
|
|
14266
|
+
}
|
|
14267
|
+
}));
|
|
14268
|
+
}
|
|
14269
|
+
const outlinePositions = polygon.points.map(
|
|
14270
|
+
(p) => C.Cartesian3.fromDegrees(p.lon, p.lat, this.isClampToGround ? 0 : this.polygonHeight)
|
|
13475
14271
|
);
|
|
13476
|
-
|
|
13477
|
-
|
|
13478
|
-
|
|
13479
|
-
|
|
13480
|
-
|
|
13481
|
-
|
|
13482
|
-
|
|
13483
|
-
|
|
13484
|
-
|
|
13485
|
-
|
|
13486
|
-
|
|
13487
|
-
|
|
13488
|
-
|
|
14272
|
+
outlinePositions.push(outlinePositions[0]);
|
|
14273
|
+
if (this.isClampToGround) {
|
|
14274
|
+
const groundOutlineGeometry = new C.GroundPolylineGeometry({
|
|
14275
|
+
positions: outlinePositions,
|
|
14276
|
+
width: this.currentStyle.outlineWidth
|
|
14277
|
+
});
|
|
14278
|
+
outlineInstances.push(new C.GeometryInstance({
|
|
14279
|
+
geometry: groundOutlineGeometry,
|
|
14280
|
+
id: `${polygon.id}-outline`,
|
|
14281
|
+
attributes: {
|
|
14282
|
+
color: C.ColorGeometryInstanceAttribute.fromColor(outlineColor)
|
|
14283
|
+
}
|
|
14284
|
+
}));
|
|
14285
|
+
} else {
|
|
14286
|
+
const outlineGeometry = new C.PolylineGeometry({
|
|
14287
|
+
positions: outlinePositions,
|
|
14288
|
+
width: this.currentStyle.outlineWidth
|
|
14289
|
+
});
|
|
14290
|
+
outlineInstances.push(new C.GeometryInstance({
|
|
14291
|
+
geometry: outlineGeometry,
|
|
14292
|
+
id: `${polygon.id}-outline`,
|
|
14293
|
+
attributes: {
|
|
14294
|
+
color: C.ColorGeometryInstanceAttribute.fromColor(outlineColor),
|
|
14295
|
+
show: new C.ShowGeometryInstanceAttribute(true)
|
|
14296
|
+
}
|
|
14297
|
+
}));
|
|
14298
|
+
}
|
|
13489
14299
|
}
|
|
13490
14300
|
if (fillInstances.length > 0) {
|
|
13491
14301
|
const appearance = new C.PerInstanceColorAppearance({ flat: true, translucent: true });
|
|
13492
|
-
this.
|
|
14302
|
+
if (this.isClampToGround) {
|
|
14303
|
+
this.primitive = new C.GroundPrimitive({
|
|
14304
|
+
geometryInstances: fillInstances,
|
|
14305
|
+
appearance,
|
|
14306
|
+
asynchronous,
|
|
14307
|
+
releaseGeometryInstances: false,
|
|
14308
|
+
allowPicking: true
|
|
14309
|
+
});
|
|
14310
|
+
} else {
|
|
14311
|
+
this.primitive = new C.Primitive({
|
|
14312
|
+
geometryInstances: fillInstances,
|
|
14313
|
+
appearance,
|
|
14314
|
+
asynchronous,
|
|
14315
|
+
releaseGeometryInstances: false,
|
|
14316
|
+
allowPicking: true
|
|
14317
|
+
});
|
|
14318
|
+
}
|
|
13493
14319
|
this.layerCollection.add(this.primitive);
|
|
13494
14320
|
}
|
|
13495
14321
|
if (outlineInstances.length > 0) {
|
|
13496
|
-
|
|
13497
|
-
|
|
13498
|
-
|
|
14322
|
+
if (this.isClampToGround) {
|
|
14323
|
+
const appearance = new C.PolylineColorAppearance();
|
|
14324
|
+
this.groundOutlinePrimitive = new C.GroundPolylinePrimitive({
|
|
14325
|
+
geometryInstances: outlineInstances,
|
|
14326
|
+
appearance,
|
|
14327
|
+
asynchronous
|
|
14328
|
+
});
|
|
14329
|
+
this.layerCollection.add(this.groundOutlinePrimitive);
|
|
14330
|
+
} else {
|
|
14331
|
+
const appearance = new C.PolylineColorAppearance();
|
|
14332
|
+
this.outlinePrimitive = new C.Primitive({ geometryInstances: outlineInstances, appearance, asynchronous });
|
|
14333
|
+
this.layerCollection.add(this.outlinePrimitive);
|
|
14334
|
+
}
|
|
13499
14335
|
}
|
|
13500
14336
|
this.labelCollection = new C.LabelCollection();
|
|
13501
14337
|
this.layerCollection.add(this.labelCollection);
|
|
@@ -13505,6 +14341,9 @@ var MassPolygonManager = class {
|
|
|
13505
14341
|
if (this.interactionOptions.enableClick) {
|
|
13506
14342
|
this.setupClickHandler();
|
|
13507
14343
|
}
|
|
14344
|
+
if (this.interactionOptions.enableRightClick) {
|
|
14345
|
+
this.setupRightClickHandler();
|
|
14346
|
+
}
|
|
13508
14347
|
this.viewer.scene.requestRender();
|
|
13509
14348
|
return {
|
|
13510
14349
|
primitive: this.primitive,
|
|
@@ -13525,19 +14364,25 @@ var MassPolygonManager = class {
|
|
|
13525
14364
|
const now = Date.now();
|
|
13526
14365
|
if (now - this.lastPickTime < this.pickThrottleMs) return;
|
|
13527
14366
|
this.lastPickTime = now;
|
|
13528
|
-
|
|
13529
|
-
if (
|
|
13530
|
-
|
|
13531
|
-
|
|
13532
|
-
|
|
13533
|
-
|
|
13534
|
-
|
|
13535
|
-
|
|
13536
|
-
|
|
13537
|
-
this.interactionOptions.onHover?.(polygonId, data ?? null);
|
|
14367
|
+
let polygonId = null;
|
|
14368
|
+
if (this.isClampToGround) {
|
|
14369
|
+
polygonId = this.pickPolygonByPosition(movement.endPosition);
|
|
14370
|
+
} else {
|
|
14371
|
+
const pickedObject = this.viewer.scene.pick(movement.endPosition);
|
|
14372
|
+
if (pickedObject?.id && typeof pickedObject.id === "string") {
|
|
14373
|
+
const pickedId = pickedObject.id.endsWith("-outline") ? pickedObject.id.replace("-outline", "") : pickedObject.id;
|
|
14374
|
+
if (this.polygonDataMap.has(pickedId)) {
|
|
14375
|
+
polygonId = pickedId;
|
|
13538
14376
|
}
|
|
13539
|
-
}
|
|
13540
|
-
|
|
14377
|
+
}
|
|
14378
|
+
}
|
|
14379
|
+
if (polygonId) {
|
|
14380
|
+
if (this.highlightedId !== polygonId) {
|
|
14381
|
+
this.clearHighlight();
|
|
14382
|
+
this.highlightPolygon(polygonId);
|
|
14383
|
+
const data = this.polygonDataMap.get(polygonId);
|
|
14384
|
+
if (data) this.showLabel(data);
|
|
14385
|
+
this.interactionOptions.onHover?.(polygonId, data ?? null);
|
|
13541
14386
|
}
|
|
13542
14387
|
} else {
|
|
13543
14388
|
this.handleMouseLeave();
|
|
@@ -13557,23 +14402,26 @@ var MassPolygonManager = class {
|
|
|
13557
14402
|
this.clickHandler = new C.ScreenSpaceEventHandler(this.viewer.scene.canvas);
|
|
13558
14403
|
this.clickHandler.setInputAction(
|
|
13559
14404
|
(movement) => {
|
|
13560
|
-
|
|
13561
|
-
if (
|
|
13562
|
-
|
|
13563
|
-
|
|
13564
|
-
|
|
13565
|
-
|
|
13566
|
-
|
|
13567
|
-
|
|
13568
|
-
|
|
13569
|
-
const data = this.polygonDataMap.get(polygonId);
|
|
13570
|
-
this.interactionOptions.onClick?.(polygonId, data ?? null);
|
|
14405
|
+
let polygonId = null;
|
|
14406
|
+
if (this.isClampToGround) {
|
|
14407
|
+
polygonId = this.pickPolygonByPosition(movement.position);
|
|
14408
|
+
} else {
|
|
14409
|
+
const pickedObject = this.viewer.scene.pick(movement.position);
|
|
14410
|
+
if (pickedObject?.id && typeof pickedObject.id === "string") {
|
|
14411
|
+
const pickedId = pickedObject.id.endsWith("-outline") ? pickedObject.id.replace("-outline", "") : pickedObject.id;
|
|
14412
|
+
if (this.polygonDataMap.has(pickedId)) {
|
|
14413
|
+
polygonId = pickedId;
|
|
13571
14414
|
}
|
|
14415
|
+
}
|
|
14416
|
+
}
|
|
14417
|
+
if (polygonId) {
|
|
14418
|
+
if (this.selectedId === polygonId) {
|
|
14419
|
+
this.deselect();
|
|
14420
|
+
this.interactionOptions.onClick?.(null, null);
|
|
13572
14421
|
} else {
|
|
13573
|
-
|
|
13574
|
-
|
|
13575
|
-
|
|
13576
|
-
}
|
|
14422
|
+
this.select(polygonId);
|
|
14423
|
+
const data = this.polygonDataMap.get(polygonId);
|
|
14424
|
+
this.interactionOptions.onClick?.(polygonId, data ?? null);
|
|
13577
14425
|
}
|
|
13578
14426
|
} else {
|
|
13579
14427
|
if (this.selectedId) {
|
|
@@ -13585,6 +14433,79 @@ var MassPolygonManager = class {
|
|
|
13585
14433
|
C.ScreenSpaceEventType.LEFT_CLICK
|
|
13586
14434
|
);
|
|
13587
14435
|
}
|
|
14436
|
+
/**
|
|
14437
|
+
* 设置右键事件处理器
|
|
14438
|
+
*/
|
|
14439
|
+
setupRightClickHandler() {
|
|
14440
|
+
if (this.rightClickHandler) {
|
|
14441
|
+
this.rightClickHandler.destroy();
|
|
14442
|
+
}
|
|
14443
|
+
const C = this.CesiumNS;
|
|
14444
|
+
this.rightClickHandler = new C.ScreenSpaceEventHandler(this.viewer.scene.canvas);
|
|
14445
|
+
this.rightClickHandler.setInputAction(
|
|
14446
|
+
(movement) => {
|
|
14447
|
+
let polygonId = null;
|
|
14448
|
+
if (this.isClampToGround) {
|
|
14449
|
+
polygonId = this.pickPolygonByPosition(movement.position);
|
|
14450
|
+
} else {
|
|
14451
|
+
const pickedObject = this.viewer.scene.pick(movement.position);
|
|
14452
|
+
if (pickedObject?.id && typeof pickedObject.id === "string") {
|
|
14453
|
+
const pickedId = pickedObject.id.endsWith("-outline") ? pickedObject.id.replace("-outline", "") : pickedObject.id;
|
|
14454
|
+
if (this.polygonDataMap.has(pickedId)) {
|
|
14455
|
+
polygonId = pickedId;
|
|
14456
|
+
}
|
|
14457
|
+
}
|
|
14458
|
+
}
|
|
14459
|
+
if (polygonId) {
|
|
14460
|
+
this.select(polygonId);
|
|
14461
|
+
const data = this.polygonDataMap.get(polygonId);
|
|
14462
|
+
if (data) {
|
|
14463
|
+
const canvas = this.viewer.scene.canvas;
|
|
14464
|
+
const canvasRect = canvas.getBoundingClientRect();
|
|
14465
|
+
const screenX = canvasRect.left + movement.position.x;
|
|
14466
|
+
const screenY = canvasRect.top + movement.position.y;
|
|
14467
|
+
this.interactionOptions.onRightClick?.(polygonId, data, { x: screenX, y: screenY });
|
|
14468
|
+
}
|
|
14469
|
+
}
|
|
14470
|
+
},
|
|
14471
|
+
C.ScreenSpaceEventType.RIGHT_CLICK
|
|
14472
|
+
);
|
|
14473
|
+
}
|
|
14474
|
+
/**
|
|
14475
|
+
* 通过屏幕坐标获取地理位置,然后判断在哪个多边形内
|
|
14476
|
+
* 用于贴地模式下的精确拾取
|
|
14477
|
+
*/
|
|
14478
|
+
pickPolygonByPosition(screenPosition) {
|
|
14479
|
+
const C = this.CesiumNS;
|
|
14480
|
+
const ray = this.viewer.camera.getPickRay(screenPosition);
|
|
14481
|
+
if (!ray) return null;
|
|
14482
|
+
const cartesian = this.viewer.scene.globe.pick(ray, this.viewer.scene);
|
|
14483
|
+
if (!cartesian) return null;
|
|
14484
|
+
const cartographic = C.Cartographic.fromCartesian(cartesian);
|
|
14485
|
+
const lon = C.Math.toDegrees(cartographic.longitude);
|
|
14486
|
+
const lat = C.Math.toDegrees(cartographic.latitude);
|
|
14487
|
+
for (const [id, polygon] of this.polygonDataMap) {
|
|
14488
|
+
if (this.isPointInPolygon(lon, lat, polygon.points)) {
|
|
14489
|
+
return id;
|
|
14490
|
+
}
|
|
14491
|
+
}
|
|
14492
|
+
return null;
|
|
14493
|
+
}
|
|
14494
|
+
/**
|
|
14495
|
+
* 判断点是否在多边形内(射线法)
|
|
14496
|
+
*/
|
|
14497
|
+
isPointInPolygon(lon, lat, points) {
|
|
14498
|
+
let inside = false;
|
|
14499
|
+
const n = points.length;
|
|
14500
|
+
for (let i = 0, j = n - 1; i < n; j = i++) {
|
|
14501
|
+
const xi = points[i].lon, yi = points[i].lat;
|
|
14502
|
+
const xj = points[j].lon, yj = points[j].lat;
|
|
14503
|
+
if (yi > lat !== yj > lat && lon < (xj - xi) * (lat - yi) / (yj - yi) + xi) {
|
|
14504
|
+
inside = !inside;
|
|
14505
|
+
}
|
|
14506
|
+
}
|
|
14507
|
+
return inside;
|
|
14508
|
+
}
|
|
13588
14509
|
/**
|
|
13589
14510
|
* 处理鼠标离开
|
|
13590
14511
|
*/
|
|
@@ -13602,6 +14523,11 @@ var MassPolygonManager = class {
|
|
|
13602
14523
|
if (id === this.selectedId) return;
|
|
13603
14524
|
const C = this.CesiumNS;
|
|
13604
14525
|
if (!this.primitive) return;
|
|
14526
|
+
if (this.isClampToGround) {
|
|
14527
|
+
this.highlightPolygonWithSeparatePrimitive(id, "highlight");
|
|
14528
|
+
this.highlightedId = id;
|
|
14529
|
+
return;
|
|
14530
|
+
}
|
|
13605
14531
|
try {
|
|
13606
14532
|
const fillAttributes = this.primitive.getGeometryInstanceAttributes?.(id);
|
|
13607
14533
|
if (fillAttributes?.color) {
|
|
@@ -13622,11 +14548,60 @@ var MassPolygonManager = class {
|
|
|
13622
14548
|
} catch (e) {
|
|
13623
14549
|
}
|
|
13624
14550
|
}
|
|
14551
|
+
/**
|
|
14552
|
+
* 贴地模式下使用独立 Primitive 高亮/选中多边形
|
|
14553
|
+
*/
|
|
14554
|
+
highlightPolygonWithSeparatePrimitive(id, type) {
|
|
14555
|
+
const C = this.CesiumNS;
|
|
14556
|
+
const polygonData = this.polygonDataMap.get(id);
|
|
14557
|
+
if (!polygonData) return;
|
|
14558
|
+
if (type === "highlight" && this.highlightPrimitive) {
|
|
14559
|
+
this.layerCollection?.remove(this.highlightPrimitive);
|
|
14560
|
+
this.highlightPrimitive = void 0;
|
|
14561
|
+
} else if (type === "select" && this.selectPrimitive) {
|
|
14562
|
+
this.layerCollection?.remove(this.selectPrimitive);
|
|
14563
|
+
this.selectPrimitive = void 0;
|
|
14564
|
+
}
|
|
14565
|
+
const positions = this.convertPointsToCartesian(polygonData.points);
|
|
14566
|
+
const color = type === "highlight" ? C.Color.fromCssColorString(this.interactionOptions.highlightStyle.fillColor) : C.Color.fromCssColorString(this.interactionOptions.selectStyle.fillColor);
|
|
14567
|
+
const geometry = new C.PolygonGeometry({
|
|
14568
|
+
polygonHierarchy: new C.PolygonHierarchy(positions)
|
|
14569
|
+
});
|
|
14570
|
+
const instance = new C.GeometryInstance({
|
|
14571
|
+
geometry,
|
|
14572
|
+
id: `${id}-${type}`,
|
|
14573
|
+
attributes: {
|
|
14574
|
+
color: C.ColorGeometryInstanceAttribute.fromColor(color)
|
|
14575
|
+
}
|
|
14576
|
+
});
|
|
14577
|
+
const primitive = new C.GroundPrimitive({
|
|
14578
|
+
geometryInstances: instance,
|
|
14579
|
+
appearance: new C.PerInstanceColorAppearance({ flat: true, translucent: true }),
|
|
14580
|
+
asynchronous: false
|
|
14581
|
+
// 同步创建,立即显示
|
|
14582
|
+
});
|
|
14583
|
+
if (type === "highlight") {
|
|
14584
|
+
this.highlightPrimitive = primitive;
|
|
14585
|
+
} else {
|
|
14586
|
+
this.selectPrimitive = primitive;
|
|
14587
|
+
}
|
|
14588
|
+
this.layerCollection?.add(primitive);
|
|
14589
|
+
this.viewer.scene.requestRender();
|
|
14590
|
+
}
|
|
13625
14591
|
/**
|
|
13626
14592
|
* 清除悬停高亮
|
|
13627
14593
|
*/
|
|
13628
14594
|
clearHighlight() {
|
|
13629
14595
|
if (!this.highlightedId) return;
|
|
14596
|
+
if (this.isClampToGround) {
|
|
14597
|
+
if (this.highlightPrimitive) {
|
|
14598
|
+
this.layerCollection?.remove(this.highlightPrimitive);
|
|
14599
|
+
this.highlightPrimitive = void 0;
|
|
14600
|
+
}
|
|
14601
|
+
this.highlightedId = void 0;
|
|
14602
|
+
this.viewer.scene.requestRender();
|
|
14603
|
+
return;
|
|
14604
|
+
}
|
|
13630
14605
|
try {
|
|
13631
14606
|
if (this.primitive && this.originalHighlightFillColor) {
|
|
13632
14607
|
const fillAttributes = this.primitive.getGeometryInstanceAttributes?.(this.highlightedId);
|
|
@@ -13662,6 +14637,11 @@ var MassPolygonManager = class {
|
|
|
13662
14637
|
}
|
|
13663
14638
|
const C = this.CesiumNS;
|
|
13664
14639
|
if (!this.primitive) return false;
|
|
14640
|
+
if (this.isClampToGround) {
|
|
14641
|
+
this.highlightPolygonWithSeparatePrimitive(id, "select");
|
|
14642
|
+
this.selectedId = id;
|
|
14643
|
+
return true;
|
|
14644
|
+
}
|
|
13665
14645
|
try {
|
|
13666
14646
|
const fillAttributes = this.primitive.getGeometryInstanceAttributes?.(id);
|
|
13667
14647
|
if (fillAttributes?.color) {
|
|
@@ -13689,6 +14669,15 @@ var MassPolygonManager = class {
|
|
|
13689
14669
|
*/
|
|
13690
14670
|
deselect() {
|
|
13691
14671
|
if (!this.selectedId) return;
|
|
14672
|
+
if (this.isClampToGround) {
|
|
14673
|
+
if (this.selectPrimitive) {
|
|
14674
|
+
this.layerCollection?.remove(this.selectPrimitive);
|
|
14675
|
+
this.selectPrimitive = void 0;
|
|
14676
|
+
}
|
|
14677
|
+
this.selectedId = void 0;
|
|
14678
|
+
this.viewer.scene.requestRender();
|
|
14679
|
+
return;
|
|
14680
|
+
}
|
|
13692
14681
|
try {
|
|
13693
14682
|
if (this.primitive && this.originalSelectFillColor) {
|
|
13694
14683
|
const fillAttributes = this.primitive.getGeometryInstanceAttributes?.(this.selectedId);
|
|
@@ -13809,36 +14798,170 @@ var MassPolygonManager = class {
|
|
|
13809
14798
|
}
|
|
13810
14799
|
/**
|
|
13811
14800
|
* 飞行到所有多边形的范围
|
|
14801
|
+
*
|
|
14802
|
+
* 优化说明:
|
|
14803
|
+
* 1. 多点采样地形高度(四角 + 中心),取最大值确保相机不会陷入地下
|
|
14804
|
+
* 2. 修正 pitch 角度对视角高度的影响计算
|
|
14805
|
+
* 3. 添加最小/最大高度限制,防止极端情况
|
|
14806
|
+
* 4. 使用异步地形查询获取更精确的高度
|
|
14807
|
+
* 5. 添加销毁检查,防止异步回调在实例销毁后执行
|
|
13812
14808
|
*/
|
|
13813
14809
|
flyToBounds(options) {
|
|
14810
|
+
if (this.isDestroyed) {
|
|
14811
|
+
console.warn("[MassPolygonManager] \u5B9E\u4F8B\u5DF2\u9500\u6BC1\uFF0C\u8DF3\u8FC7 flyToBounds");
|
|
14812
|
+
return;
|
|
14813
|
+
}
|
|
13814
14814
|
const bounds = this.getBounds();
|
|
13815
14815
|
if (!bounds) {
|
|
13816
14816
|
console.warn("[MassPolygonManager] \u6CA1\u6709\u591A\u8FB9\u5F62\u6570\u636E\uFF0C\u65E0\u6CD5\u98DE\u884C");
|
|
13817
14817
|
return;
|
|
13818
14818
|
}
|
|
14819
|
+
if (bounds.width <= 0 || bounds.height <= 0) {
|
|
14820
|
+
console.warn("[MassPolygonManager] \u591A\u8FB9\u5F62\u8303\u56F4\u65E0\u6548\uFF0C\u8DF3\u8FC7\u98DE\u884C");
|
|
14821
|
+
return;
|
|
14822
|
+
}
|
|
14823
|
+
const C = this.CesiumNS;
|
|
14824
|
+
const camera = this.viewer.camera;
|
|
14825
|
+
const duration = options?.duration ?? 2;
|
|
14826
|
+
const padding = options?.padding ?? 0.2;
|
|
14827
|
+
const pitch = options?.pitch ?? C.Math.toRadians(-45);
|
|
14828
|
+
const heading = options?.heading ?? 0;
|
|
14829
|
+
const minHeight = options?.minHeight ?? 100;
|
|
14830
|
+
const maxHeight = options?.maxHeight ?? 1e5;
|
|
14831
|
+
const paddedWest = bounds.west - bounds.width * padding;
|
|
14832
|
+
const paddedEast = bounds.east + bounds.width * padding;
|
|
14833
|
+
const paddedSouth = bounds.south - bounds.height * padding;
|
|
14834
|
+
const paddedNorth = bounds.north + bounds.height * padding;
|
|
14835
|
+
const samplePoints = [
|
|
14836
|
+
[bounds.centerLon, bounds.centerLat],
|
|
14837
|
+
// 中心
|
|
14838
|
+
[paddedWest, paddedSouth],
|
|
14839
|
+
// 左下
|
|
14840
|
+
[paddedEast, paddedSouth],
|
|
14841
|
+
// 右下
|
|
14842
|
+
[paddedWest, paddedNorth],
|
|
14843
|
+
// 左上
|
|
14844
|
+
[paddedEast, paddedNorth],
|
|
14845
|
+
// 右上
|
|
14846
|
+
[(paddedWest + paddedEast) / 2, paddedSouth],
|
|
14847
|
+
// 下边中点
|
|
14848
|
+
[(paddedWest + paddedEast) / 2, paddedNorth],
|
|
14849
|
+
// 上边中点
|
|
14850
|
+
[paddedWest, (paddedSouth + paddedNorth) / 2],
|
|
14851
|
+
// 左边中点
|
|
14852
|
+
[paddedEast, (paddedSouth + paddedNorth) / 2]
|
|
14853
|
+
// 右边中点
|
|
14854
|
+
];
|
|
14855
|
+
Promise.all(
|
|
14856
|
+
samplePoints.map(
|
|
14857
|
+
([lon, lat]) => queryTerrainHeightByLonLat(this.CesiumNS, this.viewer, lon, lat)
|
|
14858
|
+
)
|
|
14859
|
+
).then((terrainHeights) => {
|
|
14860
|
+
if (this.isDestroyed) {
|
|
14861
|
+
console.warn("[MassPolygonManager] \u5B9E\u4F8B\u5DF2\u9500\u6BC1\uFF0C\u8DF3\u8FC7\u98DE\u884C\u64CD\u4F5C");
|
|
14862
|
+
return;
|
|
14863
|
+
}
|
|
14864
|
+
const is2DMode = this.viewer.scene.mode === C.SceneMode.SCENE2D;
|
|
14865
|
+
const validTerrainHeights = terrainHeights.filter((h) => h >= -500 && h < 1e4);
|
|
14866
|
+
const maxTerrainHeight = is2DMode || validTerrainHeights.length === 0 ? 0 : Math.max(...validTerrainHeights, 0);
|
|
14867
|
+
const earthRadius = 6371e3;
|
|
14868
|
+
const avgLat = (paddedSouth + paddedNorth) / 2;
|
|
14869
|
+
const latRad = avgLat * (Math.PI / 180);
|
|
14870
|
+
const rectWidth = (paddedEast - paddedWest) * (Math.PI / 180) * earthRadius * Math.cos(latRad);
|
|
14871
|
+
const rectHeight = (paddedNorth - paddedSouth) * (Math.PI / 180) * earthRadius;
|
|
14872
|
+
if (!isFinite(rectWidth) || !isFinite(rectHeight) || rectWidth <= 0 || rectHeight <= 0) {
|
|
14873
|
+
console.warn("[MassPolygonManager] \u8303\u56F4\u8BA1\u7B97\u7ED3\u679C\u65E0\u6548\uFF0C\u8DF3\u8FC7\u98DE\u884C");
|
|
14874
|
+
return;
|
|
14875
|
+
}
|
|
14876
|
+
const frustum = camera.frustum;
|
|
14877
|
+
const fovy = frustum.fovy || frustum.fov || C.Math.toRadians(60);
|
|
14878
|
+
const canvas = this.viewer.scene.canvas;
|
|
14879
|
+
const aspectRatio = canvas.width / canvas.height;
|
|
14880
|
+
const absPitch = Math.abs(pitch);
|
|
14881
|
+
const sinPitch = Math.sin(absPitch);
|
|
14882
|
+
let viewHeight;
|
|
14883
|
+
if (absPitch > C.Math.toRadians(80)) {
|
|
14884
|
+
const tanHalfFovy = Math.tan(fovy / 2);
|
|
14885
|
+
const heightForVertical = rectHeight / (2 * tanHalfFovy);
|
|
14886
|
+
const heightForHorizontal = rectWidth / (2 * tanHalfFovy * aspectRatio);
|
|
14887
|
+
viewHeight = Math.max(heightForVertical, heightForHorizontal);
|
|
14888
|
+
} else {
|
|
14889
|
+
const tanHalfFovy = Math.tan(fovy / 2);
|
|
14890
|
+
const heightForVertical = sinPitch > 0.1 ? rectHeight / (2 * tanHalfFovy * sinPitch) : rectHeight / (2 * tanHalfFovy);
|
|
14891
|
+
const heightForHorizontal = rectWidth / (2 * tanHalfFovy * aspectRatio);
|
|
14892
|
+
viewHeight = Math.max(heightForVertical, heightForHorizontal);
|
|
14893
|
+
}
|
|
14894
|
+
viewHeight *= 1.2;
|
|
14895
|
+
viewHeight = Math.max(minHeight, Math.min(maxHeight, viewHeight));
|
|
14896
|
+
const altitude = maxTerrainHeight + viewHeight;
|
|
14897
|
+
const destination = C.Cartesian3.fromDegrees(bounds.centerLon, bounds.centerLat, altitude);
|
|
14898
|
+
const orientation = { heading, pitch, roll: 0 };
|
|
14899
|
+
if (duration > 0) {
|
|
14900
|
+
camera.flyTo({ destination, orientation, duration });
|
|
14901
|
+
} else {
|
|
14902
|
+
camera.setView({ destination, orientation });
|
|
14903
|
+
}
|
|
14904
|
+
console.log(
|
|
14905
|
+
`[MassPolygonManager] \u98DE\u884C\u5230\u8FB9\u754C: \u4E2D\u5FC3(${bounds.centerLon.toFixed(6)}, ${bounds.centerLat.toFixed(6)}), \u8303\u56F4(${rectWidth.toFixed(0)}m x ${rectHeight.toFixed(0)}m), \u6700\u9AD8\u5730\u5F62: ${maxTerrainHeight.toFixed(0)}m, \u89C6\u89D2\u9AD8\u5EA6: ${viewHeight.toFixed(0)}m, \u76F8\u673A\u9AD8\u5EA6: ${altitude.toFixed(0)}m`
|
|
14906
|
+
);
|
|
14907
|
+
}).catch((error) => {
|
|
14908
|
+
if (this.isDestroyed) {
|
|
14909
|
+
return;
|
|
14910
|
+
}
|
|
14911
|
+
console.warn("[MassPolygonManager] \u5730\u5F62\u67E5\u8BE2\u5931\u8D25\uFF0C\u4F7F\u7528\u540C\u6B65\u65B9\u6CD5:", error);
|
|
14912
|
+
this.flyToBoundsSync(options);
|
|
14913
|
+
});
|
|
14914
|
+
}
|
|
14915
|
+
/**
|
|
14916
|
+
* 同步版本的飞行方法(降级方案)
|
|
14917
|
+
*/
|
|
14918
|
+
flyToBoundsSync(options) {
|
|
14919
|
+
const bounds = this.getBounds();
|
|
14920
|
+
if (!bounds) return;
|
|
13819
14921
|
const C = this.CesiumNS;
|
|
13820
14922
|
const camera = this.viewer.camera;
|
|
13821
14923
|
const duration = options?.duration ?? 2;
|
|
13822
14924
|
const padding = options?.padding ?? 0.2;
|
|
13823
14925
|
const pitch = options?.pitch ?? C.Math.toRadians(-45);
|
|
13824
14926
|
const heading = options?.heading ?? 0;
|
|
14927
|
+
const minHeight = options?.minHeight ?? 100;
|
|
14928
|
+
const maxHeight = options?.maxHeight ?? 1e5;
|
|
13825
14929
|
const paddedWest = bounds.west - bounds.width * padding;
|
|
13826
14930
|
const paddedEast = bounds.east + bounds.width * padding;
|
|
13827
14931
|
const paddedSouth = bounds.south - bounds.height * padding;
|
|
13828
14932
|
const paddedNorth = bounds.north + bounds.height * padding;
|
|
14933
|
+
const terrainHeight = queryTerrainHeightByLonLatSync(
|
|
14934
|
+
this.CesiumNS,
|
|
14935
|
+
this.viewer,
|
|
14936
|
+
bounds.centerLon,
|
|
14937
|
+
bounds.centerLat
|
|
14938
|
+
);
|
|
14939
|
+
const is2DMode = this.viewer.scene.mode === C.SceneMode.SCENE2D;
|
|
14940
|
+
const validTerrainHeight = is2DMode || terrainHeight < -500 || terrainHeight >= 1e4 ? 0 : terrainHeight;
|
|
13829
14941
|
const earthRadius = 6371e3;
|
|
13830
|
-
const
|
|
14942
|
+
const avgLat = (paddedSouth + paddedNorth) / 2;
|
|
14943
|
+
const latRad = avgLat * (Math.PI / 180);
|
|
14944
|
+
const rectWidth = (paddedEast - paddedWest) * (Math.PI / 180) * earthRadius * Math.cos(latRad);
|
|
13831
14945
|
const rectHeight = (paddedNorth - paddedSouth) * (Math.PI / 180) * earthRadius;
|
|
13832
14946
|
const frustum = camera.frustum;
|
|
13833
14947
|
const fovy = frustum.fovy || frustum.fov || C.Math.toRadians(60);
|
|
13834
14948
|
const canvas = this.viewer.scene.canvas;
|
|
13835
14949
|
const aspectRatio = canvas.width / canvas.height;
|
|
13836
|
-
const fovx = 2 * Math.atan(Math.tan(fovy / 2) * aspectRatio);
|
|
13837
14950
|
const absPitch = Math.abs(pitch);
|
|
13838
|
-
const sinPitch = Math.sin(absPitch)
|
|
13839
|
-
const
|
|
13840
|
-
|
|
13841
|
-
|
|
14951
|
+
const sinPitch = Math.sin(absPitch);
|
|
14952
|
+
const tanHalfFovy = Math.tan(fovy / 2);
|
|
14953
|
+
let viewHeight;
|
|
14954
|
+
if (absPitch > C.Math.toRadians(80)) {
|
|
14955
|
+
const heightForVertical = rectHeight / (2 * tanHalfFovy);
|
|
14956
|
+
const heightForHorizontal = rectWidth / (2 * tanHalfFovy * aspectRatio);
|
|
14957
|
+
viewHeight = Math.max(heightForVertical, heightForHorizontal);
|
|
14958
|
+
} else {
|
|
14959
|
+
const heightForVertical = sinPitch > 0.1 ? rectHeight / (2 * tanHalfFovy * sinPitch) : rectHeight / (2 * tanHalfFovy);
|
|
14960
|
+
const heightForHorizontal = rectWidth / (2 * tanHalfFovy * aspectRatio);
|
|
14961
|
+
viewHeight = Math.max(heightForVertical, heightForHorizontal);
|
|
14962
|
+
}
|
|
14963
|
+
viewHeight = Math.max(minHeight, Math.min(maxHeight, viewHeight * 1.2));
|
|
14964
|
+
const altitude = validTerrainHeight + viewHeight;
|
|
13842
14965
|
const destination = C.Cartesian3.fromDegrees(bounds.centerLon, bounds.centerLat, altitude);
|
|
13843
14966
|
const orientation = { heading, pitch, roll: 0 };
|
|
13844
14967
|
if (duration > 0) {
|
|
@@ -13846,7 +14969,6 @@ var MassPolygonManager = class {
|
|
|
13846
14969
|
} else {
|
|
13847
14970
|
camera.setView({ destination, orientation });
|
|
13848
14971
|
}
|
|
13849
|
-
console.log(`[MassPolygonManager] \u98DE\u884C\u5230\u8FB9\u754C: \u4E2D\u5FC3(${bounds.centerLon.toFixed(6)}, ${bounds.centerLat.toFixed(6)}), \u9AD8\u5EA6: ${altitude.toFixed(0)}m`);
|
|
13850
14972
|
}
|
|
13851
14973
|
/**
|
|
13852
14974
|
* 设置可见性
|
|
@@ -13855,7 +14977,12 @@ var MassPolygonManager = class {
|
|
|
13855
14977
|
if (this.layerCollection) {
|
|
13856
14978
|
this.layerCollection.show = visible;
|
|
13857
14979
|
}
|
|
13858
|
-
this.viewer
|
|
14980
|
+
if (this.viewer?.scene) {
|
|
14981
|
+
try {
|
|
14982
|
+
this.viewer.scene.requestRender();
|
|
14983
|
+
} catch (e) {
|
|
14984
|
+
}
|
|
14985
|
+
}
|
|
13859
14986
|
}
|
|
13860
14987
|
/**
|
|
13861
14988
|
* 更新样式(需要重新创建所有多边形)
|
|
@@ -13879,6 +15006,10 @@ var MassPolygonManager = class {
|
|
|
13879
15006
|
this.clickHandler.destroy();
|
|
13880
15007
|
this.clickHandler = void 0;
|
|
13881
15008
|
}
|
|
15009
|
+
if (this.rightClickHandler) {
|
|
15010
|
+
this.rightClickHandler.destroy();
|
|
15011
|
+
this.rightClickHandler = void 0;
|
|
15012
|
+
}
|
|
13882
15013
|
this.highlightedId = void 0;
|
|
13883
15014
|
this.selectedId = void 0;
|
|
13884
15015
|
this.originalHighlightFillColor = void 0;
|
|
@@ -13886,20 +15017,32 @@ var MassPolygonManager = class {
|
|
|
13886
15017
|
this.originalSelectFillColor = void 0;
|
|
13887
15018
|
this.originalSelectOutlineColor = void 0;
|
|
13888
15019
|
this.hoverLabel = void 0;
|
|
13889
|
-
|
|
13890
|
-
|
|
15020
|
+
this.highlightPrimitive = void 0;
|
|
15021
|
+
this.selectPrimitive = void 0;
|
|
15022
|
+
if (this.layerCollection && this.viewer?.scene?.primitives) {
|
|
15023
|
+
try {
|
|
15024
|
+
this.viewer.scene.primitives.remove(this.layerCollection);
|
|
15025
|
+
} catch (e) {
|
|
15026
|
+
}
|
|
13891
15027
|
this.layerCollection = void 0;
|
|
13892
15028
|
}
|
|
13893
15029
|
this.primitive = void 0;
|
|
13894
15030
|
this.outlinePrimitive = void 0;
|
|
15031
|
+
this.groundOutlinePrimitive = void 0;
|
|
13895
15032
|
this.labelCollection = void 0;
|
|
13896
15033
|
this.polygonDataMap.clear();
|
|
13897
|
-
this.viewer
|
|
15034
|
+
if (this.viewer?.scene) {
|
|
15035
|
+
try {
|
|
15036
|
+
this.viewer.scene.requestRender();
|
|
15037
|
+
} catch (e) {
|
|
15038
|
+
}
|
|
15039
|
+
}
|
|
13898
15040
|
}
|
|
13899
15041
|
/**
|
|
13900
15042
|
* 销毁并释放资源
|
|
13901
15043
|
*/
|
|
13902
15044
|
destroy() {
|
|
15045
|
+
this.isDestroyed = true;
|
|
13903
15046
|
this.clear();
|
|
13904
15047
|
}
|
|
13905
15048
|
/**
|
|
@@ -14285,6 +15428,6 @@ var LODManager = class {
|
|
|
14285
15428
|
var placeholder = { ready: true };
|
|
14286
15429
|
var droneModelUrl = wurenji_default;
|
|
14287
15430
|
|
|
14288
|
-
export { AirplaneCursor, CZMLManager, CameraEventBus, CameraFOVController, CameraManager, Emitter, FlightSimulator, FrustumPyramid, LODManager, LayerManager, MassPolygonManager, PathSafetyChecker, PointCloudPicker, PolygonEditor, RealtimeFlightTracker, SceneManager, Selector, StateManager, assertCesiumAssetsConfigured, bringDataSourceToTop, bringPrimitiveCollectionToTop, calculateAbsoluteHeight, calculateBoundsDiagonal, calculateDistance, calculateDistanceAndMidpoint, calculateGeoBounds, calculateHeadingBetweenPoints, calculateMidpoint, calculateRelativeHeight, configureCesiumAssets, configureCesiumIonToken, convertPathToSinofly, convertSinoflyWayline, convertSinoflyWaylines, droneModelUrl, ensureCesiumIonToken, ensureLayerAbove, expandBounds, getCesiumBaseUrl, getCesiumIonToken, getDataSourceIndex, getDataSourceOrder, globalCameraEventBus, globalState, isPointInBounds, mergeBounds, placeholder, queryTerrainHeightAsync, queryTerrainHeightByLonLat, queryTerrainHeightByLonLatSync, queryTerrainHeightSync, queryTerrainHeights, queryTerrainHeightsByLonLat, renderFlightPath, renderFlightPathPreview, toggle2D3D, version, versionInfo };
|
|
15431
|
+
export { AirplaneCursor, CZMLManager, CameraEventBus, CameraFOVController, CameraManager, Emitter, FlightSimulator, FrustumPyramid, ImageryManager, LODManager, LayerManager, MassPolygonManager, PathSafetyChecker, PointCloudPicker, PolygonEditor, RealtimeFlightTracker, SceneManager, Selector, StateManager, TerrainManager, TilesetManager, assertCesiumAssetsConfigured, bringDataSourceToTop, bringPrimitiveCollectionToTop, calculateAbsoluteHeight, calculateBoundsDiagonal, calculateDistance, calculateDistanceAndMidpoint, calculateGeoBounds, calculateHeadingBetweenPoints, calculateMidpoint, calculateRelativeHeight, configureCesiumAssets, configureCesiumIonToken, convertPathToSinofly, convertSinoflyWayline, convertSinoflyWaylines, droneModelUrl, ensureCesiumIonToken, ensureLayerAbove, expandBounds, getCesiumBaseUrl, getCesiumIonToken, getDataSourceIndex, getDataSourceOrder, globalCameraEventBus, globalState, isPointInBounds, mergeBounds, placeholder, queryTerrainHeightAsync, queryTerrainHeightByLonLat, queryTerrainHeightByLonLatSync, queryTerrainHeightSync, queryTerrainHeights, queryTerrainHeightsByLonLat, renderFlightPath, renderFlightPathPreview, toggle2D3D, version, versionInfo };
|
|
14289
15432
|
//# sourceMappingURL=index.js.map
|
|
14290
15433
|
//# sourceMappingURL=index.js.map
|