[QGIS Commit] r10806 - in branches/symbology-ng-branch/src: core/symbology-ng gui/symbology-ng ui/symbollayer

svn_qgis at osgeo.org svn_qgis at osgeo.org
Sun May 17 09:02:06 EDT 2009


Author: wonder
Date: 2009-05-17 09:02:06 -0400 (Sun, 17 May 2009)
New Revision: 10806

Modified:
   branches/symbology-ng-branch/src/core/symbology-ng/qgslinesymbollayerv2.cpp
   branches/symbology-ng-branch/src/core/symbology-ng/qgslinesymbollayerv2.h
   branches/symbology-ng-branch/src/core/symbology-ng/qgssymbollayerv2utils.cpp
   branches/symbology-ng-branch/src/core/symbology-ng/qgssymbollayerv2utils.h
   branches/symbology-ng-branch/src/gui/symbology-ng/qgssymbollayerv2widget.cpp
   branches/symbology-ng-branch/src/gui/symbology-ng/qgssymbollayerv2widget.h
   branches/symbology-ng-branch/src/ui/symbollayer/widget_markerline.ui
   branches/symbology-ng-branch/src/ui/symbollayer/widget_simpleline.ui
Log:
New property for simple line and marker line: offset!


Modified: branches/symbology-ng-branch/src/core/symbology-ng/qgslinesymbollayerv2.cpp
===================================================================
--- branches/symbology-ng-branch/src/core/symbology-ng/qgslinesymbollayerv2.cpp	2009-05-16 14:25:35 UTC (rev 10805)
+++ branches/symbology-ng-branch/src/core/symbology-ng/qgslinesymbollayerv2.cpp	2009-05-17 13:02:06 UTC (rev 10806)
@@ -9,7 +9,7 @@
 #include <cmath>
 
 QgsSimpleLineSymbolLayerV2::QgsSimpleLineSymbolLayerV2(QColor color, int width, Qt::PenStyle penStyle)
- : mPenStyle(penStyle)
+ : mPenStyle(penStyle), mOffset(0)
 {
   mColor = color;
   mWidth = width;
@@ -29,7 +29,10 @@
   if (props.contains("penstyle"))
     penStyle = QgsSymbolLayerV2Utils::decodePenStyle(props["penstyle"]);
   
-  return new QgsSimpleLineSymbolLayerV2(color, width, penStyle);
+  QgsSimpleLineSymbolLayerV2* l = new QgsSimpleLineSymbolLayerV2(color, width, penStyle);
+  if (props.contains("offset"))
+    l->setOffset( props["offset"].toDouble() );
+  return l;
 }
 	
 
@@ -53,7 +56,14 @@
 void QgsSimpleLineSymbolLayerV2::renderPolyline(const QPolygonF& points, QgsRenderContext& context)
 {
   context.painter()->setPen(mPen);
-  context.painter()->drawPolyline(points);
+  if (mOffset == 0)
+  {
+    context.painter()->drawPolyline(points);
+  }
+  else
+  {
+    context.painter()->drawPolyline( ::offsetLine(points, mOffset) );
+  }
 }
 
 QgsStringMap QgsSimpleLineSymbolLayerV2::properties() const
@@ -62,12 +72,15 @@
   map["color"] = QgsSymbolLayerV2Utils::encodeColor(mColor);
   map["width"] = QString::number(mWidth);
   map["penstyle"] = QgsSymbolLayerV2Utils::encodePenStyle(mPenStyle);
+  map["offset"] = QString::number(mOffset);
   return map;
 }
 
 QgsSymbolLayerV2* QgsSimpleLineSymbolLayerV2::clone() const
 {
-  return new QgsSimpleLineSymbolLayerV2(mColor, mWidth, mPenStyle);
+  QgsSimpleLineSymbolLayerV2* l = new QgsSimpleLineSymbolLayerV2(mColor, mWidth, mPenStyle);
+  l->setOffset(mOffset);
+  return l;
 }
 
 
@@ -138,6 +151,7 @@
   mRotateMarker = rotateMarker;
   mInterval = interval;
   mMarker = NULL;
+  mOffset = 0;
   
   setSubSymbol(new QgsMarkerSymbolV2());
 }
@@ -158,6 +172,8 @@
     rotate = (props["rotate"] == "1");
   
   QgsMarkerLineSymbolLayerV2* x = new QgsMarkerLineSymbolLayerV2(rotate, interval);
+  if (props.contains("offset"))
+    x->setOffset(props["offset"].toDouble());
   return x;
 }
 
@@ -187,6 +203,19 @@
 	
 void QgsMarkerLineSymbolLayerV2::renderPolyline(const QPolygonF& points, QgsRenderContext& context)
 {
+  if (mOffset == 0)
+  {
+    renderPolylineNoOffset(points, context);
+  }
+  else
+  {
+    QPolygonF points2 = ::offsetLine( points, mOffset );
+    renderPolylineNoOffset( points2, context );
+  }
+}
+
+void QgsMarkerLineSymbolLayerV2::renderPolylineNoOffset(const QPolygonF& points, QgsRenderContext& context)
+{
   QPointF lastPt = points[0];
   double lengthLeft = 0; // how much is left until next marker
   bool first = true;
@@ -245,6 +274,7 @@
   QgsStringMap map;
   map["rotate"] = (mRotateMarker ? "1" : "0");
   map["interval"] = QString::number(mInterval);
+  map["offset"] = QString::number(mOffset);
   return map;
 }
 
@@ -271,6 +301,7 @@
 {
   QgsMarkerLineSymbolLayerV2* x = new QgsMarkerLineSymbolLayerV2(mRotateMarker, mInterval);
   x->setSubSymbol(mMarker->clone());
+  x->setOffset(mOffset);
   return x;
 }
 

Modified: branches/symbology-ng-branch/src/core/symbology-ng/qgslinesymbollayerv2.h
===================================================================
--- branches/symbology-ng-branch/src/core/symbology-ng/qgslinesymbollayerv2.h	2009-05-16 14:25:35 UTC (rev 10805)
+++ branches/symbology-ng-branch/src/core/symbology-ng/qgslinesymbollayerv2.h	2009-05-17 13:02:06 UTC (rev 10806)
@@ -40,10 +40,14 @@
   
   Qt::PenStyle penStyle() const { return mPenStyle; }
   void setPenStyle(Qt::PenStyle style) { mPenStyle = style; }
+
+  double offset() const { return mOffset; }
+  void setOffset(double offset) { mOffset = offset; }
 	
 protected:
 	Qt::PenStyle mPenStyle;
 	QPen mPen;
+  double mOffset;
 };
 
 /////////
@@ -89,11 +93,18 @@
   
   double interval() const { return mInterval; }
   void setInterval(double interval) { mInterval = interval; }
+
+  double offset() const { return mOffset; }
+  void setOffset(double offset) { mOffset = offset; }
   
 protected:
+
+  void renderPolylineNoOffset(const QPolygonF& points, QgsRenderContext& context);
+
   bool mRotateMarker;
   double mInterval;
   QgsMarkerSymbolV2* mMarker;
+  double mOffset;
 };
 
 /////////

Modified: branches/symbology-ng-branch/src/core/symbology-ng/qgssymbollayerv2utils.cpp
===================================================================
--- branches/symbology-ng-branch/src/core/symbology-ng/qgssymbollayerv2utils.cpp	2009-05-16 14:25:35 UTC (rev 10805)
+++ branches/symbology-ng-branch/src/core/symbology-ng/qgssymbollayerv2utils.cpp	2009-05-17 13:02:06 UTC (rev 10806)
@@ -133,3 +133,109 @@
   painter.end();
   return pixmap;
 }
+
+
+#include <QPolygonF>
+
+#include <cmath>
+#include <cfloat>
+
+
+// calculate line's angle and tangent
+static bool lineInfo(QPointF p1, QPointF p2, double& angle, double& t)
+{
+  double x1 = p1.x(), y1 = p1.y(), x2 = p2.x(), y2 = p2.y();
+
+  if (x1 == x2 && y1 == y2)
+    return false;
+
+  // tangent
+  t = ( x1 == x2 ? t = DBL_MAX : (y2-y1)/(x2-x1) );
+
+  // angle
+  if (t == DBL_MAX)
+    angle = ( y2 >= y1 ? M_PI/2 : M_PI*3/2 );  // angle is 90 or 270
+  else if (t >= 0)
+    angle = ( y2 >= y1 ? atan(t) : M_PI + atan(t) );
+  else // t < 0
+    angle = ( y2 >= y1 ? M_PI + atan(t) : M_PI*2 + atan(t) );
+
+  return true;
+}
+
+// offset a point with an angle and distance
+static QPointF offsetPoint(QPointF pt, double angle, double dist)
+{
+  return QPointF(pt.x() + dist * cos(angle), pt.y() + dist * sin(angle));
+}
+
+// calc intersection of two (infinite) lines defined by one point and tangent
+static QPointF linesIntersection(QPointF p1, double t1, QPointF p2, double t2)
+{
+  // parallel lines?
+  if ( (t1 == DBL_MAX && t2 == DBL_MAX) || t1 == t2)
+    return QPointF();
+
+  double x,y;
+  if (t1 == DBL_MAX || t2 == DBL_MAX)
+  {
+    // in case one line is with angle 90 resp. 270 degrees (tangent undefined)
+    // swap them so that line 2 is with undefined tangent
+    if (t1 == DBL_MAX)
+    {
+      QPointF pSwp = p1; p1 = p2; p2 = pSwp;
+      double  tSwp = t1; t1 = t2; t2 = tSwp;
+    }
+
+    x = p2.x();
+  }
+  else
+  {
+    // usual case
+    x = ( (p1.y() - p2.y()) + t2*p2.x() - t1*p1.x() ) / (t2 - t1);
+  }
+
+  y = p1.y() + t1 * (x - p1.x());
+  return QPointF(x,y);
+}
+
+
+QPolygonF offsetLine(QPolygonF polyline, double dist)
+{
+  QPolygonF newLine;
+
+  if (polyline.count() < 2)
+    return newLine;
+
+  double angle, t_new, t_old=0;
+  QPointF pt_old, pt_new;
+  QPointF p1 = polyline[0], p2;
+
+  for (int i = 1; i < polyline.count(); i++)
+  {
+    p2 = polyline[i];
+
+    if ( !lineInfo(p1, p2, angle, t_new) )
+      continue; // not a line...
+
+    pt_new = offsetPoint(p1, angle + M_PI/2, dist);
+
+    if (i != 1)
+    {
+      // if it's not the first line segment
+      // calc intersection with last line (with offset)
+      pt_new = linesIntersection(pt_old, t_old, pt_new, t_new);
+    }
+
+    newLine.append(pt_new);
+
+    pt_old = pt_new;
+    t_old = t_new;
+    p1 = p2;
+  }
+
+  // last line segment:
+  pt_new = offsetPoint(p2, angle + M_PI/2, dist);
+  newLine.append(pt_new);
+  return newLine;
+}

Modified: branches/symbology-ng-branch/src/core/symbology-ng/qgssymbollayerv2utils.h
===================================================================
--- branches/symbology-ng-branch/src/core/symbology-ng/qgssymbollayerv2utils.h	2009-05-16 14:25:35 UTC (rev 10805)
+++ branches/symbology-ng-branch/src/core/symbology-ng/qgssymbollayerv2utils.h	2009-05-17 13:02:06 UTC (rev 10806)
@@ -37,4 +37,10 @@
   static QPixmap colorRampPreviewPixmap(QgsVectorColorRampV2* ramp, QSize size);
 };
 
+class QPolygonF;
+
+//! calculate line shifted by a specified distance
+QPolygonF offsetLine(QPolygonF polyline, double dist);
+
+
 #endif

Modified: branches/symbology-ng-branch/src/gui/symbology-ng/qgssymbollayerv2widget.cpp
===================================================================
--- branches/symbology-ng-branch/src/gui/symbology-ng/qgssymbollayerv2widget.cpp	2009-05-16 14:25:35 UTC (rev 10805)
+++ branches/symbology-ng-branch/src/gui/symbology-ng/qgssymbollayerv2widget.cpp	2009-05-17 13:02:06 UTC (rev 10806)
@@ -35,6 +35,7 @@
   connect(spinWidth, SIGNAL(valueChanged(int)), this, SLOT(penWidthChanged()));
   connect(btnChangeColor, SIGNAL(clicked()), this, SLOT(colorChanged()));
   connect(cboPenStyle, SIGNAL(currentIndexChanged(int)), this, SLOT(penStyleChanged()));
+  connect(spinOffset, SIGNAL(valueChanged(double)), this, SLOT(offsetChanged()));
 }
 
 void QgsSimpleLineSymbolLayerV2Widget::setSymbolLayer(QgsSymbolLayerV2* layer)
@@ -49,6 +50,7 @@
   spinWidth->setValue(mLayer->width());
   updateColorButton(btnChangeColor, mLayer->color());
   cboPenStyle->setPenStyle(mLayer->penStyle());
+  spinOffset->setValue(mLayer->offset());
 }
 
 QgsSymbolLayerV2* QgsSimpleLineSymbolLayerV2Widget::symbolLayer()
@@ -78,7 +80,13 @@
   emit changed();
 }
 
+void QgsSimpleLineSymbolLayerV2Widget::offsetChanged()
+{
+  mLayer->setOffset(spinOffset->value());
+  emit changed();
+}
 
+
 ///////////
 
 
@@ -249,6 +257,7 @@
   connect(spinInterval, SIGNAL(valueChanged(int)), this, SLOT(setInterval(int)));
   connect(btnChangeMarker, SIGNAL(clicked()), this, SLOT(setMarker()));
   connect(chkRotateMarker, SIGNAL(clicked()), this, SLOT(setRotate()));
+  connect(spinOffset, SIGNAL(valueChanged(double)), this, SLOT(setOffset()));
 }
 
 void QgsMarkerLineSymbolLayerV2Widget::setSymbolLayer(QgsSymbolLayerV2* layer)
@@ -262,6 +271,7 @@
   // set values
   spinInterval->setValue( (int) mLayer->interval());
   chkRotateMarker->setChecked(mLayer->rotateMarker());
+  spinOffset->setValue(mLayer->offset());
   updateMarker();
 }
 
@@ -292,6 +302,13 @@
   emit changed();
 }
 
+void QgsMarkerLineSymbolLayerV2Widget::setOffset()
+{
+  mLayer->setOffset(spinOffset->value());
+  emit changed();
+}
+
+
 void QgsMarkerLineSymbolLayerV2Widget::updateMarker()
 {
   QIcon icon = QgsSymbolLayerV2Utils::symbolPreviewIcon(mLayer->subSymbol(), btnChangeMarker->iconSize());

Modified: branches/symbology-ng-branch/src/gui/symbology-ng/qgssymbollayerv2widget.h
===================================================================
--- branches/symbology-ng-branch/src/gui/symbology-ng/qgssymbollayerv2widget.h	2009-05-16 14:25:35 UTC (rev 10805)
+++ branches/symbology-ng-branch/src/gui/symbology-ng/qgssymbollayerv2widget.h	2009-05-17 13:02:06 UTC (rev 10806)
@@ -44,6 +44,7 @@
     void penWidthChanged();
     void colorChanged();
     void penStyleChanged();
+    void offsetChanged();
     
   protected:
     QgsSimpleLineSymbolLayerV2* mLayer;
@@ -132,6 +133,7 @@
     void setInterval(int val);
     void setMarker();
     void setRotate();
+    void setOffset();
     
   protected:
     

Modified: branches/symbology-ng-branch/src/ui/symbollayer/widget_markerline.ui
===================================================================
--- branches/symbology-ng-branch/src/ui/symbollayer/widget_markerline.ui	2009-05-16 14:25:35 UTC (rev 10805)
+++ branches/symbology-ng-branch/src/ui/symbollayer/widget_markerline.ui	2009-05-17 13:02:06 UTC (rev 10806)
@@ -1,7 +1,8 @@
-<ui version="4.0" >
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
  <class>WidgetMarkerLine</class>
- <widget class="QWidget" name="WidgetMarkerLine" >
-  <property name="geometry" >
+ <widget class="QWidget" name="WidgetMarkerLine">
+  <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
@@ -9,35 +10,35 @@
     <height>192</height>
    </rect>
   </property>
-  <property name="windowTitle" >
+  <property name="windowTitle">
    <string>Form</string>
   </property>
-  <layout class="QVBoxLayout" >
+  <layout class="QVBoxLayout">
    <item>
-    <layout class="QGridLayout" >
-     <item row="0" column="0" >
-      <widget class="QLabel" name="label" >
-       <property name="text" >
+    <layout class="QGridLayout">
+     <item row="0" column="0">
+      <widget class="QLabel" name="label">
+       <property name="text">
         <string>Marker:</string>
        </property>
       </widget>
      </item>
-     <item row="0" column="1" >
-      <widget class="QPushButton" name="btnChangeMarker" >
-       <property name="text" >
+     <item row="0" column="1">
+      <widget class="QPushButton" name="btnChangeMarker">
+       <property name="text">
         <string>change</string>
        </property>
       </widget>
      </item>
-     <item rowspan="3" row="0" column="2" >
+     <item row="0" column="2" rowspan="4">
       <spacer>
-       <property name="orientation" >
+       <property name="orientation">
         <enum>Qt::Horizontal</enum>
        </property>
-       <property name="sizeType" >
+       <property name="sizeType">
         <enum>QSizePolicy::Preferred</enum>
        </property>
-       <property name="sizeHint" >
+       <property name="sizeHint" stdset="0">
         <size>
          <width>40</width>
          <height>20</height>
@@ -45,35 +46,49 @@
        </property>
       </spacer>
      </item>
-     <item row="1" column="0" >
-      <widget class="QLabel" name="label_2" >
-       <property name="text" >
-        <string>Interval:</string>
+     <item row="1" column="0">
+      <widget class="QLabel" name="label_2">
+       <property name="text">
+        <string>Marker interval:</string>
        </property>
       </widget>
      </item>
-     <item row="1" column="1" >
-      <widget class="QSpinBox" name="spinInterval" >
-       <property name="minimum" >
+     <item row="1" column="1">
+      <widget class="QSpinBox" name="spinInterval">
+       <property name="minimum">
         <number>1</number>
        </property>
       </widget>
      </item>
-     <item row="2" column="0" colspan="2" >
-      <widget class="QCheckBox" name="chkRotateMarker" >
-       <property name="text" >
+     <item row="2" column="0" colspan="2">
+      <widget class="QCheckBox" name="chkRotateMarker">
+       <property name="text">
         <string>Rotate marker</string>
        </property>
       </widget>
      </item>
+     <item row="3" column="0">
+      <widget class="QLabel" name="label_3">
+       <property name="text">
+        <string>Line offset:</string>
+       </property>
+      </widget>
+     </item>
+     <item row="3" column="1">
+      <widget class="QDoubleSpinBox" name="spinOffset">
+       <property name="minimum">
+        <double>-99.989999999999995</double>
+       </property>
+      </widget>
+     </item>
     </layout>
    </item>
    <item>
     <spacer>
-     <property name="orientation" >
+     <property name="orientation">
       <enum>Qt::Vertical</enum>
      </property>
-     <property name="sizeHint" >
+     <property name="sizeHint" stdset="0">
       <size>
        <width>261</width>
        <height>40</height>
@@ -86,7 +101,6 @@
  <tabstops>
   <tabstop>btnChangeMarker</tabstop>
   <tabstop>spinInterval</tabstop>
-  <tabstop>chkRotateMarker</tabstop>
  </tabstops>
  <resources/>
  <connections/>

Modified: branches/symbology-ng-branch/src/ui/symbollayer/widget_simpleline.ui
===================================================================
--- branches/symbology-ng-branch/src/ui/symbollayer/widget_simpleline.ui	2009-05-16 14:25:35 UTC (rev 10805)
+++ branches/symbology-ng-branch/src/ui/symbollayer/widget_simpleline.ui	2009-05-17 13:02:06 UTC (rev 10806)
@@ -1,7 +1,8 @@
-<ui version="4.0" >
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
  <class>WidgetSimpleLine</class>
- <widget class="QWidget" name="WidgetSimpleLine" >
-  <property name="geometry" >
+ <widget class="QWidget" name="WidgetSimpleLine">
+  <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
@@ -9,41 +10,41 @@
     <height>244</height>
    </rect>
   </property>
-  <property name="windowTitle" >
+  <property name="windowTitle">
    <string>Form</string>
   </property>
-  <layout class="QVBoxLayout" >
+  <layout class="QVBoxLayout">
    <item>
-    <layout class="QGridLayout" >
-     <item row="0" column="0" >
-      <widget class="QLabel" name="label" >
-       <property name="text" >
+    <layout class="QGridLayout">
+     <item row="0" column="0">
+      <widget class="QLabel" name="label">
+       <property name="text">
         <string>Color:</string>
        </property>
       </widget>
      </item>
-     <item row="0" column="1" >
-      <widget class="QPushButton" name="btnChangeColor" >
-       <property name="sizePolicy" >
-        <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+     <item row="0" column="1">
+      <widget class="QPushButton" name="btnChangeColor">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
          <horstretch>0</horstretch>
          <verstretch>0</verstretch>
         </sizepolicy>
        </property>
-       <property name="text" >
+       <property name="text">
         <string>change</string>
        </property>
       </widget>
      </item>
-     <item rowspan="3" row="0" column="2" >
+     <item row="0" column="2" rowspan="4">
       <spacer>
-       <property name="orientation" >
+       <property name="orientation">
         <enum>Qt::Horizontal</enum>
        </property>
-       <property name="sizeType" >
+       <property name="sizeType">
         <enum>QSizePolicy::Preferred</enum>
        </property>
-       <property name="sizeHint" >
+       <property name="sizeHint" stdset="0">
         <size>
          <width>50</width>
          <height>91</height>
@@ -51,47 +52,61 @@
        </property>
       </spacer>
      </item>
-     <item row="1" column="0" >
-      <widget class="QLabel" name="label_2" >
-       <property name="text" >
+     <item row="1" column="0">
+      <widget class="QLabel" name="label_2">
+       <property name="text">
         <string>Pen width:</string>
        </property>
       </widget>
      </item>
-     <item row="1" column="1" >
-      <widget class="QSpinBox" name="spinWidth" >
-       <property name="sizePolicy" >
-        <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+     <item row="1" column="1">
+      <widget class="QSpinBox" name="spinWidth">
+       <property name="sizePolicy">
+        <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
          <horstretch>0</horstretch>
          <verstretch>0</verstretch>
         </sizepolicy>
        </property>
-       <property name="alignment" >
+       <property name="alignment">
         <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
        </property>
-       <property name="minimum" >
+       <property name="minimum">
         <number>1</number>
        </property>
       </widget>
      </item>
-     <item row="2" column="0" >
-      <widget class="QLabel" name="label_3" >
-       <property name="text" >
+     <item row="2" column="0">
+      <widget class="QLabel" name="label_3">
+       <property name="text">
         <string>Pen style:</string>
        </property>
       </widget>
      </item>
-     <item row="2" column="1" >
-      <widget class="QgsPenStyleComboBox" name="cboPenStyle" />
+     <item row="2" column="1">
+      <widget class="QgsPenStyleComboBox" name="cboPenStyle"/>
      </item>
+     <item row="3" column="0">
+      <widget class="QLabel" name="label_4">
+       <property name="text">
+        <string>Offset:</string>
+       </property>
+      </widget>
+     </item>
+     <item row="3" column="1">
+      <widget class="QDoubleSpinBox" name="spinOffset">
+       <property name="minimum">
+        <double>-99.989999999999995</double>
+       </property>
+      </widget>
+     </item>
     </layout>
    </item>
    <item>
     <spacer>
-     <property name="orientation" >
+     <property name="orientation">
       <enum>Qt::Vertical</enum>
      </property>
-     <property name="sizeHint" >
+     <property name="sizeHint" stdset="0">
       <size>
        <width>350</width>
        <height>81</height>



More information about the QGIS-commit mailing list