Merge pull request #3060 from nyalldawson/filled_marker

New "Filled marker" symbol layer type
This commit is contained in:
Nyall Dawson 2016-05-09 21:23:59 +10:00
commit 81e72b782f
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