地图工具类:地图坐标系转换、获取点位经纬度信息

transform.js

function transformLat(x, y) {
  let ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * Math.sqrt(Math.abs(x));
  ret += ((20.0 * Math.sin(6.0 * x * Math.PI) + 20.0 * Math.sin(2.0 * x * Math.PI)) * 2.0) / 3.0;
  ret += ((20.0 * Math.sin(y * Math.PI) + 40.0 * Math.sin((y / 3.0) * Math.PI)) * 2.0) / 3.0;
  ret += ((160.0 * Math.sin((y / 12.0) * Math.PI) + 320 * Math.sin((y * Math.PI) / 30.0)) * 2.0) / 3.0;
  return ret;
}

function transformLng(x, y) {
  let ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Math.sqrt(Math.abs(x));
  ret += ((20.0 * Math.sin(6.0 * x * Math.PI) + 20.0 * Math.sin(2.0 * x * Math.PI)) * 2.0) / 3.0;
  ret += ((20.0 * Math.sin(x * Math.PI) + 40.0 * Math.sin((x / 3.0) * Math.PI)) * 2.0) / 3.0;
  ret += ((150.0 * Math.sin((x / 12.0) * Math.PI) + 300.0 * Math.sin((x / 30.0) * Math.PI)) * 2.0) / 3.0;
  return ret;
}

export function wgs84ToGcj02(lng, lat) {
  if (outOfChina(lng, lat)) {
    return [lng, lat];
  }
  let dLat = transformLat(lng - 105.0, lat - 35.0);
  let dLng = transformLng(lng - 105.0, lat - 35.0);
  const radLat = (lat / 180.0) * Math.PI;
  let magic = Math.sin(radLat);
  magic = 1 - 0.00669342162296594323 * magic * magic;
  const sqrtMagic = Math.sqrt(magic);
  dLat = (dLat * 180.0) / (((6378245 * (1 - 0.00669342162296594323)) / (magic * sqrtMagic)) * Math.PI);
  dLng = (dLng * 180.0) / ((6378245 / sqrtMagic) * Math.cos(radLat) * Math.PI);
  const mgLat = lat + dLat;
  const mgLng = lng + dLng;
  return [mgLng, mgLat];
}

export function gcj02ToWgs84(lng, lat) {
  if (outOfChina(lng, lat)) {
    return [lng, lat];
  }
  let dLat = transformLat(lng - 105.0, lat - 35.0);
  let dLng = transformLng(lng - 105.0, lat - 35.0);
  const radLat = (lat / 180.0) * Math.PI;
  let magic = Math.sin(radLat);
  magic = 1 - 0.00669342162296594323 * magic * magic;
  const sqrtMagic = Math.sqrt(magic);
  dLat = (dLat * 180.0) / (((6378245 * (1 - 0.00669342162296594323)) / (magic * sqrtMagic)) * Math.PI);
  dLng = (dLng * 180.0) / ((6378245 / sqrtMagic) * Math.cos(radLat) * Math.PI);
  const mgLat = lat - dLat;
  const mgLng = lng - dLng;
  return [mgLng, mgLat];
}

function outOfChina(lng, lat) {
  return !(lng > 72.004 && lng < 137.8347 && lat > 0.8293 && lat < 55.8271);
}

/* 递归处理数组:WGS84 转 GCJ02 */
export function deepWgs84ToGcj02(arr) {
  return arr.map((item) => {
    if (Array.isArray(item)) {
      if (item.length === 2) {
        // 处理长度为2的数组 [lng, lat]
        const [lng, lat] = wgs84ToGcj02(item[0], item[1]);
        return [lng, lat];
      } else {
        // 递归处理其他数组
        return deepWgs84ToGcj02(item);
      }
    } else if (typeof item === 'object' && item !== null && 'lng' in item && 'lat' in item) {
      // 处理对象 { lng, lat }
      const [lng, lat] = wgs84ToGcj02(item.lng, item.lat);
      return { ...item, lng, lat };
    } else if (typeof item === 'object' && item !== null && Array.isArray(item.coordinates)) {
      // 处理包含 coordinates 属性的对象
      return { ...item, coordinates: deepWgs84ToGcj02(item.coordinates) };
    }
    return item;
  });
}

/* 递归处理数组:GCJ02 转 WGS84 */
export function deepGcj02ToWgs84(arr) {
  return arr.map((item) => {
    if (Array.isArray(item)) {
      if (item.length === 2) {
        // 处理长度为2的数组 [lng, lat]
        const [lng, lat] = gcj02ToWgs84(item[0], item[1]);
        return [lng, lat];
      } else {
        // 递归处理其他数组
        return deepGcj02ToWgs84(item);
      }
    } else if (typeof item === 'object' && item !== null && 'lng' in item && 'lat' in item) {
      // 处理对象 { lng, lat }
      const [lng, lat] = gcj02ToWgs84(item.lng, item.lat);
      return { ...item, lng, lat };
    } else if (typeof item === 'object' && item !== null && Array.isArray(item.coordinates)) {
      // 处理包含 coordinates 属性的对象
      return { ...item, coordinates: deepGcj02ToWgs84(item.coordinates) };
    }
    return item;
  });
}

/* 获取经纬度 */
export const getLngLatOfPoint = (item) => {
  if (Array.isArray(item) && item.length === 2) return item;

  if (typeof item === 'object' && item !== null && 'lng' in item && 'lat' in item) {
    return [item.lng, item.lat];
  }

  if (typeof item === 'object' && item !== null && Array.isArray(item.coordinates)) {
    return getLngLatOfPoint(item.coordinates);
  }
};

作者:yiping5

出处:https://www.cnblogs.com/yiping5/p/18558893

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   Ping5-1  阅读(23)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· AI与.NET技术实操系列(六):基于图像分类模型对图像进行分类
more_horiz
keyboard_arrow_up dark_mode palette
选择主题
点击右上角即可分享
微信分享提示