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

租赁网站空间更换怎么做成功营销十大经典案例

租赁网站空间更换怎么做,成功营销十大经典案例,关于国际贸易的网站,武汉光谷空轨C(Qt)-GIS开发-QGraphicsView显示瓦片地图简单示例 文章目录 C(Qt)-GIS开发-QGraphicsView显示瓦片地图简单示例1、概述2、实现效果3、主要代码4、源码地址 更多精彩内容👉个人内容分类汇总 👈👉GIS开发 👈 1、概述 支持多线程加…

C++(Qt)-GIS开发-QGraphicsView显示瓦片地图简单示例

文章目录

  • C++(Qt)-GIS开发-QGraphicsView显示瓦片地图简单示例
    • 1、概述
    • 2、实现效果
    • 3、主要代码
    • 4、源码地址

更多精彩内容
👉个人内容分类汇总 👈
👉GIS开发 👈

1、概述

  1. 支持多线程加载显示本地离线瓦片地图(墨卡托投影);
  2. 瓦片切片规则以左上角为原点(谷歌、高德、ArcGis等),不支持百度瓦片规则;
  3. 支持显示瓦片网格、编号信息。
  4. 支持鼠标滚轮缩放切换地图层级。
  5. 支持鼠标拖拽。
  6. 采用z/x/y层级瓦片存储格式。
  7. 在单文件中实现所有主要功能,简单便于理解。
  8. 以QGraphicsView原点为起始位置,将加载的第一张瓦片显示在原点,其它瓦片相对于第一张瓦片进行显示【相对像素坐标】。

开发环境说明

  • 系统:Windows11、Ubuntu20.04
  • Qt版本:Qt 5.14.2
  • 编译器:MSVC2017-64、GCC/G++64

2、实现效果

使用瓦片地图工具下载z/x/y存储格式的瓦片地图进行显示。

在这里插入图片描述

3、主要代码

  • mapgraphicsview.h文件

    #ifndef MAPGRAPHICSVIEW_H
    #define MAPGRAPHICSVIEW_H#include <QGraphicsView>
    #include <QGraphicsScene>
    #include <QFuture>class MapGraphicsView : public QGraphicsView
    {Q_OBJECT
    public:explicit MapGraphicsView(QWidget *parent = nullptr);~MapGraphicsView();void setPath(const QString& path);void quit();protected:void wheelEvent(QWheelEvent *event) override;signals:void addImage(QPixmap img, QPoint pos);
    private:void getMapLevel();     // 获取路径中瓦片地图的层级void getTitle();        // 获取路径中瓦片地图编号void loatImage();       // 加载瓦片void clearReset();       // 清除重置所有内容int getKey();          // 获取当前显示的层级key值void on_addImage(QPixmap img, QPoint pos);private:QGraphicsScene* m_scene = nullptr;QString m_path;          // 瓦片地图文件路径QHash<int, QGraphicsItemGroup*> m_mapItemGroups;     // 存放地图图元组的数组,以瓦片层级为keyQGraphicsItemGroup* m_mapitemGroup = nullptr;        // 当前显示层级图元QHash<int, QGraphicsItemGroup*> m_gridItemGroups;    // 存放地图网格图元组的数组,以瓦片层级为keyQGraphicsItemGroup* m_griditemGroup = nullptr;       // 当前显示层级网格图元int m_keyIndex = 0;               // 当前显示的瓦片层级QVector<QPoint> m_imgTitle;       // 保存图片编号QFuture<void> m_future;
    };#endif // MAPGRAPHICSVIEW_H
  • mapgraphicsview.cpp文件

    #include "mapgraphicsview.h"#include <QDir>
    #include <QDebug>
    #include <QGraphicsItemGroup>
    #include <QtConcurrent>
    #include <QWheelEvent>MapGraphicsView* g_this = nullptr;
    MapGraphicsView::MapGraphicsView(QWidget *parent) : QGraphicsView(parent)
    {m_scene = new QGraphicsScene(this);this->setScene(m_scene);g_this = this;connect(this, &MapGraphicsView::addImage, this, &MapGraphicsView::on_addImage);this->setDragMode(QGraphicsView::ScrollHandDrag);      // 设置鼠标拖拽
    //    QThreadPool::globalInstance()->setMaxThreadCount(1);   // 可以设置线程池线程数
    }MapGraphicsView::~MapGraphicsView()
    {g_this = nullptr;quit();   // 如果程序退出时还在调用map就会报错,所以需要关闭
    }/*** @brief 退出多线程*/
    void MapGraphicsView::quit()
    {if(m_future.isRunning())   // 判断是否在运行{m_future.cancel();               // 取消多线程m_future.waitForFinished();      // 等待退出}
    }/*** @brief       设置加载显示的瓦片地图路径* @param path*/
    void MapGraphicsView::setPath(const QString &path)
    {if(path.isEmpty()) return;m_path = path;getMapLevel();      // 获取瓦片层级loatImage();        // 加载第一层瓦片
    }/*** @brief        鼠标缩放地图* @param event*/
    void MapGraphicsView::wheelEvent(QWheelEvent *event)
    {QGraphicsView::wheelEvent(event);if(m_future.isRunning())   // 判断是否在运行{return;}if(event->angleDelta().y() > 0)   // 放大{if(m_keyIndex < m_mapItemGroups.count() -1){m_keyIndex++;}}else{if(m_keyIndex > 0){m_keyIndex--;}}loatImage();        // 加载新的层级瓦片
    }/*** @brief 计算瓦片层级*/
    void MapGraphicsView::getMapLevel()
    {if(m_path.isEmpty()) return;clearReset();    // 加载新瓦片路径时将之前的内容清空QDir dir(m_path);dir.setFilter(QDir::Dirs | QDir::NoDotAndDotDot);    // 设置过滤类型为文件夹,且不包含隐藏文件夹dir.setSorting(QDir::Name);                          // 设置按文件夹名称排序QStringList dirs = dir.entryList();for(auto& strDir : dirs){bool ok;int level = strDir.toInt(&ok);if(ok){if(!m_mapItemGroups.contains(level))  // 如果不包含{// 初始化加载所有瓦片层级到场景中,默认不显示QGraphicsItemGroup* itemMap = new QGraphicsItemGroup();m_scene->addItem(itemMap);itemMap->setVisible(false);m_mapItemGroups[level] = itemMap;// 初始化加载所有瓦片层级网格到场景中,默认不显示QGraphicsItemGroup* itemGrid = new QGraphicsItemGroup();m_scene->addItem(itemGrid);itemGrid->setVisible(false);m_gridItemGroups[level] = itemGrid;}}}
    }/*** @brief 获取当前显示层级中所有瓦片的编号*/
    void MapGraphicsView::getTitle()
    {QString path = m_path + QString("/%1").arg(getKey());    // z  第一层文件夹QDir dir(path);dir.setFilter(QDir::Dirs | QDir::NoDotAndDotDot);    // 设置过滤类型为文件夹,且不包含隐藏文件夹dir.setSorting(QDir::Name);                          // 设置按文件夹名称排序QStringList dirs = dir.entryList();QPoint point;for(auto& strDir : dirs){bool ok;int x = strDir.toInt(&ok);                         // x层级 第二层文件夹if(ok){point.setX(x);dir.setPath(path + QString("/%1").arg(x));dir.setFilter(QDir::Files | QDir::NoDotAndDotDot);    // 设置过滤类型为文件,且不包含隐藏文件dir.setSorting(QDir::Name);                           // 设置按文件夹名称排序QStringList files = dir.entryList();for(auto& file: files){int y = file.split('.').at(0).toInt(&ok);   // 去除后缀,以文件名为yif(ok){point.setY(y);m_imgTitle.append(point);}}}}
    }QString g_path;   // 保存当前层级路径
    /*** @brief       在多线程中加载图片* @param point*/
    void readImg(const QPoint& point)
    {QString path = QString("%1/%2/%3.jpg").arg(g_path).arg(point.x()).arg(point.y());QPixmap image;if(image.load(path)){if(g_this){emit g_this->addImage(image, point);   // 由于不能在子线程中访问ui,所以这里通过信号将图片传递到ui线程进行绘制}}
    //    QThread::msleep(50);     // 加载时加上延时可以更加清晰的看到加载过程
    }/*** @brief 加载显示瓦片图元*/
    void MapGraphicsView::loatImage()
    {quit();                  // 加载新瓦片之前判断是否还有线程在运行m_imgTitle.clear();if(m_mapitemGroup){m_mapitemGroup->setVisible(false);        // 隐藏图层m_griditemGroup->setVisible(false);       // 隐藏图层}m_mapitemGroup = m_mapItemGroups.value(getKey());m_griditemGroup = m_gridItemGroups.value(getKey());if(!m_mapitemGroup || !m_griditemGroup) return;if(m_mapitemGroup->boundingRect().isEmpty())   // 如果图元为空则加载图元显示{getTitle();      // 获取新层级的所有瓦片编号g_path = m_path + QString("/%1").arg(getKey());m_future = QtConcurrent::map(m_imgTitle, readImg);}m_mapitemGroup->setVisible(true);              // 显示新瓦片图层m_griditemGroup->setVisible(true);             // 显示新网格图层m_scene->setSceneRect(m_mapitemGroup->boundingRect());   // 根据图元大小自适应调整场景大小
    }/*** @brief 清除重置所有内容*/
    void MapGraphicsView::clearReset()
    {if(m_mapItemGroups.isEmpty()) return;m_keyIndex = 0;m_mapitemGroup = nullptr;m_griditemGroup = nullptr;m_imgTitle.clear();QList<int>keys = m_mapItemGroups.keys();for(auto key : keys){// 清除瓦片图元QGraphicsItemGroup* item = m_mapItemGroups.value(key);m_scene->removeItem(item);    // 从场景中移除图元delete item;m_mapItemGroups.remove(key);   // 从哈希表中移除图元// 清除网格item = m_gridItemGroups.value(key);m_scene->removeItem(item);     // 从场景中移除图元delete item;m_gridItemGroups.remove(key);   // 从哈希表中移除图元}
    }/*** @brief   获取当前层级的key值* @return  返回-1表示不存在*/
    int MapGraphicsView::getKey()
    {if(m_mapItemGroups.isEmpty()) return -1;QList<int>keys = m_mapItemGroups.keys();std::sort(keys.begin(), keys.end());    // 由于keys不是升序的,所以需要进行排序if(m_keyIndex < 0 || m_keyIndex >= keys.count()){return -1;}return keys.at(m_keyIndex);
    }/*** @brief       绘制地图瓦片图元* @param img   显示的图片* @param pos   图片显示的位置*/
    void MapGraphicsView::on_addImage(QPixmap img, QPoint pos)
    {if(!m_mapitemGroup || m_imgTitle.isEmpty()){return;}// 计算瓦片显示位置,默认为256*256的瓦片大小QPoint& begin = m_imgTitle.first();int x = (pos.x() - begin.x()) * 256;int y = (pos.y() - begin.y()) * 256;// 绘制瓦片QGraphicsPixmapItem* itemImg = new QGraphicsPixmapItem(img);itemImg->setPos(x, y);   // 以第一张瓦片为原点m_mapitemGroup->addToGroup(itemImg);// 绘制网格、QGraphicsRectItem* itemRect = new QGraphicsRectItem(x, y, 256, 256);m_griditemGroup->addToGroup(itemRect);itemRect->setPen(QPen(Qt::red));// 绘制编号QString text = QString("%1,%2,%3").arg(pos.x()).arg(pos.y()).arg(getKey());QGraphicsSimpleTextItem* itemText = new QGraphicsSimpleTextItem(text);QFont font;font.setPointSize(14);                           // 设置字体大小为12QFontMetrics metrics(font);qreal w = metrics.horizontalAdvance(text) / 2.0; // 计算字符串宽度qreal h = metrics.height() / 2.0;               // 字符串高度itemText->setPos(x + 128 - w, y + 128 - h);     // 编号居中显示itemText->setFont(font);itemText->setPen(QPen(Qt::red));m_griditemGroup->addToGroup(itemText);m_scene->setSceneRect(m_mapitemGroup->boundingRect());   // 根据图元大小自适应调整场景大小
    }

4、源码地址

  • github
  • gitee

文章转载自:
http://adventitious.mrfr.cn
http://koel.mrfr.cn
http://graphomania.mrfr.cn
http://freezer.mrfr.cn
http://caleche.mrfr.cn
http://overseas.mrfr.cn
http://drumbeating.mrfr.cn
http://clever.mrfr.cn
http://meteor.mrfr.cn
http://pen.mrfr.cn
http://baptize.mrfr.cn
http://refitment.mrfr.cn
http://indigently.mrfr.cn
http://chromite.mrfr.cn
http://downy.mrfr.cn
http://anne.mrfr.cn
http://salve.mrfr.cn
http://polycystic.mrfr.cn
http://matroclinous.mrfr.cn
http://computerize.mrfr.cn
http://questura.mrfr.cn
http://ratch.mrfr.cn
http://chlorinous.mrfr.cn
http://parable.mrfr.cn
http://dreamland.mrfr.cn
http://rammish.mrfr.cn
http://okro.mrfr.cn
http://spindling.mrfr.cn
http://cybernetical.mrfr.cn
http://magnetodisk.mrfr.cn
http://noncom.mrfr.cn
http://asphaltic.mrfr.cn
http://find.mrfr.cn
http://pinwale.mrfr.cn
http://personae.mrfr.cn
http://zingiberaceous.mrfr.cn
http://addlepate.mrfr.cn
http://homecoming.mrfr.cn
http://tlac.mrfr.cn
http://gymnastic.mrfr.cn
http://flow.mrfr.cn
http://ither.mrfr.cn
http://nappy.mrfr.cn
http://cotarnine.mrfr.cn
http://abusively.mrfr.cn
http://orinasal.mrfr.cn
http://gleg.mrfr.cn
http://nicy.mrfr.cn
http://touse.mrfr.cn
http://cognise.mrfr.cn
http://toposcopy.mrfr.cn
http://ctenophoran.mrfr.cn
http://hielamon.mrfr.cn
http://crayon.mrfr.cn
http://prototrophic.mrfr.cn
http://kunzite.mrfr.cn
http://modify.mrfr.cn
http://aurification.mrfr.cn
http://certain.mrfr.cn
http://demisemi.mrfr.cn
http://orion.mrfr.cn
http://hypergolic.mrfr.cn
http://pubsy.mrfr.cn
http://encapsidate.mrfr.cn
http://suntan.mrfr.cn
http://cyclosis.mrfr.cn
http://atonic.mrfr.cn
http://washiness.mrfr.cn
http://bearbaiting.mrfr.cn
http://innumerous.mrfr.cn
http://osb.mrfr.cn
http://uscgr.mrfr.cn
http://shamus.mrfr.cn
http://alignment.mrfr.cn
http://puzzlement.mrfr.cn
http://veronica.mrfr.cn
http://polyethnic.mrfr.cn
http://pyrometry.mrfr.cn
http://seabeach.mrfr.cn
http://defaulter.mrfr.cn
http://sealflower.mrfr.cn
http://euphemious.mrfr.cn
http://laxness.mrfr.cn
http://trithing.mrfr.cn
http://ponderation.mrfr.cn
http://decruit.mrfr.cn
http://retinocerebral.mrfr.cn
http://technologically.mrfr.cn
http://atop.mrfr.cn
http://moabite.mrfr.cn
http://groundsill.mrfr.cn
http://loftiness.mrfr.cn
http://frontenis.mrfr.cn
http://evictee.mrfr.cn
http://flokati.mrfr.cn
http://foliicolous.mrfr.cn
http://expertize.mrfr.cn
http://reactant.mrfr.cn
http://redeeming.mrfr.cn
http://scramjet.mrfr.cn
http://www.dt0577.cn/news/116643.html

相关文章:

  • 濮阳网站公司网络推广公司哪家做得好
  • 做自我介绍的网站的图片素材760关键词排名查询
  • 福建建设工程交易中心网站如何提交百度收录
  • 宝安中心区范围上海百度移动关键词排名优化
  • 网站建设项目报价新公司如何做推广
  • 返利网站怎么做南昌网优化seo公司
  • 营销型网站具备的二大能力百度售后电话人工服务
  • 营销型网站的建设重点是什么互联网营销培训
  • 有关风景的网页设计作业成都网站seo费用
  • wordpress 免插件实现seo技术服务外包
  • 做电子的外单网站有哪些的深圳龙岗区布吉街道
  • 品牌营销型网站建设泰安做网站公司
  • 建一个国外网站多少钱朋友圈广告代理商官网
  • 学做软件和网站需要知识长沙疫情最新情况
  • 牌具做网站可以吗seo关键词推广话术
  • 惠州免费自助建站模板网络营销是以什么为中心
  • 镇江积分优化淄博seo公司
  • 邢台做网站推广找谁营销型网站策划书
  • 郑州hi宝贝网站建设公司河南百度推广代理商
  • 找不同 网站开发杭州网站推广公司
  • 深圳哪些设计公司做网站比较出名自己搭建网站
  • 网站的分页效果怎么做百度热搜榜排行
  • 游戏软件开发属于什么专业做神马seo快速排名软件
  • 安康网站建设公司价格网站seo工具
  • 厦门网站设计公司找哪家厦门小程序建设东莞网站制作外包
  • 做外贸网站功能重庆seo优化公司
  • 专门做评测的网站有哪些企业推广网站
  • 新公司在哪做网站seo综合查询怎么进入网站
  • 安徽省工程信息网官网厦门关键词排名优化
  • 网站模板名称沧州seo推广