mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-16 00:03:12 -04:00
Applied patch #2747 from Marco.
git-svn-id: http://svn.osgeo.org/qgis/trunk@13587 c8812cc2-4d05-0410-92ff-de0c093fc19c
This commit is contained in:
parent
546b279cd1
commit
3b280fa705
@ -19,7 +19,7 @@ public:
|
|||||||
//! called when starting rendering of a layer
|
//! called when starting rendering of a layer
|
||||||
virtual int prepareLayer(QgsVectorLayer* layer, int& attrIndex, QgsRenderContext& ctx ) = 0;
|
virtual int prepareLayer(QgsVectorLayer* layer, int& attrIndex, QgsRenderContext& ctx ) = 0;
|
||||||
//! called for every feature
|
//! called for every feature
|
||||||
virtual void registerFeature( QgsVectorLayer* layer, QgsFeature& feat ) = 0;
|
virtual void registerFeature( QgsVectorLayer* layer, QgsFeature& feat, const QgsRenderContext& context = QgsRenderContext() ) = 0;
|
||||||
//! called when the map is drawn and labels should be placed
|
//! called when the map is drawn and labels should be placed
|
||||||
virtual void drawLabeling( QgsRenderContext& context ) = 0;
|
virtual void drawLabeling( QgsRenderContext& context ) = 0;
|
||||||
//! called when we're done with rendering
|
//! called when we're done with rendering
|
||||||
|
@ -53,7 +53,7 @@ class QgsLabelingEngineInterface
|
|||||||
//! called when starting rendering of a layer
|
//! called when starting rendering of a layer
|
||||||
virtual int prepareLayer( QgsVectorLayer* layer, int& attrIndex, QgsRenderContext& ctx ) = 0;
|
virtual int prepareLayer( QgsVectorLayer* layer, int& attrIndex, QgsRenderContext& ctx ) = 0;
|
||||||
//! called for every feature
|
//! called for every feature
|
||||||
virtual void registerFeature( QgsVectorLayer* layer, QgsFeature& feat ) = 0;
|
virtual void registerFeature( QgsVectorLayer* layer, QgsFeature& feat, const QgsRenderContext& context = QgsRenderContext() ) = 0;
|
||||||
//! called when the map is drawn and labels should be placed
|
//! called when the map is drawn and labels should be placed
|
||||||
virtual void drawLabeling( QgsRenderContext& context ) = 0;
|
virtual void drawLabeling( QgsRenderContext& context ) = 0;
|
||||||
//! called when we're done with rendering
|
//! called when we're done with rendering
|
||||||
|
@ -741,7 +741,7 @@ void QgsVectorLayer::drawRendererV2( QgsRenderContext& rendererContext, bool lab
|
|||||||
|
|
||||||
// labeling - register feature
|
// labeling - register feature
|
||||||
if ( labeling && mRendererV2->symbolForFeature( fet ) != NULL )
|
if ( labeling && mRendererV2->symbolForFeature( fet ) != NULL )
|
||||||
rendererContext.labelingEngine()->registerFeature( this, fet );
|
rendererContext.labelingEngine()->registerFeature( this, fet, rendererContext );
|
||||||
|
|
||||||
if ( mEditable )
|
if ( mEditable )
|
||||||
{
|
{
|
||||||
@ -805,7 +805,7 @@ void QgsVectorLayer::drawRendererV2Levels( QgsRenderContext& rendererContext, bo
|
|||||||
features[sym].append( fet );
|
features[sym].append( fet );
|
||||||
|
|
||||||
if ( labeling && mRendererV2->symbolForFeature( fet ) != NULL )
|
if ( labeling && mRendererV2->symbolForFeature( fet ) != NULL )
|
||||||
rendererContext.labelingEngine()->registerFeature( this, fet );
|
rendererContext.labelingEngine()->registerFeature( this, fet, rendererContext );
|
||||||
|
|
||||||
if ( mEditable )
|
if ( mEditable )
|
||||||
{
|
{
|
||||||
@ -1052,7 +1052,7 @@ bool QgsVectorLayer::draw( QgsRenderContext& rendererContext )
|
|||||||
|
|
||||||
if ( labeling && mRenderer->willRenderFeature( &fet ) )
|
if ( labeling && mRenderer->willRenderFeature( &fet ) )
|
||||||
{
|
{
|
||||||
rendererContext.labelingEngine()->registerFeature( this, fet );
|
rendererContext.labelingEngine()->registerFeature( this, fet, rendererContext );
|
||||||
}
|
}
|
||||||
|
|
||||||
++featureCount;
|
++featureCount;
|
||||||
|
@ -117,6 +117,7 @@ LabelingGui::LabelingGui( PalLabeling* lbl, QgsVectorLayer* layer, QWidget* pare
|
|||||||
chkNoObstacle->setChecked( !lyr.obstacle );
|
chkNoObstacle->setChecked( !lyr.obstacle );
|
||||||
chkLabelPerFeaturePart->setChecked( lyr.labelPerPart );
|
chkLabelPerFeaturePart->setChecked( lyr.labelPerPart );
|
||||||
chkMergeLines->setChecked( lyr.mergeLines );
|
chkMergeLines->setChecked( lyr.mergeLines );
|
||||||
|
mMinSizeSpinBox->setValue( lyr.minFeatureSize );
|
||||||
|
|
||||||
bool scaleBased = ( lyr.scaleMin != 0 && lyr.scaleMax != 0 );
|
bool scaleBased = ( lyr.scaleMin != 0 && lyr.scaleMax != 0 );
|
||||||
chkScaleBasedVisibility->setChecked( scaleBased );
|
chkScaleBasedVisibility->setChecked( scaleBased );
|
||||||
@ -231,7 +232,7 @@ LayerSettings LabelingGui::layerSettings()
|
|||||||
{
|
{
|
||||||
lyr.bufferSize = 0;
|
lyr.bufferSize = 0;
|
||||||
}
|
}
|
||||||
|
lyr.minFeatureSize = mMinSizeSpinBox->value();
|
||||||
return lyr;
|
return lyr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>480</width>
|
<width>448</width>
|
||||||
<height>610</height>
|
<height>610</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
@ -18,15 +18,15 @@
|
|||||||
<normaloff/>
|
<normaloff/>
|
||||||
</iconset>
|
</iconset>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
<layout class="QGridLayout" name="gridLayout_5">
|
||||||
<item>
|
<item row="0" column="0">
|
||||||
<widget class="QCheckBox" name="chkEnableLabeling">
|
<widget class="QCheckBox" name="chkEnableLabeling">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Label this layer</string>
|
<string>Label this layer</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item row="1" column="0">
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_9">
|
<layout class="QHBoxLayout" name="horizontalLayout_9">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="label_6">
|
<widget class="QLabel" name="label_6">
|
||||||
@ -56,7 +56,7 @@
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item row="2" column="0">
|
||||||
<widget class="QGroupBox" name="groupBox_4">
|
<widget class="QGroupBox" name="groupBox_4">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>Placement</string>
|
<string>Placement</string>
|
||||||
@ -326,7 +326,7 @@
|
|||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item row="3" column="0">
|
||||||
<layout class="QGridLayout" name="gridLayout_4">
|
<layout class="QGridLayout" name="gridLayout_4">
|
||||||
<item row="0" column="0" rowspan="2">
|
<item row="0" column="0" rowspan="2">
|
||||||
<widget class="QGroupBox" name="groupBox">
|
<widget class="QGroupBox" name="groupBox">
|
||||||
@ -648,21 +648,39 @@
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item row="4" column="0">
|
||||||
<widget class="QCheckBox" name="chkLabelPerFeaturePart">
|
<widget class="QCheckBox" name="chkLabelPerFeaturePart">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>label every part of multi-part features</string>
|
<string>label every part of multi-part features</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item row="5" column="0">
|
||||||
<widget class="QCheckBox" name="chkMergeLines">
|
<widget class="QCheckBox" name="chkMergeLines">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>merge connected lines to avoid duplicate labels</string>
|
<string>merge connected lines to avoid duplicate labels</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item row="6" column="0">
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_10">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel" name="label_19">
|
||||||
|
<property name="text">
|
||||||
|
<string>Suppress labeling of features smaller than</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QDoubleSpinBox" name="mMinSizeSpinBox">
|
||||||
|
<property name="suffix">
|
||||||
|
<string> mm</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item row="7" column="0">
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QCheckBox" name="chkNoObstacle">
|
<widget class="QCheckBox" name="chkNoObstacle">
|
||||||
@ -699,7 +717,7 @@
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item row="8" column="0">
|
||||||
<spacer name="verticalSpacer_2">
|
<spacer name="verticalSpacer_2">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Vertical</enum>
|
<enum>Qt::Vertical</enum>
|
||||||
@ -712,7 +730,7 @@
|
|||||||
</property>
|
</property>
|
||||||
</spacer>
|
</spacer>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item row="9" column="0">
|
||||||
<widget class="QDialogButtonBox" name="buttonBox">
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
<property name="orientation">
|
<property name="orientation">
|
||||||
<enum>Qt::Horizontal</enum>
|
<enum>Qt::Horizontal</enum>
|
||||||
|
@ -105,6 +105,7 @@ LayerSettings::LayerSettings()
|
|||||||
bufferColor = Qt::white;
|
bufferColor = Qt::white;
|
||||||
labelPerPart = false;
|
labelPerPart = false;
|
||||||
mergeLines = false;
|
mergeLines = false;
|
||||||
|
minFeatureSize = 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
LayerSettings::LayerSettings( const LayerSettings& s )
|
LayerSettings::LayerSettings( const LayerSettings& s )
|
||||||
@ -125,6 +126,7 @@ LayerSettings::LayerSettings( const LayerSettings& s )
|
|||||||
bufferColor = s.bufferColor;
|
bufferColor = s.bufferColor;
|
||||||
labelPerPart = s.labelPerPart;
|
labelPerPart = s.labelPerPart;
|
||||||
mergeLines = s.mergeLines;
|
mergeLines = s.mergeLines;
|
||||||
|
minFeatureSize = s.minFeatureSize;
|
||||||
|
|
||||||
fontMetrics = NULL;
|
fontMetrics = NULL;
|
||||||
ct = NULL;
|
ct = NULL;
|
||||||
@ -178,6 +180,7 @@ void LayerSettings::readFromLayer( QgsVectorLayer* layer )
|
|||||||
bufferColor = _readColor( layer, "labeling/bufferColor" );
|
bufferColor = _readColor( layer, "labeling/bufferColor" );
|
||||||
labelPerPart = layer->customProperty( "labeling/labelPerPart" ).toBool();
|
labelPerPart = layer->customProperty( "labeling/labelPerPart" ).toBool();
|
||||||
mergeLines = layer->customProperty( "labeling/mergeLines" ).toBool();
|
mergeLines = layer->customProperty( "labeling/mergeLines" ).toBool();
|
||||||
|
minFeatureSize = layer->customProperty( "labeling/minFeatureSize" ).toDouble();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LayerSettings::writeToLayer( QgsVectorLayer* layer )
|
void LayerSettings::writeToLayer( QgsVectorLayer* layer )
|
||||||
@ -205,6 +208,51 @@ void LayerSettings::writeToLayer( QgsVectorLayer* layer )
|
|||||||
_writeColor( layer, "labeling/bufferColor", bufferColor );
|
_writeColor( layer, "labeling/bufferColor", bufferColor );
|
||||||
layer->setCustomProperty( "labeling/labelPerPart", labelPerPart );
|
layer->setCustomProperty( "labeling/labelPerPart", labelPerPart );
|
||||||
layer->setCustomProperty( "labeling/mergeLines", mergeLines );
|
layer->setCustomProperty( "labeling/mergeLines", mergeLines );
|
||||||
|
layer->setCustomProperty( "labeling/minFeatureSize", minFeatureSize );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LayerSettings::checkMinimumSizeMM( const QgsRenderContext& ct, QgsGeometry* geom, double minSize ) const
|
||||||
|
{
|
||||||
|
if ( minSize <= 0 )
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !geom )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
QGis::GeometryType featureType = geom->type();
|
||||||
|
if ( featureType == QGis::Point ) //minimum size does not apply to point features
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
GEOSGeometry* geosGeom = geom->asGeos();
|
||||||
|
if ( !geosGeom )
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
double mapUnitsPerMM = ct.mapToPixel().mapUnitsPerPixel() * ct.scaleFactor();
|
||||||
|
if ( featureType == QGis::Line )
|
||||||
|
{
|
||||||
|
double length;
|
||||||
|
if ( GEOSLength( geosGeom, &length ) )
|
||||||
|
{
|
||||||
|
return ( length >= ( minSize * mapUnitsPerMM ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( featureType == QGis::Polygon )
|
||||||
|
{
|
||||||
|
double area;
|
||||||
|
if ( GEOSArea( geosGeom, &area ) )
|
||||||
|
{
|
||||||
|
return ( sqrt( area ) >= ( minSize * mapUnitsPerMM ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true; //should never be reached. Return true in this case to label such geometries anyway.
|
||||||
}
|
}
|
||||||
|
|
||||||
void LayerSettings::calculateLabelSize( QString text, double& labelX, double& labelY )
|
void LayerSettings::calculateLabelSize( QString text, double& labelX, double& labelY )
|
||||||
@ -219,7 +267,7 @@ void LayerSettings::calculateLabelSize( QString text, double& labelX, double& la
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void LayerSettings::registerFeature( QgsFeature& f )
|
void LayerSettings::registerFeature( QgsFeature& f, const QgsRenderContext& context )
|
||||||
{
|
{
|
||||||
QString labelText = f.attributeMap()[fieldIndex].toString();
|
QString labelText = f.attributeMap()[fieldIndex].toString();
|
||||||
double labelX, labelY; // will receive label size
|
double labelX, labelY; // will receive label size
|
||||||
@ -229,6 +277,11 @@ void LayerSettings::registerFeature( QgsFeature& f )
|
|||||||
if ( ct != NULL ) // reproject the geometry if necessary
|
if ( ct != NULL ) // reproject the geometry if necessary
|
||||||
geom->transform( *ct );
|
geom->transform( *ct );
|
||||||
|
|
||||||
|
if ( !checkMinimumSizeMM( context, geom, minFeatureSize ) )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
MyLabel* lbl = new MyLabel( f.id(), labelText, GEOSGeom_clone( geom->asGeos() ) );
|
MyLabel* lbl = new MyLabel( f.id(), labelText, GEOSGeom_clone( geom->asGeos() ) );
|
||||||
|
|
||||||
// record the created geometry - it will be deleted at the end.
|
// record the created geometry - it will be deleted at the end.
|
||||||
@ -375,9 +428,10 @@ int PalLabeling::prepareLayer( QgsVectorLayer* layer, int& attrIndex, QgsRenderC
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PalLabeling::registerFeature( QgsVectorLayer* layer, QgsFeature& f )
|
void PalLabeling::registerFeature( QgsVectorLayer* layer, QgsFeature& f, const QgsRenderContext& context )
|
||||||
{
|
{
|
||||||
mActiveLayers[layer].registerFeature( f );
|
LayerSettings& lyr = mActiveLayers[layer];
|
||||||
|
lyr.registerFeature( f, context );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -66,12 +66,13 @@ class LayerSettings
|
|||||||
QColor bufferColor;
|
QColor bufferColor;
|
||||||
bool labelPerPart; // whether to label every feature's part or only the biggest one
|
bool labelPerPart; // whether to label every feature's part or only the biggest one
|
||||||
bool mergeLines;
|
bool mergeLines;
|
||||||
|
double minFeatureSize; // minimum feature size to be labelled (in mm)
|
||||||
|
|
||||||
// called from register feature hook
|
// called from register feature hook
|
||||||
void calculateLabelSize( QString text, double& labelX, double& labelY );
|
void calculateLabelSize( QString text, double& labelX, double& labelY );
|
||||||
|
|
||||||
// implementation of register feature hook
|
// implementation of register feature hook
|
||||||
void registerFeature( QgsFeature& f );
|
void registerFeature( QgsFeature& f, const QgsRenderContext& context );
|
||||||
|
|
||||||
void readFromLayer( QgsVectorLayer* layer );
|
void readFromLayer( QgsVectorLayer* layer );
|
||||||
void writeToLayer( QgsVectorLayer* layer );
|
void writeToLayer( QgsVectorLayer* layer );
|
||||||
@ -85,6 +86,11 @@ class LayerSettings
|
|||||||
const QgsCoordinateTransform* ct;
|
const QgsCoordinateTransform* ct;
|
||||||
QgsPoint ptZero, ptOne;
|
QgsPoint ptZero, ptOne;
|
||||||
QList<MyLabel*> geometries;
|
QList<MyLabel*> geometries;
|
||||||
|
|
||||||
|
private:
|
||||||
|
/**Checks if a feature is larger than a minimum size (in mm)
|
||||||
|
@return true if above size, false if below*/
|
||||||
|
bool checkMinimumSizeMM( const QgsRenderContext& ct, QgsGeometry* geom, double minSize ) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class LabelCandidate
|
class LabelCandidate
|
||||||
@ -128,7 +134,7 @@ class PalLabeling : public QgsLabelingEngineInterface
|
|||||||
//! hook called when drawing layer before issuing select()
|
//! hook called when drawing layer before issuing select()
|
||||||
virtual int prepareLayer( QgsVectorLayer* layer, int& attrIndex, QgsRenderContext& ctx );
|
virtual int prepareLayer( QgsVectorLayer* layer, int& attrIndex, QgsRenderContext& ctx );
|
||||||
//! hook called when drawing for every feature in a layer
|
//! hook called when drawing for every feature in a layer
|
||||||
virtual void registerFeature( QgsVectorLayer* layer, QgsFeature& feat );
|
virtual void registerFeature( QgsVectorLayer* layer, QgsFeature& feat, const QgsRenderContext& context = QgsRenderContext() );
|
||||||
//! called when the map is drawn and labels should be placed
|
//! called when the map is drawn and labels should be placed
|
||||||
virtual void drawLabeling( QgsRenderContext& context );
|
virtual void drawLabeling( QgsRenderContext& context );
|
||||||
//! called when we're done with rendering
|
//! called when we're done with rendering
|
||||||
@ -145,6 +151,7 @@ class PalLabeling : public QgsLabelingEngineInterface
|
|||||||
|
|
||||||
void initPal();
|
void initPal();
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// temporary hashtable of layer settings, being filled during labeling, cleared once labeling's done
|
// temporary hashtable of layer settings, being filled during labeling, cleared once labeling's done
|
||||||
QHash<QgsVectorLayer*, LayerSettings> mActiveLayers;
|
QHash<QgsVectorLayer*, LayerSettings> mActiveLayers;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user