QGraphicsView实现简易地图2『瓦片经纬度』
前文链接:QGraphicsView实现简易地图1『加载离线瓦片地图』
地图采用GCJ02 Web 墨卡托投影,最小坐标:(-180.00000000000000,-85.05112877980655),最大坐标:(180.00000000000000,85.05112877980655)。瓦片地图单张图片像素大小为256*256,经度均分256像素,但纬度分布不均匀,需要公式计算。
1、动态演示效果

2、静态展示图片

核心代码
1、数据定义GeoData.h
#pragma once
#include <QMetaType>/** 地理几何数据* 瓦片地图坐标投影:GCJ02 Web 墨卡托投影*/#define PIXMAP_SIZE 256// 瓦片坐标
struct TileCoord
{TileCoord(double _x, double _y) : x(_x), y(_y) {}double x;double y;
};// 经纬度坐标
struct GeoCoord
{GeoCoord() = default;GeoCoord(double _lon, double _lat) : lon(_lon), lat(_lat) {}double lon; // 经度double lat; // 纬度
};
Q_DECLARE_METATYPE(GeoCoord)
2、MapUtility类
#pragma once
#include <QPointF>
#include "DataStruct/GeoData.h"class MapUtility
{
public:// 场景坐标转经纬度static GeoCoord geoCoordFromScene(QPointF scenePos, int level);private:// 场景坐标转瓦片坐标(瓦片坐标系)static TileCoord tileCoordFromScene(QPointF scenePos, int level);// 场景坐标转所在瓦片像素点坐标static QPointF tilePixelCoordFromScene(QPointF scenePos, int level);
};
#include "MapUtility.h"
#include "TileUtility.h"GeoCoord MapUtility::geoCoordFromScene(QPointF scenePos, int level)
{TileCoord tileCoord = tileCoordFromScene(scenePos, level);QPointF tilePixelCoord = tilePixelCoordFromScene(scenePos, level);return TileUtility::pixelToLonLat(tilePixelCoord.x(), tilePixelCoord.y(), tileCoord.x, tileCoord.y, level);
}TileCoord MapUtility::tileCoordFromScene(QPointF scenePos, int level)
{int tileX = std::floor(scenePos.x() / PIXMAP_SIZE);int tileY = std::floor(scenePos.y() / PIXMAP_SIZE);return TileCoord(tileX, tileY);
}QPointF MapUtility::tilePixelCoordFromScene(QPointF scenePos, int level)
{TileCoord tileCoord = tileCoordFromScene(scenePos, level);double left = tileCoord.x * PIXMAP_SIZE; // scenePos所在瓦片的左侧位于场景中的坐标double top = tileCoord.y * PIXMAP_SIZE; // scenePos所在瓦片的上侧位于场景中的坐标return QPointF(scenePos.x() - left, scenePos.y() - top);
}
3、TileUtility类
class TileUtility
{friend class MapUtility;private:/*** 将地图层级下瓦片的像素点转换到经纬度* 瓦片地图左上角为(0, 0)点* @param pixelX 瓦片像素点X* @param pixelY 瓦片像素点Y* @param tileX 瓦片坐标X* @param tileY 瓦片坐标Y* @param level 瓦片层级* @return 经纬度坐标*/static GeoCoord pixelToLonLat(double pixelX, double pixelY, int tileX, int tileY, int level);static double pixelXToLon(double pixelX, double tileX, int level);static double pixelXToLat(double pixelY, double tileY, int level);static double mathSinH(double value);/*** 获取地图层级下X/Y轴上的瓦片数量* @param level 瓦片层级* @return 瓦片数量*/static int mapSize(int level);
};
GeoCoord TileUtility::pixelToLonLat(double pixelX, double pixelY, int tileX, int tileY, int level)
{double lon = pixelXToLon(pixelX, tileX, level);double lat = pixelXToLat(pixelY, tileY, level);return GeoCoord(lon, lat);
}double TileUtility::pixelXToLon(double pixelX, double tileX, int level)
{const double pixelXToTileAddition = pixelX / PIXMAP_SIZE;const double lon = (tileX + pixelXToTileAddition) / mapSize(level) * 360 - 180;return lon;
}double TileUtility::pixelXToLat(double pixelY, double tileY, int level)
{const double pixelYToTileAddition = pixelY / PIXMAP_SIZE;const double lat = qAtan(mathSinH(M_PI * (1 - 2 * (tileY + pixelYToTileAddition) / mapSize(level)))) * 180.0 / M_PI;return lat;
}double TileUtility::mathSinH(double value)
{return (qExp(value) - qExp(-value)) / 2;
}int TileUtility::mapSize(int level)
{return pow(2, level);
}
4、场景鼠标移动事件
void MapScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent)
{m_coordPos = MapUtility::geoCoordFromScene(mouseEvent->scenePos(), m_curLevel);emit geoCoordChanged(m_coordPos);
}
相关文章:
QGraphicsView实现简易地图2『瓦片经纬度』
前文链接:QGraphicsView实现简易地图1『加载离线瓦片地图』 地图采用GCJ02 Web 墨卡托投影,最小坐标:(-180.00000000000000,-85.05112877980655),最大坐标:(180.00000000000000,85.05112877980655)。瓦片地图单张图片像…...
医学图像重建—第一章笔记
序言 本书涵盖内容: 2D parallel beam imaging 2D fan beam imaging 3D parallel ray imaging 3D parallel plane imaging 3D cone beam imaging 算法包括:analytical method,iterative method 应用于: X-ray CT single photon…...
python-pytorch基础之神经网络分类
这里写目录标题 生成数据函数定义数据集定义loader加载数据定义神经网络模型测试输出是否为2个输入数据,输出结果 训练模型函数计算正确率 训练数据并保存模型测试模型准备数据加载模型预测对比结果 生成数据函数 import randomdef get_rectangle():widthrandom.ra…...
【C++ 程序设计】实战:C++ 变量实践练习题
目录 01. 变量:定义 02. 变量:初始化 03. 变量:参数传递 04. 变量:格式说明符 ① 占位符 “%d” 改为格式说明符 “%llu” ② 占位符 “%d” 改为格式说明符 “%f” 或 “%e” 05. 变量:字节数统计 06. 变量&a…...
微软对Visual Studio 17.7 Preview 4进行版本更新,新插件管理器亮相
近期微软发布了Visual Studio 17.7 Preview 4版本,而在这个版本当中,全新设计的扩展插件管理器将亮相,并且可以让用户可更简单地安装和管理扩展插件。 据了解,目前用户可以从 Visual Studio Marketplace 下载各式各样的 VS 扩展插…...
Kafka 入门到起飞 - Kafka怎么做到保障消息不会重复消费的? 消费者组是什么?
Kafka怎么做到避免消息重复消费的? 消费者组是什么? 消费者: 1、订阅Topic(主题) 2、从订阅的Topic消费(pull)消息, 3、将消费消息的offset(偏移量)保存在K…...
MongoDB 的增、查、改、删
Monogo使用 增 单条增加 db.member.insertOne({"name":"张三","age":18,"create":new Date()}) db.member.insert({"name":"李四1","age":18,"create":new Date()}) db.member.insertOne(…...
mysql常用操作命令
mysql常用操作命令 mysql:单进程多线程模型,一个SQL语句无法利用多个cpu core 一:基本命令 0.查看当前连接数 show global status like Thread$; show variables like "%timeout%"; show variables like "log_%";1.查看当前连接状态 show processlist…...
数学建模常见模型汇总
优化问题 线性规划、半定规划、几何规划、非线性规划、整数规划、多目标规划(分层序列法)、动态规划、存贮论、代理模型、响应面分析法、列生成算法 预测模型 微分方程、小波分析、回归分析、灰色预测、马尔可夫预测、时间序列分析(AR MAMA.RMA ARTMA LSTM神经网络)、混沌模…...
C#使用LINQ查询操作符实例代码(二)
目录 六、连表操作符 1、内连接2、左外连接(DefaultIfEmpty)3、组连接七、集合操作 八、分区操作符 1、Take():2、TakeWhile():3、Skip():4、SkipWhile():九、聚合操作符 1、Count: 返回集合项数。 2、LongCount&…...
jenkinsfile小试牛刀
序 本文主要演示一下如何用jenkinsfile来编译java服务 安装jenkins 这里使用docker来安装jenkins docker run --name jenkins-docker \ --volume $HOME/jenkins_home:/var/jenkins_home \ -p 8080:8080 jenkins/jenkins:2.416之后访问http://${yourip}:8080,然后…...
C++ xmake构建
文章目录 一、xmake.lua二、xmake常用语句 一、xmake.lua --xmake.luaset_project("XXX")add_rules("mode.debug", "mode.release") set_config("arch", "x64")if is_plat("windows") then -- the release modei…...
推荐带500创作模型的付费创作V2.1.0独立版系统源码
ChatGPT 付费创作系统 V2.1.0 提供最新的对应版本小程序端,上一版本增加了 PC 端绘画功能, 绘画功能采用其他绘画接口 – 意间 AI,本版新增了百度文心一言接口。 后台一些小细节的优化及一些小 BUG 的处理,前端进行了些小细节优…...
wps图表怎么改横纵坐标,MLP 多层感知器和CNN卷积神经网络区别
目录 wps表格横纵坐标轴怎么设置? MLP (Multilayer Perceptron) 多层感知器 CNN (Convolutional Neural Network) 卷积神经网络 多层感知器MLP,全连接网络,DNN三者的关系 wps表格横纵坐标轴怎么设置? 1、打开表格点击图的右侧…...
rdb和aof
RDB持久化:原理是将Redis在内存中的数据库记录定时dump到磁盘上的RDB持久化AOF持久化:原理是将Redis的操作日志以追加的方式写入文件 rdb: 开启方式:客户端可以通过向Redis服务器发送save或bgsave命令让服务器生成rdb文件&#…...
TCP网络通信编程之网络上传文件
【图片】 【思路解析】 【客户端代码】 import java.io.*; import java.net.InetAddress; import java.net.Socket; import java.net.UnknownHostException;/*** ProjectName: Study* FileName: TCPFileUploadClient* author:HWJ* Data: 2023/7/29 18:44*/ public class TCPFil…...
Java中对Redis的常用操作
目录 数据类型五种常用数据类型介绍各种数据类型特点 常用命令字符串操作命令哈希操作命令列表操作命令集合操作命令有序集合操作命令通用命令 在Java中操作RedisRedis的Java客户端Spring Data Redis使用方式介绍环境搭建配置Redis数据源编写配置类,创建RedisTempla…...
链路追踪设计
...
Golang之路---02 基础语法——常量 (包括特殊常量iota)
常量 //显式类型定义const a string "test" //隐式类型定义const b 20 //多个常量定义 const(c "test2"d 2.3e 27)iota iota是Golang语言的常量计数器,只能在常量表达式中使用 iota在const关键字出现时将被重置为0,const中每新…...
Pytest学习教程_装饰器(二)
前言 pytest装饰器是在使用 pytest 测试框架时用于扩展测试功能的特殊注解或修饰符。使用装饰器可以为测试函数提供额外的功能或行为。 以下是 pytest 装饰器的一些常见用法和用途: 装饰器作用pytest.fixture用于定义测试用例的前置条件和后置操作。可以创建可重…...
生成xcframework
打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式,可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...
【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力
引言: 在人工智能快速发展的浪潮中,快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型(LLM)。该模型代表着该领域的重大突破,通过独特方式融合思考与非思考…...
SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现
摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序,以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务,提供稳定高效的数据处理与业务逻辑支持;利用 uniapp 实现跨平台前…...
听写流程自动化实践,轻量级教育辅助
随着智能教育工具的发展,越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式,也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建,…...
Redis的发布订阅模式与专业的 MQ(如 Kafka, RabbitMQ)相比,优缺点是什么?适用于哪些场景?
Redis 的发布订阅(Pub/Sub)模式与专业的 MQ(Message Queue)如 Kafka、RabbitMQ 进行比较,核心的权衡点在于:简单与速度 vs. 可靠与功能。 下面我们详细展开对比。 Redis Pub/Sub 的核心特点 它是一个发后…...
Python Ovito统计金刚石结构数量
大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...
Python 实现 Web 静态服务器(HTTP 协议)
目录 一、在本地启动 HTTP 服务器1. Windows 下安装 node.js1)下载安装包2)配置环境变量3)安装镜像4)node.js 的常用命令 2. 安装 http-server 服务3. 使用 http-server 开启服务1)使用 http-server2)详解 …...
认识CMake并使用CMake构建自己的第一个项目
1.CMake的作用和优势 跨平台支持:CMake支持多种操作系统和编译器,使用同一份构建配置可以在不同的环境中使用 简化配置:通过CMakeLists.txt文件,用户可以定义项目结构、依赖项、编译选项等,无需手动编写复杂的构建脚本…...
【把数组变成一棵树】有序数组秒变平衡BST,原来可以这么优雅!
【把数组变成一棵树】有序数组秒变平衡BST,原来可以这么优雅! 🌱 前言:一棵树的浪漫,从数组开始说起 程序员的世界里,数组是最常见的基本结构之一,几乎每种语言、每种算法都少不了它。可你有没有想过,一组看似“线性排列”的有序数组,竟然可以**“长”成一棵平衡的二…...
ubuntu中安装conda的后遗症
缘由: 在编译rk3588的sdk时,遇到编译buildroot失败,提示如下: 提示缺失expect,但是实测相关工具是在的,如下显示: 然后查找借助各个ai工具,重新安装相关的工具,依然无解。 解决&am…...
