import { Color, Raycaster, Vector2, type ColorRepresentation, type Intersection, type Mesh, type Object3D, type Side } from 'three';
import type ColorimetryOptions from '../core/ColorimetryOptions';
import type Context from '../core/Context';
import type ContourLineOptions from '../core/ContourLineOptions';
import type ElevationProvider from '../core/ElevationProvider';
import type ElevationRange from '../core/ElevationRange';
import type ElevationSample from '../core/ElevationSample';
import type Extent from '../core/geographic/Extent';
import type GetElevationOptions from '../core/GetElevationOptions';
import type GetElevationResult from '../core/GetElevationResult';
import type GraticuleOptions from '../core/GraticuleOptions';
import type HasDefaultPointOfView from '../core/HasDefaultPointOfView';
import type ColorLayer from '../core/layer/ColorLayer';
import type ElevationLayer from '../core/layer/ElevationLayer';
import type HasLayers from '../core/layer/HasLayers';
import type Layer from '../core/layer/Layer';
import type MemoryUsage from '../core/MemoryUsage';
import type Pickable from '../core/picking/Pickable';
import type PickableFeatures from '../core/picking/PickableFeatures';
import type PickOptions from '../core/picking/PickOptions';
import type TerrainOptions from '../core/TerrainOptions';
import type RenderingState from '../renderer/RenderingState';
import type { EntityUserData } from './Entity';
import type { Entity3DOptions } from './Entity3D';
import type MapLightingOptions from './MapLightingOptions';
import type { TileGeometryBuilder } from './tiles/TileGeometry';
import type TileVolume from './tiles/TileVolume';
import CoordinateSystem from '../core/geographic/CoordinateSystem';
import { type GetMemoryUsageContext } from '../core/MemoryUsage';
import { type MapPickResult } from '../core/picking/PickTilesAt';
import Entity3D, { type Entity3DEventMap } from './Entity3D';
import TileIndex from './tiles/TileIndex';
import TileMesh from './tiles/TileMesh';
export { type MapLightingOptions };
/**
 * Interface for Map tiles.
 */
export interface Tile extends Mesh {
    /**
     * The level of detail (LOD) of the tile. LOD 0 means the tile is a root tile.
     */
    lod: number;
    /**
     * The geographic extent of the tile. If the tile has LOD 0, then it is the same as the extent of its parent map.
     */
    extent: Extent;
}
/**
 * A function that allows subdivision of the specified tile.
 * If the function returns `true`, the node can be subdivided.
 */
export type MapSubdivisionStrategy = (
/**
 * The tile to subdivide.
 */
tile: Readonly<Tile>, context: {
    entity: Readonly<Map>;
    layers: readonly Readonly<Layer>[];
}) => boolean;
/**
 * Allows subdivision if:
 * - **if elevation layer present and active and terrain deformation is enabled**: wait for all elevation layers to have finished loading the tile,
 * - otherwise allow subdivision without condition
 */
export declare const defaultMapSubdivisionStrategy: MapSubdivisionStrategy;
/**
 * Allows subdivision if all layers have loaded this node, regardless the type of the layer.
 * This strategy has a greater memory, network and CPU consumption than the default strategy,
 * but can be useful to ensure a smooth rendering of tiles without visible flicker or "jumps".
 */
export declare const allLayersLoadedSubdivisionStrategy: MapSubdivisionStrategy;
/**
 * The default background color of maps.
 */
export declare const DEFAULT_MAP_BACKGROUND_COLOR: ColorRepresentation;
/**
 * The default tile subdivision threshold.
 */
export declare const DEFAULT_SUBDIVISION_THRESHOLD = 1.5;
/**
 * Comparison function to order layers.
 */
export type LayerCompareFn = (a: Layer, b: Layer) => number;
export interface MapEventMap extends Entity3DEventMap {
    /** Fires when a the layer ordering changes. */
    'layer-order-changed': unknown;
    /** Fires when a layer is added to the map. */
    'layer-added': {
        layer: Layer;
    };
    /** Fires when a layer is removed from the map. */
    'layer-removed': {
        layer: Layer;
    };
    /** Fires when the visibility of a layer present on this map changes. */
    'layer-visibility-changed': {
        layer: Layer;
    };
    /** Fires when elevation data has changed on a specific extent of the map. */
    'elevation-changed': {
        extent: Extent;
    };
    /** Fires when (final, non-interim) elevation data has been loaded for a specific tile */
    'elevation-loaded': {
        tile: Tile;
    };
    /** Fires when all tiles are painted */
    'paint-complete': unknown;
    /** Fires when a tile is created. */
    'tile-created': {
        tile: Tile;
    };
    /** Fires when a tile is deleted. */
    'tile-deleted': {
        tile: Tile;
    };
}
/**
 * Constructor options for the {@link Map} entity.
 */
export interface MapOptions extends Entity3DOptions {
    /**
     * The geographic extent of the map.
     *
     * Note: It must have the same CRS as the instance this map will be added to.
     */
    extent: Extent;
    /**
     * Maximum tile depth of the map. If `undefined`, there is no limit to the subdivision
     * of the map.
     * @defaultValue undefined
     */
    maxSubdivisionLevel?: number;
    /**
     * Lighting and shading parameters.
     * @defaultValue `undefined` (lighting is disabled)
     */
    lighting?: boolean | MapLightingOptions;
    /**
     * Enables contour lines. If `undefined` or `false`, contour lines
     * are not displayed.
     *
     * Note: this option has no effect if the map does not contain an elevation layer.
     * @defaultValue `undefined` (contour lines are disabled)
     */
    contourLines?: boolean | Partial<ContourLineOptions>;
    /**
     * The graticule options.
     * @defaultValue undefined (graticule is disabled).
     */
    graticule?: boolean | Partial<GraticuleOptions>;
    /**
     * The colorimetry for the whole map.
     * Those are distinct from the individual layers' own colorimetry.
     * @defaultValue undefined
     */
    colorimetry?: ColorimetryOptions;
    /**
     * The sidedness of the map surface:
     * - `FrontSide` will only display the "above ground" side of the map (in cartesian maps),
     * or the outer shell of the map (in globe settings).
     * - `BackSide` will only display the "underground" side of the map (in cartesian maps),
     * or the inner shell of the map (in globe settings).
     * - `DoubleSide` will display both sides of the map.
     * @defaultValue `FrontSide`
     */
    side?: Side;
    /**
     * Enable or disable depth testing on materials.
     * @defaultValue true
     */
    depthTest?: boolean;
    /**
     * Options for geometric terrain rendering.
     */
    terrain?: boolean | Partial<TerrainOptions>;
    /**
     * If `true`, parts of the map that relate to no-data elevation
     * values are not displayed. Note: you should only set this value to `true` if
     * an elevation layer is present, otherwise the map will never be displayed.
     * @defaultValue false
     */
    discardNoData?: boolean;
    /**
     * The color of the map when no color layers are present.
     * @defaultValue {@link DEFAULT_MAP_BACKGROUND_COLOR}
     */
    backgroundColor?: ColorRepresentation;
    /**
     * The opacity of the map background.
     * @defaultValue 1 (opaque)
     */
    backgroundOpacity?: number;
    /**
     * Show the map tiles' borders.
     * @defaultValue false
     */
    showOutline?: boolean;
    /**
     * The color of the tile borders.
     * @defaultValue red
     */
    outlineColor?: ColorRepresentation;
    /**
     * The optional elevation range of the map. The map will not be
     * rendered for elevations outside of this range.
     * Note: this feature is only useful if an elevation layer is added to this map.
     * @defaultValue undefined (elevation range is disabled)
     */
    elevationRange?: ElevationRange;
    /**
     * Force using texture atlases even when not required.
     * @defaultValue false
     */
    forceTextureAtlases?: boolean;
    /**
     * The threshold before which a map tile is subdivided.
     * @defaultValue {@link DEFAULT_SUBDIVISION_THRESHOLD}
     */
    subdivisionThreshold?: number;
    /**
     * If `true`, the map will cast shadow.
     * @defaultValue true
     */
    castShadow?: boolean;
    /**
     * If `true`, the map will receive shadow.
     * Note: only available if {@link lighting.mode} is {@link MapLightingMode.LightBased}
     * @defaultValue true
     */
    receiveShadow?: boolean;
    /**
     * The subdivision strategy used to subdivide map tiles.
     * @defaultValue {@link defaultMapSubdivisionStrategy}
     */
    subdivisionStrategy?: MapSubdivisionStrategy;
}
/**
 * A map is an {@link Entity3D} that represents a flat surface displaying one or more {@link core.layer.Layer | layer(s)}.
 *
 * ## Supported layers
 *
 * Maps support various types of layers.
 *
 * ### Color layers
 *
 * Maps can contain any number of {@link core.layer.ColorLayer | color layers}, as well as any number of {@link core.layer.MaskLayer | mask layers}.
 *
 * Color layers are used to display satellite imagery, vector features or any other dataset.
 * Mask layers are used to mask parts of a map (like an alpha channel).
 *
 * ### Elevation layers
 *
 * Up to one elevation layer can be added to a map, to provide features related to elevation, such
 * as terrain deformation, shading, contour lines, etc. Without an elevation layer, the map
 * will appear like a flat rectangle on the specified extent.
 *
 * Note: to benefit from the features given by elevation layers (shading for instance) while keeping
 * a flat map, disable terrain in the {@link TerrainOptions}.
 *
 * 💡 The elevation data can be sampled by the {@link getElevation} method.
 *
 * ## Picking on maps
 *
 * Maps can be picked like any other 3D entity, using the {@link entities.Entity3D#pick | pick()} method.
 *
 * ### GPU-based picking
 *
 * This is the default method for picking maps. When the user calls {@link entities.Entity3D#pick | pick()},
 * the camera's field of view is rendered into a temporary texture, then the pixel(s) around the picked
 * point are analyzed to determine the location of the picked point.
 *
 * The main advantage of this method is that it ignores transparent pixels of the map (such as
 * no-data elevation pixels, or transparent color layers).
 *
 * ### Raycasting-based picking
 *
 * 💡 This method requires that {@link core.picking.PickOptions.gpuPicking} is disabled.
 *
 * This method casts a ray that is then intersected with the map's meshes. The first intersection is
 * returned.
 *
 * The main advantage of this method is that it's much faster and puts less pressure on the GPU.
 *
 * ## Lighting and shadows
 *
 * The Map currently support two lighting modes:
 * - the simplified, hillshade model
 * - the dynamic, light-based model, that uses three.js lights
 *
 * Both modes support casting shadows from the Map (on other objects), but only the light-based
 * mode enables Maps to _receive_ shadows (from itself or other objects).
 *
 * @typeParam UserData - The type of the {@link entities.Entity#userData} property.
 */
declare class Map<UserData extends EntityUserData = EntityUserData> extends Entity3D<MapEventMap, UserData> implements Pickable<MapPickResult>, PickableFeatures<unknown, MapPickResult>, ElevationProvider, HasLayers, MemoryUsage {
    readonly isMap: true;
    readonly type: string;
    readonly hasLayers: true;
    readonly isPickableFeatures: true;
    readonly extent: Extent;
    readonly maxSubdivisionLevel: number;
    private readonly _objectOptions;
    private readonly _layers;
    private readonly _onLayerVisibilityChanged;
    private readonly _onTileElevationChanged;
    private readonly _rootTiles;
    private readonly _allTiles;
    private readonly _tileIndex;
    private readonly _layerIndices;
    private readonly _cachedTraversals;
    private readonly _layerIds;
    private readonly _materialOptions;
    private readonly _subdivisionStrategy;
    private readonly _onNodeComplete;
    private _paintCompleteTimeout;
    private _geometryBuilder;
    private _hasElevationLayer;
    private _elevationScaling;
    private _colorAtlasDataType;
    private _wireframe;
    private _subdivisionThreshold;
    getMemoryUsage(context: GetMemoryUsageContext): void;
    /**
     * Constructs a Map object.
     *
     * @param options - Constructor options.
     */
    constructor(options: MapOptions);
    get tileIndex(): Readonly<TileIndex<TileMesh>>;
    /**
     * Gets the tiles at the root of the hierarchy (i.e LOD 0).
     */
    get rootTiles(): Readonly<TileMesh[]>;
    /**
     * Returns `true` if this map is currently processing data.
     */
    get loading(): boolean;
    private onNodeComplete;
    private evaluatePaintComplete;
    /**
     * Gets the loading progress (between 0 and 1) of the map. This is the average progress of all
     * layers in this map.
     * Note: if no layer is present, this will always be 1.
     * Note: This value is only meaningful is {@link loading} is `true`.
     */
    get progress(): number;
    /**
     * Gets or sets depth testing on materials.
     */
    get depthTest(): boolean;
    set depthTest(v: boolean);
    /**
     * Gets or sets the background opacity.
     */
    get backgroundOpacity(): number;
    set backgroundOpacity(opacity: number);
    /**
     * Gets or sets the terrain options.
     */
    get terrain(): Required<TerrainOptions>;
    set terrain(terrain: TerrainOptions);
    /**
     * The global factor that drives SSE (screen space error) computation. The lower this value, the
     * sooner a tile is subdivided. Note: changing this scale to a value less than 1 can drastically
     * increase the number of tiles displayed in the scene, and can even lead to WebGL crashes.
     *
     * @defaultValue {@link DEFAULT_SUBDIVISION_THRESHOLD}
     */
    get subdivisionThreshold(): number;
    set subdivisionThreshold(v: number);
    /**
     * Gets or sets the sidedness of the map surface:
     * - `FrontSide` will only display the "above ground" side of the map (in cartesian maps),
     * or the outer shell of the map (in globe settings).
     * - `BackSide` will only display the "underground" side of the map (in cartesian maps),
     * or the inner shell of the map (in globe settings).
     * - `DoubleSide` will display both sides of the map.
     * @defaultValue `FrontSide`
     */
    get side(): Side;
    set side(newSide: Side);
    /**
     * Toggles discard no-data pixels.
     */
    get discardNoData(): boolean;
    set discardNoData(opacity: boolean);
    /**
     * Gets or sets the background color.
     */
    get backgroundColor(): Color;
    set backgroundColor(c: ColorRepresentation);
    /**
     * Gets or sets graticule options.
     */
    get graticule(): Required<GraticuleOptions>;
    set graticule(opts: GraticuleOptions);
    private updateObject;
    private updateObjectOption;
    /**
     * Toggles the `.castShadow` property on objects generated by this entity.
     */
    get castShadow(): boolean;
    set castShadow(v: boolean);
    /**
     * Toggles the `.receiveShadow` property on objects generated by this entity.
     *
     * Note that map tiles will receive shadows only if {@link lighting} mode is set to {@link MapLightingMode.LightBased}.
     */
    get receiveShadow(): boolean;
    set receiveShadow(v: boolean);
    /**
     * Gets or sets lighting options.
     */
    get lighting(): Required<MapLightingOptions>;
    set lighting(opts: MapLightingOptions);
    /**
     * Gets or sets colorimetry options.
     */
    get colorimetry(): Required<ColorimetryOptions>;
    set colorimetry(opts: ColorimetryOptions);
    /**
     * Gets or sets elevation range.
     */
    get elevationRange(): ElevationRange | null;
    set elevationRange(range: ElevationRange | null);
    /**
     * Shows tile outlines.
     */
    get showTileOutlines(): boolean;
    set showTileOutlines(show: boolean);
    /**
     * Gets or sets tile outline color.
     */
    get tileOutlineColor(): Color;
    set tileOutlineColor(color: ColorRepresentation);
    /**
     * Gets or sets contour line options.
     */
    get contourLines(): Required<ContourLineOptions>;
    set contourLines(opts: ContourLineOptions);
    /**
     * Shows volumes of tiles.
     */
    get showBoundingBoxes(): boolean;
    set showBoundingBoxes(show: boolean);
    /**
     * Shows volumes of tiles.
     */
    get showBoundingSpheres(): boolean;
    set showBoundingSpheres(show: boolean);
    /**
     * Shows volumes of tiles.
     */
    get helperColor(): ColorRepresentation;
    set helperColor(color: ColorRepresentation);
    /**
     * Shows meshes used for raycasting purposes.
     */
    get showColliderMeshes(): boolean;
    set showColliderMeshes(show: boolean);
    get segments(): number;
    set segments(v: number);
    /**
     * Displays the map tiles in wireframe.
     */
    get wireframe(): boolean;
    set wireframe(v: boolean);
    private subdivideNode;
    private updateGeometries;
    /**
     * Gets the number of vertical and horizontal subdivisions for the root tile matrix.
     */
    protected getRootTileMatrix(): {
        x: number;
        y: number;
    };
    preprocess(): Promise<void>;
    /**
     * Compute the best image size for tiles, taking into account the extent ratio.
     * In other words, rectangular tiles will have more pixels in their longest side.
     *
     * @param extent - The tile extent.
     */
    protected getTextureSize(extent: Extent): Vector2;
    protected getTileDimensions(extent: Extent): Vector2;
    protected get isEllipsoidal(): boolean;
    protected getComposerProjection(): CoordinateSystem;
    protected getGeometryBuilder(): TileGeometryBuilder;
    private requestNewTile;
    protected createTileVolume(extent: Extent): TileVolume;
    private onTileElevationChanged;
    /**
     * Sets the render state of the map.
     *
     * @internal
     * @param state - The new state.
     * @returns The function to revert to the previous state.
     */
    setRenderState(state: RenderingState): () => void;
    pick(coordinates: Vector2, options?: PickOptions): MapPickResult[];
    private raycastAtCoordinate;
    protected getDefaultTerrainOptions(): Readonly<TerrainOptions>;
    protected getDefaultLightingOptions(): Readonly<Required<MapLightingOptions>>;
    private pickUsingRaycast;
    /**
     * Perform raycasting on visible tiles.
     * @param raycaster - The THREE raycaster.
     * @param intersects  - The intersections array to populate with intersections.
     */
    raycast(raycaster: Raycaster, intersects: Intersection<TileMesh>[]): void;
    pickFeaturesFrom(pickedResult: MapPickResult, options?: PickOptions): unknown[];
    preUpdate(context: Context, changeSources: Set<unknown>): TileMesh[];
    /**
     * Sort the color layers according to the comparator function.
     *
     * @param compareFn - The comparator function.
     */
    sortColorLayers(compareFn: LayerCompareFn): void;
    /**
     * Moves the layer closer to the foreground.
     *
     * Note: this only applies to color layers.
     *
     * @param layer - The layer to move.
     * @throws If the layer is not present in the map.
     * @example
     * map.addLayer(foo);
     * map.addLayer(bar);
     * map.addLayer(baz);
     * // Layers (back to front) : foo, bar, baz
     *
     * map.moveLayerUp(foo);
     * // Layers (back to front) : bar, foo, baz
     */
    moveLayerUp(layer: ColorLayer): void;
    onRenderingContextRestored(): void;
    /**
     * Moves the specified layer after the other layer in the list.
     *
     * @param layer - The layer to move.
     * @param target - The target layer. If `null`, then the layer is put at the
     * beginning of the layer list.
     * @throws If the layer is not present in the map.
     * @example
     * map.addLayer(foo);
     * map.addLayer(bar);
     * map.addLayer(baz);
     * // Layers (back to front) : foo, bar, baz
     *
     * map.insertLayerAfter(foo, baz);
     * // Layers (back to front) : bar, baz, foo
     */
    insertLayerAfter(layer: ColorLayer, target: ColorLayer | null): void;
    /**
     * Moves the layer closer to the background.
     *
     * Note: this only applies to color layers.
     *
     * @param layer - The layer to move.
     * @throws If the layer is not present in the map.
     * @example
     * map.addLayer(foo);
     * map.addLayer(bar);
     * map.addLayer(baz);
     * // Layers (back to front) : foo, bar, baz
     *
     * map.moveLayerDown(baz);
     * // Layers (back to front) : foo, baz, bar
     */
    moveLayerDown(layer: ColorLayer): void;
    /**
     * Returns the position of the layer in the layer list, or -1 if it is not found.
     *
     * @param layer - The layer to search.
     * @returns The index of the layer.
     */
    getIndex(layer: Layer): number;
    private reorderLayers;
    contains(obj: unknown): boolean;
    update(context: Context, node: TileMesh): TileMesh[] | undefined;
    protected testVisibility(node: TileMesh, context: Context): boolean;
    postUpdate(context: Context): void;
    private registerColorLayer;
    private updateGlobalMinMax;
    private registerColorMap;
    /**
     * Adds a layer, then returns the created layer.
     * Before using this method, make sure that the map is added in an instance.
     * If the extent or the projection of the layer is not provided,
     * those values will be inherited from the map.
     *
     * @param layer - the layer to add
     * @returns a promise resolving when the layer is ready
     */
    addLayer<TLayer extends Layer>(layer: TLayer): Promise<TLayer>;
    private onLayerVisibilityChanged;
    /**
     * Removes a layer from the map.
     *
     * @param layer - the layer to remove
     * @param options - The options.
     * @returns `true` if the layer was present, `false` otherwise.
     */
    removeLayer(layer: Layer, options?: {
        /** If `true`, the layer is also disposed. */
        disposeLayer?: boolean;
    }): boolean;
    get layerCount(): number;
    forEachLayer(callback: (layer: Layer) => void): void;
    /**
     * Gets all layers that satisfy the filter predicate.
     *
     * @param predicate - the optional predicate.
     * @returns the layers that matched the predicate or all layers if no predicate was provided.
     */
    getLayers(predicate?: (arg0: Layer) => boolean): Layer[];
    /**
     * Gets all color layers in this map.
     *
     * @returns the color layers
     */
    getColorLayers(): ColorLayer[];
    /**
     * Gets all elevation layers in this map.
     *
     * @returns the elevation layers
     */
    getElevationLayers(): ElevationLayer[];
    /**
     * Disposes this map and associated unmanaged resources.
     *
     * Note: By default, layers in this map are not automatically disposed, except when
     * `disposeLayers` is `true`.
     *
     * @param options - Options.
     * @param options -.disposeLayers If true, layers are also disposed.
     */
    dispose(options?: {
        disposeLayers?: boolean;
    }): void;
    private disposeTile;
    /**
     * Gets the elevation range of visible tiles, or `null` if no tile is visible.
     *
     * If there are no elevation layers on this map, returns `null` as well.
     */
    getElevationMinMaxForVisibleTiles(): ElevationRange | null;
    /**
     * Returns the minimal and maximal elevation values in this map, in meters.
     *
     * If there is no elevation layer present, returns `{ min: 0, max: 0 }`.
     *
     * @returns The min/max value.
     */
    getElevationMinMax(): ElevationRange;
    private getRootTileThatContainsXY;
    getElevationFast(x: number, y: number): ElevationSample | undefined;
    /**
     * Sample the elevation at the specified coordinate.
     *
     * Note: this method does nothing if no elevation layer is present on the map, or if the
     * sampling coordinate is not inside the map's extent.
     *
     * Note: sampling might return more than one sample for any given coordinate. You can sort them
     * by {@link core.ElevationSample.resolution | resolution} to select the best sample for your needs.
     * @param options - The options.
     * @param result - The result object to populate with the samples. If none is provided, a new
     * empty result is created. The existing samples in the array are not removed. Useful to
     * cumulate samples across different maps.
     * @returns The {@link GetElevationResult} containing the updated sample array.
     * If the map has no elevation layer, this array is left untouched.
     */
    getElevation(options: GetElevationOptions, result?: GetElevationResult): GetElevationResult;
    /**
     * Traverses all tiles in the hierarchy of this entity.
     *
     * @param callback - The callback.
     * @param root - The raversal root. If undefined, the traversal starts at the root
     * object of this entity.
     */
    traverseTiles(callback: (arg0: TileMesh) => void, root?: Object3D | undefined): void;
    private testTileSSE;
    protected shouldSubdivide(context: Context, node: TileMesh): boolean;
    private updateMinMaxDistance;
    /**
     * Returns a {@link PointOfView} that looks at the map from the top.
     */
    getDefaultPointOfView(params: Parameters<HasDefaultPointOfView['getDefaultPointOfView']>[0]): ReturnType<HasDefaultPointOfView['getDefaultPointOfView']>;
}
export declare function isMap(o: unknown): o is Map;
export default Map;
//# sourceMappingURL=Map.d.ts.map