[Qgis-developer] arrows on line strings?
Stefanie Tellex
stefie10 at media.mit.edu
Fri Feb 1 23:37:48 EST 2008
Hi Tim,
Not sure what went wrong. Here's another one against -R8098.
I generated it by running svn diff > patch from a checkout of
https://svn.qgis.org/repos/qgis/trunk/qgis . Did I generate it wrong?
This version adds an argument to drawLineString called drawArrows that
defaults to false. I called it with that argument only when the
geometry is a linestring. So arrows no longer appear on polygons or
multi line strings, but appear on all line strings.
Stefanie
Tim Sutton wrote:
> Hi Stefanie
>
> I tried to apply your patch:
>
> [qgis] svn update -r 8092
> Na revisão 8092.
> [qgis] patch -p0 < ~/tmp/line_arrows.diff
> patching file src/core/qgsvectorlayer.cpp
> Hunk #1 FAILED at 425.
> Hunk #2 FAILED at 434.
> Hunk #3 FAILED at 452.
> 3 out of 3 hunks FAILED -- saving rejects to file
> src/core/qgsvectorlayer.cpp.rej
>
>
> I didnt have time to manually resolve the rejected but perhaps
> regenerating it off trunk might help. I can add a simple checkbox
> option to the vector props dialog and do the associated xml
> (de)serialisation. This would probably only happen in a month or so
> since we are in feature freeze for getting 0.9.2 final out (so I would
> target it for 0.9.3). I would suggest to go with your approach for now
> since we are trying to get 1.0 out and implementing the renderers
> approach described by Magnus will only happen post 1.0. On the other
> hand I have often been asked about the ability to show direction on
> lines so adding your basic implementation for now seems like a good
> way to go for 1.0 relase. If anyone vigorously disagrees let me know,
> otherwise I'll incorporate your patch in 0.9.3 with some additions
> from myself to enabled or disable line arrows via the layer props
> dialog, the vector api and the layer properties serialisation
> mechanism.
>
> Best regards
>
> Tim
>
> 2008/2/1, Stefanie Tellex <stefie10 at media.mit.edu>:
>> 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
>>
>> 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;
>> }
>>
>> _______________________________________________
>> Qgis-developer mailing list
>> Qgis-developer at lists.qgis.org
>> http://lists.qgis.org/cgi-bin/mailman/listinfo/qgis-developer
>>
>>
>
>
-------------- next part --------------
Index: src/core/qgsvectorlayer.cpp
===================================================================
--- src/core/qgsvectorlayer.cpp (revision 8098)
+++ src/core/qgsvectorlayer.cpp (working copy)
@@ -353,7 +353,8 @@
QPainter* p,
QgsMapToPixel* mtp,
QgsCoordinateTransform* ct,
- bool drawingToEditingCanvas)
+ bool drawingToEditingCanvas,
+ bool drawArrows)
{
unsigned char *ptr = feature + 5;
unsigned int wkbType = *((int*)(feature+1));
@@ -425,6 +426,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 +435,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 +453,45 @@
drawVertexMarker((int)(*xIt), (int)(*yIt), *p);
}
}
-
+ // draw arrows
+ if (drawArrows) {
+#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;
}
@@ -3035,7 +3075,7 @@
p,
theMapToPixelTransform,
ct,
- drawingToEditingCanvas);
+ drawingToEditingCanvas, TRUE);
break;
}
case QGis::WKBMultiLineString:
Index: src/core/qgsvectorlayer.h
===================================================================
--- src/core/qgsvectorlayer.h (revision 8098)
+++ src/core/qgsvectorlayer.h (working copy)
@@ -459,7 +459,8 @@
QPainter* p,
QgsMapToPixel* mtp,
QgsCoordinateTransform* ct,
- bool drawingToEditingCanvas);
+ bool drawingToEditingCanvas,
+ bool drawArrows=FALSE);
/** Draw the polygon as given in the WKB format. Returns a pointer to
* the byte after the end of the polygon binary data stream (WKB).
More information about the Qgis-developer
mailing list