import { Feature } from 'geojson';
import { FeatureCollection } from 'geojson';
import { Point } from 'geojson';
import { Polygon } from 'geojson';
import { Position } from 'geojson';

/**
 * Directional selector shared across the codebase.
 */
export declare type BiDirectionKey = "forw" | "bakw";

declare type Centroid = Feature<Point>;

export declare type CentroidBD = {
    [key in BiDirectionKey]?: Centroid;
};

/**
 * Serialized structure generated by MaplatTin and consumed by Transform.
 */
export declare interface Compiled {
    version?: number;
    points: PointSet[];
    tins_points: (number | string)[][][];
    weight_buffer: WeightBufferBD;
    strict_status?: StrictStatus;
    centroid_point: Position[];
    edgeNodes?: PointSet[];
    kinks_points?: Position[];
    yaxisMode?: YaxisMode;
    vertexMode?: VertexMode;
    strictMode?: StrictMode;
    vertices_params: number[][];
    vertices_points: PointSet[];
    edges?: EdgeSet[];
    bounds?: number[][];
    boundsPolygon?: Feature<Polygon>;
    wh?: number[];
    xy?: number[];
}

/**
 * Historical serialization format prior to 2.00703.
 */
export declare interface CompiledLegacy extends Compiled {
    tins?: TinsBD;
    centroid?: CentroidBD;
    kinks?: KinksBD;
    vertices_params: number[][] & VerticesParamsBD;
    edges: EdgeSet[] & EdgeSetLegacy[];
}

/**
 * 三角形の頂点の座標系を反転する
 * @param tri 元の三角形
 * @returns 座標系が反転された三角形
 */
export declare function counterTri(tri: Tri): Tri;

/**
 * エッジの終点を表す型
 * [始点のインデックス, 終点のインデックス]
 */
export declare type Edge = [number, number];

/**
 * エッジセットの型
 * [始点と終点の間の中間点群（地図座標系）,
 *  始点と終点の間の中間点群（変換先座標系）,
 *  始点と終点のインデックスペア]
 */
export declare type EdgeSet = [Position[], Position[], Edge];

/**
 * 古いバージョンのエッジセット型
 * @deprecated 2.00703以降は EdgeSet を使用
 */
export declare type EdgeSetLegacy = {
    illstNodes: Position[];
    mercNodes: Position[];
    startEnd: Edge;
};

export declare const format_version = 2.00703;

declare interface IndexedTins {
    gridNum: number;
    xOrigin: number;
    yOrigin: number;
    xUnit: number;
    yUnit: number;
    gridCache: number[][][];
}

export declare type IndexedTinsBD = {
    [key in BiDirectionKey]?: IndexedTins;
};

declare type Kinks = FeatureCollection<Point>;

export declare type KinksBD = {
    [key in BiDirectionKey]?: Kinks;
};

/**
 * Input data for MapTransform.setMapData().
 */
export declare interface MapData {
    /** Compiled TIN data for the main layer */
    compiled: Compiled;
    /** maxZoom value used to compute _maxxy = 2^maxZoom * 256 */
    maxZoom?: number;
    /** Sub-map layers */
    sub_maps?: SubMapData[];
}

/**
 * MapTransform — 処理2・3・4を担う座標変換クラス
 *
 * - 処理2: submaps 属性を持つ地図で、複数 TIN のうちどれを適用するか判定・選択し座標変換
 * - 処理3: ビューポート ↔ メルカトル5点 変換
 * - 処理4: ビューポート ↔ TIN 適用後メルカトル5点 変換
 *
 * OpenLayers への依存ゼロ。ブラウザ・Node.js 両対応。
 */
export declare class MapTransform {
    private mainTin;
    private subTins;
    private _maxxy;
    /**
     * 地図データ（コンパイル済み TIN + sub_maps）をロードする
     *
     * @param mapData - メイン TIN と sub_maps の情報
     */
    setMapData(mapData: MapData): void;
    /**
     * ピクセル座標 → メルカトル座標（最適レイヤー選択）
     *
     * @param xy - ピクセル座標 [x, y]
     * @returns メルカトル座標、または範囲外の場合は false
     */
    xy2Merc(xy: number[]): number[] | false;
    /**
     * メルカトル座標 → ピクセル座標（最適レイヤー選択）
     *
     * @param merc - メルカトル座標 [x, y]
     * @returns ピクセル座標、または範囲外の場合は false
     */
    merc2Xy(merc: number[]): number[] | false;
    /**
     * ピクセル座標 → メルカトル座標（レイヤーID付き）
     * histmap_tin.ts xy2MercAsync_returnLayer() の同期版
     *
     * @param xy - ピクセル座標 [x, y]
     * @returns [レイヤーインデックス, メルカトル座標] または false
     */
    xy2MercWithLayer(xy: number[]): [number, number[]] | false;
    /**
     * メルカトル座標 → ピクセル座標（複数レイヤー結果）
     * histmap_tin.ts merc2XyAsync_returnLayer() の同期版
     *
     * 現在は MaplatCore の仕様に合わせ、最大2レイヤーまで返す。
     * 3レイヤー以上返したい場合は、下記の .slice(0, 2) および .filter(i < 2) の
     * 上限値を増やすか、引数で上限を指定できるようにすること。
     *
     * @param merc - メルカトル座標 [x, y]
     * @returns 最大2要素の配列。各要素は [レイヤーインデックス, ピクセル座標] または undefined
     */
    merc2XyWithLayer(merc: number[]): ([number, number[]] | undefined)[];
    /**
     * メルカトル5点 → システム座標（複数レイヤー）
     * histmap_tin.ts mercs2SysCoordsAsync_multiLayer() の同期版
     *
     * @param mercs - 5点のメルカトル座標配列（中心＋上下左右）
     * @returns 各レイヤーのシステム座標配列（または undefined）
     */
    mercs2SysCoords(mercs: number[][]): (number[][] | undefined)[];
    /**
     * ビューポート → TIN 適用後メルカトル5点
     * histmap_tin.ts viewpoint2MercsAsync() の同期版
     *
     * @param viewpoint - ビューポート（center, zoom, rotation）
     * @param size - 画面サイズ [width, height]
     * @returns TIN 変換後のメルカトル5点
     */
    viewpoint2Mercs(viewpoint: Viewpoint, size: [number, number]): number[][];
    /**
     * TIN 適用後メルカトル5点 → ビューポート
     * histmap_tin.ts mercs2ViewpointAsync() の同期版
     *
     * @param mercs - TIN 変換後のメルカトル5点
     * @param size - 画面サイズ [width, height]
     * @returns ビューポート（center, zoom, rotation）
     */
    mercs2Viewpoint(mercs: number[][], size: [number, number]): Viewpoint;
    /** zoom2Radius の静的ラッパー */
    static zoom2Radius(size: [number, number], zoom: number): number;
    /** mercViewpoint2Mercs の静的ラッパー */
    static mercViewpoint2Mercs(center: number[], zoom: number, rotation: number, size: [number, number]): number[][];
    /** mercs2MercViewpoint の静的ラッパー */
    static mercs2MercViewpoint(mercs: number[][], size: [number, number]): Viewpoint;
    /** xy2SysCoord の静的ラッパー */
    static xy2SysCoord(xy: number[], maxxy: number): number[];
    /** sysCoord2Xy の静的ラッパー */
    static sysCoord2Xy(sysCoord: number[], maxxy: number): number[];
    private _assertMapData;
    private _assertMaxxy;
    /**
     * レイヤーインデックスに対応する Transform インスタンスを返す（三角網描画などの用途）
     *
     * @param idx - 0 = メイン TIN、1以上 = sub_maps[idx-1]
     * @returns 対応する Transform、または範囲外の場合は null
     */
    getLayerTransform(idx: number): Transform | null;
    /** レイヤー数を返す（メイン + sub 数） */
    get layerCount(): number;
    /**
     * viewpoint 変換に使用する最大ピクセル幅（2^maxZoom × 256）
     * stateToViewpoint / viewpointToState で zoom ↔ scale 変換に使用する
     * zoom = log2(scale × maxxy / 256) の関係
     */
    get maxxy(): number;
    /** priority 降順でソートした [index, tin, isMain] の配列を返す */
    private _getTinsSortedByPriority;
    /** メイン TIN + 全 sub TIN を index 付きで返す */
    private _getAllTinsWithIndex;
    /**
     * 指定レイヤーインデックスで TIN 変換を実行する
     * index 0 → mainTin, index 1..n → subTins[index-1]
     */
    private _transformByIndex;
    /** 内部用 xy2SysCoord（_maxxy を使用） */
    private xy2SysCoordInternal;
}

export declare const MERC_CROSSMATRIX: number[][];

export declare const MERC_MAX = 20037508.342789244;

/**
 * メルカトル5地点情報からメルカトル地図でのサイズ情報（中心座標、ズーム、回転）を得る
 *
 * @param mercs - 中心＋上下左右の5点のメルカトル座標配列
 * @param size - 画面サイズ [width, height]
 * @returns Viewpoint オブジェクト（center, zoom, rotation）
 */
export declare function mercs2MercViewpoint(mercs: number[][], size: [number, number]): Viewpoint;

/**
 * 画面サイズと地図ズームから、メルカトル座標上での5座標を取得する
 *
 * @param center - 中心のメルカトル座標 [x, y]
 * @param zoom - メルカトルズームレベル
 * @param rotation - 回転角（ラジアン）
 * @param size - 画面サイズ [width, height]
 * @returns 中心＋上下左右の5点のメルカトル座標配列
 */
export declare function mercViewpoint2Mercs(center: number[], zoom: number, rotation: number, size: [number, number]): number[][];

/**
 * エッジセットを正規化する
 * 古いバージョンのフォーマットを新しいフォーマットに変換する
 *
 * @param edges エッジセット配列
 * @param version バージョン番号（オプション）
 * @returns 正規化されたエッジセット配列
 */
export declare function normalizeEdges(edges: EdgeSet[] | EdgeSetLegacy[], version?: number): EdgeSet[];

/**
 * Two-way coordinate pair: [source, target].
 */
export declare type PointSet = [Position, Position];

declare type PropertiesTri = {
    [key in PropertyTriKey]: PropertyTri;
};

declare type PropertyTri = {
    geom: Position;
    index: number | string;
};

export declare type PropertyTriKey = "a" | "b" | "c";

/**
 * 与えられた差分行列を回転する
 *
 * @param xys - 回転する座標の配列
 * @param theta - 回転角（ラジアン）
 * @returns 回転後の座標の配列
 */
export declare function rotateMatrix(xys: number[][], theta: number): number[][];

/**
 * 三角形の頂点の順序を修正する
 * 地図外郭の頂点を含む三角形について、頂点の順序を統一する
 * @param tins 三角形群
 * @returns 頂点順序が修正された三角形群
 */
export declare function rotateVerticesTriangle(tins: Tins): Tins;

/**
 * Strictness flags supported during transformation.
 */
export declare type StrictMode = "strict" | "auto" | "loose";

/**
 * Result of strictness evaluation.
 */
export declare type StrictStatus = "strict" | "strict_error" | "loose";

/**
 * Sub-map TIN data for MapTransform.setMapData().
 */
export declare interface SubMapData {
    /** Compiled TIN data */
    compiled: Compiled;
    /** Layer priority (higher = checked first) */
    priority: number;
    /** Layer importance (used when multiple layers overlap) */
    importance: number;
    /** Bounds vertices in pixel (XY) space. Falls back to compiled.bounds if omitted. */
    bounds?: number[][];
}

/**
 * システム座標（EPSG:3857相当）をピクセル座標に変換する
 *
 * @param sysCoord - システム座標 [x, y]
 * @param maxxy - 最大座標値（2^maxZoom * 256）
 * @returns ピクセル座標 [x, y]
 */
export declare function sysCoord2Xy(sysCoord: number[], maxxy: number): number[];

export declare type Tins = FeatureCollection<Polygon, PropertiesTri>;

export declare type TinsBD = {
    [key in BiDirectionKey]?: Tins;
};

/**
 * 座標変換の基本機能を提供するクラス
 *
 * 2つの座標系間の変換を、TINネットワークを使用して実現します。
 * このクラスは基本的な変換機能のみを提供し、
 * 設定ファイルの生成などの追加機能はTinクラスで提供されます。
 */
export declare class Transform {
    /**
     * 各種モードの定数定義
     * すべてreadonlyで、型安全性を確保
     */
    static VERTEX_PLAIN: "plain";
    static VERTEX_BIRDEYE: "birdeye";
    static MODE_STRICT: "strict";
    static MODE_AUTO: "auto";
    static MODE_LOOSE: "loose";
    static STATUS_STRICT: "strict";
    static STATUS_ERROR: "strict_error";
    static STATUS_LOOSE: "loose";
    static YAXIS_FOLLOW: "follow";
    static YAXIS_INVERT: "invert";
    points: PointSet[];
    pointsWeightBuffer?: WeightBufferBD;
    strict_status?: StrictStatus;
    vertices_params?: VerticesParamsBD;
    centroid?: CentroidBD;
    edgeNodes?: PointSet[];
    edges?: EdgeSet[];
    tins?: TinsBD;
    kinks?: KinksBD;
    yaxisMode: YaxisMode;
    strictMode: StrictMode;
    vertexMode?: VertexMode;
    bounds?: number[][];
    boundsPolygon?: Feature<Polygon>;
    wh?: number[];
    xy?: number[];
    indexedTins?: IndexedTinsBD;
    stateFull: boolean;
    stateTriangle?: Tri;
    stateBackward?: boolean;
    /**
     * Optional properties for MaplatCore extension
     * These properties allow consuming applications to extend Transform instances
     * with additional metadata without requiring Module Augmentation
     */
    /** Layer priority for rendering order */
    priority?: number;
    /** Layer importance for display decisions */
    importance?: number;
    /** Bounds in XY (source) coordinate system */
    xyBounds?: Feature<Polygon>;
    /** Bounds in Mercator (Web Mercator) coordinate system */
    mercBounds?: Feature<Polygon>;
    constructor();
    /**
     * コンパイルされた設定を適用します
     *
     * @param compiled - コンパイルされた設定オブジェクト
     * @returns 変換に必要な主要なオブジェクトのセット
     *
     * 以下の処理を行います：
     * 1. バージョンに応じた設定の解釈
     * 2. 各種パラメータの復元
     * 3. TINネットワークの再構築
     * 4. インデックスの作成
     */
    setCompiled(compiled: Compiled | CompiledLegacy): void;
    private applyModernState;
    private applyLegacyState;
    /**
     * TINネットワークのインデックスを作成します
     *
     * インデックスは変換処理を高速化するために使用されます。
     * グリッド形式のインデックスを作成し、各グリッドに
     * 含まれる三角形を記録します。
     */
    addIndexedTin(): void;
    /**
     * 座標変換を実行します
     *
     * @param apoint - 変換する座標
     * @param backward - 逆方向の変換かどうか
     * @param ignoreBounds - 境界チェックを無視するかどうか
     * @returns 変換後の座標、または境界外の場合はfalse
     *
     * @throws {Error} 逆方向変換が許可されていない状態での逆変換時
     */
    transform(apoint: number[], backward?: boolean, ignoreBounds?: boolean): number[] | false;
}

/**
 * 点の座標を変換する
 * 点が三角形の内部にある場合は三角形による変換を、
 * 外部にある場合は頂点パラメータによる変換を行う
 * @param point 変換する点
 * @param tins 三角形群
 * @param indexedTins インデックス付き三角形群（オプション）
 * @param verticesParams 頂点パラメータ（オプション）
 * @param centroid 重心点（オプション）
 * @param weightBuffer 重み付けバッファ（オプション）
 * @param stateTriangle 状態三角形（オプション）
 * @param stateSetFunc 状態設定関数（オプション）
 * @returns 変換後の座標
 */
export declare function transformArr(point: Feature<Point>, tins: Tins, indexedTins?: IndexedTins, verticesParams?: VerticesParams, centroid?: Feature<Point>, weightBuffer?: WeightBuffer, stateTriangle?: Tri, stateSetFunc?: (tri?: Tri) => void): Position;

export declare type Tri = Feature<Polygon, PropertiesTri>;

/**
 * Vertex interpolation modes.
 */
export declare type VertexMode = "plain" | "birdeye";

declare type VerticesParams = [number[], Tins[]?];

export declare type VerticesParamsBD = {
    [key in BiDirectionKey]?: VerticesParams;
};

/**
 * Viewport representation: center in mercator, zoom level, rotation in radians.
 */
export declare interface Viewpoint {
    /** Mercator coordinate [x, y] */
    center: number[];
    /** Mercator zoom level */
    zoom: number;
    /** Rotation angle in radians */
    rotation: number;
}

declare type WeightBuffer = {
    [index: string]: number;
};

/**
 * Weight buffers indexed by node id for both directions.
 */
export declare type WeightBufferBD = {
    [key in BiDirectionKey]?: WeightBuffer;
};

/**
 * ピクセル座標をシステム座標（EPSG:3857相当）に変換する
 *
 * @param xy - ピクセル座標 [x, y]
 * @param maxxy - 最大座標値（2^maxZoom * 256）
 * @returns システム座標 [x, y]
 */
export declare function xy2SysCoord(xy: number[], maxxy: number): number[];

/**
 * Y-axis handling directive.
 */
export declare type YaxisMode = "follow" | "invert";

/**
 * size（画面サイズ）とズームから、地図面座標上での半径を得る
 *
 * @param size - 画面サイズ [width, height]
 * @param zoom - メルカトルズームレベル
 * @returns メルカトル座標上での半径
 */
export declare function zoom2Radius(size: [number, number], zoom: number): number;

export { }
