22 #include "qgsexpression.h" 23 #include "qgsexpressionnode.h" 37 #include <QDomDocument> 39 #include <QDomElement> 46 #define POINTS_TO_MM 2.83464567 50 return QStringLiteral(
"%1,%2,%3,%4" ).arg( color.red() ).arg( color.green() ).arg( color.blue() ).arg( color.alpha() );
55 QStringList lst = str.split(
',' );
56 if ( lst.count() < 3 )
60 int red, green, blue, alpha;
62 green = lst[1].toInt();
63 blue = lst[2].toInt();
65 if ( lst.count() > 3 )
67 alpha = lst[3].toInt();
69 return QColor( red, green, blue, alpha );
75 result.sprintf(
"%.2g", alpha / 255.0 );
82 double alpha = str.toDouble( &ok );
83 if ( !ok || alpha > 1 )
94 case QFont::StyleNormal:
95 return QStringLiteral(
"normal" );
96 case QFont::StyleItalic:
97 return QStringLiteral(
"italic" );
98 case QFont::StyleOblique:
99 return QStringLiteral(
"oblique" );
101 return QLatin1String(
"" );
107 if ( str == QLatin1String(
"normal" ) )
return QFont::StyleNormal;
108 if ( str == QLatin1String(
"italic" ) )
return QFont::StyleItalic;
109 if ( str == QLatin1String(
"oblique" ) )
return QFont::StyleOblique;
110 return QFont::StyleNormal;
115 if ( weight == 50 )
return QStringLiteral(
"normal" );
116 if ( weight == 75 )
return QStringLiteral(
"bold" );
120 if ( weight < 0 )
return QStringLiteral(
"100" );
121 if ( weight > 99 )
return QStringLiteral(
"900" );
122 return QString::number( weight * 800 / 99 + 100 );
128 int weight = str.toInt( &ok );
130 return static_cast< int >( QFont::Normal );
134 if ( weight > 900 )
return 99;
135 if ( weight < 100 )
return 0;
136 return ( weight - 100 ) * 99 / 800;
144 return QStringLiteral(
"no" );
146 return QStringLiteral(
"solid" );
148 return QStringLiteral(
"dash" );
150 return QStringLiteral(
"dot" );
151 case Qt::DashDotLine:
152 return QStringLiteral(
"dash dot" );
153 case Qt::DashDotDotLine:
154 return QStringLiteral(
"dash dot dot" );
156 return QStringLiteral(
"???" );
162 if ( str == QLatin1String(
"no" ) )
return Qt::NoPen;
163 if ( str == QLatin1String(
"solid" ) )
return Qt::SolidLine;
164 if ( str == QLatin1String(
"dash" ) )
return Qt::DashLine;
165 if ( str == QLatin1String(
"dot" ) )
return Qt::DotLine;
166 if ( str == QLatin1String(
"dash dot" ) )
return Qt::DashDotLine;
167 if ( str == QLatin1String(
"dash dot dot" ) )
return Qt::DashDotDotLine;
168 return Qt::SolidLine;
176 return QStringLiteral(
"bevel" );
178 return QStringLiteral(
"miter" );
180 return QStringLiteral(
"round" );
182 return QStringLiteral(
"???" );
188 if ( str == QLatin1String(
"bevel" ) )
return Qt::BevelJoin;
189 if ( str == QLatin1String(
"miter" ) )
return Qt::MiterJoin;
190 if ( str == QLatin1String(
"round" ) )
return Qt::RoundJoin;
191 return Qt::BevelJoin;
199 return QStringLiteral(
"bevel" );
201 return QStringLiteral(
"mitre" );
203 return QStringLiteral(
"round" );
205 return QLatin1String(
"" );
211 if ( str == QLatin1String(
"bevel" ) )
return Qt::BevelJoin;
212 if ( str == QLatin1String(
"mitre" ) )
return Qt::MiterJoin;
213 if ( str == QLatin1String(
"round" ) )
return Qt::RoundJoin;
214 return Qt::BevelJoin;
222 return QStringLiteral(
"square" );
224 return QStringLiteral(
"flat" );
226 return QStringLiteral(
"round" );
228 return QStringLiteral(
"???" );
234 if ( str == QLatin1String(
"square" ) )
return Qt::SquareCap;
235 if ( str == QLatin1String(
"flat" ) )
return Qt::FlatCap;
236 if ( str == QLatin1String(
"round" ) )
return Qt::RoundCap;
237 return Qt::SquareCap;
245 return QStringLiteral(
"square" );
247 return QStringLiteral(
"butt" );
249 return QStringLiteral(
"round" );
251 return QLatin1String(
"" );
257 if ( str == QLatin1String(
"square" ) )
return Qt::SquareCap;
258 if ( str == QLatin1String(
"butt" ) )
return Qt::FlatCap;
259 if ( str == QLatin1String(
"round" ) )
return Qt::RoundCap;
260 return Qt::SquareCap;
267 case Qt::SolidPattern :
268 return QStringLiteral(
"solid" );
269 case Qt::HorPattern :
270 return QStringLiteral(
"horizontal" );
271 case Qt::VerPattern :
272 return QStringLiteral(
"vertical" );
273 case Qt::CrossPattern :
274 return QStringLiteral(
"cross" );
275 case Qt::BDiagPattern :
276 return QStringLiteral(
"b_diagonal" );
277 case Qt::FDiagPattern :
278 return QStringLiteral(
"f_diagonal" );
279 case Qt::DiagCrossPattern :
280 return QStringLiteral(
"diagonal_x" );
281 case Qt::Dense1Pattern :
282 return QStringLiteral(
"dense1" );
283 case Qt::Dense2Pattern :
284 return QStringLiteral(
"dense2" );
285 case Qt::Dense3Pattern :
286 return QStringLiteral(
"dense3" );
287 case Qt::Dense4Pattern :
288 return QStringLiteral(
"dense4" );
289 case Qt::Dense5Pattern :
290 return QStringLiteral(
"dense5" );
291 case Qt::Dense6Pattern :
292 return QStringLiteral(
"dense6" );
293 case Qt::Dense7Pattern :
294 return QStringLiteral(
"dense7" );
296 return QStringLiteral(
"no" );
298 return QStringLiteral(
"???" );
304 if ( str == QLatin1String(
"solid" ) )
return Qt::SolidPattern;
305 if ( str == QLatin1String(
"horizontal" ) )
return Qt::HorPattern;
306 if ( str == QLatin1String(
"vertical" ) )
return Qt::VerPattern;
307 if ( str == QLatin1String(
"cross" ) )
return Qt::CrossPattern;
308 if ( str == QLatin1String(
"b_diagonal" ) )
return Qt::BDiagPattern;
309 if ( str == QLatin1String(
"f_diagonal" ) )
return Qt::FDiagPattern;
310 if ( str == QLatin1String(
"diagonal_x" ) )
return Qt::DiagCrossPattern;
311 if ( str == QLatin1String(
"dense1" ) )
return Qt::Dense1Pattern;
312 if ( str == QLatin1String(
"dense2" ) )
return Qt::Dense2Pattern;
313 if ( str == QLatin1String(
"dense3" ) )
return Qt::Dense3Pattern;
314 if ( str == QLatin1String(
"dense4" ) )
return Qt::Dense4Pattern;
315 if ( str == QLatin1String(
"dense5" ) )
return Qt::Dense5Pattern;
316 if ( str == QLatin1String(
"dense6" ) )
return Qt::Dense6Pattern;
317 if ( str == QLatin1String(
"dense7" ) )
return Qt::Dense7Pattern;
318 if ( str == QLatin1String(
"no" ) )
return Qt::NoBrush;
319 return Qt::SolidPattern;
326 case Qt::CrossPattern:
327 return QStringLiteral(
"cross" );
328 case Qt::DiagCrossPattern:
329 return QStringLiteral(
"x" );
336 return QStringLiteral(
"horline" );
338 return QStringLiteral(
"line" );
339 case Qt::BDiagPattern:
340 return QStringLiteral(
"slash" );
341 case Qt::FDiagPattern:
342 return QStringLiteral(
"backslash" );
345 case Qt::Dense1Pattern:
346 case Qt::Dense2Pattern:
347 case Qt::Dense3Pattern:
348 case Qt::Dense4Pattern:
349 case Qt::Dense5Pattern:
350 case Qt::Dense6Pattern:
351 case Qt::Dense7Pattern:
361 if ( str == QLatin1String(
"horline" ) )
return Qt::HorPattern;
362 if ( str == QLatin1String(
"line" ) )
return Qt::VerPattern;
363 if ( str == QLatin1String(
"cross" ) )
return Qt::CrossPattern;
364 if ( str == QLatin1String(
"slash" ) )
return Qt::BDiagPattern;
365 if ( str == QLatin1String(
"backshash" ) )
return Qt::FDiagPattern;
366 if ( str == QLatin1String(
"x" ) )
return Qt::DiagCrossPattern;
368 if ( str.startsWith( QLatin1String(
"brush://" ) ) )
381 QStringList lst = str.split(
',' );
382 if ( lst.count() != 2 )
383 return QPointF( 0, 0 );
384 return QPointF( lst[0].toDouble(), lst[1].toDouble() );
394 QStringList lst =
string.split(
',' );
395 if ( lst.count() != 2 )
396 return QSizeF( 0, 0 );
397 return QSizeF( lst[0].toDouble(), lst[1].toDouble() );
414 if ( str.startsWith( QStringLiteral(
"3x:" ) ) )
417 QString chopped = str.mid( 3 );
418 lst = chopped.split(
',' );
422 lst = str.split(
',' );
424 if ( lst.count() < 2 )
427 double minScale = lst[0].toDouble();
429 minScale = minScale != 0 ? 1.0 / minScale : 0;
430 double maxScale = lst[1].toDouble();
432 maxScale = maxScale != 0 ? 1.0 / maxScale : 0;
434 if ( lst.count() < 6 )
454 *scaleFactor = 0.001;
455 return QStringLiteral(
"http://www.opengeospatial.org/se/units/metre" );
462 *scaleFactor = 1 / 0.28;
471 if ( str == QLatin1String(
"http://www.opengeospatial.org/se/units/metre" ) )
474 *scaleFactor = 1000.0;
477 else if ( str == QLatin1String(
"http://www.opengeospatial.org/se/units/foot" ) )
480 *scaleFactor = 304.8;
487 *scaleFactor = 1 / 0.00028;
493 QString vectorString;
494 QVector<qreal>::const_iterator it = v.constBegin();
495 for ( ; it != v.constEnd(); ++it )
497 if ( it != v.constBegin() )
499 vectorString.append(
';' );
501 vectorString.append( QString::number( *it ) );
508 QVector<qreal> resultVector;
510 QStringList realList = s.split(
';' );
511 QStringList::const_iterator it = realList.constBegin();
512 for ( ; it != realList.constEnd(); ++it )
514 resultVector.append( it->toDouble() );
522 QString vectorString;
523 QVector<qreal>::const_iterator it = v.constBegin();
524 for ( ; it != v.constEnd(); ++it )
526 if ( it != v.constBegin() )
528 vectorString.append(
' ' );
530 vectorString.append( QString::number( *it ) );
537 QVector<qreal> resultVector;
539 QStringList realList = s.split(
' ' );
540 QStringList::const_iterator it = realList.constBegin();
541 for ( ; it != realList.constEnd(); ++it )
543 resultVector.append( it->toDouble() );
551 QString encodedValue;
553 switch ( scaleMethod )
556 encodedValue = QStringLiteral(
"diameter" );
559 encodedValue = QStringLiteral(
"area" );
569 if ( str == QLatin1String(
"diameter" ) )
583 if ( s.compare( QLatin1String(
"Lighten" ), Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_Lighten;
584 if ( s.compare( QLatin1String(
"Screen" ), Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_Screen;
585 if ( s.compare( QLatin1String(
"Dodge" ), Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_ColorDodge;
586 if ( s.compare( QLatin1String(
"Addition" ), Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_Plus;
587 if ( s.compare( QLatin1String(
"Darken" ), Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_Darken;
588 if ( s.compare( QLatin1String(
"Multiply" ), Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_Multiply;
589 if ( s.compare( QLatin1String(
"Burn" ), Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_ColorBurn;
590 if ( s.compare( QLatin1String(
"Overlay" ), Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_Overlay;
591 if ( s.compare( QLatin1String(
"SoftLight" ), Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_SoftLight;
592 if ( s.compare( QLatin1String(
"HardLight" ), Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_HardLight;
593 if ( s.compare( QLatin1String(
"Difference" ), Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_Difference;
594 if ( s.compare( QLatin1String(
"Subtract" ), Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_Exclusion;
595 return QPainter::CompositionMode_SourceOver;
607 QPixmap pixmap( size );
608 pixmap.fill( Qt::transparent );
610 painter.begin( &pixmap );
611 painter.setRenderHint( QPainter::Antialiasing );
620 size.setWidth( size.rwidth() - ( padding * 2 ) );
621 size.setHeight( size.rheight() - ( padding * 2 ) );
622 painter.translate( padding, padding );
638 maxBleed = layerMaxBleed > maxBleed ? layerMaxBleed : maxBleed;
648 painter.begin( &picture );
649 painter.setRenderHint( QPainter::Antialiasing );
660 QPixmap pixmap( size );
661 pixmap.fill( Qt::transparent );
663 painter.begin( &pixmap );
664 painter.setRenderHint( QPainter::Antialiasing );
669 return QIcon( pixmap );
679 QPixmap pixmap( size );
680 pixmap.fill( Qt::transparent );
683 painter.begin( &pixmap );
686 drawStippledBackground( &painter, QRect( padding, padding, size.width() - padding * 2, size.height() - padding * 2 ) );
690 for (
int i = 0; i < size.width(); i++ )
692 QPen pen( ramp->
color( static_cast< double >( i ) / size.width() ) );
693 painter.setPen( pen );
694 painter.drawLine( i, 0 + padding, i, size.height() - 1 - padding );
703 uchar pixDataRGB[] = { 255, 255, 255, 255,
708 QImage img( pixDataRGB, 2, 2, 8, QImage::Format_ARGB32 );
710 int width = ( rect.width() < rect.height() ) ?
711 rect.width() / 2.5 : rect.height() / 2.5;
712 QPixmap pix = QPixmap::fromImage( img.scaled( width, width ) );
715 brush.setTexture( pix );
716 painter->fillRect( rect, brush );
724 static QPolygonF makeOffsetGeometry(
const QgsPolylineXY &polyline )
726 int i, pointCount = polyline.count();
728 QPolygonF resultLine;
729 resultLine.resize( pointCount );
733 for ( i = 0; i < pointCount; ++i, tempPtr++ )
734 resultLine[i] = QPointF( tempPtr->
x(), tempPtr->
y() );
738 static QList<QPolygonF> makeOffsetGeometry(
const QgsPolygonXY &polygon )
740 QList<QPolygonF> resultGeom;
741 resultGeom.reserve( polygon.size() );
742 for (
int ring = 0; ring < polygon.size(); ++ring )
743 resultGeom.append( makeOffsetGeometry( polygon[ ring ] ) );
749 QList<QPolygonF> resultLine;
751 if ( polyline.count() < 2 )
753 resultLine.append( polyline );
757 unsigned int i, pointCount = polyline.count();
760 QPointF *tempPtr = polyline.data();
761 for ( i = 0; i < pointCount; ++i, tempPtr++ )
762 tempPolyline[i] =
QgsPointXY( tempPtr->rx(), tempPtr->ry() );
765 if ( !tempGeometry.
isNull() )
767 int quadSegments = 0;
768 double miterLimit = 2.0;
776 if ( !offsetGeom.
isNull() )
778 tempGeometry = offsetGeom;
785 if ( dist < 0 ) std::reverse( line.begin(), line.end() );
786 resultLine.append( makeOffsetGeometry( line ) );
791 resultLine.append( makeOffsetGeometry( tempGeometry.
asPolygon() ) );
797 resultLine.reserve( tempMPolyline.count() );
798 for (
int part = 0; part < tempMPolyline.count(); ++part )
800 resultLine.append( makeOffsetGeometry( tempMPolyline[ part ] ) );
807 resultLine.reserve( tempMPolygon.count() );
808 for (
int part = 0; part < tempMPolygon.count(); ++part )
810 resultLine.append( makeOffsetGeometry( tempMPolygon[ part ] ) );
818 resultLine.append( polyline );
828 QDomNode layerNode = element.firstChild();
830 while ( !layerNode.isNull() )
832 QDomElement e = layerNode.toElement();
835 if ( e.tagName() != QLatin1String(
"layer" ) )
846 QDomElement s = e.firstChildElement( QStringLiteral(
"symbol" ) );
853 QgsDebugMsg(
"symbol layer refused subsymbol: " + s.attribute(
"name" ) );
856 layers.append( layer );
860 layerNode = layerNode.nextSibling();
863 if ( layers.isEmpty() )
869 QString symbolType = element.attribute( QStringLiteral(
"type" ) );
872 if ( symbolType == QLatin1String(
"line" ) )
874 else if ( symbolType == QLatin1String(
"fill" ) )
876 else if ( symbolType == QLatin1String(
"marker" ) )
880 QgsDebugMsg(
"unknown symbol type " + symbolType );
884 if ( element.hasAttribute( QStringLiteral(
"outputUnit" ) ) )
888 if ( element.hasAttribute( ( QStringLiteral(
"mapUnitScale" ) ) ) )
891 double oldMin = element.attribute( QStringLiteral(
"mapUnitMinScale" ), QStringLiteral(
"0.0" ) ).toDouble();
892 mapUnitScale.
minScale = oldMin != 0 ? 1.0 / oldMin : 0;
893 double oldMax = element.attribute( QStringLiteral(
"mapUnitMaxScale" ), QStringLiteral(
"0.0" ) ).toDouble();
894 mapUnitScale.
maxScale = oldMax != 0 ? 1.0 / oldMax : 0;
897 symbol->
setOpacity( element.attribute( QStringLiteral(
"alpha" ), QStringLiteral(
"1.0" ) ).toDouble() );
898 symbol->
setClipFeaturesToExtent( element.attribute( QStringLiteral(
"clip_to_extent" ), QStringLiteral(
"1" ) ).toInt() );
905 QString layerClass = element.attribute( QStringLiteral(
"class" ) );
906 bool locked = element.attribute( QStringLiteral(
"locked" ) ).toInt();
907 bool enabled = element.attribute( QStringLiteral(
"enabled" ), QStringLiteral(
"1" ) ).toInt();
908 int pass = element.attribute( QStringLiteral(
"pass" ) ).toInt();
925 QDomElement effectElem = element.firstChildElement( QStringLiteral(
"effect" ) );
926 if ( !effectElem.isNull() )
932 QDomElement ddProps = element.firstChildElement( QStringLiteral(
"data_defined_properties" ) );
933 if ( !ddProps.isNull() )
952 return QStringLiteral(
"line" );
954 return QStringLiteral(
"marker" );
956 return QStringLiteral(
"fill" );
958 return QLatin1String(
"" );
965 QDomElement symEl = doc.createElement( QStringLiteral(
"symbol" ) );
966 symEl.setAttribute( QStringLiteral(
"type" ), _nameForSymbolType( symbol->
type() ) );
967 symEl.setAttribute( QStringLiteral(
"name" ), name );
968 symEl.setAttribute( QStringLiteral(
"alpha" ), QString::number( symbol->
opacity() ) );
969 symEl.setAttribute( QStringLiteral(
"clip_to_extent" ), symbol->
clipFeaturesToExtent() ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
976 QDomElement layerEl = doc.createElement( QStringLiteral(
"layer" ) );
977 layerEl.setAttribute( QStringLiteral(
"class" ), layer->
layerType() );
978 layerEl.setAttribute( QStringLiteral(
"enabled" ), layer->
enabled() );
979 layerEl.setAttribute( QStringLiteral(
"locked" ), layer->
isLocked() );
980 layerEl.setAttribute( QStringLiteral(
"pass" ), layer->
renderingPass() );
991 QDomElement ddProps = doc.createElement( QStringLiteral(
"data_defined_properties" ) );
993 layerEl.appendChild( ddProps );
997 QString subname = QStringLiteral(
"@%1@%2" ).arg( name ).arg( i );
999 layerEl.appendChild( subEl );
1001 symEl.appendChild( layerEl );
1009 QDomDocument doc( QStringLiteral(
"qgis-symbol-definition" ) );
1012 QTextStream stream( &props );
1013 symbolElem.save( stream, -1 );
1023 if ( element.isNull() )
1028 QString symbolizerName = element.localName();
1030 if ( symbolizerName == QLatin1String(
"PointSymbolizer" ) )
1033 QDomElement graphicElem = element.firstChildElement( QStringLiteral(
"Graphic" ) );
1034 if ( graphicElem.isNull() )
1036 QgsDebugMsg(
"Graphic element not found in PointSymbolizer" );
1072 if ( symbolizerName == QLatin1String(
"LineSymbolizer" ) )
1075 QDomElement strokeElem = element.firstChildElement( QStringLiteral(
"Stroke" ) );
1076 if ( strokeElem.isNull() )
1078 QgsDebugMsg(
"Stroke element not found in LineSymbolizer" );
1108 if ( symbolizerName == QLatin1String(
"PolygonSymbolizer" ) )
1111 QDomElement fillElem = element.firstChildElement( QStringLiteral(
"Fill" ) );
1112 QDomElement strokeElem = element.firstChildElement( QStringLiteral(
"Stroke" ) );
1113 if ( fillElem.isNull() && strokeElem.isNull() )
1115 QgsDebugMsg(
"neither Fill nor Stroke element not found in PolygonSymbolizer" );
1133 if ( l->
layerType() == QLatin1String(
"SimpleFill" ) || l->
layerType() == QLatin1String(
"SVGFill" ) )
1169 QDomElement fillElem = element.firstChildElement( QStringLiteral(
"Fill" ) );
1170 if ( fillElem.isNull() )
1192 QDomElement strokeElem = element.firstChildElement( QStringLiteral(
"Stroke" ) );
1193 if ( strokeElem.isNull() )
1211 QDomElement graphicElem = element.firstChildElement( QStringLiteral(
"Graphic" ) );
1212 if ( graphicElem.isNull() )
1234 QDomElement graphicElem = element.firstChildElement( QStringLiteral(
"Graphic" ) );
1235 if ( graphicElem.isNull() )
1238 QDomElement externalGraphicElem = graphicElem.firstChildElement( QStringLiteral(
"ExternalGraphic" ) );
1239 if ( externalGraphicElem.isNull() )
1243 QDomElement formatElem = externalGraphicElem.firstChildElement( QStringLiteral(
"Format" ) );
1244 if ( formatElem.isNull() )
1247 QString format = formatElem.firstChild().nodeValue();
1248 if ( format != QLatin1String(
"image/svg+xml" ) )
1250 QgsDebugMsg(
"unsupported External Graphic format found: " + format );
1255 QDomElement onlineResourceElem = externalGraphicElem.firstChildElement( QStringLiteral(
"OnlineResource" ) );
1256 QDomElement inlineContentElem = externalGraphicElem.firstChildElement( QStringLiteral(
"InlineContent" ) );
1257 if ( !onlineResourceElem.isNull() )
1262 else if ( !inlineContentElem.isNull() )
1275 QDomElement graphicElem = element.firstChildElement( QStringLiteral(
"Graphic" ) );
1276 if ( graphicElem.isNull() )
1279 QDomElement markElem = graphicElem.firstChildElement( QStringLiteral(
"Mark" ) );
1280 if ( markElem.isNull() )
1283 QDomElement wellKnownNameElem = markElem.firstChildElement( QStringLiteral(
"WellKnownName" ) );
1284 return !wellKnownNameElem.isNull();
1290 QDomElement graphicElem = element.firstChildElement( QStringLiteral(
"Graphic" ) );
1291 if ( graphicElem.isNull() )
1294 QDomElement markElem = graphicElem.firstChildElement( QStringLiteral(
"Mark" ) );
1295 if ( markElem.isNull() )
1299 QDomElement formatElem = markElem.firstChildElement( QStringLiteral(
"Format" ) );
1300 if ( formatElem.isNull() )
1303 QString format = formatElem.firstChild().nodeValue();
1304 if ( format != QLatin1String(
"ttf" ) )
1306 QgsDebugMsg(
"unsupported Graphic Mark format found: " + format );
1311 QDomElement onlineResourceElem = markElem.firstChildElement( QStringLiteral(
"OnlineResource" ) );
1312 QDomElement inlineContentElem = markElem.firstChildElement( QStringLiteral(
"InlineContent" ) );
1313 if ( !onlineResourceElem.isNull() )
1316 QDomElement markIndexElem = markElem.firstChildElement( QStringLiteral(
"MarkIndex" ) );
1317 if ( !markIndexElem.isNull() )
1320 else if ( !inlineContentElem.isNull() )
1335 QDomElement graphicElem = element.firstChildElement( QStringLiteral(
"Graphic" ) );
1336 if ( graphicElem.isNull() )
1340 for ( QgsStringMap::iterator it = vendorOptions.begin(); it != vendorOptions.end(); ++it )
1342 if ( it.key() == QLatin1String(
"widthHeightFactor" ) )
1353 QDomElement strokeElem = element.firstChildElement( QStringLiteral(
"Stroke" ) );
1354 if ( strokeElem.isNull() )
1357 QDomElement graphicStrokeElem = strokeElem.firstChildElement( QStringLiteral(
"GraphicStroke" ) );
1358 if ( graphicStrokeElem.isNull() )
1366 QDomElement fillElem = element.firstChildElement( QStringLiteral(
"Fill" ) );
1367 if ( fillElem.isNull() )
1370 QDomElement graphicFillElem = fillElem.firstChildElement( QStringLiteral(
"GraphicFill" ) );
1371 if ( graphicFillElem.isNull() )
1374 QDomElement graphicElem = graphicFillElem.firstChildElement( QStringLiteral(
"Graphic" ) );
1375 if ( graphicElem.isNull() )
1381 QColor fillColor, strokeColor;
1382 double size, strokeWidth;
1383 Qt::PenStyle strokeStyle;
1384 if ( !
wellKnownMarkerFromSld( graphicElem, name, fillColor, strokeColor, strokeStyle, strokeWidth, size ) )
1387 if ( name != QLatin1String(
"horline" ) )
1395 double angle = angleFunc.toDouble( &ok );
1401 Q_UNUSED( element );
1407 QDomElement fillElem = element.firstChildElement( QStringLiteral(
"Fill" ) );
1408 if ( fillElem.isNull() )
1411 QDomElement graphicFillElem = fillElem.firstChildElement( QStringLiteral(
"GraphicFill" ) );
1412 if ( graphicFillElem.isNull() )
1432 QDomElement fillElem = element.firstChildElement( QStringLiteral(
"Fill" ) );
1433 QDomElement strokeElem = element.firstChildElement( QStringLiteral(
"Stroke" ) );
1437 bool validFill =
false, validStroke =
false;
1442 Qt::BrushStyle fillStyle;
1444 if (
fillFromSld( fillElem, fillStyle, fillColor ) )
1450 Qt::PenStyle strokeStyle;
1451 double strokeWidth = 1.0, dashOffset = 0.0;
1452 QVector<qreal> customDashPattern;
1454 if (
lineFromSld( strokeElem, strokeStyle, strokeColor, strokeWidth,
1455 nullptr,
nullptr, &customDashPattern, &dashOffset ) )
1458 if ( validFill || validStroke )
1461 map[QStringLiteral(
"name" )] = QStringLiteral(
"square" );
1462 map[QStringLiteral(
"color" )] =
encodeColor( validFill ? fillColor : Qt::transparent );
1463 map[QStringLiteral(
"color_border" )] =
encodeColor( validStroke ? strokeColor : Qt::transparent );
1464 map[QStringLiteral(
"size" )] = QString::number( 6 );
1465 map[QStringLiteral(
"angle" )] = QString::number( 0 );
1466 map[QStringLiteral(
"offset" )] =
encodePoint( QPointF( 0, 0 ) );
1473 bool validFill =
false, validStroke =
false;
1476 QString name, format;
1478 QColor fillColor, strokeColor;
1479 double strokeWidth = 1.0, size = 0.0,
angle = 0.0;
1483 QDomElement graphicFillElem = fillElem.firstChildElement( QStringLiteral(
"GraphicFill" ) );
1484 if ( !graphicFillElem.isNull() )
1487 QDomElement graphicElem = graphicFillElem.firstChildElement( QStringLiteral(
"Graphic" ) );
1488 if ( !graphicElem.isNull() )
1494 QDomElement graphicChildElem = graphicElem.firstChildElement();
1495 while ( !graphicChildElem.isNull() )
1497 if ( graphicChildElem.localName() == QLatin1String(
"Mark" ) )
1500 QDomElement wellKnownNameElem = graphicChildElem.firstChildElement( QStringLiteral(
"WellKnownName" ) );
1501 if ( !wellKnownNameElem.isNull() )
1503 name = wellKnownNameElem.firstChild().nodeValue();
1509 if ( graphicChildElem.localName() == QLatin1String(
"ExternalGraphic" ) || graphicChildElem.localName() == QLatin1String(
"Mark" ) )
1512 QDomElement formatElem = graphicChildElem.firstChildElement( QStringLiteral(
"Format" ) );
1513 if ( formatElem.isNull() )
1516 format = formatElem.firstChild().nodeValue();
1520 if ( graphicChildElem.localName() == QLatin1String(
"ExternalGraphic" ) && format != QLatin1String(
"image/svg+xml" ) )
1525 if ( graphicChildElem.localName() == QLatin1String(
"Mark" ) && format != QLatin1String(
"ttf" ) )
1529 QDomElement onlineResourceElem = graphicChildElem.firstChildElement( QStringLiteral(
"OnlineResource" ) );
1530 QDomElement inlineContentElem = graphicChildElem.firstChildElement( QStringLiteral(
"InlineContent" ) );
1532 if ( !onlineResourceElem.isNull() )
1534 name = onlineResourceElem.attributeNS( QStringLiteral(
"http://www.w3.org/1999/xlink" ), QStringLiteral(
"href" ) );
1536 if ( graphicChildElem.localName() == QLatin1String(
"Mark" ) && format == QLatin1String(
"ttf" ) )
1539 if ( name.startsWith( QLatin1String(
"ttf://" ) ) )
1540 name = name.mid( 6 );
1543 QDomElement markIndexElem = graphicChildElem.firstChildElement( QStringLiteral(
"MarkIndex" ) );
1544 if ( markIndexElem.isNull() )
1548 int v = markIndexElem.firstChild().nodeValue().toInt( &ok );
1559 else if ( !inlineContentElem.isNull() )
1569 if ( graphicChildElem.localName() == QLatin1String(
"Mark" ) )
1571 name = QStringLiteral(
"square" );
1578 if ( found && graphicChildElem.localName() == QLatin1String(
"Mark" ) )
1585 Qt::BrushStyle markFillStyle;
1587 QDomElement markFillElem = graphicChildElem.firstChildElement( QStringLiteral(
"Fill" ) );
1588 if (
fillFromSld( markFillElem, markFillStyle, fillColor ) )
1593 Qt::PenStyle strokeStyle;
1594 double strokeWidth = 1.0, dashOffset = 0.0;
1595 QVector<qreal> customDashPattern;
1597 QDomElement markStrokeElem = graphicChildElem.firstChildElement( QStringLiteral(
"Stroke" ) );
1598 if (
lineFromSld( markStrokeElem, strokeStyle, strokeColor, strokeWidth,
1599 nullptr,
nullptr, &customDashPattern, &dashOffset ) )
1606 QDomElement opacityElem = graphicElem.firstChildElement( QStringLiteral(
"Opacity" ) );
1607 if ( !opacityElem.isNull() )
1608 fillColor.setAlpha(
decodeSldAlpha( opacityElem.firstChild().nodeValue() ) );
1610 QDomElement sizeElem = graphicElem.firstChildElement( QStringLiteral(
"Size" ) );
1611 if ( !sizeElem.isNull() )
1614 double v = sizeElem.firstChild().nodeValue().toDouble( &ok );
1623 double v = angleFunc.toDouble( &ok );
1633 if ( validFill || validStroke )
1635 if ( format == QLatin1String(
"image/svg+xml" ) )
1638 map[QStringLiteral(
"name" )] = name;
1639 map[QStringLiteral(
"fill" )] = fillColor.name();
1640 map[QStringLiteral(
"outline" )] = strokeColor.name();
1641 map[QStringLiteral(
"outline-width" )] = QString::number( strokeWidth );
1643 map[QStringLiteral(
"size" )] = QString::number( size );
1645 map[QStringLiteral(
"angle" )] = QString::number(
angle );
1646 if ( !offset.isNull() )
1647 map[QStringLiteral(
"offset" )] =
encodePoint( offset );
1650 else if ( format == QLatin1String(
"ttf" ) )
1653 map[QStringLiteral(
"font" )] = name;
1654 map[QStringLiteral(
"chr" )] = markIndex;
1655 map[QStringLiteral(
"color" )] =
encodeColor( validFill ? fillColor : Qt::transparent );
1657 map[QStringLiteral(
"size" )] = QString::number( size );
1659 map[QStringLiteral(
"angle" )] = QString::number(
angle );
1660 if ( !offset.isNull() )
1661 map[QStringLiteral(
"offset" )] =
encodePoint( offset );
1667 if ( layers.isEmpty() )
1670 layerList << layers;
1677 QString patternName;
1678 switch ( brushStyle )
1683 case Qt::SolidPattern:
1684 if ( color.isValid() )
1687 if ( color.alpha() < 255 )
1692 case Qt::CrossPattern:
1693 case Qt::DiagCrossPattern:
1694 case Qt::HorPattern:
1695 case Qt::VerPattern:
1696 case Qt::BDiagPattern:
1697 case Qt::FDiagPattern:
1698 case Qt::Dense1Pattern:
1699 case Qt::Dense2Pattern:
1700 case Qt::Dense3Pattern:
1701 case Qt::Dense4Pattern:
1702 case Qt::Dense5Pattern:
1703 case Qt::Dense6Pattern:
1704 case Qt::Dense7Pattern:
1709 element.appendChild( doc.createComment( QStringLiteral(
"Qt::BrushStyle '%1'' not supported yet" ).arg( brushStyle ) ) );
1713 QDomElement graphicFillElem = doc.createElement( QStringLiteral(
"se:GraphicFill" ) );
1714 element.appendChild( graphicFillElem );
1716 QDomElement graphicElem = doc.createElement( QStringLiteral(
"se:Graphic" ) );
1717 graphicFillElem.appendChild( graphicElem );
1719 QColor fillColor = patternName.startsWith( QLatin1String(
"brush://" ) ) ? color : QColor();
1720 QColor strokeColor = !patternName.startsWith( QLatin1String(
"brush://" ) ) ? color : QColor();
1723 wellKnownMarkerToSld( doc, graphicElem, patternName, fillColor, strokeColor, Qt::SolidLine, -1, -1 );
1730 brushStyle = Qt::SolidPattern;
1731 color = QColor( 128, 128, 128 );
1733 if ( element.isNull() )
1735 brushStyle = Qt::NoBrush;
1740 QDomElement graphicFillElem = element.firstChildElement( QStringLiteral(
"GraphicFill" ) );
1742 if ( graphicFillElem.isNull() )
1745 for ( QgsStringMap::iterator it = svgParams.begin(); it != svgParams.end(); ++it )
1747 QgsDebugMsg( QString(
"found SvgParameter %1: %2" ).arg( it.key(), it.value() ) );
1749 if ( it.key() == QLatin1String(
"fill" ) )
1750 color = QColor( it.value() );
1751 else if ( it.key() == QLatin1String(
"fill-opacity" ) )
1757 QDomElement graphicElem = graphicFillElem.firstChildElement( QStringLiteral(
"Graphic" ) );
1758 if ( graphicElem.isNull() )
1761 QString patternName = QStringLiteral(
"square" );
1762 QColor fillColor, strokeColor;
1763 double strokeWidth, size;
1764 Qt::PenStyle strokeStyle;
1765 if ( !
wellKnownMarkerFromSld( graphicElem, patternName, fillColor, strokeColor, strokeStyle, strokeWidth, size ) )
1769 if ( brushStyle == Qt::NoBrush )
1772 QColor c = patternName.startsWith( QLatin1String(
"brush://" ) ) ? fillColor : strokeColor;
1781 Qt::PenStyle penStyle,
const QColor &color,
double width,
1782 const Qt::PenJoinStyle *penJoinStyle,
const Qt::PenCapStyle *penCapStyle,
1783 const QVector<qreal> *customDashPattern,
double dashOffset )
1785 QVector<qreal> dashPattern;
1786 const QVector<qreal> *pattern = &dashPattern;
1788 if ( penStyle == Qt::CustomDashLine && !customDashPattern )
1790 element.appendChild( doc.createComment( QStringLiteral(
"WARNING: Custom dash pattern required but not provided. Using default dash pattern." ) ) );
1791 penStyle = Qt::DashLine;
1803 dashPattern.push_back( 4.0 );
1804 dashPattern.push_back( 2.0 );
1807 dashPattern.push_back( 1.0 );
1808 dashPattern.push_back( 2.0 );
1810 case Qt::DashDotLine:
1811 dashPattern.push_back( 4.0 );
1812 dashPattern.push_back( 2.0 );
1813 dashPattern.push_back( 1.0 );
1814 dashPattern.push_back( 2.0 );
1816 case Qt::DashDotDotLine:
1817 dashPattern.push_back( 4.0 );
1818 dashPattern.push_back( 2.0 );
1819 dashPattern.push_back( 1.0 );
1820 dashPattern.push_back( 2.0 );
1821 dashPattern.push_back( 1.0 );
1822 dashPattern.push_back( 2.0 );
1825 case Qt::CustomDashLine:
1826 Q_ASSERT( customDashPattern );
1827 pattern = customDashPattern;
1831 element.appendChild( doc.createComment( QStringLiteral(
"Qt::BrushStyle '%1'' not supported yet" ).arg( penStyle ) ) );
1835 if ( color.isValid() )
1838 if ( color.alpha() < 255 )
1845 else if ( width == 0 )
1855 if ( !pattern->isEmpty() )
1865 Qt::PenStyle &penStyle, QColor &color,
double &width,
1866 Qt::PenJoinStyle *penJoinStyle, Qt::PenCapStyle *penCapStyle,
1867 QVector<qreal> *customDashPattern,
double *dashOffset )
1871 penStyle = Qt::SolidLine;
1872 color = QColor( 0, 0, 0 );
1875 *penJoinStyle = Qt::BevelJoin;
1877 *penCapStyle = Qt::SquareCap;
1878 if ( customDashPattern )
1879 customDashPattern->clear();
1883 if ( element.isNull() )
1885 penStyle = Qt::NoPen;
1891 for ( QgsStringMap::iterator it = svgParams.begin(); it != svgParams.end(); ++it )
1893 QgsDebugMsg( QString(
"found SvgParameter %1: %2" ).arg( it.key(), it.value() ) );
1895 if ( it.key() == QLatin1String(
"stroke" ) )
1897 color = QColor( it.value() );
1899 else if ( it.key() == QLatin1String(
"stroke-opacity" ) )
1903 else if ( it.key() == QLatin1String(
"stroke-width" ) )
1906 double w = it.value().toDouble( &ok );
1910 else if ( it.key() == QLatin1String(
"stroke-linejoin" ) && penJoinStyle )
1914 else if ( it.key() == QLatin1String(
"stroke-linecap" ) && penCapStyle )
1918 else if ( it.key() == QLatin1String(
"stroke-dasharray" ) )
1921 if ( !dashPattern.isEmpty() )
1925 bool dashPatternFound =
false;
1927 if ( dashPattern.count() == 2 )
1929 if ( dashPattern.at( 0 ) == 4.0 &&
1930 dashPattern.at( 1 ) == 2.0 )
1932 penStyle = Qt::DashLine;
1933 dashPatternFound =
true;
1935 else if ( dashPattern.at( 0 ) == 1.0 &&
1936 dashPattern.at( 1 ) == 2.0 )
1938 penStyle = Qt::DotLine;
1939 dashPatternFound =
true;
1942 else if ( dashPattern.count() == 4 )
1944 if ( dashPattern.at( 0 ) == 4.0 &&
1945 dashPattern.at( 1 ) == 2.0 &&
1946 dashPattern.at( 2 ) == 1.0 &&
1947 dashPattern.at( 3 ) == 2.0 )
1949 penStyle = Qt::DashDotLine;
1950 dashPatternFound =
true;
1953 else if ( dashPattern.count() == 6 )
1955 if ( dashPattern.at( 0 ) == 4.0 &&
1956 dashPattern.at( 1 ) == 2.0 &&
1957 dashPattern.at( 2 ) == 1.0 &&
1958 dashPattern.at( 3 ) == 2.0 &&
1959 dashPattern.at( 4 ) == 1.0 &&
1960 dashPattern.at( 5 ) == 2.0 )
1962 penStyle = Qt::DashDotDotLine;
1963 dashPatternFound =
true;
1968 if ( !dashPatternFound )
1970 if ( customDashPattern )
1972 penStyle = Qt::CustomDashLine;
1973 *customDashPattern = dashPattern;
1977 QgsDebugMsg(
"custom dash pattern required but not provided. Using default dash pattern." );
1978 penStyle = Qt::DashLine;
1983 else if ( it.key() == QLatin1String(
"stroke-dashoffset" ) && dashOffset )
1986 double d = it.value().toDouble( &ok );
1996 const QString &path,
const QString &mime,
1997 const QColor &color,
double size )
1999 QDomElement externalGraphicElem = doc.createElement( QStringLiteral(
"se:ExternalGraphic" ) );
2000 element.appendChild( externalGraphicElem );
2009 QDomElement sizeElem = doc.createElement( QStringLiteral(
"se:Size" ) );
2011 element.appendChild( sizeElem );
2016 const QString &path,
const QColor &fillColor,
double size,
const QColor &strokeColor,
double strokeWidth )
2023 graphicElem.appendChild( doc.createComment( QStringLiteral(
"Parametric SVG" ) ) );
2027 graphicElem.appendChild( doc.createComment( QStringLiteral(
"Plain SVG fallback, no parameters" ) ) );
2030 graphicElem.appendChild( doc.createComment( QStringLiteral(
"Well known marker fallback" ) ) );
2036 QDomElement sizeElem = doc.createElement( QStringLiteral(
"se:Size" ) );
2038 graphicElem.appendChild( sizeElem );
2046 if ( fillColor.isValid() )
2048 url.addQueryItem( QStringLiteral(
"fill" ), fillColor.name() );
2049 url.addQueryItem( QStringLiteral(
"fill-opacity" ),
encodeSldAlpha( fillColor.alpha() ) );
2053 url.addQueryItem( QStringLiteral(
"fill" ), QStringLiteral(
"#000000" ) );
2054 url.addQueryItem( QStringLiteral(
"fill-opacity" ), QStringLiteral(
"1" ) );
2056 if ( strokeColor.isValid() )
2058 url.addQueryItem( QStringLiteral(
"outline" ), strokeColor.name() );
2059 url.addQueryItem( QStringLiteral(
"outline-opacity" ),
encodeSldAlpha( strokeColor.alpha() ) );
2063 url.addQueryItem( QStringLiteral(
"outline" ), QStringLiteral(
"#000000" ) );
2064 url.addQueryItem( QStringLiteral(
"outline-opacity" ), QStringLiteral(
"1" ) );
2066 url.addQueryItem( QStringLiteral(
"outline-width" ), QString::number( strokeWidth ) );
2067 QString params = url.encodedQuery();
2068 if ( params.isEmpty() )
2074 return basePath +
"?" + params;
2079 QString &path, QString &mime,
2080 QColor &color,
double &size )
2085 QDomElement externalGraphicElem = element.firstChildElement( QStringLiteral(
"ExternalGraphic" ) );
2086 if ( externalGraphicElem.isNull() )
2091 QDomElement sizeElem = element.firstChildElement( QStringLiteral(
"Size" ) );
2092 if ( !sizeElem.isNull() )
2095 double s = sizeElem.firstChild().nodeValue().toDouble( &ok );
2104 const QString &path,
const QString &format,
int *markIndex,
2105 const QColor &color,
double size )
2107 QDomElement markElem = doc.createElement( QStringLiteral(
"se:Mark" ) );
2108 element.appendChild( markElem );
2114 QDomElement markIndexElem = doc.createElement( QStringLiteral(
"se:MarkIndex" ) );
2115 markIndexElem.appendChild( doc.createTextNode( QString::number( *markIndex ) ) );
2116 markElem.appendChild( markIndexElem );
2120 QDomElement fillElem = doc.createElement( QStringLiteral(
"se:Fill" ) );
2121 fillToSld( doc, fillElem, Qt::SolidPattern, color );
2122 markElem.appendChild( fillElem );
2127 QDomElement sizeElem = doc.createElement( QStringLiteral(
"se:Size" ) );
2129 element.appendChild( sizeElem );
2134 QString &path, QString &format,
int &markIndex,
2135 QColor &color,
double &size )
2143 QDomElement markElem = element.firstChildElement( QStringLiteral(
"Mark" ) );
2144 if ( markElem.isNull() )
2149 QDomElement markIndexElem = markElem.firstChildElement( QStringLiteral(
"MarkIndex" ) );
2150 if ( !markIndexElem.isNull() )
2153 int i = markIndexElem.firstChild().nodeValue().toInt( &ok );
2159 QDomElement fillElem = markElem.firstChildElement( QStringLiteral(
"Fill" ) );
2160 Qt::BrushStyle b = Qt::SolidPattern;
2165 QDomElement sizeElem = element.firstChildElement( QStringLiteral(
"Size" ) );
2166 if ( !sizeElem.isNull() )
2169 double s = sizeElem.firstChild().nodeValue().toDouble( &ok );
2178 const QString &name,
const QColor &color,
const QColor &strokeColor, Qt::PenStyle strokeStyle,
2179 double strokeWidth,
double size )
2181 QDomElement markElem = doc.createElement( QStringLiteral(
"se:Mark" ) );
2182 element.appendChild( markElem );
2184 QDomElement wellKnownNameElem = doc.createElement( QStringLiteral(
"se:WellKnownName" ) );
2185 wellKnownNameElem.appendChild( doc.createTextNode( name ) );
2186 markElem.appendChild( wellKnownNameElem );
2189 if ( color.isValid() )
2191 QDomElement fillElem = doc.createElement( QStringLiteral(
"se:Fill" ) );
2192 fillToSld( doc, fillElem, Qt::SolidPattern, color );
2193 markElem.appendChild( fillElem );
2197 if ( strokeColor.isValid() )
2199 QDomElement strokeElem = doc.createElement( QStringLiteral(
"se:Stroke" ) );
2200 lineToSld( doc, strokeElem, strokeStyle, strokeColor, strokeWidth );
2201 markElem.appendChild( strokeElem );
2207 QDomElement sizeElem = doc.createElement( QStringLiteral(
"se:Size" ) );
2209 element.appendChild( sizeElem );
2214 QString &name, QColor &color, QColor &strokeColor, Qt::PenStyle &strokeStyle,
2215 double &strokeWidth,
double &size )
2219 name = QStringLiteral(
"square" );
2221 strokeColor = QColor( 0, 0, 0 );
2225 QDomElement markElem = element.firstChildElement( QStringLiteral(
"Mark" ) );
2226 if ( markElem.isNull() )
2229 QDomElement wellKnownNameElem = markElem.firstChildElement( QStringLiteral(
"WellKnownName" ) );
2230 if ( !wellKnownNameElem.isNull() )
2232 name = wellKnownNameElem.firstChild().nodeValue();
2233 QgsDebugMsg(
"found Mark with well known name: " + name );
2237 QDomElement fillElem = markElem.firstChildElement( QStringLiteral(
"Fill" ) );
2238 Qt::BrushStyle b = Qt::SolidPattern;
2243 QDomElement strokeElem = markElem.firstChildElement( QStringLiteral(
"Stroke" ) );
2244 lineFromSld( strokeElem, strokeStyle, strokeColor, strokeWidth );
2248 QDomElement sizeElem = element.firstChildElement( QStringLiteral(
"Size" ) );
2249 if ( !sizeElem.isNull() )
2252 double s = sizeElem.firstChild().nodeValue().toDouble( &ok );
2262 if ( !rotationFunc.isEmpty() )
2264 QDomElement rotationElem = doc.createElement( QStringLiteral(
"se:Rotation" ) );
2266 element.appendChild( rotationElem );
2272 QDomElement rotationElem = element.firstChildElement( QStringLiteral(
"Rotation" ) );
2273 if ( !rotationElem.isNull() )
2283 if ( !alphaFunc.isEmpty() )
2285 QDomElement opacityElem = doc.createElement( QStringLiteral(
"se:Opacity" ) );
2287 element.appendChild( opacityElem );
2293 QDomElement opacityElem = element.firstChildElement( QStringLiteral(
"Opacity" ) );
2294 if ( !opacityElem.isNull() )
2303 if ( offset.isNull() )
2306 QDomElement displacementElem = doc.createElement( QStringLiteral(
"se:Displacement" ) );
2307 element.appendChild( displacementElem );
2309 QDomElement dispXElem = doc.createElement( QStringLiteral(
"se:DisplacementX" ) );
2310 dispXElem.appendChild( doc.createTextNode(
qgsDoubleToString( offset.x(), 2 ) ) );
2312 QDomElement dispYElem = doc.createElement( QStringLiteral(
"se:DisplacementY" ) );
2313 dispYElem.appendChild( doc.createTextNode(
qgsDoubleToString( offset.y(), 2 ) ) );
2315 displacementElem.appendChild( dispXElem );
2316 displacementElem.appendChild( dispYElem );
2323 QDomElement anchorElem = doc.createElement( QStringLiteral(
"se:AnchorPoint" ) );
2324 element.appendChild( anchorElem );
2326 QDomElement anchorXElem = doc.createElement( QStringLiteral(
"se:AnchorPointX" ) );
2327 anchorXElem.appendChild( doc.createTextNode(
qgsDoubleToString( anchor.x() ) ) );
2329 QDomElement anchorYElem = doc.createElement( QStringLiteral(
"se:AnchorPointY" ) );
2330 anchorYElem.appendChild( doc.createTextNode(
qgsDoubleToString( anchor.y() ) ) );
2332 anchorElem.appendChild( anchorXElem );
2333 anchorElem.appendChild( anchorYElem );
2338 offset = QPointF( 0, 0 );
2340 QDomElement displacementElem = element.firstChildElement( QStringLiteral(
"Displacement" ) );
2341 if ( displacementElem.isNull() )
2344 QDomElement dispXElem = displacementElem.firstChildElement( QStringLiteral(
"DisplacementX" ) );
2345 if ( !dispXElem.isNull() )
2348 double offsetX = dispXElem.firstChild().nodeValue().toDouble( &ok );
2350 offset.setX( offsetX );
2353 QDomElement dispYElem = displacementElem.firstChildElement( QStringLiteral(
"DisplacementY" ) );
2354 if ( !dispYElem.isNull() )
2357 double offsetY = dispYElem.firstChild().nodeValue().toDouble( &ok );
2359 offset.setY( offsetY );
2366 const QString &label,
const QFont &font,
2367 const QColor &color,
double size )
2369 QDomElement labelElem = doc.createElement( QStringLiteral(
"se:Label" ) );
2370 labelElem.appendChild( doc.createTextNode( label ) );
2371 element.appendChild( labelElem );
2373 QDomElement fontElem = doc.createElement( QStringLiteral(
"se:Font" ) );
2374 element.appendChild( fontElem );
2378 fontElem.appendChild( createSldParameterElement( doc,
"font-style",
encodeSldFontStyle( font.style() ) ) );
2379 fontElem.appendChild( createSldParameterElement( doc,
"font-weight",
encodeSldFontWeight( font.weight() ) ) );
2384 if ( color.isValid() )
2386 QDomElement fillElem = doc.createElement( QStringLiteral(
"Fill" ) );
2387 fillToSld( doc, fillElem, Qt::SolidPattern, color );
2388 element.appendChild( fillElem );
2393 Qt::PenJoinStyle joinStyle,
2394 Qt::PenCapStyle capStyle,
2396 const QVector<qreal> *dashPattern )
2399 penStyle.append(
"PEN(" );
2400 penStyle.append(
"c:" );
2401 penStyle.append( c.name() );
2402 penStyle.append(
",w:" );
2404 penStyle.append( QString::number( width * mmScaleFactor ) );
2405 penStyle.append(
"mm" );
2408 if ( dashPattern && !dashPattern->isEmpty() )
2410 penStyle.append(
",p:\"" );
2411 QVector<qreal>::const_iterator pIt = dashPattern->constBegin();
2412 for ( ; pIt != dashPattern->constEnd(); ++pIt )
2414 if ( pIt != dashPattern->constBegin() )
2416 penStyle.append(
' ' );
2418 penStyle.append( QString::number( *pIt * mapUnitScaleFactor ) );
2419 penStyle.append(
'g' );
2421 penStyle.append(
'\"' );
2425 penStyle.append(
",cap:" );
2429 penStyle.append(
'p' );
2432 penStyle.append(
'r' );
2436 penStyle.append(
'b' );
2440 penStyle.append(
",j:" );
2441 switch ( joinStyle )
2444 penStyle.append(
'b' );
2447 penStyle.append(
'r' );
2451 penStyle.append(
'm' );
2457 penStyle.append(
",dp:" );
2458 penStyle.append( QString::number( offset * mapUnitScaleFactor ) );
2459 penStyle.append(
'g' );
2462 penStyle.append(
')' );
2469 brushStyle.append(
"BRUSH(" );
2470 brushStyle.append(
"fc:" );
2471 brushStyle.append( fillColor.name() );
2472 brushStyle.append(
')' );
2478 if ( geomFunc.isEmpty() )
2481 QDomElement geometryElem = doc.createElement( QStringLiteral(
"Geometry" ) );
2482 element.appendChild( geometryElem );
2512 QDomElement geometryElem = element.firstChildElement( QStringLiteral(
"Geometry" ) );
2513 if ( geometryElem.isNull() )
2522 QgsExpression expr(
function );
2523 if ( expr.hasParserError() )
2525 element.appendChild( doc.createComment(
"Parser Error: " + expr.parserErrorString() +
" - Expression was: " + function ) );
2529 if ( !filterElem.isNull() )
2530 element.appendChild( filterElem );
2538 QgsExpression expr(
function );
2539 if ( expr.hasParserError() )
2541 element.appendChild( doc.createComment(
"Parser Error: " + expr.parserErrorString() +
" - Expression was: " + function ) );
2545 if ( !filterElem.isNull() )
2546 element.appendChild( filterElem );
2553 QDomElement elem = element;
2554 if ( element.tagName() != QLatin1String(
"Filter" ) )
2556 QDomNodeList filterNodes = element.elementsByTagName( QStringLiteral(
"Filter" ) );
2557 if ( !filterNodes.isEmpty() )
2559 elem = filterNodes.at( 0 ).toElement();
2563 if ( elem.isNull() )
2573 bool valid = !expr->hasParserError();
2576 QgsDebugMsg(
"parser error: " + expr->parserErrorString() );
2580 function = expr->expression();
2588 const QString &path,
const QString &format )
2592 QDomElement onlineResourceElem = doc.createElement( QStringLiteral(
"se:OnlineResource" ) );
2593 onlineResourceElem.setAttribute( QStringLiteral(
"xlink:type" ), QStringLiteral(
"simple" ) );
2594 onlineResourceElem.setAttribute( QStringLiteral(
"xlink:href" ), url );
2595 element.appendChild( onlineResourceElem );
2597 QDomElement formatElem = doc.createElement( QStringLiteral(
"se:Format" ) );
2598 formatElem.appendChild( doc.createTextNode( format ) );
2599 element.appendChild( formatElem );
2606 QDomElement onlineResourceElem = element.firstChildElement( QStringLiteral(
"OnlineResource" ) );
2607 if ( onlineResourceElem.isNull() )
2610 path = onlineResourceElem.attributeNS( QStringLiteral(
"http://www.w3.org/1999/xlink" ), QStringLiteral(
"href" ) );
2612 QDomElement formatElem = element.firstChildElement( QStringLiteral(
"Format" ) );
2613 if ( formatElem.isNull() )
2616 format = formatElem.firstChild().nodeValue();
2623 QDomElement nodeElem = doc.createElement( QStringLiteral(
"se:SvgParameter" ) );
2624 nodeElem.setAttribute( QStringLiteral(
"name" ), name );
2625 nodeElem.appendChild( doc.createTextNode( value ) );
2634 QDomElement paramElem = element.firstChildElement();
2635 while ( !paramElem.isNull() )
2637 if ( paramElem.localName() == QLatin1String(
"SvgParameter" ) || paramElem.localName() == QLatin1String(
"CssParameter" ) )
2639 QString name = paramElem.attribute( QStringLiteral(
"name" ) );
2640 if ( paramElem.firstChild().nodeType() == QDomNode::TextNode )
2642 value = paramElem.firstChild().nodeValue();
2646 if ( paramElem.firstChild().nodeType() == QDomNode::ElementNode &&
2647 paramElem.firstChild().localName() == QLatin1String(
"Literal" ) )
2649 QgsDebugMsg( paramElem.firstChild().localName() );
2650 value = paramElem.firstChild().firstChild().nodeValue();
2654 QgsDebugMsg( QString(
"unexpected child of %1" ).arg( paramElem.localName() ) );
2658 if ( !name.isEmpty() && !value.isEmpty() )
2659 params[ name ] = value;
2662 paramElem = paramElem.nextSiblingElement();
2670 QDomElement nodeElem = doc.createElement( QStringLiteral(
"se:VendorOption" ) );
2671 nodeElem.setAttribute( QStringLiteral(
"name" ), name );
2672 nodeElem.appendChild( doc.createTextNode( value ) );
2680 QDomElement paramElem = element.firstChildElement( QStringLiteral(
"VendorOption" ) );
2681 while ( !paramElem.isNull() )
2683 QString name = paramElem.attribute( QStringLiteral(
"name" ) );
2684 QString value = paramElem.firstChild().nodeValue();
2686 if ( !name.isEmpty() && !value.isEmpty() )
2687 params[ name ] = value;
2689 paramElem = paramElem.nextSiblingElement( QStringLiteral(
"VendorOption" ) );
2699 QDomElement e = element.firstChildElement();
2700 while ( !e.isNull() )
2702 if ( e.tagName() == QLatin1String(
"prop" ) )
2704 QString propKey = e.attribute( QStringLiteral(
"k" ) );
2705 QString propValue = e.attribute( QStringLiteral(
"v" ) );
2706 props[propKey] = propValue;
2708 e = e.nextSiblingElement();
2716 for ( QgsStringMap::iterator it = props.begin(); it != props.end(); ++it )
2718 QDomElement propEl = doc.createElement( QStringLiteral(
"prop" ) );
2719 propEl.setAttribute( QStringLiteral(
"k" ), it.key() );
2720 propEl.setAttribute( QStringLiteral(
"v" ), it.value() );
2721 element.appendChild( propEl );
2730 QDomElement e = element.firstChildElement();
2732 while ( !e.isNull() )
2734 if ( e.tagName() == QLatin1String(
"symbol" ) )
2738 symbols.insert( e.attribute( QStringLiteral(
"name" ) ), symbol );
2744 e = e.nextSiblingElement();
2751 QStringList subsymbols;
2753 for ( QMap<QString, QgsSymbol *>::iterator it = symbols.begin(); it != symbols.end(); ++it )
2755 if ( it.key()[0] !=
'@' )
2759 subsymbols.append( it.key() );
2761 QStringList parts = it.key().split(
'@' );
2762 if ( parts.count() < 3 )
2764 QgsDebugMsg(
"found subsymbol with invalid name: " + it.key() );
2768 QString symname = parts[1];
2769 int symlayer = parts[2].toInt();
2771 if ( !symbols.contains( symname ) )
2773 QgsDebugMsg(
"subsymbol references invalid symbol: " + symname );
2781 QgsDebugMsg(
"subsymbol references invalid symbol layer: " + QString::number( symlayer ) );
2790 QgsDebugMsg(
"symbol layer refused subsymbol: " + it.key() );
2797 for (
int i = 0; i < subsymbols.count(); i++ )
2798 symbols.take( subsymbols[i] );
2805 QDomElement symbolsElem = doc.createElement( tagName );
2808 for ( QMap<QString, QgsSymbol *>::iterator its = symbols.begin(); its != symbols.end(); ++its )
2810 QDomElement symEl =
saveSymbol( its.key(), its.value(), doc, context );
2811 symbolsElem.appendChild( symEl );
2819 qDeleteAll( symbols );
2828 std::unique_ptr< QMimeData >mimeData(
new QMimeData );
2830 QDomDocument symbolDoc;
2832 symbolDoc.appendChild( symbolElem );
2833 mimeData->setText( symbolDoc.toString() );
2836 mimeData->setColorData( symbol->
color() );
2838 return mimeData.release();
2846 QString text = data->text();
2847 if ( !text.isEmpty() )
2852 if ( doc.setContent( text ) )
2854 elem = doc.documentElement();
2856 if ( elem.nodeName() != QStringLiteral(
"symbol" ) )
2857 elem = elem.firstChildElement( QStringLiteral(
"symbol" ) );
2868 QString rampType = element.attribute( QStringLiteral(
"type" ) );
2873 if ( rampType == QLatin1String(
"gradient" ) )
2875 else if ( rampType == QLatin1String(
"random" ) )
2877 else if ( rampType == QLatin1String(
"colorbrewer" ) )
2879 else if ( rampType == QLatin1String(
"cpt-city" ) )
2881 else if ( rampType == QLatin1String(
"preset" ) )
2885 QgsDebugMsg(
"unknown colorramp type " + rampType );
2893 QDomElement rampEl = doc.createElement( QStringLiteral(
"colorramp" ) );
2894 rampEl.setAttribute( QStringLiteral(
"type" ), ramp->
type() );
2895 rampEl.setAttribute( QStringLiteral(
"name" ), name );
2903 QVariantMap rampMap;
2905 rampMap.insert( QStringLiteral(
"type" ), ramp->
type() );
2906 rampMap.insert( QStringLiteral(
"name" ), name );
2910 QVariantMap propertyMap;
2911 for (
auto property = properties.constBegin();
property != properties.constEnd(); ++property )
2913 propertyMap.insert( property.key(),
property.value() );
2916 rampMap.insert( QStringLiteral(
"properties" ), propertyMap );
2922 QVariantMap rampMap = value.toMap();
2924 QString rampType = rampMap.
value( QStringLiteral(
"type" ) ).toString();
2927 QVariantMap propertyMap = rampMap.value( QStringLiteral(
"properties" ) ).toMap();
2930 for (
auto property = propertyMap.constBegin();
property != propertyMap.constEnd(); ++property )
2932 props.insert( property.key(),
property.value().toString() );
2935 if ( rampType == QLatin1String(
"gradient" ) )
2937 else if ( rampType == QLatin1String(
"random" ) )
2939 else if ( rampType == QLatin1String(
"colorbrewer" ) )
2941 else if ( rampType == QLatin1String(
"cpt-city" ) )
2943 else if ( rampType == QLatin1String(
"preset" ) )
2947 QgsDebugMsg(
"unknown colorramp type " + rampType );
2954 if ( !color.isValid() )
2961 return color.name();
2966 QList<QColor> colors;
2969 QStringList components = colorStr.simplified().split( QRegExp(
"(,|\\s)" ) );
2970 QStringList::iterator it = components.begin();
2971 for ( ; it != components.end(); ++it )
2974 if ( result.isValid() )
2979 if ( colors.length() > 0 )
2985 components = colorStr.split( QRegExp(
"(,|\n)" ) );
2986 it = components.begin();
2987 for ( ; it != components.end(); ++it )
2990 if ( result.isValid() )
2995 if ( colors.length() > 0 )
3001 components = colorStr.simplified().split( QString(
' ' ) );
3002 it = components.begin();
3003 for ( ; it != components.end(); ++it )
3006 if ( result.isValid() )
3011 if ( colors.length() > 0 )
3017 components = colorStr.split(
'\n' );
3018 it = components.begin();
3019 for ( ; it != components.end(); ++it )
3022 if ( result.isValid() )
3035 QMimeData *mimeData =
new QMimeData;
3036 mimeData->setColorData( QVariant( color ) );
3037 mimeData->setText( color.name() );
3044 QColor mimeColor = mimeData->colorData().value<QColor>();
3045 if ( mimeColor.isValid() )
3054 if ( textColor.isValid() )
3068 if ( data->hasFormat( QStringLiteral(
"text/xml" ) ) )
3071 QByteArray encodedData = data->data( QStringLiteral(
"text/xml" ) );
3072 QDomDocument xmlDoc;
3073 xmlDoc.setContent( encodedData );
3075 QDomElement dragDataElem = xmlDoc.documentElement();
3076 if ( dragDataElem.tagName() == QLatin1String(
"ColorSchemeModelDragData" ) )
3078 QDomNodeList nodeList = dragDataElem.childNodes();
3079 int nChildNodes = nodeList.size();
3080 QDomElement currentElem;
3082 for (
int i = 0; i < nChildNodes; ++i )
3084 currentElem = nodeList.at( i ).toElement();
3085 if ( currentElem.isNull() )
3090 QPair< QColor, QString> namedColor;
3092 namedColor.second = currentElem.attribute( QStringLiteral(
"label" ), QLatin1String(
"" ) );
3094 mimeColors << namedColor;
3099 if ( mimeColors.length() == 0 && data->hasFormat( QStringLiteral(
"application/x-colorobject-list" ) ) )
3102 QByteArray encodedData = data->data( QStringLiteral(
"application/x-colorobject-list" ) );
3103 QDomDocument xmlDoc;
3104 xmlDoc.setContent( encodedData );
3106 QDomNodeList colorsNodes = xmlDoc.elementsByTagName( QStringLiteral(
"colors" ) );
3107 if ( colorsNodes.length() > 0 )
3109 QDomElement colorsElem = colorsNodes.at( 0 ).toElement();
3110 QDomNodeList colorNodeList = colorsElem.childNodes();
3111 int nChildNodes = colorNodeList.size();
3112 QDomElement currentElem;
3114 for (
int i = 0; i < nChildNodes; ++i )
3117 currentElem = colorNodeList.at( i ).toElement();
3118 if ( currentElem.isNull() )
3123 QDomNodeList colorNodes = currentElem.elementsByTagName( QStringLiteral(
"color" ) );
3124 QDomNodeList nameNodes = currentElem.elementsByTagName( QStringLiteral(
"name" ) );
3126 if ( colorNodes.length() > 0 )
3128 QDomElement colorElem = colorNodes.at( 0 ).toElement();
3130 QStringList colorParts = colorElem.text().simplified().split(
' ' );
3131 if ( colorParts.length() < 3 )
3136 int red = colorParts.at( 0 ).toDouble() * 255;
3137 int green = colorParts.at( 1 ).toDouble() * 255;
3138 int blue = colorParts.at( 2 ).toDouble() * 255;
3139 QPair< QColor, QString> namedColor;
3140 namedColor.first = QColor( red, green, blue );
3141 if ( nameNodes.length() > 0 )
3143 QDomElement nameElem = nameNodes.at( 0 ).toElement();
3144 namedColor.second = nameElem.text();
3146 mimeColors << namedColor;
3152 if ( mimeColors.length() == 0 && data->hasText() )
3156 QList< QColor >::iterator it = parsedColors.begin();
3157 for ( ; it != parsedColors.end(); ++it )
3159 mimeColors << qMakePair( *it, QString() );
3163 if ( mimeColors.length() == 0 && data->hasColor() )
3166 QColor mimeColor = data->colorData().value<QColor>();
3167 if ( mimeColor.isValid() )
3169 mimeColors << qMakePair( mimeColor, QString() );
3179 QMimeData *mimeData =
new QMimeData();
3180 QDomDocument xmlDoc;
3181 QDomElement xmlRootElement = xmlDoc.createElement( QStringLiteral(
"ColorSchemeModelDragData" ) );
3182 xmlDoc.appendChild( xmlRootElement );
3184 QgsNamedColorList::const_iterator colorIt = colorList.constBegin();
3185 for ( ; colorIt != colorList.constEnd(); ++colorIt )
3187 QDomElement namedColor = xmlDoc.createElement( QStringLiteral(
"NamedColor" ) );
3189 namedColor.setAttribute( QStringLiteral(
"label" ), ( *colorIt ).second );
3190 xmlRootElement.appendChild( namedColor );
3192 mimeData->setData( QStringLiteral(
"text/xml" ), xmlDoc.toByteArray() );
3200 colorIt = colorList.constBegin();
3201 QStringList colorListString;
3202 for ( ; colorIt != colorList.constEnd(); ++colorIt )
3204 colorListString << ( *colorIt ).first.name();
3206 mimeData->setText( colorListString.join( QStringLiteral(
"\n" ) ) );
3209 if ( colorList.length() > 0 )
3211 mimeData->setColorData( QVariant( colorList.at( 0 ).first ) );
3219 if ( !file.open( QIODevice::WriteOnly | QIODevice::Truncate ) )
3224 QTextStream stream( &file );
3225 stream <<
"GIMP Palette" << endl;
3226 if ( paletteName.isEmpty() )
3228 stream <<
"Name: QGIS Palette" << endl;
3232 stream <<
"Name: " << paletteName << endl;
3234 stream <<
"Columns: 4" << endl;
3235 stream <<
'#' << endl;
3237 for ( QgsNamedColorList::ConstIterator colorIt = colors.constBegin(); colorIt != colors.constEnd(); ++colorIt )
3239 QColor color = ( *colorIt ).first;
3240 if ( !color.isValid() )
3244 stream << QStringLiteral(
"%1 %2 %3" ).arg( color.red(), 3 ).arg( color.green(), 3 ).arg( color.blue(), 3 );
3245 stream <<
"\t" << ( ( *colorIt ).second.isEmpty() ? color.name() : ( *colorIt ).second ) << endl;
3256 if ( !file.open( QIODevice::ReadOnly ) )
3259 return importedColors;
3262 QTextStream in( &file );
3264 QString line = in.readLine();
3265 if ( !line.startsWith( QLatin1String(
"GIMP Palette" ) ) )
3268 return importedColors;
3272 while ( !in.atEnd() && !line.startsWith( QLatin1String(
"Name:" ) ) && !line.startsWith(
'#' ) )
3274 line = in.readLine();
3276 if ( line.startsWith( QLatin1String(
"Name:" ) ) )
3278 QRegExp nameRx(
"Name:\\s*(\\S.*)$" );
3279 if ( nameRx.indexIn( line ) != -1 )
3281 name = nameRx.cap( 1 );
3286 while ( !in.atEnd() && !line.startsWith(
'#' ) )
3288 line = in.readLine();
3293 return importedColors;
3297 QRegExp rx(
"^\\s*(\\d+)\\s+(\\d+)\\s+(\\d+)(\\s.*)?$" );
3298 while ( !in.atEnd() )
3300 line = in.readLine();
3301 if ( rx.indexIn( line ) == -1 )
3305 int red = rx.cap( 1 ).toInt();
3306 int green = rx.cap( 2 ).toInt();
3307 int blue = rx.cap( 3 ).toInt();
3308 QColor color = QColor( red, green, blue );
3309 if ( !color.isValid() )
3316 if ( rx.captureCount() > 3 )
3318 label = rx.cap( 4 ).simplified();
3325 importedColors << qMakePair( color, label );
3330 return importedColors;
3343 QRegExp hexColorAlphaRx(
"^\\s*#?([0-9a-fA-F]{6})([0-9a-fA-F]{2})\\s*$" );
3344 int hexColorIndex = hexColorAlphaRx.indexIn( colorStr );
3347 if ( hexColorIndex == -1 && QColor::isValidColor( colorStr ) )
3350 parsedColor.setNamedColor( colorStr );
3351 if ( parsedColor.isValid() )
3353 containsAlpha =
false;
3359 if ( hexColorIndex > -1 )
3361 QString hexColor = hexColorAlphaRx.cap( 1 );
3362 parsedColor.setNamedColor( QStringLiteral(
"#" ) + hexColor );
3364 int alphaHex = hexColorAlphaRx.cap( 2 ).toInt( &alphaOk, 16 );
3366 if ( parsedColor.isValid() && alphaOk )
3368 parsedColor.setAlpha( alphaHex );
3369 containsAlpha =
true;
3377 QRegExp hexColorRx2(
"^\\s*(?:[0-9a-fA-F]{3}){1,2}\\s*$" );
3378 if ( hexColorRx2.indexIn( colorStr ) != -1 )
3381 parsedColor.setNamedColor( QStringLiteral(
"#" ) + colorStr );
3382 if ( parsedColor.isValid() )
3384 containsAlpha =
false;
3391 QRegExp rgbFormatRx(
"^\\s*(?:rgb)?\\(?\\s*([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])\\s*,\\s*([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])\\s*,\\s*([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])\\s*\\)?\\s*;?\\s*$" );
3392 if ( rgbFormatRx.indexIn( colorStr ) != -1 )
3394 int r = rgbFormatRx.cap( 1 ).toInt();
3395 int g = rgbFormatRx.cap( 2 ).toInt();
3396 int b = rgbFormatRx.cap( 3 ).toInt();
3397 parsedColor.setRgb( r, g, b );
3398 if ( parsedColor.isValid() )
3400 containsAlpha =
false;
3406 QRegExp rgbPercentFormatRx(
"^\\s*(?:rgb)?\\(?\\s*(100|0*\\d{1,2})\\s*%\\s*,\\s*(100|0*\\d{1,2})\\s*%\\s*,\\s*(100|0*\\d{1,2})\\s*%\\s*\\)?\\s*;?\\s*$" );
3407 if ( rgbPercentFormatRx.indexIn( colorStr ) != -1 )
3409 int r = std::round( rgbPercentFormatRx.cap( 1 ).toDouble() * 2.55 );
3410 int g = std::round( rgbPercentFormatRx.cap( 2 ).toDouble() * 2.55 );
3411 int b = std::round( rgbPercentFormatRx.cap( 3 ).toDouble() * 2.55 );
3412 parsedColor.setRgb( r, g, b );
3413 if ( parsedColor.isValid() )
3415 containsAlpha =
false;
3421 QRegExp rgbaFormatRx(
"^\\s*(?:rgba)?\\(?\\s*([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])\\s*,\\s*([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])\\s*,\\s*([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])\\s*,\\s*(0|0?\\.\\d*|1(?:\\.0*)?)\\s*\\)?\\s*;?\\s*$" );
3422 if ( rgbaFormatRx.indexIn( colorStr ) != -1 )
3424 int r = rgbaFormatRx.cap( 1 ).toInt();
3425 int g = rgbaFormatRx.cap( 2 ).toInt();
3426 int b = rgbaFormatRx.cap( 3 ).toInt();
3427 int a = std::round( rgbaFormatRx.cap( 4 ).toDouble() * 255.0 );
3428 parsedColor.setRgb( r, g, b, a );
3429 if ( parsedColor.isValid() )
3431 containsAlpha =
true;
3437 QRegExp rgbaPercentFormatRx(
"^\\s*(?:rgba)?\\(?\\s*(100|0*\\d{1,2})\\s*%\\s*,\\s*(100|0*\\d{1,2})\\s*%\\s*,\\s*(100|0*\\d{1,2})\\s*%\\s*,\\s*(0|0?\\.\\d*|1(?:\\.0*)?)\\s*\\)?\\s*;?\\s*$" );
3438 if ( rgbaPercentFormatRx.indexIn( colorStr ) != -1 )
3440 int r = std::round( rgbaPercentFormatRx.cap( 1 ).toDouble() * 2.55 );
3441 int g = std::round( rgbaPercentFormatRx.cap( 2 ).toDouble() * 2.55 );
3442 int b = std::round( rgbaPercentFormatRx.cap( 3 ).toDouble() * 2.55 );
3443 int a = std::round( rgbaPercentFormatRx.cap( 4 ).toDouble() * 255.0 );
3444 parsedColor.setRgb( r, g, b, a );
3445 if ( parsedColor.isValid() )
3447 containsAlpha =
true;
3464 QImage::Format format = image->format();
3465 if ( format != QImage::Format_ARGB32_Premultiplied && format != QImage::Format_ARGB32 )
3472 for (
int heightIndex = 0; heightIndex < image->height(); ++heightIndex )
3474 QRgb *scanLine =
reinterpret_cast< QRgb *
>( image->scanLine( heightIndex ) );
3475 for (
int widthIndex = 0; widthIndex < image->width(); ++widthIndex )
3477 myRgb = scanLine[widthIndex];
3478 if ( format == QImage::Format_ARGB32_Premultiplied )
3479 scanLine[widthIndex] = qRgba( opacity * qRed( myRgb ), opacity * qGreen( myRgb ), opacity * qBlue( myRgb ), opacity * qAlpha( myRgb ) );
3481 scanLine[widthIndex] = qRgba( qRed( myRgb ), qGreen( myRgb ), qBlue( myRgb ), opacity * qAlpha( myRgb ) );
3489 int tab[] = { 14, 10, 8, 6, 5, 5, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2 };
3490 int alpha = ( radius < 1 ) ? 16 : ( radius > 17 ) ? 1 : tab[radius - 1];
3492 if ( image.format() != QImage::Format_ARGB32_Premultiplied
3493 && image.format() != QImage::Format_RGB32 )
3495 image = image.convertToFormat( QImage::Format_ARGB32_Premultiplied );
3498 int r1 = rect.top();
3499 int r2 = rect.bottom();
3500 int c1 = rect.left();
3501 int c2 = rect.right();
3503 int bpl = image.bytesPerLine();
3511 i1 = i2 = ( QSysInfo::ByteOrder == QSysInfo::BigEndian ? 0 : 3 );
3513 for (
int col = c1; col <= c2; col++ )
3515 p = image.scanLine( r1 ) + col * 4;
3516 for (
int i = i1; i <= i2; i++ )
3517 rgba[i] = p[i] << 4;
3520 for (
int j = r1; j < r2; j++, p += bpl )
3521 for (
int i = i1; i <= i2; i++ )
3522 p[i] = ( rgba[i] += ( ( p[i] << 4 ) - rgba[i] ) * alpha / 16 ) >> 4;
3525 for (
int row = r1; row <= r2; row++ )
3527 p = image.scanLine( row ) + c1 * 4;
3528 for (
int i = i1; i <= i2; i++ )
3529 rgba[i] = p[i] << 4;
3532 for (
int j = c1; j < c2; j++, p += 4 )
3533 for (
int i = i1; i <= i2; i++ )
3534 p[i] = ( rgba[i] += ( ( p[i] << 4 ) - rgba[i] ) * alpha / 16 ) >> 4;
3537 for (
int col = c1; col <= c2; col++ )
3539 p = image.scanLine( r2 ) + col * 4;
3540 for (
int i = i1; i <= i2; i++ )
3541 rgba[i] = p[i] << 4;
3544 for (
int j = r1; j < r2; j++, p -= bpl )
3545 for (
int i = i1; i <= i2; i++ )
3546 p[i] = ( rgba[i] += ( ( p[i] << 4 ) - rgba[i] ) * alpha / 16 ) >> 4;
3549 for (
int row = r1; row <= r2; row++ )
3551 p = image.scanLine( row ) + c2 * 4;
3552 for (
int i = i1; i <= i2; i++ )
3553 rgba[i] = p[i] << 4;
3556 for (
int j = c1; j < c2; j++, p -= 4 )
3557 for (
int i = i1; i <= i2; i++ )
3558 p[i] = ( rgba[i] += ( ( p[i] << 4 ) - rgba[i] ) * alpha / 16 ) >> 4;
3564 if ( alpha != 255 && alpha > 0 )
3568 double alphaFactor = alpha / 255.;
3569 int r = 0, g = 0, b = 0;
3570 rgb.getRgb( &r, &g, &b );
3575 rgb.setRgb( r, g, b, alpha );
3577 else if ( alpha == 0 )
3579 rgb.setRgb( 0, 0, 0, 0 );
3585 if ( order == Qt::AscendingOrder )
3599 double dx = directionPoint.x() - startPoint.x();
3600 double dy = directionPoint.y() - startPoint.y();
3601 double length = std::sqrt( dx * dx + dy * dy );
3602 double scaleFactor = distance / length;
3603 return QPointF( startPoint.x() + dx * scaleFactor, startPoint.y() + dy * scaleFactor );
3613 for (
int i = 0; i < svgPaths.size(); i++ )
3615 QDir dir( svgPaths[i] );
3616 Q_FOREACH (
const QString &item, dir.entryList( QDir::Dirs | QDir::NoDotAndDotDot ) )
3618 svgPaths.insert( i + 1, dir.path() +
'/' + item );
3621 Q_FOREACH (
const QString &item, dir.entryList( QStringList(
"*.svg" ), QDir::Files ) )
3624 list.append( dir.path() +
'/' + item );
3636 QStringList svgPaths;
3637 svgPaths.append( directory );
3639 for (
int i = 0; i < svgPaths.size(); i++ )
3641 QDir dir( svgPaths[i] );
3642 Q_FOREACH (
const QString &item, dir.entryList( QDir::Dirs | QDir::NoDotAndDotDot ) )
3644 svgPaths.insert( i + 1, dir.path() +
'/' + item );
3647 Q_FOREACH (
const QString &item, dir.entryList( QStringList(
"*.svg" ), QDir::Files ) )
3649 list.append( dir.path() +
'/' + item );
3659 if ( QFileInfo::exists( name ) )
3660 return QFileInfo( name ).canonicalFilePath();
3663 if ( name.contains( QLatin1String(
"://" ) ) )
3666 if ( url.isValid() && !url.scheme().isEmpty() )
3668 if ( url.scheme().compare( QLatin1String(
"file" ), Qt::CaseInsensitive ) == 0 )
3671 name = url.toLocalFile();
3672 if ( QFile( name ).exists() )
3674 return QFileInfo( name ).canonicalFilePath();
3688 for (
int i = 0; i < svgPaths.size(); i++ )
3690 QString svgPath = svgPaths[i];
3691 if ( svgPath.endsWith( QChar(
'/' ) ) )
3702 QString myLocalPath = svgPath + QDir::separator() + name;
3705 if ( QFile( myLocalPath ).exists() )
3708 return QFileInfo( myLocalPath ).canonicalFilePath();
3712 return pathResolver.
readPath( name );
3717 if ( !QFileInfo::exists( path ) )
3720 path = QFileInfo( path ).canonicalFilePath();
3724 bool isInSvgPaths =
false;
3725 for (
int i = 0; i < svgPaths.size(); i++ )
3727 QString dir = QFileInfo( svgPaths[i] ).canonicalFilePath();
3729 if ( !dir.isEmpty() && path.startsWith( dir ) )
3731 path = path.mid( dir.size() + 1 );
3732 isInSvgPaths =
true;
3747 double cx = 0, cy = 0;
3748 double area, sum = 0;
3749 for (
int i = points.count() - 1, j = 0; j < points.count(); i = j++ )
3751 const QPointF &p1 = points[i];
3752 const QPointF &p2 = points[j];
3753 area = p1.x() * p2.y() - p1.y() * p2.x();
3755 cx += ( p1.x() + p2.x() ) * area;
3756 cy += ( p1.y() + p2.y() ) * area;
3763 if ( points.count() >= 2 )
3764 return QPointF( ( points[0].x() + points[1].x() ) / 2, ( points[0].y() + points[1].y() ) / 2 );
3765 else if ( points.count() == 1 )
3773 return QPointF( cx, cy );
3783 unsigned int i, pointCount = points.count();
3786 for ( i = 0; i < pointCount; ++i ) polyline[i] =
QgsPointXY( points[i].x(), points[i].y() );
3793 if ( !pointOnSurfaceGeom.
isNull() )
3797 return QPointF( point.
x(), point.
y() );
3806 bool inside =
false;
3808 double x = point.x();
3809 double y = point.y();
3811 for (
int i = 0, j = points.count() - 1; i < points.count(); i++ )
3813 const QPointF &p1 = points[i];
3814 const QPointF &p2 = points[j];
3819 if ( ( p1.y() < y && p2.y() >= y ) || ( p2.y() < y && p1.y() >= y ) )
3821 if ( p1.x() + ( y - p1.y() ) / ( p2.y() - p1.y() ) * ( p2.x() - p1.x() ) <= x )
3832 if ( fieldOrExpression.isEmpty() )
3835 QgsExpression *expr =
new QgsExpression( fieldOrExpression );
3836 if ( !expr->hasParserError() )
3841 QgsExpression *expr2 =
new QgsExpression( QgsExpression::quotedColumnRef( fieldOrExpression ) );
3842 Q_ASSERT( !expr2->hasParserError() );
3848 const QgsExpressionNode *n = expression->rootNode();
3850 if ( n && n->nodeType() == QgsExpressionNode::ntColumnRef )
3851 return static_cast<const QgsExpressionNodeColumnRef *>( n )->name();
3853 return expression->expression();
3867 QList<double> breaks;
3870 breaks.append( maximum );
3874 int minimumCount =
static_cast< int >( classes ) / 3;
3875 double shrink = 0.75;
3876 double highBias = 1.5;
3877 double adjustBias = 0.5 + 1.5 * highBias;
3878 int divisions = classes;
3879 double h = highBias;
3882 double dx = maximum - minimum;
3892 cell = std::max( std::fabs( minimum ), std::fabs( maximum ) );
3893 if ( adjustBias >= 1.5 * h + 0.5 )
3895 U = 1 + ( 1.0 / ( 1 + h ) );
3899 U = 1 + ( 1.5 / ( 1 + adjustBias ) );
3901 small = dx < ( cell * U * std::max( 1, divisions ) * 1e-07 * 3.0 );
3908 cell = 9 + cell / 10;
3909 cell = cell * shrink;
3911 if ( minimumCount > 1 )
3913 cell = cell / minimumCount;
3919 if ( divisions > 1 )
3921 cell = cell / divisions;
3924 if ( cell < 20 * 1e-07 )
3929 double base = std::pow( 10.0, std::floor( std::log10( cell ) ) );
3931 if ( ( 2 * base ) - cell < h * ( cell - unit ) )
3934 if ( ( 5 * base ) - cell < adjustBias * ( cell - unit ) )
3937 if ( ( 10.0 * base ) - cell < h * ( cell - unit ) )
3944 int start = std::floor( minimum / unit + 1e-07 );
3945 int end = std::ceil( maximum / unit - 1e-07 );
3948 while ( start * unit > minimum + ( 1e-07 * unit ) )
3952 while ( end * unit < maximum - ( 1e-07 * unit ) )
3956 QgsDebugMsg( QString(
"pretty classes: %1" ).arg( end ) );
3960 int k = std::floor( 0.5 + end - start );
3961 if ( k < minimumCount )
3963 k = minimumCount - k;
3967 start = start - k / 2 + k % 2;
3971 start = start - k / 2;
3972 end = end + k / 2 + k % 2;
3975 double minimumBreak = start * unit;
3977 int count = end - start;
3979 breaks.reserve( count );
3980 for (
int i = 1; i < count + 1; i++ )
3982 breaks.append( minimumBreak + i * unit );
3985 if ( breaks.isEmpty() )
3988 if ( breaks.first() < minimum )
3990 breaks[0] = minimum;
3992 if ( breaks.last() > maximum )
3994 breaks[breaks.count() - 1] = maximum;
4003 bool roundToUnit =
false;
4006 if ( props.contains( QStringLiteral(
"uomScale" ) ) )
4009 scale = props.value( QStringLiteral(
"uomScale" ) ).toDouble( &ok );
4018 if ( props.value( QStringLiteral(
"uom" ) ) == QLatin1String(
"http://www.opengeospatial.org/se/units/metre" ) )
4043 scale = 1 / 0.28 * 25.4;
4067 double rescaled = size * scale;
4072 rescaled = std::round( rescaled );
4079 double x =
rescaleUom( point.x(), unit, props );
4080 double y =
rescaleUom( point.y(), unit, props );
4081 return QPointF( x, y );
4086 QVector<qreal> result;
4087 QVector<qreal>::const_iterator it = array.constBegin();
4088 for ( ; it != array.constEnd(); ++it )
4090 result.append(
rescaleUom( *it, unit, props ) );
4097 if ( !props.value( QStringLiteral(
"scaleMinDenom" ), QLatin1String(
"" ) ).isEmpty() )
4099 QDomElement scaleMinDenomElem = doc.createElement( QStringLiteral(
"se:MinScaleDenominator" ) );
4100 scaleMinDenomElem.appendChild( doc.createTextNode( props.value( QStringLiteral(
"scaleMinDenom" ), QLatin1String(
"" ) ) ) );
4101 ruleElem.appendChild( scaleMinDenomElem );
4104 if ( !props.value( QStringLiteral(
"scaleMaxDenom" ), QLatin1String(
"" ) ).isEmpty() )
4106 QDomElement scaleMaxDenomElem = doc.createElement( QStringLiteral(
"se:MaxScaleDenominator" ) );
4107 scaleMaxDenomElem.appendChild( doc.createTextNode( props.value( QStringLiteral(
"scaleMaxDenom" ), QLatin1String(
"" ) ) ) );
4108 ruleElem.appendChild( scaleMaxDenomElem );
4114 if ( mScaleMinDenom != 0 )
4117 int parentScaleMinDenom = props.value( QStringLiteral(
"scaleMinDenom" ), QStringLiteral(
"0" ) ).toInt( &ok );
4118 if ( !ok || parentScaleMinDenom <= 0 )
4119 props[ QStringLiteral(
"scaleMinDenom" )] = QString::number( mScaleMinDenom );
4121 props[ QStringLiteral(
"scaleMinDenom" )] = QString::number( std::max( parentScaleMinDenom, mScaleMinDenom ) );
4124 if ( mScaleMaxDenom != 0 )
4127 int parentScaleMaxDenom = props.value( QStringLiteral(
"scaleMaxDenom" ), QStringLiteral(
"0" ) ).toInt( &ok );
4128 if ( !ok || parentScaleMaxDenom <= 0 )
4129 props[ QStringLiteral(
"scaleMaxDenom" )] = QString::number( mScaleMaxDenom );
4131 props[ QStringLiteral(
"scaleMaxDenom" )] = QString::number( std::min( parentScaleMaxDenom, mScaleMaxDenom ) );
4139 if ( uom == QLatin1String(
"http://www.opengeospatial.org/se/units/metre" ) )
4141 scale = 1.0 / 0.00028;
4143 else if ( uom == QLatin1String(
"http://www.opengeospatial.org/se/units/foot" ) )
4145 scale = 304.8 / 0.28;
4152 return size * scale;
static void wellKnownMarkerToSld(QDomDocument &doc, QDomElement &element, const QString &name, const QColor &color, const QColor &strokeColor, Qt::PenStyle strokeStyle, double strokeWidth=-1, double size=-1)
void setForceVectorOutput(bool force)
static QgsSymbolLayerRegistry * symbolLayerRegistry()
Returns the application's symbol layer registry, used for managing symbol layers. ...
The class is used as a container of context for various read/write operations on other objects...
static QgsSymbol * symbolFromMimeData(const QMimeData *data)
Attempts to parse mime data as a symbol.
Meters value as Map units.
static QPixmap symbolPreviewPixmap(QgsSymbol *symbol, QSize size, int padding=0, QgsRenderContext *customContext=nullptr)
Returns a pixmap preview for a color ramp.
static QgsStringMap parseProperties(QDomElement &element)
static QgsSymbolLayer * loadSymbolLayer(QDomElement &element, const QgsReadWriteContext &context)
Reads and returns symbol layer from XML. Caller is responsible for deleting the returned object...
double minSizeMM
The minimum size in millimeters, or 0.0 if unset.
static QgsSymbol::ScaleMethod decodeScaleMethod(const QString &str)
static QgsGeometry fromPolylineXY(const QgsPolylineXY &polyline)
Creates a new LineString geometry from a list of QgsPointXY points.
static QStringList listSvgFilesAt(const QString &directory)
Return a list of svg files at the specified directory.
static bool needFontMarker(QDomElement &element)
void setRenderingPass(int renderingPass)
static Qt::BrushStyle decodeBrushStyle(const QString &str)
static QDomElement createVendorOptionElement(QDomDocument &doc, const QString &name, const QString &value)
void setLocked(bool locked)
static bool hasWellKnownMark(QDomElement &element)
static QgsColorRamp * create(const QgsStringMap &properties=QgsStringMap())
Returns a new QgsColorBrewerColorRamp color ramp created using the properties encoded in a string map...
static QgsColorRamp * create(const QgsStringMap &properties=QgsStringMap())
Returns a new QgsPresetSchemeColorRamp color ramp created using the properties encoded in a string ma...
static QgsStringMap getSvgParameterList(QDomElement &element)
static QString svgSymbolPathToName(QString path, const QgsPathResolver &pathResolver)
Get SVG symbols's name from its path.
void setMapUnitScale(const QgsMapUnitScale &scale)
QgsPaintEffect * paintEffect() const
Returns the current paint effect for the layer.
Calculate scale by the diameter.
static bool createFunctionElement(QDomDocument &doc, QDomElement &element, const QString &function)
static QString encodeSldAlpha(int alpha)
bool isNull() const
Returns true if the geometry is null (ie, contains no underlying geometry accessible via geometry() )...
static QString encodeSldBrushStyle(Qt::BrushStyle style)
virtual QgsSymbol * subSymbol()
Returns the symbol's sub symbol, if present.
static QString encodeSize(QSizeF size)
Encodes a QSizeF to a string.
QString readPath(const QString &filename) const
Turn filename read from the project file to an absolute path.
virtual bool readXml(const QDomElement &collectionElem, const QgsPropertiesDefinition &definitions)
Reads property collection state from an XML element.
static void applyScaleDependency(QDomDocument &doc, QDomElement &ruleElem, QgsStringMap &props)
Checks if the properties contain scaleMinDenom and scaleMaxDenom, if available, they are added into t...
static Qt::PenCapStyle decodeSldLineCapStyle(const QString &str)
static void createOnlineResourceElement(QDomDocument &doc, QDomElement &element, const QString &path, const QString &format)
QgsWkbTypes::Type wkbType() const
Returns type of the geometry as a WKB type (point / linestring / polygon etc.)
static QDomElement createSvgParameterElement(QDomDocument &doc, const QString &name, const QString &value)
static bool geometryFromSldElement(QDomElement &element, QString &geomFunc)
A class to represent a 2D point.
QgsSymbolLayer * createSymbolLayer(const QString &name, const QgsStringMap &properties=QgsStringMap()) const
create a new instance of symbol layer given symbol layer name and properties
static QgsNamedColorList colorListFromMimeData(const QMimeData *data)
Attempts to parse mime data as a list of named colors.
static QString fieldOrExpressionFromExpression(QgsExpression *expression)
Return a field name if the whole expression is just a name of the field .
static bool functionFromSldElement(QDomElement &element, QString &function)
Abstract base class for color ramps.
static QString ogrFeatureStyleBrush(const QColor &fillColr)
Create ogr feature style string for brush.
static bool isDefaultStack(QgsPaintEffect *effect)
Tests whether a paint effect matches the default effects stack.
static bool displacementFromSldElement(QDomElement &element, QPointF &offset)
static void mergeScaleDependencies(int mScaleMinDenom, int mScaleMaxDenom, QgsStringMap &props)
Merges the local scale limits, if any, with the ones already in the map, if any.
static QPointF decodePoint(const QString &string)
Decodes a QSizeF from a string.
QVector< QgsPolylineXY > QgsPolygonXY
Polygon: first item of the list is outer ring, inner rings (if any) start from second item...
static QDomElement saveColorRamp(const QString &name, QgsColorRamp *ramp, QDomDocument &doc)
Encodes a color ramp's settings to an XML element.
static bool needMarkerLine(QDomElement &element)
static void externalMarkerToSld(QDomDocument &doc, QDomElement &element, const QString &path, const QString &format, int *markIndex=nullptr, const QColor &color=QColor(), double size=-1)
bool clipFeaturesToExtent() const
Returns whether features drawn by the symbol will be clipped to the render context's extent...
static bool onlineResourceFromSldElement(QDomElement &element, QString &path, QString &format)
static QString encodeMapUnitScale(const QgsMapUnitScale &mapUnitScale)
Container of fields for a vector layer.
static void createDisplacementElement(QDomDocument &doc, QDomElement &element, QPointF offset)
A geometry is the spatial representation of a feature.
static double sizeInPixelsFromSldUom(const QString &uom, double size)
Returns the size scaled in pixels according to the uom attribute.
QgsGeometry buffer(double distance, int segments) const
Returns a buffer region around this geometry having the given width and with a specified number of se...
int symbolLayerCount() const
Returns total number of symbol layers contained in the symbol.
static QgsColorRamp * create(const QgsStringMap &properties=QgsStringMap())
static void clearSymbolMap(QgsSymbolMap &symbols)
static QString svgSymbolNameToPath(QString name, const QgsPathResolver &pathResolver)
Get SVG symbol's path from its name.
static QFont::Style decodeSldFontStyle(const QString &str)
static bool rotationFromSldElement(QDomElement &element, QString &rotationFunc)
static QgsSymbol * loadSymbol(const QDomElement &element, const QgsReadWriteContext &context)
Attempts to load a symbol from a DOM element.
Percentage of another measurement (e.g., canvas size, feature size)
bool qgsVariantGreaterThan(const QVariant &lhs, const QVariant &rhs)
Compares two QVariant values and returns whether the first is greater than the second.
virtual QgsStringMap properties() const =0
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
virtual QColor color(double value) const =0
Returns the color corresponding to a specified value.
static bool createExpressionElement(QDomDocument &doc, QDomElement &element, const QString &function)
Creates a OGC Expression element based on the provided function expression.
QMap< QString, QString > QgsStringMap
bool qgsDoubleNear(double a, double b, double epsilon=4 *DBL_EPSILON)
Compare two doubles (but allow some difference)
double ANALYSIS_EXPORT angle(QgsPoint *p1, QgsPoint *p2, QgsPoint *p3, QgsPoint *p4)
Calculates the angle between two segments (in 2 dimension, z-values are ignored)
static QString encodePoint(QPointF point)
Encodes a QPointF to a string.
double maxScale
The maximum scale, or 0.0 if unset.
QVector< QgsPolygonXY > QgsMultiPolygonXY
A collection of QgsPolygons that share a common collection of attributes.
static Qt::PenJoinStyle decodePenJoinStyle(const QString &str)
bool qgsVariantLessThan(const QVariant &lhs, const QVariant &rhs)
Compares two QVariant values and returns whether the first is less than the second.
static QColor parseColor(const QString &colorStr, bool strictEval=false)
Attempts to parse a string as a color using a variety of common formats, including hex codes...
static QgsPaintEffectRegistry * paintEffectRegistry()
Returns the application's paint effect registry, used for managing paint effects. ...
bool minSizeMMEnabled
Whether the minimum size in mm should be respected.
static QIcon symbolLayerPreviewIcon(QgsSymbolLayer *layer, QgsUnitTypes::RenderUnit u, QSize size, const QgsMapUnitScale &scale=QgsMapUnitScale())
Draws a symbol layer preview to an icon.
static QString getSvgParametricPath(const QString &basePath, const QColor &fillColor, const QColor &strokeColor, double strokeWidth)
Encodes a reference to a parametric SVG into a path with parameters according to the SVG Parameters s...
static QVector< qreal > decodeRealVector(const QString &s)
static QString encodeColor(const QColor &color)
void setOutputUnit(QgsUnitTypes::RenderUnit unit)
Sets the units to use for sizes and widths within the symbol.
QVector< QgsPolylineXY > QgsMultiPolylineXY
A collection of QgsPolylines that share a common collection of attributes.
QgsMultiPolylineXY asMultiPolyline() const
Returns contents of the geometry as a multi linestring if wkbType is WKBMultiLineString, otherwise an empty list.
static QPointF pointOnLineWithDistance(QPointF startPoint, QPointF directionPoint, double distance)
Returns a point on the line from startPoint to directionPoint that is a certain distance away from th...
SymbolType
Type of the symbol.
static QString encodePenStyle(Qt::PenStyle style)
static double rescaleUom(double size, QgsUnitTypes::RenderUnit unit, const QgsStringMap &props)
Rescales the given size based on the uomScale found in the props, if any is found, otherwise returns the value un-modified.
static int decodeSldFontWeight(const QString &str)
int renderingPass() const
virtual bool setSubSymbol(QgsSymbol *symbol)
set layer's subsymbol. takes ownership of the passed symbol
static QgsUnitTypes::RenderUnit decodeSldUom(const QString &str, double *scaleFactor)
Decodes a SLD unit of measure string to a render unit.
static QgsNamedColorList importColorsFromGpl(QFile &file, bool &ok, QString &name)
Imports colors from a gpl GIMP palette file.
const QgsPathResolver & pathResolver() const
Returns path resolver for conversion between relative and absolute paths.
static QIcon symbolPreviewIcon(QgsSymbol *symbol, QSize size, int padding=0)
Returns an icon preview for a color ramp.
#define QgsDebugMsgLevel(str, level)
static QDomElement saveSymbols(QgsSymbolMap &symbols, const QString &tagName, QDomDocument &doc, const QgsReadWriteContext &context)
Writes a collection of symbols to XML with specified tagName for the top-level element.
static void externalGraphicToSld(QDomDocument &doc, QDomElement &element, const QString &path, const QString &mime, const QColor &color, double size=-1)
static QString encodeSldRealVector(const QVector< qreal > &v)
static bool needEllipseMarker(QDomElement &element)
void setOpacity(qreal opacity)
Sets the opacity for the symbol.
static QgsStringMap getVendorOptionList(QDomElement &element)
QgsPolygonXY asPolygon() const
Returns contents of the geometry as a polygon if wkbType is WKBPolygon, otherwise an empty list...
static QColor parseColorWithAlpha(const QString &colorStr, bool &containsAlpha, bool strictEval=false)
Attempts to parse a string as a color using a variety of common formats, including hex codes...
Calculate scale by the area.
static bool needSvgMarker(QDomElement &element)
static QVariant colorRampToVariant(const QString &name, QgsColorRamp *ramp)
Saves a color ramp to a QVariantMap, wrapped in a QVariant.
static QString colorToName(const QColor &color)
Returns a friendly display name for a color.
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
static QIcon colorRampPreviewIcon(QgsColorRamp *ramp, QSize size, int padding=0)
Returns an icon preview for a color ramp.
static int decodeSldAlpha(const QString &str)
QgsPropertyCollection & dataDefinedProperties()
Returns a reference to the symbol layer's property collection, used for data defined overrides...
virtual double value(int index) const =0
Returns relative value between [0,1] of color at specified index.
static QString encodeSldLineJoinStyle(Qt::PenJoinStyle style)
points (e.g., for font sizes)
static QgsRenderContext fromQPainter(QPainter *painter)
Creates a default render context given a pixel based QPainter destination.
QList< QPair< QColor, QString > > QgsNamedColorList
List of colors paired with a friendly display name identifying the color.
static QgsSymbolLayer * createMarkerLayerFromSld(QDomElement &element)
static void createRotationElement(QDomDocument &doc, QDomElement &element, const QString &rotationFunc)
void drawPreviewIcon(QPainter *painter, QSize size, QgsRenderContext *customContext=nullptr)
Draw icon of the symbol that occupyies area given by size using the painter.
QgsGeometry offsetCurve(double distance, int segments, JoinStyle joinStyle, double miterLimit) const
Returns an offset line at a given distance and side from an input line.
QList< QgsSymbolLayer * > QgsSymbolLayerList
void setPainter(QPainter *p)
Sets the destination QPainter for the render operation.
static QgsColorRamp * loadColorRamp(QDomElement &element)
Creates a color ramp from the settings encoded in an XML element.
static QString encodeSldUom(QgsUnitTypes::RenderUnit unit, double *scaleFactor)
Encodes a render unit into an SLD unit of measure string.
virtual void drawPreviewIcon(QgsSymbolRenderContext &context, QSize size)=0
static QgsSymbolLayer * createFillLayerFromSld(QDomElement &element)
static double estimateMaxSymbolBleed(QgsSymbol *symbol, const QgsRenderContext &context)
Returns the maximum estimated bleed for the symbol.
static QPainter::CompositionMode decodeBlendMode(const QString &s)
static Qt::PenCapStyle decodePenCapStyle(const QString &str)
void setPaintEffect(QgsPaintEffect *effect)
Sets the current paint effect for the layer.
static bool needLinePatternFill(QDomElement &element)
static void parametricSvgToSld(QDomDocument &doc, QDomElement &graphicElem, const QString &path, const QColor &fillColor, double size, const QColor &strokeColor, double strokeWidth)
Encodes a reference to a parametric SVG into SLD, as a succession of parametric SVG using URL paramet...
virtual QString type() const =0
Returns a string representing the color ramp type.
static Q_INVOKABLE QgsUnitTypes::RenderUnit decodeRenderUnit(const QString &string, bool *ok=nullptr)
Decodes a render unit from a string.
QgsGeometry pointOnSurface() const
Returns a point guaranteed to lie on the surface of a geometry.
static bool lineFromSld(QDomElement &element, Qt::PenStyle &penStyle, QColor &color, double &width, Qt::PenJoinStyle *penJoinStyle=nullptr, Qt::PenCapStyle *penCapStyle=nullptr, QVector< qreal > *customDashPattern=nullptr, double *dashOffset=nullptr)
void setEnabled(bool enabled)
Sets whether symbol layer is enabled and should be drawn.
static QString encodeSldFontStyle(QFont::Style style)
static QStringList listSvgFiles()
Return a list of all available svg files.
static QgsExpression * fieldOrExpressionToExpression(const QString &fieldOrExpression)
Return a new valid expression instance for given field or expression string.
static QgsSymbolMap loadSymbols(QDomElement &element, const QgsReadWriteContext &context)
Reads a collection of symbols from XML and returns them in a map. Caller is responsible for deleting ...
QgsSymbolLayer * symbolLayer(int layer)
Returns a specific symbol layers contained in the symbol.
static bool opacityFromSldElement(QDomElement &element, QString &alphaFunc)
static Qt::PenStyle decodePenStyle(const QString &str)
static bool externalGraphicFromSld(QDomElement &element, QString &path, QString &mime, QColor &color, double &size)
static void premultiplyColor(QColor &rgb, int alpha)
Converts a QColor into a premultiplied ARGB QColor value using a specified alpha value.
static bool needPointPatternFill(QDomElement &element)
virtual double estimateMaxBleed(const QgsRenderContext &context) const
Returns the estimated maximum distance which the layer style will bleed outside the drawn shape when ...
static bool fillFromSld(QDomElement &element, Qt::BrushStyle &brushStyle, QColor &color)
static QString encodeSldFontWeight(int weight)
static void createGeometryElement(QDomDocument &doc, QDomElement &element, const QString &geomFunc)
static QPixmap colorRampPreviewPixmap(QgsColorRamp *ramp, QSize size, int padding=0)
Returns a pixmap preview for a color ramp.
static bool pointInPolygon(const QPolygonF &points, QPointF point)
Calculate whether a point is within of a QPolygonF.
static QSizeF decodeSize(const QString &string)
Decodes a QSizeF from a string.
static Qt::BrushStyle decodeSldBrushStyle(const QString &str)
static QgsGeometry fromPolygonXY(const QgsPolygonXY &polygon)
Creates a new geometry from a QgsPolygon.
static QString symbolProperties(QgsSymbol *symbol)
Returns a string representing the symbol.
static QString encodeScaleMethod(QgsSymbol::ScaleMethod scaleMethod)
static bool hasExternalGraphic(QDomElement &element)
static bool externalMarkerFromSld(QDomElement &element, QString &path, QString &format, int &markIndex, QColor &color, double &size)
static QList< double > prettyBreaks(double minimum, double maximum, int classes)
Computes a sequence of about 'classes' equally spaced round values which cover the range of values fr...
GeometryType
The geometry types are used to group QgsWkbTypes::Type in a coarse way.
static void sortVariantList(QList< QVariant > &list, Qt::SortOrder order)
Sorts the passed list in requested order.
static QPointF polygonCentroid(const QPolygonF &points)
Calculate the centroid point of a QPolygonF.
static bool convertPolygonSymbolizerToPointMarker(QDomElement &element, QgsSymbolLayerList &layerList)
static QVector< qreal > decodeSldRealVector(const QString &s)
static QgsColorRamp * create(const QgsStringMap &properties=QgsStringMap())
Creates a new QgsColorRamp from a map of properties.
QVector< QgsPointXY > QgsPolylineXY
Polyline as represented as a vector of two-dimensional points.
static bool saveColorsToGpl(QFile &file, const QString &paletteName, const QgsNamedColorList &colors)
Exports colors to a gpl GIMP palette file.
Contains information about the context of a rendering operation.
void resolvePaths(const QString &name, QgsStringMap &properties, const QgsPathResolver &pathResolver, bool saving) const
Resolve paths in properties of a particular symbol layer.
static void createOpacityElement(QDomDocument &doc, QDomElement &element, const QString &alphaFunc)
static void labelTextToSld(QDomDocument &doc, QDomElement &element, const QString &label, const QFont &font, const QColor &color=QColor(), double size=-1)
static QPicture symbolLayerPreviewPicture(QgsSymbolLayer *layer, QgsUnitTypes::RenderUnit units, QSize size, const QgsMapUnitScale &scale=QgsMapUnitScale())
Draws a symbol layer preview to a QPicture.
QgsPointXY asPoint() const
Returns contents of the geometry as a point if wkbType is WKBPoint, otherwise returns [0...
static void blurImageInPlace(QImage &image, QRect rect, int radius, bool alphaOnly)
Blurs an image in place, e.g. creating Qt-independent drop shadows.
double maxSizeMM
The maximum size in millimeters, or 0.0 if unset.
bool enabled() const
Returns true if symbol layer is enabled and will be drawn.
Struct for storing maximum and minimum scales for measurements in map units.
static QString encodeBrushStyle(Qt::BrushStyle style)
static void createAnchorPointElement(QDomDocument &doc, QDomElement &element, QPointF anchor)
Creates a SE 1.1 anchor point element as a child of the specified element.
QgsSymbolLayer * createSymbolLayerFromSld(const QString &name, QDomElement &element) const
create a new instance of symbol layer given symbol layer name and SLD
static QDomElement expressionToOgcFilter(const QgsExpression &exp, QDomDocument &doc, QString *errorMessage=nullptr)
Creates OGC filter XML element.
static QMimeData * colorToMimeData(const QColor &color)
Creates mime data from a color.
static bool needSvgFill(QDomElement &element)
virtual QgsStringMap properties() const =0
Returns a string map containing all the color ramp's properties.
static QDomElement expressionToOgcExpression(const QgsExpression &exp, QDomDocument &doc, QString *errorMessage=nullptr)
Creates an OGC expression XML element.
static QgsExpression * expressionFromOgcFilter(const QDomElement &element)
Parse XML with OGC filter into QGIS expression.
static QMimeData * colorListToMimeData(const QgsNamedColorList &colorList, const bool allFormats=true)
Creates mime data from a list of named colors.
static QMimeData * symbolToMimeData(QgsSymbol *symbol)
Creates new mime data from a symbol.
QMap< QString, QgsSymbol *> QgsSymbolMap
static QDomElement saveSymbol(const QString &symbolName, QgsSymbol *symbol, QDomDocument &doc, const QgsReadWriteContext &context)
Writes a symbol definition to XML.
static bool wellKnownMarkerFromSld(QDomElement &element, QString &name, QColor &color, QColor &strokeColor, Qt::PenStyle &strokeStyle, double &strokeWidth, double &size)
QString writePath(const QString &filename) const
Prepare a filename to save it to the project file.
QList< QPolygonF > offsetLine(QPolygonF polyline, double dist, QgsWkbTypes::GeometryType geometryType)
calculate geometry shifted by a specified distance
static QStringList svgPaths()
Returns the paths to svg directories.
static QgsMapUnitScale decodeMapUnitScale(const QString &str)
static QgsSymbolLayer * createLineLayerFromSld(QDomElement &element)
QgsPolylineXY asPolyline() const
Returns contents of the geometry as a polyline if wkbType is WKBLineString, otherwise an empty list...
static void fillToSld(QDomDocument &doc, QDomElement &element, Qt::BrushStyle brushStyle, const QColor &color=QColor())
static void lineToSld(QDomDocument &doc, QDomElement &element, Qt::PenStyle penStyle, const QColor &color, double width=-1, const Qt::PenJoinStyle *penJoinStyle=nullptr, const Qt::PenCapStyle *penCapStyle=nullptr, const QVector< qreal > *customDashPattern=nullptr, double dashOffset=0.0)
static QString encodePenCapStyle(Qt::PenCapStyle style)
static QPointF polygonPointOnSurface(const QPolygonF &points)
Calculate a point within of a QPolygonF.
void setClipFeaturesToExtent(bool clipFeaturesToExtent)
Sets whether features drawn by the symbol should be clipped to the render context's extent...
qreal opacity() const
Returns the opacity for the symbol.
static const QgsPropertiesDefinition & propertyDefinitions()
Returns the symbol layer property definitions.
Resolves relative paths into absolute paths and vice versa.
static QgsColorRamp * create(const QgsStringMap &properties=QgsStringMap())
Returns a new QgsLimitedRandomColorRamp color ramp created using the properties encoded in a string m...
Flat cap (in line with start/end of line)
double minScale
The minimum scale, or 0.0 if unset.
virtual bool writeXml(QDomElement &collectionElem, const QgsPropertiesDefinition &definitions) const
Writes the current state of the property collection into an XML element.
static Type flatType(Type type)
Returns the flat type for a WKB type.
static QString ogrFeatureStylePen(double width, double mmScaleFactor, double mapUnitsScaleFactor, const QColor &c, Qt::PenJoinStyle joinStyle=Qt::MiterJoin, Qt::PenCapStyle capStyle=Qt::FlatCap, double offset=0.0, const QVector< qreal > *dashPattern=nullptr)
Create ogr feature style string for pen.
static void multiplyImageOpacity(QImage *image, qreal opacity)
Multiplies opacity of image pixel values with a (global) transparency value.
QgsMultiPolygonXY asMultiPolygon() const
Returns contents of the geometry as a multi polygon if wkbType is WKBMultiPolygon, otherwise an empty list.
bool maxSizeMMEnabled
Whether the maximum size in mm should be respected.
static void saveProperties(QgsStringMap props, QDomDocument &doc, QDomElement &element)
static Qt::PenJoinStyle decodeSldLineJoinStyle(const QString &str)
static bool createSymbolLayerListFromSld(QDomElement &element, QgsWkbTypes::GeometryType geomType, QgsSymbolLayerList &layers)
static QList< QColor > parseColorList(const QString &colorStr)
Attempts to parse a string as a list of colors using a variety of common formats, including hex codes...
static void drawStippledBackground(QPainter *painter, QRect rect)
static QString encodeSldLineCapStyle(Qt::PenCapStyle style)
static QString encodePenJoinStyle(Qt::PenJoinStyle style)
static QString encodeRealVector(const QVector< qreal > &v)
RenderUnit
Rendering size units.
static QColor decodeColor(const QString &str)
static QColor colorFromMimeData(const QMimeData *data, bool &hasAlpha)
Attempts to parse mime data as a color.
virtual QString layerType() const =0
Returns a string that represents this layer type.
virtual bool saveProperties(QDomDocument &doc, QDomElement &element) const
Saves the current state of the effect to a DOM element.