[FEATURE] New "Filled marker" symbol layer type

A "filled marker" is similar to the simple marker symbol layer, except
that it uses a fill sub symbol to render the marker. This allows use
of all the existing QGIS fill (and outline) styles for rendering
markers, eg gradient or shapeburst fills.

A new abstract class QgsSimpleMarkerSymbolLayerBase has been created
from which both QgsSimpleMarkerSymbolLayerV2 and
QgsFilledMarkerSymbolLayer derive. All common code has been moved to
this base class, allowing for easy addition of new shapes or features
to both simple markers and filled markers without duplication.

Also, adds a lot of missing docs to marker symbol layers.
This commit is contained in:
Nyall Dawson 2016-05-05 16:58:44 +10:00
parent cda387cb6f
commit ea20149239
24 changed files with 2986 additions and 695 deletions

View File

@ -1,4 +1,10 @@
class QgsSimpleMarkerSymbolLayerV2 : QgsMarkerSymbolLayerV2
/** \ingroup core
* \class QgsSimpleMarkerSymbolLayerBase
* \brief Abstract base class for simple marker symbol layers. Handles creation of the symbol shapes but
* leaves the actual drawing of the symbols to subclasses.
* \note Added in version 2.16
*/
class QgsSimpleMarkerSymbolLayerBase : QgsMarkerSymbolLayerV2
{
%TypeHeaderCode
#include <qgsmarkersymbollayerv2.h>
@ -6,7 +12,143 @@ class QgsSimpleMarkerSymbolLayerV2 : QgsMarkerSymbolLayerV2
public:
/** Constructor for QgsSimpleMarkerSymbolLayerV2.
//! Marker symbol shapes
enum Shape
{
Square, /*!< Square */
Diamond, /*!< Diamond */
Pentagon, /*!< Pentagon */
Hexagon, /*!< Hexagon */
Triangle, /*!< Triangle */
EquilateralTriangle, /*!< Equilateral triangle*/
Star, /*!< Star*/
Arrow, /*!< Arrow*/
Circle, /*!< Circle*/
Cross, /*!< Cross (lines only)*/
CrossFill, /*!< Solid filled cross*/
Cross2, /*!< Rotated cross (lines only), "x" shape*/
Line, /*!< Vertical line*/
ArrowHead, /*!< Right facing arrow head (unfilled, lines only)*/
ArrowHeadFilled, /*!< Right facing filled arrow head*/
SemiCircle, /*!< Semi circle (top half)*/
ThirdCircle, /*!< One third circle (top left third)*/
QuarterCircle, /*!< Quarter circle (top left quarter)*/
QuarterSquare, /*!< Quarter square (top left quarter)*/
HalfSquare, /*!< Half square (left half)*/
DiagonalHalfSquare, /*!< Diagonal half square (bottom left half)*/
RightHalfTriangle, /*!< Right half of triangle*/
LeftHalfTriangle, /*!< Left half of triangle*/
};
//! Returns a list of all available shape types.
static QList< QgsSimpleMarkerSymbolLayerBase::Shape > availableShapes();
/** Returns true if a symbol shape has a fill.
* @param shape shape to test
* @returns true if shape uses a fill, or false if shape uses lines only
*/
static bool shapeIsFilled( Shape shape );
/** Constructor for QgsSimpleMarkerSymbolLayerBase.
* @param shape symbol shape for markers
* @param size symbol size (in mm)
* @param angle symbol rotation angle
* @param scaleMethod scaling method for data defined scaling
*/
QgsSimpleMarkerSymbolLayerBase( Shape shape = Circle,
double size = DEFAULT_SIMPLEMARKER_SIZE,
double angle = DEFAULT_SIMPLEMARKER_ANGLE,
QgsSymbolV2::ScaleMethod scaleMethod = DEFAULT_SCALE_METHOD );
/** Returns the shape for the rendered marker symbol.
* @see setShape()
*/
Shape shape() const;
/** Sets the rendered marker shape.
* @param shape new marker shape
* @see shape()
*/
void setShape( Shape shape );
/** Attempts to decode a string representation of a shape name to the corresponding
* shape.
* @param name encoded shape name
* @param ok if specified, will be set to true if shape was successfully decoded
* @return decoded name
* @see encodeShape()
*/
static Shape decodeShape( const QString& name, bool* ok = nullptr );
/** Encodes a shape to its string representation.
* @param shape shape to encode
* @returns encoded string
* @see decodeShape()
*/
static QString encodeShape( Shape shape );
void startRender( QgsSymbolV2RenderContext& context );
void stopRender( QgsSymbolV2RenderContext& context );
void renderPoint( QPointF point, QgsSymbolV2RenderContext& context );
QRectF bounds( QPointF point, QgsSymbolV2RenderContext& context );
protected:
//! Prepares the layer for drawing the specified shape (QPolygonF version)
bool prepareMarkerShape( Shape shape );
//! Prepares the layer for drawing the specified shape (QPainterPath version)
bool prepareMarkerPath( Shape symbol );
/** Creates a polygon representing the specified shape.
* @param shape shape to create
* @param polygon destination polygon for shape
* @returns true if shape was successfully stored in polygon
*/
bool shapeToPolygon( Shape shape, QPolygonF &polygon ) const;
/** Calculates the desired size of the marker, considering data defined size overrides.
* @param context symbol render context
* @param hasDataDefinedSize will be set to true if marker uses data defined sizes
* @returns marker size, in original size units
*/
double calculateSize( QgsSymbolV2RenderContext& context, bool& hasDataDefinedSize ) const;
/** Calculates the marker offset and rotation.
* @param context symbol render context
* @param scaledSize size of symbol to render
* @param hasDataDefinedRotation will be set to true if marker has data defined rotation
* @param offset will be set to calculated marker offset (in painter units)
* @param angle will be set to calculated marker angle
*/
void calculateOffsetAndRotation( QgsSymbolV2RenderContext& context, double scaledSize, bool& hasDataDefinedRotation, QPointF& offset, double& angle ) const;
private:
/** Derived classes must implement draw() to handle drawing the generated shape onto the painter surface.
* @param context symbol render context
* @param shape shape to draw
* @param polygon polygon representing transformed marker shape. May be empty, in which case the shape will be specified
* in the path argument.
* @param path transformed painter path representing shape to draw
*/
virtual void draw( QgsSymbolV2RenderContext& context, Shape shape, const QPolygonF& polygon, const QPainterPath& path ) = 0;
};
/** \ingroup core
* \class QgsSimpleMarkerSymbolLayerV2
* \brief Simple marker symbol layer, consisting of a rendered shape with solid fill color and an outline.
*/
class QgsSimpleMarkerSymbolLayerV2 : QgsSimpleMarkerSymbolLayerBase
{
%TypeHeaderCode
#include <qgsmarkersymbollayerv2.h>
%End
public:
/** Constructor for QgsSimpleMarkerSymbolLayerV2.
* @param name symbol name, should be one of "square", "rectangle", "diamond",
* "pentagon", "hexagon", "triangle", "equilateral_triangle", "star", "arrow",
* "circle", "cross", "cross_fill", "cross2", "line", "x", "arrowhead", "filled_arrowhead",
@ -18,103 +160,247 @@ class QgsSimpleMarkerSymbolLayerV2 : QgsMarkerSymbolLayerV2
* @param angle symbol rotation angle
* @param scaleMethod scaling method for data defined scaling
* @param penJoinStyle join style for outline pen
* @deprecated use variant which accepts QgsSimpleMarkerSymbolLayerBase::Shape instead
*/
QgsSimpleMarkerSymbolLayerV2( const QString& name = DEFAULT_SIMPLEMARKER_NAME,
const QColor& color = DEFAULT_SIMPLEMARKER_COLOR,
const QColor& borderColor = DEFAULT_SIMPLEMARKER_BORDERCOLOR,
QgsSimpleMarkerSymbolLayerV2( const QString& name,
const QColor& color = DEFAULT_SIMPLEMARKER_COLOR,
const QColor& borderColor = DEFAULT_SIMPLEMARKER_BORDERCOLOR,
double size = DEFAULT_SIMPLEMARKER_SIZE,
double angle = DEFAULT_SIMPLEMARKER_ANGLE,
QgsSymbolV2::ScaleMethod scaleMethod = DEFAULT_SCALE_METHOD,
Qt::PenJoinStyle penJoinStyle = DEFAULT_SIMPLEMARKER_JOINSTYLE ) /Deprecated/;
/** Constructor for QgsSimpleMarkerSymbolLayerV2.
* @param shape symbol shape
* @param size symbol size (in mm)
* @param angle symbol rotation angle
* @param scaleMethod scaling method for data defined scaling
* @param color fill color for symbol
* @param borderColor border color for symbol
* @param penJoinStyle join style for outline pen
*/
QgsSimpleMarkerSymbolLayerV2( Shape shape = Circle,
double size = DEFAULT_SIMPLEMARKER_SIZE,
double angle = DEFAULT_SIMPLEMARKER_ANGLE,
QgsSymbolV2::ScaleMethod scaleMethod = DEFAULT_SCALE_METHOD,
const QColor& color = DEFAULT_SIMPLEMARKER_COLOR,
const QColor& borderColor = DEFAULT_SIMPLEMARKER_BORDERCOLOR,
Qt::PenJoinStyle penJoinStyle = DEFAULT_SIMPLEMARKER_JOINSTYLE );
// static stuff
// static methods
/** Creates a new QgsSimpleMarkerSymbolLayerV2.
* @param properties a property map containing symbol properties (see properties())
* @returns new QgsSimpleMarkerSymbolLayerV2
*/
static QgsSymbolLayerV2* create( const QgsStringMap& properties = QgsStringMap() ) /Factory/;
/** Creates a new QgsSimpleMarkerSymbolLayerV2 from an SLD XML element.
* @param element XML element containing SLD definition of symbol
* @returns new QgsSimpleMarkerSymbolLayerV2
*/
static QgsSymbolLayerV2* createFromSld( QDomElement &element ) /Factory/;
// implemented from base classes
// reimplemented from base classes
QString layerType() const;
void startRender( QgsSymbolV2RenderContext& context );
void stopRender( QgsSymbolV2RenderContext& context );
void renderPoint( QPointF point, QgsSymbolV2RenderContext& context );
QgsStringMap properties() const;
virtual QgsSimpleMarkerSymbolLayerV2* clone() const /Factory/;
void writeSldMarker( QDomDocument &doc, QDomElement &element, const QgsStringMap& props ) const;
QString ogrFeatureStyle( double mmScaleFactor, double mapUnitScaleFactor ) const;
QString name() const;
void setName( const QString& name );
QColor borderColor() const;
void setBorderColor( const QColor& color );
/** Get outline join style.
* @note added in 2.4 */
Qt::PenStyle outlineStyle() const;
/** Set outline join style.
* @note added in 2.4 */
void setOutlineStyle( Qt::PenStyle outlineStyle );
/** Get outline join style.
* @note added in 2.16 */
Qt::PenJoinStyle penJoinStyle() const;
/** Set outline join style.
* @note added in 2.16 */
void setPenJoinStyle( Qt::PenJoinStyle style );
/** Get outline color.
* @note added in 2.1 */
QColor outlineColor() const;
/** Set outline color.
* @note added in 2.1 */
void setOutlineColor( const QColor& color );
/** Get fill color.
* @note added in 2.1 */
QColor fillColor() const;
/** Set fill color.
* @note added in 2.1 */
void setFillColor( const QColor& color );
double outlineWidth() const;
void setOutlineWidth( double w );
void setOutlineWidthUnit( QgsSymbolV2::OutputUnit u );
QgsSymbolV2::OutputUnit outlineWidthUnit() const;
void setOutlineWidthMapUnitScale( const QgsMapUnitScale& scale);
const QgsMapUnitScale& outlineWidthMapUnitScale() const;
bool writeDxf( QgsDxfExport &e, double mmMapUnitScaleFactor, const QString &layerName, QgsSymbolV2RenderContext &context, QPointF shift = QPointF( 0.0, 0.0 ) ) const;
void setOutputUnit( QgsSymbolV2::OutputUnit unit );
QgsSymbolV2::OutputUnit outputUnit() const;
void setMapUnitScale( const QgsMapUnitScale& scale );
QgsMapUnitScale mapUnitScale() const;
QRectF bounds( QPointF point, QgsSymbolV2RenderContext& context );
QColor outlineColor() const;
void setOutlineColor( const QColor& color );
QColor fillColor() const;
void setFillColor( const QColor& color );
// new methods
//! @deprecated use shape() instead
QString name() const /Deprecated/;
//! @deprecated use setShape() instead
void setName( const QString& name ) /Deprecated/;
/** Returns the marker's border color.
* @see setBorderColor()
* @see outlineStyle()
* @see penJoinStyle()
*/
QColor borderColor() const;
/** Sets the marker's border color.
* @param color border color
* @see borderColor()
* @see setOutlineStyle()
* @see setPenJoinStyle()
*/
void setBorderColor( const QColor& color );
/** Returns the marker's outline style (eg solid, dashed, etc)
* @note added in 2.4
* @see setOutlineStyle()
* @see borderColor()
* @see penJoinStyle()
*/
Qt::PenStyle outlineStyle() const;
/** Sets the marker's outline style (eg solid, dashed, etc)
* @param outlineStyle style
* @note added in 2.4
* @see outlineStyle()
* @see setBorderColor()
* @see setPenJoinStyle()
*/
void setOutlineStyle( Qt::PenStyle outlineStyle );
/** Returns the marker's outline join style (eg miter, bevel, etc).
* @note added in 2.16
* @see setPenJoinStyle()
* @see borderColor()
* @see outlineStyle()
*/
Qt::PenJoinStyle penJoinStyle() const;
/** Sets the marker's outline join style (eg miter, bevel, etc).
* @param style join style
* @note added in 2.16
* @see penJoinStyle()
* @see setBorderColor()
* @see setOutlineStyle()
*/
void setPenJoinStyle( Qt::PenJoinStyle style );
/** Returns the width of the marker's outline.
* @see setOutlineWidth()
* @see outlineWidthUnit()
* @see outlineWidthMapUnitScale()
*/
double outlineWidth() const;
/** Sets the width of the marker's outline.
* @param w outline width. See outlineWidthUnit() for units.
* @see outlineWidth()
* @see setOutlineWidthUnit()
* @see setOutlineWidthMapUnitScale()
*/
void setOutlineWidth( double w );
/** Sets the unit for the width of the marker's outline.
* @param u outline width unit
* @see outlineWidthUnit()
* @see setOutlineWidth()
* @see setOutlineWidthMapUnitScale()
*/
void setOutlineWidthUnit( QgsSymbolV2::OutputUnit u );
/** Returns the unit for the width of the marker's outline.
* @see setOutlineWidthUnit()
* @see outlineWidth()
* @see outlineWidthMapUnitScale()
*/
QgsSymbolV2::OutputUnit outlineWidthUnit() const;
/** Sets the map scale for the width of the marker's outline.
* @param scale outline width map unit scale
* @see outlineWidthMapUnitScale()
* @see setOutlineWidth()
* @see setOutlineWidthUnit()
*/
void setOutlineWidthMapUnitScale( const QgsMapUnitScale& scale );
/** Returns the map scale for the width of the marker's outline.
* @see setOutlineWidthMapUnitScale()
* @see outlineWidth()
* @see outlineWidthUnit()
*/
const QgsMapUnitScale& outlineWidthMapUnitScale() const;
protected:
/** Draws the marker shape in the specified painter.
* @param p destination QPainter
* @param context symbol context
* @note this method does not handle setting the painter pen or brush to match the symbol's fill or outline
*/
void drawMarker( QPainter* p, QgsSymbolV2RenderContext& context );
bool prepareShape( const QString& name = QString() );
bool prepareShape( const QString& name, QPolygonF &polygon ) const;
bool preparePath( QString name = QString() );
//! @deprecated will be removed in QGIS 3.0
bool prepareShape( const QString& name = QString() ) /Deprecated/;
//! @deprecated will be removed in QGIS 3.0
bool prepareShape( const QString& name, QPolygonF &polygon ) const /Deprecated/;
//! @deprecated will be removed in QGIS 3.0
bool preparePath( QString name = QString() ) /Deprecated/;
/** Prepares cache image
@return true in case of success, false if cache image size too large*/
* @returns true in case of success, false if cache image size too large
*/
bool prepareCache( QgsSymbolV2RenderContext& context );
private:
virtual void draw( QgsSymbolV2RenderContext& context, Shape shape, const QPolygonF& polygon, const QPainterPath& path );
};
/** \ingroup core
* \class QgsFilledMarkerSymbolLayer
* \brief Filled marker symbol layer, consisting of a shape which is rendered using a QgsFillSymbolV2. This allows
* the symbol to support advanced styling of the interior and outline of the shape.
* \note Added in version 2.16
*/
class QgsFilledMarkerSymbolLayer : QgsSimpleMarkerSymbolLayerBase
{
%TypeHeaderCode
#include <qgsmarkersymbollayerv2.h>
%End
public:
/** Constructor for QgsFilledMarkerSymbolLayer.
* @param shape symbol shape
* @param size symbol size (in mm)
* @param angle symbol rotation angle
* @param scaleMethod size scaling method
*/
QgsFilledMarkerSymbolLayer( Shape shape = Circle,
double size = DEFAULT_SIMPLEMARKER_SIZE,
double angle = DEFAULT_SIMPLEMARKER_ANGLE,
QgsSymbolV2::ScaleMethod scaleMethod = DEFAULT_SCALE_METHOD );
/** Creates a new QgsFilledMarkerSymbolLayer.
* @param properties a property map containing symbol properties (see properties())
* @returns new QgsFilledMarkerSymbolLayer
*/
static QgsSymbolLayerV2* create( const QgsStringMap& properties = QgsStringMap() ) /Factory/;
QString layerType() const;
void startRender( QgsSymbolV2RenderContext& context );
void stopRender( QgsSymbolV2RenderContext& context );
QgsStringMap properties() const;
virtual QgsFilledMarkerSymbolLayer* clone() const /Factory/;
virtual QgsSymbolV2* subSymbol();
virtual bool setSubSymbol( QgsSymbolV2* symbol /Transfer/ );
virtual double estimateMaxBleed() const;
QSet<QString> usedAttributes() const;
void setColor( const QColor& c );
virtual QColor color() const;
private:
virtual void draw( QgsSymbolV2RenderContext& context, Shape shape, const QPolygonF& polygon, const QPainterPath& path );
QgsFilledMarkerSymbolLayer( const QgsFilledMarkerSymbolLayer& );
};
class QgsSvgMarkerSymbolLayerV2 : QgsMarkerSymbolLayerV2
{
%TypeHeaderCode

View File

@ -15,6 +15,8 @@ class QgsSymbolLayerV2
sipType = sipType_QgsFontMarkerSymbolLayerV2;
else if (dynamic_cast<QgsSimpleMarkerSymbolLayerV2*>(sipCpp) != NULL)
sipType = sipType_QgsSimpleMarkerSymbolLayerV2;
else if (dynamic_cast<QgsFilledMarkerSymbolLayer*>(sipCpp) != NULL)
sipType = sipType_QgsFilledMarkerSymbolLayer;
else if (dynamic_cast<QgsSvgMarkerSymbolLayerV2*>(sipCpp) != NULL)
sipType = sipType_QgsSvgMarkerSymbolLayerV2;
else if (dynamic_cast<QgsVectorFieldSymbolLayer*>(sipCpp) != NULL)
@ -28,6 +30,8 @@ class QgsSymbolLayerV2
sipType = sipType_QgsMarkerLineSymbolLayerV2;
else if (dynamic_cast<QgsSimpleLineSymbolLayerV2*>(sipCpp) != NULL)
sipType = sipType_QgsSimpleLineSymbolLayerV2;
else if (dynamic_cast<QgsArrowSymbolLayer*>(sipCpp) != NULL)
sipType = sipType_QgsArrowSymbolLayer;
else
sipType = sipType_QgsLineSymbolLayerV2;
break;
@ -330,6 +334,10 @@ class QgsSymbolLayerV2
//////////////////////
/** \ingroup core
* \class QgsMarkerSymbolLayerV2
* \brief Abstract base class for marker symbol layers.
*/
class QgsMarkerSymbolLayerV2 : QgsSymbolLayerV2
{
%TypeHeaderCode
@ -337,74 +345,203 @@ class QgsMarkerSymbolLayerV2 : QgsSymbolLayerV2
%End
public:
//! Symbol horizontal anchor points
enum HorizontalAnchorPoint
{
Left,
HCenter,
Right
Left, /*!< Align to left side of symbol */
HCenter, /*!< Align to horizontal center of symbol */
Right, /*!< Align to right side of symbol */
};
//! Symbol vertical anchor points
enum VerticalAnchorPoint
{
Top,
VCenter,
Bottom
Top, /*!< Align to top of symbol */
VCenter, /*!< Align to vertical center of symbol */
Bottom, /*!< Align to bottom of symbol */
};
void startRender( QgsSymbolV2RenderContext& context );
/** Renders a marker at the specified point. Derived classes must implement this to
* handle drawing the point.
* @param point position at which to render point, in painter units
* @param context symbol render context
*/
virtual void renderPoint( QPointF point, QgsSymbolV2RenderContext& context ) = 0;
void drawPreviewIcon( QgsSymbolV2RenderContext& context, QSize size );
/** Sets the rotation angle for the marker.
* @param angle angle in degrees clockwise from north.
* @see angle()
* @see setLineAngle()
*/
void setAngle( double angle );
/** Returns the rotation angle for the marker, in degrees clockwise from north.
* @see setAngle()
*/
double angle() const;
/** Sets the line angle modification for the symbol's angle. This angle is added to
* the marker's rotation and data defined rotation before rendering the symbol, and
* is usually used for orienting symbols to match a line's angle.
* @param lineAngle Angle in degrees, valid values are between 0 and 360
* @param lineAngle Angle in degrees clockwise from north, valid values are between 0 and 360
* @note added in QGIS 2.9
* @see setAngle()
* @see angle()
*/
void setLineAngle( double lineAngle );
/** Sets the symbol size.
* @param size symbol size. Units are specified by sizeUnit().
* @see size()
* @see setSizeUnit()
* @see setSizeMapUnitScale()
*/
void setSize( double size );
/** Returns the symbol size. Units are specified by sizeUnit().
* @see setSize()
* @see sizeUnit()
* @see sizeUnitMapScale()
*/
double size() const;
/** Sets the units for the symbol's size.
* @param unit size units
* @see sizeUnit()
* @see setSize()
* @see setSizeMapUnitScale()
*/
void setSizeUnit( QgsSymbolV2::OutputUnit unit );
/** Returns the units for the symbol's size.
* @see setSizeUnit()
* @see size()
* @see sizeMapUnitScale()
*/
QgsSymbolV2::OutputUnit sizeUnit() const;
/** Sets the map unit scale for the symbol's size.
* @param scale size map unit scale
* @see sizeMapUnitScale()
* @see setSize()
* @see setSizeUnit()
*/
void setSizeMapUnitScale( const QgsMapUnitScale& scale);
/** Returns the map unit scale for the symbol's size.
* @see setSizeMapUnitScale()
* @see size()
* @see sizeUnit()
*/
const QgsMapUnitScale& sizeMapUnitScale() const;
/** Sets the method to use for scaling the marker's size.
* @param scaleMethod scale method
* @see scaleMethod()
*/
void setScaleMethod( QgsSymbolV2::ScaleMethod scaleMethod );
/** Returns the method to use for scaling the marker's size.
* @see setScaleMethod()
*/
QgsSymbolV2::ScaleMethod scaleMethod() const;
/** Sets the marker's offset, which is the horizontal and vertical displacement which the rendered marker
* should have from the original feature's geometry.
* @param offset marker offset. Units are specified by offsetUnit()
* @see offset()
* @see setOffsetUnit()
* @see setOffsetMapUnitScale()
*/
void setOffset( QPointF offset );
/** Returns the marker's offset, which is the horizontal and vertical displacement which the rendered marker
* will have from the original feature's geometry. Units are specified by offsetUnit().
* @see setOffset()
* @see offsetUnit()
* @see offsetMapUnitScale()
*/
QPointF offset();
/** Sets the units for the symbol's offset.
* @param unit offset units
* @see offsetUnit()
* @see setOffset()
* @see setOffsetMapUnitScale()
*/
void setOffsetUnit( QgsSymbolV2::OutputUnit unit );
/** Returns the units for the symbol's offset.
* @see setOffsetUnit()
* @see offset()
* @see offsetMapUnitScale()
*/
QgsSymbolV2::OutputUnit offsetUnit() const;
/** Sets the map unit scale for the symbol's offset.
* @param scale offset map unit scale
* @see offsetMapUnitScale()
* @see setOffset()
* @see setOffsetUnit()
*/
void setOffsetMapUnitScale( const QgsMapUnitScale& scale);
/** Returns the map unit scale for the symbol's offset.
* @see setOffsetMapUnitScale()
* @see offset()
* @see offsetUnit()
*/
const QgsMapUnitScale& offsetMapUnitScale() const;
/** Sets the horizontal anchor point for positioning the symbol.
* @param h anchor point. Symbol will be drawn so that the horizontal anchor point is aligned with
* the marker's desired location.
* @see horizontalAnchorPoint()
* @see setVerticalAnchorPoint()
*/
void setHorizontalAnchorPoint( HorizontalAnchorPoint h );
/** Returns the horizontal anchor point for positioning the symbol. The symbol will be drawn so that
* the horizontal anchor point is aligned with the marker's desired location.
* @see setHorizontalAnchorPoint()
* @see verticalAnchorPoint()
*/
HorizontalAnchorPoint horizontalAnchorPoint() const;
/** Sets the vertical anchor point for positioning the symbol.
* @param v anchor point. Symbol will be drawn so that the vertical anchor point is aligned with
* the marker's desired location.
* @see verticalAnchorPoint()
* @see setHorizontalAnchorPoint()
*/
void setVerticalAnchorPoint( VerticalAnchorPoint v );
/** Returns the vertical anchor point for positioning the symbol. The symbol will be drawn so that
* the vertical anchor point is aligned with the marker's desired location.
* @see setVerticalAnchorPoint()
* @see horizontalAnchorPoint()
*/
VerticalAnchorPoint verticalAnchorPoint() const;
virtual void toSld( QDomDocument &doc, QDomElement &element, const QgsStringMap& props ) const;
/** Writes the symbol layer definition as a SLD XML element.
* @param doc XML document
* @param element parent XML element
* @param props symbol layer definition (see properties())
*/
virtual void writeSldMarker( QDomDocument &doc, QDomElement &element, const QgsStringMap& props ) const;
void setOffsetUnit( QgsSymbolV2::OutputUnit unit );
QgsSymbolV2::OutputUnit offsetUnit() const;
void setOffsetMapUnitScale( const QgsMapUnitScale& scale);
const QgsMapUnitScale& offsetMapUnitScale() const;
void setSizeUnit( QgsSymbolV2::OutputUnit unit );
QgsSymbolV2::OutputUnit sizeUnit() const;
void setSizeMapUnitScale( const QgsMapUnitScale& scale);
const QgsMapUnitScale& sizeMapUnitScale() const;
void setOutputUnit( QgsSymbolV2::OutputUnit unit );
QgsSymbolV2::OutputUnit outputUnit() const;
void setMapUnitScale( const QgsMapUnitScale& scale );
QgsMapUnitScale mapUnitScale() const;
void setHorizontalAnchorPoint( HorizontalAnchorPoint h );
HorizontalAnchorPoint horizontalAnchorPoint() const;
void setVerticalAnchorPoint( VerticalAnchorPoint v );
VerticalAnchorPoint verticalAnchorPoint() const;
/** Returns the approximate bounding box of the marker symbol layer, taking into account
* any data defined overrides and offsets which are set for the marker layer.
* @returns approximate symbol bounds, in painter units
@ -415,12 +552,29 @@ class QgsMarkerSymbolLayerV2 : QgsSymbolLayerV2
virtual QRectF bounds( QPointF point, QgsSymbolV2RenderContext& context );
protected:
/** Constructor for QgsMarkerSymbolLayerV2.
* @param locked set to true to lock symbol color
*/
QgsMarkerSymbolLayerV2( bool locked = false );
//handles marker offset and anchor point shift together
/** Calculates the required marker offset, including both the symbol offset
* and any displacement required to align with the marker's anchor point.
* @param context symbol render context
* @param offsetX will be set to required horizontal offset (in painter units)
* @param offsetY will be set to required vertical offset (in painter units)
*/
void markerOffset( QgsSymbolV2RenderContext& context, double& offsetX, double& offsetY ) const;
//! @note available in python as markerOffsetWithWidthAndHeight
/** Calculates the required marker offset, including both the symbol offset
* and any displacement required to align with the marker's anchor point.
* @param context symbol render context
* @param width marker width
* @param height marker height
* @param offsetX will be set to required horizontal offset (in painter units)
* @param offsetY will be set to required vertical offset (in painter units)
* @note available in python as markerOffsetWithWidthAndHeight
*/
void markerOffset( QgsSymbolV2RenderContext& context, double width, double height, double& offsetX, double& offsetY ) const /PyName=markerOffsetWithWidthAndHeight/;
//! @note available in python bindings as markerOffset2
@ -429,6 +583,11 @@ class QgsMarkerSymbolLayerV2 : QgsSymbolLayerV2
double& offsetX, double& offsetY,
const QgsMapUnitScale &widthMapUnitScale, const QgsMapUnitScale &heightMapUnitScale ) const /PyName=markerOffset2/;
/** Adjusts a marker offset to account for rotation.
* @param offset offset prior to rotation
* @param angle rotation angle in degrees clockwise from north
* @return adjusted offset
*/
static QPointF _rotatedOffset( QPointF offset, double angle );
};

View File

@ -178,6 +178,41 @@ class QgsSimpleFillSymbolLayerV2Widget : QgsSymbolLayerV2Widget
///////////
/** \ingroup gui
* \class QgsFilledMarkerSymbolLayerWidget
* \brief Widget for configuring QgsFilledMarkerSymbolLayer symbol layers.
* \note Added in version 2.16
*/
class QgsFilledMarkerSymbolLayerWidget : QgsSymbolLayerV2Widget
{
%TypeHeaderCode
#include <qgssymbollayerv2widget.h>
%End
public:
/** Constructor for QgsFilledMarkerSymbolLayerWidget.
* @param vl associated vector layer
* @param parent parent widget
*/
QgsFilledMarkerSymbolLayerWidget( const QgsVectorLayer* vl, QWidget* parent /TransferThis/ = nullptr );
~QgsFilledMarkerSymbolLayerWidget();
/** Creates a new QgsFilledMarkerSymbolLayerWidget.
* @param vl associated vector layer
*/
static QgsSymbolLayerV2Widget* create( const QgsVectorLayer* vl ) /Factory/;
// from base class
virtual void setSymbolLayer( QgsSymbolLayerV2* layer );
virtual QgsSymbolLayerV2* symbolLayer();
};
///////////
class QgsGradientFillSymbolLayerV2Widget : QgsSymbolLayerV2Widget
{
%TypeHeaderCode

View File

@ -153,8 +153,7 @@ void QgsDecorationGrid::projectRead()
{
// set default symbol : cross with width=3
QgsSymbolLayerV2List symbolList;
symbolList << new QgsSimpleMarkerSymbolLayerV2( "cross", DEFAULT_SIMPLEMARKER_COLOR,
DEFAULT_SIMPLEMARKER_BORDERCOLOR, 3, 0 );
symbolList << new QgsSimpleMarkerSymbolLayerV2( QgsSimpleMarkerSymbolLayerBase::Cross, 3, 0 );
mMarkerSymbol = new QgsMarkerSymbolV2( symbolList );
// mMarkerSymbol = new QgsMarkerSymbolV2();
}

File diff suppressed because it is too large Load Diff

View File

@ -32,7 +32,158 @@
#include <QPolygonF>
#include <QFont>
class CORE_EXPORT QgsSimpleMarkerSymbolLayerV2 : public QgsMarkerSymbolLayerV2
/** \ingroup core
* \class QgsSimpleMarkerSymbolLayerBase
* \brief Abstract base class for simple marker symbol layers. Handles creation of the symbol shapes but
* leaves the actual drawing of the symbols to subclasses.
* \note Added in version 2.16
*/
class CORE_EXPORT QgsSimpleMarkerSymbolLayerBase : public QgsMarkerSymbolLayerV2
{
public:
//! Marker symbol shapes
enum Shape
{
Square, /*!< Square */
Diamond, /*!< Diamond */
Pentagon, /*!< Pentagon */
Hexagon, /*!< Hexagon */
Triangle, /*!< Triangle */
EquilateralTriangle, /*!< Equilateral triangle*/
Star, /*!< Star*/
Arrow, /*!< Arrow*/
Circle, /*!< Circle*/
Cross, /*!< Cross (lines only)*/
CrossFill, /*!< Solid filled cross*/
Cross2, /*!< Rotated cross (lines only), "x" shape*/
Line, /*!< Vertical line*/
ArrowHead, /*!< Right facing arrow head (unfilled, lines only)*/
ArrowHeadFilled, /*!< Right facing filled arrow head*/
SemiCircle, /*!< Semi circle (top half)*/
ThirdCircle, /*!< One third circle (top left third)*/
QuarterCircle, /*!< Quarter circle (top left quarter)*/
QuarterSquare, /*!< Quarter square (top left quarter)*/
HalfSquare, /*!< Half square (left half)*/
DiagonalHalfSquare, /*!< Diagonal half square (bottom left half)*/
RightHalfTriangle, /*!< Right half of triangle*/
LeftHalfTriangle, /*!< Left half of triangle*/
};
//! Returns a list of all available shape types.
static QList< Shape > availableShapes();
/** Returns true if a symbol shape has a fill.
* @param shape shape to test
* @returns true if shape uses a fill, or false if shape uses lines only
*/
static bool shapeIsFilled( Shape shape );
/** Constructor for QgsSimpleMarkerSymbolLayerBase.
* @param shape symbol shape for markers
* @param size symbol size (in mm)
* @param angle symbol rotation angle
* @param scaleMethod scaling method for data defined scaling
*/
QgsSimpleMarkerSymbolLayerBase( Shape shape = Circle,
double size = DEFAULT_SIMPLEMARKER_SIZE,
double angle = DEFAULT_SIMPLEMARKER_ANGLE,
QgsSymbolV2::ScaleMethod scaleMethod = DEFAULT_SCALE_METHOD );
/** Returns the shape for the rendered marker symbol.
* @see setShape()
*/
Shape shape() const { return mShape; }
/** Sets the rendered marker shape.
* @param shape new marker shape
* @see shape()
*/
void setShape( Shape shape ) { mShape = shape; }
/** Attempts to decode a string representation of a shape name to the corresponding
* shape.
* @param name encoded shape name
* @param ok if specified, will be set to true if shape was successfully decoded
* @return decoded name
* @see encodeShape()
*/
static Shape decodeShape( const QString& name, bool* ok = nullptr );
/** Encodes a shape to its string representation.
* @param shape shape to encode
* @returns encoded string
* @see decodeShape()
*/
static QString encodeShape( Shape shape );
void startRender( QgsSymbolV2RenderContext& context ) override;
void stopRender( QgsSymbolV2RenderContext& context ) override;
void renderPoint( QPointF point, QgsSymbolV2RenderContext& context ) override;
QRectF bounds( QPointF point, QgsSymbolV2RenderContext& context ) override;
protected:
//! Prepares the layer for drawing the specified shape (QPolygonF version)
//! @note not available in Python bindings
bool prepareMarkerShape( Shape shape );
//! Prepares the layer for drawing the specified shape (QPainterPath version)
//! @note not available in Python bindings
bool prepareMarkerPath( Shape symbol );
/** Creates a polygon representing the specified shape.
* @param shape shape to create
* @param polygon destination polygon for shape
* @returns true if shape was successfully stored in polygon
* @note not available in Python bindings
*/
bool shapeToPolygon( Shape shape, QPolygonF &polygon ) const;
/** Calculates the desired size of the marker, considering data defined size overrides.
* @param context symbol render context
* @param hasDataDefinedSize will be set to true if marker uses data defined sizes
* @returns marker size, in original size units
* @note not available in Python bindings
*/
double calculateSize( QgsSymbolV2RenderContext& context, bool& hasDataDefinedSize ) const;
/** Calculates the marker offset and rotation.
* @param context symbol render context
* @param scaledSize size of symbol to render
* @param hasDataDefinedRotation will be set to true if marker has data defined rotation
* @param offset will be set to calculated marker offset (in painter units)
* @param angle will be set to calculated marker angle
* @note not available in Python bindings
*/
void calculateOffsetAndRotation( QgsSymbolV2RenderContext& context, double scaledSize, bool& hasDataDefinedRotation, QPointF& offset, double& angle ) const;
//! Polygon of points in shape. If polygon is empty then shape is using mPath.
QPolygonF mPolygon;
//! Painter path representing shape. If mPolygon is empty then the shape is stored in mPath.
QPainterPath mPath;
//! Symbol shape
Shape mShape;
private:
/** Derived classes must implement draw() to handle drawing the generated shape onto the painter surface.
* @param context symbol render context
* @param shape shape to draw
* @param polygon polygon representing transformed marker shape. May be empty, in which case the shape will be specified
* in the path argument.
* @param path transformed painter path representing shape to draw
*/
virtual void draw( QgsSymbolV2RenderContext& context, Shape shape, const QPolygonF& polygon, const QPainterPath& path ) = 0;
};
/** \ingroup core
* \class QgsSimpleMarkerSymbolLayerV2
* \brief Simple marker symbol layer, consisting of a rendered shape with solid fill color and an outline.
*/
class CORE_EXPORT QgsSimpleMarkerSymbolLayerV2 : public QgsSimpleMarkerSymbolLayerBase
{
public:
@ -48,127 +199,274 @@ class CORE_EXPORT QgsSimpleMarkerSymbolLayerV2 : public QgsMarkerSymbolLayerV2
* @param angle symbol rotation angle
* @param scaleMethod scaling method for data defined scaling
* @param penJoinStyle join style for outline pen
* @deprecated use variant which accepts QgsSimpleMarkerSymbolLayerBase::Shape instead
*/
QgsSimpleMarkerSymbolLayerV2( const QString& name = DEFAULT_SIMPLEMARKER_NAME,
const QColor& color = DEFAULT_SIMPLEMARKER_COLOR,
const QColor& borderColor = DEFAULT_SIMPLEMARKER_BORDERCOLOR,
Q_DECL_DEPRECATED QgsSimpleMarkerSymbolLayerV2( const QString& name,
const QColor& color = DEFAULT_SIMPLEMARKER_COLOR,
const QColor& borderColor = DEFAULT_SIMPLEMARKER_BORDERCOLOR,
double size = DEFAULT_SIMPLEMARKER_SIZE,
double angle = DEFAULT_SIMPLEMARKER_ANGLE,
QgsSymbolV2::ScaleMethod scaleMethod = DEFAULT_SCALE_METHOD,
Qt::PenJoinStyle penJoinStyle = DEFAULT_SIMPLEMARKER_JOINSTYLE );
/** Constructor for QgsSimpleMarkerSymbolLayerV2.
* @param shape symbol shape
* @param size symbol size (in mm)
* @param angle symbol rotation angle
* @param scaleMethod scaling method for data defined scaling
* @param color fill color for symbol
* @param borderColor border color for symbol
* @param penJoinStyle join style for outline pen
*/
QgsSimpleMarkerSymbolLayerV2( Shape shape = Circle,
double size = DEFAULT_SIMPLEMARKER_SIZE,
double angle = DEFAULT_SIMPLEMARKER_ANGLE,
QgsSymbolV2::ScaleMethod scaleMethod = DEFAULT_SCALE_METHOD,
const QColor& color = DEFAULT_SIMPLEMARKER_COLOR,
const QColor& borderColor = DEFAULT_SIMPLEMARKER_BORDERCOLOR,
Qt::PenJoinStyle penJoinStyle = DEFAULT_SIMPLEMARKER_JOINSTYLE );
// static stuff
// static methods
/** Creates a new QgsSimpleMarkerSymbolLayerV2.
* @param properties a property map containing symbol properties (see properties())
* @returns new QgsSimpleMarkerSymbolLayerV2
*/
static QgsSymbolLayerV2* create( const QgsStringMap& properties = QgsStringMap() );
/** Creates a new QgsSimpleMarkerSymbolLayerV2 from an SLD XML element.
* @param element XML element containing SLD definition of symbol
* @returns new QgsSimpleMarkerSymbolLayerV2
*/
static QgsSymbolLayerV2* createFromSld( QDomElement &element );
// implemented from base classes
// reimplemented from base classes
QString layerType() const override;
void startRender( QgsSymbolV2RenderContext& context ) override;
void stopRender( QgsSymbolV2RenderContext& context ) override;
void renderPoint( QPointF point, QgsSymbolV2RenderContext& context ) override;
QgsStringMap properties() const override;
QgsSimpleMarkerSymbolLayerV2* clone() const override;
void writeSldMarker( QDomDocument &doc, QDomElement &element, const QgsStringMap& props ) const override;
QString ogrFeatureStyle( double mmScaleFactor, double mapUnitScaleFactor ) const override;
QString name() const { return mName; }
void setName( const QString& name ) { mName = name; }
QColor borderColor() const { return mBorderColor; }
void setBorderColor( const QColor& color ) { mBorderColor = color; }
/** Get outline join style.
* @note added in 2.4 */
Qt::PenStyle outlineStyle() const { return mOutlineStyle; }
/** Set outline join style.
* @note added in 2.4 */
void setOutlineStyle( Qt::PenStyle outlineStyle ) { mOutlineStyle = outlineStyle; }
/** Get outline join style.
* @note added in 2.16 */
Qt::PenJoinStyle penJoinStyle() const { return mPenJoinStyle; }
/** Set outline join style.
* @note added in 2.16 */
void setPenJoinStyle( Qt::PenJoinStyle style ) { mPenJoinStyle = style; }
/** Get outline color.
* @note added in 2.1 */
QColor outlineColor() const override { return borderColor(); }
/** Set outline color.
* @note added in 2.1 */
void setOutlineColor( const QColor& color ) override { setBorderColor( color ); }
/** Get fill color.
* @note added in 2.1 */
QColor fillColor() const override { return color(); }
/** Set fill color.
* @note added in 2.1 */
void setFillColor( const QColor& color ) override { setColor( color ); }
double outlineWidth() const { return mOutlineWidth; }
void setOutlineWidth( double w ) { mOutlineWidth = w; }
void setOutlineWidthUnit( QgsSymbolV2::OutputUnit u ) { mOutlineWidthUnit = u; }
QgsSymbolV2::OutputUnit outlineWidthUnit() const { return mOutlineWidthUnit; }
void setOutlineWidthMapUnitScale( const QgsMapUnitScale& scale ) { mOutlineWidthMapUnitScale = scale; }
const QgsMapUnitScale& outlineWidthMapUnitScale() const { return mOutlineWidthMapUnitScale; }
bool writeDxf( QgsDxfExport &e, double mmMapUnitScaleFactor, const QString &layerName, QgsSymbolV2RenderContext &context, QPointF shift = QPointF( 0.0, 0.0 ) ) const override;
void setOutputUnit( QgsSymbolV2::OutputUnit unit ) override;
QgsSymbolV2::OutputUnit outputUnit() const override;
void setMapUnitScale( const QgsMapUnitScale& scale ) override;
QgsMapUnitScale mapUnitScale() const override;
QRectF bounds( QPointF point, QgsSymbolV2RenderContext& context ) override;
QColor outlineColor() const override { return borderColor(); }
void setOutlineColor( const QColor& color ) override { setBorderColor( color ); }
QColor fillColor() const override { return color(); }
void setFillColor( const QColor& color ) override { setColor( color ); }
// new methods
//! @deprecated use shape() instead
Q_DECL_DEPRECATED QString name() const { return encodeShape( mShape ); }
//! @deprecated use setShape() instead
Q_DECL_DEPRECATED void setName( const QString& name ) { mName = name; mShape = decodeShape( name ); }
/** Returns the marker's border color.
* @see setBorderColor()
* @see outlineStyle()
* @see penJoinStyle()
*/
QColor borderColor() const { return mBorderColor; }
/** Sets the marker's border color.
* @param color border color
* @see borderColor()
* @see setOutlineStyle()
* @see setPenJoinStyle()
*/
void setBorderColor( const QColor& color ) { mBorderColor = color; }
/** Returns the marker's outline style (eg solid, dashed, etc)
* @note added in 2.4
* @see setOutlineStyle()
* @see borderColor()
* @see penJoinStyle()
*/
Qt::PenStyle outlineStyle() const { return mOutlineStyle; }
/** Sets the marker's outline style (eg solid, dashed, etc)
* @param outlineStyle style
* @note added in 2.4
* @see outlineStyle()
* @see setBorderColor()
* @see setPenJoinStyle()
*/
void setOutlineStyle( Qt::PenStyle outlineStyle ) { mOutlineStyle = outlineStyle; }
/** Returns the marker's outline join style (eg miter, bevel, etc).
* @note added in 2.16
* @see setPenJoinStyle()
* @see borderColor()
* @see outlineStyle()
*/
Qt::PenJoinStyle penJoinStyle() const { return mPenJoinStyle; }
/** Sets the marker's outline join style (eg miter, bevel, etc).
* @param style join style
* @note added in 2.16
* @see penJoinStyle()
* @see setBorderColor()
* @see setOutlineStyle()
*/
void setPenJoinStyle( Qt::PenJoinStyle style ) { mPenJoinStyle = style; }
/** Returns the width of the marker's outline.
* @see setOutlineWidth()
* @see outlineWidthUnit()
* @see outlineWidthMapUnitScale()
*/
double outlineWidth() const { return mOutlineWidth; }
/** Sets the width of the marker's outline.
* @param w outline width. See outlineWidthUnit() for units.
* @see outlineWidth()
* @see setOutlineWidthUnit()
* @see setOutlineWidthMapUnitScale()
*/
void setOutlineWidth( double w ) { mOutlineWidth = w; }
/** Sets the unit for the width of the marker's outline.
* @param u outline width unit
* @see outlineWidthUnit()
* @see setOutlineWidth()
* @see setOutlineWidthMapUnitScale()
*/
void setOutlineWidthUnit( QgsSymbolV2::OutputUnit u ) { mOutlineWidthUnit = u; }
/** Returns the unit for the width of the marker's outline.
* @see setOutlineWidthUnit()
* @see outlineWidth()
* @see outlineWidthMapUnitScale()
*/
QgsSymbolV2::OutputUnit outlineWidthUnit() const { return mOutlineWidthUnit; }
/** Sets the map scale for the width of the marker's outline.
* @param scale outline width map unit scale
* @see outlineWidthMapUnitScale()
* @see setOutlineWidth()
* @see setOutlineWidthUnit()
*/
void setOutlineWidthMapUnitScale( const QgsMapUnitScale& scale ) { mOutlineWidthMapUnitScale = scale; }
/** Returns the map scale for the width of the marker's outline.
* @see setOutlineWidthMapUnitScale()
* @see outlineWidth()
* @see outlineWidthUnit()
*/
const QgsMapUnitScale& outlineWidthMapUnitScale() const { return mOutlineWidthMapUnitScale; }
protected:
/** Draws the marker shape in the specified painter.
* @param p destination QPainter
* @param context symbol context
* @note this method does not handle setting the painter pen or brush to match the symbol's fill or outline
*/
void drawMarker( QPainter* p, QgsSymbolV2RenderContext& context );
bool prepareShape( const QString& name = QString() );
bool prepareShape( const QString& name, QPolygonF &polygon ) const;
bool preparePath( QString name = QString() );
//! @deprecated will be removed in QGIS 3.0
Q_DECL_DEPRECATED bool prepareShape( const QString& name = QString() );
//! @deprecated will be removed in QGIS 3.0
Q_DECL_DEPRECATED bool prepareShape( const QString& name, QPolygonF &polygon ) const;
//! @deprecated will be removed in QGIS 3.0
Q_DECL_DEPRECATED bool preparePath( QString name = QString() );
/** Prepares cache image
@return true in case of success, false if cache image size too large*/
* @returns true in case of success, false if cache image size too large
*/
bool prepareCache( QgsSymbolV2RenderContext& context );
//! Outline color
QColor mBorderColor;
//! Outline style
Qt::PenStyle mOutlineStyle;
//! Outline width
double mOutlineWidth;
//! Outline width units
QgsSymbolV2::OutputUnit mOutlineWidthUnit;
//! Outline width map unit scale
QgsMapUnitScale mOutlineWidthMapUnitScale;
//! Outline pen join style
Qt::PenJoinStyle mPenJoinStyle;
//! QPen corresponding to marker's outline style
QPen mPen;
//! QBrush corresponding to marker's fill style
QBrush mBrush;
QPolygonF mPolygon;
QPainterPath mPath;
QString mName;
QImage mCache;
QPen mSelPen;
QBrush mSelBrush;
QImage mSelCache;
bool mUsingCache;
//Maximum width/height of cache image
//TODO QGIS 3.0 - remove
QString mName;
//! Cached image of marker, if using cached version
QImage mCache;
//! QPen to use as outline of selected symbols
QPen mSelPen;
//! QBrush to use as fill of selected symbols
QBrush mSelBrush;
//! Cached image of selected marker, if using cached version
QImage mSelCache;
//! True if using cached images of markers for drawing. This is faster, but cannot
//! be used when data defined properties are present
bool mUsingCache;
//! Maximum width/height of cache image
static const int mMaximumCacheWidth = 3000;
private:
double calculateSize( QgsSymbolV2RenderContext& context, bool& hasDataDefinedSize ) const;
void calculateOffsetAndRotation( QgsSymbolV2RenderContext& context, double scaledSize, bool& hasDataDefinedRotation, QPointF& offset, double& angle ) const;
bool symbolNeedsBrush( const QString& symbolName ) const;
virtual void draw( QgsSymbolV2RenderContext& context, Shape shape, const QPolygonF& polygon, const QPainterPath& path ) override;
};
/** \ingroup core
* \class QgsFilledMarkerSymbolLayer
* \brief Filled marker symbol layer, consisting of a shape which is rendered using a QgsFillSymbolV2. This allows
* the symbol to support advanced styling of the interior and outline of the shape.
* \note Added in version 2.16
*/
class CORE_EXPORT QgsFilledMarkerSymbolLayer : public QgsSimpleMarkerSymbolLayerBase
{
public:
/** Constructor for QgsFilledMarkerSymbolLayer.
* @param shape symbol shape
* @param size symbol size (in mm)
* @param angle symbol rotation angle
* @param scaleMethod size scaling method
*/
QgsFilledMarkerSymbolLayer( Shape shape = Circle,
double size = DEFAULT_SIMPLEMARKER_SIZE,
double angle = DEFAULT_SIMPLEMARKER_ANGLE,
QgsSymbolV2::ScaleMethod scaleMethod = DEFAULT_SCALE_METHOD );
/** Creates a new QgsFilledMarkerSymbolLayer.
* @param properties a property map containing symbol properties (see properties())
* @returns new QgsFilledMarkerSymbolLayer
*/
static QgsSymbolLayerV2* create( const QgsStringMap& properties = QgsStringMap() );
QString layerType() const override;
void startRender( QgsSymbolV2RenderContext& context ) override;
void stopRender( QgsSymbolV2RenderContext& context ) override;
QgsStringMap properties() const override;
QgsFilledMarkerSymbolLayer* clone() const override;
virtual QgsSymbolV2* subSymbol() override;
virtual bool setSubSymbol( QgsSymbolV2* symbol ) override;
virtual double estimateMaxBleed() const override;
QSet<QString> usedAttributes() const override;
void setColor( const QColor& c ) override;
virtual QColor color() const override;
private:
virtual void draw( QgsSymbolV2RenderContext& context, Shape shape, const QPolygonF& polygon, const QPainterPath& path ) override;
//! Fill subsymbol
QScopedPointer< QgsFillSymbolV2 > mFill;
};
//////////

View File

@ -399,79 +399,211 @@ class CORE_EXPORT QgsSymbolLayerV2
//////////////////////
/** \ingroup core
* \class QgsMarkerSymbolLayerV2
* \brief Abstract base class for marker symbol layers.
*/
class CORE_EXPORT QgsMarkerSymbolLayerV2 : public QgsSymbolLayerV2
{
public:
//! Symbol horizontal anchor points
enum HorizontalAnchorPoint
{
Left,
HCenter,
Right
Left, /*!< Align to left side of symbol */
HCenter, /*!< Align to horizontal center of symbol */
Right, /*!< Align to right side of symbol */
};
//! Symbol vertical anchor points
enum VerticalAnchorPoint
{
Top,
VCenter,
Bottom
Top, /*!< Align to top of symbol */
VCenter, /*!< Align to vertical center of symbol */
Bottom, /*!< Align to bottom of symbol */
};
void startRender( QgsSymbolV2RenderContext& context ) override;
/** Renders a marker at the specified point. Derived classes must implement this to
* handle drawing the point.
* @param point position at which to render point, in painter units
* @param context symbol render context
*/
virtual void renderPoint( QPointF point, QgsSymbolV2RenderContext& context ) = 0;
void drawPreviewIcon( QgsSymbolV2RenderContext& context, QSize size ) override;
/** Sets the rotation angle for the marker.
* @param angle angle in degrees clockwise from north.
* @see angle()
* @see setLineAngle()
*/
void setAngle( double angle ) { mAngle = angle; }
/** Returns the rotation angle for the marker, in degrees clockwise from north.
* @see setAngle()
*/
double angle() const { return mAngle; }
/** Sets the line angle modification for the symbol's angle. This angle is added to
* the marker's rotation and data defined rotation before rendering the symbol, and
* is usually used for orienting symbols to match a line's angle.
* @param lineAngle Angle in degrees, valid values are between 0 and 360
* @param lineAngle Angle in degrees clockwise from north, valid values are between 0 and 360
* @note added in QGIS 2.9
* @see setAngle()
* @see angle()
*/
void setLineAngle( double lineAngle ) { mLineAngle = lineAngle; }
/** Sets the symbol size.
* @param size symbol size. Units are specified by sizeUnit().
* @see size()
* @see setSizeUnit()
* @see setSizeMapUnitScale()
*/
void setSize( double size ) { mSize = size; }
/** Returns the symbol size. Units are specified by sizeUnit().
* @see setSize()
* @see sizeUnit()
* @see sizeUnitMapScale()
*/
double size() const { return mSize; }
/** Sets the units for the symbol's size.
* @param unit size units
* @see sizeUnit()
* @see setSize()
* @see setSizeMapUnitScale()
*/
void setSizeUnit( QgsSymbolV2::OutputUnit unit ) { mSizeUnit = unit; }
/** Returns the units for the symbol's size.
* @see setSizeUnit()
* @see size()
* @see sizeMapUnitScale()
*/
QgsSymbolV2::OutputUnit sizeUnit() const { return mSizeUnit; }
/** Sets the map unit scale for the symbol's size.
* @param scale size map unit scale
* @see sizeMapUnitScale()
* @see setSize()
* @see setSizeUnit()
*/
void setSizeMapUnitScale( const QgsMapUnitScale& scale ) { mSizeMapUnitScale = scale; }
/** Returns the map unit scale for the symbol's size.
* @see setSizeMapUnitScale()
* @see size()
* @see sizeUnit()
*/
const QgsMapUnitScale& sizeMapUnitScale() const { return mSizeMapUnitScale; }
/** Sets the method to use for scaling the marker's size.
* @param scaleMethod scale method
* @see scaleMethod()
*/
void setScaleMethod( QgsSymbolV2::ScaleMethod scaleMethod ) { mScaleMethod = scaleMethod; }
/** Returns the method to use for scaling the marker's size.
* @see setScaleMethod()
*/
QgsSymbolV2::ScaleMethod scaleMethod() const { return mScaleMethod; }
/** Sets the marker's offset, which is the horizontal and vertical displacement which the rendered marker
* should have from the original feature's geometry.
* @param offset marker offset. Units are specified by offsetUnit()
* @see offset()
* @see setOffsetUnit()
* @see setOffsetMapUnitScale()
*/
void setOffset( QPointF offset ) { mOffset = offset; }
/** Returns the marker's offset, which is the horizontal and vertical displacement which the rendered marker
* will have from the original feature's geometry. Units are specified by offsetUnit().
* @see setOffset()
* @see offsetUnit()
* @see offsetMapUnitScale()
*/
QPointF offset() const { return mOffset; }
/** Sets the units for the symbol's offset.
* @param unit offset units
* @see offsetUnit()
* @see setOffset()
* @see setOffsetMapUnitScale()
*/
void setOffsetUnit( QgsSymbolV2::OutputUnit unit ) { mOffsetUnit = unit; }
/** Returns the units for the symbol's offset.
* @see setOffsetUnit()
* @see offset()
* @see offsetMapUnitScale()
*/
QgsSymbolV2::OutputUnit offsetUnit() const { return mOffsetUnit; }
/** Sets the map unit scale for the symbol's offset.
* @param scale offset map unit scale
* @see offsetMapUnitScale()
* @see setOffset()
* @see setOffsetUnit()
*/
void setOffsetMapUnitScale( const QgsMapUnitScale& scale ) { mOffsetMapUnitScale = scale; }
/** Returns the map unit scale for the symbol's offset.
* @see setOffsetMapUnitScale()
* @see offset()
* @see offsetUnit()
*/
const QgsMapUnitScale& offsetMapUnitScale() const { return mOffsetMapUnitScale; }
/** Sets the horizontal anchor point for positioning the symbol.
* @param h anchor point. Symbol will be drawn so that the horizontal anchor point is aligned with
* the marker's desired location.
* @see horizontalAnchorPoint()
* @see setVerticalAnchorPoint()
*/
void setHorizontalAnchorPoint( HorizontalAnchorPoint h ) { mHorizontalAnchorPoint = h; }
/** Returns the horizontal anchor point for positioning the symbol. The symbol will be drawn so that
* the horizontal anchor point is aligned with the marker's desired location.
* @see setHorizontalAnchorPoint()
* @see verticalAnchorPoint()
*/
HorizontalAnchorPoint horizontalAnchorPoint() const { return mHorizontalAnchorPoint; }
/** Sets the vertical anchor point for positioning the symbol.
* @param v anchor point. Symbol will be drawn so that the vertical anchor point is aligned with
* the marker's desired location.
* @see verticalAnchorPoint()
* @see setHorizontalAnchorPoint()
*/
void setVerticalAnchorPoint( VerticalAnchorPoint v ) { mVerticalAnchorPoint = v; }
/** Returns the vertical anchor point for positioning the symbol. The symbol will be drawn so that
* the vertical anchor point is aligned with the marker's desired location.
* @see setVerticalAnchorPoint()
* @see horizontalAnchorPoint()
*/
VerticalAnchorPoint verticalAnchorPoint() const { return mVerticalAnchorPoint; }
virtual void toSld( QDomDocument &doc, QDomElement &element, const QgsStringMap& props ) const override;
/** Writes the symbol layer definition as a SLD XML element.
* @param doc XML document
* @param element parent XML element
* @param props symbol layer definition (see properties())
*/
virtual void writeSldMarker( QDomDocument &doc, QDomElement &element, const QgsStringMap& props ) const
{ Q_UNUSED( props ); element.appendChild( doc.createComment( QString( "QgsMarkerSymbolLayerV2 %1 not implemented yet" ).arg( layerType() ) ) ); }
void setOffsetUnit( QgsSymbolV2::OutputUnit unit ) { mOffsetUnit = unit; }
QgsSymbolV2::OutputUnit offsetUnit() const { return mOffsetUnit; }
void setOffsetMapUnitScale( const QgsMapUnitScale& scale ) { mOffsetMapUnitScale = scale; }
const QgsMapUnitScale& offsetMapUnitScale() const { return mOffsetMapUnitScale; }
void setSizeUnit( QgsSymbolV2::OutputUnit unit ) { mSizeUnit = unit; }
QgsSymbolV2::OutputUnit sizeUnit() const { return mSizeUnit; }
void setSizeMapUnitScale( const QgsMapUnitScale& scale ) { mSizeMapUnitScale = scale; }
const QgsMapUnitScale& sizeMapUnitScale() const { return mSizeMapUnitScale; }
void setOutputUnit( QgsSymbolV2::OutputUnit unit ) override;
QgsSymbolV2::OutputUnit outputUnit() const override;
void setMapUnitScale( const QgsMapUnitScale& scale ) override;
QgsMapUnitScale mapUnitScale() const override;
void setHorizontalAnchorPoint( HorizontalAnchorPoint h ) { mHorizontalAnchorPoint = h; }
HorizontalAnchorPoint horizontalAnchorPoint() const { return mHorizontalAnchorPoint; }
void setVerticalAnchorPoint( VerticalAnchorPoint v ) { mVerticalAnchorPoint = v; }
VerticalAnchorPoint verticalAnchorPoint() const { return mVerticalAnchorPoint; }
/** Returns the approximate bounding box of the marker symbol layer, taking into account
* any data defined overrides and offsets which are set for the marker layer.
* @returns approximate symbol bounds, in painter units
@ -482,12 +614,29 @@ class CORE_EXPORT QgsMarkerSymbolLayerV2 : public QgsSymbolLayerV2
virtual QRectF bounds( QPointF point, QgsSymbolV2RenderContext& context ) { Q_UNUSED( context ); Q_UNUSED( point ); return QRectF(); }
protected:
/** Constructor for QgsMarkerSymbolLayerV2.
* @param locked set to true to lock symbol color
*/
QgsMarkerSymbolLayerV2( bool locked = false );
//handles marker offset and anchor point shift together
/** Calculates the required marker offset, including both the symbol offset
* and any displacement required to align with the marker's anchor point.
* @param context symbol render context
* @param offsetX will be set to required horizontal offset (in painter units)
* @param offsetY will be set to required vertical offset (in painter units)
*/
void markerOffset( QgsSymbolV2RenderContext& context, double& offsetX, double& offsetY ) const;
//! @note available in python as markerOffsetWithWidthAndHeight
/** Calculates the required marker offset, including both the symbol offset
* and any displacement required to align with the marker's anchor point.
* @param context symbol render context
* @param width marker width
* @param height marker height
* @param offsetX will be set to required horizontal offset (in painter units)
* @param offsetY will be set to required vertical offset (in painter units)
* @note available in python as markerOffsetWithWidthAndHeight
*/
void markerOffset( QgsSymbolV2RenderContext& context, double width, double height, double& offsetX, double& offsetY ) const;
//! @note available in python bindings as markerOffset2
@ -496,18 +645,34 @@ class CORE_EXPORT QgsMarkerSymbolLayerV2 : public QgsSymbolLayerV2
double& offsetX, double& offsetY,
const QgsMapUnitScale &widthMapUnitScale, const QgsMapUnitScale &heightMapUnitScale ) const;
/** Adjusts a marker offset to account for rotation.
* @param offset offset prior to rotation
* @param angle rotation angle in degrees clockwise from north
* @return adjusted offset
*/
static QPointF _rotatedOffset( QPointF offset, double angle );
//! Marker rotation angle, in degrees clockwise from north
double mAngle;
//! Line rotation angle (see setLineAngle() for details)
double mLineAngle;
//! Marker size
double mSize;
//! Marker size unit
QgsSymbolV2::OutputUnit mSizeUnit;
//! Marker size map unit scale
QgsMapUnitScale mSizeMapUnitScale;
//! Marker offset
QPointF mOffset;
//! Offset units
QgsSymbolV2::OutputUnit mOffsetUnit;
//! Offset map unit scale
QgsMapUnitScale mOffsetMapUnitScale;
//! Marker size scaling method
QgsSymbolV2::ScaleMethod mScaleMethod;
//! Horizontal anchor point
HorizontalAnchorPoint mHorizontalAnchorPoint;
//! Vertical anchor point
VerticalAnchorPoint mVerticalAnchorPoint;
private:

View File

@ -34,6 +34,8 @@ QgsSymbolLayerV2Registry::QgsSymbolLayerV2Registry()
addSymbolLayerType( new QgsSymbolLayerV2Metadata( "SimpleMarker", QObject::tr( "Simple marker" ), QgsSymbolV2::Marker,
QgsSimpleMarkerSymbolLayerV2::create, QgsSimpleMarkerSymbolLayerV2::createFromSld ) );
addSymbolLayerType( new QgsSymbolLayerV2Metadata( "FilledMarker", QObject::tr( "Filled marker" ), QgsSymbolV2::Marker,
QgsFilledMarkerSymbolLayer::create ) );
addSymbolLayerType( new QgsSymbolLayerV2Metadata( "SvgMarker", QObject::tr( "SVG marker" ), QgsSymbolV2::Marker,
QgsSvgMarkerSymbolLayerV2::create, QgsSvgMarkerSymbolLayerV2::createFromSld ) );
addSymbolLayerType( new QgsSymbolLayerV2Metadata( "FontMarker", QObject::tr( "Font marker" ), QgsSymbolV2::Marker,

View File

@ -140,8 +140,10 @@ static QgsSymbolV2* readOldSymbol( const QDomNode& synode, QGis::GeometryType ge
// simple symbol marker
QColor color = readSymbolColor( synode, true );
QColor borderColor = readSymbolColor( synode, false );
QString name = symbolName.mid( 5 );
sl = new QgsSimpleMarkerSymbolLayerV2( name, color, borderColor, size, angle );
QgsSimpleMarkerSymbolLayerBase::Shape shape = QgsSimpleMarkerSymbolLayerBase::decodeShape( symbolName.mid( 5 ) );
sl = new QgsSimpleMarkerSymbolLayerV2( shape, size, angle );
sl->setColor( color );
sl->setOutlineColor( borderColor );
}
else
{

View File

@ -64,6 +64,7 @@ static void _initWidgetFunctions()
_initWidgetFunction( "ArrowLine", QgsArrowSymbolLayerWidget::create );
_initWidgetFunction( "SimpleMarker", QgsSimpleMarkerSymbolLayerV2Widget::create );
_initWidgetFunction( "FilledMarker", QgsFilledMarkerSymbolLayerWidget::create );
_initWidgetFunction( "SvgMarker", QgsSvgMarkerSymbolLayerV2Widget::create );
_initWidgetFunction( "FontMarker", QgsFontMarkerSymbolLayerV2Widget::create );
_initWidgetFunction( "EllipseMarker", QgsEllipseSymbolLayerV2Widget::create );

View File

@ -442,18 +442,16 @@ QgsSimpleMarkerSymbolLayerV2Widget::QgsSimpleMarkerSymbolLayerV2Widget( const Qg
mSizeDDBtn->setAssistant( tr( "Size Assistant..." ), new QgsSizeScaleWidget( mVectorLayer, mAssistantPreviewSymbol ) );
QSize size = lstNames->iconSize();
QStringList names;
names << "circle" << "rectangle" << "diamond" << "pentagon" << "hexagon" << "cross" << "cross_fill" << "triangle" << "equilateral_triangle"
<< "star" << "arrow" << "line" << "arrowhead" << "cross2" << "filled_arrowhead" << "semi_circle" << "third_circle" << "quarter_circle"
<< "quarter_square" << "half_square" << "diagonal_half_square" << "right_half_triangle" << "left_half_triangle";
double markerSize = DEFAULT_POINT_SIZE * 2;
Q_FOREACH ( const QString& name, names )
Q_FOREACH ( QgsSimpleMarkerSymbolLayerBase::Shape shape, QgsSimpleMarkerSymbolLayerBase::availableShapes() )
{
QgsSimpleMarkerSymbolLayerV2* lyr = new QgsSimpleMarkerSymbolLayerV2( name, QColor( 200, 200, 200 ), QColor( 0, 0, 0 ), markerSize );
QgsSimpleMarkerSymbolLayerV2* lyr = new QgsSimpleMarkerSymbolLayerV2( shape, markerSize );
lyr->setColor( QColor( 200, 200, 200 ) );
lyr->setOutlineColor( QColor( 0, 0, 0 ) );
QIcon icon = QgsSymbolLayerV2Utils::symbolLayerPreviewIcon( lyr, QgsSymbolV2::MM, size );
QListWidgetItem* item = new QListWidgetItem( icon, QString(), lstNames );
item->setData( Qt::UserRole, name );
item->setToolTip( name );
item->setData( Qt::UserRole, static_cast< int >( shape ) );
item->setToolTip( QgsSimpleMarkerSymbolLayerBase::encodeShape( shape ) );
delete lyr;
}
@ -482,10 +480,10 @@ void QgsSimpleMarkerSymbolLayerV2Widget::setSymbolLayer( QgsSymbolLayerV2* layer
mLayer = static_cast<QgsSimpleMarkerSymbolLayerV2*>( layer );
// set values
QString name = mLayer->name();
QgsSimpleMarkerSymbolLayerBase::Shape shape = mLayer->shape();
for ( int i = 0; i < lstNames->count(); ++i )
{
if ( lstNames->item( i )->data( Qt::UserRole ).toString() == name )
if ( static_cast< QgsSimpleMarkerSymbolLayerBase::Shape >( lstNames->item( i )->data( Qt::UserRole ).toInt() ) == shape )
{
lstNames->setCurrentRow( i );
break;
@ -569,7 +567,7 @@ QgsSymbolLayerV2* QgsSimpleMarkerSymbolLayerV2Widget::symbolLayer()
void QgsSimpleMarkerSymbolLayerV2Widget::setName()
{
mLayer->setName( lstNames->currentItem()->data( Qt::UserRole ).toString() );
mLayer->setShape( static_cast< QgsSimpleMarkerSymbolLayerBase::Shape>( lstNames->currentItem()->data( Qt::UserRole ).toInt() ) );
emit changed();
}
@ -839,6 +837,187 @@ void QgsSimpleFillSymbolLayerV2Widget::on_mOffsetUnitWidget_changed()
}
}
///////////
QgsFilledMarkerSymbolLayerWidget::QgsFilledMarkerSymbolLayerWidget( const QgsVectorLayer* vl, QWidget* parent )
: QgsSymbolLayerV2Widget( parent, vl )
{
mLayer = nullptr;
setupUi( this );
mSizeUnitWidget->setUnits( QgsSymbolV2::OutputUnitList() << QgsSymbolV2::MM << QgsSymbolV2::MapUnit << QgsSymbolV2::Pixel );
mOffsetUnitWidget->setUnits( QgsSymbolV2::OutputUnitList() << QgsSymbolV2::MM << QgsSymbolV2::MapUnit << QgsSymbolV2::Pixel );
spinOffsetX->setClearValue( 0.0 );
spinOffsetY->setClearValue( 0.0 );
//make a temporary symbol for the size assistant preview
mAssistantPreviewSymbol = new QgsMarkerSymbolV2();
if ( mVectorLayer )
mSizeDDBtn->setAssistant( tr( "Size Assistant..." ), new QgsSizeScaleWidget( mVectorLayer, mAssistantPreviewSymbol ) );
QSize size = lstNames->iconSize();
double markerSize = DEFAULT_POINT_SIZE * 2;
Q_FOREACH ( QgsSimpleMarkerSymbolLayerBase::Shape shape, QgsSimpleMarkerSymbolLayerBase::availableShapes() )
{
if ( !QgsSimpleMarkerSymbolLayerBase::shapeIsFilled( shape ) )
continue;
QgsSimpleMarkerSymbolLayerV2* lyr = new QgsSimpleMarkerSymbolLayerV2( shape, markerSize );
lyr->setColor( QColor( 200, 200, 200 ) );
lyr->setOutlineColor( QColor( 0, 0, 0 ) );
QIcon icon = QgsSymbolLayerV2Utils::symbolLayerPreviewIcon( lyr, QgsSymbolV2::MM, size );
QListWidgetItem* item = new QListWidgetItem( icon, QString(), lstNames );
item->setData( Qt::UserRole, static_cast< int >( shape ) );
item->setToolTip( QgsSimpleMarkerSymbolLayerBase::encodeShape( shape ) );
delete lyr;
}
connect( lstNames, SIGNAL( currentRowChanged( int ) ), this, SLOT( setShape() ) );
connect( spinSize, SIGNAL( valueChanged( double ) ), this, SLOT( setSize() ) );
connect( spinAngle, SIGNAL( valueChanged( double ) ), this, SLOT( setAngle() ) );
connect( spinOffsetX, SIGNAL( valueChanged( double ) ), this, SLOT( setOffset() ) );
connect( spinOffsetY, SIGNAL( valueChanged( double ) ), this, SLOT( setOffset() ) );
connect( this, SIGNAL( changed() ), this, SLOT( updateAssistantSymbol() ) );
}
QgsFilledMarkerSymbolLayerWidget::~QgsFilledMarkerSymbolLayerWidget()
{
delete mAssistantPreviewSymbol;
}
void QgsFilledMarkerSymbolLayerWidget::setSymbolLayer( QgsSymbolLayerV2* layer )
{
if ( layer->layerType() != "FilledMarker" )
return;
// layer type is correct, we can do the cast
mLayer = static_cast<QgsFilledMarkerSymbolLayer*>( layer );
// set values
QgsSimpleMarkerSymbolLayerBase::Shape shape = mLayer->shape();
for ( int i = 0; i < lstNames->count(); ++i )
{
if ( static_cast< QgsSimpleMarkerSymbolLayerBase::Shape >( lstNames->item( i )->data( Qt::UserRole ).toInt() ) == shape )
{
lstNames->setCurrentRow( i );
break;
}
}
whileBlocking( spinSize )->setValue( mLayer->size() );
whileBlocking( spinAngle )->setValue( mLayer->angle() );
whileBlocking( spinOffsetX )->setValue( mLayer->offset().x() );
whileBlocking( spinOffsetY )->setValue( mLayer->offset().y() );
mSizeUnitWidget->blockSignals( true );
mSizeUnitWidget->setUnit( mLayer->sizeUnit() );
mSizeUnitWidget->setMapUnitScale( mLayer->sizeMapUnitScale() );
mSizeUnitWidget->blockSignals( false );
mOffsetUnitWidget->blockSignals( true );
mOffsetUnitWidget->setUnit( mLayer->offsetUnit() );
mOffsetUnitWidget->setMapUnitScale( mLayer->offsetMapUnitScale() );
mOffsetUnitWidget->blockSignals( false );
//anchor points
whileBlocking( mHorizontalAnchorComboBox )->setCurrentIndex( mLayer->horizontalAnchorPoint() );
whileBlocking( mVerticalAnchorComboBox )->setCurrentIndex( mLayer->verticalAnchorPoint() );
registerDataDefinedButton( mNameDDBtn, "name", QgsDataDefinedButton::String, tr( "string " ) + QLatin1String( "[<b>square</b>|<b>rectangle</b>|<b>diamond</b>|"
"<b>pentagon</b>|<b>hexagon</b>|<b>triangle</b>|<b>equilateral_triangle</b>|"
"<b>star</b>|<b>arrow</b>|<b>filled_arrowhead</b>|"
"<b>circle</b>|<b>cross</b>|<b>cross_fill</b>|<b>x</b>|"
"<b>line</b>|<b>arrowhead</b>|<b>cross2</b>|<b>semi_circle</b>|<b>third_circle</b>|<b>quarter_circle</b>|"
"<b>quarter_square</b>|<b>half_square</b>|<b>diagonal_half_square</b>|<b>right_half_triangle</b>|<b>left_half_triangle</b>]" ) );
registerDataDefinedButton( mSizeDDBtn, "size", QgsDataDefinedButton::Double, QgsDataDefinedButton::doublePosDesc() );
registerDataDefinedButton( mAngleDDBtn, "angle", QgsDataDefinedButton::Double, QgsDataDefinedButton::double180RotDesc() );
registerDataDefinedButton( mOffsetDDBtn, "offset", QgsDataDefinedButton::String, QgsDataDefinedButton::doubleXYDesc() );
registerDataDefinedButton( mHorizontalAnchorDDBtn, "horizontal_anchor_point", QgsDataDefinedButton::String, QgsDataDefinedButton::horizontalAnchorDesc() );
registerDataDefinedButton( mVerticalAnchorDDBtn, "vertical_anchor_point", QgsDataDefinedButton::String, QgsDataDefinedButton::verticalAnchorDesc() );
updateAssistantSymbol();
}
QgsSymbolLayerV2* QgsFilledMarkerSymbolLayerWidget::symbolLayer()
{
return mLayer;
}
void QgsFilledMarkerSymbolLayerWidget::setShape()
{
mLayer->setShape( static_cast< QgsSimpleMarkerSymbolLayerBase::Shape>( lstNames->currentItem()->data( Qt::UserRole ).toInt() ) );
emit changed();
}
void QgsFilledMarkerSymbolLayerWidget::setSize()
{
mLayer->setSize( spinSize->value() );
emit changed();
}
void QgsFilledMarkerSymbolLayerWidget::setAngle()
{
mLayer->setAngle( spinAngle->value() );
emit changed();
}
void QgsFilledMarkerSymbolLayerWidget::setOffset()
{
mLayer->setOffset( QPointF( spinOffsetX->value(), spinOffsetY->value() ) );
emit changed();
}
void QgsFilledMarkerSymbolLayerWidget::on_mSizeUnitWidget_changed()
{
if ( mLayer )
{
mLayer->setSizeUnit( mSizeUnitWidget->unit() );
mLayer->setSizeMapUnitScale( mSizeUnitWidget->getMapUnitScale() );
emit changed();
}
}
void QgsFilledMarkerSymbolLayerWidget::on_mOffsetUnitWidget_changed()
{
if ( mLayer )
{
mLayer->setOffsetUnit( mOffsetUnitWidget->unit() );
mLayer->setOffsetMapUnitScale( mOffsetUnitWidget->getMapUnitScale() );
emit changed();
}
}
void QgsFilledMarkerSymbolLayerWidget::on_mHorizontalAnchorComboBox_currentIndexChanged( int index )
{
if ( mLayer )
{
mLayer->setHorizontalAnchorPoint(( QgsMarkerSymbolLayerV2::HorizontalAnchorPoint ) index );
emit changed();
}
}
void QgsFilledMarkerSymbolLayerWidget::on_mVerticalAnchorComboBox_currentIndexChanged( int index )
{
if ( mLayer )
{
mLayer->setVerticalAnchorPoint(( QgsMarkerSymbolLayerV2::VerticalAnchorPoint ) index );
emit changed();
}
}
void QgsFilledMarkerSymbolLayerWidget::updateAssistantSymbol()
{
for ( int i = mAssistantPreviewSymbol->symbolLayerCount() - 1 ; i >= 0; --i )
{
mAssistantPreviewSymbol->deleteSymbolLayer( i );
}
mAssistantPreviewSymbol->appendSymbolLayer( mLayer->clone() );
QgsDataDefined* ddSize = mLayer->getDataDefinedProperty( "size" );
if ( ddSize )
mAssistantPreviewSymbol->setDataDefinedSize( *ddSize );
}
///////////
QgsGradientFillSymbolLayerV2Widget::QgsGradientFillSymbolLayerV2Widget( const QgsVectorLayer* vl, QWidget* parent )

View File

@ -186,6 +186,7 @@ class GUI_EXPORT QgsSimpleMarkerSymbolLayerV2Widget : public QgsSymbolLayerV2Wid
virtual QgsSymbolLayerV2* symbolLayer() override;
public slots:
//TODO QGIS 3.0 - rename to setShape
void setName();
void setColorBorder( const QColor& color );
void setColorFill( const QColor& color );
@ -247,6 +248,60 @@ class GUI_EXPORT QgsSimpleFillSymbolLayerV2Widget : public QgsSymbolLayerV2Widge
};
///////////
#include "ui_widget_filledmarker.h"
class QgsFilledMarkerSymbolLayer;
/** \ingroup gui
* \class QgsFilledMarkerSymbolLayerWidget
* \brief Widget for configuring QgsFilledMarkerSymbolLayer symbol layers.
* \note Added in version 2.16
*/
class GUI_EXPORT QgsFilledMarkerSymbolLayerWidget : public QgsSymbolLayerV2Widget, private Ui::WidgetFilledMarker
{
Q_OBJECT
public:
/** Constructor for QgsFilledMarkerSymbolLayerWidget.
* @param vl associated vector layer
* @param parent parent widget
*/
QgsFilledMarkerSymbolLayerWidget( const QgsVectorLayer* vl, QWidget* parent = nullptr );
~QgsFilledMarkerSymbolLayerWidget();
/** Creates a new QgsFilledMarkerSymbolLayerWidget.
* @param vl associated vector layer
*/
static QgsSymbolLayerV2Widget* create( const QgsVectorLayer* vl ) { return new QgsFilledMarkerSymbolLayerWidget( vl ); }
// from base class
virtual void setSymbolLayer( QgsSymbolLayerV2* layer ) override;
virtual QgsSymbolLayerV2* symbolLayer() override;
protected:
QgsFilledMarkerSymbolLayer* mLayer;
private slots:
void updateAssistantSymbol();
void setShape();
void setSize();
void setAngle();
void setOffset();
void on_mSizeUnitWidget_changed();
void on_mOffsetUnitWidget_changed();
void on_mHorizontalAnchorComboBox_currentIndexChanged( int index );
void on_mVerticalAnchorComboBox_currentIndexChanged( int index );
private:
QgsMarkerSymbolV2* mAssistantPreviewSymbol;
};
///////////
#include "ui_widget_gradientfill.h"

View File

@ -55,7 +55,9 @@ QgsGrassEditRenderer::QgsGrassEditRenderer()
// first/last vertex marker to distinguish vertices from nodes
QgsMarkerLineSymbolLayerV2 * firstVertexMarkerLine = new QgsMarkerLineSymbolLayerV2( false );
QgsSimpleMarkerSymbolLayerV2 *markerSymbolLayer = new QgsSimpleMarkerSymbolLayerV2( "x", QColor( 255, 0, 0 ), QColor( 255, 0, 0 ), 2 );
QgsSimpleMarkerSymbolLayerV2 *markerSymbolLayer = new QgsSimpleMarkerSymbolLayerV2( QgsSimpleMarkerSymbolLayerBase::Cross2, 2 );
markerSymbolLayer->setColor( QColor( 255, 0, 0 ) );
markerSymbolLayer->setBorderColor( QColor( 255, 0, 0 ) );
markerSymbolLayer->setOutlineWidth( 0.5 );
QgsSymbolLayerV2List markerLayers;
markerLayers << markerSymbolLayer;

View File

@ -0,0 +1,338 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>WidgetFilledMarker</class>
<widget class="QWidget" name="WidgetFilledMarker">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>517</width>
<height>398</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="5" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Offset X,Y</string>
</property>
</widget>
</item>
<item row="0" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QgsDoubleSpinBox" name="spinSize">
<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>100000.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="QgsDataDefinedButton" name="mSizeDDBtn">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
<item>
<widget class="QgsUnitSelectionWidget" name="mSizeUnitWidget" native="true">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
</widget>
</item>
</layout>
</item>
<item row="6" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<widget class="QComboBox" name="mHorizontalAnchorComboBox">
<item>
<property name="text">
<string>Left</string>
</property>
</item>
<item>
<property name="text">
<string>HCenter</string>
</property>
</item>
<item>
<property name="text">
<string>Right</string>
</property>
</item>
</widget>
</item>
<item>
<widget class="QgsDataDefinedButton" name="mHorizontalAnchorDDBtn">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="mVerticalAnchorComboBox">
<item>
<property name="text">
<string>Top</string>
</property>
</item>
<item>
<property name="text">
<string>VCenter</string>
</property>
</item>
<item>
<property name="text">
<string>Bottom</string>
</property>
</item>
</widget>
</item>
<item>
<widget class="QgsDataDefinedButton" name="mVerticalAnchorDDBtn">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="4" column="1">
<layout class="QHBoxLayout" name="horizontalLayout_6">
<item>
<widget class="QgsDoubleSpinBox" name="spinAngle">
<property name="suffix">
<string> °</string>
</property>
<property name="decimals">
<number>2</number>
</property>
<property name="maximum">
<double>360.000000000000000</double>
</property>
<property name="singleStep">
<double>0.500000000000000</double>
</property>
</widget>
</item>
<item>
<widget class="QgsDataDefinedButton" name="mAngleDDBtn">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="5" column="1">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QgsDoubleSpinBox" name="spinOffsetX">
<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>-99999999.989999994635582</double>
</property>
<property name="maximum">
<double>99999999.989999994635582</double>
</property>
<property name="singleStep">
<double>0.200000000000000</double>
</property>
</widget>
</item>
<item>
<widget class="QgsDoubleSpinBox" name="spinOffsetY">
<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>-99999999.989999994635582</double>
</property>
<property name="maximum">
<double>99999999.989999994635582</double>
</property>
<property name="singleStep">
<double>0.200000000000000</double>
</property>
</widget>
</item>
<item>
<widget class="QgsDataDefinedButton" name="mOffsetDDBtn">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
<item>
<widget class="QgsUnitSelectionWidget" name="mOffsetUnitWidget" native="true">
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
</widget>
</item>
</layout>
</item>
<item row="6" column="0">
<widget class="QLabel" name="mAnchorPointLabel">
<property name="text">
<string>Anchor point</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Rotation</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Size</string>
</property>
</widget>
</item>
<item row="7" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_8">
<item>
<widget class="QListWidget" name="lstNames">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="iconSize">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
<property name="movement">
<enum>QListView::Static</enum>
</property>
<property name="flow">
<enum>QListView::LeftToRight</enum>
</property>
<property name="resizeMode">
<enum>QListView::Adjust</enum>
</property>
<property name="spacing">
<number>4</number>
</property>
<property name="gridSize">
<size>
<width>30</width>
<height>25</height>
</size>
</property>
<property name="viewMode">
<enum>QListView::IconMode</enum>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QgsDataDefinedButton" name="mNameDDBtn">
<property name="text">
<string>...</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>QgsDataDefinedButton</class>
<extends>QToolButton</extends>
<header>qgsdatadefinedbutton.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>spinSize</tabstop>
<tabstop>mSizeDDBtn</tabstop>
<tabstop>mSizeUnitWidget</tabstop>
<tabstop>spinAngle</tabstop>
<tabstop>mAngleDDBtn</tabstop>
<tabstop>spinOffsetX</tabstop>
<tabstop>spinOffsetY</tabstop>
<tabstop>mOffsetDDBtn</tabstop>
<tabstop>mOffsetUnitWidget</tabstop>
<tabstop>mHorizontalAnchorComboBox</tabstop>
<tabstop>mHorizontalAnchorDDBtn</tabstop>
<tabstop>mVerticalAnchorComboBox</tabstop>
<tabstop>mVerticalAnchorDDBtn</tabstop>
<tabstop>lstNames</tabstop>
<tabstop>mNameDDBtn</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>

View File

@ -131,6 +131,7 @@ ADD_QGIS_TEST(expressiontest testqgsexpression.cpp)
ADD_QGIS_TEST(featuretest testqgsfeature.cpp)
ADD_QGIS_TEST(fieldstest testqgsfields.cpp)
ADD_QGIS_TEST(fieldtest testqgsfield.cpp)
ADD_QGIS_TEST(filledmarkertest testqgsfilledmarker.cpp)
ADD_QGIS_TEST(filewritertest testqgsvectorfilewriter.cpp)
ADD_QGIS_TEST(fontmarkertest2 testqgsfontmarker.cpp)
ADD_QGIS_TEST(geometryimporttest testqgsgeometryimport.cpp)

View File

@ -0,0 +1,198 @@
/***************************************************************************
testqgsfilledmarker.cpp
-----------------------
Date : May 2016
Copyright : (C) 2016 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. *
* *
***************************************************************************/
#include <QtTest/QtTest>
#include <QObject>
#include <QString>
#include <QStringList>
#include <QApplication>
#include <QFileInfo>
#include <QDir>
#include <QDesktopServices>
//qgis includes...
#include <qgsmaprenderer.h>
#include <qgsmaplayer.h>
#include <qgsvectorlayer.h>
#include <qgsapplication.h>
#include <qgsproviderregistry.h>
#include <qgsmaplayerregistry.h>
#include <qgssymbolv2.h>
#include <qgssinglesymbolrendererv2.h>
#include "qgsmarkersymbollayerv2.h"
#include "qgsfillsymbollayerv2.h"
#include "qgsdatadefined.h"
//qgis test includes
#include "qgsrenderchecker.h"
/** \ingroup UnitTests
* This is a unit test for QgsFilledMarkerSymbolLayer.
*/
class TestQgsFilledMarkerSymbol : public QObject
{
Q_OBJECT
public:
TestQgsFilledMarkerSymbol()
: mTestHasError( false )
, mpPointsLayer( nullptr )
, mFilledMarkerLayer( nullptr )
, mMarkerSymbol( nullptr )
, mSymbolRenderer( nullptr )
{}
private slots:
void initTestCase();// will be called before the first testfunction is executed.
void cleanupTestCase();// will be called after the last testfunction was executed.
void init() {} // will be called before each testfunction is executed.
void cleanup() {} // will be called after every testfunction.
void filledMarkerSymbol();
void dataDefinedShape();
void bounds();
private:
bool mTestHasError;
bool imageCheck( const QString& theType );
QgsMapSettings mMapSettings;
QgsVectorLayer * mpPointsLayer;
QgsFilledMarkerSymbolLayer* mFilledMarkerLayer;
QgsMarkerSymbolV2* mMarkerSymbol;
QgsSingleSymbolRendererV2* mSymbolRenderer;
QString mTestDataDir;
QString mReport;
};
void TestQgsFilledMarkerSymbol::initTestCase()
{
mTestHasError = false;
// init QGIS's paths - true means that all path will be inited from prefix
QgsApplication::init();
QgsApplication::initQgis();
QgsApplication::showSettings();
//create some objects that will be used in all tests...
QString myDataDir( TEST_DATA_DIR ); //defined in CmakeLists.txt
mTestDataDir = myDataDir + '/';
//
//create a poly layer that will be used in all tests...
//
QString pointFileName = mTestDataDir + "points.shp";
QFileInfo pointFileInfo( pointFileName );
mpPointsLayer = new QgsVectorLayer( pointFileInfo.filePath(),
pointFileInfo.completeBaseName(), "ogr" );
// Register the layer with the registry
QgsMapLayerRegistry::instance()->addMapLayers(
QList<QgsMapLayer *>() << mpPointsLayer );
//setup symbol
QgsGradientFillSymbolLayerV2* gradientFill = new QgsGradientFillSymbolLayerV2();
gradientFill->setColor( QColor( "red" ) );
gradientFill->setColor2( QColor( "blue" ) );
gradientFill->setGradientType( QgsGradientFillSymbolLayerV2::Linear );
gradientFill->setGradientColorType( QgsGradientFillSymbolLayerV2::SimpleTwoColor );
gradientFill->setCoordinateMode( QgsGradientFillSymbolLayerV2::Feature );
gradientFill->setGradientSpread( QgsGradientFillSymbolLayerV2::Pad );
gradientFill->setReferencePoint1( QPointF( 0, 0 ) );
gradientFill->setReferencePoint2( QPointF( 1, 1 ) );
QgsFillSymbolV2* fillSymbol = new QgsFillSymbolV2();
fillSymbol->changeSymbolLayer( 0, gradientFill );
mFilledMarkerLayer = new QgsFilledMarkerSymbolLayer();
mFilledMarkerLayer->setSubSymbol( fillSymbol );
mMarkerSymbol = new QgsMarkerSymbolV2();
mMarkerSymbol->changeSymbolLayer( 0, mFilledMarkerLayer );
mSymbolRenderer = new QgsSingleSymbolRendererV2( mMarkerSymbol );
mpPointsLayer->setRendererV2( mSymbolRenderer );
// We only need maprender instead of mapcanvas
// since maprender does not require a qui
// and is more light weight
//
mMapSettings.setLayers( QStringList() << mpPointsLayer->id() );
mReport += "<h1>Filled Marker Tests</h1>\n";
}
void TestQgsFilledMarkerSymbol::cleanupTestCase()
{
QString myReportFile = QDir::tempPath() + "/qgistest.html";
QFile myFile( myReportFile );
if ( myFile.open( QIODevice::WriteOnly | QIODevice::Append ) )
{
QTextStream myQTextStream( &myFile );
myQTextStream << mReport;
myFile.close();
}
QgsApplication::exitQgis();
}
void TestQgsFilledMarkerSymbol::filledMarkerSymbol()
{
mFilledMarkerLayer->setShape( QgsSimpleMarkerSymbolLayerBase::Circle );
mFilledMarkerLayer->setSize( 15 );
QVERIFY( imageCheck( "filledmarker" ) );
}
void TestQgsFilledMarkerSymbol::dataDefinedShape()
{
mFilledMarkerLayer->setShape( QgsSimpleMarkerSymbolLayerBase::Circle );
mFilledMarkerLayer->setSize( 10 );
mFilledMarkerLayer->setDataDefinedProperty( "name", new QgsDataDefined( true, true, "if(\"class\"='Jet','square','star')" ) );
bool result = imageCheck( "filledmarker_datadefinedshape" );
mFilledMarkerLayer->removeDataDefinedProperty( "name" );
QVERIFY( result );
}
void TestQgsFilledMarkerSymbol::bounds()
{
mFilledMarkerLayer->setColor( QColor( 200, 200, 200 ) );
mFilledMarkerLayer->setShape( QgsSimpleMarkerSymbolLayerBase::Circle );
mFilledMarkerLayer->setSize( 5 );
mFilledMarkerLayer->setDataDefinedProperty( "size", new QgsDataDefined( true, true, "min(\"importance\" * 2, 6)" ) );
mMapSettings.setFlag( QgsMapSettings::DrawSymbolBounds, true );
bool result = imageCheck( "filledmarker_bounds" );
mMapSettings.setFlag( QgsMapSettings::DrawSymbolBounds, false );
mFilledMarkerLayer->removeDataDefinedProperty( "size" );
QVERIFY( result );
}
//
// Private helper functions not called directly by CTest
//
bool TestQgsFilledMarkerSymbol::imageCheck( const QString& theTestType )
{
//use the QgsRenderChecker test utility class to
//ensure the rendered output matches our control image
mMapSettings.setExtent( mpPointsLayer->extent() );
mMapSettings.setOutputDpi( 96 );
QgsRenderChecker myChecker;
myChecker.setControlPathPrefix( "symbol_filledmarker" );
myChecker.setControlName( "expected_" + theTestType );
myChecker.setMapSettings( mMapSettings );
bool myResultFlag = myChecker.runTest( theTestType );
mReport += myChecker.report();
return myResultFlag;
}
QTEST_MAIN( TestQgsFilledMarkerSymbol )
#include "testqgsfilledmarker.moc"

View File

@ -140,7 +140,7 @@ void TestQgsSimpleMarkerSymbol::simpleMarkerSymbol()
mSimpleMarkerLayer->setColor( Qt::blue );
mSimpleMarkerLayer->setBorderColor( Qt::black );
mSimpleMarkerLayer->setName( "circle" );
mSimpleMarkerLayer->setShape( QgsSimpleMarkerSymbolLayerBase::Circle );
mSimpleMarkerLayer->setSize( 5 );
mSimpleMarkerLayer->setOutlineWidth( 1 );
QVERIFY( imageCheck( "simplemarker" ) );
@ -152,7 +152,7 @@ void TestQgsSimpleMarkerSymbol::simpleMarkerSymbolBevelJoin()
mSimpleMarkerLayer->setColor( Qt::blue );
mSimpleMarkerLayer->setBorderColor( Qt::black );
mSimpleMarkerLayer->setName( "triangle" );
mSimpleMarkerLayer->setShape( QgsSimpleMarkerSymbolLayerBase::Triangle );
mSimpleMarkerLayer->setSize( 25 );
mSimpleMarkerLayer->setOutlineWidth( 3 );
mSimpleMarkerLayer->setPenJoinStyle( Qt::BevelJoin );
@ -165,7 +165,7 @@ void TestQgsSimpleMarkerSymbol::simpleMarkerSymbolMiterJoin()
mSimpleMarkerLayer->setColor( Qt::blue );
mSimpleMarkerLayer->setBorderColor( Qt::black );
mSimpleMarkerLayer->setName( "triangle" );
mSimpleMarkerLayer->setShape( QgsSimpleMarkerSymbolLayerBase::Triangle );
mSimpleMarkerLayer->setSize( 25 );
mSimpleMarkerLayer->setOutlineWidth( 3 );
mSimpleMarkerLayer->setPenJoinStyle( Qt::MiterJoin );
@ -178,7 +178,7 @@ void TestQgsSimpleMarkerSymbol::simpleMarkerSymbolRoundJoin()
mSimpleMarkerLayer->setColor( Qt::blue );
mSimpleMarkerLayer->setBorderColor( Qt::black );
mSimpleMarkerLayer->setName( "triangle" );
mSimpleMarkerLayer->setShape( QgsSimpleMarkerSymbolLayerBase::Triangle );
mSimpleMarkerLayer->setSize( 25 );
mSimpleMarkerLayer->setOutlineWidth( 3 );
mSimpleMarkerLayer->setPenJoinStyle( Qt::RoundJoin );
@ -189,7 +189,7 @@ void TestQgsSimpleMarkerSymbol::bounds()
{
mSimpleMarkerLayer->setColor( QColor( 200, 200, 200 ) );
mSimpleMarkerLayer->setBorderColor( QColor( 0, 0, 0 ) );
mSimpleMarkerLayer->setName( "circle" );
mSimpleMarkerLayer->setShape( QgsSimpleMarkerSymbolLayerBase::Circle );
mSimpleMarkerLayer->setSize( 5 );
mSimpleMarkerLayer->setDataDefinedProperty( "size", new QgsDataDefined( true, true, "min(\"importance\" * 2, 6)" ) );
mSimpleMarkerLayer->setOutlineWidth( 0.5 );
@ -205,7 +205,7 @@ void TestQgsSimpleMarkerSymbol::boundsWithOffset()
{
mSimpleMarkerLayer->setColor( QColor( 200, 200, 200 ) );
mSimpleMarkerLayer->setBorderColor( QColor( 0, 0, 0 ) );
mSimpleMarkerLayer->setName( "circle" );
mSimpleMarkerLayer->setShape( QgsSimpleMarkerSymbolLayerBase::Circle );
mSimpleMarkerLayer->setSize( 5 );
mSimpleMarkerLayer->setDataDefinedProperty( "offset", new QgsDataDefined( true, true, "if(importance > 2, '5,10', '10, 5')" ) );
mSimpleMarkerLayer->setOutlineWidth( 0.5 );
@ -221,7 +221,7 @@ void TestQgsSimpleMarkerSymbol::boundsWithRotation()
{
mSimpleMarkerLayer->setColor( QColor( 200, 200, 200 ) );
mSimpleMarkerLayer->setBorderColor( QColor( 0, 0, 0 ) );
mSimpleMarkerLayer->setName( "square" );
mSimpleMarkerLayer->setShape( QgsSimpleMarkerSymbolLayerBase::Square );
mSimpleMarkerLayer->setSize( 5 );
mSimpleMarkerLayer->setDataDefinedProperty( "angle", new QgsDataDefined( true, true, "importance * 20" ) );
mSimpleMarkerLayer->setOutlineWidth( 0.5 );
@ -237,7 +237,7 @@ void TestQgsSimpleMarkerSymbol::boundsWithRotationAndOffset()
{
mSimpleMarkerLayer->setColor( QColor( 200, 200, 200 ) );
mSimpleMarkerLayer->setBorderColor( QColor( 0, 0, 0 ) );
mSimpleMarkerLayer->setName( "square" );
mSimpleMarkerLayer->setShape( QgsSimpleMarkerSymbolLayerBase::Square );
mSimpleMarkerLayer->setSize( 5 );
mSimpleMarkerLayer->setDataDefinedProperty( "offset", new QgsDataDefined( true, true, "if(importance > 2, '5,10', '10, 5')" ) );
mSimpleMarkerLayer->setDataDefinedProperty( "angle", new QgsDataDefined( true, false, QString(), "heading" ) );

View File

@ -35,6 +35,7 @@ from qgis.core import (QgsCentroidFillSymbolLayerV2,
QgsEllipseSymbolLayerV2,
QgsFillSymbolLayerV2,
QgsFontMarkerSymbolLayerV2,
QgsFilledMarkerSymbolLayer,
QgsGradientFillSymbolLayerV2,
QgsImageFillSymbolLayer,
QgsLinePatternFillSymbolLayer,
@ -49,6 +50,9 @@ from qgis.core import (QgsCentroidFillSymbolLayerV2,
QgsSvgMarkerSymbolLayerV2,
QgsSymbolLayerV2,
QgsVectorFieldSymbolLayer,
QgsRasterFillSymbolLayer,
QgsShapeburstFillSymbolLayerV2,
QgsArrowSymbolLayer,
QgsSymbolV2,
)
from qgis.testing import start_app, unittest
@ -96,6 +100,22 @@ class TestQgsSymbolLayerV2(unittest.TestCase):
mMessage = 'Expected "%s" got "%s"' % (mExpectedType, mType)
assert mExpectedType == mType, mMessage
try:
mType = type(QgsLinePatternFillSymbolLayer)
except:
mType = None
mExpectedType = pyqtWrapperType
mMessage = 'Expected "%s" got "%s"' % (mExpectedType, mType)
assert mExpectedType == mType, mMessage
try:
mType = type(QgsPointPatternFillSymbolLayer)
except:
mType = None
mExpectedType = pyqtWrapperType
mMessage = 'Expected "%s" got "%s"' % (mExpectedType, mType)
assert mExpectedType == mType, mMessage
try:
mType = type(QgsImageFillSymbolLayer)
except:
@ -112,6 +132,22 @@ class TestQgsSymbolLayerV2(unittest.TestCase):
mMessage = 'Expected "%s" got "%s"' % (mExpectedType, mType)
assert mExpectedType == mType, mMessage
try:
mType = type(QgsGradientFillSymbolLayerV2)
except:
mType = None
mExpectedType = pyqtWrapperType
mMessage = 'Expected "%s" got "%s"' % (mExpectedType, mType)
assert mExpectedType == mType, mMessage
try:
mType = type(QgsShapeburstFillSymbolLayerV2)
except:
mType = None
mExpectedType = pyqtWrapperType
mMessage = 'Expected "%s" got "%s"' % (mExpectedType, mType)
assert mExpectedType == mType, mMessage
try:
mType = type(QgsSVGFillSymbolLayer)
except:
@ -128,6 +164,14 @@ class TestQgsSymbolLayerV2(unittest.TestCase):
mMessage = 'Expected "%s" got "%s"' % (mExpectedType, mType)
assert mExpectedType == mType, mMessage
try:
mType = type(QgsRasterFillSymbolLayer)
except:
mType = None
mExpectedType = pyqtWrapperType
mMessage = 'Expected "%s" got "%s"' % (mExpectedType, mType)
assert mExpectedType == mType, mMessage
try:
mType = type(QgsSimpleFillSymbolLayerV2)
except:
@ -152,6 +196,14 @@ class TestQgsSymbolLayerV2(unittest.TestCase):
mMessage = 'Expected "%s" got "%s"' % (mExpectedType, mType)
assert mExpectedType == mType, mMessage
try:
mType = type(QgsArrowSymbolLayer)
except:
mType = None
mExpectedType = pyqtWrapperType
mMessage = 'Expected "%s" got "%s"' % (mExpectedType, mType)
assert mExpectedType == mType, mMessage
try:
mType = type(QgsSimpleLineSymbolLayerV2)
except:
@ -192,6 +244,14 @@ class TestQgsSymbolLayerV2(unittest.TestCase):
mMessage = 'Expected "%s" got "%s"' % (mExpectedType, mType)
assert mExpectedType == mType, mMessage
try:
mType = type(QgsFilledMarkerSymbolLayer)
except:
mType = None
mExpectedType = pyqtWrapperType
mMessage = 'Expected "%s" got "%s"' % (mExpectedType, mType)
assert mExpectedType == mType, mMessage
try:
mType = type(QgsSvgMarkerSymbolLayerV2)
except:
@ -349,7 +409,7 @@ class TestQgsSymbolLayerV2(unittest.TestCase):
mMessage = 'Expected "%s" got "%s"' % (mExpectedValue, mValue)
assert mExpectedValue == mValue, mMessage
mExpectedValue = u'regular_star'
mExpectedValue = u'star'
mValue = mSymbolLayer.subSymbol().symbolLayer(0).name()
mMessage = 'Expected "%s" got "%s"' % (mExpectedValue, mValue)
assert mExpectedValue == mValue, mMessage
@ -730,5 +790,19 @@ class TestQgsSymbolLayerV2(unittest.TestCase):
mMessage = 'Expected "%s" got "%s"' % (mExpectedValue, mValue)
assert mExpectedValue == mValue, mMessage
def testQgsFilledMarkerSymbolLayer(self):
"""
Test QgsFilledMarkerSymbolLayer
"""
# test colors, need to make sure colors are passed/retrieved from subsymbol
mSymbolLayer = QgsFilledMarkerSymbolLayer.create()
mSymbolLayer.setColor(QColor(150, 50, 100))
self.assertEqual(mSymbolLayer.color(), QColor(150, 50, 100))
self.assertEqual(mSymbolLayer.subSymbol().color(), QColor(150, 50, 100))
mSymbolLayer.subSymbol().setColor(QColor(250, 150, 200))
self.assertEqual(mSymbolLayer.subSymbol().color(), QColor(250, 150, 200))
self.assertEqual(mSymbolLayer.color(), QColor(250, 150, 200))
if __name__ == '__main__':
unittest.main()

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB