Skip to content
Permalink
Browse files

[FEATURE][composer] Add tools for drawing polygon and polylines

  • Loading branch information
pblottiere authored and nyalldawson committed Apr 1, 2016
1 parent bde5126 commit 7a8a5411e09a3076f96d727166d8877304b29543
Showing with 4,453 additions and 43 deletions.
  1. +2 −0 ci/travis/linux/qt5/blacklist.txt
  2. +4 −0 images/images.qrc
  3. +332 −0 images/themes/default/mActionAddNodesItem.svg
  4. +355 −0 images/themes/default/mActionAddPolygon.svg
  5. +344 −0 images/themes/default/mActionAddPolyline.svg
  6. +423 −0 images/themes/default/mActionEditNodesItem.svg
  7. +12 −0 python/core/composer/qgscomposeritem.sip
  8. +111 −0 python/core/composer/qgscomposernodesitem.sip
  9. +41 −0 python/core/composer/qgscomposerpolygon.sip
  10. +42 −0 python/core/composer/qgscomposerpolyline.sip
  11. +16 −8 python/core/composer/qgscomposition.sip
  12. +3 −0 python/core/core.sip
  13. +4 −0 src/app/CMakeLists.txt
  14. +77 −0 src/app/composer/qgscomposer.cpp
  15. +13 −0 src/app/composer/qgscomposer.h
  16. +94 −0 src/app/composer/qgscomposerpolygonwidget.cpp
  17. +48 −0 src/app/composer/qgscomposerpolygonwidget.h
  18. +84 −0 src/app/composer/qgscomposerpolylinewidget.cpp
  19. +48 −0 src/app/composer/qgscomposerpolylinewidget.h
  20. +6 −0 src/core/CMakeLists.txt
  21. +2 −0 src/core/composer/qgscomposeritem.h
  22. +425 −0 src/core/composer/qgscomposernodesitem.cpp
  23. +169 −0 src/core/composer/qgscomposernodesitem.h
  24. +122 −0 src/core/composer/qgscomposerpolygon.cpp
  25. +85 −0 src/core/composer/qgscomposerpolygon.h
  26. +124 −0 src/core/composer/qgscomposerpolyline.cpp
  27. +85 −0 src/core/composer/qgscomposerpolyline.h
  28. +99 −0 src/core/composer/qgscomposition.cpp
  29. +18 −8 src/core/composer/qgscomposition.h
  30. +523 −25 src/gui/qgscomposerview.cpp
  31. +18 −0 src/gui/qgscomposerview.h
  32. +44 −2 src/ui/composer/qgscomposerbase.ui
  33. +113 −0 src/ui/composer/qgscomposerpolygonwidgetbase.ui
  34. +99 −0 src/ui/composer/qgscomposerpolylinewidgetbase.ui
  35. +2 −0 tests/src/python/CMakeLists.txt
  36. +234 −0 tests/src/python/test_qgscomposerpolygon.py
  37. +232 −0 tests/src/python/test_qgscomposerpolyline.py
  38. BIN ...rol_images/composer_polygon/expected_composerpolygon_addnode/expected_composerpolygon_addnode.png
  39. BIN .../composer_polygon/expected_composerpolygon_defaultstyle/expected_composerpolygon_defaultstyle.png
  40. BIN .../composer_polygon/expected_composerpolygon_displaynodes/expected_composerpolygon_displaynodes.png
  41. BIN ...l_images/composer_polygon/expected_composerpolygon_movenode/expected_composerpolygon_movenode.png
  42. BIN ...es/composer_polygon/expected_composerpolygon_removednode/expected_composerpolygon_removednode.png
  43. BIN .../composer_polygon/expected_composerpolygon_selectednode/expected_composerpolygon_selectednode.png
  44. BIN ..._images/composer_polyline/expected_composerpolyline_addnode/expected_composerpolyline_addnode.png
  45. BIN ...mposer_polyline/expected_composerpolyline_defaultstyle/expected_composerpolyline_defaultstyle.png
  46. BIN ...mposer_polyline/expected_composerpolyline_displaynodes/expected_composerpolyline_displaynodes.png
  47. BIN ...mages/composer_polyline/expected_composerpolyline_movenode/expected_composerpolyline_movenode.png
  48. BIN ...composer_polyline/expected_composerpolyline_removednode/expected_composerpolyline_removednode.png
  49. BIN ...mposer_polyline/expected_composerpolyline_selectednode/expected_composerpolyline_selectednode.png
@@ -14,6 +14,8 @@ PyQgsComposerMap
PyQgsComposerMapGrid
PyQgsComposerPicture
PyQgsComposerShapes
PyQgsComposerPolygon
PyQgsComposerPolyline
PyQgsComposition
PyQgsConditionalStyle
PyQgsCoordinateTransform
@@ -115,6 +115,10 @@
<file>themes/default/mActionAddBasicShape.png</file>
<file>themes/default/mActionAddBasicShape.svg</file>
<file>themes/default/mActionAddBasicCircle.svg</file>
<file>themes/default/mActionEditNodesItem.svg</file>
<file>themes/default/mActionAddNodesItem.svg</file>
<file>themes/default/mActionAddPolygon.svg</file>
<file>themes/default/mActionAddPolyline.svg</file>
<file>themes/default/mActionAddBasicRectangle.svg</file>
<file>themes/default/mActionAddBasicTriangle.svg</file>
<file>themes/default/mActionAddGPSLayer.png</file>
@@ -0,0 +1,332 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->

<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="24"
height="24"
id="svg5692"
version="1.1"
inkscape:version="0.48.5 r10040"
sodipodi:docname="mActionAddPointsBasedShape.svg"
inkscape:export-filename="/home/denis/Desktop/oracle.png"
inkscape:export-xdpi="67.5"
inkscape:export-ydpi="67.5">
<title
id="title2829">GIS icon theme 0.2</title>
<defs
id="defs5694">
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 16 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="32 : 16 : 1"
inkscape:persp3d-origin="16 : 10.666667 : 1"
id="perspective3486" />
<inkscape:perspective
id="perspective3496"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<inkscape:perspective
id="perspective3600"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<inkscape:perspective
id="perspective7871"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<inkscape:perspective
id="perspective8710"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<inkscape:perspective
id="perspective9811"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<inkscape:perspective
id="perspective4762"
inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
inkscape:vp_z="1 : 0.5 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 0.5 : 1"
sodipodi:type="inkscape:persp3d" />
<filter
y="-0.25"
x="-0.25"
height="1.5"
width="1.5"
inkscape:label="Drop shadow"
id="filter4128"
color-interpolation-filters="sRGB">
<feGaussianBlur
result="blur"
stdDeviation="2.000000"
in="SourceAlpha"
id="feGaussianBlur4130" />
<feColorMatrix
values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0.351000 0 "
type="matrix"
result="bluralpha"
id="feColorMatrix4132" />
<feOffset
result="offsetBlur"
dy="7.500000"
dx="7.500000"
in="bluralpha"
id="feOffset4134" />
<feMerge
id="feMerge4136">
<feMergeNode
in="offsetBlur"
id="feMergeNode4138" />
<feMergeNode
in="SourceGraphic"
id="feMergeNode4140" />
</feMerge>
</filter>
<inkscape:perspective
id="perspective2850"
inkscape:persp3d-origin="270.04437 : 185.57625 : 1"
inkscape:vp_z="540.08875 : 278.36438 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 278.36438 : 1"
sodipodi:type="inkscape:persp3d" />
<inkscape:perspective
id="perspective2491"
inkscape:persp3d-origin="270.04437 : 185.57625 : 1"
inkscape:vp_z="540.08875 : 278.36438 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_x="0 : 278.36438 : 1"
sodipodi:type="inkscape:persp3d" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="11.269514"
inkscape:cx="27.137027"
inkscape:cy="12.539424"
inkscape:current-layer="layer2"
showgrid="true"
inkscape:grid-bbox="true"
inkscape:document-units="px"
borderlayer="false"
inkscape:window-width="1918"
inkscape:window-height="1059"
inkscape:window-x="0"
inkscape:window-y="19"
inkscape:window-maximized="1"
inkscape:snap-global="true"
showguides="true"
inkscape:guide-bbox="true"
inkscape:snap-object-midpoints="false"
inkscape:snap-grids="true"
inkscape:object-paths="false">
<inkscape:grid
type="xygrid"
id="grid5700"
empspacing="5"
visible="true"
enabled="true"
snapvisiblegridlinesonly="true"
dotted="false"
originx="0"
originy="0" />
</sodipodi:namedview>
<metadata
id="metadata5697">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title>GIS icon theme 0.2</dc:title>
<dc:creator>
<cc:Agent>
<dc:title>Robert Szczepanek</dc:title>
</cc:Agent>
</dc:creator>
<dc:rights>
<cc:Agent>
<dc:title>Robert Szczepanek</dc:title>
</cc:Agent>
</dc:rights>
<dc:subject>
<rdf:Bag>
<rdf:li>GIS icons</rdf:li>
</rdf:Bag>
</dc:subject>
<dc:coverage>GIS icons</dc:coverage>
<dc:description>http://robert.szczepanek.pl/</dc:description>
<cc:license
rdf:resource="http://creativecommons.org/licenses/by-sa/3.0/" />
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/licenses/by-sa/3.0/">
<cc:permits
rdf:resource="http://creativecommons.org/ns#Reproduction" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#Distribution" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#Notice" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#Attribution" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#ShareAlike" />
</cc:License>
</rdf:RDF>
</metadata>
<g
inkscape:groupmode="layer"
id="layer2"
inkscape:label="Layer"
style="display:inline"
transform="translate(0,-8)">
<g
id="orginal-6"
style="fill-rule:nonzero;stroke:#415a75;stroke-miterlimit:4;stroke-opacity:1"
transform="matrix(0.04360941,0,0,0.04360941,-23.975751,6.5017873)" />
<path
inkscape:connector-curvature="0"
id="path2484"
style="fill-rule:nonzero;stroke:#415a75;stroke-width:0.13082823;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1"
d="" />
<g
style="display:inline"
id="g3772"
transform="matrix(0.69230769,0,0,0.69230769,1.8461539,9.8461539)">
<rect
ry="2.6149368"
inkscape:export-ydpi="120"
inkscape:export-xdpi="120"
y="19"
x="19"
height="13"
width="13"
id="rect3563"
style="fill:#5a8c5a;fill-opacity:1;stroke:#555753;stroke-width:0;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline"
inkscape:export-filename="C:\Program Files\QGIS-Dev\themes\gis-0.1\mActionAddOgrLayer.png"
rx="2.6149371" />
<path
inkscape:connector-curvature="0"
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:2.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 21.6,25.499999 7.8,0"
id="path3807"
sodipodi:nodetypes="cc" />
<path
inkscape:connector-curvature="0"
id="path3809"
d="M 25.5,29.399999 25.5,21.6"
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:2.5999999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
sodipodi:nodetypes="cc" />
<path
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccsssc"
id="path6992"
d="m 20.3,25.499999 10.4,0 c 0,0 0,0 0,-2.6 C 30.7,20.3 30.05,20.3 25.5,20.3 c -4.55,0 -5.2,0 -5.2,2.599999 0,2.6 0,2.6 0,2.6 z"
style="opacity:0.3;fill:#fcffff;fill-rule:evenodd;stroke:none;display:inline;enable-background:new" />
</g>
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline"
d="M 0,8 0,8"
id="path3872"
inkscape:connector-type="polyline"
inkscape:connector-curvature="3" />
<path
style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:1, 1;stroke-dashoffset:0;display:inline"
d="M 5.5991742,18.641711 18.400826,10.35829"
id="path3080"
inkscape:connector-type="polyline"
inkscape:connector-curvature="3"
transform="translate(0,8)"
inkscape:connection-end="#path4188-0-8-5-9-4"
inkscape:connection-end-point="d4"
inkscape:connection-start="#path4188-0-8-5-9-6"
inkscape:connection-start-point="d4" />
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline"
d="M 18.263443,7.8817218 10.736557,4.1182786"
id="path3255"
inkscape:connector-type="polyline"
inkscape:connector-curvature="0"
transform="translate(0,8)"
inkscape:connection-end="#path4188-0-8-5-9"
inkscape:connection-end-point="d4"
inkscape:connection-start="#path4188-0-8-5-9-4"
inkscape:connection-start-point="d4" />
<circle
style="fill:#2a7fff;fill-opacity:1;stroke:#333333;stroke-width:1.00173461;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:0.40000001;stroke-opacity:0.97254902;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
id="path4188-0-8-5-9"
cx="12"
cy="20"
r="8.5"
d="m 20.5,20 c 0,4.69442 -3.80558,8.5 -8.5,8.5 -4.6944204,0 -8.5,-3.80558 -8.5,-8.5 0,-4.69442 3.8055796,-8.5 8.5,-8.5 4.69442,0 8.5,3.80558 8.5,8.5 z"
sodipodi:cx="12"
sodipodi:cy="20"
sodipodi:rx="8.5"
sodipodi:ry="8.5"
transform="matrix(0.29411765,0,0,0.29411762,4.9705882,5.1176476)" />
<circle
style="fill:#2a7fff;fill-opacity:1;stroke:#333333;stroke-width:1.00173461;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:0.40000001;stroke-opacity:0.97254902;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
id="path4188-0-8-5-9-4"
cx="12"
cy="20"
r="8.5"
d="m 20.5,20 c 0,4.69442 -3.80558,8.5 -8.5,8.5 -4.6944204,0 -8.5,-3.80558 -8.5,-8.5 0,-4.69442 3.8055796,-8.5 8.5,-8.5 4.69442,0 8.5,3.80558 8.5,8.5 z"
sodipodi:cx="12"
sodipodi:cy="20"
sodipodi:rx="8.5"
sodipodi:ry="8.5"
transform="matrix(0.29411765,0,0,0.29411762,16.970588,11.117648)" />
<circle
style="fill:#2a7fff;fill-opacity:1;stroke:#333333;stroke-width:1.00173461;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:0.40000001;stroke-opacity:0.97254902;stroke-dasharray:none;stroke-dashoffset:0;display:inline"
id="path4188-0-8-5-9-6"
cx="12"
cy="20"
r="8.5"
d="m 20.5,20 c 0,4.69442 -3.80558,8.5 -8.5,8.5 -4.6944204,0 -8.5,-3.80558 -8.5,-8.5 0,-4.69442 3.8055796,-8.5 8.5,-8.5 4.69442,0 8.5,3.80558 8.5,8.5 z"
sodipodi:cx="12"
sodipodi:cy="20"
sodipodi:rx="8.5"
sodipodi:ry="8.5"
transform="matrix(0.29411765,0,0,0.29411762,-0.02941183,22.117648)" />
<path
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="M 7.7944002,5.3990395 4.2055998,17.600961"
id="path3311"
inkscape:connector-type="polyline"
inkscape:connector-curvature="0"
inkscape:connection-start="#path4188-0-8-5-9"
inkscape:connection-start-point="d4"
inkscape:connection-end="#path4188-0-8-5-9-6"
inkscape:connection-end-point="d4"
transform="translate(0,8)" />
</g>
</svg>

3 comments on commit 7a8a541

@nirvn

This comment has been minimized.

Copy link
Contributor

@nirvn nirvn replied Apr 1, 2016

@nyalldawson I get a compilation error:

`
Building CXX object src/core/CMakeFiles/qgis_core.dir/composer/qgscomposernodesitem.cpp.o
/home/webmaster/dev/cpp/QGIS/src/core/composer/qgscomposernodesitem.cpp: In member function ‘bool QgsComposerNodesItem::addNode(const QPointF&, bool, double)’:
/home/webmaster/dev/cpp/QGIS/src/core/composer/qgscomposernodesitem.cpp:82:22: error: ‘isinf’ was not declared in this scope
if ( isinf( coef ) )

/home/webmaster/dev/cpp/QGIS/src/core/composer/qgscomposernodesitem.cpp:82:22: note: suggested alternative:
In file included from /usr/include/c++/5/random:38:0,
from /usr/include/c++/5/bits/stl_algo.h:66,
from /usr/include/c++/5/algorithm:62,
from /usr/include/qt4/QtCore/qglobal.h:68,
from /usr/include/qt4/QtCore/qnamespace.h:45,
from /usr/include/qt4/QtCore/qobjectdefs.h:45,
from /usr/include/qt4/QtCore/qobject.h:47,
from /usr/include/qt4/QtGui/qundostack.h:45,
from /usr/include/qt4/QtGui/QUndoCommand:1,
from /home/webmaster/dev/cpp/QGIS/src/core/composer/qgscomposeritemcommand.h:21,
from /home/webmaster/dev/cpp/QGIS/src/core/composer/qgscomposeritem.h:20,
from /home/webmaster/dev/cpp/QGIS/src/core/composer/qgscomposernodesitem.h:20,
from /home/webmaster/dev/cpp/QGIS/src/core/composer/qgscomposernodesitem.cpp:17:
/usr/include/c++/5/cmath:621:5: note: ‘std::isinf’
isinf(_Tp __x)
^
`

(I'm on Ubuntu Xenial)

@nirvn

This comment has been minimized.

Copy link
Contributor

@nirvn nirvn replied Apr 1, 2016

@nyalldawson your suggestion to use qIsInf instead of isinf works, making process is successful.

@nirvn

This comment has been minimized.

Copy link
Contributor

@nirvn nirvn replied Apr 4, 2016

@pblottiere , @nyalldawson , spotted a serious issue with polyline which needs addressing: http://hub.qgis.org/issues/14611

A white fill is drawn for polyline items if [x] draw effects is enabled:
line-effect-problem

Please sign in to comment.
You can’t perform that action at this time.