Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge pull request #1533 from manisandro/multilabeling_datadefined
Fix multilabeling with datadefined value
  • Loading branch information
mhugent committed Aug 18, 2014
2 parents 8d822c4 + f267791 commit d69a7f2
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 47 deletions.
4 changes: 4 additions & 0 deletions src/core/pal/feature.h
Expand Up @@ -96,6 +96,8 @@ namespace pal
bool fixedPosition() const { return fixedPos; }
//Set label rotation to fixed value
void setFixedAngle( double a ) { fixedRotation = true; fixedAngle = a; }
void setRepeatDistance( double dist ) { repeatDist = dist; }
double repeatDistance() const { return repeatDist; }
void setAlwaysShow( bool bl ) { alwaysShow = bl; }

protected:
Expand All @@ -120,9 +122,11 @@ namespace pal
//Fixed (e.g. data defined) angle only makes sense together with fixed position
bool fixedRotation;
double fixedAngle; //fixed angle value (in rad)
double repeatDist;

bool alwaysShow; //true is label is to always be shown (but causes overlapping)


// array of parts - possibly not necessary
//int nPart;
//FeaturePart** parts;
Expand Down
8 changes: 5 additions & 3 deletions src/core/pal/layer.cpp
Expand Up @@ -229,7 +229,7 @@ namespace pal

bool Layer::registerFeature( const char *geom_id, PalGeometry *userGeom, double label_x, double label_y, const char* labelText,
double labelPosX, double labelPosY, bool fixedPos, double angle, bool fixedAngle,
int xQuadOffset, int yQuadOffset, double xOffset, double yOffset, bool alwaysShow )
int xQuadOffset, int yQuadOffset, double xOffset, double yOffset, bool alwaysShow, double repeatDistance )
{
if ( !geom_id || label_x < 0 || label_y < 0 )
return false;
Expand Down Expand Up @@ -269,6 +269,7 @@ namespace pal
{
f->setFixedAngle( angle );
}
f->setRepeatDistance( repeatDistance );

f->setAlwaysShow( alwaysShow );

Expand Down Expand Up @@ -490,13 +491,14 @@ namespace pal
connectedTexts = NULL;
}

void Layer::chopFeatures( double chopInterval )
void Layer::chopFeaturesAtRepeatDistance( )
{
LinkedList<FeaturePart*> * newFeatureParts = new LinkedList<FeaturePart*>( ptrFeaturePartCompare );
while ( FeaturePart* fpart = featureParts->pop_front() )
{
const GEOSGeometry* geom = fpart->getGeometry();
if ( GEOSGeomTypeId( geom ) == GEOS_LINESTRING )
double chopInterval = fpart->getFeature()->repeatDistance();
if ( chopInterval != 0. && GEOSGeomTypeId( geom ) == GEOS_LINESTRING )
{

double bmin[2], bmax[2];
Expand Down
5 changes: 3 additions & 2 deletions src/core/pal/layer.h
Expand Up @@ -326,15 +326,16 @@ namespace pal
const char* labelText = NULL, double labelPosX = 0.0, double labelPosY = 0.0,
bool fixedPos = false, double angle = 0.0, bool fixedAngle = false,
int xQuadOffset = 0, int yQuadOffset = 0, double xOffset = 0.0, double yOffset = 0.0,
bool alwaysShow = false );
bool alwaysShow = false, double repeatDistance = 0 );

/** return pointer to feature or NULL if doesn't exist */
Feature* getFeature( const char* geom_id );

/** join connected features with the same label text */
void joinConnectedFeatures();

void chopFeatures( double chopInterval );
/** chop layer features at the repeat distance **/
void chopFeaturesAtRepeatDistance();

};

Expand Down
4 changes: 2 additions & 2 deletions src/core/pal/pal.cpp
Expand Up @@ -429,8 +429,8 @@ namespace pal
if ( layer->getMergeConnectedLines() )
layer->joinConnectedFeatures();

if ( layer->getRepeatDistance() > 0 )
layer->chopFeatures( layer->getRepeatDistance() );
layer->chopFeaturesAtRepeatDistance();


context->layer = layer;
context->priority = layersFactor[i];
Expand Down
79 changes: 39 additions & 40 deletions src/core/qgspallabeling.cpp
Expand Up @@ -2249,12 +2249,50 @@ void QgsPalLayerSettings::registerFeature( QgsFeature& f, const QgsRenderContext
#endif
lbl->setDefinedFont( labelFont );

// set repeat distance
// data defined repeat distance?
double repeatDist = repeatDistance;
if ( dataDefinedEvaluate( QgsPalLayerSettings::RepeatDistance, exprVal ) )
{
bool ok;
double distD = exprVal.toDouble( &ok );
if ( ok )
{
repeatDist = distD;
}
}

// data defined label-repeat distance units?
bool repeatdistinmapunit = repeatDistanceUnit == QgsPalLayerSettings::MapUnits;
if ( dataDefinedEvaluate( QgsPalLayerSettings::RepeatDistanceUnit, exprVal ) )
{
QString units = exprVal.toString().trimmed();
QgsDebugMsgLevel( QString( "exprVal RepeatDistanceUnits:%1" ).arg( units ), 4 );
if ( !units.isEmpty() )
{
repeatdistinmapunit = ( _decodeUnits( units ) == QgsPalLayerSettings::MapUnits );
}
}

if ( repeatDist != 0 )
{
if ( repeatdistinmapunit ) //convert distance from mm/map units to pixels
{
repeatDist /= repeatDistanceMapUnitScale.computeMapUnitsPerPixel( context ) * context.scaleFactor();
}
else //mm
{
repeatDist *= vectorScaleFactor;
}
repeatDist *= qAbs( ptOne.x() - ptZero.x() );
}

// feature to the layer
try
{
if ( !palLayer->registerFeature( lbl->strId(), lbl, labelX, labelY, labelText.toUtf8().constData(),
xPos, yPos, dataDefinedPosition, angle, dataDefinedRotation,
quadOffsetX, quadOffsetY, offsetX, offsetY, alwaysShow ) )
quadOffsetX, quadOffsetY, offsetX, offsetY, alwaysShow, repeatDist ) )
return;
}
catch ( std::exception &e )
Expand Down Expand Up @@ -3375,45 +3413,6 @@ int QgsPalLabeling::prepareLayer( QgsVectorLayer* layer, QStringList& attrNames,
// set whether location of centroid must be inside of polygons
l->setCentroidInside( lyr.centroidInside );

// set repeat distance
// data defined repeat distance?
QVariant exprVal;
double repeatDist = lyr.repeatDistance;
if ( lyr.dataDefinedEvaluate( QgsPalLayerSettings::RepeatDistance, exprVal ) )
{
bool ok;
double distD = exprVal.toDouble( &ok );
if ( ok )
{
repeatDist = distD;
}
}

// data defined label-repeat distance units?
bool repeatdistinmapunit = lyr.repeatDistanceUnit == QgsPalLayerSettings::MapUnits;
if ( lyr.dataDefinedEvaluate( QgsPalLayerSettings::RepeatDistanceUnit, exprVal ) )
{
QString units = exprVal.toString().trimmed();
QgsDebugMsgLevel( QString( "exprVal RepeatDistanceUnits:%1" ).arg( units ), 4 );
if ( !units.isEmpty() )
{
repeatdistinmapunit = ( _decodeUnits( units ) == QgsPalLayerSettings::MapUnits );
}
}

if ( repeatDist != 0 )
{
if ( !repeatdistinmapunit ) //convert distance from mm/map units to pixels
{
repeatDist *= lyr.repeatDistanceMapUnitScale.computeMapUnitsPerPixel( ctx ) * ctx.scaleFactor();
}
else //mm
{
repeatDist *= lyr.vectorScaleFactor;
}
}
l->setRepeatDistance( repeatDist );

// set how to show upside-down labels
Layer::UpsideDownLabels upsdnlabels;
switch ( lyr.upsidedownLabels )
Expand Down

0 comments on commit d69a7f2

Please sign in to comment.