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

      • CRS
        • 概述
        • 源码分析
          • 源码实现
          • 源码解析
          • CRS核心组成
          • 关键方法解析
          • 坐标转换(Transformation)
          • 应用实例:CRS.EPSG38557
        • 总结
      • CRS.Earth
      • CRS.EPSG3395
      • CRS.EPSG3857
      • CRS.EPSG4326
      • CRS.Simple
    • projection

    • LatLng
    • LatLngBounds
  • layer

  • Map

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

CRS

# 概述

CRS 是 Coordinate Reference System 的缩写,即坐标参考系统

Leaflet 中CRS 是一个对象,它包含了一些方法,定义了地图坐标地理坐标之间的转换规则,如将经纬度坐标转换为像素坐标,以及将像素坐标转换为经纬度坐标,是地图渲染和交互的核心。

# 源码分析

# 源码实现

CRS的源码实现如下:

export var CRS = {
  latlngToPoint: function (latlng, zoom) {
    var projectedPoint = this.projection.project(latlng), // 经纬度 -> 平面坐标
      scale = this.scale(zoom); // 当前缩放比例

    return this.transformation._transform(projectedPoint, scale); // 应用变换
  },
  pointToLatLng: function (point, zoom) {
    var scale = this.scale(zoom),
      untransformedPoint = this.transformation.untransform(point, scale);

    return this.projection.unproject(untransformedPoint);
  },
  project: function (latlng) {
    return this.projection.project(latlng);
  },
  unproject: function (point) {
    return this.projection.unproject(point);
  },
  scale: function (zoom) {
    return 256 * Math.pow(2, zoom);
  },
  zoom: function (scale) {
    return Math.log(scale / 256) / Math.LN2;
  },
  getProjectedBounds: function (zoom) {
    if (this.infinite) {
      return null;
    }

    var b = this.projection.bounds,
      s = this.scale(zoom),
      min = this.transformation.transform(b.min, s),
      max = this.transformation.transform(b.max, s);

    return new Bounds(min, max);
  },
  infinite: false,
  wrapLatLng: function (latlng) {
    var lng = this.wrapLng
        ? Util.wrapNum(latlng.lng, this.wrapLng, true)
        : latlng.lng,
      lat = this.wrapLat
        ? Util.wrapNum(latlng.lat, this.wrapLat, true)
        : latlng.lat,
      alt = latlng.alt;

    return new LatLng(lat, lng, alt);
  },
  wrapLatLngBounds: function (bounds) {
    var center = bounds.getCenter(),
      newCenter = this.wrapLatLng(center),
      latShift = center.lat - newCenter.lat,
      lngShift = center.lng - newCenter.lng;

    if (latShift === 0 && lngShift === 0) {
      return bounds;
    }

    var sw = bounds.getSouthWest(),
      ne = bounds.getNorthEast(),
      newSw = new LatLng(sw.lat - latShift, sw.lng - lngShift),
      newNe = new LatLng(ne.lat - latShift, ne.lng - lngShift);

    return new LatLngBounds(newSw, newNe);
  },
};
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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67

# 源码解析

# CRS核心组成

CRS通过整合**投影(Projection)和坐标变换(Transformation)**实现坐标转换:

  • projection:投影对象(如L.Projection.SphericalMercator),负责经纬度 <--> 平面坐标的转换
  • transformation:变换矩阵,处理平面坐标 <--> 地图容器像素坐标的平移和缩放
  • infinite:标识地图是否无线延申(如全球地图可横向循环)
  • wrapLng/wrapLat:经度/纬度的循环范围(如[-180, 180])

# 关键方法解析

  1. latlngToPoint(latlng,zoom)

作用:将地理坐标(经纬度)转换为当前缩放级别下的地图容器像素坐标 流程:

  • 投影:projection.project(latlng) -> 平面坐标(米)
  • 缩放:计算当前缩放比例 scale = 256 * Math.pow(2, zoom)
  • 变换:应用transformation调整坐标原点和缩放
  1. pointToLatLng(point,zoom)

作用:将地图容器像素坐标转换为地理坐标(经纬度) 流程:

  • 逆变换:transformation.untransform(point, scale) -> 平面坐标
  • 投影:projection.unproject(projectedPoint) -> 经纬度
  1. scale(zoom)与zoom(scale)

作用:计算缩放级别与比例因子的转换关系 公式:

  • scale:256 * Math.pow(2, zoom)(标准瓦片尺寸为256 X 256,每级缩放翻倍)
  • zoom:Math.log(scale / 256) / Math.LN2
  1. getProjectedBounds(zoom)

作用:获取当前缩放级别下投影后的地图平面坐标范围 流程:

  • 获取投影的原始边界projection.bounds
  • 应用变换矩阵得到地图容器坐标范围
  1. wrapLatLng(latlng)与wrapLatLngBounds(bounds)

作用:调整经纬度到合理范围(如经度循环) 示例:

  • 经度 190° -> 调整 -170°
  • 纬度 91° -> 调整 85.0511287798°(若投影支持)

# 坐标转换(Transformation)

作用:处理地图平面坐标到容器像素坐标的线性变换 通常用于:

  • 平移原点:如将平面坐标原点(0,0)移到地图容器中心
  • 缩放适配:根据瓦片尺寸调整比例

# 应用实例:CRS.EPSG38557

Leaflet 默认使用CRS.EPSG3857,即球面墨卡托投影,适合全球地图显示,其配置如下:

  • 投影:L.Projection.SphericalMercator(Web Mercator)
  • 变换: 原点在左上角,缩放适配瓦片坐标
  • 循环经度:wrapLng: [-180, 180]

地图坐标转换流程:

  • 投影:经纬度 -> 平面坐标(米)
  • 变换矩阵:缩放 -> 像素坐标;平移 -> 容器像素坐标

# 总结

CRS是 Leaflet 中处理地理坐标与地图容器像素坐标转换的核心,通过整合投影和坐标变换,实现了经纬度 <--> 像素坐标的转换。

编辑 (opens new window)
上次更新: 2025/04/21, 05:18:23
PolyUtil
CRS.Earth

← PolyUtil CRS.Earth→

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