Qgis 开发初级 《地图交互》

server/2024/9/22 21:31:13/

Qigs 添加数据的方式其实有两种,一种在非编辑模式下,一宗在编辑模式下,编辑模式下的数据操作是可以追溯的,可撤销,可恢复。编辑模式下的数据操作基本都是交互式操作,所以和事件是分不开的。qgis 的有些事件是和图层绑定在一起的,前面说过,qgis有当前图层的概念,qgis的内部事件的操作逻辑也是和当前图层绑定在一起的。所以,如果我们写自己的事件的话,为了避免和qgis的事件有冲突,通常要去掉qigs的事件,我们是二次开发,原则上不动qgis的源码,所以会去除当前图层,具体如何操作,后面会介绍。

1、事件

1.1、Tool 工具

无论是arcgis 还是qgis 都有tool的概念,简单来说,就是一种和地图交互的类。事件也是和这些Tool息息相关的。先看下Qgis里面内置的一些重要的Tools类。接下来,我们主要以 QgsMapToolEdit(地图编辑类)和QgsMapToolIdentify(地图拾取类) 两个主要类介绍事件。

当我们要自定义一个工具的时候,一般这样写,下面是一个继承了QgsMapToolIdentify基类的类。其中覆写了五个事件,依次为键盘按下事件,键盘抬起事件,鼠标按下事件,鼠标抬起事件和鼠标移动事件。

class BTool : public QgsMapToolIdentify
public:BTool(QgsMapCanvas* pMapCanvas);~BTool();protected:void keyPressEvent(QKeyEvent* e) override;void keyReleaseEvent(QKeyEvent* e) override;void canvasPressEvent(QgsMapMouseEvent* e) override;void canvasReleaseEvent(QgsMapMouseEvent* e) override;void canvasMoveEvent(QgsMapMouseEvent* e) override;};

其中在键盘事件中,可通过下面方法判断是按下了哪个键,qgis里面是有按键的枚举值的,我一般是通过这种数字去判断。27 表示按下的是ESC 的键。

e->nativeVirtualKey() == 27

在鼠标事件中,可通过下面方法判断是左键,还是右键,下面的代码表示按下了左键。

e->button() == Qt::MouseButton::LeftButton

1.2、Tool 工具的激活

Tool是 工具一般都具有一个很重要的特点,一次只能启用一个工具,比如说,画点和画线,同时启用会带来混乱的。Tools 的工具激活状态和非激活状态都是通过QgsMapCanvas 来实现的。所谓其中就是让事件生效。小面就是让tool的Tool类生效。其中canvas 是QgsMapCanvas 类,tool是QgsMapTool类或者继承了该类的子类。

canvas->setMapTool(tool)

非活动状态,获取当前tool,使其进入非活动状态。

    auto tool = qgsmapcanvas->mapTool();canvas->unsetMapTool(tool);

2、交互绘图

交互绘图一般会继承QgsMapToolEdit 的类,继承里面的相关事件。交互绘图有个很重要的特点就是对象要实时显示,绘图点要跟随鼠标移动。事件怎么触发在第一小节已经介绍了。这里介绍一个很重要的对象QgsRubberBand。qgis的交互临时对象一般都离不开它。使用它可以让你更方便的绘图。用这个对象,一般在鼠标左键里面创建对象,在鼠标左键或者右键里面结束对象,在鼠标移动事件里面动态修改对象。Qgis 是由一个createRubberBand 方法,可以通过它获取对象。交互不在细说了,可以查看资源绑定里面的代码。

比如增加点

mpRubberBand->removeLastPoint();
mpRubberBand->addPoint(e->snapPoint());

比如说转成geometey

 mpRubberBand->asGeometry()

3、交互拾取

拾取是任何gis平台的一个重要功能。qgis的点击拾取功能是通过QgsMapToolIdentify(地图拾取类)这个类实现的。这个类有些非常重要的方法,qgis的拾取是通过这些方法实现的。一般传入屏幕坐标和geometry对象。

    QList<QgsMapToolIdentify::IdentifyResult> identify( int x, int y, const QList<QgsMapLayer *> &layerList = QList<QgsMapLayer *>(), IdentifyMode mode = DefaultQgsSetting, const QgsIdentifyContext &identifyContext = QgsIdentifyContext() );/*** Performs the identification.* To avoid being forced to specify IdentifyMode with a list of layers* this has been made private and two publics methods are offered* \param x x coordinates of mouseEvent* \param y y coordinates of mouseEvent* \param mode Identification mode. Can use QGIS default settings or a defined mode.* \param layerType Only performs identification in a certain type of layers (raster, vector, mesh). Default value is AllLayers.* \param identifyContext Identify context object.* \returns a list of IdentifyResult*/QList<QgsMapToolIdentify::IdentifyResult> identify( int x, int y, IdentifyMode mode, LayerType layerType = AllLayers, const QgsIdentifyContext &identifyContext = QgsIdentifyContext() );//! Performs identification based on a geometry (in map coordinates)QList<QgsMapToolIdentify::IdentifyResult> identify( const QgsGeometry &geometry, IdentifyMode mode, LayerType layerType, const QgsIdentifyContext &identifyContext = QgsIdentifyContext() );//! Performs identification based on a geometry (in map coordinates)QList<QgsMapToolIdentify::IdentifyResult> identify( const QgsGeometry &geometry, IdentifyMode mode, const QList<QgsMapLayer *> &layerList, LayerType layerType, const QgsIdentifyContext &identifyContext = QgsIdentifyContext() );

拿到IdentifyResult 对象后,它有两个很重要的属性,一个表示识别的要素,一个表示识别的图层。

QgsFeature feature = var.mFeature;
QgsMapLayer layer=var.mLayer;

还有一些其他的参数,像 IdentifyMode 控制识别的模式,是只识别激活图层,还是选择图层等等。

   enum IdentifyMode{DefaultQgsSetting = -1,ActiveLayer,TopDownStopAtFirst,TopDownAll,LayerSelection};

还有一个图层类型,用于指示识别的图层种类,qgis不仅仅能识别矢量图层,其他类型的图层也是可以识别的。

    enum Type{VectorLayer = 1,RasterLayer = 2,MeshLayer = 4, //!< \since QGIS 3.6VectorTileLayer = 8,  //!< \since QGIS 3.14PointCloudLayer = 16, //!< \since QGIS 3.18AllLayers = VectorLayer | RasterLayer | MeshLayer | VectorTileLayer | PointCloudLayer};

4、捕捉要素

要素操作还有一个重要的关于用户体验的操作,就是捕捉。首先我们看一下qgis的捕捉设置。可以看到qgis的捕捉功能是通过cavas获取QgsSnappingUtils来实现的。 用setIndividualLayerSettings,可以把特定的需要捕捉的图层添加捕捉设置中。

QgsSnappingUtils* msnapper= QgsMapToolEdit::canvas()->snappingUtils();
QgsSnappingConfig  config = msnapper->config();config.setEnabled(true);config.setMode(Qgis::SnappingMode::AdvancedConfiguration);config.clearIndividualLayerSettings();QgsSnappingConfig::IndividualLayerSettings ids;ids.setEnabled(true);ids.setType(QgsSnappingConfig::SnappingType::Vertex);ids.setUnits(Qgis::MapToolUnit::Pixels /*QgsTolerance::UnitType::Pixels*/);ids.setTolerance(CCommConfig::getConfig("tolerance").toDouble());config.setIndividualLayerSettings(layer, ids);msnapper->setConfig(config);

捕捉模式有很多种,是个枚举类型。

  enum class SnappingMode SIP_MONKEYPATCH_SCOPEENUM_UNNEST( QgsSnappingConfig, SnappingMode ) : int{ActiveLayer = 1, //!< On the active layerAllLayers = 2, //!< On all vector layersAdvancedConfiguration = 3, //!< On a per layer configuration basis};

开始捕捉是通过QgsSnapIndicator 这个类实现的。一般来说,后面两行代码放在鼠标移动事件中。

	QgsSnapIndicator* msnapIndicator = new QgsSnapIndicator(QgsMapToolEdit::canvas());  auto sp = msnapper->snapToMap(e->pos());msnapIndicator->setMatch(sp);


http://www.ppmy.cn/server/100844.html

相关文章

nginx 详解

1 nginx是什么 nginx是由俄罗斯人发明的一款高性能的web服务器&#xff0c;它同早期的Apache&#xff0c;IIS&#xff0c;Lighttpd等都具有web服务器的功能&#xff0c;能够发布网站代码等资源&#xff0c;为用户提供信息资讯。但是nginx的功能不单单只是做为web服务器&#x…

企业信息安全怎么保护?2024年最新十款文件加密软件排行榜

随着数字化转型的加速&#xff0c;企业面临的网络安全威胁日益复杂。确保企业信息安全&#xff0c;不仅关乎商业机密的保护&#xff0c;更是企业可持续发展的基石。在2024年&#xff0c;为了帮助企业有效应对数据泄露风险&#xff0c;我们特别整理了十款备受好评的文件加密软件…

MIT6.s081 2021 Lab Copy on-write

Implement copy-on write 背景 xv6 使用 fork() 系统调用创建子进程时&#xff0c;需要将父进程的地址空间进行 深拷贝 &#xff0c;即将页表和实际物理空间同时进行拷贝&#xff0c;以实现父进程和子进程地址空间的独立性。但很多时候&#xff0c;如 shell 程序&#xff0c;…

解决com.google.android.play:core:1.10.3在10.1号之后targetSDK升到34的问题

implementation com.google.android.play:core:1.10.3或者这样的 升到android14 之后可能提审的时候都会遇到这个问题&#xff0c;解决方法如下&#xff1a; implementation com.google.android.play:asset-delivery:2.2.2 implementation com.google.android.play:app-update…

设计模式实战:文件压缩工具的设计与实现

文件压缩工具在日常工作中非常实用,能够有效减少文件大小,节省存储空间。为了构建一个灵活且可扩展的文件压缩工具,我们可以结合策略模式、装饰模式和命令模式。本文将详细介绍这些模式在文件压缩工具中的应用,帮助开发者设计出功能丰富且易于维护的系统。 系统设计流程图…

第十七章:kubernetes应用扩展

本章内容包括&#xff1a; 在kubernetes上添加自定义对象为自定义对象添加控制器添加自定义API服务器使用Kubernetes服务目录完成自助服务配置 1 定义自定义API对象 随着Kubernetes⽣态系统的持续发展&#xff0c;越来越多⾼层次的对象将会不断涌现。⽐起⽬前使⽤的对象&#…

transformer(李宏毅老师系列)

自学参考&#xff1a; Transformer:Attention Is All You Need Transformer论文逐段精读 视频课 课件资料 笔记 一、引入 seq2seq&#xff1a;输入一个序列的向量作为input&#xff0c;output的长度由机器自己决定seq2seq model应用: 语音辨识 输入是声音讯号的一串vector 输出…

Web 3 一些常见术语

目录 Provider 提供者Signer 签名者Transaction 交易Contract 合约Receipt 收据 首先&#xff0c;从高层次上对可用对象的类型及其负责的内容有一个基本的了解是很有用的。 Provider 提供者 一个 Provider 是与区块链的只读连接&#xff0c;允许查询区块链状态&#xff0c;例…