效果图,拉框选择要素,高亮显示。
1.代码块
需要创建一个类,类名为QgsMapToolSelectFeatures
1.1QgsMapToolSelectFeatures.h文件代码
#ifndef QGSMAPTOOLSELECTFEATURES_H
#define QGSMAPTOOLSELECTFEATURES_H
#endif // QGSMAPTOOLSELECTFEATURES_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;
};
2.1QgsMapToolSelectFeatures .cpp文件代码
#include "QgsMapToolSelectFeatures.h"
#include"QgsMapToolIdentify.h"
#include "qgsapplication.h"
#include "qgsvectorlayer.h"
#include<QMessageBox>
#include<QMessageBox>
#include<qgsfeature.h>
#include<qgsvectorlayer.h>
#include<qgsrectangle.h>
#include<QMouseEvent>
#include<QMessageBox>
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();
// QgsVectorLayer *vlayer=qobject_cast<QgsVectorLayer*>(mCanvas->currentLayer());
// //searchfeature
// QgsFeature f;//selectfeature
// QgsFeatureRequest fReq;
// QRect rect;
// rect = QRect(e->pos(), e->pos());
// const QgsMapToPixel*mtransform=mCanvas->getCoordinateTransform();
// QgsPointXY lb=mtransform->toMapCoordinates(rect.left(),rect.bottom());
// QgsPointXY rt=mtransform->toMapCoordinates(rect.right(),rect.top());
// QgsRectangle rectSearch(lb,rt);
// fReq.setFilterRect(rectSearch);
// fReq.setFlags(QgsFeatureRequest::ExactIntersect);
// QgsAttributeList subsetList;
// subsetList<<0<<2<<8;
// fReq.setSubsetOfAttributes(subsetList);
// QgsFeatureIterator fit=vlayer->getFeatures(fReq);
// fit.rewind();
// QgsFeatureIds lst;
// QString info;
// while(fit.nextFeature(f)==true)
// {
// const QgsFields pFields=f.fields();
// for(int i=0;i<pFields.size();++i){
// QVariant att=f.attribute(i);
// QString strAtt=att.toString();
// qDebug()<<"Feild["<<i<<"]="<<pFields.at(i).name()<<endl;
// qDebug()<<"Attribute["<<i<<"]="<<strAtt<<endl;
// info+=pFields.at(i).name()+"\t"+strAtt+"\n";
// }
// lst<<f.id();
// }
// //select
// QMessageBox msg;
// msg.setText(info);
// msg.exec();
}
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);
}
1.3mainwindow.cpp文件代码
#include "qgsmaptoolidentifyfeature.h"
#include "QgsMapToolSelectFeatures.h"
//若还有其他头文件可以视情况加
void MainWindow::on_action_triggered()
{
//QgsMapToolselectFeature实例化
QgsMapToolSelectFeatures* m_mapidentifyfeature = new QgsMapToolSelectFeatures(m_mapcanvas);
m_mapcanvas->setMapTool(m_mapidentifyfeature);//将工具添加到m_mapcanvas上
}