Skip to content

Commit abd6a69

Browse files
committedJun 27, 2014
Merge pull request #1395 from manisandro/line_multi_labeling_improved
Line multi labeling improved
2 parents ae9b306 + 00692c7 commit abd6a69

File tree

7 files changed

+178
-126
lines changed

7 files changed

+178
-126
lines changed
 

‎src/app/qgslabelinggui.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1290,12 +1290,12 @@ void QgsLabelingGui::updatePlacementWidgets()
12901290
}
12911291

12921292
mPlacementLineFrame->setVisible( showLineFrame );
1293-
mPlacmentCentroidFrame->setVisible( showCentroidFrame );
1293+
mPlacementCentroidFrame->setVisible( showCentroidFrame );
12941294
mPlacementQuadrantFrame->setVisible( showQuadrantFrame );
12951295
mPlacementOffsetFrame->setVisible( showOffsetFrame );
12961296
mPlacementDistanceFrame->setVisible( showDistanceFrame );
12971297
mPlacementRotationFrame->setVisible( showRotationFrame );
1298-
mPlacmentRepeatDistanceFrame->setVisible( curWdgt == pageLine );
1298+
mPlacementRepeatDistanceFrame->setVisible( curWdgt == pageLine || ( curWdgt == pagePolygon && radPolygonPerimeter->isChecked() ) );
12991299
mPlacementMaxCharAngleFrame->setVisible( showMaxCharAngleFrame );
13001300

13011301
mMultiLinesFrame->setEnabled( enableMultiLinesFrame );

‎src/core/pal/feature.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,18 @@ namespace pal
228228
*/
229229
//int getId();
230230

231+
/**
232+
* \brief return the feature
233+
* \return the feature
234+
*/
235+
Feature* getFeature() { return f; }
236+
237+
/**
238+
* \brief return the geometry
239+
* \return the geometry
240+
*/
241+
const GEOSGeometry* getGeometry() const { return the_geom; }
242+
231243
/**
232244
* \brief return the layer that feature belongs to
233245
* \return the layer of the feature

‎src/core/pal/layer.cpp

Lines changed: 99 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,7 @@ namespace pal
229229

230230
bool Layer::registerFeature( const char *geom_id, PalGeometry *userGeom, double label_x, double label_y, const char* labelText,
231231
double labelPosX, double labelPosY, bool fixedPos, double angle, bool fixedAngle,
232-
int xQuadOffset, int yQuadOffset, double xOffset, double yOffset, bool alwaysShow, double repeatDistance )
232+
int xQuadOffset, int yQuadOffset, double xOffset, double yOffset, bool alwaysShow )
233233
{
234234
if ( !geom_id || label_x < 0 || label_y < 0 )
235235
return false;
@@ -285,86 +285,6 @@ namespace pal
285285
throw InternalException::UnknownGeometry();
286286
}
287287

288-
// if multiple labels are requested for lines, split the line in pieces of desired distance
289-
if ( repeatDistance > 0 )
290-
{
291-
int nSimpleGeometries = simpleGeometries->size();
292-
for ( int i = 0; i < nSimpleGeometries; ++i )
293-
{
294-
const GEOSGeometry* geom = simpleGeometries->pop_front();
295-
if ( GEOSGeomTypeId( geom ) == GEOS_LINESTRING )
296-
{
297-
const GEOSCoordSequence *cs = GEOSGeom_getCoordSeq( geom );
298-
299-
// get number of points
300-
unsigned int n;
301-
GEOSCoordSeq_getSize( cs, &n );
302-
303-
// Read points
304-
std::vector<Point> points( n );
305-
for ( unsigned int i = 0; i < n; ++i )
306-
{
307-
GEOSCoordSeq_getX( cs, i, &points[i].x );
308-
GEOSCoordSeq_getY( cs, i, &points[i].y );
309-
}
310-
311-
// Cumulative length vector
312-
std::vector<double> len( n, 0 );
313-
for ( unsigned int i = 1; i < n; ++i )
314-
{
315-
double dx = points[i].x - points[i - 1].x;
316-
double dy = points[i].y - points[i - 1].y;
317-
len[i] = len[i - 1] + std::sqrt( dx * dx + dy * dy );
318-
}
319-
320-
// Walk along line
321-
unsigned int cur = 0;
322-
double lambda = 0;
323-
std::vector<Point> part;
324-
for ( ;; )
325-
{
326-
lambda += repeatDistance;
327-
for ( ; cur < n && lambda > len[cur]; ++cur )
328-
{
329-
part.push_back( points[cur] );
330-
}
331-
if ( cur >= n )
332-
{
333-
break;
334-
}
335-
double c = ( lambda - len[cur - 1] ) / ( len[cur] - len[cur - 1] );
336-
Point p;
337-
p.x = points[cur - 1].x + c * ( points[cur].x - points[cur - 1].x );
338-
p.y = points[cur - 1].y + c * ( points[cur].y - points[cur - 1].y );
339-
part.push_back( p );
340-
GEOSCoordSequence* cooSeq = GEOSCoordSeq_create( part.size(), 2 );
341-
for ( std::size_t i = 0; i < part.size(); ++i )
342-
{
343-
GEOSCoordSeq_setX( cooSeq, i, part[i].x );
344-
GEOSCoordSeq_setY( cooSeq, i, part[i].y );
345-
}
346-
347-
simpleGeometries->push_back( GEOSGeom_createLineString( cooSeq ) );
348-
part.clear();
349-
part.push_back( p );
350-
}
351-
// Create final part
352-
part.push_back( points[n - 1] );
353-
GEOSCoordSequence* cooSeq = GEOSCoordSeq_create( part.size(), 2 );
354-
for ( std::size_t i = 0; i < part.size(); ++i )
355-
{
356-
GEOSCoordSeq_setX( cooSeq, i, part[i].x );
357-
GEOSCoordSeq_setY( cooSeq, i, part[i].y );
358-
}
359-
simpleGeometries->push_back( GEOSGeom_createLineString( cooSeq ) );
360-
}
361-
else
362-
{
363-
simpleGeometries->push_back( geom );
364-
}
365-
}
366-
}
367-
368288
while ( simpleGeometries->size() > 0 )
369289
{
370290
const GEOSGeometry* geom = simpleGeometries->pop_front();
@@ -401,7 +321,7 @@ namespace pal
401321
continue;
402322
}
403323

404-
if ( mode == LabelPerFeature && repeatDistance == 0.0 && ( type == GEOS_POLYGON || type == GEOS_LINESTRING ) )
324+
if ( mode == LabelPerFeature && ( type == GEOS_POLYGON || type == GEOS_LINESTRING ) )
405325
{
406326
if ( type == GEOS_LINESTRING )
407327
GEOSLength( geom, &geom_size );
@@ -430,7 +350,7 @@ namespace pal
430350
modMutex->unlock();
431351

432352
// if using only biggest parts...
433-
if ((( mode == LabelPerFeature && repeatDistance == 0.0 ) || f->fixedPosition() ) && biggest_part != NULL )
353+
if (( mode == LabelPerFeature || f->fixedPosition() ) && biggest_part != NULL )
434354
{
435355
addFeaturePart( biggest_part, labelText );
436356
first_feat = false;
@@ -569,6 +489,102 @@ namespace pal
569489
connectedTexts = NULL;
570490
}
571491

492+
void Layer::chopFeatures( double chopInterval )
493+
{
494+
LinkedList<FeaturePart*> * newFeatureParts = new LinkedList<FeaturePart*>( ptrFeaturePartCompare );
495+
while ( FeaturePart* fpart = featureParts->pop_front() )
496+
{
497+
const GEOSGeometry* geom = fpart->getGeometry();
498+
if ( GEOSGeomTypeId( geom ) == GEOS_LINESTRING )
499+
{
500+
501+
double bmin[2], bmax[2];
502+
fpart->getBoundingBox( bmin, bmax );
503+
rtree->Remove( bmin, bmax, fpart );
504+
505+
const GEOSCoordSequence *cs = GEOSGeom_getCoordSeq( geom );
506+
507+
// get number of points
508+
unsigned int n;
509+
GEOSCoordSeq_getSize( cs, &n );
510+
511+
// Read points
512+
std::vector<Point> points( n );
513+
for ( unsigned int i = 0; i < n; ++i )
514+
{
515+
GEOSCoordSeq_getX( cs, i, &points[i].x );
516+
GEOSCoordSeq_getY( cs, i, &points[i].y );
517+
}
518+
519+
// Cumulative length vector
520+
std::vector<double> len( n, 0 );
521+
for ( unsigned int i = 1; i < n; ++i )
522+
{
523+
double dx = points[i].x - points[i - 1].x;
524+
double dy = points[i].y - points[i - 1].y;
525+
len[i] = len[i - 1] + std::sqrt( dx * dx + dy * dy );
526+
}
527+
528+
// Walk along line
529+
unsigned int cur = 0;
530+
double lambda = 0;
531+
std::vector<Point> part;
532+
for ( ;; )
533+
{
534+
lambda += chopInterval;
535+
for ( ; cur < n && lambda > len[cur]; ++cur )
536+
{
537+
part.push_back( points[cur] );
538+
}
539+
if ( cur >= n )
540+
{
541+
break;
542+
}
543+
double c = ( lambda - len[cur - 1] ) / ( len[cur] - len[cur - 1] );
544+
Point p;
545+
p.x = points[cur - 1].x + c * ( points[cur].x - points[cur - 1].x );
546+
p.y = points[cur - 1].y + c * ( points[cur].y - points[cur - 1].y );
547+
part.push_back( p );
548+
GEOSCoordSequence* cooSeq = GEOSCoordSeq_create( part.size(), 2 );
549+
for ( std::size_t i = 0; i < part.size(); ++i )
550+
{
551+
GEOSCoordSeq_setX( cooSeq, i, part[i].x );
552+
GEOSCoordSeq_setY( cooSeq, i, part[i].y );
553+
}
554+
555+
GEOSGeometry* newgeom = GEOSGeom_createLineString( cooSeq );
556+
FeaturePart* newfpart = new FeaturePart( fpart->getFeature(), newgeom );
557+
newFeatureParts->push_back( newfpart );
558+
newfpart->getBoundingBox( bmin, bmax );
559+
rtree->Insert( bmin, bmax, newfpart );
560+
part.clear();
561+
part.push_back( p );
562+
}
563+
// Create final part
564+
part.push_back( points[n - 1] );
565+
GEOSCoordSequence* cooSeq = GEOSCoordSeq_create( part.size(), 2 );
566+
for ( std::size_t i = 0; i < part.size(); ++i )
567+
{
568+
GEOSCoordSeq_setX( cooSeq, i, part[i].x );
569+
GEOSCoordSeq_setY( cooSeq, i, part[i].y );
570+
}
571+
572+
GEOSGeometry* newgeom = GEOSGeom_createLineString( cooSeq );
573+
FeaturePart* newfpart = new FeaturePart( fpart->getFeature(), newgeom );
574+
newFeatureParts->push_back( newfpart );
575+
newfpart->getBoundingBox( bmin, bmax );
576+
rtree->Insert( bmin, bmax, newfpart );
577+
}
578+
else
579+
{
580+
newFeatureParts->push_back( fpart );
581+
}
582+
}
583+
584+
delete featureParts;
585+
featureParts = newFeatureParts;
586+
}
587+
572588

573589

574590
} // end namespace

‎src/core/pal/layer.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ namespace pal
113113
unsigned long arrangementFlags;
114114
LabelMode mode;
115115
bool mergeLines;
116+
double repeatDistance;
116117

117118
UpsideDownLabels upsidedownLabels;
118119

@@ -289,6 +290,9 @@ namespace pal
289290
void setMergeConnectedLines( bool m ) { mergeLines = m; }
290291
bool getMergeConnectedLines() const { return mergeLines; }
291292

293+
void setRepeatDistance( double distance ) { repeatDistance = distance; }
294+
double getRepeatDistance() const { return repeatDistance; }
295+
292296
void setUpsidedownLabels( UpsideDownLabels ud ) { upsidedownLabels = ud; }
293297
UpsideDownLabels getUpsidedownLabels() const { return upsidedownLabels; }
294298

@@ -321,14 +325,16 @@ namespace pal
321325
const char* labelText = NULL, double labelPosX = 0.0, double labelPosY = 0.0,
322326
bool fixedPos = false, double angle = 0.0, bool fixedAngle = false,
323327
int xQuadOffset = 0, int yQuadOffset = 0, double xOffset = 0.0, double yOffset = 0.0,
324-
bool alwaysShow = false, double repeatDistance = 0.0 );
328+
bool alwaysShow = false );
325329

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

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

336+
void chopFeatures(double chopInterval );
337+
332338
};
333339

334340
} // end namespace pal

‎src/core/pal/pal.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,9 @@ namespace pal
429429
if ( layer->getMergeConnectedLines() )
430430
layer->joinConnectedFeatures();
431431

432+
if ( layer->getRepeatDistance() > 0 )
433+
layer->chopFeatures( layer->getRepeatDistance() );
434+
432435
context->layer = layer;
433436
context->priority = layersFactor[i];
434437
// lookup for feature (and generates candidates list)

0 commit comments

Comments
 (0)
Please sign in to comment.