QGraphicsView实现简易地图10『自适应窗口大小』

前文链接:QGraphicsView实现简易地图9『层级缩放显示底图』
自适应窗口大小
当地图窗口放大或缩小的时候,需要地图能够动态覆盖整个视口。
1、动态演示效果
在这里插入图片描述

2、核心代码

注:WHMapView继承自MapView
void WHMapView::resize()
{
	if (m_curLevel >= 0)
		moveScene();
}

void MapView::moveScene()
{
	QString appPath = QApplication::applicationDirPath();
	QString dirPath = QString("%1/MapData/GaoDeMap/Map/MapPng/L0%2").arg(appPath).arg(m_curLevel + 1);
	// 视口宽度和高度
	int vw = viewport()->width();
	int vh = viewport()->height();

	// 计算呈现的瓦片地图左上角的场景坐标和视口坐标、呈现的瓦片地图右下角的场景坐标和视口坐标
	QPoint topLeftScenePos(m_topLeftTileCoord.x * PIXMAP_SIZE, m_topLeftTileCoord.y * PIXMAP_SIZE);
	QPointF topLeftViewPos = mapFromScene(topLeftScenePos);
	QPoint bottomRightScenePos(m_bottomRightTileCoord.x * PIXMAP_SIZE, m_bottomRightTileCoord.y * PIXMAP_SIZE);
	QPointF bottomRightViewPos = mapFromScene(bottomRightScenePos);

	int mapSideCount = pow(2, m_curLevel);

	if (MapUtility::sceneSize(m_curLevel) > vw)
	{
		// 1、水平瓦片坐标控制:判断最左侧瓦片是否完全进入视口、最右侧瓦片是否完全离开视口
		if (topLeftViewPos.x() > 0)
		{
			int count = qCeil(topLeftViewPos.x() / PIXMAP_SIZE);			// 左侧进入视口瓦片数量
			m_topLeftTileCoord.x = qMax(m_topLeftTileCoord.x - count, 0);	// 更新现左侧瓦片坐标X
		}

		if (bottomRightViewPos.x() > vw)
		{
			int count = qFloor((bottomRightViewPos.x() - vw) / PIXMAP_SIZE) + 1;	// 右侧离开视口瓦片数量
			m_bottomRightTileCoord.x = qMax(m_bottomRightTileCoord.x - count, 0);	// 更新现右侧瓦片坐标X
		}

		// 2、水平瓦片坐标控制:判断最右侧瓦片是否完全进入视口、最左侧瓦片是否完全离开视口
		if (bottomRightViewPos.x() + PIXMAP_SIZE < vw)
		{
			int count = qCeil((vw - (bottomRightViewPos.x() + PIXMAP_SIZE)) / PIXMAP_SIZE);			// 右侧进入视口瓦片数量
			m_bottomRightTileCoord.x = qMin(m_bottomRightTileCoord.x + count, mapSideCount - 1);	// 保存现右侧瓦片坐标X
		}

		if (topLeftViewPos.x() + PIXMAP_SIZE < 0)
		{
			int count = qFloor(fabs(topLeftViewPos.x()) / PIXMAP_SIZE);						// 左侧离开视口瓦片数量
			m_topLeftTileCoord.x = qMin(m_topLeftTileCoord.x + count, mapSideCount - 1);	// 保存现左侧瓦片坐标X
		}
	}

	if (MapUtility::sceneSize(m_curLevel) > vh)
	{
		// 3、垂直瓦片坐标控制:判断最上侧瓦片是否完全进入视口,最下侧瓦片是否完全离开视口
		if (topLeftViewPos.y() > 0)
		{
			int count = qCeil(topLeftViewPos.y() / PIXMAP_SIZE);			// 上侧进入视口瓦片数量
			m_topLeftTileCoord.y = qMax(m_topLeftTileCoord.y - count, 0);	// 保存现上侧瓦片坐标Y
		}

		if (bottomRightViewPos.y() > vh)
		{
			int count = qFloor((bottomRightViewPos.y() - vh) / PIXMAP_SIZE) + 1;	// 下侧离开视口瓦片数量
			m_bottomRightTileCoord.y = qMax(m_bottomRightTileCoord.y - count, 0);	// 保存现下侧瓦片坐标Y
		}

		// 4、垂直瓦片坐标控制:判断最下侧瓦片是否完全进入视口,最上侧瓦片是否完全离开视口
		if (bottomRightViewPos.y() + PIXMAP_SIZE < vh)
		{
			int count = qCeil((vh - (bottomRightViewPos.y() + PIXMAP_SIZE)) / PIXMAP_SIZE);			// 下侧进入视口瓦片数量
			m_bottomRightTileCoord.y = qMin(m_bottomRightTileCoord.y + count, mapSideCount - 1);	// 保存现下侧瓦片坐标Y
		}

		if (topLeftViewPos.y() + PIXMAP_SIZE < 0)
		{
			int count = qFloor(fabs(topLeftViewPos.y()) / PIXMAP_SIZE);						// 上侧离开视口瓦片数量
			m_topLeftTileCoord.y = qMin(m_topLeftTileCoord.y + count, mapSideCount - 1);	// 保存现上侧瓦片坐标Y
		}
	}

	// 获取移动前瓦片集合
	vector<TileCoord> vecOldTileCoord;
	for (int row = m_viewAndAroundTileRect.top(); row <= m_viewAndAroundTileRect.bottom(); ++row)
	{
		for (int col = m_viewAndAroundTileRect.left(); col <= m_viewAndAroundTileRect.right(); ++col)
		{
			vecOldTileCoord.push_back(TileCoord(col, row));
		}
	}

	// 获取移动后瓦片集合
	vector<TileCoord> vecNewTileCoord, vecAddTileCoord;
	m_viewAndAroundTileRect = CommonUtility::getViewAndAroundTileCoords(m_topLeftTileCoord.y, m_topLeftTileCoord.x, m_bottomRightTileCoord.y, m_bottomRightTileCoord.x, m_curLevel, vecNewTileCoord);
	for (const auto &tc : vecNewTileCoord)
	{
		// ①筛除已加载过的瓦片 ②线程加载存在滞后性,第二次移动时可能第一次m_tileItems还没有加载完毕,所以需要前一次范围作为过滤
		if (!m_tileItems.contains(tc) && std::find(vecOldTileCoord.begin(), vecOldTileCoord.end(), tc) == vecOldTileCoord.end())
		{
			vecAddTileCoord.push_back(tc);
		}
	}

	//showTileCoord();
	showGraticules();
	
	// 上方即为计算瓦片索引的核心代码,省略下方加载瓦片的代码...
	// 加载瓦片代码...
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Day 26 数据库日志管理

数据库日志管理 一&#xff1a;日志管理 1.日志分类 ​ 错误日志 &#xff1a;启动&#xff0c;停止&#xff0c;关闭失败报错。rpm安装日志位置 /var/log/mysqld.log ​ 通用查询日志&#xff1a;所有的查询都记下来 ​ 二进制日志&#xff1a;实现备份&#xff0c;增量备份…

开发组合php+mysql 人才招聘小程序源码搭建 招聘平台系统源码+详细图文搭建部署教程

随着互联网的快速发展&#xff0c;传统的招聘方式已经不能满足企业和求职者的需求。为了提高招聘效率&#xff0c;降低招聘成本&#xff0c;越来越多的人开始关注人才招聘小程序、在线招聘平台。分享一个人才招聘小程序源码及搭建&#xff0c;让招聘更加高效便捷。系统是运营级…

什么是光伏发电?什么是分布式光伏系统?

一、光伏发电 光伏发电&#xff0c;作为一种可再生能源利用技术&#xff0c;其核心原理基于半导体的光生伏特效应。简而言之&#xff0c;光伏发电就是将太阳能直接转换为电能的过程。它由三个主要部分组成&#xff1a;太阳电池板&#xff08;组件&#xff09;、控制器和逆变器…

STM32F10x移植FreeRTOS

一、获取FreeRTOS源码 &#xff08;1&#xff09;登录FreeRTOS官网&#xff1a;www.freertos.org&#xff0c;下载第一个压缩包 &#xff08;2&#xff09;通过GitHub网站&#xff1a;github.com/FreeRTOS/FreeRTOS下载&#xff0c;由于该网站服务器在国外&#xff0c;所以访问…

回归预测 | Matlab实现基于CNN-SE-Attention-ITCN多特征输入回归组合预测算法

回归预测 | Matlab实现基于CNN-SE-Attention-ITCN多特征输入回归组合预测算法 目录 回归预测 | Matlab实现基于CNN-SE-Attention-ITCN多特征输入回归组合预测算法预测效果基本介绍程序设计参考资料 预测效果 基本介绍 【模型简介】CNN-SE_Attention结合了卷积神经网络&#xff…

好消息|5月6日起换发补发出入境证件可“全程网办”

国家移民管理局从2024年5月6日起&#xff0c;实施若干便民利企出入境管理的六项政策措施&#xff0c;包括在北京等20个城市试点实行换发补发出入境证件的“全程网办”&#xff0c;该举措对于访问学者、博士后研究人员及联合培养博士都是利好消息。故知识人网小编转载发布。 为更…

自动语音识别

⚠申明&#xff1a; 未经许可&#xff0c;禁止以任何形式转载&#xff0c;若要引用&#xff0c;请标注链接地址。 全文共计3077字&#xff0c;阅读大概需要3分钟 &#x1f308;更多学习内容&#xff0c; 欢迎&#x1f44f;关注&#x1f440;【文末】我的个人微信公众号&#xf…

恭喜发财!东方第一 MEME 拥抱符文

第 431 号符文 HOPE•YOU•GET•RICH &#x1f9e7;&#xff0c;是 Omnity 首个支持的跨链 Runes 资产&#xff0c;也是TG群里红包小程序支持的第一个 Runes 资产。 大家可以在 Omnity 的 TG 群和 RunesCC 的 TG 群里&#xff0c;不定时的抢到符文红包。 Omnity TG&#xff1a;…

Git系列:git push (-u) 与 git branch (-u)

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

W801学习笔记二十二:英语背单词学习应用——下

续上篇&#xff1a; W801学习笔记二十一&#xff1a;英语背单词学习应用——上 五、处理用户交互 由于英语也是采用了和唐诗一样的《三分钟限时挑战》《五十题竞速挑战》《零错误闯关挑战》&#xff0c;所以用户交互的逻辑和唐诗是一样的。所以&#xff0c;我们抽一个基类&a…

热敏电阻怎么进行性能测试?并以LabVIEW为例进行说明

过程也可用于执行热敏电阻测量。RTD和热敏电阻遵循非常相似的功能原理&#xff0c;测量步骤与下面提供的步骤相同。有关热敏电阻的更多信息&#xff0c;请参阅本文档。 查找设备引脚排列 在连接任何信号之前&#xff0c;请找到您的设备引脚排列。 打开NI MAX并展开设备和接口。…

ETLCloud工具怎么实现多流SQL实时运算?

多流SQL实时运算的特点和应用场景 多流SQL实时运算是一种先进的数据处理技术&#xff0c;它在大数据处理领域中扮演着至关重要的角色&#xff0c;尤其是在需要对多个数据流进行实时分析和处理的应用场景中。该技术结合了SQL&#xff08;结构化查询语言&#xff09;的易用性和流…

【计算机毕业设计】基于SSM++jsp的网络游戏公司官方平台系统【源码+lw+部署文档+讲解】

目录 第1章 绪论 1.1 课题背景 1.2 课题意义 1.3 研究内容 第2章 开发环境与技术 2.1 MYSQL数据库 2.2 JSP技术 2.3 SSM框架 第3章 系统分析 3.1 可行性分析 3.1.1 技术可行性 3.1.2 经济可行性 3.1.3 操作可行性 3.2 系统流程 3.2.1 操作流程 3.2.2 登录流程 3.2.3 删除信息流…

Redis 入坑基本指南

引言 本指南将帮助您了解如何安装、配置和基本使用 Redis。Redis 是一款开源的高性能键值存储系统&#xff0c;可用于缓存、数据库、消息中间件等多种用途。 1. 安装 Redis a. 下载 Redis&#xff1a; 可以从 Redis 官方网站&#xff08;https://redis.io&#xff09;下载最…

GORM 与 MySQL(一)

GORM 操作 Mysql 数据库&#xff08;一&#xff09; 温馨提示&#xff1a;以下关于 GORM 的使用&#xff0c;是基于 Gin 框架的基础上&#xff0c;如果之前没有了解过 Gin 可能略微困难。 GORM 介绍 GORM 是 Golang 的一个 orm 框架。简单说&#xff0c;ORM 就是通过实例对象…

Ubuntu18.04设置SSH密钥登录

我们一般使用 VSCode 、MobaXterm、PuTTY等 SSH 客户端来远程管理 Linux 服务器。但是&#xff0c;一般的密码方式登录&#xff0c;容易有密码被暴力破解的问题。所以&#xff0c;一般我们会将 SSH 的端口设置为默认的 22 以外的端口&#xff0c;或者禁用 root 账户登录。但是即…

解决ImportError: cannot import name ‘xxx‘ from partially initialized module xxx

python项目中某个文件名与需要引入的module中的文件名相同时&#xff0c;可能出现循环引用的情况&#xff0c;此时会报错ImportError: cannot import name ‘xxx‘ from partially initialized module xxx。 所以把项目文件中涉及 报错内容的python文件名 修改即可。 如我的…

剧本杀小程序,为商家带来更多收益

剧本杀作为一种社交类游戏&#xff0c;关注度越来越高&#xff0c;目前&#xff0c;市场上剧本杀依然呈现上升发展趋势。 不过当下&#xff0c;在剧本杀市场中&#xff0c;大部分商家都开始使用小程序管理运营剧本杀。相对于线下剧本杀&#xff0c;线上剧本杀小程序便于商家管…

「51媒体」企业单位新闻稿件考核,怎么发布

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 电力税务企事业单位部门等单位提供了新闻稿件&#xff0c;如何在一些重点媒体进行宣发呢&#xff1a; 精准锁定发布媒体 了解考核要求&#xff1a;仔细阅读宣传任务名单&#xff0c;了解…

探索GitHub上的GPTs项目:泄露和被破解的GPT提示

GPTs项目是一个在GitHub上由用户linexjlin发起的开源项目&#xff0c;专注于提供泄露的GPT&#xff08;生成式预训练转换器&#xff09;提示。这些提示用于指导和优化AI模型的输出&#xff0c;进而提升代码生成的质量和效率。项目页面提供了丰富的功能和资源&#xff0c;旨在帮…
最新文章