源码分析之Leaflet中投影类型Projection.Mercator

概述

Projection.Mercator 实现了 ​​ 椭球体墨卡托投影Ellipsoidal Mercator Projection)​​,将地理坐标(经纬度)映射为平面坐标,对应EPSG:3395坐标系。

源码分析

源码实现

Projection.Mercator的源码实现如下:

export var Mercator = {
  // 椭球参数
  R: 6378137, // 地球长半轴(赤道半径)`6378137`米 ,参考WGS84标准
  R_MINOR: 6356752.314245179, // 地球短半轴(极半径)`6356752.314245179`米,参考WGS84标准
  // 边界定义:定义投影的有效经纬度范围,单位:米,
  bounds: new Bounds(
    [-20037508.34279, -15496570.73972],
    [20037508.34279, 18764656.23138]
  ),
  // 正向投影:将地理坐标(经度、纬度)转换为平面坐标(米)
  project: function (latlng) {
    var d = Math.PI / 180,
      r = this.R,
      y = latlng.lat * d,
      tmp = this.R_MINOR / r,
      e = Math.sqrt(1 - tmp * tmp), // 计算椭球的偏心率
      con = e * Math.sin(y);

    var ts =
      Math.tan(Math.PI / 4 - y / 2) / Math.pow((1 - con) / (1 + con), e / 2);
    y = -r * Math.log(Math.max(ts, 1e-10)); // 使用等角投影公式计算纬度,避免球形假设导致的误差

    var x = latlng.lng * d * r; //线性映射计算经度
    return new Point(x, y);
  },
  // 反向投影:将平面坐标(米)转换为地理坐标(经度、纬度)
  unproject: function (point) {
    var d = 180 / Math.PI, // 弧度转度因子
      r = this.R,
      tmp = this.R_MINOR / r,
      e = Math.sqrt(1 - tmp * tmp), // 偏心率
      ts = Math.exp(-point.y / r), // 初始化ts值
      phi = Math.PI / 2 - 2 * Math.atan(ts); // 初始纬度计算

    for (var i = 0, dphi = 0.1, con; i < 15 && Math.abs(dphi) > 1e-7; i++) {
      con = e * Math.sin(phi);
      con = Math.pow((1 - con) / (1 + con), e / 2); // 修正
      dphi = Math.PI / 2 - 2 * Math.atan(ts * con) - phi; //误差计算
      phi += dphi; //迭代修正
    }

    return new LatLng(phi * d, (point.x * d) / r); // 转为度数
  },
};

关键特性

  • 椭球体修正​​:相比球形墨卡托(如 Web Mercator EPSG:3857),此投影更精确,考虑地球扁率。
  • 适用场景 ​​:
    • 需要高精度的大范围地图(如航海、航空)。
    • 使用 EPSG:3395 的旧系统(现多被 Web Mercator 取代)。
  • 性能 ​​:因纬度迭代计算,性能略低于球形投影。

注意事项 ​​

  1. 数值稳定性 ​​:
  • 正向投影中 Math.max(ts, 1E-10) 防止极区计算错误。
  • 迭代次数(15 次)和误差容限(1e-7)平衡精度与性能。
    ​​
  1. 范围限制 ​​:
  • 纬度有效范围约 ±85°(超过后投影变形急剧增大)。
  1. 坐标轴方向 ​​:
  • X 轴正方向为东,Y 轴正方向为北(与屏幕坐标系相反)。

总结

通过L.Projection.Mercator,Leaflet 提供了符合 EPSG:3395 标准的高精度投影支持,适用于专业地理信息系统。

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jinuss

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值