Skip to content
Permalink
Browse files

Added possibility to choose mode when labeling a layer: label per fea…

…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
wonder committed Jul 30, 2009
1 parent 3da9fc4 commit 9513f3f9d6370bd41462a93d07ccdf9cef84515e
@@ -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];
@@ -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 );

@@ -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;
}
@@ -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 )
{
@@ -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 */

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

Arrangement arrangement;

LabelMode mode;

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

@@ -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
@@ -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
*
@@ -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);
@@ -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();
@@ -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>
@@ -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;
@@ -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;
@@ -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);

0 comments on commit 9513f3f

Please sign in to comment.
You can’t perform that action at this time.