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

news2024/9/22 3:45:17

地图坐标系转换详解

  • 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)加入鹏鹏小分队,期待与你思维的碰撞😘😘😘

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2120544.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

mfc140u.dll文件错误的相关修复方法,4种方法修复mfc140u.dll

当面对基于Microsoft Visual C开发的应用程序出现启动或运行失败时&#xff0c;mfc140u.dll文件错误往往是罪魁祸首之一。这个动态链接库&#xff08;DLL&#xff09;文件对于许多Windows软件来说是必不可少的&#xff0c;因为它包含了重要的编程代码和数据。如果发现此文件损坏…

数据结构(7.1)——查找的基本概念

基本概念 查找——在数据结构集合中寻找满足某种条件的数据元素的过程称为查找 查找表&#xff08;查找结构&#xff09;——用于查找的数据集合称为查找表&#xff0c;它由同一类型的数据元素(或记录)组成 关键字——数据元素中唯一标识该元素的某个数据项的值&#xff0c;…

【C++二分查找 贪心】1488. 避免洪水泛滥

本文涉及的基础知识点 C二分查找 贪心&#xff1a;决策包容性 LeetCode1488. 避免洪水泛滥 你的国家有无数个湖泊&#xff0c;所有湖泊一开始都是空的。当第 n 个湖泊下雨前是空的&#xff0c;那么它就会装满水。如果第 n 个湖泊下雨前是 满的 &#xff0c;这个湖泊会发生 洪…

【Canvas与艺术】菊花孔雀螺旋

【成图】 【代码】 <!DOCTYPE html> <html lang"utf-8"> <meta http-equiv"Content-Type" content"text/html; charsetutf-8"/> <head><title>菊花孔雀螺旋</title><style type"text/css">…

HTML 揭秘:HTML 编码快速入门

HTML 揭秘&#xff1a;HTML 编码快速入门 一 . 前端知识介绍二 . HTML 介绍三 . HTML 快速入门四 . HTML 编辑器 - VSCode4.1 插件安装4.2 修改主题配色4.3 修改快捷键4.4 设置自动保存4.5 创建 HTML 文件4.5 书写 HTML 代码4.6 常见快捷键 五 . 基础标签5.1 字体标签5.1.1 col…

SpringCloud之配置中心git示例

SpringCloud之配置中心git示例 随着线上项目变的日益庞大&#xff0c;每个项目都散落着各种配置文件&#xff0c;如果采用分布式的开发模式&#xff0c;需要的配置文件随着 服务增加而不断增多。 某一个基础服务信息变更&#xff0c;都会引起一系列的更新和重启&#xff0c;…

探索有向图与无向图中深度优先搜索(DFS)的边类型——3×3 网格分析

探索有向图与无向图中深度优先搜索(DFS)的边类型——33 网格分析 一、基本概念二、有向图中的 DFS 边类型分析三、有向图 DFS 的 C 代码实现在图的深度优先搜索(DFS)过程中,边的分类对于理解算法的执行流程及其复杂性至关重要。在有向图和无向图中,DFS 过程中遇到的边可以…

【Kafka】分区与复制机制:解锁高性能与容错的密钥

&#x1f407;明明跟你说过&#xff1a;个人主页 &#x1f3c5;个人专栏&#xff1a;《大数据前沿&#xff1a;技术与应用并进》&#x1f3c5; &#x1f516;行路有良友&#xff0c;便是天堂&#x1f516; 目录 一、引言 1、kafka简介 2、kafka使用场景 二、Kafka消息可…

【短距离通信】【WiFi】精讲WiFi P2P技术特点及拓扑组成

1. WiFi P2P技术特点 1.1 WiFi P2P定义 WiFi P2P&#xff08;WiFi Peer-to-Peer&#xff09;&#xff0c;也被称为WiFi Direct&#xff0c;是是WiFi联盟发布的一种无线通信技术&#xff0c;允许设备直接相互连接&#xff0c;而无需通过传统的WiFi接入点&#xff08;AP&#x…

【Python篇】matplotlib超详细教程-由入门到精通(下篇)

文章目录 前言第六部分&#xff1a;保存与导出图表6.1 保存为图片文件示例&#xff1a;保存图表为 PNG 文件解释&#xff1a;关键点&#xff1a; 6.2 保存为高分辨率图片示例&#xff1a;保存为高分辨率图片解释&#xff1a; 6.3 保存为不同文件格式示例&#xff1a;保存为不同…

SpringCloudAliaba生成式JavaAI应用开发文生问答音像

采用SpringCloudAliabaAI型式大模型LLM&#xff0c;进行生成式JavaAI应用开发&#xff0c;实现文生问答、图像和语音合成&#xff0c;Web应用页面交互展现。SpringBootGradle软件框架&#xff0c;Idea集成开发环境&#xff0c;API_Post嵌入插件一体测试。 1 工效展示[文生-答/图…

牛津大学:自动发现跨领域高阶抽象泛化框架

随着LLM等技术的快速发展&#xff0c;进一步的抽象和泛化问题亦被看作是未来AI甚至AGI发展的关键。 然而鉴于当前不论是LLM下的自回归AR条件预测Gen方法还是CV领域的diffusion扩散Gen方法&#xff0c;甚至于传统DNN的无监督学习模式&#xff0c;在所涉及的更多通用或领域场景下…

Java+Swing用户信息管理系统

JavaSwing用户信息管理系统 一、系统介绍二、功能展示1.管理员登陆2.用户信息查询3.用户信息添加4.用户信息修改5.用户信息删除 三、系统实现1.UserDao .java 四、其它1.其他系统实现 一、系统介绍 该系统实现了管理员系统登陆、用户信息查询、用户信息添加、用户信息修改、用…

大模型→世界模型下的「认知流形」本质·上

本篇内容节选自今年初我撰写的那篇10万的文章《融合RL与LLM思想&#xff0c;探寻世界模型以迈向AGI》&#xff0c;其观点也是文章中核心中的核心。 想进一步完整阅读电子版的伙伴大家可关注评论联系我&#xff0c;节选内容如下↓ “...存在一个大的开放的tokenization世界。 …

解锁SQL基础应用新境界:从入门到精通的扩展实践指南(SQL扩展)

作者简介&#xff1a;我是团团儿&#xff0c;是一名专注于云计算领域的专业创作者&#xff0c;感谢大家的关注 座右铭&#xff1a; 云端筑梦&#xff0c;数据为翼&#xff0c;探索无限可能&#xff0c;引领云计算新纪元 个人主页&#xff1a;团儿.-CSDN博客 目录 前言&#…

Unity AnimationClip详解(1)

【动画片段】 前文我们介绍了骨骼动画&#xff0c;在Unity中骨骼动画的部分静态数据存储在SkinedMeshRender中&#xff0c;而另一部分动态的关键帧数据就是存储在AnimationClip中的。 关键帧数据来自与FBX、OBJ等动画模型文件&#xff0c;可以在动画导入后的Animation选项卡中…

通信工程学习:什么是GSMP通用交换机管理协议

GSMP&#xff1a;通用交换机管理协议 GSMP&#xff08;General Switch Management Protocol&#xff0c;通用交换机管理协议&#xff09;是一种用于IP交换机对ATM交换机进行控制的协议。以下是对GSMP的详细解释&#xff1a; 一、定义与概述 GSMP是一种异步协议&#xff0c;它在…

Python画笔案例-040 绘制五角星顶圆

1、绘制五角星顶圆 通过 python 的turtle 库绘制五角星顶圆&#xff0c;如下图&#xff1a; 2、实现代码 绘制五角星顶圆&#xff0c;以下为实现代码&#xff1a; """五角星顶圆.py """ import turtledef draw_circle(d):turtle.left(90)for _ …

C#/.NET/.NET Core技术前沿周刊 | 第 4 期(2024年9.1-9.8)

前言 C#/.NET/.NET Core技术前沿周刊&#xff0c;你的每周技术指南针&#xff01;记录、追踪C#/.NET/.NET Core领域、生态的每周最新、最实用、最有价值的技术文章、社区动态、优质项目和学习资源等。让你时刻站在技术前沿&#xff0c;助力技术成长与视野拓宽。 欢迎投稿&…

客户端绑定本地端口与服务器建立连接的详细实现

客户端绑定本地端口与服务器建立连接的详细实现 一、网络编程基础1.1 TCP/IP协议1.2 套接字(Socket)1.3 客户端与服务器模型二、客户端程序的设计2.1 需求分析2.2 流程设计三、具体代码实现3.1 伪代码3.2 C代码实现四、代码详解4.1 初始化套接字库4.2 创建套接字4.3 绑定本地…