QGis(三)查询矢量图层的要素属性字段值(转载)
QGis(三)查询矢量图层的要素属性字段值
https://github.com/gwaldron/osgearth/issues/489
当加载一个矢量图层后,如果要查看要素的属性字段值,则需要实现identity的功能。可以和前面的缩放一样,添加一个工具栏按钮:
(1)在MainWindow添加一个变量,并在Qt设计师里添加Action:
QgsMapToolSelect *mpIdentifyTool; ///<查询要素
这里QgsMapToolSelect类继承自QgsMapTool,后面再列出详细内容。
(2)然后在初始化函数里添加:
mpMapToolBar->addAction(ui.mpActionIdentify); mpIdentifyTool = new QgsMapToolSelect(mainMapCanvas); mpIdentifyTool->setAction(ui.mpActionIdentify);
(3)添加信号槽函数连接:
connect(ui.mpActionIdentify, SIGNAL(triggered()), this, SLOT(identifyFeature()));
(4)槽函数实现:
void MainWindow::identifyFeature() { mpIdentifyTool->SetEnable(true); mainMapCanvas->setMapTool(mpIdentifyTool); ui.mpActionIdentify->setCheckable(true); ui.mpActionIdentify->setChecked(true); )->type() == QgsMapLayer::RasterLayer) { return; } QgsVectorLayer *pLayer=(QgsVectorLayer *)mainMapCanvas->layer(); mpIdentifyTool->SetSelectLayer(pLayer); if ( ui.mpActionIdentify->isChecked()) { pLayer->removeSelection(true); } }
可以看到,基本步骤就跟前面的缩放工具栏一模一样。但是QgsMapToolSelect不是 QgsMapTool自带的类,需要自定义,QgsMapToolSelect类的定义如下:
class QgsMapToolSelect : public QgsMapTool { Q_OBJECT; public: QgsMapToolSelect(QgsMapCanvas *); ~QgsMapToolSelect(void); public: //设置当前被选择(活动)的图层 void SetSelectLayer(QgsVectorLayer *); <span style="white-space:pre"> </span>//重载鼠标释放事件函数 virtual void canvasReleaseEvent(QMouseEvent * e); //设定工具状态 void SetEnable(bool); //得到所有的属性和属性值,<属性1,属性值1>是QMap的一对值 QList<QMap<QString, QString>> GetAttributeValue(QgsVectorLayer *layer, QgsFeatureIds selectedFIds); void setShowFlag(bool flag); IdentifyResultDlg *ResultDlg(); private: QgsVectorLayer* pLayer; QgsFeatureIds layerSelectedFeatures; bool StatusFlag; QList<QMap<QString, QString>> list; //存储选择后的要素 bool isShowFlag; ///< 是否在主界面上勾选了shp图层 IdentifyResultDlg *mIdentifyResultDlg; private: <span style="white-space:pre"> </span>//提取鼠标位置一定范围作为选择区域 void ExpandSelectRangle(QRect &Rect,QPoint Point); //将指定的设备坐标区域转换成地图坐标区域 void SetRubberBand(QRect &selectRect,QgsRubberBand *); //选择图层特征 void SetSelectFeatures(QgsGeometry *,bool,bool,bool); void SetSelectFeatures(QgsGeometry *,bool); };
具体函数实现:
#include "qgsmaptoolselect.h" //构造和析构函数 QgsMapToolSelect::QgsMapToolSelect(QgsMapCanvas *Mapcanvas):QgsMapTool(Mapcanvas) { pLayer=NULL; mCursor=Qt::ArrowCursor; mCanvas=Mapcanvas; StatusFlag=true; isShowFlag = true; mIdentifyResultDlg = NULL; } QgsMapToolSelect::~QgsMapToolSelect(void) { } //设置当前被选择(活动)的图层 void QgsMapToolSelect::SetSelectLayer(QgsVectorLayer *Layer) { pLayer=Layer; } //鼠标按钮释放时,选择包含鼠标位置的图元 void QgsMapToolSelect::canvasReleaseEvent(QMouseEvent * e ) { if(mCanvas==NULL){ return; } if(pLayer==NULL){ QMessageBox::about(mCanvas,QString::fromLocal8Bit("警告"),QString::fromLocal8Bit("请选择图层")); return; } if(StatusFlag==false){ return; } //得到产生事件的按钮信息 Qt::MouseButton mButton=e->button(); //如果不是左按钮返回 if(mButton!=Qt::MouseButton::LeftButton){ return; } //得到鼠标指针的位置 QPoint pos=e->pos(); //定义QgsRubberBand对象 QgsRubberBand rubberBand(mCanvas,true); QRect selectRect(,,,); //设置鼠标位置区域 ExpandSelectRangle(selectRect,pos); //将鼠标位置区域转换成地图坐标 SetRubberBand(selectRect,&rubberBand ); //将QgsRubberBand对象转换为几何对象,根据该几何对象在图层中选择特征 QgsGeometry* selectGeom=rubberBand.asGeometry(); if(!selectGeom){ return; } //确定是否按下ctrl键 bool doDifference=e->modifiers()&Qt::ControlModifier ? true:false; //在图层中选择最靠近几何对象的特征 SetSelectFeatures(selectGeom,false,doDifference,true); //SetSelectFeatures(selectGeom,doDifference); //设定选择的特征 pLayer->setSelectedFeatures(layerSelectedFeatures); list = GetAttributeValue(pLayer, layerSelectedFeatures); if (isShowFlag) { ResultDlg()->InitialData(list); ResultDlg()->show(); } else { QMessageBox::information(NULL, tr("警告"), tr("请选择矢量图层"), QMessageBox::Ok); } delete selectGeom; rubberBand.reset(true); } //提取鼠标位置一定范围作为选择区域 void QgsMapToolSelect::ExpandSelectRangle(QRect &Rect,QPoint Point) { ; //如果图层不是面图元类型 if(pLayer->geometryType()!=QGis::Polygon){ boxSize=; } else{ boxSize=; } //设置选择区域 Rect.setLeft(Point.x()-boxSize); Rect.setRight(Point.x()+boxSize); Rect.setTop(Point.y()-boxSize); Rect.setBottom(Point.y()+boxSize); } //将指定的设备坐标区域转换成地图坐标区域 void QgsMapToolSelect::SetRubberBand(QRect &selectRect,QgsRubberBand *pRubber) { //得到当前坐标变换对象 const QgsMapToPixel* transform=mCanvas->getCoordinateTransform(); //将区域设备坐标转换成地图坐标 QgsPoint ll=transform->toMapCoordinates(selectRect.left(),selectRect.bottom()); QgsPoint ur = transform->toMapCoordinates(selectRect.right(),selectRect.top()); pRubber->reset(true ); //将区域的4个角点添加到QgsRubberBand对象中 pRubber->addPoint(ll,false ); pRubber->addPoint(QgsPoint(ur.x(), ll.y()),false ); pRubber->addPoint(ur,false ); pRubber->addPoint(QgsPoint( ll.x(), ur.y() ),true ); } //选择几何特征 //selectGeometry:选择特征的选择几何体 //doContains:选择的特征是否包含在选择几何体内部 //singleSelect:仅仅选择和选择几何体最靠近的特征 void QgsMapToolSelect::SetSelectFeatures(QgsGeometry *selectGeometry,bool doContains, bool doDifference,bool singleSelect) { //如果选择几何体不是多边形 if(selectGeometry->type()!=QGis::Polygon){ return; } QgsGeometry selectGeomTrans(*selectGeometry); //设定选择几何体的坐标系和图层的坐标系一致 if(mCanvas->mapRenderer()->hasCrsTransformEnabled()){ try{ //将地图绘板坐标系变换到图层坐标系 QgsCoordinateTransform ct(mCanvas->mapRenderer()->destinationSrs(),pLayer->crs()); //设定几何体的坐标系和图层坐标系一致 selectGeomTrans.transform(ct); } //对于异常点抛出异常 catch(QgsCsException &cse){ Q_UNUSED(cse); //catch exception for 'invalid' point and leave existing selection unchanged QMessageBox::warning(mCanvas, QObject::tr("CRS Exception"), QObject::tr( "Selection extends beyond layer's coordinate system." ) ); return; } } //设置光标 //QApplication::setOverrideCursor(Qt::WaitCursor); //选择和选择几何体相交或在几何体内部的特征 pLayer->select(QgsAttributeList(),selectGeomTrans.boundingBox(),true,true); int nh=pLayer->selectedFeatureCount(); QgsFeatureIds newSelectedFeatures; QgsFeature f; ; bool foundSingleFeature=false; double closestFeatureDist=std::numeric_limits<double>::max(); //得到当前选择的特征 while(pLayer->nextFeature(f)){ QgsGeometry* g=f.geometry(); //g是否包含在selectGeomTrans几何体内部 if(doContains && !selectGeomTrans.contains(g)){ continue; } if(singleSelect){ //选择和几何体最靠近的特征 foundSingleFeature=true; //计算两个几何体之间的距离 double distance=g->distance(selectGeomTrans); if(distance<=closestFeatureDist){ closestFeatureDist=distance; //计算出最靠近选择几何体特征的id closestFeatureId=f.id(); } } else{ //存储符合要求的特征id newSelectedFeatures.insert(f.id()); } } //确定和选择几何体最靠近特征的id if(singleSelect && foundSingleFeature){ newSelectedFeatures.insert(closestFeatureId); } //如果按下ctrl键,选择多个特征 if(doDifference){ //得到所有选择特征的id layerSelectedFeatures=pLayer->selectedFeaturesIds(); QgsFeatureIds::const_iterator i=newSelectedFeatures.constEnd(); while(i!=newSelectedFeatures.constBegin()){ --i; if(layerSelectedFeatures.contains(*i)){ layerSelectedFeatures.remove( *i ); } else{ layerSelectedFeatures.insert( *i ); } } } else{ layerSelectedFeatures=newSelectedFeatures; } //QApplication::restoreOverrideCursor(); } //选择几何特征,用于选择面状几何特征 //selectGeometry:选择几何体 void QgsMapToolSelect::SetSelectFeatures(QgsGeometry *selectGeometry,bool doDifference) { //如果选择几何体不是多边形 if(selectGeometry->type()!=QGis::Polygon){ return; } QgsGeometry selectGeomTrans(*selectGeometry); //设定选择几何体的坐标系和图层的坐标系一致 if(mCanvas->mapRenderer()->hasCrsTransformEnabled()){ try{ //将地图绘板坐标系变换到图层坐标系 QgsCoordinateTransform ct(mCanvas->mapRenderer()->destinationSrs(),pLayer->crs()); //设定几何体的坐标系和图层坐标系一致 selectGeomTrans.transform(ct); } //对于异常点抛出异常 catch(QgsCsException &cse){ Q_UNUSED(cse); //catch exception for 'invalid' point and leave existing selection unchanged QMessageBox::warning(mCanvas, QObject::tr("CRS Exception"), QObject::tr( "Selection extends beyond layer's coordinate system." ) ); return; } } //设置光标 //QApplication::setOverrideCursor(Qt::WaitCursor); //选择和选择几何体相交或在几何体内部的特征 pLayer->select(QgsAttributeList(),selectGeomTrans.boundingBox(),true,true); int nh=pLayer->selectedFeatureCount(); QgsFeatureIds newSelectedFeatures; QgsFeature f; ; //得到当前选择的特征 while(pLayer->nextFeature(f)){ p++; QgsGeometry* g=f.geometry(); //选择的特征是否包含在选择几何体的内部 //如果g包含selectGeomTrans,返回true if(!g->contains(&selectGeomTrans)){ continue; } //存储符合条件图层特征id newSelectedFeatures.insert(f.id()); } QgsFeatureIds layerSelectedFeatures; //如果按下ctrl键,可以选择多个特征 if(doDifference){ layerSelectedFeatures=pLayer->selectedFeaturesIds(); QgsFeatureIds::const_iterator i = newSelectedFeatures.constEnd(); while( i != newSelectedFeatures.constBegin()){ --i; if( layerSelectedFeatures.contains( *i ) ) { layerSelectedFeatures.remove( *i ); } else { layerSelectedFeatures.insert( *i ); } } } else{ layerSelectedFeatures=newSelectedFeatures; } //设定选择的特征 pLayer->setSelectedFeatures(layerSelectedFeatures); //QApplication::restoreOverrideCursor(); } //设定工具状态 void QgsMapToolSelect::SetEnable(bool flag) { StatusFlag=flag; if(StatusFlag){ mCursor=Qt::CrossCursor; } else{ mCursor=Qt::ArrowCursor; } } IdentifyResultDlg * QgsMapToolSelect::ResultDlg() { if (mIdentifyResultDlg == NULL) { mIdentifyResultDlg = new IdentifyResultDlg; } return mIdentifyResultDlg; } //得到选择的要素的属性信息 QList<QMap<QString, QString>> QgsMapToolSelect::GetAttributeValue( QgsVectorLayer *layer, QgsFeatureIds selectedFIds ) { // QStringList strAttribute; QMap<QString, QString> featureValue; QList<QMap<QString, QString>> featureValues; , nFeatureCount = , nFieldsCount = ; if (layer == NULL) { return featureValues; } QgsFeatureList featurelist = layer->selectedFeatures(); nFeatureCount = featurelist.size(); QgsFeature feature; QString fieldName, fieldValue; // vector<QgsField> myFields = layer->fields(); ; i < nFeatureCount; i++) { feature = featurelist.at(i); const QgsAttributeMap &attributes = feature.attributeMap(); nFieldsCount = attributes.count(); const QgsFieldMap &fields = layer->pendingFields();//从图层得到字段信息 QgsField field; ; j < nFieldsCount; j++) { field = fields[j]; fieldName = field.name(); fieldValue = attributes[j].toString(); featureValue.insert(fieldName, fieldValue); } featureValues.push_back(featureValue); } return featureValues; } void QgsMapToolSelect::setShowFlag( bool flag ) { isShowFlag = flag; }
查询得到的数据显示在对话框:
IdentifyResultDlg对话框是为了显示查询得到的结果。它的定义:
class IdentifyResultDlg : public QDialog { Q_OBJECT public: IdentifyResultDlg(QWidget *parent = ); ~IdentifyResultDlg(); void InitialDlg(); void InitialData(QList<QMap<QString, QString>>); private: Ui::IdentifyResultDlg ui; QStandardItemModel *fieldmodel; };
IdentifyResultDlg具体实现:
#include "identifyresultdlg.h" IdentifyResultDlg::IdentifyResultDlg(QWidget *parent) : QDialog(parent) { ui.setupUi(this); QStringList lists; InitialDlg(); } IdentifyResultDlg::~IdentifyResultDlg() { } void IdentifyResultDlg::InitialDlg() { this->setWindowTitle(tr("查询要素属性信息")); fieldmodel = new QStandardItemModel(); fieldmodel->setColumnCount(); ui.tableView->setModel(fieldmodel); ui.tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);//设置表格不可编辑 ui.tableView->verticalHeader()->hide(); //列头不显示 ui.tableView->setSelectionBehavior(QAbstractItemView::SelectRows);//选择整行高亮 setWindowFlags(Qt::WindowStaysOnTopHint);//使窗口置顶 , ); } //将数据显示在表格中 void IdentifyResultDlg::InitialData( QList<QMap<QString, QString>> datas) { fieldmodel->clear();//注意:在clear之后,表头名称也被清除了,需再设置表头 fieldmodel->setHorizontalHeaderItem(, new QStandardItem(QObject::tr("属性名称"))); fieldmodel->setHorizontalHeaderItem(, new QStandardItem(QObject::tr("属性值"))); QString name, value; QMap<QString,QString>::iterator it; ; ; i < datas.count(); i ++) { QMap<QString,QString> data = datas.at(i); ; ; it != data.end(), j < data.count(); ++it, ++j) { int index = i * data.count() +j; fieldmodel->setItem(index, , new QStandardItem(it.key())); if (it.value() == NULL) { it.value() = "; } fieldmodel->setItem(index, , new QStandardItem(it.value())); fieldmodel->item(index, )->setTextAlignment(Qt::AlignCenter); fieldmodel->item(index, )->setTextAlignment(Qt::AlignCenter); ) { fieldmodel->item(index, )->setBackground(QBrush(QColor(, , ))); fieldmodel->item(index, )->setBackground(QBrush(QColor(, , ))); } } } }
查询一个要素和多个要素的结果如下图所示:
注意:可能中文字段显示乱码,解决方法:
在操作shp之前,添加这句就可以了:
CPLSetConfigOption("SHAPE_ENCODING","");
QGis(三)查询矢量图层的要素属性字段值(转载)的更多相关文章
- Qt+QGIS二次开发:自定义类实现查询矢量数据的属性字段值(图查属性)
在GIS领域,有两种重要的查询操作,图查属性和属性查图. 本文主要介绍如何在QGIS中通过从QgsMapToolIdentify中派生自定义类实现查询矢量数据的属性字段值(图查属性). 重点参考资料: ...
- OpenLayers在多个矢量图层编辑要素
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head ...
- ArcMap10.1修改要素属性字段
ArcMap10.1修改要素属性字段 问题描述:在ArcMap10.1中编辑要素属性表时,遇到输入字段值的长度超过字段最大长度时,ArcMap会抛出“基础DBMS错误[ORA-12899:value ...
- [ArcGIS API for JavaScript 4.8] Sample Code-Popups-1-popupTemplate的概念和popup中属性字段值的多种表现形式
[官方文档:https://developers.arcgis.com/javascript/latest/sample-code/intro-popuptemplate/index.html] 一. ...
- openlayers3 在地图上叠加WFS查询矢量图层
随着终端设备计算能力的加强,用户在使用地图的时候也须要越来越多的交互效果. 比方如今非常火的室内导航,为了获得好的用户体验,就须要当用户单击某一商店的时候该商店的颜色能对应的变化.这就须要叠加矢量图层 ...
- datagridcolumn单元格怎么显示查询到的某个表的字段值(字段值可能为多个)
例如,在之前做的项目中,查询mhz_xckcr表,select出某个业务的现场勘察人信息,select出的现场勘察人姓名(可能有多个)要在前台datagrid的一个datagridcolmn单元格显示 ...
- Dynamics CRM2016 Web API之更新记录的单个属性字段值
在web api中提供了对单个属性的更新接口,这和查询中查询单个属性类似,对这个接口我个人也是比较喜欢的. var id = "{D1E50347-86EB-E511-9414-ADA183 ...
- Arcpy按属性(字段值)不同将shp分割为多个独立shp_适用点线面矢量
利用代码可以进行批量处理,安装有10.5及以上版本ArcGIS可以使用工具Split by attributes完成上述任务 # -*- coding: utf-8 -*- # Import syst ...
- json转化的时候如何忽略某些属性字段值
一.有时候在将对象或list对象转化为json的时候,我们可能不需要所有的属性值,这就需要我们去过滤掉这些属性了 我下面说两种比较流行的json包如何来忽略某些属性值 二. 使用jaskson包 1. ...
随机推荐
- Entity Framework 学习初级篇6--EntityClient
System.Data.EntityClient 命名空间是 实体框架的 .NET Framework 数据提供程序.EntityClient 提供程序使用存储特定的 ADO.NET 数据提供程序类和 ...
- mysql链接表,connection string, federated engine
http://database.51cto.com/art/201011/234561.htm
- java调用dll-JNA
介绍 给大家介绍一个最新的访问本机代码的 Java 框架 —JNA . JNA(Java Native Access) 框架是一个开源的 Java 框架,是 SUN 公司主导开发的,建立在经典的 JN ...
- 兼容性,float
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- jdbc批量执行SQL insert 操作
package com.file; import java.io.BufferedReader; import java.io.FileReader; import java.util.ArrayLi ...
- ormlite 批处理操作
提高ormlite的批处理速度 http://stackoverflow.com/quegoogstions/11761472/ormlites-createorupdate-seems-slow-w ...
- 手把手教你使用startuml画用例图
转自:http://www.2cto.com/os/201502/377091.html 最近准备研究下volley的源码,但看了网上一些大牛的博客都是配合图这样看起来更直观,分析起来逻辑也很好,什么 ...
- 原生的ajax(json)
function getXHR(){ if(window.XMLHttpRequest){ return new XMLHttpRequest(); }else{ try{ return new Ac ...
- 使用bootstrap建立响应式网页——头部导航栏
1.要建立响应式网站的布局,这个时候bootstrap的高级就能体现出来了. 2.先来了解一下bootstrap提供了哪些响应式工具供我们使用: (1)屏幕宽度尺寸的概念: <768px ...
- Linux 高可用(HA)集群基本概念详解
大纲一.高可用集群的定义二.高可用集群的衡量标准三.高可用集群的层次结构四.高可用集群的分类 五.高可用集群常用软件六.共享存储七.集群文件系统与集群LVM八.高可用集群的工作原理 推荐阅读: Cen ...