[QGIS Commit] r11419 - in branches/symbology-ng-branch/src:
core/pal plugins/labeling
svn_qgis at osgeo.org
svn_qgis at osgeo.org
Mon Aug 17 18:35:01 EDT 2009
Author: wonder
Date: 2009-08-17 18:35:01 -0400 (Mon, 17 Aug 2009)
New Revision: 11419
Modified:
branches/symbology-ng-branch/src/core/pal/feature.cpp
branches/symbology-ng-branch/src/core/pal/labelposition.cpp
branches/symbology-ng-branch/src/core/pal/labelposition.h
branches/symbology-ng-branch/src/plugins/labeling/labelinggui.cpp
Log:
Options for curved labels: above/on/below line, distance from line (as with parallel labels)
Modified: branches/symbology-ng-branch/src/core/pal/feature.cpp
===================================================================
--- branches/symbology-ng-branch/src/core/pal/feature.cpp 2009-08-17 22:30:09 UTC (rev 11418)
+++ branches/symbology-ng-branch/src/core/pal/feature.cpp 2009-08-17 22:35:01 UTC (rev 11419)
@@ -840,6 +840,13 @@
return slp;
}
+ static LabelPosition* _createCurvedCandidate(LabelPosition* lp, double angle, double dist)
+ {
+ LabelPosition* newLp = new LabelPosition(*lp);
+ newLp->offsetPosition( dist*cos(angle+M_PI/2), dist*sin(angle+M_PI/2) );
+ return newLp;
+ }
+
int FeaturePart::setPositionForLineCurved( LabelPosition ***lPos, PointSet* mapShape )
{
// label info must be present
@@ -865,10 +872,13 @@
if (total_distance == 0)
return 0;
- int nbp = 0;
LinkedList<LabelPosition*> *positions = new LinkedList<LabelPosition*> ( ptrLPosCompare );
double delta = max( f->labelInfo->label_height, total_distance/10.0 );
+ unsigned long flags = f->layer->getArrangementFlags();
+ if ( flags == 0 )
+ flags = FLAG_ON_LINE; // default flag
+
// generate curved labels
std::cerr << "------" << std::endl;
for (int i = 0; i*delta < total_distance; i++)
@@ -880,6 +890,7 @@
// evaluate cost
double angle_diff = 0, angle_last, diff;
LabelPosition* tmp = slp;
+ double sin_avg=0, cos_avg=0;
while (tmp)
{
if (tmp != slp) // not first?
@@ -890,9 +901,12 @@
angle_diff += diff;
}
+ sin_avg += sin(tmp->getAlpha());
+ cos_avg += cos(tmp->getAlpha());
angle_last = tmp->getAlpha();
tmp = tmp->getNextPart();
}
+
double angle_diff_avg = angle_diff / (f->labelInfo->char_num-1); // <0, pi> but pi/8 is much already
double cost = angle_diff_avg / 100; // <0, 0.031 > but usually <0, 0.003 >
if (cost < 0.0001) cost = 0.0001;
@@ -904,12 +918,24 @@
//std::cerr << "cost " << angle_diff << " vs " << costCenter << std::endl;
slp->setCost(cost);
- positions->push_back(slp);
- nbp++;
+
+ // average angle is calculated with respect to periodicity of angles
+ double angle_avg = atan2( sin_avg / f->labelInfo->char_num, cos_avg / f->labelInfo->char_num);
+ // displacement
+ if (flags & FLAG_ABOVE_LINE)
+ positions->push_back( _createCurvedCandidate(slp, angle_avg, f->distlabel) );
+ if (flags & FLAG_ON_LINE)
+ positions->push_back( _createCurvedCandidate(slp, angle_avg, -f->labelInfo->label_height/2) );
+ if (flags & FLAG_BELOW_LINE)
+ positions->push_back( _createCurvedCandidate(slp, angle_avg, -f->labelInfo->label_height - f->distlabel) );
+
+ // delete original candidate
+ delete slp;
}
}
+ int nbp = positions->size();
( *lPos ) = new LabelPosition*[nbp];
for (int i = 0; i < nbp; i++)
{
Modified: branches/symbology-ng-branch/src/core/pal/labelposition.cpp
===================================================================
--- branches/symbology-ng-branch/src/core/pal/labelposition.cpp 2009-08-17 22:30:09 UTC (rev 11418)
+++ branches/symbology-ng-branch/src/core/pal/labelposition.cpp 2009-08-17 22:35:01 UTC (rev 11419)
@@ -118,6 +118,27 @@
}
}
+ LabelPosition::LabelPosition( const LabelPosition& other )
+ {
+ id = other.id;
+ cost = other.cost;
+ feature = other.feature;
+ probFeat = other.probFeat;
+ nbOverlap = other.nbOverlap;
+
+ memcpy(x, other.x, sizeof(double)*4);
+ memcpy(y, other.y, sizeof(double)*4);
+ alpha = other.alpha;
+ w = other.w;
+ h = other.h;
+
+ if (other.nextPart)
+ nextPart = new LabelPosition(*other.nextPart);
+ else
+ nextPart = NULL;
+ partId = other.partId;
+ }
+
bool LabelPosition::isIn( double *bbox )
{
int i;
@@ -216,6 +237,19 @@
return false; // no conflict found
}
+ void LabelPosition::offsetPosition( double xOffset, double yOffset )
+ {
+ for (int i=0; i < 4; i++)
+ {
+ x[i] += xOffset;
+ y[i] += yOffset;
+ }
+
+ if (nextPart)
+ nextPart->offsetPosition(xOffset, yOffset);
+ }
+
+
int LabelPosition::getId() const
{
return id;
Modified: branches/symbology-ng-branch/src/core/pal/labelposition.h
===================================================================
--- branches/symbology-ng-branch/src/core/pal/labelposition.h 2009-08-17 22:30:09 UTC (rev 11418)
+++ branches/symbology-ng-branch/src/core/pal/labelposition.h 2009-08-17 22:35:01 UTC (rev 11419)
@@ -95,6 +95,9 @@
double alpha, double cost,
FeaturePart *feature );
+ /** copy constructor */
+ LabelPosition( const LabelPosition& other );
+
~LabelPosition() { delete nextPart; }
@@ -125,6 +128,8 @@
/** returns number of intersections with polygon (testing border and center) */
int getNumPointsInPolygon( int npol, double *xp, double *yp );
+ /** shift the label by specified offset */
+ void offsetPosition( double xOffset, double yOffset );
/** \brief return id
Modified: branches/symbology-ng-branch/src/plugins/labeling/labelinggui.cpp
===================================================================
--- branches/symbology-ng-branch/src/plugins/labeling/labelinggui.cpp 2009-08-17 22:30:09 UTC (rev 11418)
+++ branches/symbology-ng-branch/src/plugins/labeling/labelinggui.cpp 2009-08-17 22:35:01 UTC (rev 11419)
@@ -84,15 +84,6 @@
case LayerSettings::Line:
radLineParallel->setChecked(true);
radPolygonPerimeter->setChecked(true);
-
- spinDistLine->setValue(lyr.dist);
- chkLineAbove->setChecked( lyr.placementFlags & LayerSettings::AboveLine );
- chkLineBelow->setChecked( lyr.placementFlags & LayerSettings::BelowLine );
- chkLineOn->setChecked( lyr.placementFlags & LayerSettings::OnLine );
- if ( lyr.placementFlags & LayerSettings::MapOrientation )
- radOrientationMap->setChecked(true);
- else
- radOrientationLine->setChecked(true);
break;
case LayerSettings::Curved:
radLineCurved->setChecked(true);
@@ -108,6 +99,18 @@
Q_ASSERT(0 && "NOOO!");
}
+ if (lyr.placement == LayerSettings::Line || lyr.placement == LayerSettings::Curved)
+ {
+ spinDistLine->setValue(lyr.dist);
+ chkLineAbove->setChecked( lyr.placementFlags & LayerSettings::AboveLine );
+ chkLineBelow->setChecked( lyr.placementFlags & LayerSettings::BelowLine );
+ chkLineOn->setChecked( lyr.placementFlags & LayerSettings::OnLine );
+ if ( lyr.placementFlags & LayerSettings::MapOrientation )
+ radOrientationMap->setChecked(true);
+ else
+ radOrientationLine->setChecked(true);
+ }
+
cboFieldName->setCurrentIndex( cboFieldName->findText(lyr.fieldName) );
chkEnableLabeling->setChecked( lyr.enabled );
sliderPriority->setValue( lyr.priority );
@@ -173,9 +176,11 @@
lyr.placement = LayerSettings::OverPoint;
}
else if ( (stackedPlacement->currentWidget() == pageLine && radLineParallel->isChecked())
- || (stackedPlacement->currentWidget() == pagePolygon && radPolygonPerimeter->isChecked()) )
+ || (stackedPlacement->currentWidget() == pagePolygon && radPolygonPerimeter->isChecked())
+ || (stackedPlacement->currentWidget() == pageLine && radLineCurved->isChecked()) )
{
- lyr.placement = LayerSettings::Line;
+ bool curved = (stackedPlacement->currentWidget() == pageLine && radLineCurved->isChecked());
+ lyr.placement = (curved ? LayerSettings::Curved : LayerSettings::Line);
lyr.dist = spinDistLine->value();
if (chkLineAbove->isChecked())
lyr.placementFlags |= LayerSettings::AboveLine;
@@ -187,10 +192,6 @@
if (radOrientationMap->isChecked())
lyr.placementFlags |= LayerSettings::MapOrientation;
}
- else if ( stackedPlacement->currentWidget() == pageLine && radLineCurved->isChecked() )
- {
- lyr.placement = LayerSettings::Curved;
- }
else if ( (stackedPlacement->currentWidget() == pageLine && radLineHorizontal->isChecked())
|| (stackedPlacement->currentWidget() == pagePolygon && radPolygonHorizontal->isChecked()) )
{
@@ -314,7 +315,8 @@
stackedOptions->setCurrentWidget(pageOptionsPoint);
}
else if ( (stackedPlacement->currentWidget() == pageLine && radLineParallel->isChecked())
- || (stackedPlacement->currentWidget() == pagePolygon && radPolygonPerimeter->isChecked()) )
+ || (stackedPlacement->currentWidget() == pagePolygon && radPolygonPerimeter->isChecked())
+ || (stackedPlacement->currentWidget() == pageLine && radLineCurved->isChecked()) )
{
stackedOptions->setCurrentWidget(pageOptionsLine);
}
More information about the QGIS-commit
mailing list