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

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『瓦片经纬度』

前文链接&#xff1a;QGraphicsView实现简易地图1『加载离线瓦片地图』 地图采用GCJ02 Web 墨卡托投影&#xff0c;最小坐标&#xff1a;(-180.00000000000000,-85.05112877980655)&#xff0c;最大坐标&#xff1a;(180.00000000000000,85.05112877980655)。瓦片地图单张图片像…...

医学图像重建—第一章笔记

序言 本书涵盖内容&#xff1a; 2D parallel beam imaging 2D fan beam imaging 3D parallel ray imaging 3D parallel plane imaging 3D cone beam imaging 算法包括&#xff1a;analytical method&#xff0c;iterative method 应用于&#xff1a; X-ray CT single photon…...

python-pytorch基础之神经网络分类

这里写目录标题 生成数据函数定义数据集定义loader加载数据定义神经网络模型测试输出是否为2个输入数据&#xff0c;输出结果 训练模型函数计算正确率 训练数据并保存模型测试模型准备数据加载模型预测对比结果 生成数据函数 import randomdef get_rectangle():widthrandom.ra…...

【C++ 程序设计】实战:C++ 变量实践练习题

目录 01. 变量&#xff1a;定义 02. 变量&#xff1a;初始化 03. 变量&#xff1a;参数传递 04. 变量&#xff1a;格式说明符 ① 占位符 “%d” 改为格式说明符 “%llu” ② 占位符 “%d” 改为格式说明符 “%f” 或 “%e” 05. 变量&#xff1a;字节数统计 06. 变量&a…...

微软对Visual Studio 17.7 Preview 4进行版本更新,新插件管理器亮相

近期微软发布了Visual Studio 17.7 Preview 4版本&#xff0c;而在这个版本当中&#xff0c;全新设计的扩展插件管理器将亮相&#xff0c;并且可以让用户可更简单地安装和管理扩展插件。 据了解&#xff0c;目前用户可以从 Visual Studio Marketplace 下载各式各样的 VS 扩展插…...

Kafka 入门到起飞 - Kafka怎么做到保障消息不会重复消费的? 消费者组是什么?

Kafka怎么做到避免消息重复消费的&#xff1f; 消费者组是什么&#xff1f; 消费者&#xff1a; 1、订阅Topic&#xff08;主题&#xff09; 2、从订阅的Topic消费&#xff08;pull&#xff09;消息&#xff0c; 3、将消费消息的offset&#xff08;偏移量&#xff09;保存在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()&#xff1a;2、TakeWhile()&#xff1a;3、Skip()&#xff1a;4、SkipWhile()&#xff1a;九、聚合操作符 1、Count&#xff1a; 返回集合项数。 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&#xff0c;然后…...

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 提供最新的对应版本小程序端&#xff0c;上一版本增加了 PC 端绘画功能&#xff0c; 绘画功能采用其他绘画接口 – 意间 AI&#xff0c;本版新增了百度文心一言接口。 后台一些小细节的优化及一些小 BUG 的处理&#xff0c;前端进行了些小细节优…...

wps图表怎么改横纵坐标,MLP 多层感知器和CNN卷积神经网络区别

目录 wps表格横纵坐标轴怎么设置&#xff1f; MLP (Multilayer Perceptron) 多层感知器 CNN (Convolutional Neural Network) 卷积神经网络 多层感知器MLP&#xff0c;全连接网络&#xff0c;DNN三者的关系 wps表格横纵坐标轴怎么设置&#xff1f; 1、打开表格点击图的右侧…...

rdb和aof

RDB持久化&#xff1a;原理是将Redis在内存中的数据库记录定时dump到磁盘上的RDB持久化AOF持久化&#xff1a;原理是将Redis的操作日志以追加的方式写入文件 rdb&#xff1a; 开启方式&#xff1a;客户端可以通过向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数据源编写配置类&#xff0c;创建RedisTempla…...

链路追踪设计

...

Golang之路---02 基础语法——常量 (包括特殊常量iota)

常量 //显式类型定义const a string "test" //隐式类型定义const b 20 //多个常量定义 const(c "test2"d 2.3e 27)iota iota是Golang语言的常量计数器&#xff0c;只能在常量表达式中使用 iota在const关键字出现时将被重置为0&#xff0c;const中每新…...

Pytest学习教程_装饰器(二)

前言 pytest装饰器是在使用 pytest 测试框架时用于扩展测试功能的特殊注解或修饰符。使用装饰器可以为测试函数提供额外的功能或行为。   以下是 pytest 装饰器的一些常见用法和用途&#xff1a; 装饰器作用pytest.fixture用于定义测试用例的前置条件和后置操作。可以创建可重…...

redis的如何使用

1、redis的使用 1.1windows安装 安装包下载地址&#xff1a;Releases dmajkic/redis GitHub 1.2 redis中常使用的几个文件 1.3 redis中运行 双击redis-server&#xff0c;既可以运行。 1.4使用redis客户单来连接redis 1.5redis的常用指标 redis-serve 服务端,端口号&am…...

MyBatis(二)

文章目录 一.MyBatis的模式开发1.1 定义数据表和实体类1.2 配置数据源和MyBatis1.3 编写Mapper接口和增加xxxMapper.xml1.4 测试我们功能的是否实现. 二. Mybatis的增删查改操作2.1 单表查询2.2 多表查询三.动态SQL的实现3.1 什么是动态SQL3.2 动态SQL的使用if标签的使用trim标…...

【【51单片机AD转换模块】】

代码是简单的&#xff0c;板子是坏的&#xff0c;电阻是识别不出来的 main.c #include <REGX52.H> #include "delay.h" #include "LCD1602.h" #include "XPT2046.h"unsigned int ADValue;void main(void) {LCD_Init();LCD_ShowString(1,1…...

Longest Divisors Interval(cf)

题意&#xff1a;给定一个正整数n&#xff0c;求正整数的区间[l&#xff0c;r]的最大大小&#xff0c;使得对于区间中的每个i&#xff08;即l≤i≤r&#xff09;&#xff0c;n是i的倍数。给定两个整数l≤r&#xff0c;区间[l&#xff0c;r]的大小为r−l1&#xff08;即&#xf…...

配置文件、request对象请求方法、Django连接MySQL、Django中的ORM、ORM增删改查字段、ORM增删改查数据

一、配置文件的介绍 1.注册应用的 INSTALLED_APPS [django.contrib.admin,django.contrib.auth,django.contrib.contenttypes,django.contrib.sessions,django.contrib.messages,django.contrib.staticfiles,app01.apps.App01Config, ]################中间件###############…...

CTF学习路线指南(附刷题练习网址)

前言&#xff1a; PWN,Reverse&#xff1a;偏重对汇编&#xff0c;逆向的理解&#xff1b; Gypto&#xff1a;偏重对数学&#xff0c;算法的深入学习&#xff1b; Web&#xff1a;偏重对技巧沉淀&#xff0c;快速搜索能力的挑战&#xff1b; Mic&#xff1a;则更为复杂&…...

【Rust 基础篇】Rust默认泛型参数:简化泛型使用

导言 Rust是一种以安全性和高效性著称的系统级编程语言&#xff0c;其设计哲学是在不损失性能的前提下&#xff0c;保障代码的内存安全和线程安全。在Rust中&#xff0c;泛型是一种非常重要的特性&#xff0c;它允许我们编写一种可以在多种数据类型上进行抽象的代码。然而&…...

从源码分析Handler面试问题

Handler 老生常谈的问题了&#xff0c;非常建议看一下Handler 的源码。刚入行的时候&#xff0c;大佬们就说 阅读源码 是进步很快的方式。 Handler的基本原理 Handler 的 重要组成部分 Message 消息MessageQueue 消息队列Lopper 负责处理MessageQueue中的消息 消息是如何添加…...

shell编程 变量作用域

变量 变量赋值不用$&#xff0c;访问值时用$,赋值时两边不留空格&#xff0c;双引号括起来的变量被值替换{}标记变量开始和结束,变量名区分大小写&#xff0c;所有bash变量的值变量不区分类型&#xff0c;统一为字符串 变量类型 环境变量&#xff0c;子进程可以继承父进程环境…...

华为eNSP:isis的配置

一、拓扑图 二、路由器的配置 配置接口IP AR1&#xff1a; <Huawei>system-view [Huawei]int g0/0/0 [Huawei-GigabitEthernet0/0/0]ip add 1.1.1.1 24 [Huawei-GigabitEthernet0/0/0]qu AR2: <Huawei>system-view [Huawei]int g0/0/0 [Huawei-GigabitEthe…...

网站建设行业税率/一键生成网站

简介 Google 的 gflags 是一套命令行参数处理的开源库。比 getopt 更方便&#xff0c;更功能强大&#xff0c;从 C的库更好的支持 C&#xff08;如 C的 string 类型&#xff09;。 example 源代码先看 example 源代码&#xff0c;然后逐步介绍。 example.cc 1 2 3 4 5 6 7 8 9 …...

互联网平面设计/网络优化工资一般多少

本来以为iPad已经把平板的大概趋势勾勒出来了&#xff0c;结果微软Surface又把平板和台式机进行了折中&#xff0c;而Nexus 7平板在走它的小资不创新道路&#xff0c;平板电脑的方向在哪里、如何杀出平板红海&#xff1f; 通过咨询13个科技领袖对平板趋势的意见&#xff0c;他们…...

免费做网站有哪些/成都网站建设方案托管

题目描述&#xff1a; 给定一个非空的字符串&#xff0c;判断它是否可以由它的一个子串重复多次构成。给定的字符串只含有小写英文字母&#xff0c;并且长度不超过10000。 示例 1: 输入: "abab" 输出: True 解释: 可由子字符串 "ab" 重复两次构成。示…...

无锡网站建设 首选无锡立威云商/怎样在百度上发表文章

前言 一直听说过反编译,感觉很高大上,一直没自己用过,今天因缘巧合之下,终于要开始逐渐认识,了解和学习一下反编译了~先给自己说下加油,鼓励一下下 apktool的下载和安装 apktool 下载地址: Apktool [![Join the chat athttps://gitter.im/iBotPeaches/Apktool] apktool 安装教程…...

政务服务网站建设汇报/网络营销方案策划论文

首先&#xff0c;还是想给大家继续话痨话痨&#xff0c;脱离舒适区&#xff0c;努力坚持下去。我们只要超越百分之80 的人就够了。就像陈皓老师说的&#xff0c;你只看看中国的互联网&#xff0c;你就会发现&#xff0c;他们基本上全部都是在消费大众&#xff0c;让大众变得更为…...

宁波网站建设优化排名/秦皇岛百度推广

题目 根据手机按键上的对应关系将字母转成数字, 简单模拟题 总结 1. scanf("%s", input); 不需要加上 & 2. 字符串的终结符是 \0 3. scanf 和 printf 打印的都是 char*, 不能是 int* 代码 #include <iostream> #include <cstring> #include <stdi…...