mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-14 00:07:35 -04:00
[FEATURE] New line symbol type: Hash line
This line symbol type is designed to replicate the ArcGIS Hash Line symbol layer type. It allows for a repeating line segment to be drawn over the length of a feature, with a line-sub symbol used to render each individual segment. To reduce code duplication, this is heavily based off the current line marker symbol layer, since the functionality is almost identical (draw some sub symbol at some interval along a line). Accordingly, I've split off QgsMarkerLineSymbolLayer to move as much of the common functionality as possible to a new abstract base class, so that only the actual marker/line segment rendering occurs in the marker line/hash line subclasses. This also gives the hash line all the existing placement options permissible for marker lines -- e.g. first/last vertex, mid points, regular intervals, etc. The hash line length and angle can have data defined overrides, which are evaluated per-line segment, allowing for the hash line to change size and angle over the length of a single rendered feature.
This commit is contained in:
parent
59ed07891a
commit
48d2a37057
@ -28,6 +28,7 @@ from qgis._core import *
|
||||
|
||||
from .additions.edit import edit, QgsEditError
|
||||
from .additions.fromfunction import fromFunction
|
||||
from .additions.markerlinesymbollayer import *
|
||||
from .additions.metaenum import metaEnumFromType, metaEnumFromValue
|
||||
from .additions.processing import processing_output_layer_repr, processing_source_repr
|
||||
from .additions.projectdirtyblocker import ProjectDirtyBlocker
|
||||
|
31
python/core/additions/markerlinesymbollayer.py
Normal file
31
python/core/additions/markerlinesymbollayer.py
Normal file
@ -0,0 +1,31 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
***************************************************************************
|
||||
markerlinesymbollayer.py
|
||||
---------------------
|
||||
Date : March 2019
|
||||
Copyright : (C) 2019 by Nyall Dawson
|
||||
Email : nyall dot dawson at gmail dot com
|
||||
***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************
|
||||
"""
|
||||
from qgis._core import (
|
||||
QgsMarkerLineSymbolLayer,
|
||||
QgsTemplatedLineSymbolLayerBase)
|
||||
|
||||
|
||||
# monkey patch deprecated enum values to maintain API
|
||||
# TODO - remove for QGIS 4.0
|
||||
QgsMarkerLineSymbolLayer.Interval = QgsTemplatedLineSymbolLayerBase.Interval
|
||||
QgsMarkerLineSymbolLayer.Vertex = QgsTemplatedLineSymbolLayerBase.Vertex
|
||||
QgsMarkerLineSymbolLayer.LastVertex = QgsTemplatedLineSymbolLayerBase.LastVertex
|
||||
QgsMarkerLineSymbolLayer.FirstVertex = QgsTemplatedLineSymbolLayerBase.FirstVertex
|
||||
QgsMarkerLineSymbolLayer.CentralPoint = QgsTemplatedLineSymbolLayerBase.CentralPoint
|
||||
QgsMarkerLineSymbolLayer.CurvePoint = QgsTemplatedLineSymbolLayerBase.CurvePoint
|
@ -233,10 +233,14 @@ used to render polygon rings.
|
||||
|
||||
|
||||
|
||||
class QgsMarkerLineSymbolLayer : QgsLineSymbolLayer
|
||||
class QgsTemplatedLineSymbolLayerBase : QgsLineSymbolLayer
|
||||
{
|
||||
%Docstring
|
||||
Line symbol layer type which draws repeating marker symbols along a line feature.
|
||||
|
||||
Base class for templated line symbols, e.g. line symbols which draw markers or hash
|
||||
lines at intervals along the line feature.
|
||||
|
||||
.. versionadded:: 3.8
|
||||
%End
|
||||
|
||||
%TypeHeaderCode
|
||||
@ -244,16 +248,6 @@ Line symbol layer type which draws repeating marker symbols along a line feature
|
||||
%End
|
||||
public:
|
||||
|
||||
QgsMarkerLineSymbolLayer( bool rotateMarker = DEFAULT_MARKERLINE_ROTATE,
|
||||
double interval = DEFAULT_MARKERLINE_INTERVAL );
|
||||
%Docstring
|
||||
Constructor for QgsMarkerLineSymbolLayer. Creates a marker line
|
||||
with a default marker symbol, placed at the specified ``interval`` (in millimeters).
|
||||
|
||||
The ``rotateMarker`` argument specifies whether individual marker symbols
|
||||
should be rotated to match the line segment alignment.
|
||||
%End
|
||||
|
||||
enum Placement
|
||||
{
|
||||
Interval,
|
||||
@ -264,82 +258,33 @@ should be rotated to match the line segment alignment.
|
||||
CurvePoint,
|
||||
};
|
||||
|
||||
|
||||
static QgsSymbolLayer *create( const QgsStringMap &properties = QgsStringMap() ) /Factory/;
|
||||
QgsTemplatedLineSymbolLayerBase( bool rotateSymbol = true,
|
||||
double interval = 3 );
|
||||
%Docstring
|
||||
Creates a new QgsMarkerLineSymbolLayer, using the settings
|
||||
serialized in the ``properties`` map (corresponding to the output from
|
||||
QgsMarkerLineSymbolLayer.properties() ).
|
||||
Constructor for QgsTemplatedLineSymbolLayerBase. Creates a template
|
||||
line placed at the specified ``interval`` (in millimeters).
|
||||
|
||||
The ``rotateSymbol`` argument specifies whether individual symbols
|
||||
should be rotated to match the line segment alignment.
|
||||
%End
|
||||
|
||||
static QgsSymbolLayer *createFromSld( QDomElement &element ) /Factory/;
|
||||
bool rotateSymbols() const;
|
||||
%Docstring
|
||||
Creates a new QgsMarkerLineSymbolLayer from an SLD XML DOM ``element``.
|
||||
Returns ``True`` if the repeating symbols be rotated to match their line segment orientation.
|
||||
|
||||
.. seealso:: :py:func:`setRotateSymbols`
|
||||
%End
|
||||
|
||||
|
||||
virtual QString layerType() const;
|
||||
|
||||
|
||||
virtual void startRender( QgsSymbolRenderContext &context );
|
||||
|
||||
|
||||
virtual void stopRender( QgsSymbolRenderContext &context );
|
||||
|
||||
|
||||
virtual void renderPolyline( const QPolygonF &points, QgsSymbolRenderContext &context );
|
||||
|
||||
|
||||
virtual void renderPolygonStroke( const QPolygonF &points, QList<QPolygonF> *rings, QgsSymbolRenderContext &context );
|
||||
|
||||
|
||||
virtual QgsStringMap properties() const;
|
||||
|
||||
|
||||
virtual QgsMarkerLineSymbolLayer *clone() const /Factory/;
|
||||
|
||||
|
||||
virtual void toSld( QDomDocument &doc, QDomElement &element, const QgsStringMap &props ) const;
|
||||
|
||||
|
||||
virtual void setColor( const QColor &color );
|
||||
|
||||
virtual QColor color() const;
|
||||
|
||||
|
||||
virtual QgsSymbol *subSymbol();
|
||||
|
||||
virtual bool setSubSymbol( QgsSymbol *symbol /Transfer/ );
|
||||
|
||||
|
||||
virtual void setWidth( double width );
|
||||
|
||||
virtual double width() const;
|
||||
|
||||
virtual double width( const QgsRenderContext &context ) const;
|
||||
|
||||
|
||||
virtual double estimateMaxBleed( const QgsRenderContext &context ) const;
|
||||
|
||||
|
||||
|
||||
bool rotateMarker() const;
|
||||
%Docstring
|
||||
Returns ``True`` if the repeating symbols will be rotated to match their line segment orientation.
|
||||
|
||||
.. seealso:: :py:func:`setRotateMarker`
|
||||
%End
|
||||
|
||||
void setRotateMarker( bool rotate );
|
||||
void setRotateSymbols( bool rotate );
|
||||
%Docstring
|
||||
Sets whether the repeating symbols should be rotated to match their line segment orientation.
|
||||
|
||||
.. seealso:: :py:func:`rotateMarker`
|
||||
.. seealso:: :py:func:`rotateSymbols`
|
||||
%End
|
||||
|
||||
double interval() const;
|
||||
%Docstring
|
||||
Returns the interval between individual markers. Units are specified through intervalUnits().
|
||||
Returns the interval between individual symbols. Units are specified through intervalUnits().
|
||||
|
||||
.. seealso:: :py:func:`setInterval`
|
||||
|
||||
@ -348,100 +293,13 @@ Returns the interval between individual markers. Units are specified through int
|
||||
|
||||
void setInterval( double interval );
|
||||
%Docstring
|
||||
Sets the interval between individual markers.
|
||||
Sets the interval between individual symbols.
|
||||
|
||||
:param interval: interval size. Units are specified through setIntervalUnit()
|
||||
|
||||
.. seealso:: :py:func:`interval`
|
||||
|
||||
.. seealso:: :py:func:`setIntervalUnit`
|
||||
%End
|
||||
|
||||
Placement placement() const;
|
||||
%Docstring
|
||||
Returns the placement of the symbols.
|
||||
|
||||
.. seealso:: :py:func:`setPlacement`
|
||||
%End
|
||||
|
||||
void setPlacement( Placement p );
|
||||
%Docstring
|
||||
Sets the ``placement`` of the symbols.
|
||||
|
||||
.. seealso:: :py:func:`placement`
|
||||
%End
|
||||
|
||||
double offsetAlongLine() const;
|
||||
%Docstring
|
||||
Returns the offset along the line for the marker placement. For Interval placements, this is the distance
|
||||
between the start of the line and the first marker. For FirstVertex and LastVertex placements, this is the
|
||||
distance between the marker and the start of the line or the end of the line respectively.
|
||||
This setting has no effect for Vertex or CentralPoint placements.
|
||||
|
||||
:return: The offset along the line. The unit for the offset is retrievable via offsetAlongLineUnit.
|
||||
|
||||
.. seealso:: :py:func:`setOffsetAlongLine`
|
||||
|
||||
.. seealso:: :py:func:`offsetAlongLineUnit`
|
||||
|
||||
.. seealso:: :py:func:`placement`
|
||||
|
||||
.. versionadded:: 2.3
|
||||
%End
|
||||
|
||||
void setOffsetAlongLine( double offsetAlongLine );
|
||||
%Docstring
|
||||
Sets the the offset along the line for the marker placement. For Interval placements, this is the distance
|
||||
between the start of the line and the first marker. For FirstVertex and LastVertex placements, this is the
|
||||
distance between the marker and the start of the line or the end of the line respectively.
|
||||
This setting has no effect for Vertex or CentralPoint placements.
|
||||
|
||||
:param offsetAlongLine: Distance to offset markers along the line. The offset
|
||||
unit is set via setOffsetAlongLineUnit.
|
||||
|
||||
.. seealso:: :py:func:`offsetAlongLine`
|
||||
|
||||
.. seealso:: :py:func:`setOffsetAlongLineUnit`
|
||||
|
||||
.. seealso:: :py:func:`setPlacement`
|
||||
|
||||
.. versionadded:: 2.3
|
||||
%End
|
||||
|
||||
QgsUnitTypes::RenderUnit offsetAlongLineUnit() const;
|
||||
%Docstring
|
||||
Returns the unit used for calculating the offset along line for markers.
|
||||
|
||||
:return: Offset along line unit type.
|
||||
|
||||
.. seealso:: :py:func:`setOffsetAlongLineUnit`
|
||||
|
||||
.. seealso:: :py:func:`offsetAlongLine`
|
||||
%End
|
||||
|
||||
void setOffsetAlongLineUnit( QgsUnitTypes::RenderUnit unit );
|
||||
%Docstring
|
||||
Sets the unit used for calculating the offset along line for markers.
|
||||
|
||||
:param unit: Offset along line unit type.
|
||||
|
||||
.. seealso:: :py:func:`offsetAlongLineUnit`
|
||||
|
||||
.. seealso:: :py:func:`setOffsetAlongLine`
|
||||
%End
|
||||
|
||||
const QgsMapUnitScale &offsetAlongLineMapUnitScale() const;
|
||||
%Docstring
|
||||
Returns the map unit scale used for calculating the offset in map units along line for symbols.
|
||||
|
||||
.. seealso:: :py:func:`setOffsetAlongLineMapUnitScale`
|
||||
%End
|
||||
|
||||
void setOffsetAlongLineMapUnitScale( const QgsMapUnitScale &scale );
|
||||
%Docstring
|
||||
Sets the map unit ``scale`` used for calculating the offset in map units along line for symbols.
|
||||
|
||||
.. seealso:: :py:func:`offsetAlongLineMapUnitScale`
|
||||
%End
|
||||
|
||||
void setIntervalUnit( QgsUnitTypes::RenderUnit unit );
|
||||
@ -486,31 +344,246 @@ Returns the map unit scale for the interval between symbols.
|
||||
.. seealso:: :py:func:`interval`
|
||||
%End
|
||||
|
||||
Placement placement() const;
|
||||
%Docstring
|
||||
Returns the placement of the symbols.
|
||||
|
||||
.. seealso:: :py:func:`setPlacement`
|
||||
%End
|
||||
|
||||
void setPlacement( Placement placement );
|
||||
%Docstring
|
||||
Sets the ``placement`` of the symbols.
|
||||
|
||||
.. seealso:: :py:func:`placement`
|
||||
%End
|
||||
|
||||
double offsetAlongLine() const;
|
||||
%Docstring
|
||||
Returns the offset along the line for the symbol placement. For Interval placements, this is the distance
|
||||
between the start of the line and the first symbol. For FirstVertex and LastVertex placements, this is the
|
||||
distance between the symbol and the start of the line or the end of the line respectively.
|
||||
This setting has no effect for Vertex or CentralPoint placements.
|
||||
|
||||
:return: The offset along the line. The unit for the offset is retrievable via offsetAlongLineUnit.
|
||||
|
||||
.. seealso:: :py:func:`setOffsetAlongLine`
|
||||
|
||||
.. seealso:: :py:func:`offsetAlongLineUnit`
|
||||
|
||||
.. seealso:: :py:func:`placement`
|
||||
%End
|
||||
|
||||
void setOffsetAlongLine( double offsetAlongLine );
|
||||
%Docstring
|
||||
Sets the the offset along the line for the symbol placement. For Interval placements, this is the distance
|
||||
between the start of the line and the first symbol. For FirstVertex and LastVertex placements, this is the
|
||||
distance between the symbol and the start of the line or the end of the line respectively.
|
||||
This setting has no effect for Vertex or CentralPoint placements.
|
||||
|
||||
:param offsetAlongLine: Distance to offset markers along the line. The offset
|
||||
unit is set via setOffsetAlongLineUnit.
|
||||
|
||||
.. seealso:: :py:func:`offsetAlongLine`
|
||||
|
||||
.. seealso:: :py:func:`setOffsetAlongLineUnit`
|
||||
|
||||
.. seealso:: :py:func:`setPlacement`
|
||||
%End
|
||||
|
||||
QgsUnitTypes::RenderUnit offsetAlongLineUnit() const;
|
||||
%Docstring
|
||||
Returns the unit used for calculating the offset along line for symbols.
|
||||
|
||||
:return: Offset along line unit type.
|
||||
|
||||
.. seealso:: :py:func:`setOffsetAlongLineUnit`
|
||||
|
||||
.. seealso:: :py:func:`offsetAlongLine`
|
||||
%End
|
||||
|
||||
void setOffsetAlongLineUnit( QgsUnitTypes::RenderUnit unit );
|
||||
%Docstring
|
||||
Sets the unit used for calculating the offset along line for symbols.
|
||||
|
||||
:param unit: Offset along line unit type.
|
||||
|
||||
.. seealso:: :py:func:`offsetAlongLineUnit`
|
||||
|
||||
.. seealso:: :py:func:`setOffsetAlongLine`
|
||||
%End
|
||||
|
||||
const QgsMapUnitScale &offsetAlongLineMapUnitScale() const;
|
||||
%Docstring
|
||||
Returns the map unit scale used for calculating the offset in map units along line for symbols.
|
||||
|
||||
.. seealso:: :py:func:`setOffsetAlongLineMapUnitScale`
|
||||
%End
|
||||
|
||||
void setOffsetAlongLineMapUnitScale( const QgsMapUnitScale &scale );
|
||||
%Docstring
|
||||
Sets the map unit ``scale`` used for calculating the offset in map units along line for symbols.
|
||||
|
||||
.. seealso:: :py:func:`offsetAlongLineMapUnitScale`
|
||||
%End
|
||||
|
||||
virtual void renderPolyline( const QPolygonF &points, QgsSymbolRenderContext &context ) ${SIP_FINAL};
|
||||
|
||||
virtual void renderPolygonStroke( const QPolygonF &points, QList<QPolygonF> *rings, QgsSymbolRenderContext &context ) ${SIP_FINAL};
|
||||
|
||||
virtual QgsUnitTypes::RenderUnit outputUnit() const ${SIP_FINAL};
|
||||
|
||||
virtual void setMapUnitScale( const QgsMapUnitScale &scale ) ${SIP_FINAL};
|
||||
|
||||
virtual QgsMapUnitScale mapUnitScale() const ${SIP_FINAL};
|
||||
|
||||
virtual QgsStringMap properties() const;
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
virtual void setSymbolLineAngle( double angle ) = 0;
|
||||
%Docstring
|
||||
Sets the line ``angle`` modification for the symbol's angle. This angle is added to
|
||||
the symbol's rotation and data defined rotation before rendering the symbol, and
|
||||
is used for orienting symbols to match the line's angle.
|
||||
|
||||
:param angle: Angle in degrees, valid values are between 0 and 360
|
||||
%End
|
||||
|
||||
virtual double symbolAngle() const = 0;
|
||||
%Docstring
|
||||
Returns the symbol's current angle, in degrees clockwise.
|
||||
%End
|
||||
|
||||
virtual void setSymbolAngle( double angle ) = 0;
|
||||
%Docstring
|
||||
Sets the symbol's ``angle``, in degrees clockwise.
|
||||
%End
|
||||
|
||||
virtual void renderSymbol( const QPointF &point, const QgsFeature *feature, QgsRenderContext &context, int layer = -1, bool selected = false ) = 0;
|
||||
%Docstring
|
||||
Renders the templated symbol at the specified ``point``, using the given render ``context``.
|
||||
|
||||
The ``feature`` argument is used to pass the feature currently being rendered (when available).
|
||||
|
||||
If only a single symbol layer from the symbol should be rendered, it should be specified
|
||||
in the ``layer`` argument. A ``layer`` of -1 indicates that all symbol layers should be
|
||||
rendered.
|
||||
|
||||
If ``selected`` is true then the symbol will be drawn using the "selected feature"
|
||||
style and colors instead of the symbol's normal style.
|
||||
%End
|
||||
|
||||
void copyTemplateSymbolProperties( QgsTemplatedLineSymbolLayerBase *destLayer ) const;
|
||||
%Docstring
|
||||
Copies all common properties of this layer to another templated symbol layer.
|
||||
%End
|
||||
|
||||
static void setCommonProperties( QgsTemplatedLineSymbolLayerBase *destLayer, const QgsStringMap &properties );
|
||||
%Docstring
|
||||
Sets all common symbol properties in the ``destLayer``, using the settings
|
||||
serialized in the ``properties`` map.
|
||||
%End
|
||||
|
||||
};
|
||||
|
||||
class QgsMarkerLineSymbolLayer : QgsTemplatedLineSymbolLayerBase
|
||||
{
|
||||
%Docstring
|
||||
Line symbol layer type which draws repeating marker symbols along a line feature.
|
||||
%End
|
||||
|
||||
%TypeHeaderCode
|
||||
#include "qgslinesymbollayer.h"
|
||||
%End
|
||||
public:
|
||||
|
||||
QgsMarkerLineSymbolLayer( bool rotateMarker = DEFAULT_MARKERLINE_ROTATE,
|
||||
double interval = DEFAULT_MARKERLINE_INTERVAL );
|
||||
%Docstring
|
||||
Constructor for QgsMarkerLineSymbolLayer. Creates a marker line
|
||||
with a default marker symbol, placed at the specified ``interval`` (in millimeters).
|
||||
|
||||
The ``rotateMarker`` argument specifies whether individual marker symbols
|
||||
should be rotated to match the line segment alignment.
|
||||
%End
|
||||
|
||||
|
||||
static QgsSymbolLayer *create( const QgsStringMap &properties = QgsStringMap() ) /Factory/;
|
||||
%Docstring
|
||||
Creates a new QgsMarkerLineSymbolLayer, using the settings
|
||||
serialized in the ``properties`` map (corresponding to the output from
|
||||
QgsMarkerLineSymbolLayer.properties() ).
|
||||
%End
|
||||
|
||||
static QgsSymbolLayer *createFromSld( QDomElement &element ) /Factory/;
|
||||
%Docstring
|
||||
Creates a new QgsMarkerLineSymbolLayer from an SLD XML DOM ``element``.
|
||||
%End
|
||||
|
||||
|
||||
virtual QString layerType() const;
|
||||
|
||||
virtual void startRender( QgsSymbolRenderContext &context );
|
||||
|
||||
virtual void stopRender( QgsSymbolRenderContext &context );
|
||||
|
||||
virtual QgsMarkerLineSymbolLayer *clone() const /Factory/;
|
||||
|
||||
virtual void toSld( QDomDocument &doc, QDomElement &element, const QgsStringMap &props ) const;
|
||||
|
||||
virtual void setColor( const QColor &color );
|
||||
|
||||
virtual QColor color() const;
|
||||
|
||||
virtual QgsSymbol *subSymbol();
|
||||
|
||||
virtual bool setSubSymbol( QgsSymbol *symbol /Transfer/ );
|
||||
|
||||
virtual void setWidth( double width );
|
||||
|
||||
virtual double width() const;
|
||||
|
||||
virtual double width( const QgsRenderContext &context ) const;
|
||||
|
||||
virtual double estimateMaxBleed( const QgsRenderContext &context ) const;
|
||||
|
||||
virtual void setOutputUnit( QgsUnitTypes::RenderUnit unit );
|
||||
|
||||
virtual QgsUnitTypes::RenderUnit outputUnit() const;
|
||||
|
||||
|
||||
virtual void setMapUnitScale( const QgsMapUnitScale &scale );
|
||||
|
||||
virtual QgsMapUnitScale mapUnitScale() const;
|
||||
|
||||
|
||||
virtual QSet<QString> usedAttributes( const QgsRenderContext &context ) const;
|
||||
|
||||
virtual bool hasDataDefinedProperties() const;
|
||||
|
||||
|
||||
virtual void setDataDefinedProperty( QgsSymbolLayer::Property key, const QgsProperty &property );
|
||||
|
||||
|
||||
bool rotateMarker() const /Deprecated/;
|
||||
%Docstring
|
||||
Shall the marker be rotated.
|
||||
|
||||
:return: ``True`` if the marker should be rotated.
|
||||
|
||||
.. deprecated:: Use rotateSymbols() instead.
|
||||
%End
|
||||
|
||||
void setRotateMarker( bool rotate ) /Deprecated/;
|
||||
%Docstring
|
||||
Shall the marker be rotated.
|
||||
|
||||
.. deprecated:: Use setRotateSymbols() instead.
|
||||
%End
|
||||
|
||||
protected:
|
||||
|
||||
void renderPolylineInterval( const QPolygonF &points, QgsSymbolRenderContext &context );
|
||||
void renderPolylineVertex( const QPolygonF &points, QgsSymbolRenderContext &context, Placement placement = Vertex );
|
||||
void renderPolylineCentral( const QPolygonF &points, QgsSymbolRenderContext &context );
|
||||
double markerAngle( const QPolygonF &points, bool isRing, int vertex );
|
||||
|
||||
virtual void setSymbolLineAngle( double angle );
|
||||
|
||||
virtual double symbolAngle() const;
|
||||
|
||||
virtual void setSymbolAngle( double angle );
|
||||
|
||||
virtual void renderSymbol( const QPointF &point, const QgsFeature *feature, QgsRenderContext &context, int layer = -1, bool selected = false );
|
||||
|
||||
|
||||
private:
|
||||
@ -518,6 +591,160 @@ Returns the map unit scale for the interval between symbols.
|
||||
};
|
||||
|
||||
|
||||
class QgsHashedLineSymbolLayer : QgsTemplatedLineSymbolLayerBase
|
||||
{
|
||||
%Docstring
|
||||
|
||||
Line symbol layer type which draws repeating line sections along a line feature.
|
||||
|
||||
.. versionadded:: 3.8
|
||||
%End
|
||||
|
||||
%TypeHeaderCode
|
||||
#include "qgslinesymbollayer.h"
|
||||
%End
|
||||
public:
|
||||
|
||||
QgsHashedLineSymbolLayer( bool rotateSymbol = true,
|
||||
double interval = 3 );
|
||||
%Docstring
|
||||
Constructor for QgsHashedLineSymbolLayer. Creates a line
|
||||
with a default hash symbol, placed at the specified ``interval`` (in millimeters).
|
||||
|
||||
The ``rotateSymbol`` argument specifies whether individual hash symbols
|
||||
should be rotated to match the line segment alignment.
|
||||
%End
|
||||
|
||||
static QgsSymbolLayer *create( const QgsStringMap &properties = QgsStringMap() ) /Factory/;
|
||||
%Docstring
|
||||
Creates a new QgsHashedLineSymbolLayer, using the settings
|
||||
serialized in the ``properties`` map (corresponding to the output from
|
||||
QgsHashedLineSymbolLayer.properties() ).
|
||||
%End
|
||||
|
||||
virtual QString layerType() const;
|
||||
|
||||
virtual void startRender( QgsSymbolRenderContext &context );
|
||||
|
||||
virtual void stopRender( QgsSymbolRenderContext &context );
|
||||
|
||||
virtual QgsStringMap properties() const;
|
||||
|
||||
virtual QgsHashedLineSymbolLayer *clone() const /Factory/;
|
||||
|
||||
virtual void setColor( const QColor &color );
|
||||
|
||||
virtual QColor color() const;
|
||||
|
||||
virtual QgsSymbol *subSymbol();
|
||||
|
||||
virtual bool setSubSymbol( QgsSymbol *symbol /Transfer/ );
|
||||
|
||||
virtual void setWidth( double width );
|
||||
|
||||
virtual double width() const;
|
||||
|
||||
virtual double width( const QgsRenderContext &context ) const;
|
||||
|
||||
virtual double estimateMaxBleed( const QgsRenderContext &context ) const;
|
||||
|
||||
virtual void setOutputUnit( QgsUnitTypes::RenderUnit unit );
|
||||
|
||||
virtual QSet<QString> usedAttributes( const QgsRenderContext &context ) const;
|
||||
|
||||
virtual bool hasDataDefinedProperties() const;
|
||||
|
||||
virtual void setDataDefinedProperty( QgsSymbolLayer::Property key, const QgsProperty &property );
|
||||
|
||||
|
||||
double hashAngle() const;
|
||||
%Docstring
|
||||
Returns the angle to use when drawing the hashed lines sections, in degrees clockwise.
|
||||
|
||||
.. seealso:: :py:func:`setHashAngle`
|
||||
%End
|
||||
|
||||
void setHashAngle( double angle );
|
||||
%Docstring
|
||||
Sets the ``angle`` to use when drawing the hashed lines sections, in degrees clockwise.
|
||||
|
||||
.. seealso:: :py:func:`hashAngle`
|
||||
%End
|
||||
|
||||
double hashLength() const;
|
||||
%Docstring
|
||||
Returns the length of hash symbols. Units are specified through hashLengthUnits().
|
||||
|
||||
.. seealso:: :py:func:`setHashLength`
|
||||
|
||||
.. seealso:: :py:func:`hashLengthUnit`
|
||||
%End
|
||||
|
||||
void setHashLength( double length );
|
||||
%Docstring
|
||||
Sets the ``length`` of hash symbols. Units are specified through setHashLengthUnit()
|
||||
|
||||
.. seealso:: :py:func:`hashLength`
|
||||
|
||||
.. seealso:: :py:func:`setHashLengthUnit`
|
||||
%End
|
||||
|
||||
void setHashLengthUnit( QgsUnitTypes::RenderUnit unit );
|
||||
%Docstring
|
||||
Sets the ``unit`` for the length of hash symbols.
|
||||
|
||||
.. seealso:: :py:func:`hashLengthUnit`
|
||||
|
||||
.. seealso:: :py:func:`setHashLength`
|
||||
%End
|
||||
|
||||
QgsUnitTypes::RenderUnit hashLengthUnit() const;
|
||||
%Docstring
|
||||
Returns the units for the length of hash symbols.
|
||||
|
||||
.. seealso:: :py:func:`setHashLengthUnit`
|
||||
|
||||
.. seealso:: :py:func:`hashLength`
|
||||
%End
|
||||
|
||||
void setHashLengthMapUnitScale( const QgsMapUnitScale &scale );
|
||||
%Docstring
|
||||
Sets the map unit ``scale`` for the hash length.
|
||||
|
||||
.. seealso:: :py:func:`hashLengthMapUnitScale`
|
||||
|
||||
.. seealso:: :py:func:`setHashLengthUnit`
|
||||
|
||||
.. seealso:: :py:func:`setHashLength`
|
||||
%End
|
||||
|
||||
const QgsMapUnitScale &hashLengthMapUnitScale() const;
|
||||
%Docstring
|
||||
Returns the map unit scale for the hash length.
|
||||
|
||||
.. seealso:: :py:func:`setHashLengthMapUnitScale`
|
||||
|
||||
.. seealso:: :py:func:`hashLengthUnit`
|
||||
|
||||
.. seealso:: :py:func:`hashLength`
|
||||
%End
|
||||
|
||||
protected:
|
||||
|
||||
virtual void setSymbolLineAngle( double angle );
|
||||
|
||||
virtual double symbolAngle() const;
|
||||
|
||||
virtual void setSymbolAngle( double angle );
|
||||
|
||||
virtual void renderSymbol( const QPointF &point, const QgsFeature *feature, QgsRenderContext &context, int layer = -1, bool selected = false );
|
||||
|
||||
|
||||
private:
|
||||
QgsHashedLineSymbolLayer( const QgsHashedLineSymbolLayer &other );
|
||||
};
|
||||
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* This file has been generated automatically from *
|
||||
|
@ -835,11 +835,53 @@ class QgsLineSymbolLayer : QgsSymbolLayer
|
||||
InteriorRingsOnly,
|
||||
};
|
||||
|
||||
virtual void setOutputUnit( QgsUnitTypes::RenderUnit unit );
|
||||
|
||||
virtual QgsUnitTypes::RenderUnit outputUnit() const;
|
||||
|
||||
virtual void setMapUnitScale( const QgsMapUnitScale &scale );
|
||||
|
||||
virtual QgsMapUnitScale mapUnitScale() const;
|
||||
|
||||
virtual void drawPreviewIcon( QgsSymbolRenderContext &context, QSize size );
|
||||
|
||||
virtual double dxfWidth( const QgsDxfExport &e, QgsSymbolRenderContext &context ) const;
|
||||
|
||||
|
||||
virtual void renderPolyline( const QPolygonF &points, QgsSymbolRenderContext &context ) = 0;
|
||||
%Docstring
|
||||
Renders the line symbol layer along the line joining ``points``, using the given render ``context``.
|
||||
|
||||
.. seealso:: :py:func:`renderPolygonStroke`
|
||||
%End
|
||||
|
||||
virtual void renderPolygonStroke( const QPolygonF &points, QList<QPolygonF> *rings, QgsSymbolRenderContext &context );
|
||||
%Docstring
|
||||
Renders the line symbol layer along the outline of polygon, using the given render ``context``.
|
||||
|
||||
The exterior ring of the polygon is specified in ``points``. Optionally, interior
|
||||
rings are set via the ``rings`` arugment.
|
||||
|
||||
.. seealso:: :py:func:`renderPolyline`
|
||||
%End
|
||||
|
||||
virtual void setWidth( double width );
|
||||
%Docstring
|
||||
Sets the ``width`` of the line symbol layer.
|
||||
|
||||
Calling this method updates the width of the line symbol layer, without
|
||||
changing the existing width units. It has different effects depending
|
||||
on the line symbol layer subclass, e.g. for a simple line layer it
|
||||
changes the stroke width of the line, for a marker line layer it
|
||||
changes the size of the markers used to draw the line.
|
||||
|
||||
.. seealso:: :py:func:`width`
|
||||
|
||||
.. warning::
|
||||
|
||||
Since the width units vary, this method is useful for changing the
|
||||
relative width of a line symbol layer only.
|
||||
%End
|
||||
|
||||
virtual double width() const;
|
||||
%Docstring
|
||||
@ -867,7 +909,75 @@ width of the symbol layer using the provided render ``context``.
|
||||
%End
|
||||
|
||||
double offset() const;
|
||||
%Docstring
|
||||
Returns the line's offset.
|
||||
|
||||
Offset units can be retrieved by calling offsetUnit().
|
||||
|
||||
.. seealso:: :py:func:`setOffset`
|
||||
|
||||
.. seealso:: :py:func:`offsetUnit`
|
||||
|
||||
.. seealso:: :py:func:`offsetMapUnitScale`
|
||||
%End
|
||||
|
||||
void setOffset( double offset );
|
||||
%Docstring
|
||||
Sets the line's ``offset``.
|
||||
|
||||
Offset units are set via setOffsetUnit().
|
||||
|
||||
.. seealso:: :py:func:`offset`
|
||||
|
||||
.. seealso:: :py:func:`setOffsetUnit`
|
||||
|
||||
.. seealso:: :py:func:`setOffsetMapUnitScale`
|
||||
%End
|
||||
|
||||
void setOffsetUnit( QgsUnitTypes::RenderUnit unit );
|
||||
%Docstring
|
||||
Sets the ``unit`` for the line's offset.
|
||||
|
||||
.. seealso:: :py:func:`offsetUnit`
|
||||
|
||||
.. seealso:: :py:func:`setOffset`
|
||||
|
||||
.. seealso:: :py:func:`setOffsetMapUnitScale`
|
||||
%End
|
||||
|
||||
QgsUnitTypes::RenderUnit offsetUnit() const;
|
||||
%Docstring
|
||||
Returns the units for the line's offset.
|
||||
|
||||
.. seealso:: :py:func:`setOffsetUnit`
|
||||
|
||||
.. seealso:: :py:func:`offset`
|
||||
|
||||
.. seealso:: :py:func:`offsetMapUnitScale`
|
||||
%End
|
||||
|
||||
void setOffsetMapUnitScale( const QgsMapUnitScale &scale );
|
||||
%Docstring
|
||||
Sets the map unit ``scale`` for the line's offset.
|
||||
|
||||
.. seealso:: :py:func:`offsetMapUnitScale`
|
||||
|
||||
.. seealso:: :py:func:`setOffset`
|
||||
|
||||
.. seealso:: :py:func:`setOffsetUnit`
|
||||
%End
|
||||
|
||||
const QgsMapUnitScale &offsetMapUnitScale() const;
|
||||
%Docstring
|
||||
Returns the map unit scale for the line's offset.
|
||||
|
||||
.. seealso:: :py:func:`setOffsetMapUnitScale`
|
||||
|
||||
.. seealso:: :py:func:`offset`
|
||||
|
||||
.. seealso:: :py:func:`offsetUnit`
|
||||
%End
|
||||
|
||||
|
||||
void setWidthUnit( QgsUnitTypes::RenderUnit unit );
|
||||
%Docstring
|
||||
@ -888,41 +998,6 @@ Returns the units for the line's width.
|
||||
void setWidthMapUnitScale( const QgsMapUnitScale &scale );
|
||||
const QgsMapUnitScale &widthMapUnitScale() const;
|
||||
|
||||
void setOffsetUnit( QgsUnitTypes::RenderUnit unit );
|
||||
%Docstring
|
||||
Sets the units for the line's offset.
|
||||
|
||||
:param unit: offset units
|
||||
|
||||
.. seealso:: :py:func:`offsetUnit`
|
||||
%End
|
||||
|
||||
QgsUnitTypes::RenderUnit offsetUnit() const;
|
||||
%Docstring
|
||||
Returns the units for the line's offset.
|
||||
|
||||
.. seealso:: :py:func:`setOffsetUnit`
|
||||
%End
|
||||
|
||||
void setOffsetMapUnitScale( const QgsMapUnitScale &scale );
|
||||
const QgsMapUnitScale &offsetMapUnitScale() const;
|
||||
|
||||
virtual void setOutputUnit( QgsUnitTypes::RenderUnit unit );
|
||||
|
||||
virtual QgsUnitTypes::RenderUnit outputUnit() const;
|
||||
|
||||
|
||||
virtual void setMapUnitScale( const QgsMapUnitScale &scale );
|
||||
|
||||
virtual QgsMapUnitScale mapUnitScale() const;
|
||||
|
||||
|
||||
virtual void drawPreviewIcon( QgsSymbolRenderContext &context, QSize size );
|
||||
|
||||
|
||||
virtual double dxfWidth( const QgsDxfExport &e, QgsSymbolRenderContext &context ) const;
|
||||
|
||||
|
||||
RenderRingFilter ringFilter() const;
|
||||
%Docstring
|
||||
Returns the line symbol layer's ring filter, which controls which rings are
|
||||
|
@ -377,6 +377,38 @@ Creates a new QgsMarkerLineSymbolLayerWidget.
|
||||
|
||||
|
||||
|
||||
class QgsHashedLineSymbolLayerWidget : QgsSymbolLayerWidget
|
||||
{
|
||||
|
||||
%TypeHeaderCode
|
||||
#include "qgssymbollayerwidget.h"
|
||||
%End
|
||||
public:
|
||||
|
||||
QgsHashedLineSymbolLayerWidget( QgsVectorLayer *vl, QWidget *parent /TransferThis/ = 0 );
|
||||
%Docstring
|
||||
Constructor for QgsHashedLineSymbolLayerWidget.
|
||||
|
||||
:param vl: associated vector layer
|
||||
:param parent: parent widget
|
||||
%End
|
||||
|
||||
static QgsSymbolLayerWidget *create( QgsVectorLayer *vl ) /Factory/;
|
||||
%Docstring
|
||||
Creates a new QgsHashedLineSymbolLayerWidget.
|
||||
|
||||
:param vl: associated vector layer
|
||||
%End
|
||||
|
||||
virtual void setSymbolLayer( QgsSymbolLayer *layer );
|
||||
|
||||
virtual QgsSymbolLayer *symbolLayer();
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
class QgsSvgMarkerSymbolLayerWidget : QgsSymbolLayerWidget
|
||||
{
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -244,25 +244,19 @@ class CORE_EXPORT QgsSimpleLineSymbolLayer : public QgsLineSymbolLayer
|
||||
|
||||
/**
|
||||
* \ingroup core
|
||||
* \class QgsMarkerLineSymbolLayer
|
||||
* Line symbol layer type which draws repeating marker symbols along a line feature.
|
||||
* \class QgsTemplatedLineSymbolLayerBase
|
||||
*
|
||||
* Base class for templated line symbols, e.g. line symbols which draw markers or hash
|
||||
* lines at intervals along the line feature.
|
||||
*
|
||||
* \since QGIS 3.8
|
||||
*/
|
||||
class CORE_EXPORT QgsMarkerLineSymbolLayer : public QgsLineSymbolLayer
|
||||
class CORE_EXPORT QgsTemplatedLineSymbolLayerBase : public QgsLineSymbolLayer
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor for QgsMarkerLineSymbolLayer. Creates a marker line
|
||||
* with a default marker symbol, placed at the specified \a interval (in millimeters).
|
||||
*
|
||||
* The \a rotateMarker argument specifies whether individual marker symbols
|
||||
* should be rotated to match the line segment alignment.
|
||||
*/
|
||||
QgsMarkerLineSymbolLayer( bool rotateMarker = DEFAULT_MARKERLINE_ROTATE,
|
||||
double interval = DEFAULT_MARKERLINE_INTERVAL );
|
||||
|
||||
/**
|
||||
* Defines how/where the marker should be placed on the line
|
||||
* Defines how/where the templated symbol should be placed on the line.
|
||||
*/
|
||||
enum Placement
|
||||
{
|
||||
@ -274,146 +268,43 @@ class CORE_EXPORT QgsMarkerLineSymbolLayer : public QgsLineSymbolLayer
|
||||
CurvePoint, //!< Place symbols at every virtual curve point in the line (used when rendering curved geometry types only)
|
||||
};
|
||||
|
||||
// static stuff
|
||||
/**
|
||||
* Constructor for QgsTemplatedLineSymbolLayerBase. Creates a template
|
||||
* line placed at the specified \a interval (in millimeters).
|
||||
*
|
||||
* The \a rotateSymbol argument specifies whether individual symbols
|
||||
* should be rotated to match the line segment alignment.
|
||||
*/
|
||||
QgsTemplatedLineSymbolLayerBase( bool rotateSymbol = true,
|
||||
double interval = 3 );
|
||||
|
||||
/**
|
||||
* Creates a new QgsMarkerLineSymbolLayer, using the settings
|
||||
* serialized in the \a properties map (corresponding to the output from
|
||||
* QgsMarkerLineSymbolLayer::properties() ).
|
||||
* Returns TRUE if the repeating symbols be rotated to match their line segment orientation.
|
||||
* \see setRotateSymbols()
|
||||
*/
|
||||
static QgsSymbolLayer *create( const QgsStringMap &properties = QgsStringMap() ) SIP_FACTORY;
|
||||
|
||||
/**
|
||||
* Creates a new QgsMarkerLineSymbolLayer from an SLD XML DOM \a element.
|
||||
*/
|
||||
static QgsSymbolLayer *createFromSld( QDomElement &element ) SIP_FACTORY;
|
||||
|
||||
// implemented from base classes
|
||||
|
||||
QString layerType() const override;
|
||||
|
||||
void startRender( QgsSymbolRenderContext &context ) override;
|
||||
|
||||
void stopRender( QgsSymbolRenderContext &context ) override;
|
||||
|
||||
void renderPolyline( const QPolygonF &points, QgsSymbolRenderContext &context ) override;
|
||||
|
||||
void renderPolygonStroke( const QPolygonF &points, QList<QPolygonF> *rings, QgsSymbolRenderContext &context ) override;
|
||||
|
||||
QgsStringMap properties() const override;
|
||||
|
||||
QgsMarkerLineSymbolLayer *clone() const override SIP_FACTORY;
|
||||
|
||||
void toSld( QDomDocument &doc, QDomElement &element, const QgsStringMap &props ) const override;
|
||||
|
||||
void setColor( const QColor &color ) override;
|
||||
QColor color() const override;
|
||||
|
||||
QgsSymbol *subSymbol() override;
|
||||
bool setSubSymbol( QgsSymbol *symbol SIP_TRANSFER ) override;
|
||||
|
||||
void setWidth( double width ) override;
|
||||
double width() const override;
|
||||
double width( const QgsRenderContext &context ) const override;
|
||||
|
||||
double estimateMaxBleed( const QgsRenderContext &context ) const override;
|
||||
|
||||
// new stuff
|
||||
|
||||
/**
|
||||
* Returns TRUE if the repeating symbols will be rotated to match their line segment orientation.
|
||||
* \see setRotateMarker()
|
||||
*/
|
||||
bool rotateMarker() const { return mRotateMarker; }
|
||||
bool rotateSymbols() const { return mRotateSymbols; }
|
||||
|
||||
/**
|
||||
* Sets whether the repeating symbols should be rotated to match their line segment orientation.
|
||||
* \see rotateMarker()
|
||||
* \see rotateSymbols()
|
||||
*/
|
||||
void setRotateMarker( bool rotate ) { mRotateMarker = rotate; }
|
||||
void setRotateSymbols( bool rotate ) { mRotateSymbols = rotate; }
|
||||
|
||||
/**
|
||||
* Returns the interval between individual markers. Units are specified through intervalUnits().
|
||||
* Returns the interval between individual symbols. Units are specified through intervalUnits().
|
||||
* \see setInterval()
|
||||
* \see intervalUnit()
|
||||
*/
|
||||
double interval() const { return mInterval; }
|
||||
|
||||
/**
|
||||
* Sets the interval between individual markers.
|
||||
* Sets the interval between individual symbols.
|
||||
* \param interval interval size. Units are specified through setIntervalUnit()
|
||||
* \see interval()
|
||||
* \see setIntervalUnit()
|
||||
*/
|
||||
void setInterval( double interval ) { mInterval = interval; }
|
||||
|
||||
/**
|
||||
* Returns the placement of the symbols.
|
||||
* \see setPlacement()
|
||||
*/
|
||||
Placement placement() const { return mPlacement; }
|
||||
|
||||
/**
|
||||
* Sets the \a placement of the symbols.
|
||||
* \see placement()
|
||||
*/
|
||||
void setPlacement( Placement p ) { mPlacement = p; }
|
||||
|
||||
/**
|
||||
* Returns the offset along the line for the marker placement. For Interval placements, this is the distance
|
||||
* between the start of the line and the first marker. For FirstVertex and LastVertex placements, this is the
|
||||
* distance between the marker and the start of the line or the end of the line respectively.
|
||||
* This setting has no effect for Vertex or CentralPoint placements.
|
||||
* \returns The offset along the line. The unit for the offset is retrievable via offsetAlongLineUnit.
|
||||
* \see setOffsetAlongLine
|
||||
* \see offsetAlongLineUnit
|
||||
* \see placement
|
||||
* \since QGIS 2.3
|
||||
*/
|
||||
double offsetAlongLine() const { return mOffsetAlongLine; }
|
||||
|
||||
/**
|
||||
* Sets the the offset along the line for the marker placement. For Interval placements, this is the distance
|
||||
* between the start of the line and the first marker. For FirstVertex and LastVertex placements, this is the
|
||||
* distance between the marker and the start of the line or the end of the line respectively.
|
||||
* This setting has no effect for Vertex or CentralPoint placements.
|
||||
* \param offsetAlongLine Distance to offset markers along the line. The offset
|
||||
* unit is set via setOffsetAlongLineUnit.
|
||||
* \see offsetAlongLine
|
||||
* \see setOffsetAlongLineUnit
|
||||
* \see setPlacement
|
||||
* \since QGIS 2.3
|
||||
*/
|
||||
void setOffsetAlongLine( double offsetAlongLine ) { mOffsetAlongLine = offsetAlongLine; }
|
||||
|
||||
/**
|
||||
* Returns the unit used for calculating the offset along line for markers.
|
||||
* \returns Offset along line unit type.
|
||||
* \see setOffsetAlongLineUnit
|
||||
* \see offsetAlongLine
|
||||
*/
|
||||
QgsUnitTypes::RenderUnit offsetAlongLineUnit() const { return mOffsetAlongLineUnit; }
|
||||
|
||||
/**
|
||||
* Sets the unit used for calculating the offset along line for markers.
|
||||
* \param unit Offset along line unit type.
|
||||
* \see offsetAlongLineUnit
|
||||
* \see setOffsetAlongLine
|
||||
*/
|
||||
void setOffsetAlongLineUnit( QgsUnitTypes::RenderUnit unit ) { mOffsetAlongLineUnit = unit; }
|
||||
|
||||
/**
|
||||
* Returns the map unit scale used for calculating the offset in map units along line for symbols.
|
||||
* \see setOffsetAlongLineMapUnitScale()
|
||||
*/
|
||||
const QgsMapUnitScale &offsetAlongLineMapUnitScale() const { return mOffsetAlongLineMapUnitScale; }
|
||||
|
||||
/**
|
||||
* Sets the map unit \a scale used for calculating the offset in map units along line for symbols.
|
||||
* \see offsetAlongLineMapUnitScale()
|
||||
*/
|
||||
void setOffsetAlongLineMapUnitScale( const QgsMapUnitScale &scale ) { mOffsetAlongLineMapUnitScale = scale; }
|
||||
|
||||
/**
|
||||
* Sets the units for the interval between symbols.
|
||||
* \param unit interval units
|
||||
@ -445,43 +336,132 @@ class CORE_EXPORT QgsMarkerLineSymbolLayer : public QgsLineSymbolLayer
|
||||
*/
|
||||
const QgsMapUnitScale &intervalMapUnitScale() const { return mIntervalMapUnitScale; }
|
||||
|
||||
void setOutputUnit( QgsUnitTypes::RenderUnit unit ) override;
|
||||
QgsUnitTypes::RenderUnit outputUnit() const override;
|
||||
/**
|
||||
* Returns the placement of the symbols.
|
||||
* \see setPlacement()
|
||||
*/
|
||||
Placement placement() const { return mPlacement; }
|
||||
|
||||
void setMapUnitScale( const QgsMapUnitScale &scale ) override;
|
||||
QgsMapUnitScale mapUnitScale() const override;
|
||||
/**
|
||||
* Sets the \a placement of the symbols.
|
||||
* \see placement()
|
||||
*/
|
||||
void setPlacement( Placement placement ) { mPlacement = placement; }
|
||||
|
||||
QSet<QString> usedAttributes( const QgsRenderContext &context ) const override;
|
||||
bool hasDataDefinedProperties() const override;
|
||||
/**
|
||||
* Returns the offset along the line for the symbol placement. For Interval placements, this is the distance
|
||||
* between the start of the line and the first symbol. For FirstVertex and LastVertex placements, this is the
|
||||
* distance between the symbol and the start of the line or the end of the line respectively.
|
||||
* This setting has no effect for Vertex or CentralPoint placements.
|
||||
* \returns The offset along the line. The unit for the offset is retrievable via offsetAlongLineUnit.
|
||||
* \see setOffsetAlongLine()
|
||||
* \see offsetAlongLineUnit()
|
||||
* \see placement()
|
||||
*/
|
||||
double offsetAlongLine() const { return mOffsetAlongLine; }
|
||||
|
||||
void setDataDefinedProperty( QgsSymbolLayer::Property key, const QgsProperty &property ) override;
|
||||
/**
|
||||
* Sets the the offset along the line for the symbol placement. For Interval placements, this is the distance
|
||||
* between the start of the line and the first symbol. For FirstVertex and LastVertex placements, this is the
|
||||
* distance between the symbol and the start of the line or the end of the line respectively.
|
||||
* This setting has no effect for Vertex or CentralPoint placements.
|
||||
* \param offsetAlongLine Distance to offset markers along the line. The offset
|
||||
* unit is set via setOffsetAlongLineUnit.
|
||||
* \see offsetAlongLine()
|
||||
* \see setOffsetAlongLineUnit()
|
||||
* \see setPlacement()
|
||||
*/
|
||||
void setOffsetAlongLine( double offsetAlongLine ) { mOffsetAlongLine = offsetAlongLine; }
|
||||
|
||||
/**
|
||||
* Returns the unit used for calculating the offset along line for symbols.
|
||||
* \returns Offset along line unit type.
|
||||
* \see setOffsetAlongLineUnit()
|
||||
* \see offsetAlongLine()
|
||||
*/
|
||||
QgsUnitTypes::RenderUnit offsetAlongLineUnit() const { return mOffsetAlongLineUnit; }
|
||||
|
||||
/**
|
||||
* Sets the unit used for calculating the offset along line for symbols.
|
||||
* \param unit Offset along line unit type.
|
||||
* \see offsetAlongLineUnit()
|
||||
* \see setOffsetAlongLine()
|
||||
*/
|
||||
void setOffsetAlongLineUnit( QgsUnitTypes::RenderUnit unit ) { mOffsetAlongLineUnit = unit; }
|
||||
|
||||
/**
|
||||
* Returns the map unit scale used for calculating the offset in map units along line for symbols.
|
||||
* \see setOffsetAlongLineMapUnitScale()
|
||||
*/
|
||||
const QgsMapUnitScale &offsetAlongLineMapUnitScale() const { return mOffsetAlongLineMapUnitScale; }
|
||||
|
||||
/**
|
||||
* Sets the map unit \a scale used for calculating the offset in map units along line for symbols.
|
||||
* \see offsetAlongLineMapUnitScale()
|
||||
*/
|
||||
void setOffsetAlongLineMapUnitScale( const QgsMapUnitScale &scale ) { mOffsetAlongLineMapUnitScale = scale; }
|
||||
|
||||
void renderPolyline( const QPolygonF &points, QgsSymbolRenderContext &context ) FINAL;
|
||||
void renderPolygonStroke( const QPolygonF &points, QList<QPolygonF> *rings, QgsSymbolRenderContext &context ) FINAL;
|
||||
QgsUnitTypes::RenderUnit outputUnit() const FINAL;
|
||||
void setMapUnitScale( const QgsMapUnitScale &scale ) FINAL;
|
||||
QgsMapUnitScale mapUnitScale() const FINAL;
|
||||
QgsStringMap properties() const override;
|
||||
|
||||
protected:
|
||||
|
||||
void renderPolylineInterval( const QPolygonF &points, QgsSymbolRenderContext &context );
|
||||
void renderPolylineVertex( const QPolygonF &points, QgsSymbolRenderContext &context, Placement placement = Vertex );
|
||||
void renderPolylineCentral( const QPolygonF &points, QgsSymbolRenderContext &context );
|
||||
double markerAngle( const QPolygonF &points, bool isRing, int vertex );
|
||||
/**
|
||||
* Sets the line \a angle modification for the symbol's angle. This angle is added to
|
||||
* the symbol's rotation and data defined rotation before rendering the symbol, and
|
||||
* is used for orienting symbols to match the line's angle.
|
||||
* \param angle Angle in degrees, valid values are between 0 and 360
|
||||
*/
|
||||
virtual void setSymbolLineAngle( double angle ) = 0;
|
||||
|
||||
bool mRotateMarker;
|
||||
double mInterval;
|
||||
QgsUnitTypes::RenderUnit mIntervalUnit;
|
||||
QgsMapUnitScale mIntervalMapUnitScale;
|
||||
std::unique_ptr< QgsMarkerSymbol > mMarker;
|
||||
Placement mPlacement;
|
||||
double mOffsetAlongLine; //distance to offset along line before marker is drawn
|
||||
QgsUnitTypes::RenderUnit mOffsetAlongLineUnit; //unit for offset along line
|
||||
QgsMapUnitScale mOffsetAlongLineMapUnitScale;
|
||||
/**
|
||||
* Returns the symbol's current angle, in degrees clockwise.
|
||||
*/
|
||||
virtual double symbolAngle() const = 0;
|
||||
|
||||
/**
|
||||
* Sets the symbol's \a angle, in degrees clockwise.
|
||||
*/
|
||||
virtual void setSymbolAngle( double angle ) = 0;
|
||||
|
||||
/**
|
||||
* Renders the templated symbol at the specified \a point, using the given render \a context.
|
||||
*
|
||||
* The \a feature argument is used to pass the feature currently being rendered (when available).
|
||||
*
|
||||
* If only a single symbol layer from the symbol should be rendered, it should be specified
|
||||
* in the \a layer argument. A \a layer of -1 indicates that all symbol layers should be
|
||||
* rendered.
|
||||
*
|
||||
* If \a selected is true then the symbol will be drawn using the "selected feature"
|
||||
* style and colors instead of the symbol's normal style.
|
||||
*/
|
||||
virtual void renderSymbol( const QPointF &point, const QgsFeature *feature, QgsRenderContext &context, int layer = -1, bool selected = false ) = 0;
|
||||
|
||||
/**
|
||||
* Copies all common properties of this layer to another templated symbol layer.
|
||||
*/
|
||||
void copyTemplateSymbolProperties( QgsTemplatedLineSymbolLayerBase *destLayer ) const;
|
||||
|
||||
/**
|
||||
* Sets all common symbol properties in the \a destLayer, using the settings
|
||||
* serialized in the \a properties map.
|
||||
*/
|
||||
static void setCommonProperties( QgsTemplatedLineSymbolLayerBase *destLayer, const QgsStringMap &properties );
|
||||
|
||||
private:
|
||||
|
||||
#ifdef SIP_RUN
|
||||
QgsMarkerLineSymbolLayer( const QgsMarkerLineSymbolLayer &other );
|
||||
#endif
|
||||
void renderPolylineInterval( const QPolygonF &points, QgsSymbolRenderContext &context );
|
||||
void renderPolylineVertex( const QPolygonF &points, QgsSymbolRenderContext &context, QgsTemplatedLineSymbolLayerBase::Placement placement = QgsTemplatedLineSymbolLayerBase::Vertex );
|
||||
void renderPolylineCentral( const QPolygonF &points, QgsSymbolRenderContext &context );
|
||||
double markerAngle( const QPolygonF &points, bool isRing, int vertex );
|
||||
|
||||
/**
|
||||
* Renders a marker by offsetting a vertex along the line by a specified distance.
|
||||
* Renders a symbol by offsetting a vertex along the line by a specified distance.
|
||||
* \param points vertices making up the line
|
||||
* \param vertex vertex number to begin offset at
|
||||
* \param distance distance to offset from vertex. If distance is positive, offset is calculated
|
||||
@ -492,6 +472,230 @@ class CORE_EXPORT QgsMarkerLineSymbolLayer : public QgsLineSymbolLayer
|
||||
* \see setOffsetAlongLineUnit
|
||||
*/
|
||||
void renderOffsetVertexAlongLine( const QPolygonF &points, int vertex, double distance, QgsSymbolRenderContext &context );
|
||||
|
||||
bool mRotateSymbols = true;
|
||||
double mInterval = 3;
|
||||
QgsUnitTypes::RenderUnit mIntervalUnit = QgsUnitTypes::RenderMillimeters;
|
||||
QgsMapUnitScale mIntervalMapUnitScale;
|
||||
Placement mPlacement = Interval;
|
||||
double mOffsetAlongLine = 0; //distance to offset along line before marker is drawn
|
||||
QgsUnitTypes::RenderUnit mOffsetAlongLineUnit = QgsUnitTypes::RenderMillimeters; //unit for offset along line
|
||||
QgsMapUnitScale mOffsetAlongLineMapUnitScale;
|
||||
};
|
||||
|
||||
/**
|
||||
* \ingroup core
|
||||
* \class QgsMarkerLineSymbolLayer
|
||||
* Line symbol layer type which draws repeating marker symbols along a line feature.
|
||||
*/
|
||||
class CORE_EXPORT QgsMarkerLineSymbolLayer : public QgsTemplatedLineSymbolLayerBase
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor for QgsMarkerLineSymbolLayer. Creates a marker line
|
||||
* with a default marker symbol, placed at the specified \a interval (in millimeters).
|
||||
*
|
||||
* The \a rotateMarker argument specifies whether individual marker symbols
|
||||
* should be rotated to match the line segment alignment.
|
||||
*/
|
||||
QgsMarkerLineSymbolLayer( bool rotateMarker = DEFAULT_MARKERLINE_ROTATE,
|
||||
double interval = DEFAULT_MARKERLINE_INTERVAL );
|
||||
|
||||
// static stuff
|
||||
|
||||
/**
|
||||
* Creates a new QgsMarkerLineSymbolLayer, using the settings
|
||||
* serialized in the \a properties map (corresponding to the output from
|
||||
* QgsMarkerLineSymbolLayer::properties() ).
|
||||
*/
|
||||
static QgsSymbolLayer *create( const QgsStringMap &properties = QgsStringMap() ) SIP_FACTORY;
|
||||
|
||||
/**
|
||||
* Creates a new QgsMarkerLineSymbolLayer from an SLD XML DOM \a element.
|
||||
*/
|
||||
static QgsSymbolLayer *createFromSld( QDomElement &element ) SIP_FACTORY;
|
||||
|
||||
// implemented from base classes
|
||||
|
||||
QString layerType() const override;
|
||||
void startRender( QgsSymbolRenderContext &context ) override;
|
||||
void stopRender( QgsSymbolRenderContext &context ) override;
|
||||
QgsMarkerLineSymbolLayer *clone() const override SIP_FACTORY;
|
||||
void toSld( QDomDocument &doc, QDomElement &element, const QgsStringMap &props ) const override;
|
||||
void setColor( const QColor &color ) override;
|
||||
QColor color() const override;
|
||||
QgsSymbol *subSymbol() override;
|
||||
bool setSubSymbol( QgsSymbol *symbol SIP_TRANSFER ) override;
|
||||
void setWidth( double width ) override;
|
||||
double width() const override;
|
||||
double width( const QgsRenderContext &context ) const override;
|
||||
double estimateMaxBleed( const QgsRenderContext &context ) const override;
|
||||
void setOutputUnit( QgsUnitTypes::RenderUnit unit ) override;
|
||||
QSet<QString> usedAttributes( const QgsRenderContext &context ) const override;
|
||||
bool hasDataDefinedProperties() const override;
|
||||
void setDataDefinedProperty( QgsSymbolLayer::Property key, const QgsProperty &property ) override;
|
||||
|
||||
/**
|
||||
* Shall the marker be rotated.
|
||||
*
|
||||
* \returns TRUE if the marker should be rotated.
|
||||
* \deprecated Use rotateSymbols() instead.
|
||||
*/
|
||||
Q_DECL_DEPRECATED bool rotateMarker() const SIP_DEPRECATED { return rotateSymbols(); }
|
||||
|
||||
/**
|
||||
* Shall the marker be rotated.
|
||||
* \deprecated Use setRotateSymbols() instead.
|
||||
*/
|
||||
Q_DECL_DEPRECATED void setRotateMarker( bool rotate ) SIP_DEPRECATED { setRotateSymbols( rotate ); }
|
||||
|
||||
protected:
|
||||
|
||||
std::unique_ptr< QgsMarkerSymbol > mMarker;
|
||||
|
||||
void setSymbolLineAngle( double angle ) override;
|
||||
double symbolAngle() const override;
|
||||
void setSymbolAngle( double angle ) override;
|
||||
void renderSymbol( const QPointF &point, const QgsFeature *feature, QgsRenderContext &context, int layer = -1, bool selected = false ) override;
|
||||
|
||||
private:
|
||||
|
||||
#ifdef SIP_RUN
|
||||
QgsMarkerLineSymbolLayer( const QgsMarkerLineSymbolLayer &other );
|
||||
#endif
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* \ingroup core
|
||||
* \class QgsHashedLineSymbolLayer
|
||||
*
|
||||
* Line symbol layer type which draws repeating line sections along a line feature.
|
||||
*
|
||||
* \since QGIS 3.8
|
||||
*/
|
||||
class CORE_EXPORT QgsHashedLineSymbolLayer : public QgsTemplatedLineSymbolLayerBase
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor for QgsHashedLineSymbolLayer. Creates a line
|
||||
* with a default hash symbol, placed at the specified \a interval (in millimeters).
|
||||
*
|
||||
* The \a rotateSymbol argument specifies whether individual hash symbols
|
||||
* should be rotated to match the line segment alignment.
|
||||
*/
|
||||
QgsHashedLineSymbolLayer( bool rotateSymbol = true,
|
||||
double interval = 3 );
|
||||
|
||||
/**
|
||||
* Creates a new QgsHashedLineSymbolLayer, using the settings
|
||||
* serialized in the \a properties map (corresponding to the output from
|
||||
* QgsHashedLineSymbolLayer::properties() ).
|
||||
*/
|
||||
static QgsSymbolLayer *create( const QgsStringMap &properties = QgsStringMap() ) SIP_FACTORY;
|
||||
|
||||
QString layerType() const override;
|
||||
void startRender( QgsSymbolRenderContext &context ) override;
|
||||
void stopRender( QgsSymbolRenderContext &context ) override;
|
||||
QgsStringMap properties() const override;
|
||||
QgsHashedLineSymbolLayer *clone() const override SIP_FACTORY;
|
||||
void setColor( const QColor &color ) override;
|
||||
QColor color() const override;
|
||||
QgsSymbol *subSymbol() override;
|
||||
bool setSubSymbol( QgsSymbol *symbol SIP_TRANSFER ) override;
|
||||
void setWidth( double width ) override;
|
||||
double width() const override;
|
||||
double width( const QgsRenderContext &context ) const override;
|
||||
double estimateMaxBleed( const QgsRenderContext &context ) const override;
|
||||
void setOutputUnit( QgsUnitTypes::RenderUnit unit ) override;
|
||||
QSet<QString> usedAttributes( const QgsRenderContext &context ) const override;
|
||||
bool hasDataDefinedProperties() const override;
|
||||
void setDataDefinedProperty( QgsSymbolLayer::Property key, const QgsProperty &property ) override;
|
||||
|
||||
/**
|
||||
* Returns the angle to use when drawing the hashed lines sections, in degrees clockwise.
|
||||
*
|
||||
* \see setHashAngle()
|
||||
*/
|
||||
double hashAngle() const;
|
||||
|
||||
/**
|
||||
* Sets the \a angle to use when drawing the hashed lines sections, in degrees clockwise.
|
||||
*
|
||||
* \see hashAngle()
|
||||
*/
|
||||
void setHashAngle( double angle );
|
||||
|
||||
/**
|
||||
* Returns the length of hash symbols. Units are specified through hashLengthUnits().
|
||||
* \see setHashLength()
|
||||
* \see hashLengthUnit()
|
||||
*/
|
||||
double hashLength() const { return mHashLength; }
|
||||
|
||||
/**
|
||||
* Sets the \a length of hash symbols. Units are specified through setHashLengthUnit()
|
||||
* \see hashLength()
|
||||
* \see setHashLengthUnit()
|
||||
*/
|
||||
void setHashLength( double length ) { mHashLength = length; }
|
||||
|
||||
/**
|
||||
* Sets the \a unit for the length of hash symbols.
|
||||
* \see hashLengthUnit()
|
||||
* \see setHashLength()
|
||||
*/
|
||||
void setHashLengthUnit( QgsUnitTypes::RenderUnit unit ) { mHashLengthUnit = unit; }
|
||||
|
||||
/**
|
||||
* Returns the units for the length of hash symbols.
|
||||
* \see setHashLengthUnit()
|
||||
* \see hashLength()
|
||||
*/
|
||||
QgsUnitTypes::RenderUnit hashLengthUnit() const { return mHashLengthUnit; }
|
||||
|
||||
/**
|
||||
* Sets the map unit \a scale for the hash length.
|
||||
* \see hashLengthMapUnitScale()
|
||||
* \see setHashLengthUnit()
|
||||
* \see setHashLength()
|
||||
*/
|
||||
void setHashLengthMapUnitScale( const QgsMapUnitScale &scale ) { mHashLengthMapUnitScale = scale; }
|
||||
|
||||
/**
|
||||
* Returns the map unit scale for the hash length.
|
||||
* \see setHashLengthMapUnitScale()
|
||||
* \see hashLengthUnit()
|
||||
* \see hashLength()
|
||||
*/
|
||||
const QgsMapUnitScale &hashLengthMapUnitScale() const { return mHashLengthMapUnitScale; }
|
||||
|
||||
protected:
|
||||
|
||||
void setSymbolLineAngle( double angle ) override;
|
||||
double symbolAngle() const override;
|
||||
void setSymbolAngle( double angle ) override;
|
||||
void renderSymbol( const QPointF &point, const QgsFeature *feature, QgsRenderContext &context, int layer = -1, bool selected = false ) override;
|
||||
|
||||
private:
|
||||
#ifdef SIP_RUN
|
||||
QgsHashedLineSymbolLayer( const QgsHashedLineSymbolLayer &other );
|
||||
#endif
|
||||
|
||||
std::unique_ptr< QgsLineSymbol > mHashSymbol;
|
||||
|
||||
double mSymbolLineAngle = 0;
|
||||
double mSymbolAngle = 0;
|
||||
|
||||
double mHashAngle = 0;
|
||||
double mHashLength = 3;
|
||||
QgsUnitTypes::RenderUnit mHashLengthUnit = QgsUnitTypes::RenderMillimeters;
|
||||
QgsMapUnitScale mHashLengthMapUnitScale;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -139,8 +139,8 @@ class CORE_EXPORT QgsSymbolLayer
|
||||
PropertyFillStyle, //!< Fill style (eg solid, dots)
|
||||
PropertyJoinStyle, //!< Line join style
|
||||
PropertySecondaryColor, //!< Secondary color (eg for gradient fills)
|
||||
PropertyLineAngle, //!< Line angle
|
||||
PropertyLineDistance, //!< Distance between lines
|
||||
PropertyLineAngle, //!< Line angle, or angle of hash lines for hash line symbols
|
||||
PropertyLineDistance, //!< Distance between lines, or length of lines for hash line symbols
|
||||
PropertyGradientType, //!< Gradient fill type
|
||||
PropertyCoordinateMode, //!< Gradient coordinate mode
|
||||
PropertyGradientSpread, //!< Gradient spread mode
|
||||
@ -786,10 +786,42 @@ class CORE_EXPORT QgsLineSymbolLayer : public QgsSymbolLayer
|
||||
InteriorRingsOnly, //!< Render the interior rings only
|
||||
};
|
||||
|
||||
void setOutputUnit( QgsUnitTypes::RenderUnit unit ) override;
|
||||
QgsUnitTypes::RenderUnit outputUnit() const override;
|
||||
void setMapUnitScale( const QgsMapUnitScale &scale ) override;
|
||||
QgsMapUnitScale mapUnitScale() const override;
|
||||
void drawPreviewIcon( QgsSymbolRenderContext &context, QSize size ) override;
|
||||
double dxfWidth( const QgsDxfExport &e, QgsSymbolRenderContext &context ) const override;
|
||||
|
||||
/**
|
||||
* Renders the line symbol layer along the line joining \a points, using the given render \a context.
|
||||
* \see renderPolygonStroke()
|
||||
*/
|
||||
virtual void renderPolyline( const QPolygonF &points, QgsSymbolRenderContext &context ) = 0;
|
||||
|
||||
/**
|
||||
* Renders the line symbol layer along the outline of polygon, using the given render \a context.
|
||||
*
|
||||
* The exterior ring of the polygon is specified in \a points. Optionally, interior
|
||||
* rings are set via the \a rings arugment.
|
||||
*
|
||||
* \see renderPolyline()
|
||||
*/
|
||||
virtual void renderPolygonStroke( const QPolygonF &points, QList<QPolygonF> *rings, QgsSymbolRenderContext &context );
|
||||
|
||||
/**
|
||||
* Sets the \a width of the line symbol layer.
|
||||
*
|
||||
* Calling this method updates the width of the line symbol layer, without
|
||||
* changing the existing width units. It has different effects depending
|
||||
* on the line symbol layer subclass, e.g. for a simple line layer it
|
||||
* changes the stroke width of the line, for a marker line layer it
|
||||
* changes the size of the markers used to draw the line.
|
||||
*
|
||||
* \see width()
|
||||
* \warning Since the width units vary, this method is useful for changing the
|
||||
* relative width of a line symbol layer only.
|
||||
*/
|
||||
virtual void setWidth( double width ) { mWidth = width; }
|
||||
|
||||
/**
|
||||
@ -815,9 +847,63 @@ class CORE_EXPORT QgsLineSymbolLayer : public QgsSymbolLayer
|
||||
*/
|
||||
virtual double width( const QgsRenderContext &context ) const;
|
||||
|
||||
/**
|
||||
* Returns the line's offset.
|
||||
*
|
||||
* Offset units can be retrieved by calling offsetUnit().
|
||||
*
|
||||
* \see setOffset()
|
||||
* \see offsetUnit()
|
||||
* \see offsetMapUnitScale()
|
||||
*/
|
||||
double offset() const { return mOffset; }
|
||||
|
||||
/**
|
||||
* Sets the line's \a offset.
|
||||
*
|
||||
* Offset units are set via setOffsetUnit().
|
||||
*
|
||||
* \see offset()
|
||||
* \see setOffsetUnit()
|
||||
* \see setOffsetMapUnitScale()
|
||||
*/
|
||||
void setOffset( double offset ) { mOffset = offset; }
|
||||
|
||||
/**
|
||||
* Sets the \a unit for the line's offset.
|
||||
* \see offsetUnit()
|
||||
* \see setOffset()
|
||||
* \see setOffsetMapUnitScale()
|
||||
*/
|
||||
void setOffsetUnit( QgsUnitTypes::RenderUnit unit ) { mOffsetUnit = unit; }
|
||||
|
||||
/**
|
||||
* Returns the units for the line's offset.
|
||||
* \see setOffsetUnit()
|
||||
* \see offset()
|
||||
* \see offsetMapUnitScale()
|
||||
*/
|
||||
QgsUnitTypes::RenderUnit offsetUnit() const { return mOffsetUnit; }
|
||||
|
||||
/**
|
||||
* Sets the map unit \a scale for the line's offset.
|
||||
* \see offsetMapUnitScale()
|
||||
* \see setOffset()
|
||||
* \see setOffsetUnit()
|
||||
*/
|
||||
void setOffsetMapUnitScale( const QgsMapUnitScale &scale ) { mOffsetMapUnitScale = scale; }
|
||||
|
||||
/**
|
||||
* Returns the map unit scale for the line's offset.
|
||||
* \see setOffsetMapUnitScale()
|
||||
* \see offset()
|
||||
* \see offsetUnit()
|
||||
*/
|
||||
const QgsMapUnitScale &offsetMapUnitScale() const { return mOffsetMapUnitScale; }
|
||||
|
||||
// TODO QGIS 4.0 - setWidthUnit(), widthUnit(), setWidthUnitScale(), widthUnitScale()
|
||||
// only apply to simple line symbol layers and do not belong here.
|
||||
|
||||
/**
|
||||
* Sets the units for the line's width.
|
||||
* \param unit width units
|
||||
@ -834,32 +920,6 @@ class CORE_EXPORT QgsLineSymbolLayer : public QgsSymbolLayer
|
||||
void setWidthMapUnitScale( const QgsMapUnitScale &scale ) { mWidthMapUnitScale = scale; }
|
||||
const QgsMapUnitScale &widthMapUnitScale() const { return mWidthMapUnitScale; }
|
||||
|
||||
/**
|
||||
* Sets the units for the line's offset.
|
||||
* \param unit offset units
|
||||
* \see offsetUnit()
|
||||
*/
|
||||
void setOffsetUnit( QgsUnitTypes::RenderUnit unit ) { mOffsetUnit = unit; }
|
||||
|
||||
/**
|
||||
* Returns the units for the line's offset.
|
||||
* \see setOffsetUnit()
|
||||
*/
|
||||
QgsUnitTypes::RenderUnit offsetUnit() const { return mOffsetUnit; }
|
||||
|
||||
void setOffsetMapUnitScale( const QgsMapUnitScale &scale ) { mOffsetMapUnitScale = scale; }
|
||||
const QgsMapUnitScale &offsetMapUnitScale() const { return mOffsetMapUnitScale; }
|
||||
|
||||
void setOutputUnit( QgsUnitTypes::RenderUnit unit ) override;
|
||||
QgsUnitTypes::RenderUnit outputUnit() const override;
|
||||
|
||||
void setMapUnitScale( const QgsMapUnitScale &scale ) override;
|
||||
QgsMapUnitScale mapUnitScale() const override;
|
||||
|
||||
void drawPreviewIcon( QgsSymbolRenderContext &context, QSize size ) override;
|
||||
|
||||
double dxfWidth( const QgsDxfExport &e, QgsSymbolRenderContext &context ) const override;
|
||||
|
||||
/**
|
||||
* Returns the line symbol layer's ring filter, which controls which rings are
|
||||
* rendered when the line symbol is being used to draw a polygon's rings.
|
||||
|
@ -30,6 +30,8 @@ QgsSymbolLayerRegistry::QgsSymbolLayerRegistry()
|
||||
QgsSimpleLineSymbolLayer::create, QgsSimpleLineSymbolLayer::createFromSld ) );
|
||||
addSymbolLayerType( new QgsSymbolLayerMetadata( QStringLiteral( "MarkerLine" ), QObject::tr( "Marker line" ), QgsSymbol::Line,
|
||||
QgsMarkerLineSymbolLayer::create, QgsMarkerLineSymbolLayer::createFromSld ) );
|
||||
addSymbolLayerType( new QgsSymbolLayerMetadata( QStringLiteral( "HashLine" ), QObject::tr( "Hashed line" ), QgsSymbol::Line,
|
||||
QgsHashedLineSymbolLayer::create ) );
|
||||
addSymbolLayerType( new QgsSymbolLayerMetadata( QStringLiteral( "ArrowLine" ), QObject::tr( "Arrow" ), QgsSymbol::Line, QgsArrowSymbolLayer::create ) );
|
||||
|
||||
addSymbolLayerType( new QgsSymbolLayerMetadata( QStringLiteral( "SimpleMarker" ), QObject::tr( "Simple marker" ), QgsSymbol::Marker,
|
||||
|
@ -66,6 +66,7 @@ static void _initWidgetFunctions()
|
||||
|
||||
_initWidgetFunction( QStringLiteral( "SimpleLine" ), QgsSimpleLineSymbolLayerWidget::create );
|
||||
_initWidgetFunction( QStringLiteral( "MarkerLine" ), QgsMarkerLineSymbolLayerWidget::create );
|
||||
_initWidgetFunction( QStringLiteral( "HashLine" ), QgsHashedLineSymbolLayerWidget::create );
|
||||
_initWidgetFunction( QStringLiteral( "ArrowLine" ), QgsArrowSymbolLayerWidget::create );
|
||||
|
||||
_initWidgetFunction( QStringLiteral( "SimpleMarker" ), QgsSimpleMarkerSymbolLayerWidget::create );
|
||||
|
@ -1726,20 +1726,20 @@ void QgsMarkerLineSymbolLayerWidget::setSymbolLayer( QgsSymbolLayer *layer )
|
||||
mSpinOffsetAlongLine->setValue( mLayer->offsetAlongLine() );
|
||||
mSpinOffsetAlongLine->blockSignals( false );
|
||||
chkRotateMarker->blockSignals( true );
|
||||
chkRotateMarker->setChecked( mLayer->rotateMarker() );
|
||||
chkRotateMarker->setChecked( mLayer->rotateSymbols() );
|
||||
chkRotateMarker->blockSignals( false );
|
||||
spinOffset->blockSignals( true );
|
||||
spinOffset->setValue( mLayer->offset() );
|
||||
spinOffset->blockSignals( false );
|
||||
if ( mLayer->placement() == QgsMarkerLineSymbolLayer::Interval )
|
||||
if ( mLayer->placement() == QgsTemplatedLineSymbolLayerBase::Interval )
|
||||
radInterval->setChecked( true );
|
||||
else if ( mLayer->placement() == QgsMarkerLineSymbolLayer::Vertex )
|
||||
else if ( mLayer->placement() == QgsTemplatedLineSymbolLayerBase::Vertex )
|
||||
radVertex->setChecked( true );
|
||||
else if ( mLayer->placement() == QgsMarkerLineSymbolLayer::LastVertex )
|
||||
else if ( mLayer->placement() == QgsTemplatedLineSymbolLayerBase::LastVertex )
|
||||
radVertexLast->setChecked( true );
|
||||
else if ( mLayer->placement() == QgsMarkerLineSymbolLayer::CentralPoint )
|
||||
else if ( mLayer->placement() == QgsTemplatedLineSymbolLayerBase::CentralPoint )
|
||||
radCentralPoint->setChecked( true );
|
||||
else if ( mLayer->placement() == QgsMarkerLineSymbolLayer::CurvePoint )
|
||||
else if ( mLayer->placement() == QgsTemplatedLineSymbolLayerBase::CurvePoint )
|
||||
radCurvePoint->setChecked( true );
|
||||
else
|
||||
radVertexFirst->setChecked( true );
|
||||
@ -1787,7 +1787,7 @@ void QgsMarkerLineSymbolLayerWidget::setOffsetAlongLine( double val )
|
||||
|
||||
void QgsMarkerLineSymbolLayerWidget::setRotate()
|
||||
{
|
||||
mLayer->setRotateMarker( chkRotateMarker->isChecked() );
|
||||
mLayer->setRotateSymbols( chkRotateMarker->isChecked() );
|
||||
emit changed();
|
||||
}
|
||||
|
||||
@ -1804,17 +1804,17 @@ void QgsMarkerLineSymbolLayerWidget::setPlacement()
|
||||
mSpinOffsetAlongLine->setEnabled( radInterval->isChecked() || radVertexLast->isChecked() || radVertexFirst->isChecked() );
|
||||
//mLayer->setPlacement( interval ? QgsMarkerLineSymbolLayer::Interval : QgsMarkerLineSymbolLayer::Vertex );
|
||||
if ( radInterval->isChecked() )
|
||||
mLayer->setPlacement( QgsMarkerLineSymbolLayer::Interval );
|
||||
mLayer->setPlacement( QgsTemplatedLineSymbolLayerBase::Interval );
|
||||
else if ( radVertex->isChecked() )
|
||||
mLayer->setPlacement( QgsMarkerLineSymbolLayer::Vertex );
|
||||
mLayer->setPlacement( QgsTemplatedLineSymbolLayerBase::Vertex );
|
||||
else if ( radVertexLast->isChecked() )
|
||||
mLayer->setPlacement( QgsMarkerLineSymbolLayer::LastVertex );
|
||||
mLayer->setPlacement( QgsTemplatedLineSymbolLayerBase::LastVertex );
|
||||
else if ( radVertexFirst->isChecked() )
|
||||
mLayer->setPlacement( QgsMarkerLineSymbolLayer::FirstVertex );
|
||||
mLayer->setPlacement( QgsTemplatedLineSymbolLayerBase::FirstVertex );
|
||||
else if ( radCurvePoint->isChecked() )
|
||||
mLayer->setPlacement( QgsMarkerLineSymbolLayer::CurvePoint );
|
||||
mLayer->setPlacement( QgsTemplatedLineSymbolLayerBase::CurvePoint );
|
||||
else
|
||||
mLayer->setPlacement( QgsMarkerLineSymbolLayer::CentralPoint );
|
||||
mLayer->setPlacement( QgsTemplatedLineSymbolLayerBase::CentralPoint );
|
||||
|
||||
emit changed();
|
||||
}
|
||||
@ -1849,6 +1849,234 @@ void QgsMarkerLineSymbolLayerWidget::mOffsetAlongLineUnitWidget_changed()
|
||||
emit changed();
|
||||
}
|
||||
|
||||
|
||||
///////////
|
||||
|
||||
QgsHashedLineSymbolLayerWidget::QgsHashedLineSymbolLayerWidget( QgsVectorLayer *vl, QWidget *parent )
|
||||
: QgsSymbolLayerWidget( parent, vl )
|
||||
{
|
||||
mLayer = nullptr;
|
||||
|
||||
setupUi( this );
|
||||
connect( mIntervalUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsHashedLineSymbolLayerWidget::mIntervalUnitWidget_changed );
|
||||
connect( mOffsetUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsHashedLineSymbolLayerWidget::mOffsetUnitWidget_changed );
|
||||
connect( mOffsetAlongLineUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsHashedLineSymbolLayerWidget::mOffsetAlongLineUnitWidget_changed );
|
||||
connect( mHashLengthUnitWidget, &QgsUnitSelectionWidget::changed, this, &QgsHashedLineSymbolLayerWidget::hashLengthUnitWidgetChanged );
|
||||
mIntervalUnitWidget->setUnits( QgsUnitTypes::RenderUnitList() << QgsUnitTypes::RenderMillimeters << QgsUnitTypes::RenderMetersInMapUnits << QgsUnitTypes::RenderMapUnits << QgsUnitTypes::RenderPixels
|
||||
<< QgsUnitTypes::RenderPoints << QgsUnitTypes::RenderInches );
|
||||
mOffsetUnitWidget->setUnits( QgsUnitTypes::RenderUnitList() << QgsUnitTypes::RenderMillimeters << QgsUnitTypes::RenderMetersInMapUnits << QgsUnitTypes::RenderMapUnits << QgsUnitTypes::RenderPixels
|
||||
<< QgsUnitTypes::RenderPoints << QgsUnitTypes::RenderInches );
|
||||
mOffsetAlongLineUnitWidget->setUnits( QgsUnitTypes::RenderUnitList() << QgsUnitTypes::RenderMillimeters << QgsUnitTypes::RenderMetersInMapUnits << QgsUnitTypes::RenderMapUnits << QgsUnitTypes::RenderPixels
|
||||
<< QgsUnitTypes::RenderPoints << QgsUnitTypes::RenderInches );
|
||||
|
||||
mHashLengthUnitWidget->setUnits( QgsUnitTypes::RenderUnitList() << QgsUnitTypes::RenderMillimeters << QgsUnitTypes::RenderMetersInMapUnits << QgsUnitTypes::RenderMapUnits << QgsUnitTypes::RenderPixels
|
||||
<< QgsUnitTypes::RenderPoints << QgsUnitTypes::RenderInches );
|
||||
|
||||
mRingFilterComboBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "mIconAllRings.svg" ) ), tr( "All Rings" ), QgsLineSymbolLayer::AllRings );
|
||||
mRingFilterComboBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "mIconExteriorRing.svg" ) ), tr( "Exterior Ring Only" ), QgsLineSymbolLayer::ExteriorRingOnly );
|
||||
mRingFilterComboBox->addItem( QgsApplication::getThemeIcon( QStringLiteral( "mIconInteriorRings.svg" ) ), tr( "Interior Rings Only" ), QgsLineSymbolLayer::InteriorRingsOnly );
|
||||
connect( mRingFilterComboBox, qgis::overload< int >::of( &QComboBox::currentIndexChanged ), this, [ = ]( int )
|
||||
{
|
||||
if ( mLayer )
|
||||
{
|
||||
mLayer->setRingFilter( static_cast< QgsLineSymbolLayer::RenderRingFilter >( mRingFilterComboBox->currentData().toInt() ) );
|
||||
emit changed();
|
||||
}
|
||||
} );
|
||||
|
||||
spinOffset->setClearValue( 0.0 );
|
||||
|
||||
|
||||
if ( vl && vl->geometryType() != QgsWkbTypes::PolygonGeometry )
|
||||
{
|
||||
mRingFilterComboBox->hide();
|
||||
mRingsLabel->hide();
|
||||
}
|
||||
|
||||
mHashRotationSpinBox->setClearValue( 0 );
|
||||
|
||||
connect( spinInterval, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsHashedLineSymbolLayerWidget::setInterval );
|
||||
connect( mSpinOffsetAlongLine, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsHashedLineSymbolLayerWidget::setOffsetAlongLine );
|
||||
connect( mSpinHashLength, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsHashedLineSymbolLayerWidget::setHashLength );
|
||||
connect( mHashRotationSpinBox, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsHashedLineSymbolLayerWidget::setHashAngle );
|
||||
connect( chkRotateMarker, &QAbstractButton::clicked, this, &QgsHashedLineSymbolLayerWidget::setRotate );
|
||||
connect( spinOffset, static_cast < void ( QDoubleSpinBox::* )( double ) > ( &QDoubleSpinBox::valueChanged ), this, &QgsHashedLineSymbolLayerWidget::setOffset );
|
||||
connect( radInterval, &QAbstractButton::clicked, this, &QgsHashedLineSymbolLayerWidget::setPlacement );
|
||||
connect( radVertex, &QAbstractButton::clicked, this, &QgsHashedLineSymbolLayerWidget::setPlacement );
|
||||
connect( radVertexLast, &QAbstractButton::clicked, this, &QgsHashedLineSymbolLayerWidget::setPlacement );
|
||||
connect( radVertexFirst, &QAbstractButton::clicked, this, &QgsHashedLineSymbolLayerWidget::setPlacement );
|
||||
connect( radCentralPoint, &QAbstractButton::clicked, this, &QgsHashedLineSymbolLayerWidget::setPlacement );
|
||||
connect( radCurvePoint, &QAbstractButton::clicked, this, &QgsHashedLineSymbolLayerWidget::setPlacement );
|
||||
}
|
||||
|
||||
void QgsHashedLineSymbolLayerWidget::setSymbolLayer( QgsSymbolLayer *layer )
|
||||
{
|
||||
if ( layer->layerType() != QLatin1String( "HashLine" ) )
|
||||
return;
|
||||
|
||||
// layer type is correct, we can do the cast
|
||||
mLayer = static_cast<QgsHashedLineSymbolLayer *>( layer );
|
||||
|
||||
// set values
|
||||
spinInterval->blockSignals( true );
|
||||
spinInterval->setValue( mLayer->interval() );
|
||||
spinInterval->blockSignals( false );
|
||||
mSpinOffsetAlongLine->blockSignals( true );
|
||||
mSpinOffsetAlongLine->setValue( mLayer->offsetAlongLine() );
|
||||
mSpinOffsetAlongLine->blockSignals( false );
|
||||
whileBlocking( mSpinHashLength )->setValue( mLayer->hashLength() );
|
||||
whileBlocking( mHashRotationSpinBox )->setValue( mLayer->hashAngle() );
|
||||
chkRotateMarker->blockSignals( true );
|
||||
chkRotateMarker->setChecked( mLayer->rotateSymbols() );
|
||||
chkRotateMarker->blockSignals( false );
|
||||
spinOffset->blockSignals( true );
|
||||
spinOffset->setValue( mLayer->offset() );
|
||||
spinOffset->blockSignals( false );
|
||||
if ( mLayer->placement() == QgsTemplatedLineSymbolLayerBase::Interval )
|
||||
radInterval->setChecked( true );
|
||||
else if ( mLayer->placement() == QgsTemplatedLineSymbolLayerBase::Vertex )
|
||||
radVertex->setChecked( true );
|
||||
else if ( mLayer->placement() == QgsTemplatedLineSymbolLayerBase::LastVertex )
|
||||
radVertexLast->setChecked( true );
|
||||
else if ( mLayer->placement() == QgsTemplatedLineSymbolLayerBase::CentralPoint )
|
||||
radCentralPoint->setChecked( true );
|
||||
else if ( mLayer->placement() == QgsTemplatedLineSymbolLayerBase::CurvePoint )
|
||||
radCurvePoint->setChecked( true );
|
||||
else
|
||||
radVertexFirst->setChecked( true );
|
||||
|
||||
// set units
|
||||
mIntervalUnitWidget->blockSignals( true );
|
||||
mIntervalUnitWidget->setUnit( mLayer->intervalUnit() );
|
||||
mIntervalUnitWidget->setMapUnitScale( mLayer->intervalMapUnitScale() );
|
||||
mIntervalUnitWidget->blockSignals( false );
|
||||
mOffsetUnitWidget->blockSignals( true );
|
||||
mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
|
||||
mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
|
||||
mOffsetUnitWidget->blockSignals( false );
|
||||
mOffsetAlongLineUnitWidget->blockSignals( true );
|
||||
mOffsetAlongLineUnitWidget->setUnit( mLayer->offsetAlongLineUnit() );
|
||||
mOffsetAlongLineUnitWidget->setMapUnitScale( mLayer->offsetAlongLineMapUnitScale() );
|
||||
mOffsetAlongLineUnitWidget->blockSignals( false );
|
||||
|
||||
whileBlocking( mHashLengthUnitWidget )->setUnit( mLayer->hashLengthUnit() );
|
||||
whileBlocking( mHashLengthUnitWidget )->setMapUnitScale( mLayer->hashLengthMapUnitScale() );
|
||||
|
||||
whileBlocking( mRingFilterComboBox )->setCurrentIndex( mRingFilterComboBox->findData( mLayer->ringFilter() ) );
|
||||
|
||||
setPlacement(); // update gui
|
||||
|
||||
registerDataDefinedButton( mIntervalDDBtn, QgsSymbolLayer::PropertyInterval );
|
||||
registerDataDefinedButton( mLineOffsetDDBtn, QgsSymbolLayer::PropertyOffset );
|
||||
registerDataDefinedButton( mPlacementDDBtn, QgsSymbolLayer::PropertyPlacement );
|
||||
registerDataDefinedButton( mOffsetAlongLineDDBtn, QgsSymbolLayer::PropertyOffsetAlongLine );
|
||||
registerDataDefinedButton( mHashLengthDDBtn, QgsSymbolLayer::PropertyLineDistance );
|
||||
registerDataDefinedButton( mHashRotationDDBtn, QgsSymbolLayer::PropertyLineAngle );
|
||||
}
|
||||
|
||||
QgsSymbolLayer *QgsHashedLineSymbolLayerWidget::symbolLayer()
|
||||
{
|
||||
return mLayer;
|
||||
}
|
||||
|
||||
void QgsHashedLineSymbolLayerWidget::setInterval( double val )
|
||||
{
|
||||
mLayer->setInterval( val );
|
||||
emit changed();
|
||||
}
|
||||
|
||||
void QgsHashedLineSymbolLayerWidget::setOffsetAlongLine( double val )
|
||||
{
|
||||
mLayer->setOffsetAlongLine( val );
|
||||
emit changed();
|
||||
}
|
||||
|
||||
void QgsHashedLineSymbolLayerWidget::setHashLength( double val )
|
||||
{
|
||||
mLayer->setHashLength( val );
|
||||
emit changed();
|
||||
}
|
||||
|
||||
void QgsHashedLineSymbolLayerWidget::setHashAngle( double val )
|
||||
{
|
||||
mLayer->setHashAngle( val );
|
||||
emit changed();
|
||||
}
|
||||
|
||||
void QgsHashedLineSymbolLayerWidget::setRotate()
|
||||
{
|
||||
mLayer->setRotateSymbols( chkRotateMarker->isChecked() );
|
||||
emit changed();
|
||||
}
|
||||
|
||||
void QgsHashedLineSymbolLayerWidget::setOffset()
|
||||
{
|
||||
mLayer->setOffset( spinOffset->value() );
|
||||
emit changed();
|
||||
}
|
||||
|
||||
void QgsHashedLineSymbolLayerWidget::setPlacement()
|
||||
{
|
||||
bool interval = radInterval->isChecked();
|
||||
spinInterval->setEnabled( interval );
|
||||
mSpinOffsetAlongLine->setEnabled( radInterval->isChecked() || radVertexLast->isChecked() || radVertexFirst->isChecked() );
|
||||
//mLayer->setPlacement( interval ? QgsMarkerLineSymbolLayer::Interval : QgsMarkerLineSymbolLayer::Vertex );
|
||||
if ( radInterval->isChecked() )
|
||||
mLayer->setPlacement( QgsTemplatedLineSymbolLayerBase::Interval );
|
||||
else if ( radVertex->isChecked() )
|
||||
mLayer->setPlacement( QgsTemplatedLineSymbolLayerBase::Vertex );
|
||||
else if ( radVertexLast->isChecked() )
|
||||
mLayer->setPlacement( QgsTemplatedLineSymbolLayerBase::LastVertex );
|
||||
else if ( radVertexFirst->isChecked() )
|
||||
mLayer->setPlacement( QgsTemplatedLineSymbolLayerBase::FirstVertex );
|
||||
else if ( radCurvePoint->isChecked() )
|
||||
mLayer->setPlacement( QgsTemplatedLineSymbolLayerBase::CurvePoint );
|
||||
else
|
||||
mLayer->setPlacement( QgsTemplatedLineSymbolLayerBase::CentralPoint );
|
||||
|
||||
emit changed();
|
||||
}
|
||||
|
||||
void QgsHashedLineSymbolLayerWidget::mIntervalUnitWidget_changed()
|
||||
{
|
||||
if ( mLayer )
|
||||
{
|
||||
mLayer->setIntervalUnit( mIntervalUnitWidget->unit() );
|
||||
mLayer->setIntervalMapUnitScale( mIntervalUnitWidget->getMapUnitScale() );
|
||||
emit changed();
|
||||
}
|
||||
}
|
||||
|
||||
void QgsHashedLineSymbolLayerWidget::mOffsetUnitWidget_changed()
|
||||
{
|
||||
if ( mLayer )
|
||||
{
|
||||
mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
|
||||
mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
|
||||
emit changed();
|
||||
}
|
||||
}
|
||||
|
||||
void QgsHashedLineSymbolLayerWidget::mOffsetAlongLineUnitWidget_changed()
|
||||
{
|
||||
if ( mLayer )
|
||||
{
|
||||
mLayer->setOffsetAlongLineUnit( mOffsetAlongLineUnitWidget->unit() );
|
||||
mLayer->setOffsetAlongLineMapUnitScale( mOffsetAlongLineUnitWidget->getMapUnitScale() );
|
||||
}
|
||||
emit changed();
|
||||
}
|
||||
|
||||
void QgsHashedLineSymbolLayerWidget::hashLengthUnitWidgetChanged()
|
||||
{
|
||||
if ( mLayer )
|
||||
{
|
||||
mLayer->setHashLengthUnit( mHashLengthUnitWidget->unit() );
|
||||
mLayer->setHashLengthMapUnitScale( mHashLengthUnitWidget->getMapUnitScale() );
|
||||
}
|
||||
emit changed();
|
||||
}
|
||||
|
||||
///////////
|
||||
|
||||
|
||||
|
@ -502,6 +502,57 @@ class GUI_EXPORT QgsMarkerLineSymbolLayerWidget : public QgsSymbolLayerWidget, p
|
||||
};
|
||||
|
||||
|
||||
#include "ui_widget_hashline.h"
|
||||
|
||||
class QgsHashedLineSymbolLayer;
|
||||
|
||||
/**
|
||||
* \ingroup gui
|
||||
* \class QgsHashedLineSymbolLayerWidget
|
||||
*/
|
||||
class GUI_EXPORT QgsHashedLineSymbolLayerWidget : public QgsSymbolLayerWidget, private Ui::WidgetHashedLine
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Constructor for QgsHashedLineSymbolLayerWidget.
|
||||
* \param vl associated vector layer
|
||||
* \param parent parent widget
|
||||
*/
|
||||
QgsHashedLineSymbolLayerWidget( QgsVectorLayer *vl, QWidget *parent SIP_TRANSFERTHIS = nullptr );
|
||||
|
||||
/**
|
||||
* Creates a new QgsHashedLineSymbolLayerWidget.
|
||||
* \param vl associated vector layer
|
||||
*/
|
||||
static QgsSymbolLayerWidget *create( QgsVectorLayer *vl ) SIP_FACTORY { return new QgsHashedLineSymbolLayerWidget( vl ); }
|
||||
|
||||
// from base class
|
||||
void setSymbolLayer( QgsSymbolLayer *layer ) override;
|
||||
QgsSymbolLayer *symbolLayer() override;
|
||||
|
||||
private slots:
|
||||
|
||||
void setInterval( double val );
|
||||
void setOffsetAlongLine( double val );
|
||||
void setHashLength( double val );
|
||||
void setHashAngle( double val );
|
||||
|
||||
void setRotate();
|
||||
void setOffset();
|
||||
void setPlacement();
|
||||
void mIntervalUnitWidget_changed();
|
||||
void mOffsetUnitWidget_changed();
|
||||
void mOffsetAlongLineUnitWidget_changed();
|
||||
void hashLengthUnitWidgetChanged();
|
||||
private:
|
||||
QgsHashedLineSymbolLayer *mLayer = nullptr;
|
||||
|
||||
|
||||
};
|
||||
|
||||
///////////
|
||||
|
||||
#include "ui_widget_svgmarker.h"
|
||||
|
@ -61,9 +61,9 @@ QgsGrassEditRenderer::QgsGrassEditRenderer()
|
||||
markerLayers << markerSymbolLayer;
|
||||
QgsMarkerSymbol *markerSymbol = new QgsMarkerSymbol( markerLayers );
|
||||
firstVertexMarkerLine->setSubSymbol( markerSymbol );
|
||||
firstVertexMarkerLine->setPlacement( QgsMarkerLineSymbolLayer::FirstVertex );
|
||||
firstVertexMarkerLine->setPlacement( QgsTemplatedLineSymbolLayerBase::FirstVertex );
|
||||
QgsMarkerLineSymbolLayer *lastVertexMarkerLine = static_cast<QgsMarkerLineSymbolLayer *>( firstVertexMarkerLine->clone() );
|
||||
lastVertexMarkerLine->setPlacement( QgsMarkerLineSymbolLayer::LastVertex );
|
||||
lastVertexMarkerLine->setPlacement( QgsTemplatedLineSymbolLayerBase::LastVertex );
|
||||
Q_FOREACH ( int value, colors.keys() )
|
||||
{
|
||||
QgsSymbol *symbol = QgsSymbol::defaultSymbol( QgsWkbTypes::LineGeometry );
|
||||
|
436
src/ui/symbollayer/widget_hashline.ui
Normal file
436
src/ui/symbollayer/widget_hashline.ui
Normal file
@ -0,0 +1,436 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>WidgetHashedLine</class>
|
||||
<widget class="QWidget" name="WidgetHashedLine">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>371</width>
|
||||
<height>380</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<property name="leftMargin">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Hash placement</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="3">
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="3" column="2">
|
||||
<widget class="QgsPropertyOverrideButton" name="mIntervalDDBtn">
|
||||
<property name="text">
|
||||
<string>…</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<widget class="QRadioButton" name="radInterval">
|
||||
<property name="text">
|
||||
<string>with interval</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QgsDoubleSpinBox" name="spinInterval">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>10000000.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.200000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
<property name="showClearButton" stdset="0">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QgsUnitSelectionWidget" name="mIntervalUnitWidget" native="true">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::TabFocus</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QRadioButton" name="radVertexLast">
|
||||
<property name="text">
|
||||
<string>on last vertex only</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QRadioButton" name="radVertexFirst">
|
||||
<property name="text">
|
||||
<string>on first vertex only</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<widget class="QRadioButton" name="radCentralPoint">
|
||||
<property name="text">
|
||||
<string>on central point</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="1">
|
||||
<widget class="QRadioButton" name="radCurvePoint">
|
||||
<property name="text">
|
||||
<string>on every curve point</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QRadioButton" name="radVertex">
|
||||
<property name="text">
|
||||
<string>on every vertex</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>10</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="5" column="1" colspan="2">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QgsPropertyOverrideButton" name="mPlacementDDBtn">
|
||||
<property name="text">
|
||||
<string>…</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="3">
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item row="2" column="3">
|
||||
<widget class="QgsPropertyOverrideButton" name="mHashRotationDDBtn">
|
||||
<property name="text">
|
||||
<string>…</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QgsDoubleSpinBox" name="mSpinOffsetAlongLine">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>10000000.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.200000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="3">
|
||||
<widget class="QgsPropertyOverrideButton" name="mLineOffsetDDBtn">
|
||||
<property name="text">
|
||||
<string>…</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Hash rotation</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="2">
|
||||
<widget class="QgsUnitSelectionWidget" name="mOffsetUnitWidget" native="true">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::TabFocus</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Offset along line</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="3">
|
||||
<widget class="QgsPropertyOverrideButton" name="mOffsetAlongLineDDBtn">
|
||||
<property name="text">
|
||||
<string>…</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QgsUnitSelectionWidget" name="mOffsetAlongLineUnitWidget" native="true">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::TabFocus</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="mRingsLabel">
|
||||
<property name="text">
|
||||
<string>Rings</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Line offset</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1" colspan="3">
|
||||
<widget class="QComboBox" name="mRingFilterComboBox"/>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QgsDoubleSpinBox" name="spinOffset">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>-999999999.000000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>999999999.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.200000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="4">
|
||||
<widget class="QCheckBox" name="chkRotateMarker">
|
||||
<property name="text">
|
||||
<string>Rotate hash to follow line direction</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Hash length</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QgsDoubleSpinBox" name="mSpinHashLength">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>10000000.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.200000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>1.000000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QgsUnitSelectionWidget" name="mHashLengthUnitWidget" native="true">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="focusPolicy">
|
||||
<enum>Qt::TabFocus</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="3">
|
||||
<widget class="QgsPropertyOverrideButton" name="mHashLengthDDBtn">
|
||||
<property name="text">
|
||||
<string>…</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QgsDoubleSpinBox" name="mHashRotationSpinBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="wrapping">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string> °</string>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<double>-360.000000000000000</double>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>360.000000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.500000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>QgsPropertyOverrideButton</class>
|
||||
<extends>QToolButton</extends>
|
||||
<header>qgspropertyoverridebutton.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>QgsDoubleSpinBox</class>
|
||||
<extends>QDoubleSpinBox</extends>
|
||||
<header>qgsdoublespinbox.h</header>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>QgsUnitSelectionWidget</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>qgsunitselectionwidget.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>mPlacementDDBtn</tabstop>
|
||||
<tabstop>radInterval</tabstop>
|
||||
<tabstop>spinInterval</tabstop>
|
||||
<tabstop>mIntervalUnitWidget</tabstop>
|
||||
<tabstop>mIntervalDDBtn</tabstop>
|
||||
<tabstop>radVertex</tabstop>
|
||||
<tabstop>radVertexLast</tabstop>
|
||||
<tabstop>radVertexFirst</tabstop>
|
||||
<tabstop>radCentralPoint</tabstop>
|
||||
<tabstop>radCurvePoint</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
@ -144,7 +144,7 @@ void TestQgsMarkerLineSymbol::pointNumInterval()
|
||||
mMapSettings->setLayers( QList<QgsMapLayer *>() << mLinesLayer );
|
||||
|
||||
QgsMarkerLineSymbolLayer *ml = new QgsMarkerLineSymbolLayer();
|
||||
ml->setPlacement( QgsMarkerLineSymbolLayer::Interval );
|
||||
ml->setPlacement( QgsTemplatedLineSymbolLayerBase::Interval );
|
||||
ml->setInterval( 4 );
|
||||
QgsLineSymbol *lineSymbol = new QgsLineSymbol();
|
||||
lineSymbol->changeSymbolLayer( 0, ml );
|
||||
@ -174,7 +174,7 @@ void TestQgsMarkerLineSymbol::pointNumVertex()
|
||||
mMapSettings->setLayers( QList<QgsMapLayer *>() << mLinesLayer );
|
||||
|
||||
QgsMarkerLineSymbolLayer *ml = new QgsMarkerLineSymbolLayer();
|
||||
ml->setPlacement( QgsMarkerLineSymbolLayer::Vertex );
|
||||
ml->setPlacement( QgsTemplatedLineSymbolLayerBase::Vertex );
|
||||
QgsLineSymbol *lineSymbol = new QgsLineSymbol();
|
||||
lineSymbol->changeSymbolLayer( 0, ml );
|
||||
QgsSingleSymbolRenderer *r = new QgsSingleSymbolRenderer( lineSymbol );
|
||||
@ -203,7 +203,7 @@ void TestQgsMarkerLineSymbol::ringFilter()
|
||||
mMapSettings->setLayers( QList<QgsMapLayer *>() << mLinesLayer );
|
||||
|
||||
QgsMarkerLineSymbolLayer *ml = new QgsMarkerLineSymbolLayer();
|
||||
ml->setPlacement( QgsMarkerLineSymbolLayer::Vertex );
|
||||
ml->setPlacement( QgsTemplatedLineSymbolLayerBase::Vertex );
|
||||
QgsLineSymbol *lineSymbol = new QgsLineSymbol();
|
||||
lineSymbol->changeSymbolLayer( 0, ml );
|
||||
QgsSingleSymbolRenderer *r = new QgsSingleSymbolRenderer( lineSymbol );
|
||||
|
@ -177,7 +177,7 @@ void TestQgsSymbol::testCanvasClip()
|
||||
ms.setLayers( QList<QgsMapLayer *>() << mpLinesLayer );
|
||||
|
||||
QgsMarkerLineSymbolLayer *markerLine = new QgsMarkerLineSymbolLayer();
|
||||
markerLine->setPlacement( QgsMarkerLineSymbolLayer:: CentralPoint );
|
||||
markerLine->setPlacement( QgsTemplatedLineSymbolLayerBase::CentralPoint );
|
||||
static_cast< QgsSimpleMarkerSymbolLayer *>( markerLine->subSymbol()->symbolLayer( 0 ) )->setStrokeColor( Qt::black );
|
||||
QgsLineSymbol *lineSymbol = new QgsLineSymbol();
|
||||
lineSymbol->changeSymbolLayer( 0, markerLine );
|
||||
|
234
tests/src/python/test_qgshashlinesymbollayer.py
Normal file
234
tests/src/python/test_qgshashlinesymbollayer.py
Normal file
@ -0,0 +1,234 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
***************************************************************************
|
||||
test_qgsmarkerlinesymbollayer.py
|
||||
---------------------
|
||||
Date : November 2018
|
||||
Copyright : (C) 2018 by Nyall Dawson
|
||||
Email : nyall dot dawson at gmail dot com
|
||||
***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************
|
||||
"""
|
||||
|
||||
__author__ = 'Nyall Dawson'
|
||||
__date__ = 'November 2018'
|
||||
__copyright__ = '(C) 2018, Nyall Dawson'
|
||||
# This will get replaced with a git SHA1 when you do a git archive
|
||||
__revision__ = '$Format:%H$'
|
||||
|
||||
import qgis # NOQA
|
||||
|
||||
from utilities import unitTestDataPath
|
||||
|
||||
from qgis.PyQt.QtCore import QDir, Qt, QSize
|
||||
from qgis.PyQt.QtGui import QImage, QColor, QPainter
|
||||
from qgis.PyQt.QtXml import QDomDocument
|
||||
|
||||
from qgis.core import (QgsGeometry,
|
||||
QgsFillSymbol,
|
||||
QgsRenderContext,
|
||||
QgsFeature,
|
||||
QgsMapSettings,
|
||||
QgsRenderChecker,
|
||||
QgsReadWriteContext,
|
||||
QgsSymbolLayerUtils,
|
||||
QgsSimpleMarkerSymbolLayer,
|
||||
QgsLineSymbolLayer,
|
||||
QgsMarkerLineSymbolLayer,
|
||||
QgsMarkerSymbol,
|
||||
QgsGeometryGeneratorSymbolLayer,
|
||||
QgsSymbol,
|
||||
QgsFontMarkerSymbolLayer,
|
||||
QgsFontUtils,
|
||||
QgsLineSymbol,
|
||||
QgsSymbolLayer,
|
||||
QgsProperty,
|
||||
QgsRectangle,
|
||||
QgsUnitTypes
|
||||
)
|
||||
|
||||
from qgis.testing import unittest, start_app
|
||||
|
||||
start_app()
|
||||
TEST_DATA_DIR = unitTestDataPath()
|
||||
|
||||
|
||||
class TestQgsMarkerLineSymbolLayer(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.report = "<h1>Python QgsMarkerLineSymbolLayer Tests</h1>\n"
|
||||
|
||||
def tearDown(self):
|
||||
report_file_path = "%s/qgistest.html" % QDir.tempPath()
|
||||
with open(report_file_path, 'a') as report_file:
|
||||
report_file.write(self.report)
|
||||
|
||||
def testWidth(self):
|
||||
ms = QgsMapSettings()
|
||||
extent = QgsRectangle(100, 200, 100, 200)
|
||||
ms.setExtent(extent)
|
||||
ms.setOutputSize(QSize(400, 400))
|
||||
context = QgsRenderContext.fromMapSettings(ms)
|
||||
context.setScaleFactor(96 / 25.4) # 96 DPI
|
||||
ms.setExtent(QgsRectangle(100, 150, 100, 150))
|
||||
ms.setOutputDpi(ms.outputDpi() * 2)
|
||||
context2 = QgsRenderContext.fromMapSettings(ms)
|
||||
context2.setScaleFactor(300 / 25.4)
|
||||
|
||||
s = QgsFillSymbol()
|
||||
s.deleteSymbolLayer(0)
|
||||
|
||||
marker_line = QgsMarkerLineSymbolLayer(True)
|
||||
marker_line.setPlacement(QgsMarkerLineSymbolLayer.FirstVertex)
|
||||
marker = QgsSimpleMarkerSymbolLayer(QgsSimpleMarkerSymbolLayer.Triangle, 10)
|
||||
marker.setColor(QColor(255, 0, 0))
|
||||
marker.setStrokeStyle(Qt.NoPen)
|
||||
marker_symbol = QgsMarkerSymbol()
|
||||
marker_symbol.changeSymbolLayer(0, marker)
|
||||
marker_line.setSubSymbol(marker_symbol)
|
||||
|
||||
self.assertEqual(marker_line.width(), 10)
|
||||
self.assertAlmostEqual(marker_line.width(context), 37.795275590551185, 3)
|
||||
self.assertAlmostEqual(marker_line.width(context2), 118.11023622047244, 3)
|
||||
|
||||
marker_line.subSymbol().setSizeUnit(QgsUnitTypes.RenderPixels)
|
||||
self.assertAlmostEqual(marker_line.width(context), 10.0, 3)
|
||||
self.assertAlmostEqual(marker_line.width(context2), 10.0, 3)
|
||||
|
||||
def testRingFilter(self):
|
||||
# test filtering rings during rendering
|
||||
s = QgsFillSymbol()
|
||||
s.deleteSymbolLayer(0)
|
||||
|
||||
marker_line = QgsMarkerLineSymbolLayer(True)
|
||||
marker_line.setPlacement(QgsMarkerLineSymbolLayer.FirstVertex)
|
||||
marker = QgsSimpleMarkerSymbolLayer(QgsSimpleMarkerSymbolLayer.Triangle, 4)
|
||||
marker.setColor(QColor(255, 0, 0))
|
||||
marker.setStrokeStyle(Qt.NoPen)
|
||||
marker_symbol = QgsMarkerSymbol()
|
||||
marker_symbol.changeSymbolLayer(0, marker)
|
||||
marker_line.setSubSymbol(marker_symbol)
|
||||
|
||||
s.appendSymbolLayer(marker_line.clone())
|
||||
self.assertEqual(s.symbolLayer(0).ringFilter(), QgsLineSymbolLayer.AllRings)
|
||||
s.symbolLayer(0).setRingFilter(QgsLineSymbolLayer.ExteriorRingOnly)
|
||||
self.assertEqual(s.symbolLayer(0).ringFilter(), QgsLineSymbolLayer.ExteriorRingOnly)
|
||||
|
||||
s2 = s.clone()
|
||||
self.assertEqual(s2.symbolLayer(0).ringFilter(), QgsLineSymbolLayer.ExteriorRingOnly)
|
||||
|
||||
doc = QDomDocument()
|
||||
context = QgsReadWriteContext()
|
||||
element = QgsSymbolLayerUtils.saveSymbol('test', s, doc, context)
|
||||
|
||||
s2 = QgsSymbolLayerUtils.loadSymbol(element, context)
|
||||
self.assertEqual(s2.symbolLayer(0).ringFilter(), QgsLineSymbolLayer.ExteriorRingOnly)
|
||||
|
||||
# rendering test
|
||||
s3 = QgsFillSymbol()
|
||||
s3.deleteSymbolLayer(0)
|
||||
s3.appendSymbolLayer(
|
||||
QgsMarkerLineSymbolLayer())
|
||||
s3.symbolLayer(0).setRingFilter(QgsLineSymbolLayer.ExteriorRingOnly)
|
||||
|
||||
g = QgsGeometry.fromWkt('Polygon((0 0, 10 0, 10 10, 0 10, 0 0),(1 1, 1 2, 2 2, 2 1, 1 1),(8 8, 9 8, 9 9, 8 9, 8 8))')
|
||||
rendered_image = self.renderGeometry(s3, g)
|
||||
assert self.imageCheck('markerline_exterioronly', 'markerline_exterioronly', rendered_image)
|
||||
|
||||
s3.symbolLayer(0).setRingFilter(QgsLineSymbolLayer.InteriorRingsOnly)
|
||||
g = QgsGeometry.fromWkt('Polygon((0 0, 10 0, 10 10, 0 10, 0 0),(1 1, 1 2, 2 2, 2 1, 1 1),(8 8, 9 8, 9 9, 8 9, 8 8))')
|
||||
rendered_image = self.renderGeometry(s3, g)
|
||||
assert self.imageCheck('markerline_interioronly', 'markerline_interioronly', rendered_image)
|
||||
|
||||
def testPartNum(self):
|
||||
# test geometry_part_num variable
|
||||
s = QgsLineSymbol()
|
||||
s.deleteSymbolLayer(0)
|
||||
|
||||
sym_layer = QgsGeometryGeneratorSymbolLayer.create({'geometryModifier': 'segments_to_lines($geometry)'})
|
||||
sym_layer.setSymbolType(QgsSymbol.Line)
|
||||
s.appendSymbolLayer(sym_layer)
|
||||
|
||||
marker_line = QgsMarkerLineSymbolLayer(False)
|
||||
marker_line.setPlacement(QgsMarkerLineSymbolLayer.FirstVertex)
|
||||
f = QgsFontUtils.getStandardTestFont('Bold', 24)
|
||||
marker = QgsFontMarkerSymbolLayer(f.family(), 'x', 24, QColor(255, 255, 0))
|
||||
marker.setDataDefinedProperty(QgsSymbolLayer.PropertyCharacter, QgsProperty.fromExpression('@geometry_part_num'))
|
||||
marker_symbol = QgsMarkerSymbol()
|
||||
marker_symbol.changeSymbolLayer(0, marker)
|
||||
marker_line.setSubSymbol(marker_symbol)
|
||||
line_symbol = QgsLineSymbol()
|
||||
line_symbol.changeSymbolLayer(0, marker_line)
|
||||
sym_layer.setSubSymbol(line_symbol)
|
||||
|
||||
# rendering test
|
||||
g = QgsGeometry.fromWkt('LineString(0 0, 10 0, 10 10, 0 10)')
|
||||
rendered_image = self.renderGeometry(s, g, buffer=4)
|
||||
assert self.imageCheck('part_num_variable', 'part_num_variable', rendered_image)
|
||||
|
||||
marker.setDataDefinedProperty(QgsSymbolLayer.PropertyCharacter,
|
||||
QgsProperty.fromExpression('@geometry_part_count'))
|
||||
|
||||
# rendering test
|
||||
g = QgsGeometry.fromWkt('LineString(0 0, 10 0, 10 10, 0 10)')
|
||||
rendered_image = self.renderGeometry(s, g, buffer=4)
|
||||
assert self.imageCheck('part_count_variable', 'part_count_variable', rendered_image)
|
||||
|
||||
def renderGeometry(self, symbol, geom, buffer=20):
|
||||
f = QgsFeature()
|
||||
f.setGeometry(geom)
|
||||
|
||||
image = QImage(200, 200, QImage.Format_RGB32)
|
||||
|
||||
painter = QPainter()
|
||||
ms = QgsMapSettings()
|
||||
extent = geom.get().boundingBox()
|
||||
# buffer extent by 10%
|
||||
if extent.width() > 0:
|
||||
extent = extent.buffered((extent.height() + extent.width()) / buffer)
|
||||
else:
|
||||
extent = extent.buffered(buffer / 2)
|
||||
|
||||
ms.setExtent(extent)
|
||||
ms.setOutputSize(image.size())
|
||||
context = QgsRenderContext.fromMapSettings(ms)
|
||||
context.setPainter(painter)
|
||||
context.setScaleFactor(96 / 25.4) # 96 DPI
|
||||
context.expressionContext().setFeature(f)
|
||||
|
||||
painter.begin(image)
|
||||
try:
|
||||
image.fill(QColor(0, 0, 0))
|
||||
symbol.startRender(context)
|
||||
symbol.renderFeature(f, context)
|
||||
symbol.stopRender(context)
|
||||
finally:
|
||||
painter.end()
|
||||
|
||||
return image
|
||||
|
||||
def imageCheck(self, name, reference_image, image):
|
||||
self.report += "<h2>Render {}</h2>\n".format(name)
|
||||
temp_dir = QDir.tempPath() + '/'
|
||||
file_name = temp_dir + 'symbol_' + name + ".png"
|
||||
image.save(file_name, "PNG")
|
||||
checker = QgsRenderChecker()
|
||||
checker.setControlPathPrefix("symbol_markerline")
|
||||
checker.setControlName("expected_" + reference_image)
|
||||
checker.setRenderedImage(file_name)
|
||||
checker.setColorTolerance(2)
|
||||
result = checker.compareImages(name, 20)
|
||||
self.report += checker.report()
|
||||
print((self.report))
|
||||
return result
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
Loading…
x
Reference in New Issue
Block a user