@juun-roh/cesium-utils
Version:
Solve common Cesium.js challenges: combine multiple terrain sources, tag and filter entity collections, and add visual highlights.
1,342 lines (1,327 loc) • 47.3 kB
text/typescript
import { DataSourceCollection, EntityCollection, ImageryLayerCollection, PrimitiveCollection, Billboard, Cesium3DTileset, GroundPrimitive, Label, PointPrimitive, Polyline, Primitive, DataSource, Entity, ImageryLayer, Color, Viewer, Model, Cesium3DTileFeature, TerrainProvider, TilingScheme, TileAvailability, Credit, Event, Request, TerrainData, Cartesian3, JulianDate, Rectangle } from 'cesium';
/**
* Represents a path to any nested property in an object, using dot notation.
*
* The `(keyof T & string)` portion provides top-level key hints in autocomplete,
* while `(string & {})` allows any string input to pass through.
*
* Actual path validation is delegated to {@link NestedValueOf}, which returns `never`
* for invalid paths — causing a type error on the corresponding value parameter.
*
* @example
* ```ts
* function f<Path extends NestedKeyOf<Obj>>(
* key: Path,
* value: NestedValueOf<Obj, Path> // ← validation happens here
* ) {}
*
* f("a.b.c", 123); // ✅ valid path, correct value type
* f("invalid.path", 1); // ❌ NestedValueOf returns never
* ```
*/
type NestedKeyOf<T extends object> = (keyof T & string) | (string & {});
/**
* Extracts the type of a nested property from a property path string.
*
* @template ObjectType - The object type to extract the value type from
* @template Path - The property path string (e.g., "a.b.c")
*
* @example
* type Value = NestedValueOf<{ a: { b: number } }, "a.b">
* // Result: number
*/
type NestedValueOf<ObjectType, Path extends string> = Path extends `${infer Cur}.${infer Rest}` ? Cur extends keyof ObjectType ? NonNullable<ObjectType[Cur]> extends Function | ((...args: any[]) => any) ? never : NestedValueOf<NonNullable<ObjectType[Cur]>, Rest> : never : Path extends keyof ObjectType ? NonNullable<ObjectType[Path]> extends Function | ((...args: any[]) => any) ? never : ObjectType[Path] : never;
/**
* @class
* A wrapper class that enhances Cesium collection objects with tagging functionality.
* This class provides a consistent API for working with different types of Cesium collections
* and allows grouping and manipulating collection items by custom tags.
*
* @template C - The type of Cesium collection (e.g., EntityCollection, PrimitiveCollection)
* @template I - The type of items in the collection (e.g., Entity, Primitive)
*
* @see [Collection Demo](https://juun.vercel.app/cesium-utils/collection)
*
* @example
* // Example 1: Managing Complex Scene with Multiple Object Types
* class SceneOrganizer {
* private entities: Collection<EntityCollection, Entity>;
* private billboards: Collection<BillboardCollection, Billboard>;
* private primitives: Collection<PrimitiveCollection, Primitive>;
*
* constructor(viewer: Viewer) {
* this.entities = new Collection({ collection: viewer.entities });
* this.billboards = new Collection({
* collection: viewer.scene.primitives.add(new BillboardCollection())
* });
* this.primitives = new Collection({
* collection: viewer.scene.primitives
* });
* }
*
* // Unified API across different collection types!
* showLayer(layerName: string) {
* this.entities.show(layerName);
* this.billboards.show(layerName);
* this.primitives.show(layerName);
* }
*
* hideLayer(layerName: string) {
* this.entities.hide(layerName);
* this.billboards.hide(layerName);
* this.primitives.hide(layerName);
* }
*
* removeLayer(layerName: string) {
* this.entities.remove(layerName);
* this.billboards.remove(layerName);
* this.primitives.remove(layerName);
* }
* }
*
* // Example 2: Extend the class for Domain-Specific Needs
* class BuildingCollection extends Collection<EntityCollection, Entity> {
* constructor(viewer: Viewer) {
* super({ collection: viewer.entities, tag: 'buildings' });
* }
*
* addBuilding(options: {
* position: Cartesian3;
* height: number;
* floors: number;
* type: 'residential' | 'commercial' | 'industrial';
* }): Entity {
* const building = new Entity({
* position: options.position,
* box: {
* dimensions: new Cartesian3(50, 50, options.height),
* material: this.getMaterialForType(options.type)
* }
* });
*
* // Tag by type AND by floor count
* this.add(building, options.type);
* this.add(building, `floors-${options.floors}`);
*
* return building;
* }
*
* getByFloorRange(min: number, max: number): Entity[] {
* const results: Entity[] = [];
* for (let i = min; i <= max; i++) {
* results.push(...this.get(`floors-${i}`));
* }
* return results;
* }
*
* private getMaterialForType(type: string): Material {
* const colors = {
* residential: Color.GREEN,
* commercial: Color.BLUE,
* industrial: Color.YELLOW
* };
* return new ColorMaterialProperty(colors[type] || Color.WHITE);
* }
* }
*/
declare class Collection<C extends Collection.Base, I extends Collection.ItemFor<C>> {
/**
* Symbol used as a property key to store tags on collection items.
* Using a Symbol ensures no property naming conflicts with the item's own properties.
* @readonly
*/
static readonly symbol: unique symbol;
/**
* Default tag used when adding items without specifying a tag.
* @protected
*/
protected tag: Collection.Tag;
/**
* The underlying Cesium collection being wrapped.
* @protected
*/
protected collection: C;
/**
* Cache for values array to improve performance
* @private
*/
private _valuesCache;
/**
* Tag to items map for faster lookups
* @private
*/
private _tagMap;
/**
* Event listeners
* @private
*/
private _eventListeners;
/**
* For cleaning up the instances
* @private
*/
private _eventCleanupFunctions;
/**
* Creates a new Collection instance.
*
* @param options - Configuration options
* @param options.collection - The Cesium collection to wrap
* @param options.tag - The default tag to use for items (defaults to 'default')
*/
constructor({ collection, tag }: {
collection: C;
tag?: Collection.Tag;
});
/**
* Makes the collection directly iterable, allowing it to be used in `for...of` loops
* and with spread operators.
*
* @returns An iterator for the items in the collection
*
* @example
* // Iterate through all items in the collection
* for (const entity of collection) {
* console.log(entity.id);
* }
*
* // Convert collection to array using spread syntax
* const entitiesArray = [...collection];
*/
[Symbol.iterator](): Iterator<I>;
/**
* Gets all item instances in the collection.
* This array should not be modified directly.
*
* @returns An array of all items in the collection
*/
get values(): I[];
/**
* Gets the number of items in the collection.
*
* @returns The item count
*/
get length(): number;
/**
* Gets all unique tags currently in use in the collection.
*
* @returns An array of all unique tags
*
* @example
* // Get all tags
* const tags = collection.tags;
* console.log(`Collection has these tags: ${tags.join(', ')}`);
*/
get tags(): Collection.Tag[];
/**
* Registers an event listener for collection events.
*
* @param type - The event type to listen for
* @param handler - The callback function
* @returns The collection instance for method chaining
*/
addEventListener(type: Collection.Event, handler: Collection.EventHandler<I>): this;
/**
* Removes an event listener.
*
* @param type - The event type
* @param handler - The callback function to remove
* @returns The collection instance for method chaining
*/
removeEventListener(type: Collection.Event, handler: Collection.EventHandler<I>): this;
/**
* Adds a single item with a tag to the collection.
*
* @param item - The item to add to the collection
* @param tag - Tag to associate with this item (defaults to the collection's default tag)
* @param index - The index to add the item at (if supported by the collection)
* @returns The collection instance for method chaining
*
* @example
* const entity = collection.add(new Entity({ ... }), 'landmarks');
*/
add(item: I, tag?: Collection.Tag, index?: number): this;
/**
* Adds multiple items with the same tag to the collection.
*
* @param items - The array of items to add to the collection
* @param tag - Tag to associate with this item (defaults to the collection's default tag)
* @returns The collection instance for method chaining
*
* @example
* // Add multiple entities with the same tag
* const entities = [new Entity({ ... }), new Entity({ ... })];
* const addedEntities = collection.add(entities, 'buildings');
*/
add(items: I[], tag?: Collection.Tag): this;
/**
* Returns true if the provided item is in this collection, false otherwise.
*
* @param item - The item instance to check for
* @returns True if the item is in the collection, false otherwise
*/
contains(item: I): boolean;
/**
* Checks if the collection has any items with the specified tag.
*
* @param tag - The tag to check for
* @returns True if items with the tag exist, false otherwise
*
* @example
* if (collection.contains('temporary')) {
* console.log('Temporary items exist');
* }
*/
contains(tag: Collection.Tag): boolean;
/**
* Removes an item from the collection.
*
* @param item - The item to remove
* @returns The collection instance for method chaining
*/
remove(item: I): this;
/**
* Removes all items with the specified tag from the collection.
*
* @param by - The tag identifying which items to remove
* @returns The collection instance for method chaining
*/
remove(by: Collection.Tag): this;
/**
* Removes all items with the array of tags from the collection.
*
* @param by - The tags identifying which items to remove
* @returns The collection instance for method chaining
*/
remove(by: Collection.Tag[]): this;
/**
* Removes all items from the collection.
*/
removeAll(): void;
/**
* Permanently destroys this Collection instance.
* Removes all event listeners and clears internal state.
* The Collection instance should not be used after calling this method.
*/
destroy(): void;
/**
* Gets all items with the specified tag from the collection.
* Uses an optimized internal map for faster lookups.
*
* @param by - The tag to filter by
* @returns An array of items with the specified tag, or an empty array if none found
*
* @example
* // Get all buildings
* const buildings = collection.get('buildings');
*/
get(by: Collection.Tag): I[];
/**
* Gets the first item matching the tag. More efficient than `get` when
* you only need one item, especially for large collections.
*
* @param by - The tag to search for
* @returns The first matching item or undefined if none found
*
* @example
* // Get the first building
* const firstBuilding = collection.first('buildings');
*/
first(by: Collection.Tag): I | undefined;
/**
* Updates the tag for all items with the specified tag.
*
* @param from - The tag to replace
* @param to - The new tag to assign
* @returns The number of items updated
*
* @example
* // Rename a tag
* const count = collection.update('temp', 'temporary');
* console.log(`Updated ${count} items`);
*/
update(from: Collection.Tag, to: Collection.Tag): number;
/**
* Makes all items with the specified tag visible.
* Only affects items that have a 'show' property.
*
* @param by - The tag identifying which items to show
* @returns The collection itself.
*
* @example
* // Show all buildings
* collection.show('buildings');
*/
show(by: Collection.Tag): this;
/**
* Hides all items with the specified tag.
* Only affects items that have a 'show' property.
*
* @param by - The tag identifying which items to hide
* @returns The collection itself.
*
* @example
* // Hide all buildings
* collection.hide('buildings');
*/
hide(by: Collection.Tag): this;
/**
* Toggles visibility of all items with the specified tag.
* Only affects items that have a 'show' property.
*
* @param by - The tag identifying which items to toggle
* @returns The collection itself.
*
* @example
* // Toggle visibility of all buildings
* collection.toggle('buildings');
*/
toggle(by: Collection.Tag): this;
/**
* Sets a property value on all items with the specified tag.
* Supports nested property paths using dot notation (e.g., 'billboard.scale').
*
* @template Path - A nested property path type
*
* @param property - The property name or nested path to set (e.g., 'name' or 'billboard.scale')
* @param value - The value to set
* @param by - The tag identifying which items to update
* @returns The collection itself.
*
* @example
* // Change color of all buildings to red
* collection.setProperty('color', Color.RED, 'buildings');
*
* @example
* // Change billboard scale using nested path
* collection.setProperty('billboard.scale', 2.0, 'buildings');
*/
setProperty<Path extends NestedKeyOf<I>>(property: Path, value: NestedValueOf<I, Path>, by?: Collection.Tag): this;
/**
* Filters items in the collection based on a predicate function.
* Optionally only filters items with a specific tag.
*
* @param predicate - Function that tests each item
* @param by - Optional tag to filter by before applying the predicate
* @returns Array of items that pass the test
*
* @example
* // Get all buildings taller than 100 meters
* const tallBuildings = collection.filter(
* entity => entity.properties?.height?.getValue() > 100,
* 'buildings'
* );
*/
filter(predicate: (item: I) => boolean, by?: Collection.Tag): I[];
/**
* Executes a callback function for each item in the collection.
* Optionally filters items by tag before execution.
*
* @param callback - Function to execute for each item
* @param by - Optional tag to filter items (if not provided, processes all items)
*
* @example
* // Highlight all buildings
* collection.forEach((entity) => {
* if (entity.polygon) {
* entity.polygon.material = new ColorMaterialProperty(Color.YELLOW);
* }
* }, 'buildings');
*/
forEach(callback: (value: I, index: number) => void, by?: Collection.Tag): void;
/**
* Creates a new array with the results of calling a provided function on every element
* in the collection. Optionally filters by tag before mapping.
*
* @param callbackfn - Function that produces an element of the new array
* @param by - Optional tag to filter items by before mapping
* @returns A new array with each element being the result of the callback function
*
* @example
* // Get all entity IDs
* const entityIds = collection.map(entity => entity.id);
*
* // Get positions of all buildings
* const buildingPositions = collection.map(
* entity => entity.position.getValue(Cesium.JulianDate.now()),
* 'buildings'
* );
*/
map<R>(callbackfn: (value: I, index: number) => R, by?: Collection.Tag): R[];
/**
* Returns the first element in the collection that satisfies the provided testing function.
* Optionally filters by tag before searching.
*
* @param predicate - Function to test each element
* @param by - Optional tag to filter items by before searching
* @returns The first element that passes the test, or undefined if no elements pass
*
* @example
* // Find the first entity with a specific name
* const namedEntity = collection.find(entity => entity.name === 'Target');
*
* // Find the first building taller than 100 meters
* const tallBuilding = collection.find(
* entity => entity.properties?.height?.getValue() > 100,
* 'buildings'
* );
*/
find(predicate: (value: I) => boolean, by?: Collection.Tag): I | undefined;
/**
* Emits an event to all registered listeners.
*
* @private
* @param type - The event type
* @param data - Additional event data
*/
private _emit;
/**
* Adds an item to the internal tag map for quick lookups.
*
* @private
* @param item - The item to add
* @param tag - The tag to associate with the item
*/
private _addToTagMap;
/**
* Removes an item from the internal tag map.
*
* @private
* @param item - The item to remove
*/
private _removeFromTagMap;
/**
* Invalidates the values cache when collection changes.
*
* @private
*/
private _invalidateCache;
/**
* Sets up automatic cache invalidation by registering event listeners on the underlying Cesium collection.
*
* @private
* @param collection - The Cesium collection to monitor for changes
*
* @see {@link destroy} For cleanup of event listeners
* @see {@link _invalidateCache} For the actual cache invalidation logic
*/
private _setupCacheInvalidator;
}
/**
* @namespace
*/
declare namespace Collection {
/**
* The underlying Cesium collection type being wrapped.
*/
export type Base = DataSourceCollection | EntityCollection | ImageryLayerCollection | PrimitiveCollection;
/**
* The item types that can be added to the `PrimitiveCollection` instance.
*/
type Primitives = Billboard | Cesium3DTileset | GroundPrimitive | Label | PointPrimitive | Polyline | Primitive;
/**
* Cesium item type that can be added to the {@link Collection.Base} instance.
*/
export type Item = DataSource | Entity | ImageryLayer | Primitives;
/**
* Gets the item type for a given collection type
*/
export type ItemFor<C extends Base> = C extends DataSourceCollection ? DataSource : C extends EntityCollection ? Entity : C extends ImageryLayerCollection ? ImageryLayer : C extends PrimitiveCollection ? Primitives : never;
/**
* Collection tag type.
*/
export type Tag = string | number;
export interface WithTag {
[key: symbol]: Tag;
}
/**
* Collection event types
*/
export type Event = "add" | "remove" | "update" | "clear";
/**
* Event handler function type
*/
export type EventHandler<I> = (event: {
type: Event;
items?: I[];
tag?: Collection.Tag;
}) => void;
export { };
}
/**
* @class
* Lightweight multiton highlight manager for Cesium using flyweight pattern.
*
* @example
* ```
* // Setup
* const viewer1 = new Viewer('cesiumContainer1');
* const viewer2 = new Viewer('cesiumContainer2');
*
* const highlighter1 = Highlight.getInstance(viewer1);
* const highlighter2 = Highlight.getInstance(viewer2);
*
* // This highlight only affects viewer1
* highlighter1.show(someEntity, { color: Color.RED });
*
* // This highlight only affects viewer2
* highlighter2.show(someEntity, { color: Color.BLUE });
*
* // When done with viewers
* Highlight.releaseInstance(viewer1);
* Highlight.releaseInstance(viewer2);
* viewer1.destroy();
* viewer2.destroy();
* ```
*/
declare class Highlight {
private static instances;
private _surface;
private _silhouette;
private _color;
/**
* Creates a new `Highlight` instance.
* @private Use {@link getInstance `Highlight.getInstance()`}
* @param viewer A viewer to create highlight entity in
*/
private constructor();
/** Gets the highlight color. */
get color(): Color;
/**
* Sets the highlight color.
* @param color The new color for highlights
*/
set color(color: Color);
/**
* Gets or creates highlight instance from a viewer.
* @param viewer The viewer to get or create a new instance from.
*/
static getInstance(viewer: Viewer): Highlight;
/**
* Releases the highlight instance associated with a viewer.
* @param viewer The viewer whose highlight instance should be released.
*/
static releaseInstance(viewer: Viewer): void;
/**
* Highlights a picked object or a direct instance.
* @param picked The result of `Scene.pick()` or direct instance to be highlighted.
* @param options Optional style for the highlight.
* @see {@link Highlight.Options}
*/
show(picked: Highlight.Picked, options?: Highlight.Options): void | Entity;
private _getObject;
/**
* Clears the current highlight effects.
*/
hide(): void;
}
declare namespace Highlight {
export interface Base {
show(object: any, options?: Highlight.Options): void;
hide(): void;
destroy(): void;
color: Color;
}
export interface Options {
/** Color of the highlight */
color?: Color;
/** To apply outline style for the highlight */
outline?: boolean;
/** Outline width */
width?: number;
}
type PickedObject = {
id?: Entity;
primitive?: Primitive | GroundPrimitive | Model | Cesium3DTileset;
tileset?: Cesium3DTileset;
detail?: {
model?: Model;
};
};
export type Picked = Entity | Cesium3DTileFeature | GroundPrimitive | PickedObject;
export { };
}
/**
* @class
* An implementation for highlighting 3D objects in Cesium.
*
* **Supported Object Types:**
* - `Entity` with model graphics. (adjustable outline width)
* - `Cesium3DTileset` instances. (fixed outline width)
*
* Currently supports outline style only.
*
* @example
* ```typescript
* const viewer = new Viewer("cesiumContainer");
* const silhouetteHighlight = new SilhouetteHighlight(viewer);
*
* // Highlight an object
* const entity = viewer.entities.add(new Entity({
* model: new ModelGraphics(),
* }));
* silhouetteHighlight.show(entity);
* ```
*/
declare class SilhouetteHighlight implements Highlight.Base {
private _color;
private _silhouette;
private _composite;
private _stages;
private _entity?;
private _currentObject;
private _currentOptions;
/**
* Creates a new `Silhouette` instance.
* @param viewer A viewer to create highlight silhouette in
*/
constructor(viewer: Viewer);
/** Gets the highlight color. */
get color(): Color;
/** Sets the highlight color. */
set color(color: Color);
/** Gets the currently highlighted object */
get currentObject(): Cesium3DTileFeature | Entity | undefined;
/**
* Highlights a picked `Cesium3DTileset` by updating silhouette composite.
* @param object The object to be highlighted.
* @param options Optional style for the highlight.
*/
show(object: Cesium3DTileFeature, options?: Highlight.Options): void;
/**
* Highlights a picked `Entity` by updating the model properties.
* @param object The object to be highlighted.
* @param options Optional style for the highlight.
*/
show(object: Entity, options?: Highlight.Options): void;
/** Clears the current highlight */
hide(): void;
/** Clean up the instances */
destroy(): void;
/**
* Compares two Highlight.Options objects for equality
* @private
*/
private _optionsEqual;
/**
* Clears all current highlights
* @private
*/
private _clearHighlights;
}
/**
* @class
* A flyweight implementation for highlighting 2D surface objects in Cesium.
*
* This class provides highlighting for ground-clamped geometries (polygons, polylines, rectangles)
*
* **Supported Geometry Types:**
* - `Entity` with polygon, polyline, or rectangle graphics
* - `GroundPrimitive` instances
*
* **Highlighting Modes:**
* - **Fill mode** (default): Creates a filled geometry using the original shape
* - **Outline mode**: Creates a polyline outline of the original geometry
*
* @example
* ```typescript
* // Basic usage
* const viewer = new Viewer('cesiumContainer');
* const surfaceHighlight = new SurfaceHighlight(viewer);
*
* // Highlight an entity with default red fill
* const entity = viewer.entities.add(new Entity({
* polygon: {
* hierarchy: Cartesian3.fromDegreesArray([-75, 35, -74, 35, -74, 36, -75, 36]),
* material: Color.BLUE
* }
* }));
* surfaceHighlight.show(entity);
* ```
*/
declare class SurfaceHighlight implements Highlight.Base {
private _color;
private _entity;
private _entities;
private _currentObject;
private _currentOptions;
/**
* Creates a new `SurfaceHighlight` instance.
* @param viewer A viewer to create highlight entity in
*/
constructor(viewer: Viewer);
/** Gets the highlight color. */
get color(): Color;
/** Sets the highlight color. */
set color(color: Color);
/** Gets the highlight entity */
get entity(): Entity;
/** Gets the currently highlighted object */
get currentObject(): Entity | GroundPrimitive | undefined;
/**
* Highlights a picked object by updating the reusable entity
* @param object The object to be highlighted.
* @param options Optional style for the highlight.
* @see {@link Highlight.Options}
*/
show(object: Entity | GroundPrimitive, options?: Highlight.Options): Entity | undefined;
/**
* Clears the current highlight
*/
hide(): void;
/** Clean up the instances */
destroy(): void;
/**
* Compares two Highlight.Options objects for equality
* @private
*/
private _optionsEqual;
/**
* Removes all geometry properties from the highlight entity
* @private
*/
private _clearGeometries;
/**
* Updates the highlight entity from an Entity object
* @private
*/
private _update;
}
/**
* @class
* Provides terrain by delegating requests to different terrain providers
* based on geographic regions and zoom levels. This allows combining
* multiple terrain sources into a single seamless terrain.
*
* @example
* ``` typescript
* // Tile-coordinate based for precise control (multiple levels)
* const customTiles: TerrainTiles = new Map();
* customTiles.set(15, { x: [55852, 55871], y: [9556, 9575] });
* customTiles.set(16, { x: [111704, 111742], y: [19112, 19150] });
*
* const hybridTerrain = new HybridTerrainProvider({
* regions: [
* {
* provider: customProvider,
* tiles: customTiles,
* }
* ],
* defaultProvider: worldTerrain
* });
*
* viewer.terrainProvider = hybridTerrain;
* ```
*/
declare class HybridTerrainProvider implements TerrainProvider {
private _regions;
private _defaultProvider;
/** @deprecated This will be removed in 0.5.0. */
private _fallbackProvider;
private _tilingScheme;
private _ready;
private _availability?;
private _errorEvent;
private _removeEventListeners;
private _hasWaterMask;
private _hasVertexNormals;
/**
* Creates a new `HybridTerrainProvider` instance.
* @param options {@link HybridTerrainProvider.ConstructorOptions}
* @returns A new `HybridTerrainProvider` instance.
*/
constructor(options: HybridTerrainProvider.ConstructorOptions);
/**
* Gets a value indicating whether or not the provider is ready for use,
* or a promise that resolves when the provider becomes ready.
*/
get ready(): boolean;
/**
* Gets the tiling scheme used by this provider.
*/
get tilingScheme(): TilingScheme;
/**
* Gets an object that can be used to determine availability of terrain from this provider.
*/
get availability(): TileAvailability | undefined;
/**
* Gets the list of terrain regions managed by this provider.
*/
get regions(): readonly HybridTerrainProvider.TerrainRegion[];
/**
* Gets the default terrain provider.
*/
get defaultProvider(): TerrainProvider;
/**
* @deprecated
*/
get fallbackProvider(): TerrainProvider;
/**
* Gets all the credits to display from registered providers when
* this terrain provider is active. Typically this is used to credit
* the source of the terrain.
*/
get credit(): Credit;
/**
* Gets an event that is raised when the terrain provider encounters an asynchronous error. By subscribing
* to the event, you will be notified of the error and can potentially recover from it. Event listeners
* are passed an instance of `TileProviderError`.
*/
get errorEvent(): Event<TerrainProvider.ErrorEvent>;
/**
* Gets a value indicating whether or not the provider includes a water mask. The water mask
* indicates which areas of the globe are water rather than land, so they can be rendered
* as a reflective surface with animated waves.
*/
get hasWaterMask(): boolean;
/** Gets a value indicating whether or not the requested tiles include vertex normals. */
get hasVertexNormals(): boolean;
/**
* Makes sure we load availability data for a tile
* @param x - The X coordinate of the tile for which to request geometry.
* @param y - The Y coordinate of the tile for which to request geometry.
* @param level - The level of the tile for which to request geometry.
* @returns Undefined if nothing need to be loaded or a Promise that resolves when all required tiles are loaded
*/
loadTileDataAvailability(x: number, y: number, level: number): Promise<void> | undefined;
/**
* Gets the maximum geometric error allowed in a tile at a given level, taken as the
* worst case across the default provider and all region providers. Because the hybrid
* provider's coverage is a composition of multiple sources, the reported error reflects
* the highest error any source could contribute at this level, ensuring the LOD system
* refines conservatively enough for all sources.
* @param level - The tile level for which to get the maximum geometric error.
* @returns The maximum geometric error across all providers.
*/
getLevelMaximumGeometricError(level: number): number;
/**
* Requests the terrain for a given tile coordinate.
* @param x The X coordinate of the tile.
* @param y The Y coordinate of the tile.
* @param level The zoom level of the tile.
* @param request The request.
* @returns A promise for the requested terrain.
*/
requestTileGeometry(x: number, y: number, level: number, request?: Request): Promise<TerrainData> | undefined;
/**
* Determines whether data for a tile is available to be loaded. Checks the specified terrain regions first.
* @param x - The X coordinate of the tile for which to request geometry.
* @param y - The Y coordinate of the tile for which to request geometry.
* @param level - The level of the tile for which to request geometry.
* @returns Undefined if not supported by the terrain provider, otherwise true or false.
*/
getTileDataAvailable(x: number, y: number, level: number): boolean | undefined;
/**
* Cleans up resources used in the `HybridTerrainProvider`.
*
* This method only releases additional resources used to instantiate the `HybridTerrainProvider`.
*/
destroy(): void;
}
/**
* @namespace
* Contains types and factory methods for `HybridTerrainProvider` instance.
*/
declare namespace HybridTerrainProvider {
/** Initialization options for `HybridTerrainProvider` constructor. */
interface ConstructorOptions {
/** An array of terrain regions to include in the hybrid terrain. */
regions?: TerrainRegion[];
/** Default provider to use outside of specified terrain regions. */
defaultProvider: TerrainProvider;
/**
* Optional fallback provider when data is not available from default provider.
*
* @default EllipsoidTerrainProvider
* @deprecated
*/
fallbackProvider?: TerrainProvider;
}
/**
* A factory function which creates a HybridTerrainProvider from tile-coordinate based regions.
* @param regions Array of regions with tile-coordinate bounds
* @param defaultProvider Default terrain provider
* @param fallbackProvider Optional fallback provider
*/
function fromTileRanges(regions: Array<{
provider: TerrainProvider;
tiles: Map<number, {
x: number | [number, number];
y: number | [number, number];
}>;
levels?: number[];
}>, defaultProvider: TerrainProvider, fallbackProvider?: TerrainProvider): HybridTerrainProvider;
/** Represents a terrain region with provider and geographic bounds. */
interface TerrainRegion {
/** The terrain provider for this region. */
provider: TerrainProvider;
/**
* Tile-coordinate based bounds (precise control).
* Map of level to tile coordinate ranges for that level.
*/
tiles?: Map<number, {
/** X tile coordinate range [min, max] or single value. */
x: number | [number, number];
/** Y tile coordinate range [min, max] or single value. */
y: number | [number, number];
}>;
/** Optional level constraints. If specified, region only applies to these levels. */
levels?: number[];
}
/**
* Checks if a terrain region contains the specified tile.
* @param region The terrain region to check
* @param x The X coordinate of the tile
* @param y The Y coordinate of the tile
* @param level The zoom level of the tile
* @returns True if the region contains the tile, false otherwise
*/
function regionContainsTile(region: HybridTerrainProvider.TerrainRegion, x: number, y: number, level: number): boolean;
/**
* @namespace
* Utility functions for working with TerrainRegion objects.
*
* @deprecated This will be removed in 0.5.0, due to the usage of nested namespace.
*/
namespace TerrainRegion {
/**
* Checks if a terrain region contains the specified tile.
*
* @deprecated This will be removed in 0.5.0. Use {@link HybridTerrainProvider.regionContainsTile} instead.
*/
function contains(region: HybridTerrainProvider.TerrainRegion, x: number, y: number, level: number): boolean;
}
}
type TerrainTiles = NonNullable<HybridTerrainProvider.TerrainRegion["tiles"]>;
type TerrainRegion = HybridTerrainProvider.TerrainRegion;
type TerrainOptions = HybridTerrainProvider.ConstructorOptions;
/**
* Copies configuration and state from one Cesium Viewer to another.
* @param source - The source viewer to copy properties from
* @param container - DOM element ID or element for the new viewer
* @param options - Optional override options for the new viewer
* @returns A new Viewer instance with copied properties
*/
declare function cloneViewer(source: Viewer, container: Element | string, options?: Viewer.ConstructorOptions): Viewer;
/**
* Copies camera state from source viewer to destination viewer.
* @param source The source viewer to copy camera states from.
* @param dest The destination viewer to apply camera properties from the source.
*/
declare function syncCamera(source: Viewer, dest: Viewer): void;
/**
* Utility for managing deprecation warnings in the cesium-utils library.
* Provides runtime warnings to help developers identify deprecated API usage.
*/
declare namespace Deprecate {
/**
* Configuration options for deprecation warnings.
*/
interface Options {
/**
* Whether to show the warning only once per deprecation message.
* @default true
*/
once?: boolean;
/**
* Custom prefix for the warning message.
* @default "[DEPRECATED]"
*/
prefix?: string;
/**
* Whether to include a stack trace in the warning.
* @default true
*/
includeStack?: boolean;
/**
* Version when the feature will be removed.
*/
removeInVersion?: string;
}
/**
* Displays a deprecation warning message.
*
* @param message - The deprecation message to display
* @param options - Configuration options for the warning
*
* @example
* ```typescript
* // Basic usage
* deprecationWarning("oldFunction() is deprecated. Use newFunction() instead.");
*
* // With removal version
* deprecationWarning("TerrainArea is deprecated.", {
* removeInVersion: "v0.3.0"
* });
*
* // Allow multiple warnings
* deprecationWarning("Repeated warning", { once: false });
* ```
*/
function warn(message: string, options?: Options): void;
/**
* Creates a deprecation wrapper function that shows a warning when called.
*
* @param fn - The function to wrap
* @param message - The deprecation message
* @param options - Configuration options for the warning
* @returns A wrapped function that shows a deprecation warning when called
*
* @example
* ```typescript
* const oldFunction = deprecate(
* () => console.log("old implementation"),
* "oldFunction() is deprecated. Use newFunction() instead."
* );
*
* oldFunction(); // Shows warning and executes function
* ```
*/
function deprecate<T extends (...args: any[]) => any>(fn: T, message: string, options?: Options): T;
/**
* Clears all shown warning messages.
* Useful for testing or when you want to reset the warning state.
*
* @example
* ```typescript
* clearDeprecationWarnings();
* deprecationWarning("This will show again");
* ```
*/
function clear(): void;
/**
* Gets the count of unique deprecation warnings that have been shown.
*
* @returns The number of unique deprecation warnings shown
*/
function getWarningCount(): number;
/**
* Checks if a specific deprecation warning has been shown.
*
* @param message - The deprecation message to check
* @returns True if the warning has been shown, false otherwise
*/
function hasShown(message: string): boolean;
}
declare const deprecate: typeof Deprecate.deprecate;
/**
* @since Cesium 1.132.0
* @experimental
* Point sunlight analysis utility for shadow calculations.
*
* ⚠️ **Warning**: This is an experimental feature that uses Cesium's internal APIs.
* The API may change or break in future versions of Cesium or cesium-utils.
*
* @example
* ```typescript
* const sunlight = new Sunlight(viewer);
* sunlight.analyze(point, JulianDate.now());
* ```
*/
declare class Sunlight {
private _uniformState;
private _viewer;
private _analyzing;
private _pointEntityId?;
private _objectsToExclude;
private _polylines;
private _points;
constructor(viewer: Viewer);
/** The sun position in 3D world coordinates at the current scene time. */
get sunPositionWC(): Cartesian3;
/** A normalized vector to the sun in 3D world coordinates at the current scene time. */
get sunDirectionWC(): Cartesian3;
/** Whether sunlight analysis is currently in progress. */
get isAnalyzing(): boolean;
/**
* Gets virtual position and direction of the sun to reduce calculation overhead.
*
* @param from target point to start from
* @param radius virtual distance between target point and the sun. Defaults to 10000 (10km)
*/
virtualSun(from: Cartesian3, radius?: number): {
position: Cartesian3;
direction: Cartesian3;
};
/**
* Analyze the sunlight acceptance from a given point at a given time.
* @param from target point to analyze
* @param at time to analyze
* @param options {@link Sunlight.AnalyzeOptions}
*/
analyze(from: Cartesian3, at: JulianDate, options?: Sunlight.AnalyzeOptions): Promise<Sunlight.AnalysisResult>;
/**
* Analyze the sunlight acceptance from a given point at a given time range.
* @param from target point to analyze
* @param range time range to analyze
* @param options {@link Sunlight.AnalyzeOptions}
*/
analyze(from: Cartesian3, range: Sunlight.TimeRange, options?: Sunlight.AnalyzeOptions): Promise<Sunlight.AnalysisResult[]>;
/**
* Remove all instances created for debug purpose
*/
clear(): void;
/**
* Create an ellipsoid entity for ray collision detection to complement cesium's native click event accuracy
* @param at where to create the entity
* @param show whether to show point entity
* @param errorBoundary size of the point entity for error tolerance
*/
setTargetPoint(at: Cartesian3, show?: boolean, errorBoundary?: number, color?: Color): Entity;
private _analyzeSingleTime;
private _analyzeTimeRange;
/**
* @returns A promise tht resolves to an object containing the object and position of the first intersection.
* @see https://github.com/CesiumGS/cesium/blob/1.136/packages/engine/Source/Scene/Scene.js#L4868
*/
private _pick;
private _getExcludedObjects;
}
declare namespace Sunlight {
const DETECTION_ELLIPSOID_ID = "sunlight-detection-ellipsoid";
/** for time-range analysis */
interface TimeRange {
/** When to start analysis */
start: JulianDate;
/** When to end analysis */
end: JulianDate;
/** Step interval (seconds) inside the range */
step: number;
}
interface AnalyzeOptions {
/** List of objects to exclude from ray pick */
objectsToExclude?: any[];
/** size of the point entity for error tolerance */
errorBoundary?: number;
/** Whether to show sunlight paths */
debugShowRays?: boolean;
/** Whether to show points */
debugShowPoints?: boolean;
}
interface AnalysisResult {
/** ISO time string */
timestamp: string;
/** Whether the sunlight has reached */
result: boolean | any;
}
}
/**
* @class
* Utility class for visualizing terrain provider boundaries and debugging terrain loading.
*/
declare class TerrainVisualizer {
private _viewer;
private _terrainProvider;
private _visible;
private _tileCoordinatesLayer;
private _hybridImageryLayer;
private _colors;
/**
* Creates a new `TerrainVisualizer`.
* @param viewer The Cesium viewer instance
* @param options {@link TerrainVisualizer.ConstructorOptions}
*/
constructor(viewer: Viewer, options: TerrainVisualizer.ConstructorOptions);
/**
* Sets the terrain provider to visualize.
* @param terrainProvider The terrain provider to visualize.
*/
setTerrainProvider(terrainProvider: HybridTerrainProvider): void;
/**
* Updates all active visualizations.
*/
update(): void;
/**
* Clears all visualizations.
*/
clear(): void;
/**
* Shows terrain visualization using HybridImageryProvider.
* Optionally adds tile coordinate grid overlay.
* @param options Visualization options
*/
show(options?: {
/** Show tile coordinate labels. Default: true */
showTileCoordinates?: boolean;
/** Transparency level (0-1). Default: 0.5 */
alpha?: number;
}): void;
private _ensureTileCoordinatesLayer;
/**
* Hides the terrain visualization.
*/
hide(): void;
/**
* Sets the colors used for visualization.
* @param colors Map of role names to colors
*/
setColors(colors: Record<string, Color>): void;
/**
* Shows terrain regions using HybridImageryProvider (performant, global coverage).
* This replaces the entity-based approach with an imagery layer.
* @param alpha Transparency level (0-1), default 0.5
*/
showImageryOverlay(alpha?: number): void;
/**
* Hides the imagery overlay.
*/
hideImageryOverlay(): void;
/**
* Shows tile coordinate grid overlay.
*/
showTileCoordinates(): void;
/**
* Hides tile coordinate grid overlay.
*/
hideTileCoordinates(): void;
/**
* Sets the transparency of the imagery overlay.
* @param alpha Transparency level (0-1), where 0 is fully transparent and 1 is fully opaque
*/
setAlpha(alpha: number): void;
/**
* Flies the camera to focus on a rectangle.
* @param rectangle The rectangle to focus on.
* @param options {@link Viewer.flyTo}
*/
flyTo(rectangle: Rectangle, options?: {
duration?: number;
}): void;
/** Whether tile coordinates are currently visible. */
get tileCoordinatesVisible(): boolean;
/** Whether the grid is currently visible. */
get visible(): boolean;
/** The viewer used in the visualizer */
get viewer(): Viewer;
/** The colors used in the visualizer */
get colors(): Map<string, Color>;
/** The hybrid terrain instance used in the visualizer */
get terrainProvider(): HybridTerrainProvider;
}
/**
* @namespace
* Contains types, utility functions, and constants for terrain visualization.
*/
declare namespace TerrainVisualizer {
/** Initialization options for `TerrainVisualizer` constructor. */
interface ConstructorOptions {
/** Colors to use for different visualization elements */
colors?: Record<string, Color>;
/** Whether to show tile grid initially. */
tile?: boolean;
/** Initial zoom level to use for visualizations. */
activeLevel?: number;
/** Terrain provider to visualize. */
terrainProvider: HybridTerrainProvider;
}
/** Options for {@link TerrainVisualizer.visualize} */
interface Options {
color?: Color;
show?: boolean;
maxTilesToShow?: number;
levels?: number[];
tag?: string;
alpha?: number;
tileAlpha?: number;
}
}
export { Collection, Deprecate, Highlight, HybridTerrainProvider, SilhouetteHighlight, Sunlight, SurfaceHighlight, type TerrainOptions, TerrainRegion, type TerrainTiles, TerrainVisualizer, cloneViewer, deprecate, syncCamera };