@juun-roh/cesium-utils 0.0.2 → 0.0.3

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/README.md CHANGED
@@ -13,13 +13,13 @@ A utility library for Cesium.js that simplifies working with collections and ter
13
13
 
14
14
  ```bash
15
15
  # npm
16
- npm install @juun_roh/cesium-utils
16
+ npm install @juun-roh/cesium-utils
17
17
 
18
18
  # yarn
19
- yarn add @juun_roh/cesium-utils
19
+ yarn add @juun-roh/cesium-utils
20
20
 
21
21
  # pnpm
22
- pnpm add @juun_roh/cesium-utils
22
+ pnpm add @juun-roh/cesium-utils
23
23
  ```
24
24
 
25
25
  ## Browser Compatibility
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";var k=Object.defineProperty;var H=Object.getOwnPropertyDescriptor;var Y=Object.getOwnPropertyNames;var q=Object.prototype.hasOwnProperty;var W=(n,e)=>{for(var t in e)k(n,t,{get:e[t],enumerable:!0})},$=(n,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of Y(e))!q.call(n,i)&&i!==t&&k(n,i,{get:()=>e[i],enumerable:!(r=H(e,i))||r.enumerable});return n};var U=n=>$(k({},"__esModule",{value:!0}),n);var X={};W(X,{Collection:()=>R,HybridTerrainProvider:()=>_,TerrainArea:()=>v,TerrainBounds:()=>h,TerrainVisualizer:()=>C,cloneViewer:()=>D,syncCameraState:()=>B});module.exports=U(X);var y=require("cesium"),M=class n{static symbol=Symbol("cesium-item-tag");tag;collection;_valuesCache=null;_tagMap=new Map;_eventListeners=new Map;constructor({collection:e,tag:t}){this.tag=t||"default",this.collection=e}_emit(e,t){let r=this._eventListeners.get(e);if(r){let i={type:e,...t};r.forEach(o=>o(i))}}_addToTagMap(e,t){this._tagMap.has(t)||this._tagMap.set(t,new Set),this._tagMap.get(t)?.add(e)}_removeFromTagMap(e){let t=e[n.symbol],r=this._tagMap.get(t);r&&(r.delete(e),r.size===0&&this._tagMap.delete(t))}_invalidateCache(){this._valuesCache=null}addEventListener(e,t){return this._eventListeners.has(e)||this._eventListeners.set(e,new Set),this._eventListeners.get(e)?.add(t),this}removeEventListener(e,t){return this._eventListeners.get(e)?.delete(t),this}add(e,t=this.tag,r){return Array.isArray(e)?e.forEach(i=>{this.add(i)}):(Object.defineProperty(e,n.symbol,{value:t,enumerable:!1,writable:!0,configurable:!0}),this.collection.add(e,r),this._addToTagMap(e,t),this._invalidateCache(),this._emit("add",{items:[e],tag:t})),e}contains(e){return this.collection.contains(e)}remove(e){let t=this.collection.remove(e);return t&&(this._removeFromTagMap(e),this._invalidateCache(),this._emit("remove",{items:[e]})),t}removeAll(){this._tagMap.clear(),this.collection.removeAll(),this._invalidateCache(),this._emit("clear")}get values(){if(this._valuesCache)return this._valuesCache;if(this.collection instanceof y.EntityCollection)this._valuesCache=this.collection.values||[];else{let e=[];for(let t=0;t<this.collection.length;t++)e.push(this.collection.get(t));this._valuesCache=e}return this._valuesCache}get length(){return this.values?.length||0}getByTag(e){let t=this._tagMap.get(e);return t?Array.from(t):[]}getFirstByTag(e){let t=this._tagMap.get(e);if(t&&t.size>0)return t.values().next().value}getTags(){return Array.from(this._tagMap.keys())}hasTag(e){let t=this._tagMap.get(e);return!!t&&t.size>0}updateTag(e,t){let r=this.getByTag(e);for(let i of r)this._removeFromTagMap(i),Object.defineProperty(i,n.symbol,t),this._addToTagMap(i,t);return r.length>0&&this._emit("update",{items:r,tag:t}),r.length}removeByTag(e){let t=0;return Array.isArray(e)?e.forEach(r=>{this.removeByTag(r)}):this.getByTag(e).forEach(r=>{this.remove(r)&&t++}),t}show(e){let t=this.getByTag(e),r=0;for(let i of t)(0,y.defined)(i.show)&&(i.show=!0,r++);return r}hide(e){let t=this.getByTag(e),r=0;for(let i of t)(0,y.defined)(i.show)&&(i.show=!1,r++);return r}toggle(e){let t=this.getByTag(e),r=0;for(let i of t)(0,y.defined)(i.show)&&(i.show=!i.show,r++);return r}setProperty(e,t,r){let i=this.getByTag(e),o=0;for(let a of i)t in a?(a[t]=r,o++):console.warn(`${t} does not exists in ${a}`);return o}filter(e,t){return(t?this.getByTag(t):this.values).filter(e)}forEach(e,t){(t?this.getByTag(t):this.values).forEach((i,o)=>e(i,o))}},R=M;var f=require("cesium");var O=require("cesium");var m=require("cesium"),h=class{_rectangle;_tilingScheme;_tileRanges;_levels;constructor(e,t){if(this._tilingScheme=t||new m.GeographicTilingScheme,this._rectangle=new m.Rectangle,this._tileRanges=new Map,this._levels=new Set,e.type==="rectangle"&&e.rectangle)this._rectangle=m.Rectangle.clone(e.rectangle);else if(e.type==="tileRange"&&e.tileRanges)e.tileRanges instanceof Map?this._tileRanges=new Map(e.tileRanges):this._tileRanges=new Map(Object.entries(e.tileRanges).map(([r,i])=>[parseInt(r),i])),this._calculateRectangleFromTileRanges();else throw new Error("Either rectangle or tileRanges must be provided.");this._levels=new Set(Array.from(this._tileRanges.keys()))}contains(e,t,r){if(this._tileRanges.has(r)){let o=this._tileRanges.get(r);return e>=o.start.x&&e<=o.end.x&&t>=o.start.y&&t<=o.end.y}let i=this._tilingScheme.tileXYToRectangle(e,t,r);return m.Rectangle.intersection(i,this._rectangle)!==void 0}configureAvailability(e){if(e.availability){e.availability._tilingScheme&&(e.availability._tilingScheme=this._tilingScheme);for(let[t,r]of this._tileRanges.entries())e.availability.addAvailableTileRange(t,r.start.x,r.start.y,r.end.x,r.end.y)}}get rectangle(){return this._rectangle}get tilingScheme(){return this._tilingScheme}get tileRanges(){return this._tileRanges}get levels(){return this._levels}_calculateRectangleFromTileRanges(){let e=Number.POSITIVE_INFINITY,t=Number.POSITIVE_INFINITY,r=Number.NEGATIVE_INFINITY,i=Number.NEGATIVE_INFINITY,o=Array.from(this._tileRanges.keys());if(o.length===0){this._rectangle=m.Rectangle.MAX_VALUE;return}let a=Math.min(...o),s=this._tileRanges.get(a);if(s){let{start:c,end:d}=s,b=this._tilingScheme.tileXYToRectangle(c.x,c.y,a),u=this._tilingScheme.tileXYToRectangle(d.x,d.y,a);e=Math.min(b.west,e),t=Math.min(u.south,t),r=Math.max(u.east,r),i=Math.max(b.north,i)}this._rectangle=new m.Rectangle(e,t,r,i)}};(t=>{function n(r,i,o,a=new m.GeographicTilingScheme){let s=new Map;return s.set(o,{start:{x:r,y:i},end:{x:r,y:i}}),new t({type:"tileRange",tileRanges:s},a)}t.fromTile=n;function e(r,i=new m.GeographicTilingScheme){return new t({type:"rectangle",rectangle:m.Rectangle.clone(r)},i)}t.fromRectangle=e})(h||={});var v=class n{_provider;_bounds;_levels;_ready=!1;_credit;_isCustom;constructor(e,t){this._bounds=e.bounds instanceof h?e.bounds:new h(e.bounds),this._levels=new Set(e.levels||[]),this._credit=e.credit||"custom",this._isCustom=e.isCustom!==void 0?e.isCustom:!0,this._provider=t,this._ready=!0,this._bounds.configureAvailability(this._provider)}static async create(e){let t;return typeof e.provider=="string"?t=await O.CesiumTerrainProvider.fromUrl(e.provider,{requestVertexNormals:!0,credit:e.credit||"custom"}):t=e.provider,new n(e,t)}contains(e,t,r){return this._levels.size>0&&!this._levels.has(r)?!1:this._bounds.contains(e,t,r)}requestTileGeometry(e,t,r,i){if(!(!this._ready||!this.contains(e,t,r)||!this._provider?.getTileDataAvailable(e,t,r)))return this._provider.requestTileGeometry(e,t,r,i)}getTileDataAvailable(e,t,r){return!this.contains(e,t,r)||!this._ready?!1:this._provider?.getTileDataAvailable(e,t,r)??!1}get isCustom(){return this._isCustom}get credit(){return this._credit}get provider(){return this._provider}get bounds(){return this._bounds}get levels(){return this._levels}get ready(){return this._ready}};(e=>{async function n(t,r,i,o="custom"){let a=new h({type:"tileRange",tileRanges:r});return await e.create({provider:t,bounds:a,levels:i||Object.keys(r).map(c=>parseInt(c)),credit:o})}e.fromUrl=n})(v||={});var I=class extends Array{async add(e){let t;return e instanceof v?t=e:t=await v.create(e),this.push(t)}remove(e){let t=this.indexOf(e);return t>=0?(this.splice(t,1),!0):!1}clear(){this.length=0}},_=class n{_terrainAreas=new I;_terrainProvider;_fallbackProvider;_tilingScheme;_ready=!1;_availability;constructor(e,t,r){this._terrainProvider=e,this._fallbackProvider=t,this._tilingScheme=e.tilingScheme||new f.GeographicTilingScheme,this._terrainAreas=new I(...r),this._availability=e.availability,this._ready=!0}static async create(e){try{let t;typeof e.terrainProvider=="string"?t=await f.CesiumTerrainProvider.fromUrl(e.terrainProvider,{requestVertexNormals:!0}):t=e.terrainProvider;let r;e.fallbackProvider?typeof e.fallbackProvider=="string"?r=await f.CesiumTerrainProvider.fromUrl(e.fallbackProvider,{requestVertexNormals:!0}):r=e.fallbackProvider:r=new f.EllipsoidTerrainProvider;let i=[];for(let o of e.terrainAreas){let a=await v.create(o);i.push(a)}return new n(t,r,i)}catch(t){throw console.error("Failed to initialize HybridTerrainProvider:",t),t}}get ready(){return this._ready}get tilingScheme(){return this._tilingScheme}get availability(){return this._availability}get terrainAreas(){return[...this._terrainAreas]}get defaultProvider(){return this._terrainProvider}get fallbackProvider(){return this._fallbackProvider}get credit(){return this._terrainProvider?.credit}get errorEvent(){return this._terrainProvider.errorEvent}get hasWaterMask(){return this._terrainProvider.hasWaterMask}get hasVertexNormals(){return this._terrainProvider.hasVertexNormals}loadTileDataAvailability(e,t,r){return this._terrainProvider.loadTileDataAvailability(e,t,r)}getLevelMaximumGeometricError(e){return this._terrainProvider.getLevelMaximumGeometricError(e)}requestTileGeometry(e,t,r,i){if(this._ready){for(let o of this._terrainAreas)if(o.contains(e,t,r))return o.requestTileGeometry(e,t,r,i);return this._terrainProvider.getTileDataAvailable(e,t,r)?this._terrainProvider.requestTileGeometry(e,t,r,i):this._fallbackProvider.requestTileGeometry(e,t,r,i)}}getTileDataAvailable(e,t,r){return this._terrainAreas.forEach(i=>{if(i.contains(e,t,r)&&i.getTileDataAvailable(e,t,r))return!0}),this._terrainProvider.getTileDataAvailable(e,t,r)||!0}};(e=>{async function n(t,r,i,o){return e.create({terrainAreas:[{provider:t,bounds:{type:"tileRange",tileRanges:i},levels:o||Object.keys(i).map(a=>parseInt(a)),credit:"custom"}],terrainProvider:r,fallbackProvider:new f.EllipsoidTerrainProvider})}e.createOverlay=n})(_||={});var l=require("cesium");var E=class extends R{},C=class n{_viewer;_collection;_hybridTerrain;_visible=!1;_level=15;_tileCoordinatesLayer;_colors=new Map([["custom",l.Color.RED],["default",l.Color.BLUE],["fallback",l.Color.GRAY],["grid",l.Color.YELLOW]]);constructor(e,t){this._viewer=e,this._collection=new E({collection:e.entities,tag:n.tag.default}),t&&(t.colors&&Object.entries(t.colors).forEach(([r,i])=>{this._colors.set(r,i)}),t.tile!==void 0&&(this._visible=t.tile),t.activeLevel!==void 0&&(this._level=t.activeLevel),t.terrainProvider&&this.setTerrainProvider(t.terrainProvider))}setTerrainProvider(e){this._hybridTerrain=e,this.update()}update(){this.clear(),this._visible&&this.show(this._level)}clear(){this._collection.removeByTag(this._collection.getTags())}show(e=15){if(!this._hybridTerrain)return;this._collection.removeByTag(n.tag.grid),this._level=e;let t=this._hybridTerrain.tilingScheme;this._tileCoordinatesLayer||(this._tileCoordinatesLayer=this._viewer.imageryLayers.addImageryProvider(new l.TileCoordinatesImageryProvider({tilingScheme:t,color:l.Color.YELLOW})));let r=(a,s,c)=>{if(this._hybridTerrain){for(let d of this._hybridTerrain.terrainAreas)if(d.contains(a,s,c))return d.isCustom?this._colors.get("custom")||l.Color.RED:this._colors.get("default")||l.Color.BLUE;if(this._hybridTerrain.getTileDataAvailable(a,s,c))return this._colors.get("default")||l.Color.BLUE}return this._colors.get("fallback")||l.Color.TRANSPARENT},i=this._getVisibleRectangle();if(!i)return;function o(a){return a&&Number.isFinite(a.west)&&Number.isFinite(a.south)&&Number.isFinite(a.east)&&Number.isFinite(a.north)&&a.west<=a.east&&a.south<=a.north}if(!o(i)){console.warn("Invalid visible rectangle detected, skipping grid display");return}try{let a=t.positionToTileXY(l.Rectangle.northwest(i),e),s=t.positionToTileXY(l.Rectangle.southeast(i),e);if(!a||!s)return;let c=100,d=Math.min(s.x-a.x+1,c),b=Math.min(s.y-a.y+1,c);for(let u=a.x;u<=a.x+d-1;u++)for(let T=a.y;T<=a.y+b-1;T++)try{let g=t.tileXYToRectangle(u,T,e);if(!o(g)){console.warn(`Invalid rectangle for tile (${u}, ${T}, ${e}), skipping`);continue}let P=r(u,T,e),p=n.createRectangle(g,P.withAlpha(.3));p.properties?.addProperty("tileX",u),p.properties?.addProperty("tileY",T),p.properties?.addProperty("tileLevel",e),this._collection.add(p,n.tag.grid)}catch(g){console.warn(`Error creating tile (${u}, ${T}, ${e}): ${g.message}`);continue}console.log("\u{1F680} ~ TerrainVisualizer ~ showGrid ~ collection:",this._collection),this._visible=!0}catch(a){console.error("Error displaying tile grid:",a)}}hide(){this._collection.removeByTag(n.tag.grid),this._tileCoordinatesLayer&&(this._viewer.imageryLayers.remove(this._tileCoordinatesLayer),this._tileCoordinatesLayer=void 0),this._visible=!1}setColors(e){Object.entries(e).forEach(([t,r])=>{this._colors.set(t,r)}),this.update()}flyTo(e,t){let{rectangle:r}=e.bounds;this._viewer.camera.flyTo({destination:r,...t,complete:()=>{this._visible&&this.update()}})}_getVisibleRectangle(){return this._viewer.camera.computeViewRectangle()}get level(){return this._level}set level(e){this._level=e,this._visible&&this.update()}get visible(){return this._visible}get collection(){return this._collection}get viewer(){return this._viewer}};(r=>{r.tag={default:"Terrain Visualizer",boundary:"Terrain Visualizer Boundary",grid:"Terrain Visualizer Tile Grid"};function e(i,o){return new l.Entity({rectangle:{coordinates:i,material:o,heightReference:l.HeightReference.CLAMP_TO_GROUND}})}r.createRectangle=e;function t(i,o,a){let s=a?.tag||"terrain_area_visualization",c=a?.color||l.Color.RED,d=a?.maxTilesToShow||100,b=a?.show!==void 0?a.show:!0,u=a?.alpha||.7,T=a?.tileAlpha||.2,g="provider"in i?i.bounds:i,P=new E({collection:o.entities,tag:s}),{rectangle:p}=g;if(P.add(r.createRectangle(p,c.withAlpha(u)),s),b&&g.levels.size>0){let{tilingScheme:N}=g;g.levels.forEach(V=>{let S=0,{tileRanges:G}=g;for(let[z,A]of G.entries())if(z===V)for(let x=A.start.x;x<=A.end.x&&S<d;x++)for(let L=A.start.y;L<=A.end.y&&S<d;L++){let F=N.tileXYToRectangle(x,L,V);P.add(e(F,c.withAlpha(T)),`${s}_tile`),S++}})}return P}r.visualize=t})(C||={});var w=require("cesium");function D(n,e,t){let r={baseLayerPicker:n.baseLayerPicker!==void 0,geocoder:n.geocoder!==void 0,homeButton:n.homeButton!==void 0,sceneModePicker:n.sceneModePicker!==void 0,timeline:n.timeline!==void 0,navigationHelpButton:n.navigationHelpButton!==void 0,animation:n.animation!==void 0,fullscreenButton:n.fullscreenButton!==void 0,shouldAnimate:n.clock.shouldAnimate,terrainProvider:n.terrainProvider,requestRenderMode:n.scene.requestRenderMode,infoBox:n.infoBox!==void 0},i=new w.Viewer(e,{...r,...t});B(n,i);let o=n.imageryLayers;i.imageryLayers.removeAll();for(let c=0;c<o.length;c++){let d=o.get(c);i.imageryLayers.addImageryProvider(d.imageryProvider,c)}i.clock.startTime=n.clock.startTime.clone(),i.clock.stopTime=n.clock.stopTime.clone(),i.clock.currentTime=n.clock.currentTime.clone(),i.clock.multiplier=n.clock.multiplier,i.clock.clockStep=n.clock.clockStep,i.clock.clockRange=n.clock.clockRange,i.clock.shouldAnimate=n.clock.shouldAnimate,i.scene.globe.enableLighting=n.scene.globe.enableLighting,i.scene.globe.depthTestAgainstTerrain=n.scene.globe.depthTestAgainstTerrain,i.scene.screenSpaceCameraController.enableCollisionDetection=n.scene.screenSpaceCameraController.enableCollisionDetection;let a=n.scene.screenSpaceCameraController.tiltEventTypes;a&&(i.scene.screenSpaceCameraController.tiltEventTypes=Array.isArray(a)?[...a]:a);let s=n.scene.screenSpaceCameraController.zoomEventTypes;return s&&(i.scene.screenSpaceCameraController.zoomEventTypes=Array.isArray(s)?[...s]:s),i}function B(n,e){if((0,w.defined)(n)&&(0,w.defined)(e)){let{camera:t}=n;e.camera.position=t.positionWC.clone(),e.camera.direction=t.directionWC.clone(),e.camera.up=t.upWC.clone()}}
1
+ "use strict";var L=Object.defineProperty;var H=Object.getOwnPropertyDescriptor;var Y=Object.getOwnPropertyNames;var q=Object.prototype.hasOwnProperty;var z=(n,e)=>{for(var t in e)L(n,t,{get:e[t],enumerable:!0})},W=(n,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of Y(e))!q.call(n,i)&&i!==t&&L(n,i,{get:()=>e[i],enumerable:!(r=H(e,i))||r.enumerable});return n};var $=n=>W(L({},"__esModule",{value:!0}),n);var U={};z(U,{Collection:()=>P,HybridTerrainProvider:()=>_,TerrainArea:()=>v,TerrainBounds:()=>h,TerrainVisualizer:()=>A,cloneViewer:()=>O,syncCameraState:()=>M});module.exports=$(U);var p=require("cesium"),k=class n{static symbol=Symbol("cesium-item-tag");tag;collection;_valuesCache=null;_tagMap=new Map;_eventListeners=new Map;constructor({collection:e,tag:t}){this.tag=t||"default",this.collection=e}_emit(e,t){let r=this._eventListeners.get(e);if(r){let i={type:e,...t};r.forEach(o=>o(i))}}_addToTagMap(e,t){this._tagMap.has(t)||this._tagMap.set(t,new Set),this._tagMap.get(t)?.add(e)}_removeFromTagMap(e){let t=e[n.symbol],r=this._tagMap.get(t);r&&(r.delete(e),r.size===0&&this._tagMap.delete(t))}_invalidateCache(){this._valuesCache=null}addEventListener(e,t){return this._eventListeners.has(e)||this._eventListeners.set(e,new Set),this._eventListeners.get(e)?.add(t),this}removeEventListener(e,t){return this._eventListeners.get(e)?.delete(t),this}add(e,t=this.tag,r){return Array.isArray(e)?e.forEach(i=>{this.add(i)}):(Object.defineProperty(e,n.symbol,{value:t,enumerable:!1,writable:!0,configurable:!0}),this.collection.add(e,r),this._addToTagMap(e,t),this._invalidateCache(),this._emit("add",{items:[e],tag:t})),e}contains(e){return this.collection.contains(e)}remove(e){let t=this.collection.remove(e);return t&&(this._removeFromTagMap(e),this._invalidateCache(),this._emit("remove",{items:[e]})),t}removeAll(){this._tagMap.clear(),this.collection.removeAll(),this._invalidateCache(),this._emit("clear")}get values(){if(this._valuesCache)return this._valuesCache;if(this.collection instanceof p.EntityCollection)this._valuesCache=this.collection.values||[];else{let e=[];for(let t=0;t<this.collection.length;t++)e.push(this.collection.get(t));this._valuesCache=e}return this._valuesCache}get length(){return this.values?.length||0}getByTag(e){let t=this._tagMap.get(e);return t?Array.from(t):[]}getFirstByTag(e){let t=this._tagMap.get(e);if(t&&t.size>0)return t.values().next().value}getTags(){return Array.from(this._tagMap.keys())}hasTag(e){let t=this._tagMap.get(e);return!!t&&t.size>0}updateTag(e,t){let r=this.getByTag(e);for(let i of r)this._removeFromTagMap(i),Object.defineProperty(i,n.symbol,t),this._addToTagMap(i,t);return r.length>0&&this._emit("update",{items:r,tag:t}),r.length}removeByTag(e){let t=0;return Array.isArray(e)?e.forEach(r=>{this.removeByTag(r)}):this.getByTag(e).forEach(r=>{this.remove(r)&&t++}),t}show(e){let t=this.getByTag(e),r=0;for(let i of t)(0,p.defined)(i.show)&&(i.show=!0,r++);return r}hide(e){let t=this.getByTag(e),r=0;for(let i of t)(0,p.defined)(i.show)&&(i.show=!1,r++);return r}toggle(e){let t=this.getByTag(e),r=0;for(let i of t)(0,p.defined)(i.show)&&(i.show=!i.show,r++);return r}setProperty(e,t,r){let i=this.getByTag(e),o=0;for(let a of i)t in a?(a[t]=r,o++):console.warn(`${t} does not exists in ${a}`);return o}filter(e,t){return(t?this.getByTag(t):this.values).filter(e)}forEach(e,t){(t?this.getByTag(t):this.values).forEach((i,o)=>e(i,o))}},P=k;var f=require("cesium");var V=require("cesium");var m=require("cesium"),h=class{_rectangle;_tilingScheme;_tileRanges;_levels;constructor(e,t){if(this._tilingScheme=t||new m.GeographicTilingScheme,this._rectangle=new m.Rectangle,this._tileRanges=new Map,this._levels=new Set,e.type==="rectangle"&&e.rectangle)this._rectangle=m.Rectangle.clone(e.rectangle);else if(e.type==="tileRange"&&e.tileRanges)e.tileRanges instanceof Map?this._tileRanges=new Map(e.tileRanges):this._tileRanges=new Map(Object.entries(e.tileRanges).map(([r,i])=>[parseInt(r),i])),this._calculateRectangleFromTileRanges();else throw new Error("Either rectangle or tileRanges must be provided.");this._levels=new Set(Array.from(this._tileRanges.keys()))}contains(e,t,r){if(this._tileRanges.has(r)){let o=this._tileRanges.get(r);return e>=o.start.x&&e<=o.end.x&&t>=o.start.y&&t<=o.end.y}let i=this._tilingScheme.tileXYToRectangle(e,t,r);return m.Rectangle.intersection(i,this._rectangle)!==void 0}configureAvailability(e){if(e.availability){e.availability._tilingScheme&&(e.availability._tilingScheme=this._tilingScheme);for(let[t,r]of this._tileRanges.entries())e.availability.addAvailableTileRange(t,r.start.x,r.start.y,r.end.x,r.end.y)}}get rectangle(){return this._rectangle}get tilingScheme(){return this._tilingScheme}get tileRanges(){return this._tileRanges}get levels(){return this._levels}_calculateRectangleFromTileRanges(){let e=Number.POSITIVE_INFINITY,t=Number.POSITIVE_INFINITY,r=Number.NEGATIVE_INFINITY,i=Number.NEGATIVE_INFINITY,o=Array.from(this._tileRanges.keys());if(o.length===0){this._rectangle=m.Rectangle.MAX_VALUE;return}let a=Math.min(...o),s=this._tileRanges.get(a);if(s){let{start:c,end:d}=s,b=this._tilingScheme.tileXYToRectangle(c.x,c.y,a),u=this._tilingScheme.tileXYToRectangle(d.x,d.y,a);e=Math.min(b.west,e),t=Math.min(u.south,t),r=Math.max(u.east,r),i=Math.max(b.north,i)}this._rectangle=new m.Rectangle(e,t,r,i)}};(t=>{function n(r,i,o,a=new m.GeographicTilingScheme){let s=new Map;return s.set(o,{start:{x:r,y:i},end:{x:r,y:i}}),new t({type:"tileRange",tileRanges:s},a)}t.fromTile=n;function e(r,i=new m.GeographicTilingScheme){return new t({type:"rectangle",rectangle:m.Rectangle.clone(r)},i)}t.fromRectangle=e})(h||={});var v=class n{_provider;_bounds;_levels;_ready=!1;_credit;_isCustom;constructor(e,t){this._bounds=e.bounds instanceof h?e.bounds:new h(e.bounds),this._levels=new Set(e.levels||[]),this._credit=e.credit||"custom",this._isCustom=e.isCustom!==void 0?e.isCustom:!0,this._provider=t,this._ready=!0,this._bounds.configureAvailability(this._provider)}static async create(e){let t;return typeof e.provider=="string"?t=await V.CesiumTerrainProvider.fromUrl(e.provider,{requestVertexNormals:!0,credit:e.credit||"custom"}):t=e.provider,new n(e,t)}contains(e,t,r){return this._levels.size>0&&!this._levels.has(r)?!1:this._bounds.contains(e,t,r)}requestTileGeometry(e,t,r,i){if(!(!this._ready||!this.contains(e,t,r)||!this._provider?.getTileDataAvailable(e,t,r)))return this._provider.requestTileGeometry(e,t,r,i)}getTileDataAvailable(e,t,r){return!this.contains(e,t,r)||!this._ready?!1:this._provider?.getTileDataAvailable(e,t,r)??!1}get isCustom(){return this._isCustom}get credit(){return this._credit}get provider(){return this._provider}get bounds(){return this._bounds}get levels(){return this._levels}get ready(){return this._ready}};(e=>{async function n(t,r,i,o="custom"){let a=new h({type:"tileRange",tileRanges:r});return await e.create({provider:t,bounds:a,levels:i||Object.keys(r).map(c=>parseInt(c)),credit:o})}e.fromUrl=n})(v||={});var E=class extends Array{async add(e){let t;return e instanceof v?t=e:t=await v.create(e),this.push(t)}remove(e){let t=this.indexOf(e);return t>=0?(this.splice(t,1),!0):!1}clear(){this.length=0}},_=class n{_terrainAreas=new E;_terrainProvider;_fallbackProvider;_tilingScheme;_ready=!1;_availability;constructor(e,t,r){this._terrainProvider=e,this._fallbackProvider=t,this._tilingScheme=e.tilingScheme||new f.GeographicTilingScheme,this._terrainAreas=new E(...r),this._availability=e.availability,this._ready=!0}static async create(e){try{let t;typeof e.terrainProvider=="string"?t=await f.CesiumTerrainProvider.fromUrl(e.terrainProvider,{requestVertexNormals:!0}):t=e.terrainProvider;let r;e.fallbackProvider?typeof e.fallbackProvider=="string"?r=await f.CesiumTerrainProvider.fromUrl(e.fallbackProvider,{requestVertexNormals:!0}):r=e.fallbackProvider:r=new f.EllipsoidTerrainProvider;let i=[];for(let o of e.terrainAreas){let a=await v.create(o);i.push(a)}return new n(t,r,i)}catch(t){throw console.error("Failed to initialize HybridTerrainProvider:",t),t}}get ready(){return this._ready}get tilingScheme(){return this._tilingScheme}get availability(){return this._availability}get terrainAreas(){return[...this._terrainAreas]}get defaultProvider(){return this._terrainProvider}get fallbackProvider(){return this._fallbackProvider}get credit(){return this._terrainProvider?.credit}get errorEvent(){return this._terrainProvider.errorEvent}get hasWaterMask(){return this._terrainProvider.hasWaterMask}get hasVertexNormals(){return this._terrainProvider.hasVertexNormals}loadTileDataAvailability(e,t,r){return this._terrainProvider.loadTileDataAvailability(e,t,r)}getLevelMaximumGeometricError(e){return this._terrainProvider.getLevelMaximumGeometricError(e)}requestTileGeometry(e,t,r,i){if(this._ready){for(let o of this._terrainAreas)if(o.contains(e,t,r))return o.requestTileGeometry(e,t,r,i);return this._terrainProvider.getTileDataAvailable(e,t,r)?this._terrainProvider.requestTileGeometry(e,t,r,i):this._fallbackProvider.requestTileGeometry(e,t,r,i)}}getTileDataAvailable(e,t,r){return this._terrainAreas.forEach(i=>{if(i.contains(e,t,r)&&i.getTileDataAvailable(e,t,r))return!0}),this._terrainProvider.getTileDataAvailable(e,t,r)||!0}};(e=>{async function n(t,r,i,o){return e.create({terrainAreas:[{provider:t,bounds:{type:"tileRange",tileRanges:i},levels:o||Object.keys(i).map(a=>parseInt(a)),credit:"custom"}],terrainProvider:r,fallbackProvider:new f.EllipsoidTerrainProvider})}e.createOverlay=n})(_||={});var w=require("cesium");function O(n,e,t){let r={baseLayerPicker:n.baseLayerPicker!==void 0,geocoder:n.geocoder!==void 0,homeButton:n.homeButton!==void 0,sceneModePicker:n.sceneModePicker!==void 0,timeline:n.timeline!==void 0,navigationHelpButton:n.navigationHelpButton!==void 0,animation:n.animation!==void 0,fullscreenButton:n.fullscreenButton!==void 0,shouldAnimate:n.clock.shouldAnimate,terrainProvider:n.terrainProvider,requestRenderMode:n.scene.requestRenderMode,infoBox:n.infoBox!==void 0},i=new w.Viewer(e,{...r,...t});M(n,i);let o=n.imageryLayers;i.imageryLayers.removeAll();for(let c=0;c<o.length;c++){let d=o.get(c);i.imageryLayers.addImageryProvider(d.imageryProvider,c)}i.clock.startTime=n.clock.startTime.clone(),i.clock.stopTime=n.clock.stopTime.clone(),i.clock.currentTime=n.clock.currentTime.clone(),i.clock.multiplier=n.clock.multiplier,i.clock.clockStep=n.clock.clockStep,i.clock.clockRange=n.clock.clockRange,i.clock.shouldAnimate=n.clock.shouldAnimate,i.scene.globe.enableLighting=n.scene.globe.enableLighting,i.scene.globe.depthTestAgainstTerrain=n.scene.globe.depthTestAgainstTerrain,i.scene.screenSpaceCameraController.enableCollisionDetection=n.scene.screenSpaceCameraController.enableCollisionDetection;let a=n.scene.screenSpaceCameraController.tiltEventTypes;a&&(i.scene.screenSpaceCameraController.tiltEventTypes=Array.isArray(a)?[...a]:a);let s=n.scene.screenSpaceCameraController.zoomEventTypes;return s&&(i.scene.screenSpaceCameraController.zoomEventTypes=Array.isArray(s)?[...s]:s),i}function M(n,e){if((0,w.defined)(n)&&(0,w.defined)(e)){let{camera:t}=n;e.camera.position=t.positionWC.clone(),e.camera.direction=t.directionWC.clone(),e.camera.up=t.upWC.clone()}}var l=require("cesium");var A=class n{_viewer;_collection;_hybridTerrain;_visible=!1;_level=15;_tileCoordinatesLayer;_colors=new Map([["custom",l.Color.RED],["default",l.Color.BLUE],["fallback",l.Color.GRAY],["grid",l.Color.YELLOW]]);constructor(e,t){this._viewer=e,this._collection=new P({collection:e.entities,tag:n.tag.default}),t&&(t.colors&&Object.entries(t.colors).forEach(([r,i])=>{this._colors.set(r,i)}),t.tile!==void 0&&(this._visible=t.tile),t.activeLevel!==void 0&&(this._level=t.activeLevel),t.terrainProvider&&this.setTerrainProvider(t.terrainProvider))}setTerrainProvider(e){this._hybridTerrain=e,this.update()}update(){this.clear(),this._visible&&this.show(this._level)}clear(){this._collection.removeByTag(this._collection.getTags())}show(e=15){if(!this._hybridTerrain)return;this._collection.removeByTag(n.tag.grid),this._level=e;let t=this._hybridTerrain.tilingScheme;this._tileCoordinatesLayer||(this._tileCoordinatesLayer=this._viewer.imageryLayers.addImageryProvider(new l.TileCoordinatesImageryProvider({tilingScheme:t,color:l.Color.YELLOW})));let r=(a,s,c)=>{if(this._hybridTerrain){for(let d of this._hybridTerrain.terrainAreas)if(d.contains(a,s,c))return d.isCustom?this._colors.get("custom")||l.Color.RED:this._colors.get("default")||l.Color.BLUE;if(this._hybridTerrain.getTileDataAvailable(a,s,c))return this._colors.get("default")||l.Color.BLUE}return this._colors.get("fallback")||l.Color.TRANSPARENT},i=this._getVisibleRectangle();if(!i)return;function o(a){return a&&Number.isFinite(a.west)&&Number.isFinite(a.south)&&Number.isFinite(a.east)&&Number.isFinite(a.north)&&a.west<=a.east&&a.south<=a.north}if(!o(i)){console.warn("Invalid visible rectangle detected, skipping grid display");return}try{let a=t.positionToTileXY(l.Rectangle.northwest(i),e),s=t.positionToTileXY(l.Rectangle.southeast(i),e);if(!a||!s)return;let c=100,d=Math.min(s.x-a.x+1,c),b=Math.min(s.y-a.y+1,c);for(let u=a.x;u<=a.x+d-1;u++)for(let T=a.y;T<=a.y+b-1;T++)try{let g=t.tileXYToRectangle(u,T,e);if(!o(g)){console.warn(`Invalid rectangle for tile (${u}, ${T}, ${e}), skipping`);continue}let C=r(u,T,e),y=n.createRectangle(g,C.withAlpha(.3));y.properties?.addProperty("tileX",u),y.properties?.addProperty("tileY",T),y.properties?.addProperty("tileLevel",e),this._collection.add(y,n.tag.grid)}catch(g){console.warn(`Error creating tile (${u}, ${T}, ${e}): ${g.message}`);continue}console.log("\u{1F680} ~ TerrainVisualizer ~ showGrid ~ collection:",this._collection),this._visible=!0}catch(a){console.error("Error displaying tile grid:",a)}}hide(){this._collection.removeByTag(n.tag.grid),this._tileCoordinatesLayer&&(this._viewer.imageryLayers.remove(this._tileCoordinatesLayer),this._tileCoordinatesLayer=void 0),this._visible=!1}setColors(e){Object.entries(e).forEach(([t,r])=>{this._colors.set(t,r)}),this.update()}flyTo(e,t){let{rectangle:r}=e.bounds;this._viewer.camera.flyTo({destination:r,...t,complete:()=>{this._visible&&this.update()}})}_getVisibleRectangle(){return this._viewer.camera.computeViewRectangle()}get level(){return this._level}set level(e){this._level=e,this._visible&&this.update()}get visible(){return this._visible}get collection(){return this._collection}get viewer(){return this._viewer}};(r=>{r.tag={default:"Terrain Visualizer",boundary:"Terrain Visualizer Boundary",grid:"Terrain Visualizer Tile Grid"};function e(i,o){return new l.Entity({rectangle:{coordinates:i,material:o,heightReference:l.HeightReference.CLAMP_TO_GROUND}})}r.createRectangle=e;function t(i,o,a){let s=a?.tag||"terrain_area_visualization",c=a?.color||l.Color.RED,d=a?.maxTilesToShow||100,b=a?.show!==void 0?a.show:!0,u=a?.alpha||.7,T=a?.tileAlpha||.2,g="provider"in i?i.bounds:i,C=new P({collection:o.entities,tag:s}),{rectangle:y}=g;if(C.add(r.createRectangle(y,c.withAlpha(u)),s),b&&g.levels.size>0){let{tilingScheme:D}=g;g.levels.forEach(B=>{let I=0,{tileRanges:N}=g;for(let[G,R]of N.entries())if(G===B)for(let S=R.start.x;S<=R.end.x&&I<d;S++)for(let x=R.start.y;x<=R.end.y&&I<d;x++){let F=D.tileXYToRectangle(S,x,B);C.add(e(F,c.withAlpha(T)),`${s}_tile`),I++}})}return C}r.visualize=t})(A||={});
package/dist/index.d.cts CHANGED
@@ -20,11 +20,11 @@ type EventHandler<I> = (event: {
20
20
  tag?: Tag;
21
21
  }) => void;
22
22
  /**
23
+ * @class
23
24
  * Abstract class that enhances Cesium collection objects with tagging functionality.
24
25
  * This class provides a consistent API for working with different types of Cesium collections
25
26
  * and allows grouping and manipulating collection items by custom tags.
26
27
  *
27
- * @abstract
28
28
  * @template C - The type of Cesium collection (e.g., EntityCollection, PrimitiveCollection)
29
29
  * @template I - The type of items in the collection (e.g., Entity, Primitive)
30
30
  *
@@ -48,7 +48,7 @@ type EventHandler<I> = (event: {
48
48
  * entities.show('buildings');
49
49
  * entities.hide('roads');
50
50
  */
51
- declare abstract class Collection<C extends CesiumCollection, I extends CesiumCollectionItem> {
51
+ declare class Collection<C extends CesiumCollection, I extends CesiumCollectionItem> {
52
52
  /**
53
53
  * Symbol used as a property key to store tags on collection items.
54
54
  * Using a Symbol ensures no property naming conflicts with the item's own properties.
@@ -375,8 +375,8 @@ type TileRange = {
375
375
  /** A `TileRange` map with specific levels as their keys. */
376
376
  type TileRanges = Map<number, TileRange>;
377
377
  /**
378
- * Defines the geographic boundaries for a terrain area and handles tile availability checks.
379
378
  * @class
379
+ * Defines the geographic boundaries for a terrain area and handles tile availability checks.
380
380
  */
381
381
  declare class TerrainBounds {
382
382
  private _rectangle;
@@ -408,17 +408,11 @@ declare class TerrainBounds {
408
408
  * Gets the rectangle representing these bounds.
409
409
  */
410
410
  get rectangle(): Rectangle;
411
- /**
412
- * Gets the tiling scheme used by these bounds.
413
- */
411
+ /** Gets the tiling scheme used by these bounds. */
414
412
  get tilingScheme(): TilingScheme;
415
- /**
416
- * Gets the tile ranges defined for these bounds.
417
- */
413
+ /** Gets the tile ranges defined for these bounds. */
418
414
  get tileRanges(): TileRanges;
419
- /**
420
- * Gets the levels for which tile ranges are defined.
421
- */
415
+ /** Gets the levels for which tile ranges are defined. */
422
416
  get levels(): Set<number>;
423
417
  /**
424
418
  * Calculates a bounding rectangle that encompasses all the specified tile ranges.
@@ -427,8 +421,8 @@ declare class TerrainBounds {
427
421
  private _calculateRectangleFromTileRanges;
428
422
  }
429
423
  /**
430
- * Contains types and factory methods for creating `TerrainBounds` instances.
431
424
  * @namespace
425
+ * Contains types and factory methods for creating `TerrainBounds` instances.
432
426
  */
433
427
  declare namespace TerrainBounds {
434
428
  /** Initialization options for Terrain Bounds constructor */
@@ -491,14 +485,24 @@ declare class TerrainArea {
491
485
  */
492
486
  contains(x: number, y: number, level: number): boolean;
493
487
  /**
494
- * Requests the terrain for a given tile coordinate.
495
- * @param x The X coordinate of the tile.
496
- * @param y The Y coordinate of the tile.
497
- * @param level The zoom level of the tile.
498
- * @param request The request.
499
- * @returns A promise for the requested terrain.
488
+ * Requests the geometry for a given tile. The result must include terrain data and
489
+ * may optionally include a water mask and an indication of which child tiles are available.
490
+ * @param x - The X coordinate of the tile for which to request geometry.
491
+ * @param y - The Y coordinate of the tile for which to request geometry.
492
+ * @param level - The level of the tile for which to request geometry.
493
+ * @param [request] - The request object. Intended for internal use only.
494
+ * @returns A promise for the requested geometry. If this method
495
+ * returns undefined instead of a promise, it is an indication that too many requests are already
496
+ * pending and the request will be retried later.
500
497
  */
501
498
  requestTileGeometry(x: number, y: number, level: number, request?: Request): Promise<Awaited<TerrainData>> | undefined;
499
+ /**
500
+ * Determines whether data for a tile is available to be loaded.
501
+ * @param x - The X coordinate of the tile for which to request geometry.
502
+ * @param y - The Y coordinate of the tile for which to request geometry.
503
+ * @param level - The level of the tile for which to request geometry.
504
+ * @returns Undefined if not supported by the terrain provider, otherwise true or false.
505
+ * @see {@link TerrainProvider.getTileDataAvailable} */
502
506
  getTileDataAvailable(x: number, y: number, level: number): boolean;
503
507
  /** Checks if this terrain provider is marked as a custom provider. */
504
508
  get isCustom(): boolean;
@@ -506,8 +510,11 @@ declare class TerrainArea {
506
510
  get credit(): string | Credit;
507
511
  /** Gets the terrain provider for this terrain area. */
508
512
  get provider(): TerrainProvider | undefined;
513
+ /** Gets the terrain bounds for this terrain area. */
509
514
  get bounds(): TerrainBounds;
515
+ /** Gets available zoom levels set with this terrain area. */
510
516
  get levels(): Set<number>;
517
+ /** Gets if this terrain area is ready. */
511
518
  get ready(): boolean;
512
519
  }
513
520
  /**
@@ -693,8 +700,21 @@ declare namespace HybridTerrainProvider {
693
700
  function createOverlay(customTerrainUrl: string, baseTerrainUrl: string, tileRanges: TileRanges, levels?: number[]): Promise<Awaited<HybridTerrainProvider>>;
694
701
  }
695
702
 
696
- declare class TerrainEntities extends Collection<EntityCollection, Entity> {
697
- }
703
+ /**
704
+ * Copies configuration and state from one Cesium Viewer to another.
705
+ * @param source - The source viewer to copy properties from
706
+ * @param container - DOM element ID or element for the new viewer
707
+ * @param options - Optional override options for the new viewer
708
+ * @returns A new Viewer instance with copied properties
709
+ */
710
+ declare function cloneViewer(source: Viewer, container: Element | string, options?: Viewer.ConstructorOptions): Viewer;
711
+ /**
712
+ * Copies camera state from source viewer to destination viewer.
713
+ * @param source The source viewer to copy camera states from.
714
+ * @param dest The destination viewer to apply camera properties from the source.
715
+ */
716
+ declare function syncCameraState(source: Viewer, dest: Viewer): void;
717
+
698
718
  /**
699
719
  * @class
700
720
  * Utility class for visualizing terrain provider boundaries and debugging terrain loading.
@@ -761,7 +781,7 @@ declare class TerrainVisualizer {
761
781
  /** Whether the grid is currently visible. */
762
782
  get visible(): boolean;
763
783
  /** The collection used in the visualizer. */
764
- get collection(): TerrainEntities;
784
+ get collection(): Collection<EntityCollection, Entity>;
765
785
  /** The viewer used in the visualizer */
766
786
  get viewer(): Viewer;
767
787
  }
@@ -790,7 +810,7 @@ declare namespace TerrainVisualizer {
790
810
  grid: string;
791
811
  };
792
812
  /**
793
- * Creates a rectangle entity fo r visualization.
813
+ * Creates a ground-clamped rectangle entity for visualization.
794
814
  * @param rectangle The rectangle to visualize
795
815
  * @param color The color to use
796
816
  * @returns A new entity
@@ -816,19 +836,4 @@ declare namespace TerrainVisualizer {
816
836
  function visualize(terrain: TerrainArea | TerrainBounds, viewer: Viewer, options?: Options): Collection<EntityCollection, Entity>;
817
837
  }
818
838
 
819
- /**
820
- * Copies configuration and state from one Cesium Viewer to another.
821
- * @param source - The source viewer to copy properties from
822
- * @param container - DOM element ID or element for the new viewer
823
- * @param options - Optional override options for the new viewer
824
- * @returns A new Viewer instance with copied properties
825
- */
826
- declare function cloneViewer(source: Viewer, container: Element | string, options?: Viewer.ConstructorOptions): Viewer;
827
- /**
828
- * Copies camera state from source viewer to destination viewer.
829
- * @param source The source viewer to copy camera states from.
830
- * @param dest The destination viewer to apply camera properties from the source.
831
- */
832
- declare function syncCameraState(source: Viewer, dest: Viewer): void;
833
-
834
839
  export { Collection, HybridTerrainProvider, TerrainArea, TerrainBounds, TerrainVisualizer, cloneViewer, syncCameraState };
package/dist/index.d.ts CHANGED
@@ -20,11 +20,11 @@ type EventHandler<I> = (event: {
20
20
  tag?: Tag;
21
21
  }) => void;
22
22
  /**
23
+ * @class
23
24
  * Abstract class that enhances Cesium collection objects with tagging functionality.
24
25
  * This class provides a consistent API for working with different types of Cesium collections
25
26
  * and allows grouping and manipulating collection items by custom tags.
26
27
  *
27
- * @abstract
28
28
  * @template C - The type of Cesium collection (e.g., EntityCollection, PrimitiveCollection)
29
29
  * @template I - The type of items in the collection (e.g., Entity, Primitive)
30
30
  *
@@ -48,7 +48,7 @@ type EventHandler<I> = (event: {
48
48
  * entities.show('buildings');
49
49
  * entities.hide('roads');
50
50
  */
51
- declare abstract class Collection<C extends CesiumCollection, I extends CesiumCollectionItem> {
51
+ declare class Collection<C extends CesiumCollection, I extends CesiumCollectionItem> {
52
52
  /**
53
53
  * Symbol used as a property key to store tags on collection items.
54
54
  * Using a Symbol ensures no property naming conflicts with the item's own properties.
@@ -375,8 +375,8 @@ type TileRange = {
375
375
  /** A `TileRange` map with specific levels as their keys. */
376
376
  type TileRanges = Map<number, TileRange>;
377
377
  /**
378
- * Defines the geographic boundaries for a terrain area and handles tile availability checks.
379
378
  * @class
379
+ * Defines the geographic boundaries for a terrain area and handles tile availability checks.
380
380
  */
381
381
  declare class TerrainBounds {
382
382
  private _rectangle;
@@ -408,17 +408,11 @@ declare class TerrainBounds {
408
408
  * Gets the rectangle representing these bounds.
409
409
  */
410
410
  get rectangle(): Rectangle;
411
- /**
412
- * Gets the tiling scheme used by these bounds.
413
- */
411
+ /** Gets the tiling scheme used by these bounds. */
414
412
  get tilingScheme(): TilingScheme;
415
- /**
416
- * Gets the tile ranges defined for these bounds.
417
- */
413
+ /** Gets the tile ranges defined for these bounds. */
418
414
  get tileRanges(): TileRanges;
419
- /**
420
- * Gets the levels for which tile ranges are defined.
421
- */
415
+ /** Gets the levels for which tile ranges are defined. */
422
416
  get levels(): Set<number>;
423
417
  /**
424
418
  * Calculates a bounding rectangle that encompasses all the specified tile ranges.
@@ -427,8 +421,8 @@ declare class TerrainBounds {
427
421
  private _calculateRectangleFromTileRanges;
428
422
  }
429
423
  /**
430
- * Contains types and factory methods for creating `TerrainBounds` instances.
431
424
  * @namespace
425
+ * Contains types and factory methods for creating `TerrainBounds` instances.
432
426
  */
433
427
  declare namespace TerrainBounds {
434
428
  /** Initialization options for Terrain Bounds constructor */
@@ -491,14 +485,24 @@ declare class TerrainArea {
491
485
  */
492
486
  contains(x: number, y: number, level: number): boolean;
493
487
  /**
494
- * Requests the terrain for a given tile coordinate.
495
- * @param x The X coordinate of the tile.
496
- * @param y The Y coordinate of the tile.
497
- * @param level The zoom level of the tile.
498
- * @param request The request.
499
- * @returns A promise for the requested terrain.
488
+ * Requests the geometry for a given tile. The result must include terrain data and
489
+ * may optionally include a water mask and an indication of which child tiles are available.
490
+ * @param x - The X coordinate of the tile for which to request geometry.
491
+ * @param y - The Y coordinate of the tile for which to request geometry.
492
+ * @param level - The level of the tile for which to request geometry.
493
+ * @param [request] - The request object. Intended for internal use only.
494
+ * @returns A promise for the requested geometry. If this method
495
+ * returns undefined instead of a promise, it is an indication that too many requests are already
496
+ * pending and the request will be retried later.
500
497
  */
501
498
  requestTileGeometry(x: number, y: number, level: number, request?: Request): Promise<Awaited<TerrainData>> | undefined;
499
+ /**
500
+ * Determines whether data for a tile is available to be loaded.
501
+ * @param x - The X coordinate of the tile for which to request geometry.
502
+ * @param y - The Y coordinate of the tile for which to request geometry.
503
+ * @param level - The level of the tile for which to request geometry.
504
+ * @returns Undefined if not supported by the terrain provider, otherwise true or false.
505
+ * @see {@link TerrainProvider.getTileDataAvailable} */
502
506
  getTileDataAvailable(x: number, y: number, level: number): boolean;
503
507
  /** Checks if this terrain provider is marked as a custom provider. */
504
508
  get isCustom(): boolean;
@@ -506,8 +510,11 @@ declare class TerrainArea {
506
510
  get credit(): string | Credit;
507
511
  /** Gets the terrain provider for this terrain area. */
508
512
  get provider(): TerrainProvider | undefined;
513
+ /** Gets the terrain bounds for this terrain area. */
509
514
  get bounds(): TerrainBounds;
515
+ /** Gets available zoom levels set with this terrain area. */
510
516
  get levels(): Set<number>;
517
+ /** Gets if this terrain area is ready. */
511
518
  get ready(): boolean;
512
519
  }
513
520
  /**
@@ -693,8 +700,21 @@ declare namespace HybridTerrainProvider {
693
700
  function createOverlay(customTerrainUrl: string, baseTerrainUrl: string, tileRanges: TileRanges, levels?: number[]): Promise<Awaited<HybridTerrainProvider>>;
694
701
  }
695
702
 
696
- declare class TerrainEntities extends Collection<EntityCollection, Entity> {
697
- }
703
+ /**
704
+ * Copies configuration and state from one Cesium Viewer to another.
705
+ * @param source - The source viewer to copy properties from
706
+ * @param container - DOM element ID or element for the new viewer
707
+ * @param options - Optional override options for the new viewer
708
+ * @returns A new Viewer instance with copied properties
709
+ */
710
+ declare function cloneViewer(source: Viewer, container: Element | string, options?: Viewer.ConstructorOptions): Viewer;
711
+ /**
712
+ * Copies camera state from source viewer to destination viewer.
713
+ * @param source The source viewer to copy camera states from.
714
+ * @param dest The destination viewer to apply camera properties from the source.
715
+ */
716
+ declare function syncCameraState(source: Viewer, dest: Viewer): void;
717
+
698
718
  /**
699
719
  * @class
700
720
  * Utility class for visualizing terrain provider boundaries and debugging terrain loading.
@@ -761,7 +781,7 @@ declare class TerrainVisualizer {
761
781
  /** Whether the grid is currently visible. */
762
782
  get visible(): boolean;
763
783
  /** The collection used in the visualizer. */
764
- get collection(): TerrainEntities;
784
+ get collection(): Collection<EntityCollection, Entity>;
765
785
  /** The viewer used in the visualizer */
766
786
  get viewer(): Viewer;
767
787
  }
@@ -790,7 +810,7 @@ declare namespace TerrainVisualizer {
790
810
  grid: string;
791
811
  };
792
812
  /**
793
- * Creates a rectangle entity fo r visualization.
813
+ * Creates a ground-clamped rectangle entity for visualization.
794
814
  * @param rectangle The rectangle to visualize
795
815
  * @param color The color to use
796
816
  * @returns A new entity
@@ -816,19 +836,4 @@ declare namespace TerrainVisualizer {
816
836
  function visualize(terrain: TerrainArea | TerrainBounds, viewer: Viewer, options?: Options): Collection<EntityCollection, Entity>;
817
837
  }
818
838
 
819
- /**
820
- * Copies configuration and state from one Cesium Viewer to another.
821
- * @param source - The source viewer to copy properties from
822
- * @param container - DOM element ID or element for the new viewer
823
- * @param options - Optional override options for the new viewer
824
- * @returns A new Viewer instance with copied properties
825
- */
826
- declare function cloneViewer(source: Viewer, container: Element | string, options?: Viewer.ConstructorOptions): Viewer;
827
- /**
828
- * Copies camera state from source viewer to destination viewer.
829
- * @param source The source viewer to copy camera states from.
830
- * @param dest The destination viewer to apply camera properties from the source.
831
- */
832
- declare function syncCameraState(source: Viewer, dest: Viewer): void;
833
-
834
839
  export { Collection, HybridTerrainProvider, TerrainArea, TerrainBounds, TerrainVisualizer, cloneViewer, syncCameraState };
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import{defined as E,EntityCollection as H}from"cesium";var S=class a{static symbol=Symbol("cesium-item-tag");tag;collection;_valuesCache=null;_tagMap=new Map;_eventListeners=new Map;constructor({collection:e,tag:t}){this.tag=t||"default",this.collection=e}_emit(e,t){let r=this._eventListeners.get(e);if(r){let i={type:e,...t};r.forEach(o=>o(i))}}_addToTagMap(e,t){this._tagMap.has(t)||this._tagMap.set(t,new Set),this._tagMap.get(t)?.add(e)}_removeFromTagMap(e){let t=e[a.symbol],r=this._tagMap.get(t);r&&(r.delete(e),r.size===0&&this._tagMap.delete(t))}_invalidateCache(){this._valuesCache=null}addEventListener(e,t){return this._eventListeners.has(e)||this._eventListeners.set(e,new Set),this._eventListeners.get(e)?.add(t),this}removeEventListener(e,t){return this._eventListeners.get(e)?.delete(t),this}add(e,t=this.tag,r){return Array.isArray(e)?e.forEach(i=>{this.add(i)}):(Object.defineProperty(e,a.symbol,{value:t,enumerable:!1,writable:!0,configurable:!0}),this.collection.add(e,r),this._addToTagMap(e,t),this._invalidateCache(),this._emit("add",{items:[e],tag:t})),e}contains(e){return this.collection.contains(e)}remove(e){let t=this.collection.remove(e);return t&&(this._removeFromTagMap(e),this._invalidateCache(),this._emit("remove",{items:[e]})),t}removeAll(){this._tagMap.clear(),this.collection.removeAll(),this._invalidateCache(),this._emit("clear")}get values(){if(this._valuesCache)return this._valuesCache;if(this.collection instanceof H)this._valuesCache=this.collection.values||[];else{let e=[];for(let t=0;t<this.collection.length;t++)e.push(this.collection.get(t));this._valuesCache=e}return this._valuesCache}get length(){return this.values?.length||0}getByTag(e){let t=this._tagMap.get(e);return t?Array.from(t):[]}getFirstByTag(e){let t=this._tagMap.get(e);if(t&&t.size>0)return t.values().next().value}getTags(){return Array.from(this._tagMap.keys())}hasTag(e){let t=this._tagMap.get(e);return!!t&&t.size>0}updateTag(e,t){let r=this.getByTag(e);for(let i of r)this._removeFromTagMap(i),Object.defineProperty(i,a.symbol,t),this._addToTagMap(i,t);return r.length>0&&this._emit("update",{items:r,tag:t}),r.length}removeByTag(e){let t=0;return Array.isArray(e)?e.forEach(r=>{this.removeByTag(r)}):this.getByTag(e).forEach(r=>{this.remove(r)&&t++}),t}show(e){let t=this.getByTag(e),r=0;for(let i of t)E(i.show)&&(i.show=!0,r++);return r}hide(e){let t=this.getByTag(e),r=0;for(let i of t)E(i.show)&&(i.show=!1,r++);return r}toggle(e){let t=this.getByTag(e),r=0;for(let i of t)E(i.show)&&(i.show=!i.show,r++);return r}setProperty(e,t,r){let i=this.getByTag(e),o=0;for(let n of i)t in n?(n[t]=r,o++):console.warn(`${t} does not exists in ${n}`);return o}filter(e,t){return(t?this.getByTag(t):this.values).filter(e)}forEach(e,t){(t?this.getByTag(t):this.values).forEach((i,o)=>e(i,o))}},x=S;import{CesiumTerrainProvider as M,EllipsoidTerrainProvider as B,GeographicTilingScheme as q}from"cesium";import{CesiumTerrainProvider as Y}from"cesium";import{GeographicTilingScheme as L,Rectangle as b}from"cesium";var h=class{_rectangle;_tilingScheme;_tileRanges;_levels;constructor(e,t){if(this._tilingScheme=t||new L,this._rectangle=new b,this._tileRanges=new Map,this._levels=new Set,e.type==="rectangle"&&e.rectangle)this._rectangle=b.clone(e.rectangle);else if(e.type==="tileRange"&&e.tileRanges)e.tileRanges instanceof Map?this._tileRanges=new Map(e.tileRanges):this._tileRanges=new Map(Object.entries(e.tileRanges).map(([r,i])=>[parseInt(r),i])),this._calculateRectangleFromTileRanges();else throw new Error("Either rectangle or tileRanges must be provided.");this._levels=new Set(Array.from(this._tileRanges.keys()))}contains(e,t,r){if(this._tileRanges.has(r)){let o=this._tileRanges.get(r);return e>=o.start.x&&e<=o.end.x&&t>=o.start.y&&t<=o.end.y}let i=this._tilingScheme.tileXYToRectangle(e,t,r);return b.intersection(i,this._rectangle)!==void 0}configureAvailability(e){if(e.availability){e.availability._tilingScheme&&(e.availability._tilingScheme=this._tilingScheme);for(let[t,r]of this._tileRanges.entries())e.availability.addAvailableTileRange(t,r.start.x,r.start.y,r.end.x,r.end.y)}}get rectangle(){return this._rectangle}get tilingScheme(){return this._tilingScheme}get tileRanges(){return this._tileRanges}get levels(){return this._levels}_calculateRectangleFromTileRanges(){let e=Number.POSITIVE_INFINITY,t=Number.POSITIVE_INFINITY,r=Number.NEGATIVE_INFINITY,i=Number.NEGATIVE_INFINITY,o=Array.from(this._tileRanges.keys());if(o.length===0){this._rectangle=b.MAX_VALUE;return}let n=Math.min(...o),s=this._tileRanges.get(n);if(s){let{start:l,end:c}=s,T=this._tilingScheme.tileXYToRectangle(l.x,l.y,n),d=this._tilingScheme.tileXYToRectangle(c.x,c.y,n);e=Math.min(T.west,e),t=Math.min(d.south,t),r=Math.max(d.east,r),i=Math.max(T.north,i)}this._rectangle=new b(e,t,r,i)}};(t=>{function a(r,i,o,n=new L){let s=new Map;return s.set(o,{start:{x:r,y:i},end:{x:r,y:i}}),new t({type:"tileRange",tileRanges:s},n)}t.fromTile=a;function e(r,i=new L){return new t({type:"rectangle",rectangle:b.clone(r)},i)}t.fromRectangle=e})(h||={});var v=class a{_provider;_bounds;_levels;_ready=!1;_credit;_isCustom;constructor(e,t){this._bounds=e.bounds instanceof h?e.bounds:new h(e.bounds),this._levels=new Set(e.levels||[]),this._credit=e.credit||"custom",this._isCustom=e.isCustom!==void 0?e.isCustom:!0,this._provider=t,this._ready=!0,this._bounds.configureAvailability(this._provider)}static async create(e){let t;return typeof e.provider=="string"?t=await Y.fromUrl(e.provider,{requestVertexNormals:!0,credit:e.credit||"custom"}):t=e.provider,new a(e,t)}contains(e,t,r){return this._levels.size>0&&!this._levels.has(r)?!1:this._bounds.contains(e,t,r)}requestTileGeometry(e,t,r,i){if(!(!this._ready||!this.contains(e,t,r)||!this._provider?.getTileDataAvailable(e,t,r)))return this._provider.requestTileGeometry(e,t,r,i)}getTileDataAvailable(e,t,r){return!this.contains(e,t,r)||!this._ready?!1:this._provider?.getTileDataAvailable(e,t,r)??!1}get isCustom(){return this._isCustom}get credit(){return this._credit}get provider(){return this._provider}get bounds(){return this._bounds}get levels(){return this._levels}get ready(){return this._ready}};(e=>{async function a(t,r,i,o="custom"){let n=new h({type:"tileRange",tileRanges:r});return await e.create({provider:t,bounds:n,levels:i||Object.keys(r).map(l=>parseInt(l)),credit:o})}e.fromUrl=a})(v||={});var P=class extends Array{async add(e){let t;return e instanceof v?t=e:t=await v.create(e),this.push(t)}remove(e){let t=this.indexOf(e);return t>=0?(this.splice(t,1),!0):!1}clear(){this.length=0}},y=class a{_terrainAreas=new P;_terrainProvider;_fallbackProvider;_tilingScheme;_ready=!1;_availability;constructor(e,t,r){this._terrainProvider=e,this._fallbackProvider=t,this._tilingScheme=e.tilingScheme||new q,this._terrainAreas=new P(...r),this._availability=e.availability,this._ready=!0}static async create(e){try{let t;typeof e.terrainProvider=="string"?t=await M.fromUrl(e.terrainProvider,{requestVertexNormals:!0}):t=e.terrainProvider;let r;e.fallbackProvider?typeof e.fallbackProvider=="string"?r=await M.fromUrl(e.fallbackProvider,{requestVertexNormals:!0}):r=e.fallbackProvider:r=new B;let i=[];for(let o of e.terrainAreas){let n=await v.create(o);i.push(n)}return new a(t,r,i)}catch(t){throw console.error("Failed to initialize HybridTerrainProvider:",t),t}}get ready(){return this._ready}get tilingScheme(){return this._tilingScheme}get availability(){return this._availability}get terrainAreas(){return[...this._terrainAreas]}get defaultProvider(){return this._terrainProvider}get fallbackProvider(){return this._fallbackProvider}get credit(){return this._terrainProvider?.credit}get errorEvent(){return this._terrainProvider.errorEvent}get hasWaterMask(){return this._terrainProvider.hasWaterMask}get hasVertexNormals(){return this._terrainProvider.hasVertexNormals}loadTileDataAvailability(e,t,r){return this._terrainProvider.loadTileDataAvailability(e,t,r)}getLevelMaximumGeometricError(e){return this._terrainProvider.getLevelMaximumGeometricError(e)}requestTileGeometry(e,t,r,i){if(this._ready){for(let o of this._terrainAreas)if(o.contains(e,t,r))return o.requestTileGeometry(e,t,r,i);return this._terrainProvider.getTileDataAvailable(e,t,r)?this._terrainProvider.requestTileGeometry(e,t,r,i):this._fallbackProvider.requestTileGeometry(e,t,r,i)}}getTileDataAvailable(e,t,r){return this._terrainAreas.forEach(i=>{if(i.contains(e,t,r)&&i.getTileDataAvailable(e,t,r))return!0}),this._terrainProvider.getTileDataAvailable(e,t,r)||!0}};(e=>{async function a(t,r,i,o){return e.create({terrainAreas:[{provider:t,bounds:{type:"tileRange",tileRanges:i},levels:o||Object.keys(i).map(n=>parseInt(n)),credit:"custom"}],terrainProvider:r,fallbackProvider:new B})}e.createOverlay=a})(y||={});import{Color as m,Entity as W,HeightReference as $,Rectangle as V,TileCoordinatesImageryProvider as U}from"cesium";var w=class extends x{},_=class a{_viewer;_collection;_hybridTerrain;_visible=!1;_level=15;_tileCoordinatesLayer;_colors=new Map([["custom",m.RED],["default",m.BLUE],["fallback",m.GRAY],["grid",m.YELLOW]]);constructor(e,t){this._viewer=e,this._collection=new w({collection:e.entities,tag:a.tag.default}),t&&(t.colors&&Object.entries(t.colors).forEach(([r,i])=>{this._colors.set(r,i)}),t.tile!==void 0&&(this._visible=t.tile),t.activeLevel!==void 0&&(this._level=t.activeLevel),t.terrainProvider&&this.setTerrainProvider(t.terrainProvider))}setTerrainProvider(e){this._hybridTerrain=e,this.update()}update(){this.clear(),this._visible&&this.show(this._level)}clear(){this._collection.removeByTag(this._collection.getTags())}show(e=15){if(!this._hybridTerrain)return;this._collection.removeByTag(a.tag.grid),this._level=e;let t=this._hybridTerrain.tilingScheme;this._tileCoordinatesLayer||(this._tileCoordinatesLayer=this._viewer.imageryLayers.addImageryProvider(new U({tilingScheme:t,color:m.YELLOW})));let r=(n,s,l)=>{if(this._hybridTerrain){for(let c of this._hybridTerrain.terrainAreas)if(c.contains(n,s,l))return c.isCustom?this._colors.get("custom")||m.RED:this._colors.get("default")||m.BLUE;if(this._hybridTerrain.getTileDataAvailable(n,s,l))return this._colors.get("default")||m.BLUE}return this._colors.get("fallback")||m.TRANSPARENT},i=this._getVisibleRectangle();if(!i)return;function o(n){return n&&Number.isFinite(n.west)&&Number.isFinite(n.south)&&Number.isFinite(n.east)&&Number.isFinite(n.north)&&n.west<=n.east&&n.south<=n.north}if(!o(i)){console.warn("Invalid visible rectangle detected, skipping grid display");return}try{let n=t.positionToTileXY(V.northwest(i),e),s=t.positionToTileXY(V.southeast(i),e);if(!n||!s)return;let l=100,c=Math.min(s.x-n.x+1,l),T=Math.min(s.y-n.y+1,l);for(let d=n.x;d<=n.x+c-1;d++)for(let g=n.y;g<=n.y+T-1;g++)try{let u=t.tileXYToRectangle(d,g,e);if(!o(u)){console.warn(`Invalid rectangle for tile (${d}, ${g}, ${e}), skipping`);continue}let p=r(d,g,e),f=a.createRectangle(u,p.withAlpha(.3));f.properties?.addProperty("tileX",d),f.properties?.addProperty("tileY",g),f.properties?.addProperty("tileLevel",e),this._collection.add(f,a.tag.grid)}catch(u){console.warn(`Error creating tile (${d}, ${g}, ${e}): ${u.message}`);continue}console.log("\u{1F680} ~ TerrainVisualizer ~ showGrid ~ collection:",this._collection),this._visible=!0}catch(n){console.error("Error displaying tile grid:",n)}}hide(){this._collection.removeByTag(a.tag.grid),this._tileCoordinatesLayer&&(this._viewer.imageryLayers.remove(this._tileCoordinatesLayer),this._tileCoordinatesLayer=void 0),this._visible=!1}setColors(e){Object.entries(e).forEach(([t,r])=>{this._colors.set(t,r)}),this.update()}flyTo(e,t){let{rectangle:r}=e.bounds;this._viewer.camera.flyTo({destination:r,...t,complete:()=>{this._visible&&this.update()}})}_getVisibleRectangle(){return this._viewer.camera.computeViewRectangle()}get level(){return this._level}set level(e){this._level=e,this._visible&&this.update()}get visible(){return this._visible}get collection(){return this._collection}get viewer(){return this._viewer}};(r=>{r.tag={default:"Terrain Visualizer",boundary:"Terrain Visualizer Boundary",grid:"Terrain Visualizer Tile Grid"};function e(i,o){return new W({rectangle:{coordinates:i,material:o,heightReference:$.CLAMP_TO_GROUND}})}r.createRectangle=e;function t(i,o,n){let s=n?.tag||"terrain_area_visualization",l=n?.color||m.RED,c=n?.maxTilesToShow||100,T=n?.show!==void 0?n.show:!0,d=n?.alpha||.7,g=n?.tileAlpha||.2,u="provider"in i?i.bounds:i,p=new w({collection:o.entities,tag:s}),{rectangle:f}=u;if(p.add(r.createRectangle(f,l.withAlpha(d)),s),T&&u.levels.size>0){let{tilingScheme:N}=u;u.levels.forEach(k=>{let A=0,{tileRanges:G}=u;for(let[z,C]of G.entries())if(z===k)for(let R=C.start.x;R<=C.end.x&&A<c;R++)for(let I=C.start.y;I<=C.end.y&&A<c;I++){let F=N.tileXYToRectangle(R,I,k);p.add(e(F,l.withAlpha(g)),`${s}_tile`),A++}})}return p}r.visualize=t})(_||={});import{defined as O,Viewer as X}from"cesium";function j(a,e,t){let r={baseLayerPicker:a.baseLayerPicker!==void 0,geocoder:a.geocoder!==void 0,homeButton:a.homeButton!==void 0,sceneModePicker:a.sceneModePicker!==void 0,timeline:a.timeline!==void 0,navigationHelpButton:a.navigationHelpButton!==void 0,animation:a.animation!==void 0,fullscreenButton:a.fullscreenButton!==void 0,shouldAnimate:a.clock.shouldAnimate,terrainProvider:a.terrainProvider,requestRenderMode:a.scene.requestRenderMode,infoBox:a.infoBox!==void 0},i=new X(e,{...r,...t});D(a,i);let o=a.imageryLayers;i.imageryLayers.removeAll();for(let l=0;l<o.length;l++){let c=o.get(l);i.imageryLayers.addImageryProvider(c.imageryProvider,l)}i.clock.startTime=a.clock.startTime.clone(),i.clock.stopTime=a.clock.stopTime.clone(),i.clock.currentTime=a.clock.currentTime.clone(),i.clock.multiplier=a.clock.multiplier,i.clock.clockStep=a.clock.clockStep,i.clock.clockRange=a.clock.clockRange,i.clock.shouldAnimate=a.clock.shouldAnimate,i.scene.globe.enableLighting=a.scene.globe.enableLighting,i.scene.globe.depthTestAgainstTerrain=a.scene.globe.depthTestAgainstTerrain,i.scene.screenSpaceCameraController.enableCollisionDetection=a.scene.screenSpaceCameraController.enableCollisionDetection;let n=a.scene.screenSpaceCameraController.tiltEventTypes;n&&(i.scene.screenSpaceCameraController.tiltEventTypes=Array.isArray(n)?[...n]:n);let s=a.scene.screenSpaceCameraController.zoomEventTypes;return s&&(i.scene.screenSpaceCameraController.zoomEventTypes=Array.isArray(s)?[...s]:s),i}function D(a,e){if(O(a)&&O(e)){let{camera:t}=a;e.camera.position=t.positionWC.clone(),e.camera.direction=t.directionWC.clone(),e.camera.up=t.upWC.clone()}}export{x as Collection,y as HybridTerrainProvider,v as TerrainArea,h as TerrainBounds,_ as TerrainVisualizer,j as cloneViewer,D as syncCameraState};
1
+ import{defined as I,EntityCollection as H}from"cesium";var S=class a{static symbol=Symbol("cesium-item-tag");tag;collection;_valuesCache=null;_tagMap=new Map;_eventListeners=new Map;constructor({collection:e,tag:t}){this.tag=t||"default",this.collection=e}_emit(e,t){let r=this._eventListeners.get(e);if(r){let i={type:e,...t};r.forEach(o=>o(i))}}_addToTagMap(e,t){this._tagMap.has(t)||this._tagMap.set(t,new Set),this._tagMap.get(t)?.add(e)}_removeFromTagMap(e){let t=e[a.symbol],r=this._tagMap.get(t);r&&(r.delete(e),r.size===0&&this._tagMap.delete(t))}_invalidateCache(){this._valuesCache=null}addEventListener(e,t){return this._eventListeners.has(e)||this._eventListeners.set(e,new Set),this._eventListeners.get(e)?.add(t),this}removeEventListener(e,t){return this._eventListeners.get(e)?.delete(t),this}add(e,t=this.tag,r){return Array.isArray(e)?e.forEach(i=>{this.add(i)}):(Object.defineProperty(e,a.symbol,{value:t,enumerable:!1,writable:!0,configurable:!0}),this.collection.add(e,r),this._addToTagMap(e,t),this._invalidateCache(),this._emit("add",{items:[e],tag:t})),e}contains(e){return this.collection.contains(e)}remove(e){let t=this.collection.remove(e);return t&&(this._removeFromTagMap(e),this._invalidateCache(),this._emit("remove",{items:[e]})),t}removeAll(){this._tagMap.clear(),this.collection.removeAll(),this._invalidateCache(),this._emit("clear")}get values(){if(this._valuesCache)return this._valuesCache;if(this.collection instanceof H)this._valuesCache=this.collection.values||[];else{let e=[];for(let t=0;t<this.collection.length;t++)e.push(this.collection.get(t));this._valuesCache=e}return this._valuesCache}get length(){return this.values?.length||0}getByTag(e){let t=this._tagMap.get(e);return t?Array.from(t):[]}getFirstByTag(e){let t=this._tagMap.get(e);if(t&&t.size>0)return t.values().next().value}getTags(){return Array.from(this._tagMap.keys())}hasTag(e){let t=this._tagMap.get(e);return!!t&&t.size>0}updateTag(e,t){let r=this.getByTag(e);for(let i of r)this._removeFromTagMap(i),Object.defineProperty(i,a.symbol,t),this._addToTagMap(i,t);return r.length>0&&this._emit("update",{items:r,tag:t}),r.length}removeByTag(e){let t=0;return Array.isArray(e)?e.forEach(r=>{this.removeByTag(r)}):this.getByTag(e).forEach(r=>{this.remove(r)&&t++}),t}show(e){let t=this.getByTag(e),r=0;for(let i of t)I(i.show)&&(i.show=!0,r++);return r}hide(e){let t=this.getByTag(e),r=0;for(let i of t)I(i.show)&&(i.show=!1,r++);return r}toggle(e){let t=this.getByTag(e),r=0;for(let i of t)I(i.show)&&(i.show=!i.show,r++);return r}setProperty(e,t,r){let i=this.getByTag(e),o=0;for(let n of i)t in n?(n[t]=r,o++):console.warn(`${t} does not exists in ${n}`);return o}filter(e,t){return(t?this.getByTag(t):this.values).filter(e)}forEach(e,t){(t?this.getByTag(t):this.values).forEach((i,o)=>e(i,o))}},C=S;import{CesiumTerrainProvider as k,EllipsoidTerrainProvider as M,GeographicTilingScheme as q}from"cesium";import{CesiumTerrainProvider as Y}from"cesium";import{GeographicTilingScheme as x,Rectangle as b}from"cesium";var h=class{_rectangle;_tilingScheme;_tileRanges;_levels;constructor(e,t){if(this._tilingScheme=t||new x,this._rectangle=new b,this._tileRanges=new Map,this._levels=new Set,e.type==="rectangle"&&e.rectangle)this._rectangle=b.clone(e.rectangle);else if(e.type==="tileRange"&&e.tileRanges)e.tileRanges instanceof Map?this._tileRanges=new Map(e.tileRanges):this._tileRanges=new Map(Object.entries(e.tileRanges).map(([r,i])=>[parseInt(r),i])),this._calculateRectangleFromTileRanges();else throw new Error("Either rectangle or tileRanges must be provided.");this._levels=new Set(Array.from(this._tileRanges.keys()))}contains(e,t,r){if(this._tileRanges.has(r)){let o=this._tileRanges.get(r);return e>=o.start.x&&e<=o.end.x&&t>=o.start.y&&t<=o.end.y}let i=this._tilingScheme.tileXYToRectangle(e,t,r);return b.intersection(i,this._rectangle)!==void 0}configureAvailability(e){if(e.availability){e.availability._tilingScheme&&(e.availability._tilingScheme=this._tilingScheme);for(let[t,r]of this._tileRanges.entries())e.availability.addAvailableTileRange(t,r.start.x,r.start.y,r.end.x,r.end.y)}}get rectangle(){return this._rectangle}get tilingScheme(){return this._tilingScheme}get tileRanges(){return this._tileRanges}get levels(){return this._levels}_calculateRectangleFromTileRanges(){let e=Number.POSITIVE_INFINITY,t=Number.POSITIVE_INFINITY,r=Number.NEGATIVE_INFINITY,i=Number.NEGATIVE_INFINITY,o=Array.from(this._tileRanges.keys());if(o.length===0){this._rectangle=b.MAX_VALUE;return}let n=Math.min(...o),s=this._tileRanges.get(n);if(s){let{start:l,end:c}=s,T=this._tilingScheme.tileXYToRectangle(l.x,l.y,n),d=this._tilingScheme.tileXYToRectangle(c.x,c.y,n);e=Math.min(T.west,e),t=Math.min(d.south,t),r=Math.max(d.east,r),i=Math.max(T.north,i)}this._rectangle=new b(e,t,r,i)}};(t=>{function a(r,i,o,n=new x){let s=new Map;return s.set(o,{start:{x:r,y:i},end:{x:r,y:i}}),new t({type:"tileRange",tileRanges:s},n)}t.fromTile=a;function e(r,i=new x){return new t({type:"rectangle",rectangle:b.clone(r)},i)}t.fromRectangle=e})(h||={});var v=class a{_provider;_bounds;_levels;_ready=!1;_credit;_isCustom;constructor(e,t){this._bounds=e.bounds instanceof h?e.bounds:new h(e.bounds),this._levels=new Set(e.levels||[]),this._credit=e.credit||"custom",this._isCustom=e.isCustom!==void 0?e.isCustom:!0,this._provider=t,this._ready=!0,this._bounds.configureAvailability(this._provider)}static async create(e){let t;return typeof e.provider=="string"?t=await Y.fromUrl(e.provider,{requestVertexNormals:!0,credit:e.credit||"custom"}):t=e.provider,new a(e,t)}contains(e,t,r){return this._levels.size>0&&!this._levels.has(r)?!1:this._bounds.contains(e,t,r)}requestTileGeometry(e,t,r,i){if(!(!this._ready||!this.contains(e,t,r)||!this._provider?.getTileDataAvailable(e,t,r)))return this._provider.requestTileGeometry(e,t,r,i)}getTileDataAvailable(e,t,r){return!this.contains(e,t,r)||!this._ready?!1:this._provider?.getTileDataAvailable(e,t,r)??!1}get isCustom(){return this._isCustom}get credit(){return this._credit}get provider(){return this._provider}get bounds(){return this._bounds}get levels(){return this._levels}get ready(){return this._ready}};(e=>{async function a(t,r,i,o="custom"){let n=new h({type:"tileRange",tileRanges:r});return await e.create({provider:t,bounds:n,levels:i||Object.keys(r).map(l=>parseInt(l)),credit:o})}e.fromUrl=a})(v||={});var P=class extends Array{async add(e){let t;return e instanceof v?t=e:t=await v.create(e),this.push(t)}remove(e){let t=this.indexOf(e);return t>=0?(this.splice(t,1),!0):!1}clear(){this.length=0}},p=class a{_terrainAreas=new P;_terrainProvider;_fallbackProvider;_tilingScheme;_ready=!1;_availability;constructor(e,t,r){this._terrainProvider=e,this._fallbackProvider=t,this._tilingScheme=e.tilingScheme||new q,this._terrainAreas=new P(...r),this._availability=e.availability,this._ready=!0}static async create(e){try{let t;typeof e.terrainProvider=="string"?t=await k.fromUrl(e.terrainProvider,{requestVertexNormals:!0}):t=e.terrainProvider;let r;e.fallbackProvider?typeof e.fallbackProvider=="string"?r=await k.fromUrl(e.fallbackProvider,{requestVertexNormals:!0}):r=e.fallbackProvider:r=new M;let i=[];for(let o of e.terrainAreas){let n=await v.create(o);i.push(n)}return new a(t,r,i)}catch(t){throw console.error("Failed to initialize HybridTerrainProvider:",t),t}}get ready(){return this._ready}get tilingScheme(){return this._tilingScheme}get availability(){return this._availability}get terrainAreas(){return[...this._terrainAreas]}get defaultProvider(){return this._terrainProvider}get fallbackProvider(){return this._fallbackProvider}get credit(){return this._terrainProvider?.credit}get errorEvent(){return this._terrainProvider.errorEvent}get hasWaterMask(){return this._terrainProvider.hasWaterMask}get hasVertexNormals(){return this._terrainProvider.hasVertexNormals}loadTileDataAvailability(e,t,r){return this._terrainProvider.loadTileDataAvailability(e,t,r)}getLevelMaximumGeometricError(e){return this._terrainProvider.getLevelMaximumGeometricError(e)}requestTileGeometry(e,t,r,i){if(this._ready){for(let o of this._terrainAreas)if(o.contains(e,t,r))return o.requestTileGeometry(e,t,r,i);return this._terrainProvider.getTileDataAvailable(e,t,r)?this._terrainProvider.requestTileGeometry(e,t,r,i):this._fallbackProvider.requestTileGeometry(e,t,r,i)}}getTileDataAvailable(e,t,r){return this._terrainAreas.forEach(i=>{if(i.contains(e,t,r)&&i.getTileDataAvailable(e,t,r))return!0}),this._terrainProvider.getTileDataAvailable(e,t,r)||!0}};(e=>{async function a(t,r,i,o){return e.create({terrainAreas:[{provider:t,bounds:{type:"tileRange",tileRanges:i},levels:o||Object.keys(i).map(n=>parseInt(n)),credit:"custom"}],terrainProvider:r,fallbackProvider:new M})}e.createOverlay=a})(p||={});import{defined as B,Viewer as z}from"cesium";function W(a,e,t){let r={baseLayerPicker:a.baseLayerPicker!==void 0,geocoder:a.geocoder!==void 0,homeButton:a.homeButton!==void 0,sceneModePicker:a.sceneModePicker!==void 0,timeline:a.timeline!==void 0,navigationHelpButton:a.navigationHelpButton!==void 0,animation:a.animation!==void 0,fullscreenButton:a.fullscreenButton!==void 0,shouldAnimate:a.clock.shouldAnimate,terrainProvider:a.terrainProvider,requestRenderMode:a.scene.requestRenderMode,infoBox:a.infoBox!==void 0},i=new z(e,{...r,...t});V(a,i);let o=a.imageryLayers;i.imageryLayers.removeAll();for(let l=0;l<o.length;l++){let c=o.get(l);i.imageryLayers.addImageryProvider(c.imageryProvider,l)}i.clock.startTime=a.clock.startTime.clone(),i.clock.stopTime=a.clock.stopTime.clone(),i.clock.currentTime=a.clock.currentTime.clone(),i.clock.multiplier=a.clock.multiplier,i.clock.clockStep=a.clock.clockStep,i.clock.clockRange=a.clock.clockRange,i.clock.shouldAnimate=a.clock.shouldAnimate,i.scene.globe.enableLighting=a.scene.globe.enableLighting,i.scene.globe.depthTestAgainstTerrain=a.scene.globe.depthTestAgainstTerrain,i.scene.screenSpaceCameraController.enableCollisionDetection=a.scene.screenSpaceCameraController.enableCollisionDetection;let n=a.scene.screenSpaceCameraController.tiltEventTypes;n&&(i.scene.screenSpaceCameraController.tiltEventTypes=Array.isArray(n)?[...n]:n);let s=a.scene.screenSpaceCameraController.zoomEventTypes;return s&&(i.scene.screenSpaceCameraController.zoomEventTypes=Array.isArray(s)?[...s]:s),i}function V(a,e){if(B(a)&&B(e)){let{camera:t}=a;e.camera.position=t.positionWC.clone(),e.camera.direction=t.directionWC.clone(),e.camera.up=t.upWC.clone()}}import{Color as m,Entity as $,HeightReference as U,Rectangle as O,TileCoordinatesImageryProvider as X}from"cesium";var w=class a{_viewer;_collection;_hybridTerrain;_visible=!1;_level=15;_tileCoordinatesLayer;_colors=new Map([["custom",m.RED],["default",m.BLUE],["fallback",m.GRAY],["grid",m.YELLOW]]);constructor(e,t){this._viewer=e,this._collection=new C({collection:e.entities,tag:a.tag.default}),t&&(t.colors&&Object.entries(t.colors).forEach(([r,i])=>{this._colors.set(r,i)}),t.tile!==void 0&&(this._visible=t.tile),t.activeLevel!==void 0&&(this._level=t.activeLevel),t.terrainProvider&&this.setTerrainProvider(t.terrainProvider))}setTerrainProvider(e){this._hybridTerrain=e,this.update()}update(){this.clear(),this._visible&&this.show(this._level)}clear(){this._collection.removeByTag(this._collection.getTags())}show(e=15){if(!this._hybridTerrain)return;this._collection.removeByTag(a.tag.grid),this._level=e;let t=this._hybridTerrain.tilingScheme;this._tileCoordinatesLayer||(this._tileCoordinatesLayer=this._viewer.imageryLayers.addImageryProvider(new X({tilingScheme:t,color:m.YELLOW})));let r=(n,s,l)=>{if(this._hybridTerrain){for(let c of this._hybridTerrain.terrainAreas)if(c.contains(n,s,l))return c.isCustom?this._colors.get("custom")||m.RED:this._colors.get("default")||m.BLUE;if(this._hybridTerrain.getTileDataAvailable(n,s,l))return this._colors.get("default")||m.BLUE}return this._colors.get("fallback")||m.TRANSPARENT},i=this._getVisibleRectangle();if(!i)return;function o(n){return n&&Number.isFinite(n.west)&&Number.isFinite(n.south)&&Number.isFinite(n.east)&&Number.isFinite(n.north)&&n.west<=n.east&&n.south<=n.north}if(!o(i)){console.warn("Invalid visible rectangle detected, skipping grid display");return}try{let n=t.positionToTileXY(O.northwest(i),e),s=t.positionToTileXY(O.southeast(i),e);if(!n||!s)return;let l=100,c=Math.min(s.x-n.x+1,l),T=Math.min(s.y-n.y+1,l);for(let d=n.x;d<=n.x+c-1;d++)for(let g=n.y;g<=n.y+T-1;g++)try{let u=t.tileXYToRectangle(d,g,e);if(!o(u)){console.warn(`Invalid rectangle for tile (${d}, ${g}, ${e}), skipping`);continue}let y=r(d,g,e),f=a.createRectangle(u,y.withAlpha(.3));f.properties?.addProperty("tileX",d),f.properties?.addProperty("tileY",g),f.properties?.addProperty("tileLevel",e),this._collection.add(f,a.tag.grid)}catch(u){console.warn(`Error creating tile (${d}, ${g}, ${e}): ${u.message}`);continue}console.log("\u{1F680} ~ TerrainVisualizer ~ showGrid ~ collection:",this._collection),this._visible=!0}catch(n){console.error("Error displaying tile grid:",n)}}hide(){this._collection.removeByTag(a.tag.grid),this._tileCoordinatesLayer&&(this._viewer.imageryLayers.remove(this._tileCoordinatesLayer),this._tileCoordinatesLayer=void 0),this._visible=!1}setColors(e){Object.entries(e).forEach(([t,r])=>{this._colors.set(t,r)}),this.update()}flyTo(e,t){let{rectangle:r}=e.bounds;this._viewer.camera.flyTo({destination:r,...t,complete:()=>{this._visible&&this.update()}})}_getVisibleRectangle(){return this._viewer.camera.computeViewRectangle()}get level(){return this._level}set level(e){this._level=e,this._visible&&this.update()}get visible(){return this._visible}get collection(){return this._collection}get viewer(){return this._viewer}};(r=>{r.tag={default:"Terrain Visualizer",boundary:"Terrain Visualizer Boundary",grid:"Terrain Visualizer Tile Grid"};function e(i,o){return new $({rectangle:{coordinates:i,material:o,heightReference:U.CLAMP_TO_GROUND}})}r.createRectangle=e;function t(i,o,n){let s=n?.tag||"terrain_area_visualization",l=n?.color||m.RED,c=n?.maxTilesToShow||100,T=n?.show!==void 0?n.show:!0,d=n?.alpha||.7,g=n?.tileAlpha||.2,u="provider"in i?i.bounds:i,y=new C({collection:o.entities,tag:s}),{rectangle:f}=u;if(y.add(r.createRectangle(f,l.withAlpha(d)),s),T&&u.levels.size>0){let{tilingScheme:D}=u;u.levels.forEach(L=>{let A=0,{tileRanges:N}=u;for(let[G,_]of N.entries())if(G===L)for(let R=_.start.x;R<=_.end.x&&A<c;R++)for(let E=_.start.y;E<=_.end.y&&A<c;E++){let F=D.tileXYToRectangle(R,E,L);y.add(e(F,l.withAlpha(g)),`${s}_tile`),A++}})}return y}r.visualize=t})(w||={});export{C as Collection,p as HybridTerrainProvider,v as TerrainArea,h as TerrainBounds,w as TerrainVisualizer,W as cloneViewer,V as syncCameraState};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@juun-roh/cesium-utils",
3
- "version": "0.0.2",
3
+ "version": "0.0.3",
4
4
  "description": "Utilities to handle Cesium classes easier.",
5
5
  "keywords": [
6
6
  "Cesium",
@@ -53,16 +53,16 @@
53
53
  },
54
54
  "devDependencies": {
55
55
  "@changesets/cli": "^2.28.1",
56
- "@commitlint/cli": "^19",
57
- "@commitlint/config-conventional": "^19",
58
- "@commitlint/cz-commitlint": "^19",
59
- "@commitlint/format": "^19",
60
- "@commitlint/types": "^19",
61
- "@eslint/js": "^9.23.0",
62
- "@typescript-eslint/eslint-plugin": "^8.29.0",
63
- "@typescript-eslint/parser": "^8.29.0",
56
+ "@commitlint/cli": "^19.8.0",
57
+ "@commitlint/config-conventional": "^19.8.0",
58
+ "@commitlint/cz-commitlint": "^19.8.0",
59
+ "@commitlint/format": "^19.8.0",
60
+ "@commitlint/types": "^19.8.0",
61
+ "@eslint/js": "^9.24.0",
62
+ "@typescript-eslint/eslint-plugin": "^8.29.1",
63
+ "@typescript-eslint/parser": "^8.29.1",
64
64
  "cesium": "^1.128.0",
65
- "eslint": "^9.23.0",
65
+ "eslint": "^9.24.0",
66
66
  "eslint-plugin-jsdoc": "^50.6.9",
67
67
  "eslint-plugin-prettier": "^5.2.6",
68
68
  "eslint-plugin-simple-import-sort": "^12.1.1",
@@ -70,14 +70,15 @@
70
70
  "husky": "^9.1.7",
71
71
  "rimraf": "^6.0.1",
72
72
  "tsup": "^8.4.0",
73
- "typedoc": "^0.28.1",
74
- "typescript": "^5.8.2",
75
- "vite": "^6.2.5"
73
+ "typedoc": "^0.28.2",
74
+ "typedoc-material-theme": "^1.4.0",
75
+ "typescript": "^5.8.3",
76
+ "vite": "^6.2.6"
76
77
  },
77
78
  "scripts": {
78
79
  "build": "tsup",
79
80
  "build:dev": "tsup --watch",
80
- "clean": "rimraf dist docs",
81
+ "clean": "rimraf dist",
81
82
  "lint": "eslint .",
82
83
  "ci:publish": "pnpm build && pnpm publish --no-git-checks",
83
84
  "prebuild": "pnpm clean",