41 #include <QDomDocument> 43 #include <QDomElement> 50 #define POINTS_TO_MM 2.83464567 54 return QStringLiteral(
"%1,%2,%3,%4" ).arg( color.red() ).arg( color.green() ).arg( color.blue() ).arg( color.alpha() );
59 const QStringList lst = str.split(
',' );
60 if ( lst.count() < 3 )
64 int red, green, blue, alpha;
66 green = lst[1].toInt();
67 blue = lst[2].toInt();
69 if ( lst.count() > 3 )
71 alpha = lst[3].toInt();
73 return QColor( red, green, blue, alpha );
79 result.sprintf(
"%.2g", alpha / 255.0 );
86 double alpha = str.toDouble( &ok );
87 if ( !ok || alpha > 1 )
98 case QFont::StyleNormal:
99 return QStringLiteral(
"normal" );
100 case QFont::StyleItalic:
101 return QStringLiteral(
"italic" );
102 case QFont::StyleOblique:
103 return QStringLiteral(
"oblique" );
111 if ( str == QLatin1String(
"normal" ) )
return QFont::StyleNormal;
112 if ( str == QLatin1String(
"italic" ) )
return QFont::StyleItalic;
113 if ( str == QLatin1String(
"oblique" ) )
return QFont::StyleOblique;
114 return QFont::StyleNormal;
119 if ( weight == 50 )
return QStringLiteral(
"normal" );
120 if ( weight == 75 )
return QStringLiteral(
"bold" );
124 if ( weight < 0 )
return QStringLiteral(
"100" );
125 if ( weight > 99 )
return QStringLiteral(
"900" );
126 return QString::number( weight * 800 / 99 + 100 );
132 int weight = str.toInt( &ok );
134 return static_cast< int >( QFont::Normal );
138 if ( weight > 900 )
return 99;
139 if ( weight < 100 )
return 0;
140 return ( weight - 100 ) * 99 / 800;
148 return QStringLiteral(
"no" );
150 return QStringLiteral(
"solid" );
152 return QStringLiteral(
"dash" );
154 return QStringLiteral(
"dot" );
155 case Qt::DashDotLine:
156 return QStringLiteral(
"dash dot" );
157 case Qt::DashDotDotLine:
158 return QStringLiteral(
"dash dot dot" );
160 return QStringLiteral(
"???" );
166 if ( str == QLatin1String(
"no" ) )
return Qt::NoPen;
167 if ( str == QLatin1String(
"solid" ) )
return Qt::SolidLine;
168 if ( str == QLatin1String(
"dash" ) )
return Qt::DashLine;
169 if ( str == QLatin1String(
"dot" ) )
return Qt::DotLine;
170 if ( str == QLatin1String(
"dash dot" ) )
return Qt::DashDotLine;
171 if ( str == QLatin1String(
"dash dot dot" ) )
return Qt::DashDotDotLine;
172 return Qt::SolidLine;
180 return QStringLiteral(
"bevel" );
182 return QStringLiteral(
"miter" );
184 return QStringLiteral(
"round" );
186 return QStringLiteral(
"???" );
192 const QString cleaned = str.toLower().trimmed();
193 if ( cleaned == QLatin1String(
"bevel" ) )
194 return Qt::BevelJoin;
195 if ( cleaned == QLatin1String(
"miter" ) )
196 return Qt::MiterJoin;
197 if ( cleaned == QLatin1String(
"round" ) )
198 return Qt::RoundJoin;
199 return Qt::BevelJoin;
207 return QStringLiteral(
"bevel" );
209 return QStringLiteral(
"mitre" );
211 return QStringLiteral(
"round" );
219 if ( str == QLatin1String(
"bevel" ) )
return Qt::BevelJoin;
220 if ( str == QLatin1String(
"mitre" ) )
return Qt::MiterJoin;
221 if ( str == QLatin1String(
"round" ) )
return Qt::RoundJoin;
222 return Qt::BevelJoin;
230 return QStringLiteral(
"square" );
232 return QStringLiteral(
"flat" );
234 return QStringLiteral(
"round" );
236 return QStringLiteral(
"???" );
242 if ( str == QLatin1String(
"square" ) )
return Qt::SquareCap;
243 if ( str == QLatin1String(
"flat" ) )
return Qt::FlatCap;
244 if ( str == QLatin1String(
"round" ) )
return Qt::RoundCap;
245 return Qt::SquareCap;
253 return QStringLiteral(
"square" );
255 return QStringLiteral(
"butt" );
257 return QStringLiteral(
"round" );
265 if ( str == QLatin1String(
"square" ) )
return Qt::SquareCap;
266 if ( str == QLatin1String(
"butt" ) )
return Qt::FlatCap;
267 if ( str == QLatin1String(
"round" ) )
return Qt::RoundCap;
268 return Qt::SquareCap;
275 case Qt::SolidPattern :
276 return QStringLiteral(
"solid" );
277 case Qt::HorPattern :
278 return QStringLiteral(
"horizontal" );
279 case Qt::VerPattern :
280 return QStringLiteral(
"vertical" );
281 case Qt::CrossPattern :
282 return QStringLiteral(
"cross" );
283 case Qt::BDiagPattern :
284 return QStringLiteral(
"b_diagonal" );
285 case Qt::FDiagPattern :
286 return QStringLiteral(
"f_diagonal" );
287 case Qt::DiagCrossPattern :
288 return QStringLiteral(
"diagonal_x" );
289 case Qt::Dense1Pattern :
290 return QStringLiteral(
"dense1" );
291 case Qt::Dense2Pattern :
292 return QStringLiteral(
"dense2" );
293 case Qt::Dense3Pattern :
294 return QStringLiteral(
"dense3" );
295 case Qt::Dense4Pattern :
296 return QStringLiteral(
"dense4" );
297 case Qt::Dense5Pattern :
298 return QStringLiteral(
"dense5" );
299 case Qt::Dense6Pattern :
300 return QStringLiteral(
"dense6" );
301 case Qt::Dense7Pattern :
302 return QStringLiteral(
"dense7" );
304 return QStringLiteral(
"no" );
306 return QStringLiteral(
"???" );
312 if ( str == QLatin1String(
"solid" ) )
return Qt::SolidPattern;
313 if ( str == QLatin1String(
"horizontal" ) )
return Qt::HorPattern;
314 if ( str == QLatin1String(
"vertical" ) )
return Qt::VerPattern;
315 if ( str == QLatin1String(
"cross" ) )
return Qt::CrossPattern;
316 if ( str == QLatin1String(
"b_diagonal" ) )
return Qt::BDiagPattern;
317 if ( str == QLatin1String(
"f_diagonal" ) )
return Qt::FDiagPattern;
318 if ( str == QLatin1String(
"diagonal_x" ) )
return Qt::DiagCrossPattern;
319 if ( str == QLatin1String(
"dense1" ) )
return Qt::Dense1Pattern;
320 if ( str == QLatin1String(
"dense2" ) )
return Qt::Dense2Pattern;
321 if ( str == QLatin1String(
"dense3" ) )
return Qt::Dense3Pattern;
322 if ( str == QLatin1String(
"dense4" ) )
return Qt::Dense4Pattern;
323 if ( str == QLatin1String(
"dense5" ) )
return Qt::Dense5Pattern;
324 if ( str == QLatin1String(
"dense6" ) )
return Qt::Dense6Pattern;
325 if ( str == QLatin1String(
"dense7" ) )
return Qt::Dense7Pattern;
326 if ( str == QLatin1String(
"no" ) )
return Qt::NoBrush;
327 return Qt::SolidPattern;
334 case Qt::CrossPattern:
335 return QStringLiteral(
"cross" );
336 case Qt::DiagCrossPattern:
337 return QStringLiteral(
"x" );
344 return QStringLiteral(
"horline" );
346 return QStringLiteral(
"line" );
347 case Qt::BDiagPattern:
348 return QStringLiteral(
"slash" );
349 case Qt::FDiagPattern:
350 return QStringLiteral(
"backslash" );
353 case Qt::Dense1Pattern:
354 case Qt::Dense2Pattern:
355 case Qt::Dense3Pattern:
356 case Qt::Dense4Pattern:
357 case Qt::Dense5Pattern:
358 case Qt::Dense6Pattern:
359 case Qt::Dense7Pattern:
369 if ( str == QLatin1String(
"horline" ) )
return Qt::HorPattern;
370 if ( str == QLatin1String(
"line" ) )
return Qt::VerPattern;
371 if ( str == QLatin1String(
"cross" ) )
return Qt::CrossPattern;
372 if ( str == QLatin1String(
"slash" ) )
return Qt::BDiagPattern;
373 if ( str == QLatin1String(
"backshash" ) )
return Qt::FDiagPattern;
374 if ( str == QLatin1String(
"x" ) )
return Qt::DiagCrossPattern;
376 if ( str.startsWith( QLatin1String(
"brush://" ) ) )
388 QString s = value.toString().toLower().trimmed();
389 if ( s == QLatin1String(
"single" ) )
391 else if ( s == QLatin1String(
"reversed" ) )
393 else if ( s == QLatin1String(
"double" ) )
395 else if ( value.toInt() == 1 )
397 else if ( value.toInt() == 2 )
399 else if ( value.toInt( &intOk ) == 0 && intOk )
413 QString s = value.toString().toLower().trimmed();
414 if ( s == QLatin1String(
"plain" ) )
416 else if ( s == QLatin1String(
"lefthalf" ) )
418 else if ( s == QLatin1String(
"righthalf" ) )
420 else if ( value.toInt() == 1 )
422 else if ( value.toInt() == 2 )
424 else if ( value.toInt( &intOk ) == 0 && intOk )
439 QStringList lst = str.split(
',' );
440 if ( lst.count() != 2 )
441 return QPointF( 0, 0 );
442 return QPointF( lst[0].toDouble(), lst[1].toDouble() );
450 if ( value.isNull() )
453 if ( value.type() == QVariant::List )
455 const QVariantList list = value.toList();
456 if ( list.size() != 2 )
460 bool convertOk =
false;
461 double x = list.at( 0 ).toDouble( &convertOk );
464 double y = list.at( 1 ).toDouble( &convertOk );
469 return QPointF( x, y );
477 const QStringList list = value.toString().trimmed().split(
',' );
478 if ( list.count() != 2 )
480 bool convertOk =
false;
481 double x = list.at( 0 ).toDouble( &convertOk );
484 double y = list.at( 1 ).toDouble( &convertOk );
489 return QPointF( x, y );
503 QStringList lst =
string.split(
',' );
504 if ( lst.count() != 2 )
505 return QSizeF( 0, 0 );
506 return QSizeF( lst[0].toDouble(), lst[1].toDouble() );
514 if ( value.isNull() )
517 if ( value.type() == QVariant::List )
519 const QVariantList list = value.toList();
520 if ( list.size() != 2 )
524 bool convertOk =
false;
525 double x = list.at( 0 ).toDouble( &convertOk );
528 double y = list.at( 1 ).toDouble( &convertOk );
533 return QSizeF( x, y );
541 const QStringList list = value.toString().trimmed().split(
',' );
542 if ( list.count() != 2 )
544 bool convertOk =
false;
545 double x = list.at( 0 ).toDouble( &convertOk );
548 double y = list.at( 1 ).toDouble( &convertOk );
553 return QSizeF( x, y );
574 if ( str.startsWith( QLatin1String(
"3x:" ) ) )
577 QString chopped = str.mid( 3 );
578 lst = chopped.split(
',' );
582 lst = str.split(
',' );
584 if ( lst.count() < 2 )
587 double minScale = lst[0].toDouble();
589 minScale = minScale != 0 ? 1.0 / minScale : 0;
590 double maxScale = lst[1].toDouble();
592 maxScale = maxScale != 0 ? 1.0 / maxScale : 0;
594 if ( lst.count() < 6 )
614 *scaleFactor = 0.001;
615 return QStringLiteral(
"http://www.opengeospatial.org/se/units/metre" );
622 *scaleFactor = 1 / 0.28;
631 if ( str == QLatin1String(
"http://www.opengeospatial.org/se/units/metre" ) )
634 *scaleFactor = 1000.0;
637 else if ( str == QLatin1String(
"http://www.opengeospatial.org/se/units/foot" ) )
640 *scaleFactor = 304.8;
643 else if ( str == QLatin1String(
"http://www.opengeospatial.org/se/units/pixel" ) )
653 *scaleFactor = 1 / 0.00028;
659 QString vectorString;
660 QVector<qreal>::const_iterator it = v.constBegin();
661 for ( ; it != v.constEnd(); ++it )
663 if ( it != v.constBegin() )
665 vectorString.append(
';' );
667 vectorString.append( QString::number( *it ) );
674 QVector<qreal> resultVector;
676 QStringList realList = s.split(
';' );
677 QStringList::const_iterator it = realList.constBegin();
678 for ( ; it != realList.constEnd(); ++it )
680 resultVector.append( it->toDouble() );
688 QString vectorString;
689 QVector<qreal>::const_iterator it = v.constBegin();
690 for ( ; it != v.constEnd(); ++it )
692 if ( it != v.constBegin() )
694 vectorString.append(
' ' );
696 vectorString.append( QString::number( *it ) );
703 QVector<qreal> resultVector;
705 QStringList realList = s.split(
' ' );
706 QStringList::const_iterator it = realList.constBegin();
707 for ( ; it != realList.constEnd(); ++it )
709 resultVector.append( it->toDouble() );
717 QString encodedValue;
719 switch ( scaleMethod )
722 encodedValue = QStringLiteral(
"diameter" );
725 encodedValue = QStringLiteral(
"area" );
735 if ( str == QLatin1String(
"diameter" ) )
749 if ( s.compare( QLatin1String(
"Lighten" ), Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_Lighten;
750 if ( s.compare( QLatin1String(
"Screen" ), Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_Screen;
751 if ( s.compare( QLatin1String(
"Dodge" ), Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_ColorDodge;
752 if ( s.compare( QLatin1String(
"Addition" ), Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_Plus;
753 if ( s.compare( QLatin1String(
"Darken" ), Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_Darken;
754 if ( s.compare( QLatin1String(
"Multiply" ), Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_Multiply;
755 if ( s.compare( QLatin1String(
"Burn" ), Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_ColorBurn;
756 if ( s.compare( QLatin1String(
"Overlay" ), Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_Overlay;
757 if ( s.compare( QLatin1String(
"SoftLight" ), Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_SoftLight;
758 if ( s.compare( QLatin1String(
"HardLight" ), Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_HardLight;
759 if ( s.compare( QLatin1String(
"Difference" ), Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_Difference;
760 if ( s.compare( QLatin1String(
"Subtract" ), Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_Exclusion;
761 return QPainter::CompositionMode_SourceOver;
772 QPixmap pixmap( size );
773 pixmap.fill( Qt::transparent );
775 painter.begin( &pixmap );
776 painter.setRenderHint( QPainter::Antialiasing );
785 size.setWidth( size.rwidth() - ( padding * 2 ) );
786 size.setHeight( size.rheight() - ( padding * 2 ) );
787 painter.translate( padding, padding );
797 std::unique_ptr<QgsSymbol> symbol_noDD( symbol->
clone( ) );
799 for (
const auto &layer : layers )
801 for (
int i = 0; i < layer->dataDefinedProperties().count(); ++i )
803 QgsProperty &prop = layer->dataDefinedProperties().property( i );
809 symbol_noDD->drawPreviewIcon( &painter, size, customContext, selected, expressionContext );
813 std::unique_ptr<QgsSymbol> symbolClone( symbol->
clone( ) );
814 symbolClone->drawPreviewIcon( &painter, size, customContext, selected, expressionContext );
828 maxBleed = layerMaxBleed > maxBleed ? layerMaxBleed : maxBleed;
838 painter.begin( &picture );
839 painter.setRenderHint( QPainter::Antialiasing );
843 std::unique_ptr< QgsSymbolLayer > layerClone( layer->
clone() );
844 layerClone->drawPreviewIcon( symbolContext, size );
851 QPixmap pixmap( size );
852 pixmap.fill( Qt::transparent );
854 painter.begin( &pixmap );
855 painter.setRenderHint( QPainter::Antialiasing );
863 std::unique_ptr< QgsSymbolLayer > layerClone( layer->
clone() );
864 layerClone->drawPreviewIcon( symbolContext, size );
866 return QIcon( pixmap );
876 QPixmap pixmap( size );
877 pixmap.fill( Qt::transparent );
880 painter.begin( &pixmap );
883 drawStippledBackground( &painter, QRect( padding, padding, size.width() - padding * 2, size.height() - padding * 2 ) );
887 for (
int i = 0; i < size.width(); i++ )
889 QPen pen( ramp->
color( static_cast< double >( i ) / size.width() ) );
890 painter.setPen( pen );
891 painter.drawLine( i, 0 + padding, i, size.height() - 1 - padding );
900 uchar pixDataRGB[] = { 255, 255, 255, 255,
905 QImage img( pixDataRGB, 2, 2, 8, QImage::Format_ARGB32 );
907 int width = ( rect.width() < rect.height() ) ?
908 rect.width() / 2.5 : rect.height() / 2.5;
909 QPixmap pix = QPixmap::fromImage( img.scaled( width, width ) );
912 brush.setTexture( pix );
913 painter->fillRect( rect, brush );
918 qreal s = ( markerSize - 1 ) / 2.0;
923 p.setPen( QColor( 50, 100, 120, 200 ) );
924 p.setBrush( QColor( 200, 200, 210, 120 ) );
925 p.drawEllipse( x - s, y - s, s * 2, s * 2 );
928 p.setPen( QColor( 255, 0, 0 ) );
929 p.drawLine( x - s, y + s, x + s, y - s );
930 p.drawLine( x - s, y - s, x + s, y + s );
942 static QPolygonF makeOffsetGeometry(
const QgsPolylineXY &polyline )
944 int i, pointCount = polyline.count();
946 QPolygonF resultLine;
947 resultLine.resize( pointCount );
951 for ( i = 0; i < pointCount; ++i, tempPtr++ )
952 resultLine[i] = QPointF( tempPtr->
x(), tempPtr->
y() );
956 static QList<QPolygonF> makeOffsetGeometry(
const QgsPolygonXY &polygon )
958 QList<QPolygonF> resultGeom;
959 resultGeom.reserve( polygon.size() );
960 for (
int ring = 0; ring < polygon.size(); ++ring )
961 resultGeom.append( makeOffsetGeometry( polygon[ ring ] ) );
967 QList<QPolygonF> resultLine;
969 if ( polyline.count() < 2 )
971 resultLine.append( polyline );
975 unsigned int i, pointCount = polyline.count();
978 QPointF *tempPtr = polyline.data();
979 for ( i = 0; i < pointCount; ++i, tempPtr++ )
980 tempPolyline[i] =
QgsPointXY( tempPtr->rx(), tempPtr->ry() );
983 if ( !tempGeometry.
isNull() )
985 int quadSegments = 0;
986 double miterLimit = 2.0;
994 if ( !offsetGeom.
isNull() )
996 tempGeometry = offsetGeom;
1001 resultLine.append( makeOffsetGeometry( line ) );
1006 resultLine.append( makeOffsetGeometry( tempGeometry.
asPolygon() ) );
1012 resultLine.reserve( tempMPolyline.count() );
1013 for (
int part = 0; part < tempMPolyline.count(); ++part )
1015 resultLine.append( makeOffsetGeometry( tempMPolyline[ part ] ) );
1022 resultLine.reserve( tempMPolygon.count() );
1023 for (
int part = 0; part < tempMPolygon.count(); ++part )
1025 resultLine.append( makeOffsetGeometry( tempMPolygon[ part ] ) );
1033 resultLine.append( polyline );
1043 QDomNode layerNode = element.firstChild();
1045 while ( !layerNode.isNull() )
1047 QDomElement e = layerNode.toElement();
1050 if ( e.tagName() != QLatin1String(
"layer" ) )
1061 QDomElement s = e.firstChildElement( QStringLiteral(
"symbol" ) );
1068 QgsDebugMsg(
"symbol layer refused subsymbol: " + s.attribute(
"name" ) );
1071 layers.append( layer );
1075 layerNode = layerNode.nextSibling();
1078 if ( layers.isEmpty() )
1080 QgsDebugMsg( QStringLiteral(
"no layers for symbol" ) );
1084 QString symbolType = element.attribute( QStringLiteral(
"type" ) );
1087 if ( symbolType == QLatin1String(
"line" ) )
1089 else if ( symbolType == QLatin1String(
"fill" ) )
1091 else if ( symbolType == QLatin1String(
"marker" ) )
1095 QgsDebugMsg(
"unknown symbol type " + symbolType );
1099 if ( element.hasAttribute( QStringLiteral(
"outputUnit" ) ) )
1103 if ( element.hasAttribute( ( QStringLiteral(
"mapUnitScale" ) ) ) )
1106 double oldMin = element.attribute( QStringLiteral(
"mapUnitMinScale" ), QStringLiteral(
"0.0" ) ).toDouble();
1107 mapUnitScale.
minScale = oldMin != 0 ? 1.0 / oldMin : 0;
1108 double oldMax = element.attribute( QStringLiteral(
"mapUnitMaxScale" ), QStringLiteral(
"0.0" ) ).toDouble();
1109 mapUnitScale.
maxScale = oldMax != 0 ? 1.0 / oldMax : 0;
1112 symbol->
setOpacity( element.attribute( QStringLiteral(
"alpha" ), QStringLiteral(
"1.0" ) ).toDouble() );
1113 symbol->
setClipFeaturesToExtent( element.attribute( QStringLiteral(
"clip_to_extent" ), QStringLiteral(
"1" ) ).toInt() );
1114 symbol->
setForceRHR( element.attribute( QStringLiteral(
"force_rhr" ), QStringLiteral(
"0" ) ).toInt() );
1120 QString layerClass = element.attribute( QStringLiteral(
"class" ) );
1121 bool locked = element.attribute( QStringLiteral(
"locked" ) ).toInt();
1122 bool enabled = element.attribute( QStringLiteral(
"enabled" ), QStringLiteral(
"1" ) ).toInt();
1123 int pass = element.attribute( QStringLiteral(
"pass" ) ).toInt();
1140 QDomElement effectElem = element.firstChildElement( QStringLiteral(
"effect" ) );
1141 if ( !effectElem.isNull() )
1149 QDomElement ddProps = element.firstChildElement( QStringLiteral(
"data_defined_properties" ) );
1150 if ( !ddProps.isNull() )
1169 return QStringLiteral(
"line" );
1171 return QStringLiteral(
"marker" );
1173 return QStringLiteral(
"fill" );
1182 QDomElement symEl = doc.createElement( QStringLiteral(
"symbol" ) );
1183 symEl.setAttribute( QStringLiteral(
"type" ), _nameForSymbolType( symbol->
type() ) );
1184 symEl.setAttribute( QStringLiteral(
"name" ), name );
1185 symEl.setAttribute( QStringLiteral(
"alpha" ), QString::number( symbol->
opacity() ) );
1186 symEl.setAttribute( QStringLiteral(
"clip_to_extent" ), symbol->
clipFeaturesToExtent() ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
1187 symEl.setAttribute( QStringLiteral(
"force_rhr" ), symbol->
forceRHR() ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
1194 QDomElement layerEl = doc.createElement( QStringLiteral(
"layer" ) );
1195 layerEl.setAttribute( QStringLiteral(
"class" ), layer->
layerType() );
1196 layerEl.setAttribute( QStringLiteral(
"enabled" ), layer->
enabled() );
1197 layerEl.setAttribute( QStringLiteral(
"locked" ), layer->
isLocked() );
1198 layerEl.setAttribute( QStringLiteral(
"pass" ), layer->
renderingPass() );
1209 QDomElement ddProps = doc.createElement( QStringLiteral(
"data_defined_properties" ) );
1211 layerEl.appendChild( ddProps );
1213 if (
const QgsSymbol *subSymbol = const_cast< QgsSymbolLayer * >( layer )->subSymbol() )
1215 QString subname = QStringLiteral(
"@%1@%2" ).arg( name ).arg( i );
1216 QDomElement subEl =
saveSymbol( subname, subSymbol, doc, context );
1217 layerEl.appendChild( subEl );
1219 symEl.appendChild( layerEl );
1227 QDomDocument doc( QStringLiteral(
"qgis-symbol-definition" ) );
1230 QTextStream stream( &props );
1231 symbolElem.save( stream, -1 );
1241 if ( element.isNull() )
1246 QString symbolizerName = element.localName();
1248 if ( symbolizerName == QLatin1String(
"PointSymbolizer" ) )
1251 QDomElement graphicElem = element.firstChildElement( QStringLiteral(
"Graphic" ) );
1252 if ( graphicElem.isNull() )
1254 QgsDebugMsg( QStringLiteral(
"Graphic element not found in PointSymbolizer" ) );
1290 if ( symbolizerName == QLatin1String(
"LineSymbolizer" ) )
1293 QDomElement strokeElem = element.firstChildElement( QStringLiteral(
"Stroke" ) );
1294 if ( strokeElem.isNull() )
1296 QgsDebugMsg( QStringLiteral(
"Stroke element not found in LineSymbolizer" ) );
1326 if ( symbolizerName == QLatin1String(
"PolygonSymbolizer" ) )
1329 QDomElement fillElem = element.firstChildElement( QStringLiteral(
"Fill" ) );
1330 QDomElement strokeElem = element.firstChildElement( QStringLiteral(
"Stroke" ) );
1331 if ( fillElem.isNull() && strokeElem.isNull() )
1333 QgsDebugMsg( QStringLiteral(
"neither Fill nor Stroke element not found in PolygonSymbolizer" ) );
1351 if ( l->
layerType() == QLatin1String(
"SimpleFill" ) || l->
layerType() == QLatin1String(
"SVGFill" ) )
1387 QDomElement fillElem = element.firstChildElement( QStringLiteral(
"Fill" ) );
1388 if ( fillElem.isNull() )
1390 QgsDebugMsg( QStringLiteral(
"Fill element not found" ) );
1410 QDomElement strokeElem = element.firstChildElement( QStringLiteral(
"Stroke" ) );
1411 if ( strokeElem.isNull() )
1413 QgsDebugMsg( QStringLiteral(
"Stroke element not found" ) );
1429 QDomElement graphicElem = element.firstChildElement( QStringLiteral(
"Graphic" ) );
1430 if ( graphicElem.isNull() )
1432 QgsDebugMsg( QStringLiteral(
"Graphic element not found" ) );
1452 QDomElement graphicElem = element.firstChildElement( QStringLiteral(
"Graphic" ) );
1453 if ( graphicElem.isNull() )
1456 QDomElement externalGraphicElem = graphicElem.firstChildElement( QStringLiteral(
"ExternalGraphic" ) );
1457 if ( externalGraphicElem.isNull() )
1461 QDomElement formatElem = externalGraphicElem.firstChildElement( QStringLiteral(
"Format" ) );
1462 if ( formatElem.isNull() )
1465 QString format = formatElem.firstChild().nodeValue();
1466 if ( format != QLatin1String(
"image/svg+xml" ) )
1468 QgsDebugMsg(
"unsupported External Graphic format found: " + format );
1473 QDomElement onlineResourceElem = externalGraphicElem.firstChildElement( QStringLiteral(
"OnlineResource" ) );
1474 QDomElement inlineContentElem = externalGraphicElem.firstChildElement( QStringLiteral(
"InlineContent" ) );
1475 if ( !onlineResourceElem.isNull() )
1480 else if ( !inlineContentElem.isNull() )
1493 QDomElement graphicElem = element.firstChildElement( QStringLiteral(
"Graphic" ) );
1494 if ( graphicElem.isNull() )
1497 QDomElement markElem = graphicElem.firstChildElement( QStringLiteral(
"Mark" ) );
1498 if ( markElem.isNull() )
1501 QDomElement wellKnownNameElem = markElem.firstChildElement( QStringLiteral(
"WellKnownName" ) );
1502 return !wellKnownNameElem.isNull();
1508 QDomElement graphicElem = element.firstChildElement( QStringLiteral(
"Graphic" ) );
1509 if ( graphicElem.isNull() )
1512 QDomElement markElem = graphicElem.firstChildElement( QStringLiteral(
"Mark" ) );
1513 if ( markElem.isNull() )
1517 QDomElement formatElem = markElem.firstChildElement( QStringLiteral(
"Format" ) );
1518 if ( formatElem.isNull() )
1521 QString format = formatElem.firstChild().nodeValue();
1522 if ( format != QLatin1String(
"ttf" ) )
1524 QgsDebugMsg(
"unsupported Graphic Mark format found: " + format );
1529 QDomElement onlineResourceElem = markElem.firstChildElement( QStringLiteral(
"OnlineResource" ) );
1530 QDomElement inlineContentElem = markElem.firstChildElement( QStringLiteral(
"InlineContent" ) );
1531 if ( !onlineResourceElem.isNull() )
1534 QDomElement markIndexElem = markElem.firstChildElement( QStringLiteral(
"MarkIndex" ) );
1535 if ( !markIndexElem.isNull() )
1538 else if ( !inlineContentElem.isNull() )
1553 QDomElement graphicElem = element.firstChildElement( QStringLiteral(
"Graphic" ) );
1554 if ( graphicElem.isNull() )
1558 for ( QgsStringMap::iterator it = vendorOptions.begin(); it != vendorOptions.end(); ++it )
1560 if ( it.key() == QLatin1String(
"widthHeightFactor" ) )
1571 QDomElement strokeElem = element.firstChildElement( QStringLiteral(
"Stroke" ) );
1572 if ( strokeElem.isNull() )
1575 QDomElement graphicStrokeElem = strokeElem.firstChildElement( QStringLiteral(
"GraphicStroke" ) );
1576 if ( graphicStrokeElem.isNull() )
1584 QDomElement fillElem = element.firstChildElement( QStringLiteral(
"Fill" ) );
1585 if ( fillElem.isNull() )
1588 QDomElement graphicFillElem = fillElem.firstChildElement( QStringLiteral(
"GraphicFill" ) );
1589 if ( graphicFillElem.isNull() )
1592 QDomElement graphicElem = graphicFillElem.firstChildElement( QStringLiteral(
"Graphic" ) );
1593 if ( graphicElem.isNull() )
1599 QColor fillColor, strokeColor;
1600 double size, strokeWidth;
1601 Qt::PenStyle strokeStyle;
1602 if ( !
wellKnownMarkerFromSld( graphicElem, name, fillColor, strokeColor, strokeStyle, strokeWidth, size ) )
1605 if ( name != QLatin1String(
"horline" ) )
1613 double angle = angleFunc.toDouble( &ok );
1625 QDomElement fillElem = element.firstChildElement( QStringLiteral(
"Fill" ) );
1626 if ( fillElem.isNull() )
1629 QDomElement graphicFillElem = fillElem.firstChildElement( QStringLiteral(
"GraphicFill" ) );
1630 if ( graphicFillElem.isNull() )
1650 QDomElement fillElem = element.firstChildElement( QStringLiteral(
"Fill" ) );
1651 QDomElement strokeElem = element.firstChildElement( QStringLiteral(
"Stroke" ) );
1655 bool validFill =
false, validStroke =
false;
1660 Qt::BrushStyle fillStyle;
1662 if (
fillFromSld( fillElem, fillStyle, fillColor ) )
1668 Qt::PenStyle strokeStyle;
1669 double strokeWidth = 1.0, dashOffset = 0.0;
1670 QVector<qreal> customDashPattern;
1672 if (
lineFromSld( strokeElem, strokeStyle, strokeColor, strokeWidth,
1673 nullptr,
nullptr, &customDashPattern, &dashOffset ) )
1676 if ( validFill || validStroke )
1679 map[QStringLiteral(
"name" )] = QStringLiteral(
"square" );
1680 map[QStringLiteral(
"color" )] =
encodeColor( validFill ? fillColor : Qt::transparent );
1681 map[QStringLiteral(
"color_border" )] =
encodeColor( validStroke ? strokeColor : Qt::transparent );
1682 map[QStringLiteral(
"size" )] = QString::number( 6 );
1683 map[QStringLiteral(
"angle" )] = QString::number( 0 );
1684 map[QStringLiteral(
"offset" )] =
encodePoint( QPointF( 0, 0 ) );
1691 bool validFill =
false, validStroke =
false;
1694 QString name, format;
1696 QColor fillColor, strokeColor;
1697 double strokeWidth = 1.0, size = 0.0,
angle = 0.0;
1701 QDomElement graphicFillElem = fillElem.firstChildElement( QStringLiteral(
"GraphicFill" ) );
1702 if ( !graphicFillElem.isNull() )
1705 QDomElement graphicElem = graphicFillElem.firstChildElement( QStringLiteral(
"Graphic" ) );
1706 if ( !graphicElem.isNull() )
1712 QDomElement graphicChildElem = graphicElem.firstChildElement();
1713 while ( !graphicChildElem.isNull() )
1715 if ( graphicChildElem.localName() == QLatin1String(
"Mark" ) )
1718 QDomElement wellKnownNameElem = graphicChildElem.firstChildElement( QStringLiteral(
"WellKnownName" ) );
1719 if ( !wellKnownNameElem.isNull() )
1721 name = wellKnownNameElem.firstChild().nodeValue();
1727 if ( graphicChildElem.localName() == QLatin1String(
"ExternalGraphic" ) || graphicChildElem.localName() == QLatin1String(
"Mark" ) )
1730 QDomElement formatElem = graphicChildElem.firstChildElement( QStringLiteral(
"Format" ) );
1731 if ( formatElem.isNull() )
1734 format = formatElem.firstChild().nodeValue();
1738 if ( graphicChildElem.localName() == QLatin1String(
"ExternalGraphic" ) && format != QLatin1String(
"image/svg+xml" ) )
1743 if ( graphicChildElem.localName() == QLatin1String(
"Mark" ) && format != QLatin1String(
"ttf" ) )
1747 QDomElement onlineResourceElem = graphicChildElem.firstChildElement( QStringLiteral(
"OnlineResource" ) );
1748 QDomElement inlineContentElem = graphicChildElem.firstChildElement( QStringLiteral(
"InlineContent" ) );
1750 if ( !onlineResourceElem.isNull() )
1752 name = onlineResourceElem.attributeNS( QStringLiteral(
"http://www.w3.org/1999/xlink" ), QStringLiteral(
"href" ) );
1754 if ( graphicChildElem.localName() == QLatin1String(
"Mark" ) && format == QLatin1String(
"ttf" ) )
1757 if ( name.startsWith( QLatin1String(
"ttf://" ) ) )
1758 name = name.mid( 6 );
1761 QDomElement markIndexElem = graphicChildElem.firstChildElement( QStringLiteral(
"MarkIndex" ) );
1762 if ( markIndexElem.isNull() )
1766 int v = markIndexElem.firstChild().nodeValue().toInt( &ok );
1777 else if ( !inlineContentElem.isNull() )
1787 if ( graphicChildElem.localName() == QLatin1String(
"Mark" ) )
1789 name = QStringLiteral(
"square" );
1796 if ( found && graphicChildElem.localName() == QLatin1String(
"Mark" ) )
1803 Qt::BrushStyle markFillStyle;
1805 QDomElement markFillElem = graphicChildElem.firstChildElement( QStringLiteral(
"Fill" ) );
1806 if (
fillFromSld( markFillElem, markFillStyle, fillColor ) )
1811 Qt::PenStyle strokeStyle;
1812 double strokeWidth = 1.0, dashOffset = 0.0;
1813 QVector<qreal> customDashPattern;
1815 QDomElement markStrokeElem = graphicChildElem.firstChildElement( QStringLiteral(
"Stroke" ) );
1816 if (
lineFromSld( markStrokeElem, strokeStyle, strokeColor, strokeWidth,
1817 nullptr,
nullptr, &customDashPattern, &dashOffset ) )
1824 QDomElement opacityElem = graphicElem.firstChildElement( QStringLiteral(
"Opacity" ) );
1825 if ( !opacityElem.isNull() )
1826 fillColor.setAlpha(
decodeSldAlpha( opacityElem.firstChild().nodeValue() ) );
1828 QDomElement sizeElem = graphicElem.firstChildElement( QStringLiteral(
"Size" ) );
1829 if ( !sizeElem.isNull() )
1832 double v = sizeElem.firstChild().nodeValue().toDouble( &ok );
1841 double v = angleFunc.toDouble( &ok );
1851 if ( validFill || validStroke )
1853 if ( format == QLatin1String(
"image/svg+xml" ) )
1856 map[QStringLiteral(
"name" )] = name;
1857 map[QStringLiteral(
"fill" )] = fillColor.name();
1858 map[QStringLiteral(
"outline" )] = strokeColor.name();
1859 map[QStringLiteral(
"outline-width" )] = QString::number( strokeWidth );
1861 map[QStringLiteral(
"size" )] = QString::number( size );
1863 map[QStringLiteral(
"angle" )] = QString::number(
angle );
1864 if ( !offset.isNull() )
1865 map[QStringLiteral(
"offset" )] =
encodePoint( offset );
1868 else if ( format == QLatin1String(
"ttf" ) )
1871 map[QStringLiteral(
"font" )] = name;
1872 map[QStringLiteral(
"chr" )] = markIndex;
1873 map[QStringLiteral(
"color" )] =
encodeColor( validFill ? fillColor : Qt::transparent );
1875 map[QStringLiteral(
"size" )] = QString::number( size );
1877 map[QStringLiteral(
"angle" )] = QString::number(
angle );
1878 if ( !offset.isNull() )
1879 map[QStringLiteral(
"offset" )] =
encodePoint( offset );
1885 if ( layers.isEmpty() )
1888 layerList << layers;
1895 QString patternName;
1896 switch ( brushStyle )
1901 case Qt::SolidPattern:
1902 if ( color.isValid() )
1905 if ( color.alpha() < 255 )
1910 case Qt::CrossPattern:
1911 case Qt::DiagCrossPattern:
1912 case Qt::HorPattern:
1913 case Qt::VerPattern:
1914 case Qt::BDiagPattern:
1915 case Qt::FDiagPattern:
1916 case Qt::Dense1Pattern:
1917 case Qt::Dense2Pattern:
1918 case Qt::Dense3Pattern:
1919 case Qt::Dense4Pattern:
1920 case Qt::Dense5Pattern:
1921 case Qt::Dense6Pattern:
1922 case Qt::Dense7Pattern:
1927 element.appendChild( doc.createComment( QStringLiteral(
"Qt::BrushStyle '%1'' not supported yet" ).arg( brushStyle ) ) );
1931 QDomElement graphicFillElem = doc.createElement( QStringLiteral(
"se:GraphicFill" ) );
1932 element.appendChild( graphicFillElem );
1934 QDomElement graphicElem = doc.createElement( QStringLiteral(
"se:Graphic" ) );
1935 graphicFillElem.appendChild( graphicElem );
1937 QColor fillColor = patternName.startsWith( QLatin1String(
"brush://" ) ) ? color : QColor();
1938 QColor strokeColor = !patternName.startsWith( QLatin1String(
"brush://" ) ) ? color : QColor();
1941 wellKnownMarkerToSld( doc, graphicElem, patternName, fillColor, strokeColor, Qt::SolidLine, -1, -1 );
1948 brushStyle = Qt::SolidPattern;
1949 color = QColor( 128, 128, 128 );
1951 if ( element.isNull() )
1953 brushStyle = Qt::NoBrush;
1958 QDomElement graphicFillElem = element.firstChildElement( QStringLiteral(
"GraphicFill" ) );
1960 if ( graphicFillElem.isNull() )
1963 for ( QgsStringMap::iterator it = svgParams.begin(); it != svgParams.end(); ++it )
1965 QgsDebugMsg( QStringLiteral(
"found SvgParameter %1: %2" ).arg( it.key(), it.value() ) );
1967 if ( it.key() == QLatin1String(
"fill" ) )
1968 color = QColor( it.value() );
1969 else if ( it.key() == QLatin1String(
"fill-opacity" ) )
1975 QDomElement graphicElem = graphicFillElem.firstChildElement( QStringLiteral(
"Graphic" ) );
1976 if ( graphicElem.isNull() )
1979 QString patternName = QStringLiteral(
"square" );
1980 QColor fillColor, strokeColor;
1981 double strokeWidth, size;
1982 Qt::PenStyle strokeStyle;
1983 if ( !
wellKnownMarkerFromSld( graphicElem, patternName, fillColor, strokeColor, strokeStyle, strokeWidth, size ) )
1987 if ( brushStyle == Qt::NoBrush )
1990 QColor
c = patternName.startsWith( QLatin1String(
"brush://" ) ) ? fillColor : strokeColor;
1999 Qt::PenStyle penStyle,
const QColor &color,
double width,
2000 const Qt::PenJoinStyle *penJoinStyle,
const Qt::PenCapStyle *penCapStyle,
2001 const QVector<qreal> *customDashPattern,
double dashOffset )
2003 QVector<qreal> dashPattern;
2004 const QVector<qreal> *pattern = &dashPattern;
2006 if ( penStyle == Qt::CustomDashLine && !customDashPattern )
2008 element.appendChild( doc.createComment( QStringLiteral(
"WARNING: Custom dash pattern required but not provided. Using default dash pattern." ) ) );
2009 penStyle = Qt::DashLine;
2021 dashPattern.push_back( 4.0 );
2022 dashPattern.push_back( 2.0 );
2025 dashPattern.push_back( 1.0 );
2026 dashPattern.push_back( 2.0 );
2028 case Qt::DashDotLine:
2029 dashPattern.push_back( 4.0 );
2030 dashPattern.push_back( 2.0 );
2031 dashPattern.push_back( 1.0 );
2032 dashPattern.push_back( 2.0 );
2034 case Qt::DashDotDotLine:
2035 dashPattern.push_back( 4.0 );
2036 dashPattern.push_back( 2.0 );
2037 dashPattern.push_back( 1.0 );
2038 dashPattern.push_back( 2.0 );
2039 dashPattern.push_back( 1.0 );
2040 dashPattern.push_back( 2.0 );
2043 case Qt::CustomDashLine:
2044 Q_ASSERT( customDashPattern );
2045 pattern = customDashPattern;
2049 element.appendChild( doc.createComment( QStringLiteral(
"Qt::BrushStyle '%1'' not supported yet" ).arg( penStyle ) ) );
2053 if ( color.isValid() )
2056 if ( color.alpha() < 255 )
2063 else if ( width == 0 )
2073 if ( !pattern->isEmpty() )
2083 Qt::PenStyle &penStyle, QColor &color,
double &width,
2084 Qt::PenJoinStyle *penJoinStyle, Qt::PenCapStyle *penCapStyle,
2085 QVector<qreal> *customDashPattern,
double *dashOffset )
2089 penStyle = Qt::SolidLine;
2090 color = QColor( 0, 0, 0 );
2093 *penJoinStyle = Qt::BevelJoin;
2095 *penCapStyle = Qt::SquareCap;
2096 if ( customDashPattern )
2097 customDashPattern->clear();
2101 if ( element.isNull() )
2103 penStyle = Qt::NoPen;
2109 for ( QgsStringMap::iterator it = svgParams.begin(); it != svgParams.end(); ++it )
2111 QgsDebugMsg( QStringLiteral(
"found SvgParameter %1: %2" ).arg( it.key(), it.value() ) );
2113 if ( it.key() == QLatin1String(
"stroke" ) )
2115 color = QColor( it.value() );
2117 else if ( it.key() == QLatin1String(
"stroke-opacity" ) )
2121 else if ( it.key() == QLatin1String(
"stroke-width" ) )
2124 double w = it.value().toDouble( &ok );
2128 else if ( it.key() == QLatin1String(
"stroke-linejoin" ) && penJoinStyle )
2132 else if ( it.key() == QLatin1String(
"stroke-linecap" ) && penCapStyle )
2136 else if ( it.key() == QLatin1String(
"stroke-dasharray" ) )
2139 if ( !dashPattern.isEmpty() )
2143 bool dashPatternFound =
false;
2145 if ( dashPattern.count() == 2 )
2147 if ( dashPattern.at( 0 ) == 4.0 &&
2148 dashPattern.at( 1 ) == 2.0 )
2150 penStyle = Qt::DashLine;
2151 dashPatternFound =
true;
2153 else if ( dashPattern.at( 0 ) == 1.0 &&
2154 dashPattern.at( 1 ) == 2.0 )
2156 penStyle = Qt::DotLine;
2157 dashPatternFound =
true;
2160 else if ( dashPattern.count() == 4 )
2162 if ( dashPattern.at( 0 ) == 4.0 &&
2163 dashPattern.at( 1 ) == 2.0 &&
2164 dashPattern.at( 2 ) == 1.0 &&
2165 dashPattern.at( 3 ) == 2.0 )
2167 penStyle = Qt::DashDotLine;
2168 dashPatternFound =
true;
2171 else if ( dashPattern.count() == 6 )
2173 if ( dashPattern.at( 0 ) == 4.0 &&
2174 dashPattern.at( 1 ) == 2.0 &&
2175 dashPattern.at( 2 ) == 1.0 &&
2176 dashPattern.at( 3 ) == 2.0 &&
2177 dashPattern.at( 4 ) == 1.0 &&
2178 dashPattern.at( 5 ) == 2.0 )
2180 penStyle = Qt::DashDotDotLine;
2181 dashPatternFound =
true;
2186 if ( !dashPatternFound )
2188 if ( customDashPattern )
2190 penStyle = Qt::CustomDashLine;
2191 *customDashPattern = dashPattern;
2195 QgsDebugMsg( QStringLiteral(
"custom dash pattern required but not provided. Using default dash pattern." ) );
2196 penStyle = Qt::DashLine;
2201 else if ( it.key() == QLatin1String(
"stroke-dashoffset" ) && dashOffset )
2204 double d = it.value().toDouble( &ok );
2214 const QString &path,
const QString &mime,
2215 const QColor &color,
double size )
2217 QDomElement externalGraphicElem = doc.createElement( QStringLiteral(
"se:ExternalGraphic" ) );
2218 element.appendChild( externalGraphicElem );
2227 QDomElement sizeElem = doc.createElement( QStringLiteral(
"se:Size" ) );
2229 element.appendChild( sizeElem );
2234 const QString &path,
const QColor &fillColor,
double size,
const QColor &strokeColor,
double strokeWidth )
2241 graphicElem.appendChild( doc.createComment( QStringLiteral(
"Parametric SVG" ) ) );
2245 graphicElem.appendChild( doc.createComment( QStringLiteral(
"Plain SVG fallback, no parameters" ) ) );
2248 graphicElem.appendChild( doc.createComment( QStringLiteral(
"Well known marker fallback" ) ) );
2254 QDomElement sizeElem = doc.createElement( QStringLiteral(
"se:Size" ) );
2256 graphicElem.appendChild( sizeElem );
2264 if ( fillColor.isValid() )
2266 url.addQueryItem( QStringLiteral(
"fill" ), fillColor.name() );
2267 url.addQueryItem( QStringLiteral(
"fill-opacity" ),
encodeSldAlpha( fillColor.alpha() ) );
2271 url.addQueryItem( QStringLiteral(
"fill" ), QStringLiteral(
"#000000" ) );
2272 url.addQueryItem( QStringLiteral(
"fill-opacity" ), QStringLiteral(
"1" ) );
2274 if ( strokeColor.isValid() )
2276 url.addQueryItem( QStringLiteral(
"outline" ), strokeColor.name() );
2277 url.addQueryItem( QStringLiteral(
"outline-opacity" ),
encodeSldAlpha( strokeColor.alpha() ) );
2281 url.addQueryItem( QStringLiteral(
"outline" ), QStringLiteral(
"#000000" ) );
2282 url.addQueryItem( QStringLiteral(
"outline-opacity" ), QStringLiteral(
"1" ) );
2284 url.addQueryItem( QStringLiteral(
"outline-width" ), QString::number( strokeWidth ) );
2285 QString params = url.toString( QUrl::FullyEncoded );
2286 if ( params.isEmpty() )
2292 return basePath +
"?" + params;
2297 QString &path, QString &mime,
2298 QColor &color,
double &size )
2303 QDomElement externalGraphicElem = element.firstChildElement( QStringLiteral(
"ExternalGraphic" ) );
2304 if ( externalGraphicElem.isNull() )
2309 QDomElement sizeElem = element.firstChildElement( QStringLiteral(
"Size" ) );
2310 if ( !sizeElem.isNull() )
2313 double s = sizeElem.firstChild().nodeValue().toDouble( &ok );
2322 const QString &path,
const QString &format,
int *markIndex,
2323 const QColor &color,
double size )
2325 QDomElement markElem = doc.createElement( QStringLiteral(
"se:Mark" ) );
2326 element.appendChild( markElem );
2332 QDomElement markIndexElem = doc.createElement( QStringLiteral(
"se:MarkIndex" ) );
2333 markIndexElem.appendChild( doc.createTextNode( QString::number( *markIndex ) ) );
2334 markElem.appendChild( markIndexElem );
2338 QDomElement fillElem = doc.createElement( QStringLiteral(
"se:Fill" ) );
2339 fillToSld( doc, fillElem, Qt::SolidPattern, color );
2340 markElem.appendChild( fillElem );
2345 QDomElement sizeElem = doc.createElement( QStringLiteral(
"se:Size" ) );
2347 element.appendChild( sizeElem );
2352 QString &path, QString &format,
int &markIndex,
2353 QColor &color,
double &size )
2361 QDomElement markElem = element.firstChildElement( QStringLiteral(
"Mark" ) );
2362 if ( markElem.isNull() )
2367 QDomElement markIndexElem = markElem.firstChildElement( QStringLiteral(
"MarkIndex" ) );
2368 if ( !markIndexElem.isNull() )
2371 int i = markIndexElem.firstChild().nodeValue().toInt( &ok );
2377 QDomElement fillElem = markElem.firstChildElement( QStringLiteral(
"Fill" ) );
2378 Qt::BrushStyle b = Qt::SolidPattern;
2383 QDomElement sizeElem = element.firstChildElement( QStringLiteral(
"Size" ) );
2384 if ( !sizeElem.isNull() )
2387 double s = sizeElem.firstChild().nodeValue().toDouble( &ok );
2396 const QString &name,
const QColor &color,
const QColor &strokeColor, Qt::PenStyle strokeStyle,
2397 double strokeWidth,
double size )
2399 QDomElement markElem = doc.createElement( QStringLiteral(
"se:Mark" ) );
2400 element.appendChild( markElem );
2402 QDomElement wellKnownNameElem = doc.createElement( QStringLiteral(
"se:WellKnownName" ) );
2403 wellKnownNameElem.appendChild( doc.createTextNode( name ) );
2404 markElem.appendChild( wellKnownNameElem );
2407 if ( color.isValid() )
2409 QDomElement fillElem = doc.createElement( QStringLiteral(
"se:Fill" ) );
2410 fillToSld( doc, fillElem, Qt::SolidPattern, color );
2411 markElem.appendChild( fillElem );
2415 if ( strokeColor.isValid() )
2417 QDomElement strokeElem = doc.createElement( QStringLiteral(
"se:Stroke" ) );
2418 lineToSld( doc, strokeElem, strokeStyle, strokeColor, strokeWidth );
2419 markElem.appendChild( strokeElem );
2425 QDomElement sizeElem = doc.createElement( QStringLiteral(
"se:Size" ) );
2427 element.appendChild( sizeElem );
2432 QString &name, QColor &color, QColor &strokeColor, Qt::PenStyle &strokeStyle,
2433 double &strokeWidth,
double &size )
2437 name = QStringLiteral(
"square" );
2439 strokeColor = QColor( 0, 0, 0 );
2443 QDomElement markElem = element.firstChildElement( QStringLiteral(
"Mark" ) );
2444 if ( markElem.isNull() )
2447 QDomElement wellKnownNameElem = markElem.firstChildElement( QStringLiteral(
"WellKnownName" ) );
2448 if ( !wellKnownNameElem.isNull() )
2450 name = wellKnownNameElem.firstChild().nodeValue();
2451 QgsDebugMsg(
"found Mark with well known name: " + name );
2455 QDomElement fillElem = markElem.firstChildElement( QStringLiteral(
"Fill" ) );
2456 Qt::BrushStyle b = Qt::SolidPattern;
2461 QDomElement strokeElem = markElem.firstChildElement( QStringLiteral(
"Stroke" ) );
2462 lineFromSld( strokeElem, strokeStyle, strokeColor, strokeWidth );
2466 QDomElement sizeElem = element.firstChildElement( QStringLiteral(
"Size" ) );
2467 if ( !sizeElem.isNull() )
2470 double s = sizeElem.firstChild().nodeValue().toDouble( &ok );
2480 if ( !rotationFunc.isEmpty() )
2482 QDomElement rotationElem = doc.createElement( QStringLiteral(
"se:Rotation" ) );
2484 element.appendChild( rotationElem );
2490 QDomElement rotationElem = element.firstChildElement( QStringLiteral(
"Rotation" ) );
2491 if ( !rotationElem.isNull() )
2501 if ( !alphaFunc.isEmpty() )
2503 QDomElement opacityElem = doc.createElement( QStringLiteral(
"se:Opacity" ) );
2505 element.appendChild( opacityElem );
2511 QDomElement opacityElem = element.firstChildElement( QStringLiteral(
"Opacity" ) );
2512 if ( !opacityElem.isNull() )
2521 if ( offset.isNull() )
2524 QDomElement displacementElem = doc.createElement( QStringLiteral(
"se:Displacement" ) );
2525 element.appendChild( displacementElem );
2527 QDomElement dispXElem = doc.createElement( QStringLiteral(
"se:DisplacementX" ) );
2528 dispXElem.appendChild( doc.createTextNode(
qgsDoubleToString( offset.x(), 2 ) ) );
2530 QDomElement dispYElem = doc.createElement( QStringLiteral(
"se:DisplacementY" ) );
2531 dispYElem.appendChild( doc.createTextNode(
qgsDoubleToString( offset.y(), 2 ) ) );
2533 displacementElem.appendChild( dispXElem );
2534 displacementElem.appendChild( dispYElem );
2541 QDomElement anchorElem = doc.createElement( QStringLiteral(
"se:AnchorPoint" ) );
2542 element.appendChild( anchorElem );
2544 QDomElement anchorXElem = doc.createElement( QStringLiteral(
"se:AnchorPointX" ) );
2545 anchorXElem.appendChild( doc.createTextNode(
qgsDoubleToString( anchor.x() ) ) );
2547 QDomElement anchorYElem = doc.createElement( QStringLiteral(
"se:AnchorPointY" ) );
2548 anchorYElem.appendChild( doc.createTextNode(
qgsDoubleToString( anchor.y() ) ) );
2550 anchorElem.appendChild( anchorXElem );
2551 anchorElem.appendChild( anchorYElem );
2556 offset = QPointF( 0, 0 );
2558 QDomElement displacementElem = element.firstChildElement( QStringLiteral(
"Displacement" ) );
2559 if ( displacementElem.isNull() )
2562 QDomElement dispXElem = displacementElem.firstChildElement( QStringLiteral(
"DisplacementX" ) );
2563 if ( !dispXElem.isNull() )
2566 double offsetX = dispXElem.firstChild().nodeValue().toDouble( &ok );
2568 offset.setX( offsetX );
2571 QDomElement dispYElem = displacementElem.firstChildElement( QStringLiteral(
"DisplacementY" ) );
2572 if ( !dispYElem.isNull() )
2575 double offsetY = dispYElem.firstChild().nodeValue().toDouble( &ok );
2577 offset.setY( offsetY );
2584 const QString &label,
const QFont &font,
2585 const QColor &color,
double size )
2587 QDomElement labelElem = doc.createElement( QStringLiteral(
"se:Label" ) );
2588 labelElem.appendChild( doc.createTextNode( label ) );
2589 element.appendChild( labelElem );
2591 QDomElement fontElem = doc.createElement( QStringLiteral(
"se:Font" ) );
2592 element.appendChild( fontElem );
2596 fontElem.appendChild( createSldParameterElement( doc,
"font-style",
encodeSldFontStyle( font.style() ) ) );
2597 fontElem.appendChild( createSldParameterElement( doc,
"font-weight",
encodeSldFontWeight( font.weight() ) ) );
2602 if ( color.isValid() )
2604 QDomElement fillElem = doc.createElement( QStringLiteral(
"Fill" ) );
2605 fillToSld( doc, fillElem, Qt::SolidPattern, color );
2606 element.appendChild( fillElem );
2611 Qt::PenJoinStyle joinStyle,
2612 Qt::PenCapStyle capStyle,
2614 const QVector<qreal> *dashPattern )
2617 penStyle.append(
"PEN(" );
2618 penStyle.append(
"c:" );
2619 penStyle.append( c.name() );
2620 penStyle.append(
",w:" );
2622 penStyle.append( QString::number( width * mmScaleFactor ) );
2623 penStyle.append(
"mm" );
2626 if ( dashPattern && !dashPattern->isEmpty() )
2628 penStyle.append(
",p:\"" );
2629 QVector<qreal>::const_iterator pIt = dashPattern->constBegin();
2630 for ( ; pIt != dashPattern->constEnd(); ++pIt )
2632 if ( pIt != dashPattern->constBegin() )
2634 penStyle.append(
' ' );
2636 penStyle.append( QString::number( *pIt * mapUnitScaleFactor ) );
2637 penStyle.append(
'g' );
2639 penStyle.append(
'\"' );
2643 penStyle.append(
",cap:" );
2647 penStyle.append(
'p' );
2650 penStyle.append(
'r' );
2654 penStyle.append(
'b' );
2658 penStyle.append(
",j:" );
2659 switch ( joinStyle )
2662 penStyle.append(
'b' );
2665 penStyle.append(
'r' );
2669 penStyle.append(
'm' );
2675 penStyle.append(
",dp:" );
2676 penStyle.append( QString::number( offset * mapUnitScaleFactor ) );
2677 penStyle.append(
'g' );
2680 penStyle.append(
')' );
2687 brushStyle.append(
"BRUSH(" );
2688 brushStyle.append(
"fc:" );
2689 brushStyle.append( fillColor.name() );
2690 brushStyle.append(
')' );
2696 if ( geomFunc.isEmpty() )
2699 QDomElement geometryElem = doc.createElement( QStringLiteral(
"Geometry" ) );
2700 element.appendChild( geometryElem );
2730 QDomElement geometryElem = element.firstChildElement( QStringLiteral(
"Geometry" ) );
2731 if ( geometryElem.isNull() )
2743 element.appendChild( doc.createComment(
"Parser Error: " + expr.
parserErrorString() +
" - Expression was: " + function ) );
2747 if ( !filterElem.isNull() )
2748 element.appendChild( filterElem );
2759 element.appendChild( doc.createComment(
"Parser Error: " + expr.
parserErrorString() +
" - Expression was: " + function ) );
2763 if ( !filterElem.isNull() )
2764 element.appendChild( filterElem );
2771 QDomElement elem = element;
2772 if ( element.tagName() != QLatin1String(
"Filter" ) )
2774 QDomNodeList filterNodes = element.elementsByTagName( QStringLiteral(
"Filter" ) );
2775 if ( !filterNodes.isEmpty() )
2777 elem = filterNodes.at( 0 ).toElement();
2781 if ( elem.isNull() )
2806 const QString &path,
const QString &format )
2810 QDomElement onlineResourceElem = doc.createElement( QStringLiteral(
"se:OnlineResource" ) );
2811 onlineResourceElem.setAttribute( QStringLiteral(
"xlink:type" ), QStringLiteral(
"simple" ) );
2812 onlineResourceElem.setAttribute( QStringLiteral(
"xlink:href" ), url );
2813 element.appendChild( onlineResourceElem );
2815 QDomElement formatElem = doc.createElement( QStringLiteral(
"se:Format" ) );
2816 formatElem.appendChild( doc.createTextNode( format ) );
2817 element.appendChild( formatElem );
2824 QDomElement onlineResourceElem = element.firstChildElement( QStringLiteral(
"OnlineResource" ) );
2825 if ( onlineResourceElem.isNull() )
2828 path = onlineResourceElem.attributeNS( QStringLiteral(
"http://www.w3.org/1999/xlink" ), QStringLiteral(
"href" ) );
2830 QDomElement formatElem = element.firstChildElement( QStringLiteral(
"Format" ) );
2831 if ( formatElem.isNull() )
2834 format = formatElem.firstChild().nodeValue();
2841 QDomElement nodeElem = doc.createElement( QStringLiteral(
"se:SvgParameter" ) );
2842 nodeElem.setAttribute( QStringLiteral(
"name" ), name );
2843 nodeElem.appendChild( doc.createTextNode( value ) );
2852 QDomElement paramElem = element.firstChildElement();
2853 while ( !paramElem.isNull() )
2855 if ( paramElem.localName() == QLatin1String(
"SvgParameter" ) || paramElem.localName() == QLatin1String(
"CssParameter" ) )
2857 QString name = paramElem.attribute( QStringLiteral(
"name" ) );
2858 if ( paramElem.firstChild().nodeType() == QDomNode::TextNode )
2860 value = paramElem.firstChild().nodeValue();
2864 if ( paramElem.firstChild().nodeType() == QDomNode::ElementNode &&
2865 paramElem.firstChild().localName() == QLatin1String(
"Literal" ) )
2867 QgsDebugMsg( paramElem.firstChild().localName() );
2868 value = paramElem.firstChild().firstChild().nodeValue();
2872 QgsDebugMsg( QStringLiteral(
"unexpected child of %1" ).arg( paramElem.localName() ) );
2876 if ( !name.isEmpty() && !value.isEmpty() )
2877 params[ name ] = value;
2880 paramElem = paramElem.nextSiblingElement();
2888 QDomElement nodeElem = doc.createElement( QStringLiteral(
"se:VendorOption" ) );
2889 nodeElem.setAttribute( QStringLiteral(
"name" ), name );
2890 nodeElem.appendChild( doc.createTextNode( value ) );
2898 QDomElement paramElem = element.firstChildElement( QStringLiteral(
"VendorOption" ) );
2899 while ( !paramElem.isNull() )
2901 QString name = paramElem.attribute( QStringLiteral(
"name" ) );
2902 QString value = paramElem.firstChild().nodeValue();
2904 if ( !name.isEmpty() && !value.isEmpty() )
2905 params[ name ] = value;
2907 paramElem = paramElem.nextSiblingElement( QStringLiteral(
"VendorOption" ) );
2917 QDomElement e = element.firstChildElement();
2918 while ( !e.isNull() )
2920 if ( e.tagName() == QLatin1String(
"prop" ) )
2922 QString propKey = e.attribute( QStringLiteral(
"k" ) );
2923 QString propValue = e.attribute( QStringLiteral(
"v" ) );
2924 props[propKey] = propValue;
2926 e = e.nextSiblingElement();
2934 for ( QgsStringMap::iterator it = props.begin(); it != props.end(); ++it )
2936 QDomElement propEl = doc.createElement( QStringLiteral(
"prop" ) );
2937 propEl.setAttribute( QStringLiteral(
"k" ), it.key() );
2938 propEl.setAttribute( QStringLiteral(
"v" ), it.value() );
2939 element.appendChild( propEl );
2948 QDomElement e = element.firstChildElement();
2950 while ( !e.isNull() )
2952 if ( e.tagName() == QLatin1String(
"symbol" ) )
2956 symbols.insert( e.attribute( QStringLiteral(
"name" ) ), symbol );
2962 e = e.nextSiblingElement();
2969 QStringList subsymbols;
2971 for ( QMap<QString, QgsSymbol *>::iterator it = symbols.begin(); it != symbols.end(); ++it )
2973 if ( it.key()[0] !=
'@' )
2977 subsymbols.append( it.key() );
2979 QStringList parts = it.key().split(
'@' );
2980 if ( parts.count() < 3 )
2982 QgsDebugMsg(
"found subsymbol with invalid name: " + it.key() );
2986 QString symname = parts[1];
2987 int symlayer = parts[2].toInt();
2989 if ( !symbols.contains( symname ) )
2991 QgsDebugMsg(
"subsymbol references invalid symbol: " + symname );
2999 QgsDebugMsg(
"subsymbol references invalid symbol layer: " + QString::number( symlayer ) );
3008 QgsDebugMsg(
"symbol layer refused subsymbol: " + it.key() );
3015 for (
int i = 0; i < subsymbols.count(); i++ )
3016 symbols.take( subsymbols[i] );
3023 QDomElement symbolsElem = doc.createElement( tagName );
3026 for ( QMap<QString, QgsSymbol *>::iterator its = symbols.begin(); its != symbols.end(); ++its )
3028 QDomElement symEl =
saveSymbol( its.key(), its.value(), doc, context );
3029 symbolsElem.appendChild( symEl );
3037 qDeleteAll( symbols );
3046 std::unique_ptr< QMimeData >mimeData(
new QMimeData );
3048 QDomDocument symbolDoc;
3050 symbolDoc.appendChild( symbolElem );
3051 mimeData->setText( symbolDoc.toString() );
3054 mimeData->setColorData( symbol->
color() );
3056 return mimeData.release();
3064 QString text = data->text();
3065 if ( !text.isEmpty() )
3070 if ( doc.setContent( text ) )
3072 elem = doc.documentElement();
3074 if ( elem.nodeName() != QStringLiteral(
"symbol" ) )
3075 elem = elem.firstChildElement( QStringLiteral(
"symbol" ) );
3086 QString rampType = element.attribute( QStringLiteral(
"type" ) );
3091 if ( rampType == QLatin1String(
"gradient" ) )
3093 else if ( rampType == QLatin1String(
"random" ) )
3095 else if ( rampType == QLatin1String(
"colorbrewer" ) )
3097 else if ( rampType == QLatin1String(
"cpt-city" ) )
3099 else if ( rampType == QLatin1String(
"preset" ) )
3103 QgsDebugMsg(
"unknown colorramp type " + rampType );
3111 QDomElement rampEl = doc.createElement( QStringLiteral(
"colorramp" ) );
3112 rampEl.setAttribute( QStringLiteral(
"type" ), ramp->
type() );
3113 rampEl.setAttribute( QStringLiteral(
"name" ), name );
3121 QVariantMap rampMap;
3123 rampMap.insert( QStringLiteral(
"type" ), ramp->
type() );
3124 rampMap.insert( QStringLiteral(
"name" ), name );
3128 QVariantMap propertyMap;
3129 for (
auto property = properties.constBegin();
property != properties.constEnd(); ++property )
3131 propertyMap.insert( property.key(),
property.value() );
3134 rampMap.insert( QStringLiteral(
"properties" ), propertyMap );
3140 QVariantMap rampMap = value.toMap();
3142 QString rampType = rampMap.
value( QStringLiteral(
"type" ) ).toString();
3145 QVariantMap propertyMap = rampMap.value( QStringLiteral(
"properties" ) ).toMap();
3148 for (
auto property = propertyMap.constBegin();
property != propertyMap.constEnd(); ++property )
3150 props.insert( property.key(),
property.value().toString() );
3153 if ( rampType == QLatin1String(
"gradient" ) )
3155 else if ( rampType == QLatin1String(
"random" ) )
3157 else if ( rampType == QLatin1String(
"colorbrewer" ) )
3159 else if ( rampType == QLatin1String(
"cpt-city" ) )
3161 else if ( rampType == QLatin1String(
"preset" ) )
3165 QgsDebugMsg(
"unknown colorramp type " + rampType );
3172 if ( !color.isValid() )
3179 return color.name();
3184 QList<QColor> colors;
3187 QStringList components = colorStr.simplified().split( QRegExp(
"(,|\\s)" ) );
3188 QStringList::iterator it = components.begin();
3189 for ( ; it != components.end(); ++it )
3192 if ( result.isValid() )
3197 if ( colors.length() > 0 )
3203 components = colorStr.split( QRegExp(
"(,|\n)" ) );
3204 it = components.begin();
3205 for ( ; it != components.end(); ++it )
3208 if ( result.isValid() )
3213 if ( colors.length() > 0 )
3219 components = colorStr.simplified().split( QString(
' ' ) );
3220 it = components.begin();
3221 for ( ; it != components.end(); ++it )
3224 if ( result.isValid() )
3229 if ( colors.length() > 0 )
3235 components = colorStr.split(
'\n' );
3236 it = components.begin();
3237 for ( ; it != components.end(); ++it )
3240 if ( result.isValid() )
3253 QMimeData *mimeData =
new QMimeData;
3254 mimeData->setColorData( QVariant( color ) );
3255 mimeData->setText( color.name() );
3262 QColor mimeColor = mimeData->colorData().value<QColor>();
3263 if ( mimeColor.isValid() )
3272 if ( textColor.isValid() )
3286 if ( data->hasFormat( QStringLiteral(
"text/xml" ) ) )
3289 QByteArray encodedData = data->data( QStringLiteral(
"text/xml" ) );
3290 QDomDocument xmlDoc;
3291 xmlDoc.setContent( encodedData );
3293 QDomElement dragDataElem = xmlDoc.documentElement();
3294 if ( dragDataElem.tagName() == QLatin1String(
"ColorSchemeModelDragData" ) )
3296 QDomNodeList nodeList = dragDataElem.childNodes();
3297 int nChildNodes = nodeList.size();
3298 QDomElement currentElem;
3300 for (
int i = 0; i < nChildNodes; ++i )
3302 currentElem = nodeList.at( i ).toElement();
3303 if ( currentElem.isNull() )
3308 QPair< QColor, QString> namedColor;
3310 namedColor.second = currentElem.attribute( QStringLiteral(
"label" ), QString() );
3312 mimeColors << namedColor;
3317 if ( mimeColors.length() == 0 && data->hasFormat( QStringLiteral(
"application/x-colorobject-list" ) ) )
3320 QByteArray encodedData = data->data( QStringLiteral(
"application/x-colorobject-list" ) );
3321 QDomDocument xmlDoc;
3322 xmlDoc.setContent( encodedData );
3324 QDomNodeList colorsNodes = xmlDoc.elementsByTagName( QStringLiteral(
"colors" ) );
3325 if ( colorsNodes.length() > 0 )
3327 QDomElement colorsElem = colorsNodes.at( 0 ).toElement();
3328 QDomNodeList colorNodeList = colorsElem.childNodes();
3329 int nChildNodes = colorNodeList.size();
3330 QDomElement currentElem;
3332 for (
int i = 0; i < nChildNodes; ++i )
3335 currentElem = colorNodeList.at( i ).toElement();
3336 if ( currentElem.isNull() )
3341 QDomNodeList colorNodes = currentElem.elementsByTagName( QStringLiteral(
"color" ) );
3342 QDomNodeList nameNodes = currentElem.elementsByTagName( QStringLiteral(
"name" ) );
3344 if ( colorNodes.length() > 0 )
3346 QDomElement colorElem = colorNodes.at( 0 ).toElement();
3348 QStringList colorParts = colorElem.text().simplified().split(
' ' );
3349 if ( colorParts.length() < 3 )
3354 int red = colorParts.at( 0 ).toDouble() * 255;
3355 int green = colorParts.at( 1 ).toDouble() * 255;
3356 int blue = colorParts.at( 2 ).toDouble() * 255;
3357 QPair< QColor, QString> namedColor;
3358 namedColor.first = QColor( red, green, blue );
3359 if ( nameNodes.length() > 0 )
3361 QDomElement nameElem = nameNodes.at( 0 ).toElement();
3362 namedColor.second = nameElem.text();
3364 mimeColors << namedColor;
3370 if ( mimeColors.length() == 0 && data->hasText() )
3374 QList< QColor >::iterator it = parsedColors.begin();
3375 for ( ; it != parsedColors.end(); ++it )
3377 mimeColors << qMakePair( *it, QString() );
3381 if ( mimeColors.length() == 0 && data->hasColor() )
3384 QColor mimeColor = data->colorData().value<QColor>();
3385 if ( mimeColor.isValid() )
3387 mimeColors << qMakePair( mimeColor, QString() );
3397 QMimeData *mimeData =
new QMimeData();
3398 QDomDocument xmlDoc;
3399 QDomElement xmlRootElement = xmlDoc.createElement( QStringLiteral(
"ColorSchemeModelDragData" ) );
3400 xmlDoc.appendChild( xmlRootElement );
3402 QgsNamedColorList::const_iterator colorIt = colorList.constBegin();
3403 for ( ; colorIt != colorList.constEnd(); ++colorIt )
3405 QDomElement namedColor = xmlDoc.createElement( QStringLiteral(
"NamedColor" ) );
3407 namedColor.setAttribute( QStringLiteral(
"label" ), ( *colorIt ).second );
3408 xmlRootElement.appendChild( namedColor );
3410 mimeData->setData( QStringLiteral(
"text/xml" ), xmlDoc.toByteArray() );
3418 colorIt = colorList.constBegin();
3419 QStringList colorListString;
3420 for ( ; colorIt != colorList.constEnd(); ++colorIt )
3422 colorListString << ( *colorIt ).first.name();
3424 mimeData->setText( colorListString.join( QStringLiteral(
"\n" ) ) );
3427 if ( colorList.length() > 0 )
3429 mimeData->setColorData( QVariant( colorList.at( 0 ).first ) );
3437 if ( !file.open( QIODevice::WriteOnly | QIODevice::Truncate ) )
3442 QTextStream stream( &file );
3443 stream <<
"GIMP Palette" << endl;
3444 if ( paletteName.isEmpty() )
3446 stream <<
"Name: QGIS Palette" << endl;
3450 stream <<
"Name: " << paletteName << endl;
3452 stream <<
"Columns: 4" << endl;
3453 stream <<
'#' << endl;
3455 for ( QgsNamedColorList::ConstIterator colorIt = colors.constBegin(); colorIt != colors.constEnd(); ++colorIt )
3457 QColor color = ( *colorIt ).first;
3458 if ( !color.isValid() )
3462 stream << QStringLiteral(
"%1 %2 %3" ).arg( color.red(), 3 ).arg( color.green(), 3 ).arg( color.blue(), 3 );
3463 stream <<
"\t" << ( ( *colorIt ).second.isEmpty() ? color.name() : ( *colorIt ).second ) << endl;
3474 if ( !file.open( QIODevice::ReadOnly ) )
3477 return importedColors;
3480 QTextStream in( &file );
3482 QString line = in.readLine();
3483 if ( !line.startsWith( QLatin1String(
"GIMP Palette" ) ) )
3486 return importedColors;
3490 while ( !in.atEnd() && !line.startsWith( QLatin1String(
"Name:" ) ) && !line.startsWith(
'#' ) )
3492 line = in.readLine();
3494 if ( line.startsWith( QLatin1String(
"Name:" ) ) )
3496 QRegExp nameRx(
"Name:\\s*(\\S.*)$" );
3497 if ( nameRx.indexIn( line ) != -1 )
3499 name = nameRx.cap( 1 );
3504 while ( !in.atEnd() && !line.startsWith(
'#' ) )
3506 line = in.readLine();
3511 return importedColors;
3515 QRegExp rx(
"^\\s*(\\d+)\\s+(\\d+)\\s+(\\d+)(\\s.*)?$" );
3516 while ( !in.atEnd() )
3518 line = in.readLine();
3519 if ( rx.indexIn( line ) == -1 )
3523 int red = rx.cap( 1 ).toInt();
3524 int green = rx.cap( 2 ).toInt();
3525 int blue = rx.cap( 3 ).toInt();
3526 QColor color = QColor( red, green, blue );
3527 if ( !color.isValid() )
3534 if ( rx.captureCount() > 3 )
3536 label = rx.cap( 4 ).simplified();
3543 importedColors << qMakePair( color, label );
3548 return importedColors;
3561 QRegExp hexColorAlphaRx(
"^\\s*#?([0-9a-fA-F]{6})([0-9a-fA-F]{2})\\s*$" );
3562 int hexColorIndex = hexColorAlphaRx.indexIn( colorStr );
3565 if ( hexColorIndex == -1 && QColor::isValidColor( colorStr ) )
3568 parsedColor.setNamedColor( colorStr );
3569 if ( parsedColor.isValid() )
3571 containsAlpha =
false;
3577 if ( hexColorIndex > -1 )
3579 QString hexColor = hexColorAlphaRx.cap( 1 );
3580 parsedColor.setNamedColor( QStringLiteral(
"#" ) + hexColor );
3582 int alphaHex = hexColorAlphaRx.cap( 2 ).toInt( &alphaOk, 16 );
3584 if ( parsedColor.isValid() && alphaOk )
3586 parsedColor.setAlpha( alphaHex );
3587 containsAlpha =
true;
3595 QRegExp hexColorRx2(
"^\\s*(?:[0-9a-fA-F]{3}){1,2}\\s*$" );
3596 if ( hexColorRx2.indexIn( colorStr ) != -1 )
3599 parsedColor.setNamedColor( QStringLiteral(
"#" ) + colorStr );
3600 if ( parsedColor.isValid() )
3602 containsAlpha =
false;
3609 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*$" );
3610 if ( rgbFormatRx.indexIn( colorStr ) != -1 )
3612 int r = rgbFormatRx.cap( 1 ).toInt();
3613 int g = rgbFormatRx.cap( 2 ).toInt();
3614 int b = rgbFormatRx.cap( 3 ).toInt();
3615 parsedColor.setRgb( r, g, b );
3616 if ( parsedColor.isValid() )
3618 containsAlpha =
false;
3624 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*$" );
3625 if ( rgbPercentFormatRx.indexIn( colorStr ) != -1 )
3627 int r = std::round( rgbPercentFormatRx.cap( 1 ).toDouble() * 2.55 );
3628 int g = std::round( rgbPercentFormatRx.cap( 2 ).toDouble() * 2.55 );
3629 int b = std::round( rgbPercentFormatRx.cap( 3 ).toDouble() * 2.55 );
3630 parsedColor.setRgb( r, g, b );
3631 if ( parsedColor.isValid() )
3633 containsAlpha =
false;
3639 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*$" );
3640 if ( rgbaFormatRx.indexIn( colorStr ) != -1 )
3642 int r = rgbaFormatRx.cap( 1 ).toInt();
3643 int g = rgbaFormatRx.cap( 2 ).toInt();
3644 int b = rgbaFormatRx.cap( 3 ).toInt();
3645 int a = std::round( rgbaFormatRx.cap( 4 ).toDouble() * 255.0 );
3646 parsedColor.setRgb( r, g, b, a );
3647 if ( parsedColor.isValid() )
3649 containsAlpha =
true;
3655 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*$" );
3656 if ( rgbaPercentFormatRx.indexIn( colorStr ) != -1 )
3658 int r = std::round( rgbaPercentFormatRx.cap( 1 ).toDouble() * 2.55 );
3659 int g = std::round( rgbaPercentFormatRx.cap( 2 ).toDouble() * 2.55 );
3660 int b = std::round( rgbaPercentFormatRx.cap( 3 ).toDouble() * 2.55 );
3661 int a = std::round( rgbaPercentFormatRx.cap( 4 ).toDouble() * 255.0 );
3662 parsedColor.setRgb( r, g, b, a );
3663 if ( parsedColor.isValid() )
3665 containsAlpha =
true;
3682 QImage::Format format = image->format();
3683 if ( format != QImage::Format_ARGB32_Premultiplied && format != QImage::Format_ARGB32 )
3685 QgsDebugMsg( QStringLiteral(
"no alpha channel." ) );
3690 for (
int heightIndex = 0; heightIndex < image->height(); ++heightIndex )
3692 QRgb *scanLine =
reinterpret_cast< QRgb *
>( image->scanLine( heightIndex ) );
3693 for (
int widthIndex = 0; widthIndex < image->width(); ++widthIndex )
3695 myRgb = scanLine[widthIndex];
3696 if ( format == QImage::Format_ARGB32_Premultiplied )
3697 scanLine[widthIndex] = qRgba( opacity * qRed( myRgb ), opacity * qGreen( myRgb ), opacity * qBlue( myRgb ), opacity * qAlpha( myRgb ) );
3699 scanLine[widthIndex] = qRgba( qRed( myRgb ), qGreen( myRgb ), qBlue( myRgb ), opacity * qAlpha( myRgb ) );
3707 int tab[] = { 14, 10, 8, 6, 5, 5, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2 };
3708 int alpha = ( radius < 1 ) ? 16 : ( radius > 17 ) ? 1 : tab[radius - 1];
3710 if ( image.format() != QImage::Format_ARGB32_Premultiplied
3711 && image.format() != QImage::Format_RGB32 )
3713 image = image.convertToFormat( QImage::Format_ARGB32_Premultiplied );
3716 int r1 = rect.top();
3717 int r2 = rect.bottom();
3718 int c1 = rect.left();
3719 int c2 = rect.right();
3721 int bpl = image.bytesPerLine();
3729 i1 = i2 = ( QSysInfo::ByteOrder == QSysInfo::BigEndian ? 0 : 3 );
3731 for (
int col = c1; col <= c2; col++ )
3733 p = image.scanLine( r1 ) + col * 4;
3734 for (
int i = i1; i <= i2; i++ )
3735 rgba[i] = p[i] << 4;
3738 for (
int j = r1; j < r2; j++, p += bpl )
3739 for (
int i = i1; i <= i2; i++ )
3740 p[i] = ( rgba[i] += ( ( p[i] << 4 ) - rgba[i] ) * alpha / 16 ) >> 4;
3743 for (
int row = r1; row <= r2; row++ )
3745 p = image.scanLine( row ) + c1 * 4;
3746 for (
int i = i1; i <= i2; i++ )
3747 rgba[i] = p[i] << 4;
3750 for (
int j = c1; j < c2; j++, p += 4 )
3751 for (
int i = i1; i <= i2; i++ )
3752 p[i] = ( rgba[i] += ( ( p[i] << 4 ) - rgba[i] ) * alpha / 16 ) >> 4;
3755 for (
int col = c1; col <= c2; col++ )
3757 p = image.scanLine( r2 ) + col * 4;
3758 for (
int i = i1; i <= i2; i++ )
3759 rgba[i] = p[i] << 4;
3762 for (
int j = r1; j < r2; j++, p -= bpl )
3763 for (
int i = i1; i <= i2; i++ )
3764 p[i] = ( rgba[i] += ( ( p[i] << 4 ) - rgba[i] ) * alpha / 16 ) >> 4;
3767 for (
int row = r1; row <= r2; row++ )
3769 p = image.scanLine( row ) + c2 * 4;
3770 for (
int i = i1; i <= i2; i++ )
3771 rgba[i] = p[i] << 4;
3774 for (
int j = c1; j < c2; j++, p -= 4 )
3775 for (
int i = i1; i <= i2; i++ )
3776 p[i] = ( rgba[i] += ( ( p[i] << 4 ) - rgba[i] ) * alpha / 16 ) >> 4;
3782 if ( alpha != 255 && alpha > 0 )
3786 double alphaFactor = alpha / 255.;
3787 int r = 0, g = 0, b = 0;
3788 rgb.getRgb( &r, &g, &b );
3793 rgb.setRgb( r, g, b, alpha );
3795 else if ( alpha == 0 )
3797 rgb.setRgb( 0, 0, 0, 0 );
3803 if ( order == Qt::AscendingOrder )
3817 double dx = directionPoint.x() - startPoint.x();
3818 double dy = directionPoint.y() - startPoint.y();
3819 double length = std::sqrt( dx * dx + dy * dy );
3820 double scaleFactor = distance / length;
3821 return QPointF( startPoint.x() + dx * scaleFactor, startPoint.y() + dy * scaleFactor );
3831 for (
int i = 0; i < svgPaths.size(); i++ )
3833 QDir dir( svgPaths[i] );
3834 const auto svgSubPaths = dir.entryList( QDir::Dirs | QDir::NoDotAndDotDot );
3835 for (
const QString &item : svgSubPaths )
3837 svgPaths.insert( i + 1, dir.path() +
'/' + item );
3840 const auto svgFiles = dir.entryList( QStringList(
"*.svg" ), QDir::Files );
3841 for (
const QString &item : svgFiles )
3844 list.append( dir.path() +
'/' + item );
3856 QStringList svgPaths;
3857 svgPaths.append( directory );
3859 for (
int i = 0; i < svgPaths.size(); i++ )
3861 QDir dir( svgPaths[i] );
3862 const auto svgSubPaths = dir.entryList( QDir::Dirs | QDir::NoDotAndDotDot );
3863 for (
const QString &item : svgSubPaths )
3865 svgPaths.insert( i + 1, dir.path() +
'/' + item );
3868 const auto svgFiles = dir.entryList( QStringList(
"*.svg" ), QDir::Files );
3869 for (
const QString &item : svgFiles )
3871 list.append( dir.path() +
'/' + item );
3883 if ( n.startsWith( QLatin1String(
"base64:" ) ) )
3887 if ( QFileInfo::exists( n ) )
3888 return QFileInfo( n ).canonicalFilePath();
3892 if ( name.contains( QLatin1String(
"://" ) ) )
3895 if ( url.isValid() && !url.scheme().isEmpty() )
3897 if ( url.scheme().compare( QLatin1String(
"file" ), Qt::CaseInsensitive ) == 0 )
3900 name = url.toLocalFile();
3901 if ( QFile( name ).exists() )
3903 return QFileInfo( name ).canonicalFilePath();
3917 for (
int i = 0; i < svgPaths.size(); i++ )
3919 QString svgPath = svgPaths[i];
3920 if ( svgPath.endsWith( QChar(
'/' ) ) )
3931 QString myLocalPath = svgPath + QDir::separator() + name;
3934 if ( QFile( myLocalPath ).exists() )
3937 return QFileInfo( myLocalPath ).canonicalFilePath();
3941 return pathResolver.
readPath( name );
3949 if ( p.startsWith( QLatin1String(
"base64:" ) ) )
3952 if ( !QFileInfo::exists( p ) )
3955 QString path = QFileInfo( p ).canonicalFilePath();
3959 bool isInSvgPaths =
false;
3960 for (
int i = 0; i < svgPaths.size(); i++ )
3962 QString dir = QFileInfo( svgPaths[i] ).canonicalFilePath();
3964 if ( !dir.isEmpty() && path.startsWith( dir ) )
3966 path = path.mid( dir.size() + 1 );
3967 isInSvgPaths =
true;
3982 double cx = 0, cy = 0;
3983 double area, sum = 0;
3984 for (
int i = points.count() - 1, j = 0; j < points.count(); i = j++ )
3986 const QPointF &p1 = points[i];
3987 const QPointF &p2 = points[j];
3988 area = p1.x() * p2.y() - p1.y() * p2.x();
3990 cx += ( p1.x() + p2.x() ) * area;
3991 cy += ( p1.y() + p2.y() ) * area;
3998 if ( points.count() >= 2 )
3999 return QPointF( ( points[0].x() + points[1].x() ) / 2, ( points[0].y() + points[1].y() ) / 2 );
4000 else if ( points.count() == 1 )
4008 return QPointF( cx, cy );
4015 if ( ( rings && rings->count() > 0 ) || !
pointInPolygon( points, centroid ) )
4017 unsigned int i, pointCount = points.count();
4019 for ( i = 0; i < pointCount; ++i ) polyline[i] =
QgsPointXY( points[i].x(), points[i].y() );
4025 QList<QPolygonF>::const_iterator ringIt = rings->constBegin();
4026 for ( ; ringIt != rings->constEnd(); ++ringIt )
4028 pointCount = ( *ringIt ).count();
4030 for ( i = 0; i < pointCount; ++i ) polyline[i] =
QgsPointXY( ( *ringIt )[i].x(), ( *ringIt )[i].y() );
4036 if ( !pointOnSurfaceGeom.
isNull() )
4039 centroid.
setX( point.
x() );
4040 centroid.setY( point.
y() );
4045 return QPointF( centroid.x(), centroid.y() );
4050 bool inside =
false;
4052 double x = point.x();
4053 double y = point.y();
4055 for (
int i = 0, j = points.count() - 1; i < points.count(); i++ )
4057 const QPointF &p1 = points[i];
4058 const QPointF &p2 = points[j];
4063 if ( ( p1.y() < y && p2.y() >= y ) || ( p2.y() < y && p1.y() >= y ) )
4065 if ( p1.x() + ( y - p1.y() ) / ( p2.y() - p1.y() ) * ( p2.x() - p1.x() ) <= x )
4076 if ( fieldOrExpression.isEmpty() )
4095 return static_cast<const QgsExpressionNodeColumnRef *>( n )->name();
4111 QList<double> breaks;
4114 breaks.append( maximum );
4118 int minimumCount =
static_cast< int >( classes ) / 3;
4119 double shrink = 0.75;
4120 double highBias = 1.5;
4121 double adjustBias = 0.5 + 1.5 * highBias;
4122 int divisions = classes;
4123 double h = highBias;
4126 double dx = maximum - minimum;
4136 cell = std::max( std::fabs( minimum ), std::fabs( maximum ) );
4137 if ( adjustBias >= 1.5 * h + 0.5 )
4139 U = 1 + ( 1.0 / ( 1 + h ) );
4143 U = 1 + ( 1.5 / ( 1 + adjustBias ) );
4145 small = dx < ( cell * U * std::max( 1, divisions ) * 1e-07 * 3.0 );
4152 cell = 9 + cell / 10;
4153 cell = cell * shrink;
4155 if ( minimumCount > 1 )
4157 cell = cell / minimumCount;
4163 if ( divisions > 1 )
4165 cell = cell / divisions;
4168 if ( cell < 20 * 1e-07 )
4173 double base = std::pow( 10.0, std::floor( std::log10( cell ) ) );
4175 if ( ( 2 * base ) - cell < h * ( cell - unit ) )
4178 if ( ( 5 * base ) - cell < adjustBias * ( cell - unit ) )
4181 if ( ( 10.0 * base ) - cell < h * ( cell - unit ) )
4188 int start = std::floor( minimum / unit + 1e-07 );
4189 int end = std::ceil( maximum / unit - 1e-07 );
4192 while ( start * unit > minimum + ( 1e-07 * unit ) )
4196 while ( end * unit < maximum - ( 1e-07 * unit ) )
4200 QgsDebugMsg( QStringLiteral(
"pretty classes: %1" ).arg( end ) );
4204 int k = std::floor( 0.5 + end - start );
4205 if ( k < minimumCount )
4207 k = minimumCount - k;
4211 start = start - k / 2 + k % 2;
4215 start = start - k / 2;
4216 end = end + k / 2 + k % 2;
4219 double minimumBreak = start * unit;
4221 int count = end - start;
4223 breaks.reserve( count );
4224 for (
int i = 1; i < count + 1; i++ )
4226 breaks.append( minimumBreak + i * unit );
4229 if ( breaks.isEmpty() )
4232 if ( breaks.first() < minimum )
4234 breaks[0] = minimum;
4236 if ( breaks.last() > maximum )
4238 breaks[breaks.count() - 1] = maximum;
4243 if ( minimum < 0.0 && maximum > 0.0 )
4245 QList<double> breaksMinusZero;
4246 for (
int i = 0; i < breaks.count(); i++ )
4248 breaksMinusZero.append( breaks[i] - 0.0 );
4251 for (
int i = 1; i < breaks.count(); i++ )
4253 if ( std::abs( breaksMinusZero[i] ) < std::abs( breaksMinusZero[i - 1] ) )
4256 breaks[posOfMin] = 0.0;
4265 bool roundToUnit =
false;
4268 if ( props.contains( QStringLiteral(
"uomScale" ) ) )
4271 scale = props.value( QStringLiteral(
"uomScale" ) ).toDouble( &ok );
4280 if ( props.value( QStringLiteral(
"uom" ) ) == QLatin1String(
"http://www.opengeospatial.org/se/units/metre" ) )
4305 scale = 1 / 0.28 * 25.4;
4329 double rescaled = size * scale;
4334 rescaled = std::round( rescaled );
4341 double x =
rescaleUom( point.x(), unit, props );
4342 double y =
rescaleUom( point.y(), unit, props );
4343 return QPointF( x, y );
4348 QVector<qreal> result;
4349 QVector<qreal>::const_iterator it = array.constBegin();
4350 for ( ; it != array.constEnd(); ++it )
4352 result.append(
rescaleUom( *it, unit, props ) );
4359 if ( !props.value( QStringLiteral(
"scaleMinDenom" ), QString() ).isEmpty() )
4361 QDomElement scaleMinDenomElem = doc.createElement( QStringLiteral(
"se:MinScaleDenominator" ) );
4362 scaleMinDenomElem.appendChild( doc.createTextNode(
qgsDoubleToString( props.value( QStringLiteral(
"scaleMinDenom" ) ).toDouble() ) ) );
4363 ruleElem.appendChild( scaleMinDenomElem );
4366 if ( !props.value( QStringLiteral(
"scaleMaxDenom" ), QString() ).isEmpty() )
4368 QDomElement scaleMaxDenomElem = doc.createElement( QStringLiteral(
"se:MaxScaleDenominator" ) );
4369 scaleMaxDenomElem.appendChild( doc.createTextNode(
qgsDoubleToString( props.value( QStringLiteral(
"scaleMaxDenom" ) ).toDouble() ) ) );
4370 ruleElem.appendChild( scaleMaxDenomElem );
4379 double parentScaleMinDenom = props.value( QStringLiteral(
"scaleMinDenom" ), QStringLiteral(
"0" ) ).toDouble( &ok );
4380 if ( !ok || parentScaleMinDenom <= 0 )
4381 props[ QStringLiteral(
"scaleMinDenom" )] = QString::number( mScaleMinDenom );
4383 props[ QStringLiteral(
"scaleMinDenom" )] = QString::number( std::max( parentScaleMinDenom, mScaleMinDenom ) );
4389 double parentScaleMaxDenom = props.value( QStringLiteral(
"scaleMaxDenom" ), QStringLiteral(
"0" ) ).toDouble( &ok );
4390 if ( !ok || parentScaleMaxDenom <= 0 )
4391 props[ QStringLiteral(
"scaleMaxDenom" )] = QString::number( mScaleMaxDenom );
4393 props[ QStringLiteral(
"scaleMaxDenom" )] = QString::number( std::min( parentScaleMaxDenom, mScaleMaxDenom ) );
4401 if ( uom == QLatin1String(
"http://www.opengeospatial.org/se/units/metre" ) )
4403 scale = 1.0 / 0.00028;
4405 else if ( uom == QLatin1String(
"http://www.opengeospatial.org/se/units/foot" ) )
4407 scale = 304.8 / 0.28;
4414 return size * scale;
4422 SymbolLayerVisitor(
const QSet<QgsSymbolLayerId> &layerIds )
4423 : mSymbolLayerIds( layerIds )
4436 void visitSymbol(
const QgsSymbol *symbol,
const QString &identifier, QVector<int> rootPath )
4440 QVector<int> indexPath = rootPath;
4441 indexPath.append( idx );
4443 if ( mSymbolLayerIds.contains(
QgsSymbolLayerId( mCurrentRuleKey + identifier, indexPath ) ) )
4445 mSymbolLayers.insert( sl );
4450 visitSymbol( subSymbol, identifier, indexPath );
4459 if ( symbolEntity->symbol() )
4461 visitSymbol( symbolEntity->symbol(), leaf.
identifier, {} );
4467 QString mCurrentRuleKey;
4468 const QSet<QgsSymbolLayerId> &mSymbolLayerIds;
4469 QSet<const QgsSymbolLayer *> mSymbolLayers;
4472 SymbolLayerVisitor visitor( symbolLayerIds );
4473 renderer->
accept( &visitor );
4474 return visitor.mSymbolLayers;
static void mergeScaleDependencies(double mScaleMinDenom, double mScaleMaxDenom, QgsStringMap &props)
Merges the local scale limits, if any, with the ones already in the map, if any.
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)
Class for parsing and evaluation of expressions (formerly called "search strings").
void setForceVectorOutput(bool force)
Sets whether rendering operations should use vector operations instead of any faster raster shortcuts...
bool hasParserError() const
Returns true if an error occurred when parsing the input expression.
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 QIcon symbolLayerPreviewIcon(const QgsSymbolLayer *layer, QgsUnitTypes::RenderUnit u, QSize size, const QgsMapUnitScale &scale=QgsMapUnitScale())
Draws a symbol layer preview to an icon.
A symbol entity for QgsStyle databases.
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)
Returns a list of svg files at the specified directory.
static bool needFontMarker(QDomElement &element)
QString identifier
A string identifying the style entity.
void setRenderingPass(int renderingPass)
Specifies the rendering pass in which this symbol layer should be rendered.
static QPointF toPoint(const QVariant &value, bool *ok=nullptr)
Converts a value to a point.
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 QString quotedColumnRef(QString name)
Returns a quoted column reference (in double quotes)
static QgsStringMap getSvgParameterList(QDomElement &element)
void setMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale for the symbol.
static QPicture symbolLayerPreviewPicture(const QgsSymbolLayer *layer, QgsUnitTypes::RenderUnit units, QSize size, const QgsMapUnitScale &scale=QgsMapUnitScale())
Draws a symbol layer preview to a QPicture.
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)
Abstract base class for all rendered symbols.
static QgsArrowSymbolLayer::ArrowType decodeArrowType(const QVariant &value, bool *ok=nullptr)
Decodes a value representing an arrow type.
static QString encodeSldBrushStyle(Qt::BrushStyle style)
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
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
static QgsNamedColorList colorListFromMimeData(const QMimeData *data)
Attempts to parse mime data as a list of named colors.
static QString fieldOrExpressionFromExpression(QgsExpression *expression)
Returns 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 QIcon symbolPreviewIcon(const QgsSymbol *symbol, QSize size, int padding=0)
Returns an icon preview for a color ramp.
static bool isDefaultStack(QgsPaintEffect *effect)
Tests whether a paint effect matches the default effects stack.
static bool displacementFromSldElement(QDomElement &element, QPointF &offset)
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 QPointF polygonPointOnSurface(const QPolygonF &points, QList< QPolygonF > *rings=nullptr)
Calculate a point on the surface of a QPolygonF.
static bool onlineResourceFromSldElement(QDomElement &element, QString &path, QString &format)
static QString encodeMapUnitScale(const QgsMapUnitScale &mapUnitScale)
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 the total number of symbol layers contained in the symbol.
static QDomElement saveSymbol(const QString &symbolName, const QgsSymbol *symbol, QDomDocument &doc, const QgsReadWriteContext &context)
Writes a symbol definition to XML.
static QgsColorRamp * create(const QgsStringMap &properties=QgsStringMap())
static void clearSymbolMap(QgsSymbolMap &symbols)
OperationResult addRing(const QVector< QgsPointXY > &ring)
Adds a new ring to this geometry.
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)
static QgsArrowSymbolLayer::HeadType decodeArrowHeadType(const QVariant &value, bool *ok=nullptr)
Decodes a value representing an arrow head type.
An interface for classes which can visit style entity (e.g.
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...
static QSet< const QgsSymbolLayer * > toSymbolLayerPointers(QgsFeatureRenderer *renderer, const QSet< QgsSymbolLayerId > &symbolLayerIds)
Converts a set of symbol layer id to a set of pointers to actual symbol layers carried by the feature...
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.
QString parserErrorString() const
Returns parser error.
QMap< QString, QString > QgsStringMap
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.
A marker symbol type, for rendering Point and MultiPoint geometries.
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.
A line symbol type, for rendering LineString and MultiLineString geometries.
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.
bool hasFeature() const
Returns true if the context has a feature associated with it.
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 the contents of the geometry as a multi-linestring.
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
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...
static QSizeF toSize(const QVariant &value, bool *ok=nullptr)
Converts a value to a size.
SymbolType
Type of the symbol.
static QString encodePenStyle(Qt::PenStyle style)
static QString svgSymbolPathToName(const QString &path, const QgsPathResolver &pathResolver)
Determines an SVG symbol's name from its path.
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
Specifies the rendering pass in which this symbol layer should be rendered.
virtual bool setSubSymbol(QgsSymbol *symbol)
Sets layer's subsymbol. takes ownership of the passed symbol.
bool isProjectColor() const
Returns true if the property is set to a linked project color.
static QgsNamedColorList importColorsFromGpl(QFile &file, bool &ok, QString &name)
Imports colors from a gpl GIMP palette file.
#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.
bool forceRHR() const
Returns true if polygon features drawn by the symbol will be reoriented to follow the standard right-...
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 the contents of the geometry as a polygon.
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.
static QMimeData * symbolToMimeData(const QgsSymbol *symbol)
Creates new mime data from a symbol.
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
void setActive(bool active)
Sets whether the property is currently active.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
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)
virtual QgsSymbolLayer * clone() const =0
Shall be reimplemented by subclasses to create a deep copy of the instance.
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)
ArrowType
Possible arrow types.
Contains information relating to a node (i.e.
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.
QgsStyleEntityVisitorInterface::NodeType type
Node type.
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.
QColor color() const
Returns the symbol's color.
static QgsSymbolLayer * createFillLayerFromSld(QDomElement &element)
static double estimateMaxSymbolBleed(QgsSymbol *symbol, const QgsRenderContext &context)
Returns the maximum estimated bleed for the symbol.
Abstract base class for all nodes that can appear in an expression.
static QList< QgsExpressionContextScope * > globalProjectLayerScopes(const QgsMapLayer *layer)
Creates a list of three scopes: global, layer's project and layer.
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.
A store for object properties.
static QString encodeSldFontStyle(QFont::Style style)
static QStringList listSvgFiles()
Returns a list of all available svg files.
static QgsExpression * fieldOrExpressionToExpression(const QString &fieldOrExpression)
Returns 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 the symbol layer at the specified index.
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)
void setX(double x)
Sets the x value of the point.
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.
QString expression() const
Returns the original, unmodified expression string.
QgsExpressionContext & expressionContext()
Gets the expression context.
Rule based symbology or label child rule.
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)
virtual bool accept(QgsStyleEntityVisitorInterface *visitor) const
Accepts the specified symbology visitor, causing it to visit all symbols associated with the renderer...
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.
VertexMarkerType
Editing vertex markers.
static bool convertPolygonSymbolizerToPointMarker(QDomElement &element, QgsSymbolLayerList &layerList)
static void drawVertexMarker(double x, double y, QPainter &p, QgsSymbolLayerUtils::VertexMarkerType type, int markerSize)
Draws a vertex symbol at (painter) coordinates x, y.
static QVector< qreal > decodeSldRealVector(const QString &s)
static QgsColorRamp * create(const QgsStringMap &properties=QgsStringMap())
Creates a new QgsColorRamp from a map of properties.
const QgsPathResolver & pathResolver() const
Returns path resolver for conversion between relative and absolute paths.
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.
virtual QgsStyle::StyleEntity type() const =0
Returns the type of style entity.
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)
QgsPointXY asPoint() const
Returns the contents of the geometry as a 2-dimensional point.
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 hasDataDefinedProperties() const
Returns whether the symbol utilizes any data defined properties.
Points (e.g., for font sizes)
bool enabled() const
Returns true if symbol layer is enabled and will be drawn.
SymbolType type() const
Returns the symbol's type.
Struct for storing maximum and minimum scales for measurements in map units.
static QString encodeBrushStyle(Qt::BrushStyle style)
const QgsExpressionNode * rootNode() const
Returns the root node of the expression.
static void createAnchorPointElement(QDomDocument &doc, QDomElement &element, QPointF anchor)
Creates a SE 1.1 anchor point element as a child of the specified element.
virtual QgsSymbol * clone() const =0
Returns a deep copy of this symbol.
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 QgsUnitTypes::RenderUnit decodeSldUom(const QString &str, double *scaleFactor=nullptr)
Decodes a SLD unit of measure string to a render unit.
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 QPixmap symbolPreviewPixmap(const QgsSymbol *symbol, QSize size, int padding=0, QgsRenderContext *customContext=nullptr, bool selected=false, const QgsExpressionContext *expressionContext=nullptr)
Returns a pixmap preview for a color ramp.
QMap< QString, QgsSymbol *> QgsSymbolMap
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.
static QMimeData * colorListToMimeData(const QgsNamedColorList &colorList, bool allFormats=true)
Creates mime data from a list of named colors.
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 the contents of the geometry as a polyline.
A fill symbol type, for rendering Polygon and MultiPolygon geometries.
static void fillToSld(QDomDocument &doc, QDomElement &element, Qt::BrushStyle brushStyle, const QColor &color=QColor())
void appendScopes(const QList< QgsExpressionContextScope *> &scopes)
Appends a list of scopes to the end of the context.
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 svgSymbolNameToPath(const QString &name, const QgsPathResolver &pathResolver)
Determines an SVG symbol's path from its name.
static QString encodePenCapStyle(Qt::PenCapStyle style)
const QgsStyleEntityInterface * entity
Reference to style entity being visited.
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.
void setForceRHR(bool force)
Sets whether polygon features drawn by the symbol should be reoriented to follow the standard right-h...
static QgsColorRamp * create(const QgsStringMap &properties=QgsStringMap())
Returns a new QgsLimitedRandomColorRamp color ramp created using the properties encoded in a string m...
HeadType
Possible head types.
Flat cap (in line with start/end of line)
static QgsExpression * expressionFromOgcFilter(const QDomElement &element, QgsVectorLayer *layer=nullptr)
Parse XML with OGC filter into QGIS expression.
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.
virtual QgsExpressionNode::NodeType nodeType() const =0
Gets the type of this node.
We may need stable references to symbol layers, when pointers to symbol layers is not usable (when a ...
static void multiplyImageOpacity(QImage *image, qreal opacity)
Multiplies opacity of image pixel values with a (global) transparency value.
QgsMultiPolygonXY asMultiPolygon() const
Returns the contents of the geometry as a multi-polygon.
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)
Contains information relating to the style entity currently being visited.
static QString encodeSldLineCapStyle(Qt::PenCapStyle style)
static QString encodePenJoinStyle(Qt::PenJoinStyle style)
bool isActive() const
Returns whether the property is currently active.
static QString encodeRealVector(const QVector< qreal > &v)
RenderUnit
Rendering size units.
void setExpressionContext(const QgsExpressionContext &context)
Sets the expression context.
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.
QString identifier
A string identifying the node.
virtual bool saveProperties(QDomDocument &doc, QDomElement &element) const
Saves the current state of the effect to a DOM element.