Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Update to limit of number of features sent to PAL
- Distributes max number across total number of features registered in PAL
- Caveat: PAL may not show label for every registered feature
  • Loading branch information
dakcarto committed Nov 16, 2012
1 parent 9183adc commit e3d30af
Show file tree
Hide file tree
Showing 7 changed files with 67 additions and 15 deletions.
3 changes: 3 additions & 0 deletions python/core/qgsmaprenderer.sip
Expand Up @@ -40,6 +40,9 @@ class QgsLabelingEngineInterface
//! called when starting rendering of a layer
//! @note: this method was added in version 1.6
virtual int prepareLayer( QgsVectorLayer* layer, QSet<int>& attrIndices, QgsRenderContext& ctx ) = 0;
//! returns PAL layer settings for a registered layer
//! @note: this method was added in version 1.9
virtual QgsPalLayerSettings& layer( const QString& layerName ) = 0;
//! adds a diagram layer to the labeling engine
virtual int addDiagramLayer( QgsVectorLayer* layer, QgsDiagramLayerSettings* s );
//! called for every feature
Expand Down
2 changes: 0 additions & 2 deletions python/core/qgspallabeling.sip
Expand Up @@ -126,8 +126,6 @@ class QgsPalLayerSettings
double minFeatureSize; // minimum feature size to be labelled (in mm)
bool limitNumLabels; // whether to limit the number of labels to be drawn
int maxNumLabels; // maximum number of labels to be drawn
//bool rndMaxNumLabels; // whether to take a randomized maxNumLabels subset of features to be labeled

// Adds '<' or '>', or user-defined symbol to the label string pointing to the
// direction of the line / polygon ring
// Works only if Placement == Line
Expand Down
4 changes: 4 additions & 0 deletions src/core/qgsmaprenderer.h
Expand Up @@ -39,6 +39,7 @@ class QgsDistanceArea;
class QgsOverlayObjectPositionManager;
class QgsVectorLayer;

class QgsPalLayerSettings;
class QgsDiagramLayerSettings;

class CORE_EXPORT QgsLabelPosition
Expand Down Expand Up @@ -75,6 +76,9 @@ class CORE_EXPORT QgsLabelingEngineInterface
//! called when starting rendering of a layer
//! @note: this method was added in version 1.6
virtual int prepareLayer( QgsVectorLayer* layer, QSet<int>& attrIndices, QgsRenderContext& ctx ) = 0;
//! returns PAL layer settings for a registered layer
//! @note: this method was added in version 1.9
virtual QgsPalLayerSettings& layer( const QString& layerName ) = 0;
//! adds a diagram layer to the labeling engine
virtual int addDiagramLayer( QgsVectorLayer* layer, QgsDiagramLayerSettings* s )
{ Q_UNUSED( layer ); Q_UNUSED( s ); return 0; }
Expand Down
44 changes: 36 additions & 8 deletions src/core/qgspallabeling.cpp
Expand Up @@ -177,7 +177,7 @@ class QgsPalGeometry : public PalGeometry
// -------------

QgsPalLayerSettings::QgsPalLayerSettings()
: palLayer( NULL ), ct( NULL ), extentGeom( NULL ), expression( NULL )
: palLayer( NULL ), ct( NULL ), extentGeom( NULL ), mFeaturesToLabel( 0 ), mFeatsSendingToPal( 0 ), mFeatsRegPal( 0 ), expression( NULL )
{
placement = AroundPoint;
placementFlags = 0;
Expand Down Expand Up @@ -658,13 +658,6 @@ void QgsPalLayerSettings::calculateLabelSize( const QFontMetricsF* fm, QString t

void QgsPalLayerSettings::registerFeature( QgsVectorLayer* layer, QgsFeature& f, const QgsRenderContext& context )
{

// check if max number of labels to draw (already registered features) has been reached
if ( limitNumLabels && ( maxNumLabels == 0 || palLayer->getNbFeatures() >= maxNumLabels ) )
{
return;
}

// data defined show label? defaults to show label if not 0
QMap< DataDefinedProperties, int >::const_iterator showIt = dataDefinedProperties.find( QgsPalLayerSettings::Show );
if ( showIt != dataDefinedProperties.constEnd() )
Expand Down Expand Up @@ -822,6 +815,32 @@ void QgsPalLayerSettings::registerFeature( QgsVectorLayer* layer, QgsFeature& f
if ( geos_geom == NULL )
return; // invalid geometry

// likelihood exists label will be registered with PAL and may be drawn
// check if max number of features to label (already registered with PAL) has been reached
// Debug output at end of QgsPalLabeling::drawLabeling(), when deleting temp geometries
if ( limitNumLabels )
{
if ( !maxNumLabels )
{
return;
}
mFeatsRegPal = palLayer->getNbFeatures();
if ( mFeatsRegPal >= maxNumLabels )
{
return;
}

int divNum = ( int )(( mFeaturesToLabel / maxNumLabels ) + 0.5 );
if ( divNum && ( mFeatsRegPal == ( int )( mFeatsSendingToPal / divNum ) ) )
{
mFeatsSendingToPal += 1;
if ( divNum && mFeatsSendingToPal % divNum )
{
return;
}
}
}

GEOSGeometry* geos_geom_clone = GEOSGeom_clone( geos_geom );

//data defined position / alignment / rotation?
Expand Down Expand Up @@ -1259,6 +1278,8 @@ int QgsPalLabeling::prepareLayer( QgsVectorLayer* layer, QSet<int>& attrIndices,
// rect for clipping
lyr.extentGeom = QgsGeometry::fromRect( mMapRenderer->extent() );

lyr.mFeatsSendingToPal = 0;

return 1; // init successful
}

Expand Down Expand Up @@ -1656,6 +1677,13 @@ void QgsPalLabeling::drawLabeling( QgsRenderContext& context )
QgsPalLayerSettings& lyr = lit.value();
for ( QList<QgsPalGeometry*>::iterator git = lyr.geometries.begin(); git != lyr.geometries.end(); ++git )
delete *git;
if ( lyr.limitNumLabels )
{
QgsDebugMsg( QString( "mFeaturesToLabel: %1" ).arg( lyr.mFeaturesToLabel ) );
QgsDebugMsg( QString( "maxNumLabels: %1" ).arg( lyr.maxNumLabels ) );
QgsDebugMsg( QString( "mFeatsSendingToPal: %1" ).arg( lyr.mFeatsSendingToPal ) );
QgsDebugMsg( QString( "mFeatsRegPal: %1" ).arg( lyr.geometries.count() ) );
}
lyr.geometries.clear();
}

Expand Down
7 changes: 4 additions & 3 deletions src/core/qgspallabeling.h
Expand Up @@ -180,8 +180,6 @@ class CORE_EXPORT QgsPalLayerSettings
double minFeatureSize; // minimum feature size to be labelled (in mm)
bool limitNumLabels; // whether to limit the number of labels to be drawn
int maxNumLabels; // maximum number of labels to be drawn
//bool rndMaxNumLabels; // whether to take a randomized maxNumLabels subset of features to be labeled

// Adds '<' or '>', or user-defined symbol to the label string pointing to the
// direction of the line / polygon ring
// Works only if Placement == Line
Expand Down Expand Up @@ -228,14 +226,17 @@ class CORE_EXPORT QgsPalLayerSettings
@return font pixel size*/
int sizeToPixel( double size, const QgsRenderContext& c , bool buffer = false ) const;

// temporary stuff: set when layer gets prepared
// temporary stuff: set when layer gets prepared or labeled
pal::Layer* palLayer;
int fieldIndex;
const QgsMapToPixel* xform;
const QgsCoordinateTransform* ct;
QgsPoint ptZero, ptOne;
QList<QgsPalGeometry*> geometries;
QgsGeometry* extentGeom;
int mFeaturesToLabel; // total features that will probably be labeled, may be less (figured before PAL)
int mFeatsSendingToPal; // total features tested for sending into PAL (relative to maxNumLabels)
int mFeatsRegPal; // number of features registered in PAL, when using limitNumLabels

private:
/**Checks if a feature is larger than a minimum size (in mm)
Expand Down
15 changes: 15 additions & 0 deletions src/core/qgsvectorlayer.cpp
Expand Up @@ -5699,6 +5699,21 @@ void QgsVectorLayer::prepareLabelingAndDiagrams( QgsRenderContext& rendererConte
labeling = true;
}

if ( labeling )
{
// see if feature count limit is set for labeling
QgsPalLayerSettings& palyr = rendererContext.labelingEngine()->layer( this->id() );
if ( palyr.limitNumLabels && palyr.maxNumLabels > 0 )
{
select( QgsAttributeList(), rendererContext.extent() );
// total number of features that may be labeled
QgsFeature ftr;
int nFeatsToLabel = 0;
while ( nextFeature( ftr ) ) { nFeatsToLabel += 1; }
palyr.mFeaturesToLabel = nFeatsToLabel;
}
}

//register diagram layers
if ( mDiagramRenderer && mDiagramLayerSettings )
{
Expand Down
7 changes: 5 additions & 2 deletions src/ui/qgslabelingguibase.ui
Expand Up @@ -2780,7 +2780,7 @@
</sizepolicy>
</property>
<property name="text">
<string>Limit number of labels drawn to</string>
<string>Limit number of features to be labeled to</string>
</property>
</widget>
</item>
Expand All @@ -2795,6 +2795,9 @@
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>Number of features sent to labeling engine, though not all may be labeled</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
Expand Down Expand Up @@ -2855,7 +2858,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>686</width>
<width>488</width>
<height>981</height>
</rect>
</property>
Expand Down

0 comments on commit e3d30af

Please sign in to comment.