当前位置: 首页 > news >正文

【经纬度坐标系、墨卡托投影坐标系和屏幕坐标系转换详解】

地图坐标系转换详解

  • 1. 引言
  • 2. 坐标系定义
    • 2.1 经纬度坐标系
    • 2.2 墨卡托投影坐标系
    • 3.3 屏幕坐标系
  • 2. 坐标系间的转换
    • 2.1 经纬度坐标系到墨卡托投影坐标系
    • 2.2 墨卡托投影坐标系到经纬度坐标系
    • 2.3 墨卡托投影坐标系到屏幕坐标系
    • 2.4 屏幕坐标系到墨卡托投影坐标系
    • 2.5 经纬度坐标系到屏幕坐标系
    • 2.6 屏幕坐标系到经纬度坐标系
  • 3. 示例代码
  • 4. 结语

1. 引言

在地理信息系统(GIS)领域,坐标系转换是一项基础而重要的任务。本文将围绕三种主要的地图坐标系——墨卡托投影坐标系、屏幕坐标系和经纬度坐标系——探讨它们之间的相互转换关系,并提供相应的数学推导及实现方法。
在这里插入图片描述

2. 坐标系定义

2.1 经纬度坐标系

原点:经纬度坐标系的原点是位于赤道和格林威治子午线交点的位置,即 (0°, 0°)

  • 定义:经纬度坐标系是最常见的地理坐标系统,其中经度(longitude)范围是 -180°+180°,纬度(latitude)范围是 -90°+90°
  • 坐标轴:经度值从西向东递增,纬度值从南向北递增。
  • 符号表示(lon, lat)

在这里插入图片描述

         North (positive latitude)||+---+---+|   |   |
West (-longitude) +---+---+ East (positive longitude)|   |   |+---+---+||South (negative latitude)

2.2 墨卡托投影坐标系

原点:墨卡托投影坐标系的原点通常位于 (0°, 0°),即赤道和格林威治子午线的交点。但在实际应用中,特别是在Web地图服务中,原点可能被设置为地图的中心点,以适应特定的地图范围。

  • 定义:墨卡托投影是一种圆柱投影,地球表面在投影平面上表现为正方形网格,适用于Web地图服务。
  • 坐标轴:X 轴代表经度,Y 轴代表纬度,但纬度经过了变形处理。
  • 符号表示(x, y)

谷歌地图、微软地图、百度地图、腾讯地图、高德地图等网络地图所使用的投影都是网络墨卡托投影(Web Mercator),尽管我们喜欢把百度地图、高德地图称之为火星坐标系,不过它们还是没逃出网络墨卡托投影的手心。
在这里插入图片描述

         North (positive y)||+---+---+|   |   |
West (negative x) +---+---+ East (positive x)|   |   |+---+---+||South (negative y)

3.3 屏幕坐标系

原点:屏幕坐标系的原点通常位于屏幕的左上角,即 (0, 0)。这意味着 X 值从左向右增大,Y 值从上向下增大。

  • 定义:屏幕坐标系是图形显示设备(如显示器)的像素坐标系统。
  • 坐标轴:通常情况下,原点位于左上角,X 轴水平向右,Y 轴垂直向下。
  • 符号表示(x_screen, y_screen)

在这里插入图片描述

    +------------------------------------> x+|                                    |               (o o)           |              /  V  \             |             (_______)                |                                    |                                    |                                    ∨y+

2. 坐标系间的转换

2.1 经纬度坐标系到墨卡托投影坐标系

墨卡托投影的转换公式如下:

x m e r c a t o r = R ⋅ x l o n g i t u d e ⋅ π 180 x_{mercator} = \frac{R \cdot {x_{longitude} } \cdot \pi}{180} xmercator=180Rxlongitudeπ

y m e r c a t o r = R ⋅ ln ⁡ ( tan ⁡ ( π 4 + y l a t i t u d e 2 ) ) π 180 y_{mercator} = \frac{R \cdot \ln(\tan(\frac{\pi}{4} + \frac{y_{latitude}}{2})) \pi}{180} ymercator=180Rln(tan(4π+2ylatitude))π

其中,经纬度以角度为单位 R R R是地球半径,通常取为 6378137 米。

2.2 墨卡托投影坐标系到经纬度坐标系

反向转换公式为:

x l o n g i t u d e = 180 ⋅ x m e r c a t o r π ⋅ R x_{longitude} = \frac{180\cdot x_{mercator}}{\pi\cdot R} xlongitude=πR180xmercator
y l a t i t u d e = ( 2 ⋅ arctan ⁡ ( e y m e r c a t o r / R ) − π 2 ) 180 π y_{latitude} = \frac{(2 \cdot \arctan(e^{y_{mercator}/R}) - \frac{\pi}{2})180}{\pi} ylatitude=π(2arctan(eymercator/R)2π)180

2.3 墨卡托投影坐标系到屏幕坐标系

假设屏幕分辨率是 widthheight,并且屏幕中心对应于地图的中心点 ( x c e n t e r , y c e n t e r ) (x_{center}, y_{center}) (xcenter,ycenter),缩放级别为 zoomLevel。
计算缩放因子:
s c a l e = 2 z o o m l e v e l scale =2^{zoomlevel} scale=2zoomlevel
计算屏幕中心点对应的墨卡托投影坐标:
x c e n t e r _ s r e e n = x c e n t e r _ m e r a t o r ; y c e n t e r _ s r e e n = y c e n t e r _ m e r a t o r x_{center\_sreen} = x_{center\_merator} ;y_{center\_sreen} = y_{center\_merator} xcenter_sreen=xcenter_merator;ycenter_sreen=ycenter_merator
计算屏幕坐标:

x s c r e e n = ( x m e r a t o r − x c e n t e r _ m e r a t o r R ) ⋅ s c a l e + w i d t h 2 x_{screen} = (\frac{x_{merator}-x_{center\_merator}}{R})\cdot scale +\frac {width}{2} xscreen=(Rxmeratorxcenter_merator)scale+2width
y s c r e e n = h e i g h 2 − ( y m e r a t o r − y c e n t e r _ m e r a t o r R ) ⋅ s c a l e y_{screen} = \frac {heigh}{2}-(\frac{y_{merator}-y_{center\_merator}}{R})\cdot scale yscreen=2heigh(Rymeratorycenter_merator)scale

2.4 屏幕坐标系到墨卡托投影坐标系

假设屏幕坐标为 ( x s r e e n , y s r e e n ) (x_{sreen},y_{sreen}) (xsreen,ysreen) ,屏幕分辨率为 width 和 height,屏幕中心对应于地图的中心点 ( x c e n t e r s r e e n , y c e n t e r s r e e n ) (x_{center_sreen},y_{center_sreen}) (xcentersreen,ycentersreen) ,缩放级别为 zoomLevel
计算缩放因子:
s c a l e = 2 z o o m l e v e l scale =2^{zoomlevel} scale=2zoomlevel
计算墨卡托中心点对应的投影屏幕坐标:
x c e n t e r _ m e r a t o r = x c e n t e r _ s r e e n ; y c e n t e r _ m e r a t o r = y c e n t e r _ s r e e n x_{center\_merator} = x_{center\_sreen} ;y_{center\_merator} = y_{center\_sreen} xcenter_merator=xcenter_sreen;ycenter_merator=ycenter_sreen
计算屏幕坐标:

x m e r a t o r = ( x s r e e n − s c a l e 2 ) ⋅ R s c a l e + x c e n t e r _ m e r a t o r x_{merator} = (x_{sreen}-\frac{scale}{2})\cdot \frac {R}{scale} + x_{center\_merator} xmerator=(xsreen2scale)scaleR+xcenter_merator
y m e r a t o r = y c e n t e r _ m e r a t o r − ( y s r e e n − s c a l e 2 ) ⋅ R s c a l e y_{merator} = y_{center\_merator} - (y_{sreen}-\frac{scale}{2})\cdot \frac {R}{scale} ymerator=ycenter_merator(ysreen2scale)scaleR

2.5 经纬度坐标系到屏幕坐标系

结合上述 2.1 和 2.3 的转换公式,可以得到:
x s c r e e n = ( R ⋅ x l o n g i t u d e ⋅ π 180 − x c e n t e r _ m e r a t o r R ) ⋅ s c a l e + w i d t h 2 x_{screen} = (\frac{\frac{R \cdot {x_{longitude} } \cdot \pi}{180}-x_{center\_merator}}{R})\cdot scale +\frac {width}{2} xscreen=(R180Rxlongitudeπxcenter_merator)scale+2width
y s c r e e n = h e i g h 2 − ( R ⋅ ln ⁡ ( tan ⁡ ( π 4 + y l a t i t u d e 2 ) ) π 180 − y c e n t e r _ m e r a t o r R ) ⋅ s c a l e y_{screen} = \frac {heigh}{2}-(\frac{\frac{R \cdot \ln(\tan(\frac{\pi}{4} + \frac{y_{latitude}}{2})) \pi}{180}-y_{center\_merator}}{R})\cdot scale yscreen=2heigh(R180Rln(tan(4π+2ylatitude))πycenter_merator)scale

2.6 屏幕坐标系到经纬度坐标系

结合上述 2.4 和 2.2 的转换公式,可以得到:
x l o n g i t u d e = 180 ⋅ ( ( x s r e e n − s c a l e 2 ) ⋅ R s c a l e + x c e n t e r _ m e r a t o r ) π ⋅ R x_{longitude} = \frac{180\cdot ((x_{sreen}-\frac{scale}{2})\cdot \frac {R}{scale} + x_{center\_merator})}{\pi\cdot R} xlongitude=πR180((xsreen2scale)scaleR+xcenter_merator)
y l a t i t u d e = ( 2 ⋅ arctan ⁡ ( e y c e n t e r _ m e r a t o r − ( y s r e e n − s c a l e 2 ) ⋅ R s c a l e R ) − π 2 ) 180 π y_{latitude} = \frac{(2 \cdot \arctan(e^{\frac{y_{center\_merator} - (y_{sreen}-\frac{scale}{2})\cdot \frac {R}{scale}}R}) - \frac{\pi}{2})180}{\pi} ylatitude=π(2arctan(eRycenter_merator(ysreen2scale)scaleR)2π)180

3. 示例代码

以下是一个简单的 C++ 示例代码,演示了上述部分转换的过程:

#include <iostream>
#include <cmath>// 常量定义
const double EARTH_RADIUS = 6378137.0; // 地球半径,单位:米
const double PI = 3.14159265358979323846;// 经纬度坐标结构体
struct LatLng {double lat; // 纬度double lng; // 经度
};// 墨卡托投影坐标结构体
struct Mercator {double x; // 经度方向的投影坐标double y; // 纬度方向的投影坐标
};// 屏幕坐标结构体
struct Screen {double x; // 屏幕x坐标double y; // 屏幕y坐标
};// 经纬度转墨卡托投影
Mercator latLngToMercator(const LatLng& latLng) {Mercator mercator;mercator.x = latLng.lng * EARTH_RADIUS * PI / 180.0;mercator.y = log(tan((90.0 + latLng.lat) * PI / 360.0)) * EARTH_RADIUS;return mercator;
}// 墨卡托投影转经纬度
LatLng mercatorToLatLng(const Mercator& mercator) {LatLng latLng;latLng.lng = mercator.x / (EARTH_RADIUS * PI / 180.0);latLng.lat = 180.0 / PI * (2.0 * atan(exp(mercator.y / EARTH_RADIUS)) - PI / 2.0);return latLng;
}// 墨卡托投影转屏幕坐标
Screen mercatorToScreen(const Mercator& mercator, double zoomLevel) {Screen screen;double scale = pow(2.0, zoomLevel);screen.x = mercator.x * scale / EARTH_RADIUS + 0.5;screen.y = 0.5 - mercator.y * scale / EARTH_RADIUS;return screen;
}// 屏幕坐标转墨卡托投影
Mercator screenToMercator(const Screen& screen, double zoomLevel) {Mercator mercator;double scale = pow(2.0, zoomLevel);mercator.x = (screen.x - 0.5) * EARTH_RADIUS / scale;mercator.y = (0.5 - screen.y) * EARTH_RADIUS / scale;return mercator;
}// 屏幕坐标转经纬度
LatLng screenToLatLng(const Screen& screen, double zoomLevel) {Mercator mercator = screenToMercator(screen, zoomLevel);return mercatorToLatLng(mercator);
}// 经纬度转屏幕坐标
Screen latLngToScreen(const LatLng& latLng, double zoomLevel) {Mercator mercator = latLngToMercator(latLng);return mercatorToScreen(mercator, zoomLevel);
}// 测试代码
int main() {LatLng latLng = {39.9042, 116.4074}; // 北京经纬度double zoomLevel = 10.0; // 缩放级别// 经纬度转墨卡托投影Mercator mercator = latLngToMercator(latLng);std::cout << "经纬度转墨卡托投影: (" << mercator.x << ", " << mercator.y << ")" << std::endl;// 墨卡托投影转经纬度LatLng latLng2 = mercatorToLatLng(mercator);std::cout << "墨卡托投影转经纬度: (" << latLng2.lat << ", " << latLng2.lng << ")" << std::endl;// 墨卡托投影转屏幕坐标Screen screen = mercatorToScreen(mercator, zoomLevel);std::cout << "墨卡托投影转屏幕坐标: (" << screen.x << ", " << screen.y << ")" << std::endl;// 屏幕坐标转墨卡托投影Mercator mercator2 = screenToMercator(screen, zoomLevel);std::cout << "屏幕坐标转墨卡托投影: (" << mercator2.x << ", " << mercator2.y << ")" << std::endl;// 屏幕坐标转经纬度LatLng latLng3 = screenToLatLng(screen, zoomLevel);std::cout << "屏幕坐标转经纬度: (" << latLng3.lat << ", " << latLng3.lng << ")" << std::endl;// 经纬度转屏幕坐标Screen screen2 = latLngToScreen(latLng, zoomLevel);std::cout << "经纬度转屏幕坐标: (" << screen2.x << ", " << screen2.y << ")" << std::endl;return 0;
}

测试效果:
在这里插入图片描述

4. 结语

🥳🥳🥳现在,我们在本教程中,您学习了不同坐标系之间的转换涉及到几何变换和数学运算。理解这些转换对于开发地图应用至关重要,希望本文能帮助开发者更好地理解和运用坐标系转换技术。🛹🛹🛹从而实现对外部世界进行感知,充分认识这个有机与无机的环境,后期会持续分享esp32跑freertos实用案列🥳🥳🥳科学地合理地进行创作和发挥效益,然后为人类社会发展贡献一点微薄之力。🤣🤣🤣

如果你有任何问题,可以通过q group(945348278)加入鹏鹏小分队,期待与你思维的碰撞😘😘😘

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • Numpy中常用的数学方法
  • 输入子系统
  • 大型语言模型中推理链的演绎验证
  • 漫谈设计模式 [2]:工厂方法模式
  • 第145天:内网安全-Linux权限维持Rootkit后门Strace监控Alias别名Cron定时任务
  • 在这12种场景下会使Spring事务失效--注意防范
  • RestTemplate服务调用
  • Qt C++ Udp相关知识学习(一)
  • React 通用后台管理项目
  • 使用paddlerocr识别固定颜色验证码
  • Spring Boot实现发QQ邮件
  • 算法day23| 93.复原IP地址、78.子集、90.子集II
  • python第二章课堂笔记
  • Maven基本使用(下)
  • Zenmap
  • (十五)java多线程之并发集合ArrayBlockingQueue
  • [nginx文档翻译系列] 控制nginx
  • 《微软的软件测试之道》成书始末、出版宣告、补充致谢名单及相关信息
  • CSS居中完全指南——构建CSS居中决策树
  • Linux后台研发超实用命令总结
  • Linux学习笔记6-使用fdisk进行磁盘管理
  • TCP拥塞控制
  • Vultr 教程目录
  • webgl (原生)基础入门指南【一】
  • Work@Alibaba 阿里巴巴的企业应用构建之路
  • 分布式事物理论与实践
  • 网络应用优化——时延与带宽
  • 硬币翻转问题,区间操作
  • 找一份好的前端工作,起点很重要
  • TPG领衔财团投资轻奢珠宝品牌APM Monaco
  • ​Java基础复习笔记 第16章:网络编程
  • ​软考-高级-系统架构设计师教程(清华第2版)【第12章 信息系统架构设计理论与实践(P420~465)-思维导图】​
  • # 计算机视觉入门
  • #pragma预处理命令
  • #职场发展#其他
  • (3) cmake编译多个cpp文件
  • (3)(3.5) 遥测无线电区域条例
  • (C)一些题4
  • (C语言)strcpy与strcpy详解,与模拟实现
  • (js)循环条件满足时终止循环
  • (SpringBoot)第七章:SpringBoot日志文件
  • (zt)最盛行的警世狂言(爆笑)
  • (每日持续更新)jdk api之FileFilter基础、应用、实战
  • (免费领源码)Java#Springboot#mysql农产品销售管理系统47627-计算机毕业设计项目选题推荐
  • (一)基于IDEA的JAVA基础12
  • (转)linux自定义开机启动服务和chkconfig使用方法
  • (转)Scala的“=”符号简介
  • (转载)(官方)UE4--图像编程----着色器开发
  • (转载)Google Chrome调试JS
  • .Net 6.0 处理跨域的方式
  • .NET 8 中引入新的 IHostedLifecycleService 接口 实现定时任务
  • .NET CORE 2.0发布后没有 VIEWS视图页面文件
  • .Net core 6.0 升8.0
  • .NET Core、DNX、DNU、DNVM、MVC6学习资料
  • .NET Framework、.NET Core 、 .NET 5、.NET 6和.NET 7 和.NET8 简介及区别