25 #include <QDomDocument>
26 #include <QDomElement>
29 mSymbolHeightUnit(
QgsSymbolV2::MM ), mFillColor( Qt::white ), mOutlineColor( Qt::black ), mOutlineStyle( Qt::SolidLine ), mOutlineWidth( 0 ), mOutlineWidthUnit(
QgsSymbolV2::MM )
31 mPen.setColor( mOutlineColor );
32 mPen.setStyle( mOutlineStyle );
34 mPen.setJoinStyle( Qt::MiterJoin );
35 mBrush.setColor( mFillColor );
36 mBrush.setStyle( Qt::SolidPattern );
49 if ( properties.contains(
"symbol_name" ) )
53 if ( properties.contains(
"symbol_width" ) )
57 if ( properties.contains(
"symbol_width_unit" ) )
61 if ( properties.contains(
"symbol_width_map_unit_scale" ) )
65 if ( properties.contains(
"symbol_height" ) )
69 if ( properties.contains(
"symbol_height_unit" ) )
73 if ( properties.contains(
"symbol_height_map_unit_scale" ) )
77 if ( properties.contains(
"angle" ) )
79 layer->
setAngle( properties[
"angle"].toDouble() );
81 if ( properties.contains(
"outline_style" ) )
85 else if ( properties.contains(
"line_style" ) )
89 if ( properties.contains(
"outline_width" ) )
93 else if ( properties.contains(
"line_width" ) )
97 if ( properties.contains(
"outline_width_unit" ) )
101 else if ( properties.contains(
"line_width_unit" ) )
105 if ( properties.contains(
"outline_width_map_unit_scale" ) )
109 if ( properties.contains(
"fill_color" ) )
114 else if ( properties.contains(
"color" ) )
118 if ( properties.contains(
"outline_color" ) )
122 else if ( properties.contains(
"line_color" ) )
126 if ( properties.contains(
"size" ) )
128 layer->
setSize( properties[
"size"].toDouble() );
130 if ( properties.contains(
"size_unit" ) )
134 if ( properties.contains(
"size_map_unit_scale" ) )
138 if ( properties.contains(
"offset" ) )
142 if ( properties.contains(
"offset_unit" ) )
146 if ( properties.contains(
"offset_map_unit_scale" ) )
150 if ( properties.contains(
"horizontal_anchor_point" ) )
154 if ( properties.contains(
"vertical_anchor_point" ) )
160 if ( properties.contains(
"width_expression" ) )
164 if ( properties.contains(
"height_expression" ) )
168 if ( properties.contains(
"rotation_expression" ) )
172 if ( properties.contains(
"outline_width_expression" ) )
176 if ( properties.contains(
"outline_style_expression" ) )
180 if ( properties.contains(
"fill_color_expression" ) )
184 if ( properties.contains(
"outline_color_expression" ) )
188 if ( properties.contains(
"symbol_name_expression" ) )
192 if ( properties.contains(
"offset_expression" ) )
196 if ( properties.contains(
"horizontal_anchor_point_expression" ) )
198 layer->
setDataDefinedProperty(
"horizontal_anchor_point", properties[
"horizontal_anchor_point_expression" ] );
200 if ( properties.contains(
"vertical_anchor_point_expression" ) )
202 layer->
setDataDefinedProperty(
"vertical_anchor_point", properties[
"vertical_anchor_point_expression" ] );
206 if ( !properties[
"width_field"].isEmpty() )
210 if ( !properties[
"height_field"].isEmpty() )
214 if ( !properties[
"rotation_field"].isEmpty() )
218 if ( !properties[
"outline_width_field"].isEmpty() )
222 if ( !properties[
"fill_color_field"].isEmpty() )
226 if ( !properties[
"outline_color_field"].isEmpty() )
230 if ( !properties[
"symbol_name_field"].isEmpty() )
249 if ( outlineWidthExpression )
251 double width = outlineWidthExpression->
evaluate( const_cast<QgsFeature*>( context.
feature() ) ).toDouble();
253 mPen.setWidthF( width );
255 if ( outlineStyleExpression )
258 mPen.setStyle( style );
260 if ( fillColorExpression )
262 QString colorString = fillColorExpression->
evaluate( const_cast<QgsFeature*>( context.
feature() ) ).toString();
265 if ( outlineColorExpression )
267 QString colorString = outlineColorExpression->
evaluate( const_cast<QgsFeature*>( context.
feature() ) ).toString();
270 double scaledWidth = mSymbolWidth;
271 double scaledHeight = mSymbolHeight;
272 if ( widthExpression || heightExpression || symbolNameExpression )
275 if ( symbolNameExpression )
277 symbolName = symbolNameExpression->
evaluate( const_cast<QgsFeature*>( context.
feature() ) ).toString();
279 preparePath( symbolName, context, &scaledWidth, &scaledHeight, context.
feature() );
285 markerOffset( context, scaledWidth, scaledHeight, mSymbolWidthUnit, mSymbolHeightUnit, offsetX, offsetY, mSymbolWidthMapUnitScale, mSymbolHeightMapUnitScale );
286 QPointF off( offsetX, offsetY );
295 double rotation = 0.0;
296 if ( rotationExpression )
298 rotation = rotationExpression->
evaluate( const_cast<QgsFeature*>( context.
feature() ) ).toDouble();
308 transform.translate( point.x() + off.x(), point.y() + off.y() );
311 transform.rotate( rotation );
315 p->setBrush( mBrush );
316 p->drawPath( transform.map( mPainterPath ) );
321 return "EllipseMarker";
327 if ( !context.
feature() || !hasDataDefinedProperty() )
329 preparePath( mSymbolName, context );
331 mPen.setColor( mOutlineColor );
332 mPen.setStyle( mOutlineStyle );
334 mBrush.setColor( mFillColor );
349 QDomElement symbolizerElem = doc.createElement(
"se:PointSymbolizer" );
350 if ( !props.value(
"uom",
"" ).isEmpty() )
351 symbolizerElem.setAttribute(
"uom", props.value(
"uom",
"" ) );
352 element.appendChild( symbolizerElem );
363 QDomElement graphicElem = doc.createElement(
"se:Graphic" );
364 element.appendChild( graphicElem );
369 double widthHeightFactor = mSymbolWidth / mSymbolHeight;
371 graphicElem.appendChild( factorElem );
375 QString angleFunc = props.value(
"angle",
"" );
376 if ( angleFunc.isEmpty() )
379 if ( rotationExpression )
382 angleFunc = QString::number(
mAngle );
384 else if ( rotationExpression )
388 angleFunc = QString(
"%1 + %2" ).arg( angleFunc ).arg( rotationExpression->
expression() );
394 double angle = angleFunc.toDouble( &ok );
398 angleFunc = QString(
"%1 + %2" ).arg( angleFunc ).arg(
mAngle );
403 angleFunc = QString::number( angle +
mAngle );
413 QDomElement graphicElem = element.firstChildElement(
"Graphic" );
414 if ( graphicElem.isNull() )
417 QString name =
"circle";
419 double borderWidth,
size;
420 double widthHeightFactor = 1.0;
421 Qt::PenStyle borderStyle;
424 for ( QgsStringMap::iterator it = vendorOptions.begin(); it != vendorOptions.end(); ++it )
426 if ( it.key() ==
"widthHeightFactor" )
429 double v = it.value().toDouble( &ok );
431 widthHeightFactor = v;
443 double d = angleFunc.toDouble( &ok );
463 map[
"symbol_name"] = mSymbolName;
464 map[
"symbol_width"] = QString::number( mSymbolWidth );
467 map[
"symbol_height"] = QString::number( mSymbolHeight );
470 map[
"angle"] = QString::number(
mAngle );
472 map[
"outline_width"] = QString::number( mOutlineWidth );
480 map[
"size"] = QString::number(
mSize );
489 bool QgsEllipseSymbolLayerV2::hasDataDefinedProperty()
const
496 void QgsEllipseSymbolLayerV2::preparePath(
const QString& symbolName,
QgsSymbolV2RenderContext& context,
double* scaledWidth,
double* scaledHeight,
const QgsFeature* f )
498 mPainterPath = QPainterPath();
504 if ( widthExpression )
506 width = widthExpression->
evaluate( const_cast<QgsFeature*>( f ) ).toDouble();
514 width = mSymbolWidth;
518 *scaledWidth = width;
524 if ( heightExpression )
526 height = heightExpression->
evaluate( const_cast<QgsFeature*>( f ) ).toDouble();
534 height = mSymbolHeight;
538 *scaledHeight = height;
542 if ( symbolName ==
"circle" )
544 mPainterPath.addEllipse( QRectF( -width / 2.0, -height / 2.0, width, height ) );
546 else if ( symbolName ==
"rectangle" )
548 mPainterPath.addRect( QRectF( -width / 2.0, -height / 2.0, width, height ) );
550 else if ( symbolName ==
"cross" )
552 mPainterPath.moveTo( 0, -height / 2.0 );
553 mPainterPath.lineTo( 0, height / 2.0 );
554 mPainterPath.moveTo( -width / 2.0, 0 );
555 mPainterPath.lineTo( width / 2.0, 0 );
557 else if ( symbolName ==
"triangle" )
559 mPainterPath.moveTo( 0, -height / 2.0 );
560 mPainterPath.lineTo( -width / 2.0, height / 2.0 );
561 mPainterPath.lineTo( width / 2.0, height / 2.0 );
562 mPainterPath.lineTo( 0, -height / 2.0 );
569 mSymbolWidthUnit = unit;
570 mSymbolHeightUnit = unit;
571 mOutlineWidthUnit = unit;
577 if ( mSymbolWidthUnit != unit || mSymbolHeightUnit != unit || mOutlineWidthUnit != unit )
587 mSymbolWidthMapUnitScale = scale;
588 mSymbolHeightMapUnitScale = scale;
589 mOutlineWidthMapUnitScale = scale;
595 mSymbolWidthMapUnitScale == mSymbolHeightMapUnitScale &&
596 mSymbolHeightMapUnitScale == mOutlineWidthMapUnitScale )
598 return mSymbolWidthMapUnitScale;
608 if ( widthExpression )
610 symbolWidth = widthExpression->
evaluate( const_cast<QgsFeature*>( f ) ).toDouble();
618 symbolWidth *= mmMapUnitScaleFactor;
624 if ( heightExpression )
626 symbolHeight = heightExpression->
evaluate( const_cast<QgsFeature*>( f ) ).toDouble();
630 symbolHeight =
mSize;
634 symbolHeight *= mmMapUnitScaleFactor;
640 if ( outlineWidthExpression )
642 outlineWidth = outlineWidthExpression->
evaluate( const_cast<QgsFeature*>( context->
feature() ) ).toDouble();
650 QColor fc = mFillColor;
652 if ( fillColorExpression )
654 fc = QColor( fillColorExpression->
evaluate( const_cast<QgsFeature*>( context->
feature() ) ).toString() );
658 QColor oc = mOutlineColor;
660 if ( outlineColorExpression )
662 oc = QColor( outlineColorExpression->
evaluate( const_cast<QgsFeature*>( context->
feature() ) ).toString() );
666 QString symbolName = mSymbolName;
668 if ( symbolNameExpression )
671 symbolName = symbolNameExpression->
evaluate( const_cast<QgsFeature*>( context->
feature() ) ).toString();
678 QPointF off( offsetX, offsetY );
681 double rotation = 0.0;
683 if ( rotationExpression )
685 rotation = rotationExpression->
evaluate( const_cast<QgsFeature*>( context->
feature() ) ).toDouble();
691 rotation = -rotation;
696 t.translate( shift.x() + offsetX, shift.y() + offsetY );
699 t.rotate( rotation );
701 double halfWidth = symbolWidth / 2.0;
702 double halfHeight = symbolHeight / 2.0;
704 if ( symbolName ==
"circle" )
708 QPointF pt( t.map( QPointF( 0, 0 ) ) );
714 double stepsize = 2 *
M_PI / 40;
715 for (
int i = 0; i < 39; ++i )
717 double angle = stepsize * i;
718 double x = halfWidth * cos( angle );
719 double y = halfHeight * sin( angle );
720 QPointF pt( t.map( QPointF( x, y ) ) );
721 line.push_back( pt );
724 line.push_back( line.at( 0 ) );
725 e.
writePolyline( line, layerName,
"SOLID", oc, outlineWidth,
true );
728 else if ( symbolName ==
"rectangle" )
730 QPointF pt1( t.map( QPointF( -halfWidth, -halfHeight ) ) );
731 QPointF pt2( t.map( QPointF( halfWidth, -halfHeight ) ) );
732 QPointF pt3( t.map( QPointF( -halfWidth, halfHeight ) ) );
733 QPointF pt4( t.map( QPointF( halfWidth, halfHeight ) ) );
734 e.
writeSolid( layerName, fc, pt1, pt2, pt3, pt4 );
737 else if ( symbolName ==
"cross" )
740 QPointF pt1( t.map( QPointF( -halfWidth, 0 ) ) );
741 QPointF pt2( t.map( QPointF( halfWidth, 0 ) ) );
744 e.
writePolyline( line1, layerName,
"CONTINUOUS", oc, outlineWidth,
false );
746 QPointF pt3( t.map( QPointF( 0, halfHeight ) ) );
747 QPointF pt4( t.map( QPointF( 0, -halfHeight ) ) );
750 e.
writePolyline( line2, layerName,
"CONTINUOUS", oc, outlineWidth,
false );
753 else if ( symbolName ==
"triangle" )
755 QPointF pt1( t.map( QPointF( -halfWidth, -halfHeight ) ) );
756 QPointF pt2( t.map( QPointF( halfWidth, -halfHeight ) ) );
757 QPointF pt3( t.map( QPointF( 0, halfHeight ) ) );
758 QPointF pt4( t.map( QPointF( 0, halfHeight ) ) );
759 e.
writeSolid( layerName, fc, pt1, pt2, pt3, pt4 );