QGIS二次开发02:交互动作实现

2023-11-09

地图交互动作就是通过鼠标操作与地图间的互动。动作包括按下(press)、按键弹起(release)、鼠标移动(move)、双击等等。

QGIS实现地图的交互主要是通过继承QgsMapTool这个类实现,目前集成了QgsMapToolZoom(拉框缩放)、QgsMapToolPan(地图移动)、QgsMapToolEmitPoint(点击地图)、QgsMapToolExtent(拉框)、QgsMapToolEdit(交互编辑)、QgsMapToolIdentify(点击矢量要素)。

这些个性动作主要是实现了QgsMapTool的几个接口:

virtual void  canvasDoubleClickEvent (QgsMapMouseEvent *e)
双击鼠标
virtual void  canvasMoveEvent (QgsMapMouseEvent *e)
鼠标移动
virtual void  canvasPressEvent (QgsMapMouseEvent *e)
鼠标按下
virtual void  canvasReleaseEvent (QgsMapMouseEvent *e)
鼠标抬起

下面我们将通过一个封装类实现点击画点的交互动作

一、思路

动作逻辑:点击地图->获取点击处的坐标->绘制地图

实现:继承QgsMapToolEmitPint,实现canvasReleaseEvent即可,如下:

void SHQgsMapToolEmitPoint::canvasReleaseEvent(QgsMapMouseEvent *e){    
    QgsMapToolEmitPoint::canvasReleaseEvent(e);
    if(!mMapCanvas)return;
    QgsRubberBand *rb = new QgsRubberBand(mMapCanvas,QgsWkbTypes::PointGeometry);
    rb->setSize(100);
    rb->setColor(QColor(255,0,0));
    rb->addPoint(e->mapPoint);    //画点
}

二、进阶

如果我们现在有个新的需求,比如实现点击获取坐标,显然我们依照上面的思路通过再继承QgsMapToolEmitPoint也可以实现。但很明显“点击画点”和“点击获取坐标"的实现基本都差不多,区别仅仅在于最后一步的实现不同而已。能否再抽象,实现更佳的封装和调用呢。答案是明显了,思路:

1、定义不同的交互动作

2、设置动作

3、点击时发送信号传送坐标

4、在槽函数中根据动作不同对坐标进行不同处理,从而实现点击获取坐标和点击绘制

如下:

第一步:定义动作

enum MapAction{
        Null,               //无动作
        PointClick,         //点击
        DrawPoint,          //绘制点
    };
    Q_ENUM(MapAction);

第二步:setAction定义和实现,信号和槽函数关联

//mAction用来记录当前动作的成员变量

void MyTest::setAction(MapAction action){
    if(action==MapAction::PointClick || action==MapAction::DrawPoint){
        mAction = action;
        if(!this->mEmitPointTool){
            this->mEmitPointTool = new MyQgsMapToolEmitPoint(this->m_mapCanvas);    connect(mEmitPointTool,SIGNAL(signal_point_click(QgsPointXY)),this,SLOT(handlePointClickEvent(QgsPointXY)));
        }
        this->m_mapCanvas->setMapTool(this->mEmitPointTool);
    }else{
        mAction = MapAction::Null;
        QgsMapTool *tool = this->m_mapCanvas->mapTool();
        this->m_mapCanvas->unsetMapTool(tool);
    }

}

实现点击类,增加坐标的返回

//重载canvasReleaseEvent,实现信号signal_point_click的发送,传递回点击处坐标

void MyMapToolEmitPoint::canvasReleaseEvent(QgsMapMouseEvent *e){    
    QgsMapToolEmitPoint::canvasReleaseEvent(e);
    if(!mMapCanvas)return;
    emit signal_point_click(e->mapPoint);
}

第三步:实例化MyMapToolEmitPoint,并作为成员变量

//m_mapCanvas是地图画布指针
MyQgsMapToolEmitPoint mEmitPointTool = new MyQgsMapToolEmitPoint(this->m_mapCanvas);

第四步:槽函数实现

/**
 * 处理点击事件
 * @brief SHQgisMap2DHandler::handlePointClickEvent
 * @param xy
 */
void SHQgisMap2DHandler::handlePointClickEvent(QgsPointXY xy){

    if(m_action==SHMapAction::MapAction::PointClick)    {
        QString msg = QString("%1").arg(xy.x());
        msg += QString(",%1").arg(xy.y());
        QDebug<<msg;
    }else if(m_action==SHMapAction::MapAction::DrawPoint)
    {
        QgsRubberBand *rb = new QgsRubberBand(m_mapCanvas,QgsWkbTypes::PointGeometry);
        rb->setSize(100);
        rb->setColor(QColor(200,0,0));
        rb->addPoint(xy);        
    }

}

第五步:调用

setAction(MapAction::DrawPoint);

设置点击画点动作,在地图上点击即可以绘制点对象。

三、再进阶

实现交互动作后的回调,如setAction(xxx,myCallBack);

思路:1、定义一个回调类,比如MyCallBack,里面有不同的实现的回调函数callback

           2、在上面的槽函数里调用具体的回调函数callback即可

当然用信号和槽函数也可以实现类似。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

QGIS二次开发02:交互动作实现 的相关文章

  • MVC 重定向到没有控制器的视图

    希望应该是一个简单的 我创建了一个通用错误视图 当整个站点的操作方法内发生异常时 我想显示该视图 我创建了一个部分页面 所有导航都位于其中 因此我不需要在此视图上使用控制器 那么如何从控制器内的操作方法重定向到它 像这样的东西 HttpPo
  • 更快的算法来计算有多少数字可以被范围内的特定整数整除

    int a b c d 0 cin gt gt a gt gt b gt gt c for int i a i lt b i if i c 0 d cout lt
  • 切换图片框可见性 C#

    为什么图片框控件的可见性属性在这里不起作用 我最初将它们设置为 false 以便在屏幕加载时它们不可见 但后来我想切换这个 我已完成以下操作 但似乎不起作用 这是一个 Windows 窗体应用程序 private void Action w
  • C# 中的协变和逆变

    首先我要说的是 我是一名正在学习 C 编程的 Java 开发人员 因此 我会将我所知道的与我正在学习的进行比较 我已经使用 C 泛型几个小时了 我已经能够在 C 中重现我在 Java 中知道的相同内容 除了几个使用协变和逆变的示例 我正在读
  • 使用不带参数的 Split() 时,默认分隔符是什么?

    所以我看了看String Split 今天 C 中的方法 我意识到你也可以向它传递零参数 这是我从未考虑过的 使用时默认的分隔符是什么Split 没有任何参数 如果没有值 则为空白 来源自here https msdn microsoft
  • QT:模块“QtWebView”未安装

    我的操作系统是win10 QT版本是Qt5 7 mingw53 32 目标操作系统是win10 当我使用qmlscene执行qml文件时 发生了一些错误 qrc qml 3 模块 QtWebView 未安装 我的 qml 文件如下 impo
  • 将成员函数作为参数传递/c++

    我想用 C 实现一个类b可以通过封装该迭代器类型的成员集进行某种迭代 喜欢 b object for each x do function f so 函数 f会得到每个人的x成员并做任何事情 比方说 void function f x me
  • 特定设备的不同字体大小

    我目前正在开发通用应用程序 我需要分别处理移动设备和桌面的文本框字体大小 我找到了一些方法 但都不能解决问题 使用 VisualStateManager 和 StateTrigger 为例
  • .net Framework (.net 4.0) 中定义 Base 3 数字的类

    我正在寻找一些可以用来定义 3 基数 三进制数 的类 有什么我可以在 net 框架中使用的东西或者我需要写一些东西吗 谢谢你的帮助 您可以使用解析Convert ToInt32 s base http msdn microsoft com
  • 用 C# 制作 Vista 风格的应用程序

    我正在运行 Windows Vista 并且希望外观看起来像常规 Vista 程序 有没有关于如何构建 Vista 风格应用程序的真正好的教程 文章 我还想学习如何使用本机代码并将其转换为 C 如this http bartdesmet n
  • 指示泛型返回动态类型的对象

    这个问题是我原来问题的后续问题here https stackoverflow com questions 2541184 using a type object to create a generic 假设我有以下泛型类 简化 class
  • 在“using”语句中使用各种类型 (C#)

    自从C usingstatements只是try finally dispose 的语法糖 为什么它接受多个对象仅当它们属于同一类型时 我不明白 因为它们需要的只是 IDisposable 如果它们都实现 IDisposable 应该没问题
  • 为什么WCF中不允许方法重载?

    假设这是一个ServiceContract ServiceContract public interface MyService OperationContract int Sum int x int y OperationContract
  • 使用 qbs 构建 qt 应用程序

    我想知道在 Linux 上使用 qbs 编译 构建和创建 Android Qt 应用程序的步骤 我拥有所有必要的工具 目前我可以使用 qmake 创建 apk Qbs 目前不支持构建 Qt Android 应用程序 Qbs v1 4 中引入
  • QML MouseArea 将事件传播到按钮

    我正在开发一个应用程序 其菜单类似于 Android 版 Gmail 收件箱应用程序菜单 基本上 当您按下按钮打开菜单时 它就会滑入视图 用户可以将其滑开或按菜单上的按钮 对于滑动我使用了代码SwipeArea from kovrov ht
  • 是什么原因导致 Linq 错误:此方法无法转换为存储表达式?

    我有一堆具有相同 select 语句的 Linq to Entity 方法 所以我想我会很聪明 并将其分离到它自己的方法中以减少冗余 但是当我尝试运行代码时 我得到了以下内容错误 该方法不能转化为 商店表达式 这是我创建的方法 public
  • `cosf`、`sinf` 等不在 `std` 中 [重复]

    这个问题在这里已经有答案了 根据这里的讨论 我有报告了一个错误 https bugs launchpad net ubuntu source gcc 8 bug 1831385给 Ubuntu 开发者 编译以下示例 C 程序时 includ
  • 无法通过 LINQ to Entities 使用某些功能?

    我正在尝试使用 LINQ 查询在项目上实现搜索功能 由于数据有时包含带有重音符号和其他符号的字符 因此我创建了一种方法来删除这些字符以进行搜索 这是我的代码 var addresses from a in db Addresses join
  • 是否有任何不使用公共虚拟方法的正当理由? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 是否有任何不使用公共虚拟方法的正当理由 我在某处读到我们应该避免使用公共虚拟方法 但我想向专家确认这是否是有效的声明 对于良好且稳定的 API
  • 将一个 long 转换为两个 int 以进行重构

    我需要将一个参数作为两个 int 参数传递给 Telerik Report 因为它不能接受长参数 将 long 拆分为两个 int 并在不丢失数据的情况下重建它的最简单方法是什么 使用掩蔽和移位是最好的选择 根据文档 long 保证为 64

随机推荐

  • Apache Beam实战指南

    https mp weixin qq com s biz MzU1NDA4NjU2MA mid 2247492538 idx 2 sn 9a2bd9fe2d7fd681c10ebd368ef81c9c chksm fbea5a75cc9dd
  • [原创]LoadRunner 12.02 录制脚本时提示无Internet访问,如何解决?

    在使用LoadRunner 12 02 进行录制脚本时提示无Internet访问 如下图 翻译中文如下 可以尝试以下方式解决 点击弹出框中的 Yes 即可 若还是有问题 尝试以下方式 1 LR12走的是证书机制 你按照我附件 图片1 中提供
  • springboot集成springsecurity + jwt的使用

    当项目中要用到用户的认证及权限的时候我们一般会使用 springSecurity来解决 引入 引入很简单
  • 学习若依框架----之----获取登录登录系统、ip、浏览器信息

    文章目录 1 导入需要用到的依赖 2 IP获取 3 AddressUtils 获取地址类 4 登录日志管理工具 4 SpringUtils获取bean工具 5 客户端工具 6 使用 7 测试 8 数据库记录 若依里面 创建登录日志是根据异步
  • USDT信用卡和转账入账接口

    class Usdtpay public function index data this gt request gt param uid data uid token data token type data type changeid
  • 经验模态分解(EMD)

    目录 1 背景 2 时间序列平稳性 3 EMD 方法 4 EMD 过程 5 EMD 方法的缺陷 6 Python 1 背景 实际工程测量中由于测量系统受外界环境影响经常在测量信号中产生趋势项 趋势项是指信号中周期大于采样长度的频率成分 通常
  • Unity内存与资源管理

    内存管理是程序开发的核心问题 而资源的使用又与内存息息相关 因此本章想要梳理整个开发流程中Unity对于内存与资源的管理方式 一 内存基础 1 1 基础概念 内存是暂时存放CPU中的运算数据 与硬盘等外部存储器交换的数据 在操作系统中 内存
  • R语言产生随机数

    R语言中有4个产生随机数的函数 dunif 指定随机数密度 punif 指定随机数的分布类型 qunif 指定quantile function runif 产生随机分布的散点 如果需要指定随机数的类型 可用以下几个函数 round 四舍五
  • kubernetes deploy standalone mysql demo

    文章目录 deployment mysql standalone statefulset mysql standalone helm install mysql standalone deployment mysql standalone
  • mac连接linux报错Unable to negotiate with port 22: no matching host key type found. Their offer: ssh-rsa,

    mac 使用ssh连接linux服务器报错 Unable to negotiate with 10 254 8 211 port 22 no matching host key type found Their offer ssh rsa
  • 软件测试怎么去介绍一个项目的测试流程?

    1 自我介绍 以XXX简历来举例 参照下面的案例 编写你的自我介绍 框架就是 我是谁 我做过什么 我能做什么 我来的目的是什么 面试官您好 我叫 毕业之后进入河北东软软件有限公司从事软件测试方面的工作 一开始从底层做起 在工作中逐渐接触和学
  • shell脚本启动jar包示例

    这里主要为shell脚本启动部署在服务器中jar包 bin bash 这里可替换为你自己的执行程序 其他代码无需更改 APP NAME demo jar 使用说明 用来提示输入参数 usage echo Usage sh demo sh s
  • 数据结构和算法(1)-----稀疏数组

    一 实际需求 编写的五子棋程序中 有存盘退出和继续上盘的功能 分析问题 因为该二维数组的很多值是默认值0 因此记录了很多没有意思的数据 如何在计算机中高效的存储这样的二维数组是一个需要考虑的问题 二 基本介绍 当一个数组中大部分元素为0 或
  • CTF.show:web6

    登陆窗 先想到sql注入 抓包测试发现失败 利用 代替空格进行绕过 username admin or 1 1 password 123456 利用联合查询找到回显位置 username admin or 1 1 union select
  • IDispose

    需要为本类提供DISPOSE函数的情况 1 从IDispose继承 2 有成员对象实现了IDispose 3 本类有包装本机资源 需要在回收对象堆内存前进行释放 Dispose函数并不会将托管对象从托管堆删除 只会回收内部的本机资源
  • 万向锁的理解

    万向锁 万向锁这个概念其实还是不大好理解的 看了很多的博客 虽然看起来他们讲的很有道理 可还是想不通 希望我这篇文章能讲清楚 万向锁产生的根本原因是绕三个轴的旋转不是同时进行的 想象一下我们旋转矩阵的推导是不是绕三个轴的旋转矩阵乘起来得到的
  • 测试用例设计白皮书--测试用例设计综合策略

    测试用例设计白皮书 测试用例设计综合策略 Author Vince 来源 http blog csdn net vincetest 1 Myers提出了使用各种测试方法的综合策略 1 在任何情况下都必须使用边界值分析方法 经验表明用这种方法
  • 微信小程序-SOA架构(17年1月)

    微信小程序 顾名思义 它有两个方面的含义 重点在小 也就是不用安装就能使用的意思 另一个重点 它是应用程序 它和公众号绑定在一起使用 从用户角度去看 它是各种APP的替代品 有了它以后 不再需要安装APP 作为IT人员 更多的是从工程思维的
  • Snort搭建以及规则编写

    目录 Snort IDS Snort搭建 安装web服务 方便设置sonrt后期访问 Mysql安装 PHP安装 安装 Snort Snort配置 创建snort专用的用户和组 配置目录 配置规则 修改配置文件 规则编写 Snort IDS
  • QGIS二次开发02:交互动作实现

    地图交互动作就是通过鼠标操作与地图间的互动 动作包括按下 press 按键弹起 release 鼠标移动 move 双击等等 QGIS实现地图的交互主要是通过继承QgsMapTool这个类实现 目前集成了QgsMapToolZoom 拉框缩