Skip to content
Permalink
Browse files

[FEATURE] Average line angles for marker and hashed line symbology

Previously, when marker or hash lines were rendered using interval
or center point place placement, the symbol angles were determined
by taking the exact line orientation at the position of the symbol.

This often leads to undesirable rendering effects, where little
jaggies or corners in lines which occur at the position of the
symbol cause the marker or hash line to be oriented at a very
different angle to what the eye expects to see.

With this new option, the angle is instead calculated by averaging
the line over a specified distance either side of the symbol. E.g.
averaging the line angle over 4mm means we take the points along
the line 2mm from either side of the symbol placement, and use these
instead to calculate the line angle for that symbol. This has the
effect of smoothing (or removing) any tiny local deviations from
the overall line direction, resulting in much nicer visual
orientation of marker or hash lines.

Like all symbol settings, the average angle smoothing distance
can be set using mm/pixels/map units/etc, and supports data-defined
values.

Closed rings also correctly consider wrapping around these average
angles from the start/end vertex.

(Sponsored by an anonymous corporate backer)
  • Loading branch information
nyalldawson committed Apr 5, 2019
1 parent 4d7f0c2 commit 426382c919a0082e86d22b63200bb9c39b065573
Showing with 1,169 additions and 164 deletions.
  1. +76 −0 python/core/auto_generated/symbology/qgslinesymbollayer.sip.in
  2. +1 −0 python/core/auto_generated/symbology/qgssymbollayer.sip.in
  3. +273 −53 src/core/symbology/qgslinesymbollayer.cpp
  4. +77 −2 src/core/symbology/qgslinesymbollayer.h
  5. +1 −0 src/core/symbology/qgssymbollayer.cpp
  6. +1 −0 src/core/symbology/qgssymbollayer.h
  7. +70 −2 src/gui/symbology/qgssymbollayerwidget.cpp
  8. +4 −0 src/gui/symbology/qgssymbollayerwidget.h
  9. +154 −73 src/ui/symbollayer/widget_hashline.ui
  10. +107 −31 src/ui/symbollayer/widget_markerline.ui
  11. +238 −3 tests/src/core/testqgsmarkerlinesymbol.cpp
  12. +73 −0 tests/src/python/test_qgshashlinesymbollayer.py
  13. +94 −0 tests/src/python/test_qgsmarkerlinesymbollayer.py
  14. BIN ...ser_paper/expected_composerpaper_markerborder/layout/expected_composerpaper_markerborder_mask.png
  15. BIN ...rter/expected_importComposerTemplatePolyline_0/expected_importComposerTemplatePolyline_0_mask.png
  16. BIN ...compositionconverter/expected_importComposerTemplate_1/expected_importComposerTemplate_1_mask.png
  17. BIN tests/testdata/control_images/expected_style_linecanvasclip/expected_style_linecanvasclip_mask.png
  18. BIN ...tdata/control_images/expected_style_linecanvasclip_off/expected_style_linecanvasclip_off_mask.png
  19. BIN ...trol_images/symbol_hashline/expected_line_hash_average_angle/expected_line_hash_average_angle.png
  20. BIN ...mbol_hashline/expected_line_hash_center_average_angle/expected_line_hash_center_average_angle.png
  21. BIN ...s/symbol_hashline/expected_line_hash_ring_average_angle/expected_line_hash_ring_average_angle.png
  22. BIN ..._images/symbol_markerline/expected_markerline_average_angle/expected_markerline_average_angle.png
  23. BIN ..._markerline/expected_markerline_center_average_angle/expected_markerline_center_average_angle.png
  24. BIN ...mbol_markerline/expected_markerline_ring_average_angle/expected_markerline_ring_average_angle.png
  25. BIN ..._images/symbol_markerline/expected_markerline_ring_no_dupes/expected_markerline_ring_no_dupes.png
@@ -425,6 +425,82 @@ Returns the map unit scale used for calculating the offset in map units along li
Sets the map unit ``scale`` used for calculating the offset in map units along line for symbols.

.. seealso:: :py:func:`offsetAlongLineMapUnitScale`
%End

double averageAngleLength() const;
%Docstring
Returns the length of line over which the line's direction is averaged when
calculating individual symbol angles. Longer lengths smooth out angles from jagged lines to a greater extent.

Units are retrieved through averageAngleUnit()

.. seealso:: :py:func:`setAverageAngleLength`

.. seealso:: :py:func:`averageAngleUnit`

.. seealso:: :py:func:`averageAngleMapUnitScale`
%End

void setAverageAngleLength( double length );
%Docstring
Sets the ``length`` of line over which the line's direction is averaged when
calculating individual symbol angles. Longer lengths smooth out angles from jagged lines to a greater extent.

Units are set through setAverageAngleUnit()

.. seealso:: :py:func:`averageAngleLength`

.. seealso:: :py:func:`setAverageAngleUnit`

.. seealso:: :py:func:`setAverageAngleMapUnitScale`
%End

void setAverageAngleUnit( QgsUnitTypes::RenderUnit unit );
%Docstring
Sets the ``unit`` for the length over which the line's direction is averaged when
calculating individual symbol angles.

.. seealso:: :py:func:`averageAngleUnit`

.. seealso:: :py:func:`setAverageAngleLength`

.. seealso:: :py:func:`setAverageAngleMapUnitScale`
%End

QgsUnitTypes::RenderUnit averageAngleUnit() const;
%Docstring
Returns the unit for the length over which the line's direction is averaged when
calculating individual symbol angles.

.. seealso:: :py:func:`setAverageAngleUnit`

.. seealso:: :py:func:`averageAngleLength`

.. seealso:: :py:func:`averageAngleMapUnitScale`
%End

void setAverageAngleMapUnitScale( const QgsMapUnitScale &scale );
%Docstring
Sets the map unit ``scale`` for the length over which the line's direction is averaged when
calculating individual symbol angles.

.. seealso:: :py:func:`averageAngleMapUnitScale`

.. seealso:: :py:func:`setAverageAngleLength`

.. seealso:: :py:func:`setAverageAngleUnit`
%End

const QgsMapUnitScale &averageAngleMapUnitScale() const;
%Docstring
Returns the map unit scale for the length over which the line's direction is averaged when
calculating individual symbol angles.

.. seealso:: :py:func:`setAverageAngleMapUnitScale`

.. seealso:: :py:func:`averageAngleLength`

.. seealso:: :py:func:`averageAngleUnit`
%End

virtual void renderPolyline( const QPolygonF &points, QgsSymbolRenderContext &context ) ${SIP_FINAL};
@@ -123,6 +123,7 @@ class QgsSymbolLayer
PropertyPlacement,
PropertyInterval,
PropertyOffsetAlongLine,
PropertyAverageAngleLength,
PropertyHorizontalAnchor,
PropertyVerticalAnchor,
PropertyLayerEnabled,

0 comments on commit 426382c

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