void QgsMapHitTest::runHitTestLayer( QgsVectorLayer* vl, SymbolV2Set& usedSymbols, QgsRenderContext& context ) { QgsFeatureRendererV2* r = vl->rendererV2(); bool moreSymbolsPerFeature = r->capabilities() & QgsFeatureRendererV2::MoreSymbolsPerFeature; r->startRender( context, vl->fields() ); QgsFeature f; QgsFeatureRequest request( context.extent() ); request.setFlags( QgsFeatureRequest::ExactIntersect ); QgsFeatureIterator fi = vl->getFeatures( request ); while ( fi.nextFeature( f ) ) { context.expressionContext().setFeature( f ); if ( moreSymbolsPerFeature ) { Q_FOREACH ( QgsSymbolV2* s, r->originalSymbolsForFeature( f, context ) ) usedSymbols.insert( s ); } else usedSymbols.insert( r->originalSymbolForFeature( f, context ) ); } r->stopRender( context ); }
bool QgsMapToolIdentify::identifyVectorLayer( QList<IdentifyResult> *results, QgsVectorLayer *layer, const QgsPoint& point ) { if ( !layer || !layer->hasGeometryType() ) return false; if ( layer->hasScaleBasedVisibility() && ( layer->minimumScale() > mCanvas->mapSettings().scale() || layer->maximumScale() <= mCanvas->mapSettings().scale() ) ) { QgsDebugMsg( "Out of scale limits" ); return false; } QApplication::setOverrideCursor( Qt::WaitCursor ); QMap< QString, QString > commonDerivedAttributes; commonDerivedAttributes.insert( tr( "(clicked coordinate)" ), point.toString() ); int featureCount = 0; QgsFeatureList featureList; // toLayerCoordinates will throw an exception for an 'invalid' point. // 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. try { // create the search rectangle double searchRadius = searchRadiusMU( mCanvas ); QgsRectangle r; r.setXMinimum( point.x() - searchRadius ); r.setXMaximum( point.x() + searchRadius ); r.setYMinimum( point.y() - searchRadius ); r.setYMaximum( point.y() + searchRadius ); r = toLayerCoordinates( layer, r ); QgsFeatureIterator fit = layer->getFeatures( QgsFeatureRequest().setFilterRect( r ).setFlags( QgsFeatureRequest::ExactIntersect ) ); QgsFeature f; while ( fit.nextFeature( f ) ) featureList << QgsFeature( f ); } catch ( QgsCsException & cse ) { Q_UNUSED( cse ); // catch exception for 'invalid' point and proceed with no features found QgsDebugMsg( QString( "Caught CRS exception %1" ).arg( cse.what() ) ); } QgsFeatureList::iterator f_it = featureList.begin(); bool filter = false; QgsRenderContext context( QgsRenderContext::fromMapSettings( mCanvas->mapSettings() ) ); context.expressionContext() << QgsExpressionContextUtils::layerScope( layer ); QgsFeatureRendererV2* renderer = layer->rendererV2(); if ( renderer && renderer->capabilities() & QgsFeatureRendererV2::ScaleDependent ) { // setup scale for scale dependent visibility (rule based) renderer->startRender( context, layer->fields() ); filter = renderer->capabilities() & QgsFeatureRendererV2::Filter; } for ( ; f_it != featureList.end(); ++f_it ) { QMap< QString, QString > derivedAttributes = commonDerivedAttributes; QgsFeatureId fid = f_it->id(); context.expressionContext().setFeature( *f_it ); if ( filter && !renderer->willRenderFeature( *f_it, context ) ) continue; featureCount++; derivedAttributes.unite( featureDerivedAttributes( &( *f_it ), layer, toLayerCoordinates( layer, point ) ) ); derivedAttributes.insert( tr( "feature id" ), fid < 0 ? tr( "new feature" ) : FID_TO_STRING( fid ) ); results->append( IdentifyResult( qobject_cast<QgsMapLayer *>( layer ), *f_it, derivedAttributes ) ); } if ( renderer && renderer->capabilities() & QgsFeatureRendererV2::ScaleDependent ) { renderer->stopRender( context ); } QgsDebugMsg( "Feature count on identify: " + QString::number( featureCount ) ); QApplication::restoreOverrideCursor(); return featureCount > 0; }
void QgsAttributeTableFilterModel::generateListOfVisibleFeatures() { if ( !layer() ) return; bool filter = false; QgsRectangle rect = mCanvas->mapSettings().mapToLayerCoordinates( layer(), mCanvas->extent() ); QgsRenderContext renderContext; renderContext.expressionContext() << QgsExpressionContextUtils::globalScope() << QgsExpressionContextUtils::projectScope() << QgsExpressionContextUtils::layerScope( layer() ); QgsFeatureRendererV2* renderer = layer()->rendererV2(); mFilteredFeatures.clear(); if ( !renderer ) { QgsDebugMsg( "Cannot get renderer" ); return; } const QgsMapSettings& ms = mCanvas->mapSettings(); if ( layer()->hasScaleBasedVisibility() && ( layer()->minimumScale() > ms.scale() || layer()->maximumScale() <= ms.scale() ) ) { QgsDebugMsg( "Out of scale limits" ); } else { if ( renderer && renderer->capabilities() & QgsFeatureRendererV2::ScaleDependent ) { // setup scale // mapRenderer()->renderContext()->scale is not automaticaly updated when // render extent changes (because it's scale is used to identify if changed // since last render) -> use local context renderContext.setExtent( ms.visibleExtent() ); renderContext.setMapToPixel( ms.mapToPixel() ); renderContext.setRendererScale( ms.scale() ); } filter = renderer && renderer->capabilities() & QgsFeatureRendererV2::Filter; } renderer->startRender( renderContext, layer()->fields() ); QgsFeatureRequest r( masterModel()->request() ); if ( !r.filterRect().isNull() ) { r.setFilterRect( r.filterRect().intersect( &rect ) ); } else { r.setFilterRect( rect ); } QgsFeatureIterator features = masterModel()->layerCache()->getFeatures( r ); QgsFeature f; while ( features.nextFeature( f ) ) { renderContext.expressionContext().setFeature( f ); if ( !filter || renderer->willRenderFeature( f, renderContext ) ) { mFilteredFeatures << f.id(); } #if 0 if ( t.elapsed() > 5000 ) { bool cancel = false; emit progress( i, cancel ); if ( cancel ) break; t.restart(); } #endif } features.close(); if ( renderer && renderer->capabilities() & QgsFeatureRendererV2::ScaleDependent ) { renderer->stopRender( renderContext ); } }
void QgsMapToolSelectUtils::setSelectFeatures( QgsMapCanvas* canvas, QgsGeometry* selectGeometry, bool doContains, bool doDifference, bool singleSelect ) { if ( selectGeometry->type() != QGis::Polygon ) { return; } QgsVectorLayer* vlayer = QgsMapToolSelectUtils::getCurrentVectorLayer( canvas ); if ( vlayer == nullptr ) { 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__ ) ); // LOG_INFO( "CRS Exception\nSelection extends beyond layer's coordinate system" ); // return; // } //} QgsGeometry selectGeomTrans; try{ selectGeomTrans = toLayerCoordinates( canvas, selectGeometry, vlayer ); } catch ( QgsCsException & ) { 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" ) ); QgsRenderContext context = QgsRenderContext::fromMapSettings( canvas->mapSettings() ); QgsFeatureRendererV2* r = vlayer->rendererV2(); if ( r ) r->startRender( context, vlayer->pendingFields() ); QgsFeatureRequest request; request.setFilterRect( selectGeomTrans.boundingBox() ); request.setFlags( QgsFeatureRequest::ExactIntersect ); if ( r ) request.setSubsetOfAttributes( r->usedAttributes(), vlayer->pendingFields() ); else request.setSubsetOfAttributes( QgsAttributeList() ); QgsFeatureIterator fit = vlayer->getFeatures( request ); QgsFeatureIds newSelectedFeatures; QgsFeature f; QgsFeatureId closestFeatureId = 0; bool foundSingleFeature = false; double closestFeatureDist = std::numeric_limits<double>::max(); while ( fit.nextFeature( f ) ) { #if (VERSION_INT >= 21601) context.expressionContext().setFeature( f ); //taken from QGIS 2.16.1 // make sure to only use features that are visible if ( r && !r->willRenderFeature( f, context ) ) #else if ( r && !r->willRenderFeature( f ) ) #endif continue; 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 ); } if ( r ) r->stopRender( context ); 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 { SelectFeatures( vlayer, newSelectedFeatures ); // vlayer->setSelectedFeatures( newSelectedFeatures ); } QApplication::restoreOverrideCursor(); }
void QgsDxfExport::writeEntitiesSymbolLevels( QgsVectorLayer* layer ) { if ( !layer ) { return; } QgsFeatureRendererV2* renderer = layer->rendererV2(); if ( !renderer ) { //return error } QHash< QgsSymbolV2*, QList<QgsFeature> > features; QgsRenderContext ctx = renderContext(); QgsSymbolV2RenderContext sctx( ctx, QgsSymbolV2::MM , 1.0, false, 0, 0 ); renderer->startRender( ctx, layer->pendingFields() ); //get iterator QgsFeatureRequest req; if ( layer->wkbType() == QGis::WKBNoGeometry ) { req.setFlags( QgsFeatureRequest::NoGeometry ); } req.setSubsetOfAttributes( QStringList( renderer->usedAttributes() ), layer->pendingFields() ); if ( !mExtent.isEmpty() ) { req.setFilterRect( mExtent ); } QgsFeatureIterator fit = layer->getFeatures( req ); //fetch features QgsFeature fet; QgsSymbolV2* featureSymbol = 0; while ( fit.nextFeature( fet ) ) { featureSymbol = renderer->symbolForFeature( fet ); if ( !featureSymbol ) { continue; } QHash< QgsSymbolV2*, QList<QgsFeature> >::iterator it = features.find( featureSymbol ); if ( it == features.end() ) { it = features.insert( featureSymbol, QList<QgsFeature>() ); } it.value().append( fet ); } //find out order QgsSymbolV2LevelOrder levels; QgsSymbolV2List symbols = renderer->symbols(); for ( int i = 0; i < symbols.count(); i++ ) { QgsSymbolV2* sym = symbols[i]; for ( int j = 0; j < sym->symbolLayerCount(); j++ ) { int level = sym->symbolLayer( j )->renderingPass(); if ( level < 0 || level >= 1000 ) // ignore invalid levels continue; QgsSymbolV2LevelItem item( sym, j ); while ( level >= levels.count() ) // append new empty levels levels.append( QgsSymbolV2Level() ); levels[level].append( item ); } } //export symbol layers and symbology for ( int l = 0; l < levels.count(); l++ ) { QgsSymbolV2Level& level = levels[l]; for ( int i = 0; i < level.count(); i++ ) { QgsSymbolV2LevelItem& item = level[i]; QHash< QgsSymbolV2*, QList<QgsFeature> >::iterator levelIt = features.find( item.symbol() ); int llayer = item.layer(); QList<QgsFeature>& featureList = levelIt.value(); QList<QgsFeature>::iterator featureIt = featureList.begin(); for ( ; featureIt != featureList.end(); ++featureIt ) { addFeature( sctx, layer->name(), levelIt.key()->symbolLayer( llayer ), levelIt.key() ); } } } renderer->stopRender( ctx ); }
void QgsDxfExport::writeEntities() { startSection(); writeGroup( 2, "ENTITIES" ); //label engine QgsDxfPalLabeling labelEngine( this, mExtent.isEmpty() ? dxfExtent() : mExtent, mSymbologyScaleDenominator, mMapUnits ); QgsRenderContext& ctx = labelEngine.renderContext(); //iterate through the maplayers QList< QgsMapLayer* >::iterator layerIt = mLayers.begin(); for ( ; layerIt != mLayers.end(); ++layerIt ) { QgsVectorLayer* vl = qobject_cast<QgsVectorLayer*>( *layerIt ); if ( !vl || !layerIsScaleBasedVisible( vl ) ) { continue; } QgsSymbolV2RenderContext sctx( ctx, QgsSymbolV2::MM , 1.0, false, 0, 0 ); QgsFeatureRendererV2* renderer = vl->rendererV2(); renderer->startRender( ctx, vl->pendingFields() ); QStringList attributes = renderer->usedAttributes(); bool labelLayer = ( labelEngine.prepareLayer( vl, attributes, ctx ) != 0 ); if ( mSymbologyExport == QgsDxfExport::SymbolLayerSymbology && ( renderer->capabilities() & QgsFeatureRendererV2::SymbolLevels ) && renderer->usingSymbolLevels() ) { writeEntitiesSymbolLevels( vl ); renderer->stopRender( ctx ); continue; } QgsFeatureRequest freq = QgsFeatureRequest().setSubsetOfAttributes( attributes, vl->pendingFields() ); if ( !mExtent.isEmpty() ) { freq.setFilterRect( mExtent ); } QgsFeatureIterator featureIt = vl->getFeatures( freq ); QgsFeature fet; while ( featureIt.nextFeature( fet ) ) { sctx.setFeature( &fet ); if ( mSymbologyExport == NoSymbology ) { addFeature( sctx, dxfLayerName( vl->name() ), 0, 0 ); //no symbology at all } else { if ( !renderer ) { continue; } QgsSymbolV2List symbolList = renderer->symbolsForFeature( fet ); if ( symbolList.size() < 1 ) { continue; } if ( mSymbologyExport == QgsDxfExport::SymbolLayerSymbology ) //symbol layer symbology, but layer does not use symbol levels { QgsSymbolV2List::iterator symbolIt = symbolList.begin(); for ( ; symbolIt != symbolList.end(); ++symbolIt ) { int nSymbolLayers = ( *symbolIt )->symbolLayerCount(); for ( int i = 0; i < nSymbolLayers; ++i ) { addFeature( sctx, dxfLayerName( vl->name() ), ( *symbolIt )->symbolLayer( i ), *symbolIt ); } } } else { //take first symbollayer from first symbol QgsSymbolV2* s = symbolList.first(); if ( !s || s->symbolLayerCount() < 1 ) { continue; } addFeature( sctx, dxfLayerName( vl->name() ), s->symbolLayer( 0 ), s ); } if ( labelLayer ) { labelEngine.registerFeature( vl->id(), fet, ctx ); } } } renderer->stopRender( ctx ); } labelEngine.drawLabeling( ctx ); endSection(); }
bool QgsMapToolIdentify::identifyVectorLayer( QList<IdentifyResult> *results, QgsVectorLayer *layer, QgsPoint point ) { if ( !layer ) return false; if ( layer->hasScaleBasedVisibility() && ( layer->minimumScale() > mCanvas->mapRenderer()->scale() || layer->maximumScale() <= mCanvas->mapRenderer()->scale() ) ) { QgsDebugMsg( "Out of scale limits" ); return false; } QMap< QString, QString > derivedAttributes; derivedAttributes.insert( tr( "(clicked coordinate)" ), point.toString() ); // load identify radius from settings QSettings settings; double identifyValue = settings.value( "/Map/identifyRadius", QGis::DEFAULT_IDENTIFY_RADIUS ).toDouble(); if ( identifyValue <= 0.0 ) identifyValue = QGis::DEFAULT_IDENTIFY_RADIUS; int featureCount = 0; QgsFeatureList featureList; // toLayerCoordinates will throw an exception for an 'invalid' point. // 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. try { // create the search rectangle double searchRadius = mCanvas->extent().width() * ( identifyValue / 100.0 ); QgsRectangle r; r.setXMinimum( point.x() - searchRadius ); r.setXMaximum( point.x() + searchRadius ); r.setYMinimum( point.y() - searchRadius ); r.setYMaximum( point.y() + searchRadius ); r = toLayerCoordinates( layer, r ); QgsFeatureIterator fit = layer->getFeatures( QgsFeatureRequest().setFilterRect( r ).setFlags( QgsFeatureRequest::ExactIntersect ) ); QgsFeature f; while ( fit.nextFeature( f ) ) featureList << QgsFeature( f ); } catch ( QgsCsException & cse ) { Q_UNUSED( cse ); // catch exception for 'invalid' point and proceed with no features found QgsDebugMsg( QString( "Caught CRS exception %1" ).arg( cse.what() ) ); } QgsFeatureList::iterator f_it = featureList.begin(); bool filter = false; QgsFeatureRendererV2* renderer = layer->rendererV2(); if ( renderer && renderer->capabilities() & QgsFeatureRendererV2::ScaleDependent ) { // setup scale for scale dependent visibility (rule based) renderer->startRender( *( mCanvas->mapRenderer()->rendererContext() ), layer ); filter = renderer->capabilities() & QgsFeatureRendererV2::Filter; } for ( ; f_it != featureList.end(); ++f_it ) { QgsFeatureId fid = f_it->id(); if ( filter && !renderer->willRenderFeature( *f_it ) ) continue; featureCount++; derivedAttributes.unite( featureDerivedAttributes( &( *f_it ), layer ) ); derivedAttributes.insert( tr( "feature id" ), fid < 0 ? tr( "new feature" ) : FID_TO_STRING( fid ) ); results->append( IdentifyResult( qobject_cast<QgsMapLayer *>( layer ), *f_it, derivedAttributes ) ); } if ( renderer && renderer->capabilities() & QgsFeatureRendererV2::ScaleDependent ) { renderer->stopRender( *( mCanvas->mapRenderer()->rendererContext() ) ); } QgsDebugMsg( "Feature count on identify: " + QString::number( featureCount ) ); return featureCount > 0; }
bool QgsMapToolIdentify::identifyVectorLayer( QgsVectorLayer *layer, int x, int y ) { if ( !layer || !layer->rendererV2() ) return false; if ( layer->hasScaleBasedVisibility() && ( layer->minimumScale() > mCanvas->mapRenderer()->scale() || layer->maximumScale() <= mCanvas->mapRenderer()->scale() ) ) { QgsDebugMsg( "Out of scale limits" ); return false; } QgsFeatureRendererV2* renderer = layer->rendererV2(); QMap< QString, QString > attributes, derivedAttributes; QgsPoint point = mCanvas->getCoordinateTransform()->toMapCoordinates( x, y ); derivedAttributes.insert( tr( "(clicked coordinate)" ), point.toString() ); // load identify radius from settings QSettings settings; double identifyValue = settings.value( "/Map/identifyRadius", QGis::DEFAULT_IDENTIFY_RADIUS ).toDouble(); QString ellipsoid = settings.value( "/qgis/measure/ellipsoid", GEO_NONE ).toString(); if ( identifyValue <= 0.0 ) identifyValue = QGis::DEFAULT_IDENTIFY_RADIUS; int featureCount = 0; QgsFeatureList featureList; // toLayerCoordinates will throw an exception for an 'invalid' point. // 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. try { // create the search rectangle double searchRadius = mCanvas->extent().width() * ( identifyValue / 100.0 ); QgsRectangle r; r.setXMinimum( point.x() - searchRadius ); r.setXMaximum( point.x() + searchRadius ); r.setYMinimum( point.y() - searchRadius ); r.setYMaximum( point.y() + searchRadius ); r = toLayerCoordinates( layer, r ); layer->select( layer->pendingAllAttributesList(), r, true, true ); QgsFeature f; while ( layer->nextFeature( f ) ) featureList << QgsFeature( f ); } catch ( QgsCsException & cse ) { Q_UNUSED( cse ); // catch exception for 'invalid' point and proceed with no features found QgsDebugMsg( QString( "Caught CRS exception %1" ).arg( cse.what() ) ); } // init distance/area calculator QgsDistanceArea calc; if ( !featureList.count() == 0 ) { calc.setEllipsoidalMode( mCanvas->hasCrsTransformEnabled() ); calc.setEllipsoid( ellipsoid ); calc.setSourceCrs( layer->crs().srsid() ); } QgsFeatureList::iterator f_it = featureList.begin(); if ( renderer->capabilities() & QgsFeatureRendererV2::ScaleDependent ) { // setup scale for scale dependent visibility (rule based) renderer->startRender( *( mCanvas->mapRenderer()->rendererContext() ), layer ); } bool filter = renderer->capabilities() & QgsFeatureRendererV2::Filter; for ( ; f_it != featureList.end(); ++f_it ) { QgsFeatureId fid = f_it->id(); if ( filter && !renderer->willRenderFeature( *f_it ) ) continue; featureCount++; QMap<QString, QString> derivedAttributes; // Calculate derived attributes and insert: // measure distance or area depending on geometry type if ( layer->geometryType() == QGis::Line ) { double dist = calc.measure( f_it->geometry() ); QGis::UnitType myDisplayUnits; convertMeasurement( calc, dist, myDisplayUnits, false ); QString str = calc.textUnit( dist, 3, myDisplayUnits, false ); // dist and myDisplayUnits are out params derivedAttributes.insert( tr( "Length" ), str ); if ( f_it->geometry()->wkbType() == QGis::WKBLineString || f_it->geometry()->wkbType() == QGis::WKBLineString25D ) { // Add the start and end points in as derived attributes str = QLocale::system().toString( f_it->geometry()->asPolyline().first().x(), 'g', 10 ); derivedAttributes.insert( tr( "firstX", "attributes get sorted; translation for lastX should be lexically larger than this one" ), str ); str = QLocale::system().toString( f_it->geometry()->asPolyline().first().y(), 'g', 10 ); derivedAttributes.insert( tr( "firstY" ), str ); str = QLocale::system().toString( f_it->geometry()->asPolyline().last().x(), 'g', 10 ); derivedAttributes.insert( tr( "lastX", "attributes get sorted; translation for firstX should be lexically smaller than this one" ), str ); str = QLocale::system().toString( f_it->geometry()->asPolyline().last().y(), 'g', 10 ); derivedAttributes.insert( tr( "lastY" ), str ); } } else if ( layer->geometryType() == QGis::Polygon ) { double area = calc.measure( f_it->geometry() ); QGis::UnitType myDisplayUnits; convertMeasurement( calc, area, myDisplayUnits, true ); // area and myDisplayUnits are out params QString str = calc.textUnit( area, 3, myDisplayUnits, true ); derivedAttributes.insert( tr( "Area" ), str ); } else if ( layer->geometryType() == QGis::Point && ( f_it->geometry()->wkbType() == QGis::WKBPoint || f_it->geometry()->wkbType() == QGis::WKBPoint25D ) ) { // Include the x and y coordinates of the point as a derived attribute QString str; str = QLocale::system().toString( f_it->geometry()->asPoint().x(), 'g', 10 ); derivedAttributes.insert( "X", str ); str = QLocale::system().toString( f_it->geometry()->asPoint().y(), 'g', 10 ); derivedAttributes.insert( "Y", str ); } derivedAttributes.insert( tr( "feature id" ), fid < 0 ? tr( "new feature" ) : FID_TO_STRING( fid ) ); results()->addFeature( layer, *f_it, derivedAttributes ); } if ( renderer->capabilities() & QgsFeatureRendererV2::ScaleDependent ) { renderer->stopRender( *( mCanvas->mapRenderer()->rendererContext() ) ); } QgsDebugMsg( "Feature count on identify: " + QString::number( featureCount ) ); return featureCount > 0; }