var sin = Math.sin, cos = Math.cos, sqrt = Math.sqrt, abs = Math.abs, PI = Math.PI;
var a = 6378245;
var ee = 0.006693421622965823;
export function GCJ02ToWGS84(coord) {
    var lon = coord[0], lat = coord[1];
    if (!isInChinaBbox(lon, lat))
        return [lon, lat];
    var _a = [lon, lat], wgsLon = _a[0], wgsLat = _a[1];
    var tempPoint = WGS84ToGCJ02([wgsLon, wgsLat]);
    var dx = tempPoint[0] - lon;
    var dy = tempPoint[1] - lat;
    while (abs(dx) > 1e-6 || abs(dy) > 1e-6) {
        wgsLon -= dx;
        wgsLat -= dy;
        tempPoint = WGS84ToGCJ02([wgsLon, wgsLat]);
        dx = tempPoint[0] - lon;
        dy = tempPoint[1] - lat;
    }
    return [wgsLon, wgsLat];
}
export function WGS84ToGCJ02(coord) {
    var lon = coord[0], lat = coord[1];
    if (!isInChinaBbox(lon, lat))
        return [lon, lat];
    var d = delta(lon, lat);
    return [lon + d[0], lat + d[1]];
}
function transformLat(x, y) {
    var ret = -100 + 2 * x + 3 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * sqrt(abs(x));
    ret += (20 * sin(6 * x * PI) + 20 * sin(2 * x * PI)) * 2 / 3;
    ret += (20 * sin(y * PI) + 40 * sin(y / 3 * PI)) * 2 / 3;
    ret += (160 * sin(y / 12 * PI) + 320 * sin(y * PI / 30)) * 2 / 3;
    return ret;
}
function transformLon(x, y) {
    var ret = 300 + x + 2 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * sqrt(abs(x));
    ret += (20 * sin(6 * x * PI) + 20 * sin(2 * x * PI)) * 2 / 3;
    ret += (20 * sin(x * PI) + 40 * sin(x / 3 * PI)) * 2 / 3;
    ret += (150 * sin(x / 12 * PI) + 300 * sin(x / 30 * PI)) * 2 / 3;
    return ret;
}
function delta(lon, lat) {
    var dLon = transformLon(lon - 105, lat - 35);
    var dLat = transformLat(lon - 105, lat - 35);
    var radLat = lat / 180 * PI;
    var magic = sin(radLat);
    magic = 1 - ee * magic * magic;
    var sqrtMagic = sqrt(magic);
    dLon = (dLon * 180) / (a / sqrtMagic * cos(radLat) * PI);
    dLat = (dLat * 180) / ((a * (1 - ee)) / (magic * sqrtMagic) * PI);
    return [dLon, dLat];
}
// roughly check whether coordinates are in China.
function isInChinaBbox(lon, lat) {
    return lon >= 72.004 && lon <= 137.8347 && lat >= 0.8293 && lat <= 55.8271;
}
