import { BBox, BBoxFeature, BBoxFeatureCollection } from '@linzjs/geojson';
import { Position } from 'geojson';
import { PROJJSONDefinition } from 'proj4/dist/lib/core.js';
import { BoundingBox, NamedBounds } from '../bounds.js';
import { Epsg, EpsgCode } from '../epsg.js';
import { Tile, TileMatrixSet } from '../tile.matrix.set.js';
export declare const Projections: Map<number, {
    json?: PROJJSONDefinition;
    converter: proj4.Converter;
}>;
export interface LatLon {
    lat: number;
    lon: number;
}
export declare class Projection {
    static All: Map<EpsgCode, Projection>;
    /** If floating point numbers differ by this amount they are close enough */
    static AllowedFloatingError: number;
    /** EPSG code for the projection other than Epsg.Wgs84 */
    epsg: Epsg;
    /** Transform coordinates to and from Wgs84 */
    private projection;
    /** If the projection was definied with a projjson */
    definition?: PROJJSONDefinition;
    /**
     * Wrapper around TileMatrixSet with utilities for converting Points and Polygons
     */
    private constructor();
    /** Ensure that a transformation in proj4.js is defined */
    static define(epsg: Epsg, def: PROJJSONDefinition): Projection;
    /**
     * Get the Projection instance for a specified code,
     *
     * throws a exception if the code is not recognized
     *
     * @param epsgCode
     */
    static get(epsgCode: Epsg | EpsgCode | TileMatrixSet): Projection;
    /**
     * Try to find a corresponding Projection for a number
     * @param epsgCode
     */
    static tryGet(unk?: Epsg | EpsgCode | TileMatrixSet): Projection | null;
    /**
     * Project the points in a MultiPolygon array to the `targetProjection`.
     *
     * @return if multipoly is not projected return it verbatim otherwise creates a new multi
     * polygon
     */
    projectMultipolygon(multipoly: Position[][][], targetProjection: Projection): Position[][][];
    /**
     * Convert source `[x, y]` coordinates to `[lon, lat]`
     */
    get toWgs84(): (coordinates: Position) => Position;
    /**
     * Convert `[lon, lat]` coordinates to source `[x, y]`
     */
    get fromWgs84(): (coordinates: Position) => Position;
    /**
     * Convert a source Bounds to GeoJSON WGS84 BoundingBox. In particular if the bounds crosses the
     * anti-meridian then the east component will be less than the west component.
     *
     * @param source
     * @returns [west, south, east, north]
     */
    boundsToWgs84BoundingBox(source: BoundingBox): BBox;
    /**
     * Convert a source bounds to a WSG84 GeoJSON Feature
     *
     * @param bounds in source epsg
     * @param properties any properties to include in the feature such as name
     *
     * @returns If `bounds` crosses the antimeridian then and east and west pair of non crossing
     * polygons will be returned; otherwise a single Polygon will be returned.
     */
    boundsToGeoJsonFeature(bounds: BoundingBox, properties?: {}): BBoxFeature;
    /** Convert a tile covering to a GeoJSON FeatureCollection */
    toGeoJson(files: NamedBounds[]): BBoxFeatureCollection;
    /**
     * Find the closest zoom level to `pixelScale` that is at
     * least as good as `pixelScale` or within the error bounds (+- 1e-8)
     *
     * @see Projection.AllowedFloatingError.
     *
     * @param pixelScale A pixel's resolution in metres
     */
    static getTiffResZoom(tms: TileMatrixSet, pixelScale: number): number;
    /** Convert a tile to the wgs84 bounds */
    static tileToWgs84Bbox(tms: TileMatrixSet, tile: Tile): BBox;
    /**
     * return the `lat`, `lon` of a Tile's center
     */
    static tileCenterToLatLon(tms: TileMatrixSet, tile: Tile): LatLon;
    /**
     * Reused from : https://github.com/pelias/api/blob/6a7751f35882698eb885b93635656ec0c2941633/sanitizer/wrap.js
     *
     * Normalize co-ordinates that lie outside of the normal ranges.
     *
     * longitude wrapping simply requires adding +- 360 to the value until it comes in to range.
     * for the latitude values we need to flip the longitude whenever the latitude
     * crosses a pole.
     *
     */
    static wrapLatLon(lat: number, lon: number): LatLon;
    /**
     * Find the number of alignment levels required to render the tile. Min 0
     *
     * @param tile
     * @param gsd the pixel resolution of the source imagery
     */
    static findAlignmentLevels(tms: TileMatrixSet, tile: Tile, gsd: number, blockFactor?: number): number;
    /**
     * Return the expected width in pixels of an image at the tile resolution.
     *
     * @param tile
     * @param targetZoom The desired zoom level for the imagery
     */
    static getImagePixelWidth(tms: TileMatrixSet, tile: Tile, targetZoom: number): number;
}
