写点什么

JSAPIThree 地图投影学习笔记:理解坐标系统

作者:map_3d_vis
  • 2025-11-24
    北京
  • 本文字数:5084 字

    阅读完需:约 17 分钟

作为一个刚开始学习 mapvthree 的小白,今天要学习地图投影了!听说这个系统可以控制地图的坐标系统,不同的投影方式有不同的效果!想想就好奇!

第一次听说地图投影

今天在文档里看到了"投影"这个词,一开始我还以为是投影仪那种投影,结果查了一下才知道,原来这是地图学里的概念!


文档说地图投影是:


  • 将地球表面的地理坐标(经纬度)转换为平面坐标的数学方法

  • 不同的投影方式适合不同的应用场景

  • 选择合适的投影对准确展示地理数据很重要


我的理解:简单说就是把地球这个球面"展开"成平面的方法!就像把橘子皮剥下来摊平一样,不同的剥法会有不同的效果!

第一步:为什么需要投影?

作为一个初学者,我一开始很困惑:为什么需要投影?直接用经纬度不行吗?


我的疑问:经纬度不是已经很准确了吗?为什么还要转换?


看了文档才知道:


  • 经纬度是球面坐标,不能直接在平面上显示

  • 不同的投影方式有不同的特点(有的保持角度,有的保持面积)

  • 选择合适的投影可以让地图更准确、更美观


我的理解:就像拍照一样,不同的角度拍出来的效果不一样,投影就是选择"拍照角度"!

第二步:发现引擎支持的投影类型

文档说 mapvthree 支持多种投影方式,我数了数,主要有这几种:

投影 1:Web 墨卡托投影(EPSG:3857)

const engine = new mapvthree.Engine(container, {    map: {        projection: 'EPSG:3857', // Web 墨卡托投影(默认)    },});
复制代码


我的理解:这是最常用的网络地图投影,也是引擎的默认投影。


我的发现


  • 适合低纬度地区(赤道附近)

  • 高纬度地区会有严重变形

  • 大多数在线地图都用这个投影


我的想法:如果做普通的网络地图,用这个投影就够了!

投影 2:ECEF 投影(EPSG:4978)

const engine = new mapvthree.Engine(container, {    map: {        projection: 'EPSG:4978', // ECEF 投影(3D 地球)    },});
复制代码


我的理解:ECEF 是地心地固坐标系,是一个三维直角坐标系统。


我的发现


  • 能准确表达地球形状

  • 所有区域几乎无形变

  • 适合精确的三维空间定位和计算

  • 是三维数据可视化的理想投影


我的想法:如果做 3D 地球效果,应该用这个投影!


我的尝试


import * as mapvthree from '@baidumap/mapv-three';
const container = document.getElementById('container');
const engine = new mapvthree.Engine(container, { map: { projection: 'EPSG:4978', // 3D 地球模式 center: [0, 0], range: 30000000, // 很远的距离,能看到整个地球 },});
复制代码


我的发现:地图变成了一个球体!可以旋转看整个地球,太酷了!


我的感受:这个投影真的很适合做 3D 地球效果!

投影 3:WGS84 地理坐标系(EPSG:4326)

const engine = new mapvthree.Engine(container, {    map: {        projection: 'EPSG:4326', // WGS84 地理坐标系    },});
复制代码


我的理解:WGS84 是最常用的地理坐标系统,使用经纬度表示位置。


我的发现


  • 全球统一的标准

  • 跨应用数据兼容性最好

  • 经纬度数据需要投影转换才能在平面地图上显示


我的想法:如果数据是经纬度格式,用这个投影比较方便!

投影 4:UTM 投影

const engine = new mapvthree.Engine(container, {    map: {        projection: 'EPSG:32633', // UTM 33N 带    },});
复制代码


我的理解:UTM 投影将地球分为 60 个等分带,每个带覆盖 6 度经度。


我的发现


  • 能够保持较好的距离和面积比例

  • 适合局部区域的地图

  • 高纬度地区变形较大


我的想法:如果做局部区域的地图,可以考虑用 UTM 投影!

投影 5:高斯克吕格投影

const engine = new mapvthree.Engine(container, {    map: {        projection: 'EPSG:4491', // 高斯克吕格六度带投影    },});
复制代码


我的理解:高斯克吕格投影是一种等角投影,角度保持不变,适合进行测量和制图。


我的发现


  • 分为六度带和三度带投影

  • 分为标准投影和截取投影

  • 适合中国地区的地图


我的想法:如果做中国地区的地图,可以考虑用这个投影!

投影 6:EqualEarth 投影(EPSG:8857)

const engine = new mapvthree.Engine(container, {    map: {        projection: 'EPSG:8857', // EqualEarth 投影    },});
复制代码


我的理解:EqualEarth 投影是一种等面积投影,面积保持不变。


我的发现


  • 适合进行面积计算和制图

  • 面积比例准确


我的想法:如果要做面积相关的计算,可以用这个投影!

第三步:如何设置投影

看到这么多投影类型后,我开始好奇:怎么设置投影?


文档说目标投影只能在引擎初始化时设置,之后不能修改!


const engine = new mapvthree.Engine(container, {    map: {        projection: 'EPSG:4978', // 设置目标投影    },});
复制代码


我的理解:投影必须在创建引擎时设置,创建后不能改。


我的尝试


import * as mapvthree from '@baidumap/mapv-three';
const container = document.getElementById('container');
// 设置为 3D 地球模式const engine = new mapvthree.Engine(container, { map: { projection: 'EPSG:4978', // ECEF 投影 center: [0, 0], range: 30000000, },});
复制代码


我的发现:设置后,地图的显示方式完全变了!


我的注意:投影设置后不能修改,所以要在初始化时就确定好!

第四步:理解投影的作用

看到可以设置投影后,我想:不同的投影会有什么不同的效果?


我试了几个不同的投影:


// Web 墨卡托投影(默认)const engine1 = new mapvthree.Engine(container1, {    map: {        projection: 'EPSG:3857',        center: [0, 0],        range: 10000000,    },});
// ECEF 投影(3D 地球)const engine2 = new mapvthree.Engine(container2, { map: { projection: 'EPSG:4978', center: [0, 0], range: 30000000, },});
复制代码


我的发现


  • EPSG:3857:平面地图,像普通的地图

  • EPSG:4978:球体地图,像真实的地球


我的感受:不同的投影真的有完全不同的视觉效果!


我的理解:投影决定了地图的"形状",选择合适的投影很重要!

第五步:数据源的投影设置

看到可以设置目标投影后,我想:如果我的数据不是经纬度,怎么办?


文档说数据源可以设置自己的投影!

GeoJSON 数据源

对于 GeoJSON 数据,可以在数据中声明 crs 信息:


const geojson = {    type: 'FeatureCollection',    crs: {        type: 'name',        properties: {            name: 'EPSG:3857', // 声明数据源的投影        },    },    features: [        // ... 数据    ],};
const dataSource = mapvthree.GeoJSONDataSource.fromGeoJSON(geojson);
复制代码


我的理解:在 GeoJSON 中声明 crs,引擎会自动识别并转换。


我的发现:引擎会自动将数据源的投影转换为目标投影!


我的想法:这样就不用手动转换坐标了,引擎会自动处理!

DataItem 的投影设置

文档说 DataItem 也支持在属性字段设置 crs 信息。


我的理解:每个数据项都可以有自己的投影设置。


我的发现:这样就能处理混合投影的数据了!

第六步:底图的投影处理

看到数据源的投影后,我想:底图的投影怎么处理?


文档说底图的投影由 TileProvider 处理,大部分 TileProvider 内部都能自动处理投影转换!


const engine = new mapvthree.Engine(container, {    map: {        projection: 'EPSG:4978', // 目标投影是 ECEF        provider: new mapvthree.BaiduVectorTileProvider(), // 底图 Provider    },});
复制代码


我的理解TileProvider 会自动处理底图的投影转换。


我的发现:不需要手动设置底图的投影,Provider 会自动处理!


我的想法:这样就很方便了,不用关心底图的投影问题!

第七步:实际应用场景

学到这里,我开始想:不同的投影适合什么场景?

场景 1:普通网络地图

如果做普通的网络地图,用 Web 墨卡托投影:


const engine = new mapvthree.Engine(container, {    map: {        projection: 'EPSG:3857', // Web 墨卡托投影(默认)    },});
复制代码


我的想法:这是最常用的投影,适合大多数场景!

场景 2:3D 地球效果

如果做 3D 地球效果,用 ECEF 投影:


const engine = new mapvthree.Engine(container, {    map: {        projection: 'EPSG:4978', // ECEF 投影        center: [0, 0],        range: 30000000,    },});
复制代码


我的想法:这个投影最适合做 3D 地球,效果最真实!

场景 3:精确计算

如果要做精确的空间计算,用 ECEF 投影:


const engine = new mapvthree.Engine(container, {    map: {        projection: 'EPSG:4978', // ECEF 投影,精度高    },});
复制代码


我的想法:ECEF 投影精度最高,适合做精确计算!

场景 4:面积计算

如果要做面积计算,用 EqualEarth 投影:


const engine = new mapvthree.Engine(container, {    map: {        projection: 'EPSG:8857', // EqualEarth 投影    },});
复制代码


我的想法:这个投影面积比例准确,适合做面积相关的计算!

第八步:做一个完整的示例

我想写一个完整的示例,展示不同投影的效果:


import * as mapvthree from '@baidumap/mapv-three';
// 创建多个容器展示不同投影const container1 = document.getElementById('container1');const container2 = document.getElementById('container2');
// Web 墨卡托投影(平面地图)const engine1 = new mapvthree.Engine(container1, { map: { projection: 'EPSG:3857', center: [116.404, 39.915], range: 10000, },});
// ECEF 投影(3D 地球)const engine2 = new mapvthree.Engine(container2, { map: { projection: 'EPSG:4978', center: [116.404, 39.915], range: 1000000, },});
// 添加一些测试点const points = [ [116.404, 39.915], // 北京 [121.473, 31.230], // 上海 [113.264, 23.129], // 广州];
const geojson = { type: 'FeatureCollection', features: points.map(coord => ({ type: 'Feature', properties: {}, geometry: { type: 'Point', coordinates: coord, }, })),};
const dataSource = mapvthree.GeoJSONDataSource.fromGeoJSON(geojson);
// 在两个引擎中都添加点const point1 = engine1.add(new mapvthree.SimplePoint({ size: 20 }));point1.dataSource = dataSource;
const point2 = engine2.add(new mapvthree.SimplePoint({ size: 20 }));point2.dataSource = dataSource;
复制代码


我的感受:写一个完整的示例,对比不同投影的效果,感觉很有成就感!


我的发现


  • 不同的投影有不同的视觉效果

  • 数据会自动转换到目标投影

  • 选择合适的投影很重要


虽然代码还很简单,但是已经能展示不同投影的效果了!

第九步:踩过的坑

作为一个初学者,我踩了不少坑,记录下来避免再犯:

坑 1:投影设置后不能修改

原因:不知道投影只能在初始化时设置。


解决:在创建引擎时就确定好投影方式,之后不能修改。

坑 2:数据投影设置错误

原因:数据源的投影设置错误,导致显示位置不对。


解决:确保数据源的投影设置正确,或者在 GeoJSON 中正确声明 crs

坑 3:选择了不合适的投影

原因:不了解不同投影的特点,选择了不合适的投影。


解决:根据应用场景选择合适的投影:


  • 普通地图:EPSG:3857

  • 3D 地球:EPSG:4978

  • 面积计算:EPSG:8857

坑 4:高纬度地区变形严重

原因:使用 Web 墨卡托投影显示高纬度地区。


解决:高纬度地区建议使用 ECEF 投影或其他适合的投影。

坑 5:坐标转换问题

原因:数据投影和目标投影不一致,但没有正确设置。


解决:确保数据源的投影设置正确,引擎会自动转换。

我的学习总结

经过这一天的学习,我掌握了:


  1. 地图投影的作用:将地球表面的地理坐标转换为平面坐标

  2. 引擎支持的投影类型

  3. Web 墨卡托投影(EPSG:3857)- 默认,适合普通地图

  4. ECEF 投影(EPSG:4978)- 适合 3D 地球和精确计算

  5. WGS84 地理坐标系(EPSG:4326)- 经纬度格式

  6. UTM 投影 - 适合局部区域

  7. 高斯克吕格投影 - 适合中国地区

  8. EqualEarth 投影(EPSG:8857)- 适合面积计算

  9. 如何设置投影:在引擎初始化时通过 map.projection 设置

  10. 数据源的投影:可以在 GeoJSON 中声明 crs,引擎会自动转换

  11. 底图的投影:由 TileProvider 自动处理


我的感受:地图投影虽然概念有点抽象,但是用起来其实不难。关键是要理解不同投影的特点,然后根据应用场景选择合适的投影!


下一步计划


  1. 深入学习不同投影的数学原理

  2. 尝试在不同投影下做数据可视化

  3. 做一个完整的投影对比项目




学习笔记就到这里啦!作为一个初学者,我觉得地图投影虽然概念有点抽象,但是用起来其实不难。关键是要理解不同投影的特点,然后根据应用场景选择合适的投影!希望我的笔记能帮到其他初学者!大家一起加油!

用户头像

map_3d_vis

关注

还未添加个人签名 2025-11-17 加入

还未添加个人简介

评论

发布
暂无评论
JSAPIThree 地图投影学习笔记:理解坐标系统_初学者_map_3d_vis_InfoQ写作社区