QGIS二次开发之选择要素功能

  • Post author:
  • Post category:其他


通过查看qgis源码,发现qgis标识的功能在QgsMapToolSelectionHandler类和QgsMapToolIdentify类中;在选择图形时QgsMapToolSelectionHandler发出geometryChanged信号,然后通过重写的QgsMapToolIdentifyAction类进行接收,从而实现选中图形的高亮和以及数据的显示。

参考这两个类和官方文档,重写了一个选择工具类

.h文件

#include <QObject>
#include <QList>
#include <QScopedPointer>
#include<qmath.h>
#include <qgsmapcanvas.h>
#include <qgsmaptoolidentify.h>
#include <qgsrubberband.h>
#include <qgsmapmouseevent.h>
class QgsMapToolSelectFeatures : public QgsMapToolIdentify
{
    Q_OBJECT
public:
    QgsMapToolSelectFeatures(QgsMapCanvas *mapCanvas);
protected:
    //重写鼠标移动
    void canvasMoveEvent(QgsMapMouseEvent *e) override;
    //重写鼠标按下
    void canvasPressEvent(QgsMapMouseEvent *e) override;
    //重写鼠标抬起
    void canvasReleaseEvent(QgsMapMouseEvent *e) override;

    void initRubberBand();
    void identifyFromGeometry();
signals:
	//发出选中的要素信号
    void sigSelectFeatureChange(QList<QgsFeature>);
private:
    // 是否正在选择
    bool mSelectionActive = false;
    QScopedPointer<QgsRubberBand> mSelectionRubberBand;
    QColor mFillColor = QColor(254, 178, 76, 63);
    QColor mStrokeColor = QColor(254, 58, 29, 100);
    QPoint mInitDragPos;
    //选择的Geometry
    QgsGeometry mSelectGeometry;
};

cpp文件

#include "QgsMapToolSelectFeatures.h"

#include "qgsapplication.h"
#include "qgsvectorlayer.h"

QgsMapToolSelectFeatures::QgsMapToolSelectFeatures(QgsMapCanvas *mapCanvas)
    : QgsMapToolIdentify(mapCanvas)
{

}
void QgsMapToolSelectFeatures::canvasMoveEvent(QgsMapMouseEvent * e)
{
    if (e->buttons() != Qt::LeftButton)
        return;
    QRect rect;
    if (!mSelectionActive)
    {
        mSelectionActive = true;
        rect = QRect(e->pos(), e->pos());
    }
    else
    {
        rect = QRect(e->pos(), mInitDragPos);
    }
    if (mSelectionRubberBand)
        mSelectionRubberBand->setToCanvasRectangle(rect);
}

void QgsMapToolSelectFeatures::canvasPressEvent(QgsMapMouseEvent * e)
{
    if (!mSelectionRubberBand)
        initRubberBand();
    mInitDragPos = e->pos();
}

void QgsMapToolSelectFeatures::canvasReleaseEvent(QgsMapMouseEvent * e)
{
    QPoint point = e->pos() - mInitDragPos;
    //点
    if (!mSelectionActive || (point.manhattanLength() < QApplication::startDragDistance()))
    {
        mSelectionActive = false;
        mSelectGeometry = QgsGeometry::fromPointXY(toMapCoordinates(e->pos()));
        identifyFromGeometry();
    }
    //矩形
    if (mSelectionRubberBand && mSelectionActive)
    {
        mSelectGeometry = mSelectionRubberBand->asGeometry();
        mSelectionRubberBand.reset();
        identifyFromGeometry();
    }
    mSelectionActive = false;
}

void QgsMapToolSelectFeatures::initRubberBand()
{
    mSelectionRubberBand.reset(new QgsRubberBand(mCanvas, QgsWkbTypes::PolygonGeometry));
    mSelectionRubberBand->setFillColor(mFillColor);
    mSelectionRubberBand->setStrokeColor(mStrokeColor);
}
void QgsMapToolSelectFeatures::identifyFromGeometry()
{
    if (mCanvas)
    {
        mCanvas->setSelectionColor(Qt::red);//设置颜色
        QList< QgsMapLayer * > 	layers = mCanvas->layers();
        foreach (QgsMapLayer *l , layers)
        {
            QgsVectorLayer *l1 = qobject_cast<QgsVectorLayer*>(l);
            l1->removeSelection();
        }
    }
    //返回选中的结果
    QList<IdentifyResult> results = QgsMapToolIdentify::identify(mSelectGeometry, IdentifyMode::TopDownAll, AllLayers);
    //选择的Features集合
    QList<QgsFeature> selectFeatures;
    //显示出来
    for (int i = 0; i < results.count(); ++i)
    {
        QgsVectorLayer *layer = qobject_cast<QgsVectorLayer*>(results.at(i).mLayer);
        QgsFeatureIds ids;
        for (IdentifyResult var : results)
        {
            QgsFeature _Feature = var.mFeature;
            ids.insert(_Feature.id());
        }
        if (ids.count() > 0)
            layer->selectByIds(ids);
        QgsFeature feature = results.at(i).mFeature;
        selectFeatures.append(feature);
    }
     //发出选中的Feature信息信号
        if (selectFeatures.count() > 0)
            emit sigSelectFeatureChange(selectFeatures);
}

然后在其他地方接收sigSelectFeatureChange 信号,即可获得选中要素的信息。



版权声明:本文为mayiyouguodahai原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。