Jinuss's blog Jinuss's blog
首页
  • 前端文章

    • JavaScript
  • 学习笔记

    • 《JavaScript高级程序设计》
    • 《Vue》
    • 《React》
    • 《Git》
    • JS设计模式总结
  • HTML
  • CSS
  • 技术文档
  • GitHub技巧
  • 学习
  • 实用技巧
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

东流

前端可视化
首页
  • 前端文章

    • JavaScript
  • 学习笔记

    • 《JavaScript高级程序设计》
    • 《Vue》
    • 《React》
    • 《Git》
    • JS设计模式总结
  • HTML
  • CSS
  • 技术文档
  • GitHub技巧
  • 学习
  • 实用技巧
关于
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 框架

  • core模块

  • dom模块

  • control

  • geometry

  • geo

    • crs

    • projection

      • Projection.LonLat
      • Projection.Mercator
        • 概述
        • 源码分析
          • 源码实现
          • 关键特性
          • 注意事项 ​​
        • 总结
      • Projection.SphericalMercator
    • LatLng
    • LatLngBounds
  • layer

  • Map

  • 《Leaflet源码》笔记
  • geo
  • projection
东流
2025-04-10
目录

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); // 转为度数
  },
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

# 关键特性

  • 椭球体修正​​:相比球形墨卡托(如 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 标准的高精度投影支持,适用于专业地理信息系统。

编辑 (opens new window)
上次更新: 2025/04/18, 09:09:53
Projection.LonLat
Projection.SphericalMercator

← Projection.LonLat Projection.SphericalMercator→

最近更新
01
GeoJSON
05-08
02
Circle
04-15
03
CircleMarker
04-15
更多文章>
Theme by Vdoing | Copyright © 2024-2025 东流 | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式