Skip to content

Commit 9513f3f

Browse files
author
wonder
committed
Added possibility to choose mode when labeling a layer: label per feature (default) or label per feature part.
Label per feature uses longest line resp. largest polygon, for multipoint features fallback to label per feature part. git-svn-id: http://svn.osgeo.org/qgis/branches/symbology-ng-branch@11209 c8812cc2-4d05-0410-92ff-de0c093fc19c
1 parent 3da9fc4 commit 9513f3f

File tree

6 files changed

+70
-10
lines changed

6 files changed

+70
-10
lines changed

src/core/pal/layer.cpp

Lines changed: 45 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ namespace pal
6262
: pal( pal ), obstacle( obstacle ), active( active ),
6363
toLabel( toLabel ), label_unit( label_unit ),
6464
min_scale( min_scale ), max_scale( max_scale ),
65-
arrangement( arrangement ), arrangementFlags( 0 )
65+
arrangement( arrangement ), arrangementFlags( 0 ), mode(LabelPerFeature)
6666
{
6767

6868
this->name = new char[strlen( lyrName ) +1];
@@ -240,6 +240,9 @@ bool Layer::registerFeature( const char *geom_id, PalGeometry *userGeom, double
240240

241241
bool first_feat = true;
242242

243+
double geom_size, biggest_size = -1;
244+
FeaturePart* biggest_part = NULL;
245+
243246
// break the (possibly multi-part) geometry into simple geometries
244247
LinkedList <const GEOSGeometry*> *simpleGeometries = unmulti( the_geom );
245248

@@ -276,17 +279,25 @@ bool Layer::registerFeature( const char *geom_id, PalGeometry *userGeom, double
276279
continue;
277280
}
278281

279-
// feature part is ready!
280-
281-
double bmin[2];
282-
double bmax[2];
283-
fpart->getBoundingBox(bmin, bmax);
282+
if (mode == LabelPerFeature && (type == GEOS_POLYGON || type == GEOS_LINESTRING))
283+
{
284+
if (type == GEOS_LINESTRING)
285+
GEOSLength(geom, &geom_size);
286+
else if (type == GEOS_POLYGON)
287+
GEOSArea(geom, &geom_size);
284288

285-
// add to list of layer's feature parts
286-
featureParts->push_back( fpart );
289+
if (geom_size > biggest_size)
290+
{
291+
biggest_size = geom_size;
292+
delete biggest_part; // safe with NULL part
293+
biggest_part = fpart;
294+
}
295+
continue; // don't add the feature part now, do it later
296+
// TODO: we should probably add also other parts to act just as obstacles
297+
}
287298

288-
// add to r-tree for fast spatial access
289-
rtree->Insert( bmin, bmax, fpart );
299+
// feature part is ready!
300+
addFeaturePart(fpart);
290301

291302
first_feat = false;
292303
}
@@ -296,16 +307,40 @@ bool Layer::registerFeature( const char *geom_id, PalGeometry *userGeom, double
296307

297308
modMutex->unlock();
298309

310+
// if using only biggest parts...
311+
if (mode == LabelPerFeature && biggest_part != NULL)
312+
{
313+
addFeaturePart(biggest_part);
314+
first_feat = false;
315+
}
316+
299317
// add feature to layer if we have added something
300318
if (!first_feat)
301319
{
302320
features->push_back( f );
303321
hashtable->insertItem( geom_id, f );
304322
}
323+
else
324+
{
325+
delete f;
326+
}
305327

306328
return !first_feat; // true if we've added something
307329
}
308330

331+
void Layer::addFeaturePart( FeaturePart* fpart )
332+
{
333+
double bmin[2];
334+
double bmax[2];
335+
fpart->getBoundingBox(bmin, bmax);
336+
337+
// add to list of layer's feature parts
338+
featureParts->push_back( fpart );
339+
340+
// add to r-tree for fast spatial access
341+
rtree->Insert( bmin, bmax, fpart );
342+
}
343+
309344

310345
void Layer::setLabelUnit( Units label_unit )
311346
{

src/core/pal/layer.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,9 @@ namespace pal
7373
friend bool extractFeatCallback( FeaturePart *ft_ptr, void *ctx );
7474
friend void toSVGPath( int nbPoints, double *x, double *y, int dpi, Layer *layer, int type, char *uid, std::ostream &out, double scale, int xmin, int ymax, bool exportInfo, char *color );
7575

76+
public:
77+
enum LabelMode { LabelPerFeature, LabelPerFeaturePart };
78+
7679
protected:
7780
char *name; /* unique */
7881

@@ -97,6 +100,8 @@ namespace pal
97100

98101
Arrangement arrangement;
99102

103+
LabelMode mode;
104+
100105
/** optional flags used for some placement methods */
101106
unsigned long arrangementFlags;
102107

@@ -134,6 +139,9 @@ namespace pal
134139
*/
135140
bool isScaleValid( double scale );
136141

142+
/** add newly creted feature part into r tree and to the list */
143+
void addFeaturePart( FeaturePart* fpart );
144+
137145
public:
138146
/**
139147
* \brief get the number of features into layer
@@ -260,6 +268,9 @@ namespace pal
260268
*/
261269
double getPriority();
262270

271+
void setLabelMode( LabelMode m ) { mode = m; }
272+
LabelMode getLabelMode() const { return mode; }
273+
263274
/**
264275
* \brief register a feature in the layer
265276
*

src/plugins/labeling/labelinggui.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ LabelingGui::LabelingGui( PalLabeling* lbl, QString layerId, QWidget* parent )
111111
chkEnableLabeling->setChecked( lyr.enabled );
112112
sliderPriority->setValue( lyr.priority );
113113
chkNoObstacle->setChecked( !lyr.obstacle );
114+
chkLabelPerFeaturePart->setChecked( lyr.labelPerPart );
114115

115116
bool scaleBased = (lyr.scaleMin != 0 && lyr.scaleMax != 0);
116117
chkScaleBasedVisibility->setChecked(scaleBased);
@@ -222,6 +223,7 @@ LayerSettings LabelingGui::layerSettings()
222223
lyr.enabled = chkEnableLabeling->isChecked();
223224
lyr.priority = sliderPriority->value();
224225
lyr.obstacle = !chkNoObstacle->isChecked();
226+
lyr.labelPerPart = chkLabelPerFeaturePart->isChecked();
225227
if (chkScaleBasedVisibility->isChecked())
226228
{
227229
lyr.scaleMin = spinScaleMin->value();

src/plugins/labeling/labelingguibase.ui

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -648,6 +648,13 @@
648648
</item>
649649
</layout>
650650
</item>
651+
<item>
652+
<widget class="QCheckBox" name="chkLabelPerFeaturePart">
653+
<property name="text">
654+
<string>label every part of multi-part features</string>
655+
</property>
656+
</widget>
657+
</item>
651658
<item>
652659
<layout class="QHBoxLayout" name="horizontalLayout_2">
653660
<item>

src/plugins/labeling/pallabeling.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ LayerSettings::LayerSettings(const LayerSettings& s)
109109
scaleMax = s.scaleMax;
110110
bufferSize = s.bufferSize;
111111
bufferColor = s.bufferColor;
112+
labelPerPart = s.labelPerPart;
112113

113114
fontMetrics = NULL;
114115
ct = NULL;
@@ -287,6 +288,9 @@ int PalLabeling::prepareLayerHook(void* context, void* layerContext, int& attrIn
287288
if ( lyr->placementFlags )
288289
l->setArrangementFlags( lyr->placementFlags );
289290

291+
// set label mode (label per feature is the default)
292+
l->setLabelMode( lyr->labelPerPart ? Layer::LabelPerFeaturePart : Layer::LabelPerFeature );
293+
290294
// save the pal layer to our layer context (with some additional info)
291295
lyr->palLayer = l;
292296
lyr->fieldIndex = fldIndex;

src/plugins/labeling/pallabeling.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ class LayerSettings
6363
int scaleMin, scaleMax; // disabled if both are zero
6464
int bufferSize;
6565
QColor bufferColor;
66+
bool labelPerPart; // whether to label every feature's part or only the biggest one
6667

6768
// called from register feature hook
6869
void calculateLabelSize(QString text, double& labelX, double& labelY);

0 commit comments

Comments
 (0)