通过查看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 版权协议,转载请附上原文出处链接和本声明。