Skip to content

Commit

Permalink
Added possibility to choose mode when labeling a layer: label per fea…
Browse files Browse the repository at this point in the history
…ture (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
  • Loading branch information
wonder committed Jul 30, 2009
1 parent 3da9fc4 commit 9513f3f
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 10 deletions.
55 changes: 45 additions & 10 deletions src/core/pal/layer.cpp
Expand Up @@ -62,7 +62,7 @@ namespace pal
: pal( pal ), obstacle( obstacle ), active( active ),
toLabel( toLabel ), label_unit( label_unit ),
min_scale( min_scale ), max_scale( max_scale ),
arrangement( arrangement ), arrangementFlags( 0 )
arrangement( arrangement ), arrangementFlags( 0 ), mode(LabelPerFeature)
{

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

bool first_feat = true;

double geom_size, biggest_size = -1;
FeaturePart* biggest_part = NULL;

// break the (possibly multi-part) geometry into simple geometries
LinkedList <const GEOSGeometry*> *simpleGeometries = unmulti( the_geom );

Expand Down Expand Up @@ -276,17 +279,25 @@ bool Layer::registerFeature( const char *geom_id, PalGeometry *userGeom, double
continue;
}

// feature part is ready!

double bmin[2];
double bmax[2];
fpart->getBoundingBox(bmin, bmax);
if (mode == LabelPerFeature && (type == GEOS_POLYGON || type == GEOS_LINESTRING))
{
if (type == GEOS_LINESTRING)
GEOSLength(geom, &geom_size);
else if (type == GEOS_POLYGON)
GEOSArea(geom, &geom_size);

// add to list of layer's feature parts
featureParts->push_back( fpart );
if (geom_size > biggest_size)
{
biggest_size = geom_size;
delete biggest_part; // safe with NULL part
biggest_part = fpart;
}
continue; // don't add the feature part now, do it later
// TODO: we should probably add also other parts to act just as obstacles
}

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

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

modMutex->unlock();

// if using only biggest parts...
if (mode == LabelPerFeature && biggest_part != NULL)
{
addFeaturePart(biggest_part);
first_feat = false;
}

// add feature to layer if we have added something
if (!first_feat)
{
features->push_back( f );
hashtable->insertItem( geom_id, f );
}
else
{
delete f;
}

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

void Layer::addFeaturePart( FeaturePart* fpart )
{
double bmin[2];
double bmax[2];
fpart->getBoundingBox(bmin, bmax);

// add to list of layer's feature parts
featureParts->push_back( fpart );

// add to r-tree for fast spatial access
rtree->Insert( bmin, bmax, fpart );
}


void Layer::setLabelUnit( Units label_unit )
{
Expand Down
11 changes: 11 additions & 0 deletions src/core/pal/layer.h
Expand Up @@ -73,6 +73,9 @@ namespace pal
friend bool extractFeatCallback( FeaturePart *ft_ptr, void *ctx );
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 );

public:
enum LabelMode { LabelPerFeature, LabelPerFeaturePart };

protected:
char *name; /* unique */

Expand All @@ -97,6 +100,8 @@ namespace pal

Arrangement arrangement;

LabelMode mode;

/** optional flags used for some placement methods */
unsigned long arrangementFlags;

Expand Down Expand Up @@ -134,6 +139,9 @@ namespace pal
*/
bool isScaleValid( double scale );

/** add newly creted feature part into r tree and to the list */
void addFeaturePart( FeaturePart* fpart );

public:
/**
* \brief get the number of features into layer
Expand Down Expand Up @@ -260,6 +268,9 @@ namespace pal
*/
double getPriority();

void setLabelMode( LabelMode m ) { mode = m; }
LabelMode getLabelMode() const { return mode; }

/**
* \brief register a feature in the layer
*
Expand Down
2 changes: 2 additions & 0 deletions src/plugins/labeling/labelinggui.cpp
Expand Up @@ -111,6 +111,7 @@ LabelingGui::LabelingGui( PalLabeling* lbl, QString layerId, QWidget* parent )
chkEnableLabeling->setChecked( lyr.enabled );
sliderPriority->setValue( lyr.priority );
chkNoObstacle->setChecked( !lyr.obstacle );
chkLabelPerFeaturePart->setChecked( lyr.labelPerPart );

bool scaleBased = (lyr.scaleMin != 0 && lyr.scaleMax != 0);
chkScaleBasedVisibility->setChecked(scaleBased);
Expand Down Expand Up @@ -222,6 +223,7 @@ LayerSettings LabelingGui::layerSettings()
lyr.enabled = chkEnableLabeling->isChecked();
lyr.priority = sliderPriority->value();
lyr.obstacle = !chkNoObstacle->isChecked();
lyr.labelPerPart = chkLabelPerFeaturePart->isChecked();
if (chkScaleBasedVisibility->isChecked())
{
lyr.scaleMin = spinScaleMin->value();
Expand Down
7 changes: 7 additions & 0 deletions src/plugins/labeling/labelingguibase.ui
Expand Up @@ -648,6 +648,13 @@
</item>
</layout>
</item>
<item>
<widget class="QCheckBox" name="chkLabelPerFeaturePart">
<property name="text">
<string>label every part of multi-part features</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
Expand Down
4 changes: 4 additions & 0 deletions src/plugins/labeling/pallabeling.cpp
Expand Up @@ -109,6 +109,7 @@ LayerSettings::LayerSettings(const LayerSettings& s)
scaleMax = s.scaleMax;
bufferSize = s.bufferSize;
bufferColor = s.bufferColor;
labelPerPart = s.labelPerPart;

fontMetrics = NULL;
ct = NULL;
Expand Down Expand Up @@ -287,6 +288,9 @@ int PalLabeling::prepareLayerHook(void* context, void* layerContext, int& attrIn
if ( lyr->placementFlags )
l->setArrangementFlags( lyr->placementFlags );

// set label mode (label per feature is the default)
l->setLabelMode( lyr->labelPerPart ? Layer::LabelPerFeaturePart : Layer::LabelPerFeature );

// save the pal layer to our layer context (with some additional info)
lyr->palLayer = l;
lyr->fieldIndex = fldIndex;
Expand Down
1 change: 1 addition & 0 deletions src/plugins/labeling/pallabeling.h
Expand Up @@ -63,6 +63,7 @@ class LayerSettings
int scaleMin, scaleMax; // disabled if both are zero
int bufferSize;
QColor bufferColor;
bool labelPerPart; // whether to label every feature's part or only the biggest one

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

0 comments on commit 9513f3f

Please sign in to comment.