[Qgis-developer] arrows on line strings?

Stefanie Tellex stefie10 at media.mit.edu
Fri Feb 1 12:11:04 EST 2008


Hi,

The attached patch against R8092 draws arrows on all linestrings 
everywhere, no matter what, using code swiped from this GPL v2.0 
licensed file: 
http://doc.trolltech.com/4.3/graphicsview-diagramscene-arrow-cpp.html

What's the best way to control arrow drawing so it only shows up on 
particular layers? Seems like it should be written to the xml file also, 
in which case it might be better to just wait until better rendering 
happens, and live with patching QGIS myself until then...?

There's also a bug on multi-line-strings where an arrow line gets drawn 
to some random coordinate in the upper left hand corner which I'm not 
motivated to fix since I only need arrows on line-strings...

Stefanie

Martin Dobias wrote:
> On Jan 31, 2008 5:49 PM, Stefanie Tellex <stefie10 at media.mit.edu> wrote:
>> Hi,
>>
>> I would like to draw arrows on line strings, since they represent
>> movement vectors and I want to show the direction of movement.  I
>> couldn't find any way to do that in the gui or any obvious way in the
>> programmatic API.  What's the best way to add this feature or is it
>> there already somewhere?
> 
> Currently QGIS renderers work in a way that they just set some
> properties for painting and let the vector layer to draw the polyline,
> so it's not possible to create a renderer which would e.g. render
> arrows in the direction of the flow. We should allow renderers to do
> arbitrary drawing in future.
> 
> Now it will be more complicated to acquire this effect: you can
> generate some points (e.g. in the middle of every line segment) and
> determine the angle of direction. Such generated vector layer with
> points you can load to map canvas and for rendering set a SVG symbol
> with an arrow and set rotation field appropriately to the field you've
> generated.
> 
> Martin

-------------- next part --------------
Index: src/core/qgsvectorlayer.cpp
===================================================================
--- src/core/qgsvectorlayer.cpp	(revision 8092)
+++ src/core/qgsvectorlayer.cpp	(working copy)
@@ -425,6 +425,7 @@
   // 255 = opaque
   //
   QPen myTransparentPen = p->pen(); // store current pen
+  QBrush brush = p->brush(); //to be kept as original
   QColor myColor = myTransparentPen.color();
   //only set transparency from layer level if renderer does not provide
   //transparency on class level
@@ -433,7 +434,9 @@
       myColor.setAlpha(mTransparencyLevel);
     }
   myTransparentPen.setColor(myColor);
+
   p->setPen(myTransparentPen);
+  
   p->drawPolyline(pa);
 
   // draw vertex markers if in editing mode, but only to the main canvas
@@ -449,9 +452,43 @@
 	  drawVertexMarker((int)(*xIt), (int)(*yIt), *p);
 	}
     }
+  // draw arrows
+#define PI 3.14159
+  p->setBrush(QBrush(myColor, Qt::SolidPattern));
+  
+  for (int i = 0; i < pa.size(); ++i)
+    {
+      if (i > 0) 
+	{
+	  QPointF p1 = pa[i];
+	  QPointF p2 = pa[i-1];
 
+	  QLineF line = QLineF(p1, p2);
+	  double angle = ::acos(line.dx() / line.length());
+	  if (line.dy() >= 0)
+	    {
+	    angle = (PI * 2) - angle;
+	    }
+
+	  float arrowSize = 10;
+	  QPointF arrowP1 = 
+	    line.p1() + QPointF(sin(angle + PI / 3) * arrowSize,
+				cos(angle + PI / 3) * arrowSize);
+	  QPointF arrowP2 = 
+	    line.p1() + QPointF(sin(angle + PI - PI / 3) * arrowSize,
+				cos(angle + PI - PI / 3) * arrowSize);
+	  QPolygonF arrowHead;
+	  arrowHead << line.p1() << arrowP1 << arrowP2;
+	  p->drawPolygon(arrowHead);
+
+	
+	}
+      QgsDebugMsgLevel("pa" + QString::number(pa.point(i).x()), 2);
+      QgsDebugMsgLevel("pa" + QString::number(pa.point(i).y()), 2);
+    }
   //restore the pen
   p->setPen(pen);
+  p->setBrush(brush);
   
   return ptr;
 }


More information about the Qgis-developer mailing list