[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