qgis二次开发矢量数据点选择的方法
来源:互联网 发布:linux smp调度 编辑:程序博客网 时间:2024/05/22 01:47
qgis网上的资料比较少,能找到的资料就那么几篇基本的加载图层之类的,最主要还是参考qgis本身的源码和其api文档。
在这里感谢qgis群同时也是地大群的大哥的指导。
qgis程序是C++和qt平台编译出来的可执行文件。
其中MapCanvas保存了一个指针指向当前的tool,tool里面有各种响应鼠标等事件。
MapCanvas中的响应系统鼠标事件,调用tool的事件
其中鼠标Middle单击事件,被定义为pan(tool)的事件
tool可以setAction,也可以设置按键。(效果应该等同于Action的trigger信号
绑定MapCanvas,设置mapcanvas的当前tool。
)
还可以设置cursor设置鼠标的形状(手型)
所以在知道qgis的tool功能的基础上找到源码中的selecttool,将selecttool移植到
自己的程序中。
注意:这移植的过程中,也出现了一些问题,以为可以调用qgisapp的库进行移植,
但是移植过程中出现了一系列的错误。所以最后还是只调用qgis的核心库
//QgsVectorLayer* vlayer = QgsMapToolSelectUtils::getCurrentVectorLayer( mCanvas );
//这一行的功能为选择当前的矢量图层,改成如下代码:
QgsVectorLayer* vlayer = NULL;
if ( !canvas->currentLayer()
|| ( vlayer = qobject_cast<QgsVectorLayer *>( canvas->currentLayer() ) ) == NULL )
{
QMessageBoox::information(...);
}
if ( vlayer == NULL )
{
return;
}
QgsRubberBand *rubberBand = new QgsRubberBand( mCanvas, QGis::Polygon );
QRect selectRect( 0, 0, 0, 0 );
//QgsMapToolSelectUtils::expandSelectRectangle( selectRect, vlayer, e->pos() );
//这行代码的意义在于将点的范围扩大。
int boxSize = 0;
if ( vlayer->geometryType() != QGis::Polygon )
{
//if point or line use an artificial bounding box of 10x10 pixels
//to aid the user to click on a feature accurately
boxSize = 5;
}
else
{
//otherwise just use the click point for polys
boxSize = 1;
}
selectRect.setLeft( point.x() - boxSize );
selectRect.setRight( point.x() + boxSize );
selectRect.setTop( point.y() - boxSize );
selectRect.setBottom( point.y() + boxSize );
//
// QgsMapToolSelectUtils::setRubberBand( mCanvas, selectRect, &rubberBand );
const QgsMapToPixel* transform = canvas->getCoordinateTransform();
QgsPoint ll = transform->toMapCoordinates( selectRect.left(), selectRect.bottom() );
QgsPoint ur = transform->toMapCoordinates( selectRect.right(), selectRect.top() );
if ( rubberBand )
{
rubberBand->reset( QGis::Polygon );
rubberBand->addPoint( ll, false );
rubberBand->addPoint( QgsPoint( ur.x(), ll.y() ), false );
rubberBand->addPoint( ur, false );
rubberBand->addPoint( QgsPoint( ll.x(), ur.y() ), true );
}
QgsGeometry* selectGeom = rubberBand.asGeometry();
bool doDifference = e->modifiers() & Qt::ControlModifier ? true : false;
// QgsMapToolSelectUtils::setSelectFeatures( mCanvas, selectGeom, false, doDifference, true );
//这一行才是选择的功能
if ( selectGeometry->type() != QGis::Polygon )
{
return;
}
QgsVectorLayer* vlayer = QgsMapToolSelectUtils::getCurrentVectorLayer( canvas );
if ( vlayer == NULL )
{
return;
}
// toLayerCoordinates will throw an exception for any 'invalid' points in
// the rubber band.
// For example, if you project a world map onto a globe using EPSG 2163
// and then click somewhere off the globe, an exception will be thrown.
QgsGeometry selectGeomTrans( *selectGeometry );
if ( canvas->mapSettings().hasCrsTransformEnabled() )
{
try
{
QgsCoordinateTransform ct( canvas->mapSettings().destinationCrs(), vlayer->crs() );
selectGeomTrans.transform( ct );
}
catch ( QgsCsException &cse )
{
Q_UNUSED( cse );
// catch exception for 'invalid' point and leave existing selection unchanged
// QgsLogger::warning( "Caught CRS exception " + QString( __FILE__ ) + ": " + QString::number( __LINE__ ) );
QMessageBox::warning( canvas, QObject::tr( "CRS Exception" ),
QObject::tr( "Selection extends beyond layer's coordinate system." ) );
return;
}
}
QApplication::setOverrideCursor( Qt::WaitCursor );
QgsDebugMsg( "Selection layer: " + vlayer->name() );
QgsDebugMsg( "Selection polygon: " + selectGeomTrans.exportToWkt() );
QgsDebugMsg( "doContains: " + QString( doContains ? "T" : "F" ) );
QgsDebugMsg( "doDifference: " + QString( doDifference ? "T" : "F" ) );
QgsFeatureIterator fit = vlayer->getFeatures( QgsFeatureRequest().setFilterRect( selectGeomTrans.boundingBox() ).setFlags( QgsFeatureRequest::ExactIntersect ).setSubsetOfAttributes( QgsAttributeList() ) );
QgsFeatureIds newSelectedFeatures;
QgsFeature f;
QgsFeatureId closestFeatureId = 0;
bool foundSingleFeature = false;
double closestFeatureDist = std::numeric_limits<double>::max();
while ( fit.nextFeature( f ) )
{
QgsGeometry* g = f.geometry();
//if ( doContains )
// {
if ( !selectGeomTrans.contains( g ) )
continue;
// }
// else
// {
// if ( !selectGeomTrans.intersects( g ) )
// continue;
// }
//if ( singleSelect )
// {
foundSingleFeature = true;
double distance = g->distance( selectGeomTrans );
if ( distance <= closestFeatureDist )
{
closestFeatureDist = distance;
closestFeatureId = f.id();
}
// }
// else
// {
// newSelectedFeatures.insert( f.id() );
// }
}
if ( /*singleSelect &&*/ foundSingleFeature )
{
newSelectedFeatures.insert( closestFeatureId );
}
QgsDebugMsg( "Number of new selected features: " + QString::number( newSelectedFeatures.size() ) );
if ( doDifference )
{
QgsFeatureIds layerSelectedFeatures = vlayer->selectedFeaturesIds();
QgsFeatureIds selectedFeatures;
QgsFeatureIds deselectedFeatures;
QgsFeatureIds::const_iterator i = newSelectedFeatures.constEnd();
while ( i != newSelectedFeatures.constBegin() )
{
--i;
if ( layerSelectedFeatures.contains( *i ) )
{
deselectedFeatures.insert( *i );
}
else
{
selectedFeatures.insert( *i );
}
}
vlayer->modifySelection( selectedFeatures, deselectedFeatures );
}
else
{
vlayer->setSelectedFeatures( newSelectedFeatures );
}
QApplication::restoreOverrideCursor();
delete selectGeom;
rubberBand.reset( QGis::Polygon );
- qgis二次开发矢量数据点选择的方法
- QGis二次开发基础 -- 添加矢量要素功能
- QGis二次开发基础 -- 添加矢量要素功能
- QGis 二次开发基础 -- 显示数据
- QGis 二次开发基础 -- 显示数据
- QGIS二次开发,我的第一篇
- Qgis 数据的入库
- Qgis应用-矢量操作
- QGIS二次开发第一讲
- QGIS二次开发第二讲
- QGIS二次开发第三讲
- QGIS二次开发第四讲
- QGIS二次开发第一讲
- QGIS二次开发第二讲
- QGIS二次开发第三讲
- QGIS二次开发第四讲
- qgis二次开发之编译
- Python qgis二次开发
- git commmit -m注释中换行问题
- 利用JDBC连接Oracle数据库
- 下拉刷新功能的实现。
- Tomcat 5.5 JNDI Resource 配置 (tomcat数据源配置)
- 关于图片延迟加载技术-ImageLazyLoad
- qgis二次开发矢量数据点选择的方法
- Spring MVC 文件上传下载 方法二
- Python 字符填充问题
- jni学习环境搭建
- VC获取文件大小的方法
- Android中预估view的大小(宽高)
- 用java实现打印功能
- Android开发_如何实现留言意见反馈功能界面
- 从贝叶斯方法谈到贝叶斯网络