37 #include <QDomDocument> 39 #include <QDomElement> 46 #define POINTS_TO_MM 2.83464567 50 return QStringLiteral(
"%1,%2,%3,%4" ).arg( color.red() ).arg( color.green() ).arg( color.blue() ).arg( color.alpha() );
55 QStringList lst = str.split(
',' );
56 if ( lst.count() < 3 )
60 int red, green, blue, alpha;
62 green = lst[1].toInt();
63 blue = lst[2].toInt();
65 if ( lst.count() > 3 )
67 alpha = lst[3].toInt();
69 return QColor( red, green, blue, alpha );
75 result.sprintf(
"%.2g", alpha / 255.0 );
82 double alpha = str.toDouble( &ok );
83 if ( !ok || alpha > 1 )
94 case QFont::StyleNormal:
95 return QStringLiteral(
"normal" );
96 case QFont::StyleItalic:
97 return QStringLiteral(
"italic" );
98 case QFont::StyleOblique:
99 return QStringLiteral(
"oblique" );
101 return QLatin1String(
"" );
107 if ( str == QLatin1String(
"normal" ) )
return QFont::StyleNormal;
108 if ( str == QLatin1String(
"italic" ) )
return QFont::StyleItalic;
109 if ( str == QLatin1String(
"oblique" ) )
return QFont::StyleOblique;
110 return QFont::StyleNormal;
115 if ( weight == 50 )
return QStringLiteral(
"normal" );
116 if ( weight == 75 )
return QStringLiteral(
"bold" );
120 if ( weight < 0 )
return QStringLiteral(
"100" );
121 if ( weight > 99 )
return QStringLiteral(
"900" );
122 return QString::number( weight * 800 / 99 + 100 );
128 int weight = str.toInt( &ok );
130 return static_cast< int >( QFont::Normal );
134 if ( weight > 900 )
return 99;
135 if ( weight < 100 )
return 0;
136 return ( weight - 100 ) * 99 / 800;
144 return QStringLiteral(
"no" );
146 return QStringLiteral(
"solid" );
148 return QStringLiteral(
"dash" );
150 return QStringLiteral(
"dot" );
151 case Qt::DashDotLine:
152 return QStringLiteral(
"dash dot" );
153 case Qt::DashDotDotLine:
154 return QStringLiteral(
"dash dot dot" );
156 return QStringLiteral(
"???" );
162 if ( str == QLatin1String(
"no" ) )
return Qt::NoPen;
163 if ( str == QLatin1String(
"solid" ) )
return Qt::SolidLine;
164 if ( str == QLatin1String(
"dash" ) )
return Qt::DashLine;
165 if ( str == QLatin1String(
"dot" ) )
return Qt::DotLine;
166 if ( str == QLatin1String(
"dash dot" ) )
return Qt::DashDotLine;
167 if ( str == QLatin1String(
"dash dot dot" ) )
return Qt::DashDotDotLine;
168 return Qt::SolidLine;
176 return QStringLiteral(
"bevel" );
178 return QStringLiteral(
"miter" );
180 return QStringLiteral(
"round" );
182 return QStringLiteral(
"???" );
188 if ( str == QLatin1String(
"bevel" ) )
return Qt::BevelJoin;
189 if ( str == QLatin1String(
"miter" ) )
return Qt::MiterJoin;
190 if ( str == QLatin1String(
"round" ) )
return Qt::RoundJoin;
191 return Qt::BevelJoin;
199 return QStringLiteral(
"bevel" );
201 return QStringLiteral(
"mitre" );
203 return QStringLiteral(
"round" );
205 return QLatin1String(
"" );
211 if ( str == QLatin1String(
"bevel" ) )
return Qt::BevelJoin;
212 if ( str == QLatin1String(
"mitre" ) )
return Qt::MiterJoin;
213 if ( str == QLatin1String(
"round" ) )
return Qt::RoundJoin;
214 return Qt::BevelJoin;
222 return QStringLiteral(
"square" );
224 return QStringLiteral(
"flat" );
226 return QStringLiteral(
"round" );
228 return QStringLiteral(
"???" );
234 if ( str == QLatin1String(
"square" ) )
return Qt::SquareCap;
235 if ( str == QLatin1String(
"flat" ) )
return Qt::FlatCap;
236 if ( str == QLatin1String(
"round" ) )
return Qt::RoundCap;
237 return Qt::SquareCap;
245 return QStringLiteral(
"square" );
247 return QStringLiteral(
"butt" );
249 return QStringLiteral(
"round" );
251 return QLatin1String(
"" );
257 if ( str == QLatin1String(
"square" ) )
return Qt::SquareCap;
258 if ( str == QLatin1String(
"butt" ) )
return Qt::FlatCap;
259 if ( str == QLatin1String(
"round" ) )
return Qt::RoundCap;
260 return Qt::SquareCap;
267 case Qt::SolidPattern :
268 return QStringLiteral(
"solid" );
269 case Qt::HorPattern :
270 return QStringLiteral(
"horizontal" );
271 case Qt::VerPattern :
272 return QStringLiteral(
"vertical" );
273 case Qt::CrossPattern :
274 return QStringLiteral(
"cross" );
275 case Qt::BDiagPattern :
276 return QStringLiteral(
"b_diagonal" );
277 case Qt::FDiagPattern :
278 return QStringLiteral(
"f_diagonal" );
279 case Qt::DiagCrossPattern :
280 return QStringLiteral(
"diagonal_x" );
281 case Qt::Dense1Pattern :
282 return QStringLiteral(
"dense1" );
283 case Qt::Dense2Pattern :
284 return QStringLiteral(
"dense2" );
285 case Qt::Dense3Pattern :
286 return QStringLiteral(
"dense3" );
287 case Qt::Dense4Pattern :
288 return QStringLiteral(
"dense4" );
289 case Qt::Dense5Pattern :
290 return QStringLiteral(
"dense5" );
291 case Qt::Dense6Pattern :
292 return QStringLiteral(
"dense6" );
293 case Qt::Dense7Pattern :
294 return QStringLiteral(
"dense7" );
296 return QStringLiteral(
"no" );
298 return QStringLiteral(
"???" );
304 if ( str == QLatin1String(
"solid" ) )
return Qt::SolidPattern;
305 if ( str == QLatin1String(
"horizontal" ) )
return Qt::HorPattern;
306 if ( str == QLatin1String(
"vertical" ) )
return Qt::VerPattern;
307 if ( str == QLatin1String(
"cross" ) )
return Qt::CrossPattern;
308 if ( str == QLatin1String(
"b_diagonal" ) )
return Qt::BDiagPattern;
309 if ( str == QLatin1String(
"f_diagonal" ) )
return Qt::FDiagPattern;
310 if ( str == QLatin1String(
"diagonal_x" ) )
return Qt::DiagCrossPattern;
311 if ( str == QLatin1String(
"dense1" ) )
return Qt::Dense1Pattern;
312 if ( str == QLatin1String(
"dense2" ) )
return Qt::Dense2Pattern;
313 if ( str == QLatin1String(
"dense3" ) )
return Qt::Dense3Pattern;
314 if ( str == QLatin1String(
"dense4" ) )
return Qt::Dense4Pattern;
315 if ( str == QLatin1String(
"dense5" ) )
return Qt::Dense5Pattern;
316 if ( str == QLatin1String(
"dense6" ) )
return Qt::Dense6Pattern;
317 if ( str == QLatin1String(
"dense7" ) )
return Qt::Dense7Pattern;
318 if ( str == QLatin1String(
"no" ) )
return Qt::NoBrush;
319 return Qt::SolidPattern;
326 case Qt::CrossPattern:
327 return QStringLiteral(
"cross" );
328 case Qt::DiagCrossPattern:
329 return QStringLiteral(
"x" );
336 return QStringLiteral(
"horline" );
338 return QStringLiteral(
"line" );
339 case Qt::BDiagPattern:
340 return QStringLiteral(
"slash" );
341 case Qt::FDiagPattern:
342 return QStringLiteral(
"backslash" );
345 case Qt::Dense1Pattern:
346 case Qt::Dense2Pattern:
347 case Qt::Dense3Pattern:
348 case Qt::Dense4Pattern:
349 case Qt::Dense5Pattern:
350 case Qt::Dense6Pattern:
351 case Qt::Dense7Pattern:
361 if ( str == QLatin1String(
"horline" ) )
return Qt::HorPattern;
362 if ( str == QLatin1String(
"line" ) )
return Qt::VerPattern;
363 if ( str == QLatin1String(
"cross" ) )
return Qt::CrossPattern;
364 if ( str == QLatin1String(
"slash" ) )
return Qt::BDiagPattern;
365 if ( str == QLatin1String(
"backshash" ) )
return Qt::FDiagPattern;
366 if ( str == QLatin1String(
"x" ) )
return Qt::DiagCrossPattern;
368 if ( str.startsWith( QLatin1String(
"brush://" ) ) )
380 QString s = value.toString().toLower().trimmed();
381 if ( s == QLatin1String(
"single" ) )
383 else if ( s == QLatin1String(
"reversed" ) )
385 else if ( s == QLatin1String(
"double" ) )
387 else if ( value.toInt() == 1 )
389 else if ( value.toInt() == 2 )
391 else if ( value.toInt( &intOk ) == 0 && intOk )
405 QString s = value.toString().toLower().trimmed();
406 if ( s == QLatin1String(
"plain" ) )
408 else if ( s == QLatin1String(
"lefthalf" ) )
410 else if ( s == QLatin1String(
"righthalf" ) )
412 else if ( value.toInt() == 1 )
414 else if ( value.toInt() == 2 )
416 else if ( value.toInt( &intOk ) == 0 && intOk )
431 QStringList lst = str.split(
',' );
432 if ( lst.count() != 2 )
433 return QPointF( 0, 0 );
434 return QPointF( lst[0].toDouble(), lst[1].toDouble() );
444 QStringList lst =
string.split(
',' );
445 if ( lst.count() != 2 )
446 return QSizeF( 0, 0 );
447 return QSizeF( lst[0].toDouble(), lst[1].toDouble() );
464 if ( str.startsWith( QStringLiteral(
"3x:" ) ) )
467 QString chopped = str.mid( 3 );
468 lst = chopped.split(
',' );
472 lst = str.split(
',' );
474 if ( lst.count() < 2 )
477 double minScale = lst[0].toDouble();
479 minScale = minScale != 0 ? 1.0 / minScale : 0;
480 double maxScale = lst[1].toDouble();
482 maxScale = maxScale != 0 ? 1.0 / maxScale : 0;
484 if ( lst.count() < 6 )
504 *scaleFactor = 0.001;
505 return QStringLiteral(
"http://www.opengeospatial.org/se/units/metre" );
512 *scaleFactor = 1 / 0.28;
521 if ( str == QLatin1String(
"http://www.opengeospatial.org/se/units/metre" ) )
524 *scaleFactor = 1000.0;
527 else if ( str == QLatin1String(
"http://www.opengeospatial.org/se/units/foot" ) )
530 *scaleFactor = 304.8;
537 *scaleFactor = 1 / 0.00028;
543 QString vectorString;
544 QVector<qreal>::const_iterator it = v.constBegin();
545 for ( ; it != v.constEnd(); ++it )
547 if ( it != v.constBegin() )
549 vectorString.append(
';' );
551 vectorString.append( QString::number( *it ) );
558 QVector<qreal> resultVector;
560 QStringList realList = s.split(
';' );
561 QStringList::const_iterator it = realList.constBegin();
562 for ( ; it != realList.constEnd(); ++it )
564 resultVector.append( it->toDouble() );
572 QString vectorString;
573 QVector<qreal>::const_iterator it = v.constBegin();
574 for ( ; it != v.constEnd(); ++it )
576 if ( it != v.constBegin() )
578 vectorString.append(
' ' );
580 vectorString.append( QString::number( *it ) );
587 QVector<qreal> resultVector;
589 QStringList realList = s.split(
' ' );
590 QStringList::const_iterator it = realList.constBegin();
591 for ( ; it != realList.constEnd(); ++it )
593 resultVector.append( it->toDouble() );
601 QString encodedValue;
603 switch ( scaleMethod )
606 encodedValue = QStringLiteral(
"diameter" );
609 encodedValue = QStringLiteral(
"area" );
619 if ( str == QLatin1String(
"diameter" ) )
633 if ( s.compare( QLatin1String(
"Lighten" ), Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_Lighten;
634 if ( s.compare( QLatin1String(
"Screen" ), Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_Screen;
635 if ( s.compare( QLatin1String(
"Dodge" ), Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_ColorDodge;
636 if ( s.compare( QLatin1String(
"Addition" ), Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_Plus;
637 if ( s.compare( QLatin1String(
"Darken" ), Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_Darken;
638 if ( s.compare( QLatin1String(
"Multiply" ), Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_Multiply;
639 if ( s.compare( QLatin1String(
"Burn" ), Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_ColorBurn;
640 if ( s.compare( QLatin1String(
"Overlay" ), Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_Overlay;
641 if ( s.compare( QLatin1String(
"SoftLight" ), Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_SoftLight;
642 if ( s.compare( QLatin1String(
"HardLight" ), Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_HardLight;
643 if ( s.compare( QLatin1String(
"Difference" ), Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_Difference;
644 if ( s.compare( QLatin1String(
"Subtract" ), Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_Exclusion;
645 return QPainter::CompositionMode_SourceOver;
656 QPixmap pixmap( size );
657 pixmap.fill( Qt::transparent );
659 painter.begin( &pixmap );
660 painter.setRenderHint( QPainter::Antialiasing );
669 size.setWidth( size.rwidth() - ( padding * 2 ) );
670 size.setHeight( size.rheight() - ( padding * 2 ) );
671 painter.translate( padding, padding );
681 std::unique_ptr<QgsSymbol> symbol_noDD( symbol->
clone( ) );
683 for (
const auto &layer : layers )
685 layer->dataDefinedProperties().clear();
687 symbol_noDD->drawPreviewIcon( &painter, size, customContext );
705 maxBleed = layerMaxBleed > maxBleed ? layerMaxBleed : maxBleed;
715 painter.begin( &picture );
716 painter.setRenderHint( QPainter::Antialiasing );
727 QPixmap pixmap( size );
728 pixmap.fill( Qt::transparent );
730 painter.begin( &pixmap );
731 painter.setRenderHint( QPainter::Antialiasing );
736 return QIcon( pixmap );
746 QPixmap pixmap( size );
747 pixmap.fill( Qt::transparent );
750 painter.begin( &pixmap );
753 drawStippledBackground( &painter, QRect( padding, padding, size.width() - padding * 2, size.height() - padding * 2 ) );
757 for (
int i = 0; i < size.width(); i++ )
759 QPen pen( ramp->
color( static_cast< double >( i ) / size.width() ) );
760 painter.setPen( pen );
761 painter.drawLine( i, 0 + padding, i, size.height() - 1 - padding );
770 uchar pixDataRGB[] = { 255, 255, 255, 255,
775 QImage img( pixDataRGB, 2, 2, 8, QImage::Format_ARGB32 );
777 int width = ( rect.width() < rect.height() ) ?
778 rect.width() / 2.5 : rect.height() / 2.5;
779 QPixmap pix = QPixmap::fromImage( img.scaled( width, width ) );
782 brush.setTexture( pix );
783 painter->fillRect( rect, brush );
791 static QPolygonF makeOffsetGeometry(
const QgsPolylineXY &polyline )
793 int i, pointCount = polyline.count();
795 QPolygonF resultLine;
796 resultLine.resize( pointCount );
800 for ( i = 0; i < pointCount; ++i, tempPtr++ )
801 resultLine[i] = QPointF( tempPtr->
x(), tempPtr->
y() );
805 static QList<QPolygonF> makeOffsetGeometry(
const QgsPolygonXY &polygon )
807 QList<QPolygonF> resultGeom;
808 resultGeom.reserve( polygon.size() );
809 for (
int ring = 0; ring < polygon.size(); ++ring )
810 resultGeom.append( makeOffsetGeometry( polygon[ ring ] ) );
816 QList<QPolygonF> resultLine;
818 if ( polyline.count() < 2 )
820 resultLine.append( polyline );
824 unsigned int i, pointCount = polyline.count();
827 QPointF *tempPtr = polyline.data();
828 for ( i = 0; i < pointCount; ++i, tempPtr++ )
829 tempPolyline[i] =
QgsPointXY( tempPtr->rx(), tempPtr->ry() );
832 if ( !tempGeometry.
isNull() )
834 int quadSegments = 0;
835 double miterLimit = 2.0;
843 if ( !offsetGeom.
isNull() )
845 tempGeometry = offsetGeom;
852 if ( dist < 0 ) std::reverse( line.begin(), line.end() );
853 resultLine.append( makeOffsetGeometry( line ) );
858 resultLine.append( makeOffsetGeometry( tempGeometry.
asPolygon() ) );
864 resultLine.reserve( tempMPolyline.count() );
865 for (
int part = 0; part < tempMPolyline.count(); ++part )
867 resultLine.append( makeOffsetGeometry( tempMPolyline[ part ] ) );
874 resultLine.reserve( tempMPolygon.count() );
875 for (
int part = 0; part < tempMPolygon.count(); ++part )
877 resultLine.append( makeOffsetGeometry( tempMPolygon[ part ] ) );
885 resultLine.append( polyline );
895 QDomNode layerNode = element.firstChild();
897 while ( !layerNode.isNull() )
899 QDomElement e = layerNode.toElement();
902 if ( e.tagName() != QLatin1String(
"layer" ) )
913 QDomElement s = e.firstChildElement( QStringLiteral(
"symbol" ) );
920 QgsDebugMsg(
"symbol layer refused subsymbol: " + s.attribute(
"name" ) );
923 layers.append( layer );
927 layerNode = layerNode.nextSibling();
930 if ( layers.isEmpty() )
936 QString symbolType = element.attribute( QStringLiteral(
"type" ) );
939 if ( symbolType == QLatin1String(
"line" ) )
941 else if ( symbolType == QLatin1String(
"fill" ) )
943 else if ( symbolType == QLatin1String(
"marker" ) )
947 QgsDebugMsg(
"unknown symbol type " + symbolType );
951 if ( element.hasAttribute( QStringLiteral(
"outputUnit" ) ) )
955 if ( element.hasAttribute( ( QStringLiteral(
"mapUnitScale" ) ) ) )
958 double oldMin = element.attribute( QStringLiteral(
"mapUnitMinScale" ), QStringLiteral(
"0.0" ) ).toDouble();
959 mapUnitScale.
minScale = oldMin != 0 ? 1.0 / oldMin : 0;
960 double oldMax = element.attribute( QStringLiteral(
"mapUnitMaxScale" ), QStringLiteral(
"0.0" ) ).toDouble();
961 mapUnitScale.
maxScale = oldMax != 0 ? 1.0 / oldMax : 0;
964 symbol->
setOpacity( element.attribute( QStringLiteral(
"alpha" ), QStringLiteral(
"1.0" ) ).toDouble() );
965 symbol->
setClipFeaturesToExtent( element.attribute( QStringLiteral(
"clip_to_extent" ), QStringLiteral(
"1" ) ).toInt() );
972 QString layerClass = element.attribute( QStringLiteral(
"class" ) );
973 bool locked = element.attribute( QStringLiteral(
"locked" ) ).toInt();
974 bool enabled = element.attribute( QStringLiteral(
"enabled" ), QStringLiteral(
"1" ) ).toInt();
975 int pass = element.attribute( QStringLiteral(
"pass" ) ).toInt();
992 QDomElement effectElem = element.firstChildElement( QStringLiteral(
"effect" ) );
993 if ( !effectElem.isNull() )
999 QDomElement ddProps = element.firstChildElement( QStringLiteral(
"data_defined_properties" ) );
1000 if ( !ddProps.isNull() )
1019 return QStringLiteral(
"line" );
1021 return QStringLiteral(
"marker" );
1023 return QStringLiteral(
"fill" );
1025 return QLatin1String(
"" );
1032 QDomElement symEl = doc.createElement( QStringLiteral(
"symbol" ) );
1033 symEl.setAttribute( QStringLiteral(
"type" ), _nameForSymbolType( symbol->
type() ) );
1034 symEl.setAttribute( QStringLiteral(
"name" ), name );
1035 symEl.setAttribute( QStringLiteral(
"alpha" ), QString::number( symbol->
opacity() ) );
1036 symEl.setAttribute( QStringLiteral(
"clip_to_extent" ), symbol->
clipFeaturesToExtent() ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
1043 QDomElement layerEl = doc.createElement( QStringLiteral(
"layer" ) );
1044 layerEl.setAttribute( QStringLiteral(
"class" ), layer->
layerType() );
1045 layerEl.setAttribute( QStringLiteral(
"enabled" ), layer->
enabled() );
1046 layerEl.setAttribute( QStringLiteral(
"locked" ), layer->
isLocked() );
1047 layerEl.setAttribute( QStringLiteral(
"pass" ), layer->
renderingPass() );
1058 QDomElement ddProps = doc.createElement( QStringLiteral(
"data_defined_properties" ) );
1060 layerEl.appendChild( ddProps );
1064 QString subname = QStringLiteral(
"@%1@%2" ).arg( name ).arg( i );
1066 layerEl.appendChild( subEl );
1068 symEl.appendChild( layerEl );
1076 QDomDocument doc( QStringLiteral(
"qgis-symbol-definition" ) );
1079 QTextStream stream( &props );
1080 symbolElem.save( stream, -1 );
1090 if ( element.isNull() )
1095 QString symbolizerName = element.localName();
1097 if ( symbolizerName == QLatin1String(
"PointSymbolizer" ) )
1100 QDomElement graphicElem = element.firstChildElement( QStringLiteral(
"Graphic" ) );
1101 if ( graphicElem.isNull() )
1103 QgsDebugMsg(
"Graphic element not found in PointSymbolizer" );
1139 if ( symbolizerName == QLatin1String(
"LineSymbolizer" ) )
1142 QDomElement strokeElem = element.firstChildElement( QStringLiteral(
"Stroke" ) );
1143 if ( strokeElem.isNull() )
1145 QgsDebugMsg(
"Stroke element not found in LineSymbolizer" );
1175 if ( symbolizerName == QLatin1String(
"PolygonSymbolizer" ) )
1178 QDomElement fillElem = element.firstChildElement( QStringLiteral(
"Fill" ) );
1179 QDomElement strokeElem = element.firstChildElement( QStringLiteral(
"Stroke" ) );
1180 if ( fillElem.isNull() && strokeElem.isNull() )
1182 QgsDebugMsg(
"neither Fill nor Stroke element not found in PolygonSymbolizer" );
1200 if ( l->
layerType() == QLatin1String(
"SimpleFill" ) || l->
layerType() == QLatin1String(
"SVGFill" ) )
1236 QDomElement fillElem = element.firstChildElement( QStringLiteral(
"Fill" ) );
1237 if ( fillElem.isNull() )
1259 QDomElement strokeElem = element.firstChildElement( QStringLiteral(
"Stroke" ) );
1260 if ( strokeElem.isNull() )
1278 QDomElement graphicElem = element.firstChildElement( QStringLiteral(
"Graphic" ) );
1279 if ( graphicElem.isNull() )
1301 QDomElement graphicElem = element.firstChildElement( QStringLiteral(
"Graphic" ) );
1302 if ( graphicElem.isNull() )
1305 QDomElement externalGraphicElem = graphicElem.firstChildElement( QStringLiteral(
"ExternalGraphic" ) );
1306 if ( externalGraphicElem.isNull() )
1310 QDomElement formatElem = externalGraphicElem.firstChildElement( QStringLiteral(
"Format" ) );
1311 if ( formatElem.isNull() )
1314 QString format = formatElem.firstChild().nodeValue();
1315 if ( format != QLatin1String(
"image/svg+xml" ) )
1317 QgsDebugMsg(
"unsupported External Graphic format found: " + format );
1322 QDomElement onlineResourceElem = externalGraphicElem.firstChildElement( QStringLiteral(
"OnlineResource" ) );
1323 QDomElement inlineContentElem = externalGraphicElem.firstChildElement( QStringLiteral(
"InlineContent" ) );
1324 if ( !onlineResourceElem.isNull() )
1329 else if ( !inlineContentElem.isNull() )
1342 QDomElement graphicElem = element.firstChildElement( QStringLiteral(
"Graphic" ) );
1343 if ( graphicElem.isNull() )
1346 QDomElement markElem = graphicElem.firstChildElement( QStringLiteral(
"Mark" ) );
1347 if ( markElem.isNull() )
1350 QDomElement wellKnownNameElem = markElem.firstChildElement( QStringLiteral(
"WellKnownName" ) );
1351 return !wellKnownNameElem.isNull();
1357 QDomElement graphicElem = element.firstChildElement( QStringLiteral(
"Graphic" ) );
1358 if ( graphicElem.isNull() )
1361 QDomElement markElem = graphicElem.firstChildElement( QStringLiteral(
"Mark" ) );
1362 if ( markElem.isNull() )
1366 QDomElement formatElem = markElem.firstChildElement( QStringLiteral(
"Format" ) );
1367 if ( formatElem.isNull() )
1370 QString format = formatElem.firstChild().nodeValue();
1371 if ( format != QLatin1String(
"ttf" ) )
1373 QgsDebugMsg(
"unsupported Graphic Mark format found: " + format );
1378 QDomElement onlineResourceElem = markElem.firstChildElement( QStringLiteral(
"OnlineResource" ) );
1379 QDomElement inlineContentElem = markElem.firstChildElement( QStringLiteral(
"InlineContent" ) );
1380 if ( !onlineResourceElem.isNull() )
1383 QDomElement markIndexElem = markElem.firstChildElement( QStringLiteral(
"MarkIndex" ) );
1384 if ( !markIndexElem.isNull() )
1387 else if ( !inlineContentElem.isNull() )
1402 QDomElement graphicElem = element.firstChildElement( QStringLiteral(
"Graphic" ) );
1403 if ( graphicElem.isNull() )
1407 for ( QgsStringMap::iterator it = vendorOptions.begin(); it != vendorOptions.end(); ++it )
1409 if ( it.key() == QLatin1String(
"widthHeightFactor" ) )
1420 QDomElement strokeElem = element.firstChildElement( QStringLiteral(
"Stroke" ) );
1421 if ( strokeElem.isNull() )
1424 QDomElement graphicStrokeElem = strokeElem.firstChildElement( QStringLiteral(
"GraphicStroke" ) );
1425 if ( graphicStrokeElem.isNull() )
1433 QDomElement fillElem = element.firstChildElement( QStringLiteral(
"Fill" ) );
1434 if ( fillElem.isNull() )
1437 QDomElement graphicFillElem = fillElem.firstChildElement( QStringLiteral(
"GraphicFill" ) );
1438 if ( graphicFillElem.isNull() )
1441 QDomElement graphicElem = graphicFillElem.firstChildElement( QStringLiteral(
"Graphic" ) );
1442 if ( graphicElem.isNull() )
1448 QColor fillColor, strokeColor;
1449 double size, strokeWidth;
1450 Qt::PenStyle strokeStyle;
1451 if ( !
wellKnownMarkerFromSld( graphicElem, name, fillColor, strokeColor, strokeStyle, strokeWidth, size ) )
1454 if ( name != QLatin1String(
"horline" ) )
1462 double angle = angleFunc.toDouble( &ok );
1468 Q_UNUSED( element );
1474 QDomElement fillElem = element.firstChildElement( QStringLiteral(
"Fill" ) );
1475 if ( fillElem.isNull() )
1478 QDomElement graphicFillElem = fillElem.firstChildElement( QStringLiteral(
"GraphicFill" ) );
1479 if ( graphicFillElem.isNull() )
1499 QDomElement fillElem = element.firstChildElement( QStringLiteral(
"Fill" ) );
1500 QDomElement strokeElem = element.firstChildElement( QStringLiteral(
"Stroke" ) );
1504 bool validFill =
false, validStroke =
false;
1509 Qt::BrushStyle fillStyle;
1511 if (
fillFromSld( fillElem, fillStyle, fillColor ) )
1517 Qt::PenStyle strokeStyle;
1518 double strokeWidth = 1.0, dashOffset = 0.0;
1519 QVector<qreal> customDashPattern;
1521 if (
lineFromSld( strokeElem, strokeStyle, strokeColor, strokeWidth,
1522 nullptr,
nullptr, &customDashPattern, &dashOffset ) )
1525 if ( validFill || validStroke )
1528 map[QStringLiteral(
"name" )] = QStringLiteral(
"square" );
1529 map[QStringLiteral(
"color" )] =
encodeColor( validFill ? fillColor : Qt::transparent );
1530 map[QStringLiteral(
"color_border" )] =
encodeColor( validStroke ? strokeColor : Qt::transparent );
1531 map[QStringLiteral(
"size" )] = QString::number( 6 );
1532 map[QStringLiteral(
"angle" )] = QString::number( 0 );
1533 map[QStringLiteral(
"offset" )] =
encodePoint( QPointF( 0, 0 ) );
1540 bool validFill =
false, validStroke =
false;
1543 QString name, format;
1545 QColor fillColor, strokeColor;
1546 double strokeWidth = 1.0, size = 0.0,
angle = 0.0;
1550 QDomElement graphicFillElem = fillElem.firstChildElement( QStringLiteral(
"GraphicFill" ) );
1551 if ( !graphicFillElem.isNull() )
1554 QDomElement graphicElem = graphicFillElem.firstChildElement( QStringLiteral(
"Graphic" ) );
1555 if ( !graphicElem.isNull() )
1561 QDomElement graphicChildElem = graphicElem.firstChildElement();
1562 while ( !graphicChildElem.isNull() )
1564 if ( graphicChildElem.localName() == QLatin1String(
"Mark" ) )
1567 QDomElement wellKnownNameElem = graphicChildElem.firstChildElement( QStringLiteral(
"WellKnownName" ) );
1568 if ( !wellKnownNameElem.isNull() )
1570 name = wellKnownNameElem.firstChild().nodeValue();
1576 if ( graphicChildElem.localName() == QLatin1String(
"ExternalGraphic" ) || graphicChildElem.localName() == QLatin1String(
"Mark" ) )
1579 QDomElement formatElem = graphicChildElem.firstChildElement( QStringLiteral(
"Format" ) );
1580 if ( formatElem.isNull() )
1583 format = formatElem.firstChild().nodeValue();
1587 if ( graphicChildElem.localName() == QLatin1String(
"ExternalGraphic" ) && format != QLatin1String(
"image/svg+xml" ) )
1592 if ( graphicChildElem.localName() == QLatin1String(
"Mark" ) && format != QLatin1String(
"ttf" ) )
1596 QDomElement onlineResourceElem = graphicChildElem.firstChildElement( QStringLiteral(
"OnlineResource" ) );
1597 QDomElement inlineContentElem = graphicChildElem.firstChildElement( QStringLiteral(
"InlineContent" ) );
1599 if ( !onlineResourceElem.isNull() )
1601 name = onlineResourceElem.attributeNS( QStringLiteral(
"http://www.w3.org/1999/xlink" ), QStringLiteral(
"href" ) );
1603 if ( graphicChildElem.localName() == QLatin1String(
"Mark" ) && format == QLatin1String(
"ttf" ) )
1606 if ( name.startsWith( QLatin1String(
"ttf://" ) ) )
1607 name = name.mid( 6 );
1610 QDomElement markIndexElem = graphicChildElem.firstChildElement( QStringLiteral(
"MarkIndex" ) );
1611 if ( markIndexElem.isNull() )
1615 int v = markIndexElem.firstChild().nodeValue().toInt( &ok );
1626 else if ( !inlineContentElem.isNull() )
1636 if ( graphicChildElem.localName() == QLatin1String(
"Mark" ) )
1638 name = QStringLiteral(
"square" );
1645 if ( found && graphicChildElem.localName() == QLatin1String(
"Mark" ) )
1652 Qt::BrushStyle markFillStyle;
1654 QDomElement markFillElem = graphicChildElem.firstChildElement( QStringLiteral(
"Fill" ) );
1655 if (
fillFromSld( markFillElem, markFillStyle, fillColor ) )
1660 Qt::PenStyle strokeStyle;
1661 double strokeWidth = 1.0, dashOffset = 0.0;
1662 QVector<qreal> customDashPattern;
1664 QDomElement markStrokeElem = graphicChildElem.firstChildElement( QStringLiteral(
"Stroke" ) );
1665 if (
lineFromSld( markStrokeElem, strokeStyle, strokeColor, strokeWidth,
1666 nullptr,
nullptr, &customDashPattern, &dashOffset ) )
1673 QDomElement opacityElem = graphicElem.firstChildElement( QStringLiteral(
"Opacity" ) );
1674 if ( !opacityElem.isNull() )
1675 fillColor.setAlpha(
decodeSldAlpha( opacityElem.firstChild().nodeValue() ) );
1677 QDomElement sizeElem = graphicElem.firstChildElement( QStringLiteral(
"Size" ) );
1678 if ( !sizeElem.isNull() )
1681 double v = sizeElem.firstChild().nodeValue().toDouble( &ok );
1690 double v = angleFunc.toDouble( &ok );
1700 if ( validFill || validStroke )
1702 if ( format == QLatin1String(
"image/svg+xml" ) )
1705 map[QStringLiteral(
"name" )] = name;
1706 map[QStringLiteral(
"fill" )] = fillColor.name();
1707 map[QStringLiteral(
"outline" )] = strokeColor.name();
1708 map[QStringLiteral(
"outline-width" )] = QString::number( strokeWidth );
1710 map[QStringLiteral(
"size" )] = QString::number( size );
1712 map[QStringLiteral(
"angle" )] = QString::number(
angle );
1713 if ( !offset.isNull() )
1714 map[QStringLiteral(
"offset" )] =
encodePoint( offset );
1717 else if ( format == QLatin1String(
"ttf" ) )
1720 map[QStringLiteral(
"font" )] = name;
1721 map[QStringLiteral(
"chr" )] = markIndex;
1722 map[QStringLiteral(
"color" )] =
encodeColor( validFill ? fillColor : Qt::transparent );
1724 map[QStringLiteral(
"size" )] = QString::number( size );
1726 map[QStringLiteral(
"angle" )] = QString::number(
angle );
1727 if ( !offset.isNull() )
1728 map[QStringLiteral(
"offset" )] =
encodePoint( offset );
1734 if ( layers.isEmpty() )
1737 layerList << layers;
1744 QString patternName;
1745 switch ( brushStyle )
1750 case Qt::SolidPattern:
1751 if ( color.isValid() )
1754 if ( color.alpha() < 255 )
1759 case Qt::CrossPattern:
1760 case Qt::DiagCrossPattern:
1761 case Qt::HorPattern:
1762 case Qt::VerPattern:
1763 case Qt::BDiagPattern:
1764 case Qt::FDiagPattern:
1765 case Qt::Dense1Pattern:
1766 case Qt::Dense2Pattern:
1767 case Qt::Dense3Pattern:
1768 case Qt::Dense4Pattern:
1769 case Qt::Dense5Pattern:
1770 case Qt::Dense6Pattern:
1771 case Qt::Dense7Pattern:
1776 element.appendChild( doc.createComment( QStringLiteral(
"Qt::BrushStyle '%1'' not supported yet" ).arg( brushStyle ) ) );
1780 QDomElement graphicFillElem = doc.createElement( QStringLiteral(
"se:GraphicFill" ) );
1781 element.appendChild( graphicFillElem );
1783 QDomElement graphicElem = doc.createElement( QStringLiteral(
"se:Graphic" ) );
1784 graphicFillElem.appendChild( graphicElem );
1786 QColor fillColor = patternName.startsWith( QLatin1String(
"brush://" ) ) ? color : QColor();
1787 QColor strokeColor = !patternName.startsWith( QLatin1String(
"brush://" ) ) ? color : QColor();
1790 wellKnownMarkerToSld( doc, graphicElem, patternName, fillColor, strokeColor, Qt::SolidLine, -1, -1 );
1797 brushStyle = Qt::SolidPattern;
1798 color = QColor( 128, 128, 128 );
1800 if ( element.isNull() )
1802 brushStyle = Qt::NoBrush;
1807 QDomElement graphicFillElem = element.firstChildElement( QStringLiteral(
"GraphicFill" ) );
1809 if ( graphicFillElem.isNull() )
1812 for ( QgsStringMap::iterator it = svgParams.begin(); it != svgParams.end(); ++it )
1814 QgsDebugMsg( QString(
"found SvgParameter %1: %2" ).arg( it.key(), it.value() ) );
1816 if ( it.key() == QLatin1String(
"fill" ) )
1817 color = QColor( it.value() );
1818 else if ( it.key() == QLatin1String(
"fill-opacity" ) )
1824 QDomElement graphicElem = graphicFillElem.firstChildElement( QStringLiteral(
"Graphic" ) );
1825 if ( graphicElem.isNull() )
1828 QString patternName = QStringLiteral(
"square" );
1829 QColor fillColor, strokeColor;
1830 double strokeWidth, size;
1831 Qt::PenStyle strokeStyle;
1832 if ( !
wellKnownMarkerFromSld( graphicElem, patternName, fillColor, strokeColor, strokeStyle, strokeWidth, size ) )
1836 if ( brushStyle == Qt::NoBrush )
1839 QColor
c = patternName.startsWith( QLatin1String(
"brush://" ) ) ? fillColor : strokeColor;
1848 Qt::PenStyle penStyle,
const QColor &color,
double width,
1849 const Qt::PenJoinStyle *penJoinStyle,
const Qt::PenCapStyle *penCapStyle,
1850 const QVector<qreal> *customDashPattern,
double dashOffset )
1852 QVector<qreal> dashPattern;
1853 const QVector<qreal> *pattern = &dashPattern;
1855 if ( penStyle == Qt::CustomDashLine && !customDashPattern )
1857 element.appendChild( doc.createComment( QStringLiteral(
"WARNING: Custom dash pattern required but not provided. Using default dash pattern." ) ) );
1858 penStyle = Qt::DashLine;
1870 dashPattern.push_back( 4.0 );
1871 dashPattern.push_back( 2.0 );
1874 dashPattern.push_back( 1.0 );
1875 dashPattern.push_back( 2.0 );
1877 case Qt::DashDotLine:
1878 dashPattern.push_back( 4.0 );
1879 dashPattern.push_back( 2.0 );
1880 dashPattern.push_back( 1.0 );
1881 dashPattern.push_back( 2.0 );
1883 case Qt::DashDotDotLine:
1884 dashPattern.push_back( 4.0 );
1885 dashPattern.push_back( 2.0 );
1886 dashPattern.push_back( 1.0 );
1887 dashPattern.push_back( 2.0 );
1888 dashPattern.push_back( 1.0 );
1889 dashPattern.push_back( 2.0 );
1892 case Qt::CustomDashLine:
1893 Q_ASSERT( customDashPattern );
1894 pattern = customDashPattern;
1898 element.appendChild( doc.createComment( QStringLiteral(
"Qt::BrushStyle '%1'' not supported yet" ).arg( penStyle ) ) );
1902 if ( color.isValid() )
1905 if ( color.alpha() < 255 )
1912 else if ( width == 0 )
1922 if ( !pattern->isEmpty() )
1932 Qt::PenStyle &penStyle, QColor &color,
double &width,
1933 Qt::PenJoinStyle *penJoinStyle, Qt::PenCapStyle *penCapStyle,
1934 QVector<qreal> *customDashPattern,
double *dashOffset )
1938 penStyle = Qt::SolidLine;
1939 color = QColor( 0, 0, 0 );
1942 *penJoinStyle = Qt::BevelJoin;
1944 *penCapStyle = Qt::SquareCap;
1945 if ( customDashPattern )
1946 customDashPattern->clear();
1950 if ( element.isNull() )
1952 penStyle = Qt::NoPen;
1958 for ( QgsStringMap::iterator it = svgParams.begin(); it != svgParams.end(); ++it )
1960 QgsDebugMsg( QString(
"found SvgParameter %1: %2" ).arg( it.key(), it.value() ) );
1962 if ( it.key() == QLatin1String(
"stroke" ) )
1964 color = QColor( it.value() );
1966 else if ( it.key() == QLatin1String(
"stroke-opacity" ) )
1970 else if ( it.key() == QLatin1String(
"stroke-width" ) )
1973 double w = it.value().toDouble( &ok );
1977 else if ( it.key() == QLatin1String(
"stroke-linejoin" ) && penJoinStyle )
1981 else if ( it.key() == QLatin1String(
"stroke-linecap" ) && penCapStyle )
1985 else if ( it.key() == QLatin1String(
"stroke-dasharray" ) )
1988 if ( !dashPattern.isEmpty() )
1992 bool dashPatternFound =
false;
1994 if ( dashPattern.count() == 2 )
1996 if ( dashPattern.at( 0 ) == 4.0 &&
1997 dashPattern.at( 1 ) == 2.0 )
1999 penStyle = Qt::DashLine;
2000 dashPatternFound =
true;
2002 else if ( dashPattern.at( 0 ) == 1.0 &&
2003 dashPattern.at( 1 ) == 2.0 )
2005 penStyle = Qt::DotLine;
2006 dashPatternFound =
true;
2009 else if ( dashPattern.count() == 4 )
2011 if ( dashPattern.at( 0 ) == 4.0 &&
2012 dashPattern.at( 1 ) == 2.0 &&
2013 dashPattern.at( 2 ) == 1.0 &&
2014 dashPattern.at( 3 ) == 2.0 )
2016 penStyle = Qt::DashDotLine;
2017 dashPatternFound =
true;
2020 else if ( dashPattern.count() == 6 )
2022 if ( dashPattern.at( 0 ) == 4.0 &&
2023 dashPattern.at( 1 ) == 2.0 &&
2024 dashPattern.at( 2 ) == 1.0 &&
2025 dashPattern.at( 3 ) == 2.0 &&
2026 dashPattern.at( 4 ) == 1.0 &&
2027 dashPattern.at( 5 ) == 2.0 )
2029 penStyle = Qt::DashDotDotLine;
2030 dashPatternFound =
true;
2035 if ( !dashPatternFound )
2037 if ( customDashPattern )
2039 penStyle = Qt::CustomDashLine;
2040 *customDashPattern = dashPattern;
2044 QgsDebugMsg(
"custom dash pattern required but not provided. Using default dash pattern." );
2045 penStyle = Qt::DashLine;
2050 else if ( it.key() == QLatin1String(
"stroke-dashoffset" ) && dashOffset )
2053 double d = it.value().toDouble( &ok );
2063 const QString &path,
const QString &mime,
2064 const QColor &color,
double size )
2066 QDomElement externalGraphicElem = doc.createElement( QStringLiteral(
"se:ExternalGraphic" ) );
2067 element.appendChild( externalGraphicElem );
2076 QDomElement sizeElem = doc.createElement( QStringLiteral(
"se:Size" ) );
2078 element.appendChild( sizeElem );
2083 const QString &path,
const QColor &fillColor,
double size,
const QColor &strokeColor,
double strokeWidth )
2090 graphicElem.appendChild( doc.createComment( QStringLiteral(
"Parametric SVG" ) ) );
2094 graphicElem.appendChild( doc.createComment( QStringLiteral(
"Plain SVG fallback, no parameters" ) ) );
2097 graphicElem.appendChild( doc.createComment( QStringLiteral(
"Well known marker fallback" ) ) );
2103 QDomElement sizeElem = doc.createElement( QStringLiteral(
"se:Size" ) );
2105 graphicElem.appendChild( sizeElem );
2113 if ( fillColor.isValid() )
2115 url.addQueryItem( QStringLiteral(
"fill" ), fillColor.name() );
2116 url.addQueryItem( QStringLiteral(
"fill-opacity" ),
encodeSldAlpha( fillColor.alpha() ) );
2120 url.addQueryItem( QStringLiteral(
"fill" ), QStringLiteral(
"#000000" ) );
2121 url.addQueryItem( QStringLiteral(
"fill-opacity" ), QStringLiteral(
"1" ) );
2123 if ( strokeColor.isValid() )
2125 url.addQueryItem( QStringLiteral(
"outline" ), strokeColor.name() );
2126 url.addQueryItem( QStringLiteral(
"outline-opacity" ),
encodeSldAlpha( strokeColor.alpha() ) );
2130 url.addQueryItem( QStringLiteral(
"outline" ), QStringLiteral(
"#000000" ) );
2131 url.addQueryItem( QStringLiteral(
"outline-opacity" ), QStringLiteral(
"1" ) );
2133 url.addQueryItem( QStringLiteral(
"outline-width" ), QString::number( strokeWidth ) );
2134 QString params = url.encodedQuery();
2135 if ( params.isEmpty() )
2141 return basePath +
"?" + params;
2146 QString &path, QString &mime,
2147 QColor &color,
double &size )
2152 QDomElement externalGraphicElem = element.firstChildElement( QStringLiteral(
"ExternalGraphic" ) );
2153 if ( externalGraphicElem.isNull() )
2158 QDomElement sizeElem = element.firstChildElement( QStringLiteral(
"Size" ) );
2159 if ( !sizeElem.isNull() )
2162 double s = sizeElem.firstChild().nodeValue().toDouble( &ok );
2171 const QString &path,
const QString &format,
int *markIndex,
2172 const QColor &color,
double size )
2174 QDomElement markElem = doc.createElement( QStringLiteral(
"se:Mark" ) );
2175 element.appendChild( markElem );
2181 QDomElement markIndexElem = doc.createElement( QStringLiteral(
"se:MarkIndex" ) );
2182 markIndexElem.appendChild( doc.createTextNode( QString::number( *markIndex ) ) );
2183 markElem.appendChild( markIndexElem );
2187 QDomElement fillElem = doc.createElement( QStringLiteral(
"se:Fill" ) );
2188 fillToSld( doc, fillElem, Qt::SolidPattern, color );
2189 markElem.appendChild( fillElem );
2194 QDomElement sizeElem = doc.createElement( QStringLiteral(
"se:Size" ) );
2196 element.appendChild( sizeElem );
2201 QString &path, QString &format,
int &markIndex,
2202 QColor &color,
double &size )
2210 QDomElement markElem = element.firstChildElement( QStringLiteral(
"Mark" ) );
2211 if ( markElem.isNull() )
2216 QDomElement markIndexElem = markElem.firstChildElement( QStringLiteral(
"MarkIndex" ) );
2217 if ( !markIndexElem.isNull() )
2220 int i = markIndexElem.firstChild().nodeValue().toInt( &ok );
2226 QDomElement fillElem = markElem.firstChildElement( QStringLiteral(
"Fill" ) );
2227 Qt::BrushStyle b = Qt::SolidPattern;
2232 QDomElement sizeElem = element.firstChildElement( QStringLiteral(
"Size" ) );
2233 if ( !sizeElem.isNull() )
2236 double s = sizeElem.firstChild().nodeValue().toDouble( &ok );
2245 const QString &name,
const QColor &color,
const QColor &strokeColor, Qt::PenStyle strokeStyle,
2246 double strokeWidth,
double size )
2248 QDomElement markElem = doc.createElement( QStringLiteral(
"se:Mark" ) );
2249 element.appendChild( markElem );
2251 QDomElement wellKnownNameElem = doc.createElement( QStringLiteral(
"se:WellKnownName" ) );
2252 wellKnownNameElem.appendChild( doc.createTextNode( name ) );
2253 markElem.appendChild( wellKnownNameElem );
2256 if ( color.isValid() )
2258 QDomElement fillElem = doc.createElement( QStringLiteral(
"se:Fill" ) );
2259 fillToSld( doc, fillElem, Qt::SolidPattern, color );
2260 markElem.appendChild( fillElem );
2264 if ( strokeColor.isValid() )
2266 QDomElement strokeElem = doc.createElement( QStringLiteral(
"se:Stroke" ) );
2267 lineToSld( doc, strokeElem, strokeStyle, strokeColor, strokeWidth );
2268 markElem.appendChild( strokeElem );
2274 QDomElement sizeElem = doc.createElement( QStringLiteral(
"se:Size" ) );
2276 element.appendChild( sizeElem );
2281 QString &name, QColor &color, QColor &strokeColor, Qt::PenStyle &strokeStyle,
2282 double &strokeWidth,
double &size )
2286 name = QStringLiteral(
"square" );
2288 strokeColor = QColor( 0, 0, 0 );
2292 QDomElement markElem = element.firstChildElement( QStringLiteral(
"Mark" ) );
2293 if ( markElem.isNull() )
2296 QDomElement wellKnownNameElem = markElem.firstChildElement( QStringLiteral(
"WellKnownName" ) );
2297 if ( !wellKnownNameElem.isNull() )
2299 name = wellKnownNameElem.firstChild().nodeValue();
2300 QgsDebugMsg(
"found Mark with well known name: " + name );
2304 QDomElement fillElem = markElem.firstChildElement( QStringLiteral(
"Fill" ) );
2305 Qt::BrushStyle b = Qt::SolidPattern;
2310 QDomElement strokeElem = markElem.firstChildElement( QStringLiteral(
"Stroke" ) );
2311 lineFromSld( strokeElem, strokeStyle, strokeColor, strokeWidth );
2315 QDomElement sizeElem = element.firstChildElement( QStringLiteral(
"Size" ) );
2316 if ( !sizeElem.isNull() )
2319 double s = sizeElem.firstChild().nodeValue().toDouble( &ok );
2329 if ( !rotationFunc.isEmpty() )
2331 QDomElement rotationElem = doc.createElement( QStringLiteral(
"se:Rotation" ) );
2333 element.appendChild( rotationElem );
2339 QDomElement rotationElem = element.firstChildElement( QStringLiteral(
"Rotation" ) );
2340 if ( !rotationElem.isNull() )
2350 if ( !alphaFunc.isEmpty() )
2352 QDomElement opacityElem = doc.createElement( QStringLiteral(
"se:Opacity" ) );
2354 element.appendChild( opacityElem );
2360 QDomElement opacityElem = element.firstChildElement( QStringLiteral(
"Opacity" ) );
2361 if ( !opacityElem.isNull() )
2370 if ( offset.isNull() )
2373 QDomElement displacementElem = doc.createElement( QStringLiteral(
"se:Displacement" ) );
2374 element.appendChild( displacementElem );
2376 QDomElement dispXElem = doc.createElement( QStringLiteral(
"se:DisplacementX" ) );
2377 dispXElem.appendChild( doc.createTextNode(
qgsDoubleToString( offset.x(), 2 ) ) );
2379 QDomElement dispYElem = doc.createElement( QStringLiteral(
"se:DisplacementY" ) );
2380 dispYElem.appendChild( doc.createTextNode(
qgsDoubleToString( offset.y(), 2 ) ) );
2382 displacementElem.appendChild( dispXElem );
2383 displacementElem.appendChild( dispYElem );
2390 QDomElement anchorElem = doc.createElement( QStringLiteral(
"se:AnchorPoint" ) );
2391 element.appendChild( anchorElem );
2393 QDomElement anchorXElem = doc.createElement( QStringLiteral(
"se:AnchorPointX" ) );
2394 anchorXElem.appendChild( doc.createTextNode(
qgsDoubleToString( anchor.x() ) ) );
2396 QDomElement anchorYElem = doc.createElement( QStringLiteral(
"se:AnchorPointY" ) );
2397 anchorYElem.appendChild( doc.createTextNode(
qgsDoubleToString( anchor.y() ) ) );
2399 anchorElem.appendChild( anchorXElem );
2400 anchorElem.appendChild( anchorYElem );
2405 offset = QPointF( 0, 0 );
2407 QDomElement displacementElem = element.firstChildElement( QStringLiteral(
"Displacement" ) );
2408 if ( displacementElem.isNull() )
2411 QDomElement dispXElem = displacementElem.firstChildElement( QStringLiteral(
"DisplacementX" ) );
2412 if ( !dispXElem.isNull() )
2415 double offsetX = dispXElem.firstChild().nodeValue().toDouble( &ok );
2417 offset.setX( offsetX );
2420 QDomElement dispYElem = displacementElem.firstChildElement( QStringLiteral(
"DisplacementY" ) );
2421 if ( !dispYElem.isNull() )
2424 double offsetY = dispYElem.firstChild().nodeValue().toDouble( &ok );
2426 offset.setY( offsetY );
2433 const QString &label,
const QFont &font,
2434 const QColor &color,
double size )
2436 QDomElement labelElem = doc.createElement( QStringLiteral(
"se:Label" ) );
2437 labelElem.appendChild( doc.createTextNode( label ) );
2438 element.appendChild( labelElem );
2440 QDomElement fontElem = doc.createElement( QStringLiteral(
"se:Font" ) );
2441 element.appendChild( fontElem );
2445 fontElem.appendChild( createSldParameterElement( doc,
"font-style",
encodeSldFontStyle( font.style() ) ) );
2446 fontElem.appendChild( createSldParameterElement( doc,
"font-weight",
encodeSldFontWeight( font.weight() ) ) );
2451 if ( color.isValid() )
2453 QDomElement fillElem = doc.createElement( QStringLiteral(
"Fill" ) );
2454 fillToSld( doc, fillElem, Qt::SolidPattern, color );
2455 element.appendChild( fillElem );
2460 Qt::PenJoinStyle joinStyle,
2461 Qt::PenCapStyle capStyle,
2463 const QVector<qreal> *dashPattern )
2466 penStyle.append(
"PEN(" );
2467 penStyle.append(
"c:" );
2468 penStyle.append( c.name() );
2469 penStyle.append(
",w:" );
2471 penStyle.append( QString::number( width * mmScaleFactor ) );
2472 penStyle.append(
"mm" );
2475 if ( dashPattern && !dashPattern->isEmpty() )
2477 penStyle.append(
",p:\"" );
2478 QVector<qreal>::const_iterator pIt = dashPattern->constBegin();
2479 for ( ; pIt != dashPattern->constEnd(); ++pIt )
2481 if ( pIt != dashPattern->constBegin() )
2483 penStyle.append(
' ' );
2485 penStyle.append( QString::number( *pIt * mapUnitScaleFactor ) );
2486 penStyle.append(
'g' );
2488 penStyle.append(
'\"' );
2492 penStyle.append(
",cap:" );
2496 penStyle.append(
'p' );
2499 penStyle.append(
'r' );
2503 penStyle.append(
'b' );
2507 penStyle.append(
",j:" );
2508 switch ( joinStyle )
2511 penStyle.append(
'b' );
2514 penStyle.append(
'r' );
2518 penStyle.append(
'm' );
2524 penStyle.append(
",dp:" );
2525 penStyle.append( QString::number( offset * mapUnitScaleFactor ) );
2526 penStyle.append(
'g' );
2529 penStyle.append(
')' );
2536 brushStyle.append(
"BRUSH(" );
2537 brushStyle.append(
"fc:" );
2538 brushStyle.append( fillColor.name() );
2539 brushStyle.append(
')' );
2545 if ( geomFunc.isEmpty() )
2548 QDomElement geometryElem = doc.createElement( QStringLiteral(
"Geometry" ) );
2549 element.appendChild( geometryElem );
2579 QDomElement geometryElem = element.firstChildElement( QStringLiteral(
"Geometry" ) );
2580 if ( geometryElem.isNull() )
2592 element.appendChild( doc.createComment(
"Parser Error: " + expr.
parserErrorString() +
" - Expression was: " + function ) );
2596 if ( !filterElem.isNull() )
2597 element.appendChild( filterElem );
2608 element.appendChild( doc.createComment(
"Parser Error: " + expr.
parserErrorString() +
" - Expression was: " + function ) );
2612 if ( !filterElem.isNull() )
2613 element.appendChild( filterElem );
2620 QDomElement elem = element;
2621 if ( element.tagName() != QLatin1String(
"Filter" ) )
2623 QDomNodeList filterNodes = element.elementsByTagName( QStringLiteral(
"Filter" ) );
2624 if ( !filterNodes.isEmpty() )
2626 elem = filterNodes.at( 0 ).toElement();
2630 if ( elem.isNull() )
2655 const QString &path,
const QString &format )
2659 QDomElement onlineResourceElem = doc.createElement( QStringLiteral(
"se:OnlineResource" ) );
2660 onlineResourceElem.setAttribute( QStringLiteral(
"xlink:type" ), QStringLiteral(
"simple" ) );
2661 onlineResourceElem.setAttribute( QStringLiteral(
"xlink:href" ), url );
2662 element.appendChild( onlineResourceElem );
2664 QDomElement formatElem = doc.createElement( QStringLiteral(
"se:Format" ) );
2665 formatElem.appendChild( doc.createTextNode( format ) );
2666 element.appendChild( formatElem );
2673 QDomElement onlineResourceElem = element.firstChildElement( QStringLiteral(
"OnlineResource" ) );
2674 if ( onlineResourceElem.isNull() )
2677 path = onlineResourceElem.attributeNS( QStringLiteral(
"http://www.w3.org/1999/xlink" ), QStringLiteral(
"href" ) );
2679 QDomElement formatElem = element.firstChildElement( QStringLiteral(
"Format" ) );
2680 if ( formatElem.isNull() )
2683 format = formatElem.firstChild().nodeValue();
2690 QDomElement nodeElem = doc.createElement( QStringLiteral(
"se:SvgParameter" ) );
2691 nodeElem.setAttribute( QStringLiteral(
"name" ), name );
2692 nodeElem.appendChild( doc.createTextNode( value ) );
2701 QDomElement paramElem = element.firstChildElement();
2702 while ( !paramElem.isNull() )
2704 if ( paramElem.localName() == QLatin1String(
"SvgParameter" ) || paramElem.localName() == QLatin1String(
"CssParameter" ) )
2706 QString name = paramElem.attribute( QStringLiteral(
"name" ) );
2707 if ( paramElem.firstChild().nodeType() == QDomNode::TextNode )
2709 value = paramElem.firstChild().nodeValue();
2713 if ( paramElem.firstChild().nodeType() == QDomNode::ElementNode &&
2714 paramElem.firstChild().localName() == QLatin1String(
"Literal" ) )
2716 QgsDebugMsg( paramElem.firstChild().localName() );
2717 value = paramElem.firstChild().firstChild().nodeValue();
2721 QgsDebugMsg( QString(
"unexpected child of %1" ).arg( paramElem.localName() ) );
2725 if ( !name.isEmpty() && !value.isEmpty() )
2726 params[ name ] = value;
2729 paramElem = paramElem.nextSiblingElement();
2737 QDomElement nodeElem = doc.createElement( QStringLiteral(
"se:VendorOption" ) );
2738 nodeElem.setAttribute( QStringLiteral(
"name" ), name );
2739 nodeElem.appendChild( doc.createTextNode( value ) );
2747 QDomElement paramElem = element.firstChildElement( QStringLiteral(
"VendorOption" ) );
2748 while ( !paramElem.isNull() )
2750 QString name = paramElem.attribute( QStringLiteral(
"name" ) );
2751 QString value = paramElem.firstChild().nodeValue();
2753 if ( !name.isEmpty() && !value.isEmpty() )
2754 params[ name ] = value;
2756 paramElem = paramElem.nextSiblingElement( QStringLiteral(
"VendorOption" ) );
2766 QDomElement e = element.firstChildElement();
2767 while ( !e.isNull() )
2769 if ( e.tagName() == QLatin1String(
"prop" ) )
2771 QString propKey = e.attribute( QStringLiteral(
"k" ) );
2772 QString propValue = e.attribute( QStringLiteral(
"v" ) );
2773 props[propKey] = propValue;
2775 e = e.nextSiblingElement();
2783 for ( QgsStringMap::iterator it = props.begin(); it != props.end(); ++it )
2785 QDomElement propEl = doc.createElement( QStringLiteral(
"prop" ) );
2786 propEl.setAttribute( QStringLiteral(
"k" ), it.key() );
2787 propEl.setAttribute( QStringLiteral(
"v" ), it.value() );
2788 element.appendChild( propEl );
2797 QDomElement e = element.firstChildElement();
2799 while ( !e.isNull() )
2801 if ( e.tagName() == QLatin1String(
"symbol" ) )
2805 symbols.insert( e.attribute( QStringLiteral(
"name" ) ), symbol );
2811 e = e.nextSiblingElement();
2818 QStringList subsymbols;
2820 for ( QMap<QString, QgsSymbol *>::iterator it = symbols.begin(); it != symbols.end(); ++it )
2822 if ( it.key()[0] !=
'@' )
2826 subsymbols.append( it.key() );
2828 QStringList parts = it.key().split(
'@' );
2829 if ( parts.count() < 3 )
2831 QgsDebugMsg(
"found subsymbol with invalid name: " + it.key() );
2835 QString symname = parts[1];
2836 int symlayer = parts[2].toInt();
2838 if ( !symbols.contains( symname ) )
2840 QgsDebugMsg(
"subsymbol references invalid symbol: " + symname );
2848 QgsDebugMsg(
"subsymbol references invalid symbol layer: " + QString::number( symlayer ) );
2857 QgsDebugMsg(
"symbol layer refused subsymbol: " + it.key() );
2864 for (
int i = 0; i < subsymbols.count(); i++ )
2865 symbols.take( subsymbols[i] );
2872 QDomElement symbolsElem = doc.createElement( tagName );
2875 for ( QMap<QString, QgsSymbol *>::iterator its = symbols.begin(); its != symbols.end(); ++its )
2877 QDomElement symEl =
saveSymbol( its.key(), its.value(), doc, context );
2878 symbolsElem.appendChild( symEl );
2886 qDeleteAll( symbols );
2895 std::unique_ptr< QMimeData >mimeData(
new QMimeData );
2897 QDomDocument symbolDoc;
2899 symbolDoc.appendChild( symbolElem );
2900 mimeData->setText( symbolDoc.toString() );
2903 mimeData->setColorData( symbol->
color() );
2905 return mimeData.release();
2913 QString text = data->text();
2914 if ( !text.isEmpty() )
2919 if ( doc.setContent( text ) )
2921 elem = doc.documentElement();
2923 if ( elem.nodeName() != QStringLiteral(
"symbol" ) )
2924 elem = elem.firstChildElement( QStringLiteral(
"symbol" ) );
2935 QString rampType = element.attribute( QStringLiteral(
"type" ) );
2940 if ( rampType == QLatin1String(
"gradient" ) )
2942 else if ( rampType == QLatin1String(
"random" ) )
2944 else if ( rampType == QLatin1String(
"colorbrewer" ) )
2946 else if ( rampType == QLatin1String(
"cpt-city" ) )
2948 else if ( rampType == QLatin1String(
"preset" ) )
2952 QgsDebugMsg(
"unknown colorramp type " + rampType );
2960 QDomElement rampEl = doc.createElement( QStringLiteral(
"colorramp" ) );
2961 rampEl.setAttribute( QStringLiteral(
"type" ), ramp->
type() );
2962 rampEl.setAttribute( QStringLiteral(
"name" ), name );
2970 QVariantMap rampMap;
2972 rampMap.insert( QStringLiteral(
"type" ), ramp->
type() );
2973 rampMap.insert( QStringLiteral(
"name" ), name );
2977 QVariantMap propertyMap;
2978 for (
auto property = properties.constBegin();
property != properties.constEnd(); ++property )
2980 propertyMap.insert( property.key(),
property.value() );
2983 rampMap.insert( QStringLiteral(
"properties" ), propertyMap );
2989 QVariantMap rampMap = value.toMap();
2991 QString rampType = rampMap.
value( QStringLiteral(
"type" ) ).toString();
2994 QVariantMap propertyMap = rampMap.value( QStringLiteral(
"properties" ) ).toMap();
2997 for (
auto property = propertyMap.constBegin();
property != propertyMap.constEnd(); ++property )
2999 props.insert( property.key(),
property.value().toString() );
3002 if ( rampType == QLatin1String(
"gradient" ) )
3004 else if ( rampType == QLatin1String(
"random" ) )
3006 else if ( rampType == QLatin1String(
"colorbrewer" ) )
3008 else if ( rampType == QLatin1String(
"cpt-city" ) )
3010 else if ( rampType == QLatin1String(
"preset" ) )
3014 QgsDebugMsg(
"unknown colorramp type " + rampType );
3021 if ( !color.isValid() )
3028 return color.name();
3033 QList<QColor> colors;
3036 QStringList components = colorStr.simplified().split( QRegExp(
"(,|\\s)" ) );
3037 QStringList::iterator it = components.begin();
3038 for ( ; it != components.end(); ++it )
3041 if ( result.isValid() )
3046 if ( colors.length() > 0 )
3052 components = colorStr.split( QRegExp(
"(,|\n)" ) );
3053 it = components.begin();
3054 for ( ; it != components.end(); ++it )
3057 if ( result.isValid() )
3062 if ( colors.length() > 0 )
3068 components = colorStr.simplified().split( QString(
' ' ) );
3069 it = components.begin();
3070 for ( ; it != components.end(); ++it )
3073 if ( result.isValid() )
3078 if ( colors.length() > 0 )
3084 components = colorStr.split(
'\n' );
3085 it = components.begin();
3086 for ( ; it != components.end(); ++it )
3089 if ( result.isValid() )
3102 QMimeData *mimeData =
new QMimeData;
3103 mimeData->setColorData( QVariant( color ) );
3104 mimeData->setText( color.name() );
3111 QColor mimeColor = mimeData->colorData().value<QColor>();
3112 if ( mimeColor.isValid() )
3121 if ( textColor.isValid() )
3135 if ( data->hasFormat( QStringLiteral(
"text/xml" ) ) )
3138 QByteArray encodedData = data->data( QStringLiteral(
"text/xml" ) );
3139 QDomDocument xmlDoc;
3140 xmlDoc.setContent( encodedData );
3142 QDomElement dragDataElem = xmlDoc.documentElement();
3143 if ( dragDataElem.tagName() == QLatin1String(
"ColorSchemeModelDragData" ) )
3145 QDomNodeList nodeList = dragDataElem.childNodes();
3146 int nChildNodes = nodeList.size();
3147 QDomElement currentElem;
3149 for (
int i = 0; i < nChildNodes; ++i )
3151 currentElem = nodeList.at( i ).toElement();
3152 if ( currentElem.isNull() )
3157 QPair< QColor, QString> namedColor;
3159 namedColor.second = currentElem.attribute( QStringLiteral(
"label" ), QLatin1String(
"" ) );
3161 mimeColors << namedColor;
3166 if ( mimeColors.length() == 0 && data->hasFormat( QStringLiteral(
"application/x-colorobject-list" ) ) )
3169 QByteArray encodedData = data->data( QStringLiteral(
"application/x-colorobject-list" ) );
3170 QDomDocument xmlDoc;
3171 xmlDoc.setContent( encodedData );
3173 QDomNodeList colorsNodes = xmlDoc.elementsByTagName( QStringLiteral(
"colors" ) );
3174 if ( colorsNodes.length() > 0 )
3176 QDomElement colorsElem = colorsNodes.at( 0 ).toElement();
3177 QDomNodeList colorNodeList = colorsElem.childNodes();
3178 int nChildNodes = colorNodeList.size();
3179 QDomElement currentElem;
3181 for (
int i = 0; i < nChildNodes; ++i )
3184 currentElem = colorNodeList.at( i ).toElement();
3185 if ( currentElem.isNull() )
3190 QDomNodeList colorNodes = currentElem.elementsByTagName( QStringLiteral(
"color" ) );
3191 QDomNodeList nameNodes = currentElem.elementsByTagName( QStringLiteral(
"name" ) );
3193 if ( colorNodes.length() > 0 )
3195 QDomElement colorElem = colorNodes.at( 0 ).toElement();
3197 QStringList colorParts = colorElem.text().simplified().split(
' ' );
3198 if ( colorParts.length() < 3 )
3203 int red = colorParts.at( 0 ).toDouble() * 255;
3204 int green = colorParts.at( 1 ).toDouble() * 255;
3205 int blue = colorParts.at( 2 ).toDouble() * 255;
3206 QPair< QColor, QString> namedColor;
3207 namedColor.first = QColor( red, green, blue );
3208 if ( nameNodes.length() > 0 )
3210 QDomElement nameElem = nameNodes.at( 0 ).toElement();
3211 namedColor.second = nameElem.text();
3213 mimeColors << namedColor;
3219 if ( mimeColors.length() == 0 && data->hasText() )
3223 QList< QColor >::iterator it = parsedColors.begin();
3224 for ( ; it != parsedColors.end(); ++it )
3226 mimeColors << qMakePair( *it, QString() );
3230 if ( mimeColors.length() == 0 && data->hasColor() )
3233 QColor mimeColor = data->colorData().value<QColor>();
3234 if ( mimeColor.isValid() )
3236 mimeColors << qMakePair( mimeColor, QString() );
3246 QMimeData *mimeData =
new QMimeData();
3247 QDomDocument xmlDoc;
3248 QDomElement xmlRootElement = xmlDoc.createElement( QStringLiteral(
"ColorSchemeModelDragData" ) );
3249 xmlDoc.appendChild( xmlRootElement );
3251 QgsNamedColorList::const_iterator colorIt = colorList.constBegin();
3252 for ( ; colorIt != colorList.constEnd(); ++colorIt )
3254 QDomElement namedColor = xmlDoc.createElement( QStringLiteral(
"NamedColor" ) );
3256 namedColor.setAttribute( QStringLiteral(
"label" ), ( *colorIt ).second );
3257 xmlRootElement.appendChild( namedColor );
3259 mimeData->setData( QStringLiteral(
"text/xml" ), xmlDoc.toByteArray() );
3267 colorIt = colorList.constBegin();
3268 QStringList colorListString;
3269 for ( ; colorIt != colorList.constEnd(); ++colorIt )
3271 colorListString << ( *colorIt ).first.name();
3273 mimeData->setText( colorListString.join( QStringLiteral(
"\n" ) ) );
3276 if ( colorList.length() > 0 )
3278 mimeData->setColorData( QVariant( colorList.at( 0 ).first ) );
3286 if ( !file.open( QIODevice::WriteOnly | QIODevice::Truncate ) )
3291 QTextStream stream( &file );
3292 stream <<
"GIMP Palette" << endl;
3293 if ( paletteName.isEmpty() )
3295 stream <<
"Name: QGIS Palette" << endl;
3299 stream <<
"Name: " << paletteName << endl;
3301 stream <<
"Columns: 4" << endl;
3302 stream <<
'#' << endl;
3304 for ( QgsNamedColorList::ConstIterator colorIt = colors.constBegin(); colorIt != colors.constEnd(); ++colorIt )
3306 QColor color = ( *colorIt ).first;
3307 if ( !color.isValid() )
3311 stream << QStringLiteral(
"%1 %2 %3" ).arg( color.red(), 3 ).arg( color.green(), 3 ).arg( color.blue(), 3 );
3312 stream <<
"\t" << ( ( *colorIt ).second.isEmpty() ? color.name() : ( *colorIt ).second ) << endl;
3323 if ( !file.open( QIODevice::ReadOnly ) )
3326 return importedColors;
3329 QTextStream in( &file );
3331 QString line = in.readLine();
3332 if ( !line.startsWith( QLatin1String(
"GIMP Palette" ) ) )
3335 return importedColors;
3339 while ( !in.atEnd() && !line.startsWith( QLatin1String(
"Name:" ) ) && !line.startsWith(
'#' ) )
3341 line = in.readLine();
3343 if ( line.startsWith( QLatin1String(
"Name:" ) ) )
3345 QRegExp nameRx(
"Name:\\s*(\\S.*)$" );
3346 if ( nameRx.indexIn( line ) != -1 )
3348 name = nameRx.cap( 1 );
3353 while ( !in.atEnd() && !line.startsWith(
'#' ) )
3355 line = in.readLine();
3360 return importedColors;
3364 QRegExp rx(
"^\\s*(\\d+)\\s+(\\d+)\\s+(\\d+)(\\s.*)?$" );
3365 while ( !in.atEnd() )
3367 line = in.readLine();
3368 if ( rx.indexIn( line ) == -1 )
3372 int red = rx.cap( 1 ).toInt();
3373 int green = rx.cap( 2 ).toInt();
3374 int blue = rx.cap( 3 ).toInt();
3375 QColor color = QColor( red, green, blue );
3376 if ( !color.isValid() )
3383 if ( rx.captureCount() > 3 )
3385 label = rx.cap( 4 ).simplified();
3392 importedColors << qMakePair( color, label );
3397 return importedColors;
3410 QRegExp hexColorAlphaRx(
"^\\s*#?([0-9a-fA-F]{6})([0-9a-fA-F]{2})\\s*$" );
3411 int hexColorIndex = hexColorAlphaRx.indexIn( colorStr );
3414 if ( hexColorIndex == -1 && QColor::isValidColor( colorStr ) )
3417 parsedColor.setNamedColor( colorStr );
3418 if ( parsedColor.isValid() )
3420 containsAlpha =
false;
3426 if ( hexColorIndex > -1 )
3428 QString hexColor = hexColorAlphaRx.cap( 1 );
3429 parsedColor.setNamedColor( QStringLiteral(
"#" ) + hexColor );
3431 int alphaHex = hexColorAlphaRx.cap( 2 ).toInt( &alphaOk, 16 );
3433 if ( parsedColor.isValid() && alphaOk )
3435 parsedColor.setAlpha( alphaHex );
3436 containsAlpha =
true;
3444 QRegExp hexColorRx2(
"^\\s*(?:[0-9a-fA-F]{3}){1,2}\\s*$" );
3445 if ( hexColorRx2.indexIn( colorStr ) != -1 )
3448 parsedColor.setNamedColor( QStringLiteral(
"#" ) + colorStr );
3449 if ( parsedColor.isValid() )
3451 containsAlpha =
false;
3458 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*$" );
3459 if ( rgbFormatRx.indexIn( colorStr ) != -1 )
3461 int r = rgbFormatRx.cap( 1 ).toInt();
3462 int g = rgbFormatRx.cap( 2 ).toInt();
3463 int b = rgbFormatRx.cap( 3 ).toInt();
3464 parsedColor.setRgb( r, g, b );
3465 if ( parsedColor.isValid() )
3467 containsAlpha =
false;
3473 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*$" );
3474 if ( rgbPercentFormatRx.indexIn( colorStr ) != -1 )
3476 int r = std::round( rgbPercentFormatRx.cap( 1 ).toDouble() * 2.55 );
3477 int g = std::round( rgbPercentFormatRx.cap( 2 ).toDouble() * 2.55 );
3478 int b = std::round( rgbPercentFormatRx.cap( 3 ).toDouble() * 2.55 );
3479 parsedColor.setRgb( r, g, b );
3480 if ( parsedColor.isValid() )
3482 containsAlpha =
false;
3488 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*$" );
3489 if ( rgbaFormatRx.indexIn( colorStr ) != -1 )
3491 int r = rgbaFormatRx.cap( 1 ).toInt();
3492 int g = rgbaFormatRx.cap( 2 ).toInt();
3493 int b = rgbaFormatRx.cap( 3 ).toInt();
3494 int a = std::round( rgbaFormatRx.cap( 4 ).toDouble() * 255.0 );
3495 parsedColor.setRgb( r, g, b, a );
3496 if ( parsedColor.isValid() )
3498 containsAlpha =
true;
3504 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*$" );
3505 if ( rgbaPercentFormatRx.indexIn( colorStr ) != -1 )
3507 int r = std::round( rgbaPercentFormatRx.cap( 1 ).toDouble() * 2.55 );
3508 int g = std::round( rgbaPercentFormatRx.cap( 2 ).toDouble() * 2.55 );
3509 int b = std::round( rgbaPercentFormatRx.cap( 3 ).toDouble() * 2.55 );
3510 int a = std::round( rgbaPercentFormatRx.cap( 4 ).toDouble() * 255.0 );
3511 parsedColor.setRgb( r, g, b, a );
3512 if ( parsedColor.isValid() )
3514 containsAlpha =
true;
3531 QImage::Format format = image->format();
3532 if ( format != QImage::Format_ARGB32_Premultiplied && format != QImage::Format_ARGB32 )
3539 for (
int heightIndex = 0; heightIndex < image->height(); ++heightIndex )
3541 QRgb *scanLine =
reinterpret_cast< QRgb *
>( image->scanLine( heightIndex ) );
3542 for (
int widthIndex = 0; widthIndex < image->width(); ++widthIndex )
3544 myRgb = scanLine[widthIndex];
3545 if ( format == QImage::Format_ARGB32_Premultiplied )
3546 scanLine[widthIndex] = qRgba( opacity * qRed( myRgb ), opacity * qGreen( myRgb ), opacity * qBlue( myRgb ), opacity * qAlpha( myRgb ) );
3548 scanLine[widthIndex] = qRgba( qRed( myRgb ), qGreen( myRgb ), qBlue( myRgb ), opacity * qAlpha( myRgb ) );
3556 int tab[] = { 14, 10, 8, 6, 5, 5, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2 };
3557 int alpha = ( radius < 1 ) ? 16 : ( radius > 17 ) ? 1 : tab[radius - 1];
3559 if ( image.format() != QImage::Format_ARGB32_Premultiplied
3560 && image.format() != QImage::Format_RGB32 )
3562 image = image.convertToFormat( QImage::Format_ARGB32_Premultiplied );
3565 int r1 = rect.top();
3566 int r2 = rect.bottom();
3567 int c1 = rect.left();
3568 int c2 = rect.right();
3570 int bpl = image.bytesPerLine();
3578 i1 = i2 = ( QSysInfo::ByteOrder == QSysInfo::BigEndian ? 0 : 3 );
3580 for (
int col = c1; col <= c2; col++ )
3582 p = image.scanLine( r1 ) + col * 4;
3583 for (
int i = i1; i <= i2; i++ )
3584 rgba[i] = p[i] << 4;
3587 for (
int j = r1; j < r2; j++, p += bpl )
3588 for (
int i = i1; i <= i2; i++ )
3589 p[i] = ( rgba[i] += ( ( p[i] << 4 ) - rgba[i] ) * alpha / 16 ) >> 4;
3592 for (
int row = r1; row <= r2; row++ )
3594 p = image.scanLine( row ) + c1 * 4;
3595 for (
int i = i1; i <= i2; i++ )
3596 rgba[i] = p[i] << 4;
3599 for (
int j = c1; j < c2; j++, p += 4 )
3600 for (
int i = i1; i <= i2; i++ )
3601 p[i] = ( rgba[i] += ( ( p[i] << 4 ) - rgba[i] ) * alpha / 16 ) >> 4;
3604 for (
int col = c1; col <= c2; col++ )
3606 p = image.scanLine( r2 ) + col * 4;
3607 for (
int i = i1; i <= i2; i++ )
3608 rgba[i] = p[i] << 4;
3611 for (
int j = r1; j < r2; j++, p -= bpl )
3612 for (
int i = i1; i <= i2; i++ )
3613 p[i] = ( rgba[i] += ( ( p[i] << 4 ) - rgba[i] ) * alpha / 16 ) >> 4;
3616 for (
int row = r1; row <= r2; row++ )
3618 p = image.scanLine( row ) + c2 * 4;
3619 for (
int i = i1; i <= i2; i++ )
3620 rgba[i] = p[i] << 4;
3623 for (
int j = c1; j < c2; j++, p -= 4 )
3624 for (
int i = i1; i <= i2; i++ )
3625 p[i] = ( rgba[i] += ( ( p[i] << 4 ) - rgba[i] ) * alpha / 16 ) >> 4;
3631 if ( alpha != 255 && alpha > 0 )
3635 double alphaFactor = alpha / 255.;
3636 int r = 0, g = 0, b = 0;
3637 rgb.getRgb( &r, &g, &b );
3642 rgb.setRgb( r, g, b, alpha );
3644 else if ( alpha == 0 )
3646 rgb.setRgb( 0, 0, 0, 0 );
3652 if ( order == Qt::AscendingOrder )
3666 double dx = directionPoint.x() - startPoint.x();
3667 double dy = directionPoint.y() - startPoint.y();
3668 double length = std::sqrt( dx * dx + dy * dy );
3669 double scaleFactor = distance / length;
3670 return QPointF( startPoint.x() + dx * scaleFactor, startPoint.y() + dy * scaleFactor );
3680 for (
int i = 0; i < svgPaths.size(); i++ )
3682 QDir dir( svgPaths[i] );
3683 Q_FOREACH (
const QString &item, dir.entryList( QDir::Dirs | QDir::NoDotAndDotDot ) )
3685 svgPaths.insert( i + 1, dir.path() +
'/' + item );
3688 Q_FOREACH (
const QString &item, dir.entryList( QStringList(
"*.svg" ), QDir::Files ) )
3691 list.append( dir.path() +
'/' + item );
3703 QStringList svgPaths;
3704 svgPaths.append( directory );
3706 for (
int i = 0; i < svgPaths.size(); i++ )
3708 QDir dir( svgPaths[i] );
3709 Q_FOREACH (
const QString &item, dir.entryList( QDir::Dirs | QDir::NoDotAndDotDot ) )
3711 svgPaths.insert( i + 1, dir.path() +
'/' + item );
3714 Q_FOREACH (
const QString &item, dir.entryList( QStringList(
"*.svg" ), QDir::Files ) )
3716 list.append( dir.path() +
'/' + item );
3729 if ( QFileInfo::exists( n ) )
3730 return QFileInfo( n ).canonicalFilePath();
3734 if ( name.contains( QLatin1String(
"://" ) ) )
3737 if ( url.isValid() && !url.scheme().isEmpty() )
3739 if ( url.scheme().compare( QLatin1String(
"file" ), Qt::CaseInsensitive ) == 0 )
3742 name = url.toLocalFile();
3743 if ( QFile( name ).exists() )
3745 return QFileInfo( name ).canonicalFilePath();
3759 for (
int i = 0; i < svgPaths.size(); i++ )
3761 QString svgPath = svgPaths[i];
3762 if ( svgPath.endsWith( QChar(
'/' ) ) )
3773 QString myLocalPath = svgPath + QDir::separator() + name;
3776 if ( QFile( myLocalPath ).exists() )
3779 return QFileInfo( myLocalPath ).canonicalFilePath();
3783 return pathResolver.
readPath( name );
3791 if ( !QFileInfo::exists( p ) )
3794 QString path = QFileInfo( p ).canonicalFilePath();
3798 bool isInSvgPaths =
false;
3799 for (
int i = 0; i < svgPaths.size(); i++ )
3801 QString dir = QFileInfo( svgPaths[i] ).canonicalFilePath();
3803 if ( !dir.isEmpty() && path.startsWith( dir ) )
3805 path = path.mid( dir.size() + 1 );
3806 isInSvgPaths =
true;
3821 double cx = 0, cy = 0;
3822 double area, sum = 0;
3823 for (
int i = points.count() - 1, j = 0; j < points.count(); i = j++ )
3825 const QPointF &p1 = points[i];
3826 const QPointF &p2 = points[j];
3827 area = p1.x() * p2.y() - p1.y() * p2.x();
3829 cx += ( p1.x() + p2.x() ) * area;
3830 cy += ( p1.y() + p2.y() ) * area;
3837 if ( points.count() >= 2 )
3838 return QPointF( ( points[0].x() + points[1].x() ) / 2, ( points[0].y() + points[1].y() ) / 2 );
3839 else if ( points.count() == 1 )
3847 return QPointF( cx, cy );
3857 unsigned int i, pointCount = points.count();
3860 for ( i = 0; i < pointCount; ++i ) polyline[i] =
QgsPointXY( points[i].x(), points[i].y() );
3867 if ( !pointOnSurfaceGeom.
isNull() )
3871 return QPointF( point.
x(), point.
y() );
3880 bool inside =
false;
3882 double x = point.x();
3883 double y = point.y();
3885 for (
int i = 0, j = points.count() - 1; i < points.count(); i++ )
3887 const QPointF &p1 = points[i];
3888 const QPointF &p2 = points[j];
3893 if ( ( p1.y() < y && p2.y() >= y ) || ( p2.y() < y && p1.y() >= y ) )
3895 if ( p1.x() + ( y - p1.y() ) / ( p2.y() - p1.y() ) * ( p2.x() - p1.x() ) <= x )
3906 if ( fieldOrExpression.isEmpty() )
3925 return static_cast<const QgsExpressionNodeColumnRef *>( n )->name();
3941 QList<double> breaks;
3944 breaks.append( maximum );
3948 int minimumCount =
static_cast< int >( classes ) / 3;
3949 double shrink = 0.75;
3950 double highBias = 1.5;
3951 double adjustBias = 0.5 + 1.5 * highBias;
3952 int divisions = classes;
3953 double h = highBias;
3956 double dx = maximum - minimum;
3966 cell = std::max( std::fabs( minimum ), std::fabs( maximum ) );
3967 if ( adjustBias >= 1.5 * h + 0.5 )
3969 U = 1 + ( 1.0 / ( 1 + h ) );
3973 U = 1 + ( 1.5 / ( 1 + adjustBias ) );
3975 small = dx < ( cell * U * std::max( 1, divisions ) * 1e-07 * 3.0 );
3982 cell = 9 + cell / 10;
3983 cell = cell * shrink;
3985 if ( minimumCount > 1 )
3987 cell = cell / minimumCount;
3993 if ( divisions > 1 )
3995 cell = cell / divisions;
3998 if ( cell < 20 * 1e-07 )
4003 double base = std::pow( 10.0, std::floor( std::log10( cell ) ) );
4005 if ( ( 2 * base ) - cell < h * ( cell - unit ) )
4008 if ( ( 5 * base ) - cell < adjustBias * ( cell - unit ) )
4011 if ( ( 10.0 * base ) - cell < h * ( cell - unit ) )
4018 int start = std::floor( minimum / unit + 1e-07 );
4019 int end = std::ceil( maximum / unit - 1e-07 );
4022 while ( start * unit > minimum + ( 1e-07 * unit ) )
4026 while ( end * unit < maximum - ( 1e-07 * unit ) )
4030 QgsDebugMsg( QString(
"pretty classes: %1" ).arg( end ) );
4034 int k = std::floor( 0.5 + end - start );
4035 if ( k < minimumCount )
4037 k = minimumCount - k;
4041 start = start - k / 2 + k % 2;
4045 start = start - k / 2;
4046 end = end + k / 2 + k % 2;
4049 double minimumBreak = start * unit;
4051 int count = end - start;
4053 breaks.reserve( count );
4054 for (
int i = 1; i < count + 1; i++ )
4056 breaks.append( minimumBreak + i * unit );
4059 if ( breaks.isEmpty() )
4062 if ( breaks.first() < minimum )
4064 breaks[0] = minimum;
4066 if ( breaks.last() > maximum )
4068 breaks[breaks.count() - 1] = maximum;
4077 bool roundToUnit =
false;
4080 if ( props.contains( QStringLiteral(
"uomScale" ) ) )
4083 scale = props.value( QStringLiteral(
"uomScale" ) ).toDouble( &ok );
4092 if ( props.value( QStringLiteral(
"uom" ) ) == QLatin1String(
"http://www.opengeospatial.org/se/units/metre" ) )
4117 scale = 1 / 0.28 * 25.4;
4141 double rescaled = size * scale;
4146 rescaled = std::round( rescaled );
4153 double x =
rescaleUom( point.x(), unit, props );
4154 double y =
rescaleUom( point.y(), unit, props );
4155 return QPointF( x, y );
4160 QVector<qreal> result;
4161 QVector<qreal>::const_iterator it = array.constBegin();
4162 for ( ; it != array.constEnd(); ++it )
4164 result.append(
rescaleUom( *it, unit, props ) );
4171 if ( !props.value( QStringLiteral(
"scaleMinDenom" ), QLatin1String(
"" ) ).isEmpty() )
4173 QDomElement scaleMinDenomElem = doc.createElement( QStringLiteral(
"se:MinScaleDenominator" ) );
4174 scaleMinDenomElem.appendChild( doc.createTextNode( props.value( QStringLiteral(
"scaleMinDenom" ), QLatin1String(
"" ) ) ) );
4175 ruleElem.appendChild( scaleMinDenomElem );
4178 if ( !props.value( QStringLiteral(
"scaleMaxDenom" ), QLatin1String(
"" ) ).isEmpty() )
4180 QDomElement scaleMaxDenomElem = doc.createElement( QStringLiteral(
"se:MaxScaleDenominator" ) );
4181 scaleMaxDenomElem.appendChild( doc.createTextNode( props.value( QStringLiteral(
"scaleMaxDenom" ), QLatin1String(
"" ) ) ) );
4182 ruleElem.appendChild( scaleMaxDenomElem );
4188 if ( mScaleMinDenom != 0 )
4191 int parentScaleMinDenom = props.value( QStringLiteral(
"scaleMinDenom" ), QStringLiteral(
"0" ) ).toInt( &ok );
4192 if ( !ok || parentScaleMinDenom <= 0 )
4193 props[ QStringLiteral(
"scaleMinDenom" )] = QString::number( mScaleMinDenom );
4195 props[ QStringLiteral(
"scaleMinDenom" )] = QString::number( std::max( parentScaleMinDenom, mScaleMinDenom ) );
4198 if ( mScaleMaxDenom != 0 )
4201 int parentScaleMaxDenom = props.value( QStringLiteral(
"scaleMaxDenom" ), QStringLiteral(
"0" ) ).toInt( &ok );
4202 if ( !ok || parentScaleMaxDenom <= 0 )
4203 props[ QStringLiteral(
"scaleMaxDenom" )] = QString::number( mScaleMaxDenom );
4205 props[ QStringLiteral(
"scaleMaxDenom" )] = QString::number( std::min( parentScaleMaxDenom, mScaleMaxDenom ) );
4213 if ( uom == QLatin1String(
"http://www.opengeospatial.org/se/units/metre" ) )
4215 scale = 1.0 / 0.00028;
4217 else if ( uom == QLatin1String(
"http://www.opengeospatial.org/se/units/foot" ) )
4219 scale = 304.8 / 0.28;
4226 return size * scale;
static void wellKnownMarkerToSld(QDomDocument &doc, QDomElement &element, const QString &name, const QColor &color, const QColor &strokeColor, Qt::PenStyle strokeStyle, double strokeWidth=-1, double size=-1)
Class for parsing and evaluation of expressions (formerly called "search strings").
void setForceVectorOutput(bool force)
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 QPixmap symbolPreviewPixmap(QgsSymbol *symbol, QSize size, int padding=0, QgsRenderContext *customContext=nullptr)
Returns a pixmap preview for a color ramp.
static QgsStringMap parseProperties(QDomElement &element)
static QgsSymbolLayer * loadSymbolLayer(QDomElement &element, const QgsReadWriteContext &context)
Reads and returns symbol layer from XML. Caller is responsible for deleting the returned object...
double minSizeMM
The minimum size in millimeters, or 0.0 if unset.
static QgsSymbol::ScaleMethod decodeScaleMethod(const QString &str)
static QgsGeometry fromPolylineXY(const QgsPolylineXY &polyline)
Creates a new LineString geometry from a list of QgsPointXY points.
static QStringList listSvgFilesAt(const QString &directory)
Returns a list of svg files at the specified directory.
static bool needFontMarker(QDomElement &element)
void setRenderingPass(int renderingPass)
static Qt::BrushStyle decodeBrushStyle(const QString &str)
static QDomElement createVendorOptionElement(QDomDocument &doc, const QString &name, const QString &value)
void setLocked(bool locked)
static bool hasWellKnownMark(QDomElement &element)
static QgsColorRamp * create(const QgsStringMap &properties=QgsStringMap())
Returns a new QgsColorBrewerColorRamp color ramp created using the properties encoded in a string map...
static QgsColorRamp * create(const QgsStringMap &properties=QgsStringMap())
Returns a new QgsPresetSchemeColorRamp color ramp created using the properties encoded in a string ma...
static QString quotedColumnRef(QString name)
Returns a quoted column reference (in double quotes)
static QgsStringMap getSvgParameterList(QDomElement &element)
void setMapUnitScale(const QgsMapUnitScale &scale)
QgsPaintEffect * paintEffect() const
Returns the current paint effect for the layer.
Calculate scale by the diameter.
static bool createFunctionElement(QDomDocument &doc, QDomElement &element, const QString &function)
static QString encodeSldAlpha(int alpha)
bool isNull() const
Returns true if the geometry is null (ie, contains no underlying geometry accessible via geometry() )...
static QgsArrowSymbolLayer::ArrowType decodeArrowType(const QVariant &value, bool *ok=nullptr)
Decodes a value representing an arrow type.
static QString encodeSldBrushStyle(Qt::BrushStyle style)
virtual QgsSymbol * subSymbol()
Returns the symbol's sub symbol, if present.
static QString encodeSize(QSizeF size)
Encodes a QSizeF to a string.
QString readPath(const QString &filename) const
Turn filename read from the project file to an absolute path.
virtual bool readXml(const QDomElement &collectionElem, const QgsPropertiesDefinition &definitions)
Reads property collection state from an XML element.
static void applyScaleDependency(QDomDocument &doc, QDomElement &ruleElem, QgsStringMap &props)
Checks if the properties contain scaleMinDenom and scaleMaxDenom, if available, they are added into t...
static Qt::PenCapStyle decodeSldLineCapStyle(const QString &str)
static void createOnlineResourceElement(QDomDocument &doc, QDomElement &element, const QString &path, const QString &format)
QgsWkbTypes::Type wkbType() const
Returns type of the geometry as a WKB type (point / linestring / polygon etc.)
static QDomElement createSvgParameterElement(QDomDocument &doc, const QString &name, const QString &value)
static bool geometryFromSldElement(QDomElement &element, QString &geomFunc)
A class to represent a 2D point.
QgsSymbolLayer * createSymbolLayer(const QString &name, const QgsStringMap &properties=QgsStringMap()) const
create a new instance of symbol layer given symbol layer name and properties
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 bool isDefaultStack(QgsPaintEffect *effect)
Tests whether a paint effect matches the default effects stack.
static bool displacementFromSldElement(QDomElement &element, QPointF &offset)
static void mergeScaleDependencies(int mScaleMinDenom, int mScaleMaxDenom, QgsStringMap &props)
Merges the local scale limits, if any, with the ones already in the map, if any.
static QPointF decodePoint(const QString &string)
Decodes a QSizeF from a string.
QVector< QgsPolylineXY > QgsPolygonXY
Polygon: first item of the list is outer ring, inner rings (if any) start from second item...
static QDomElement saveColorRamp(const QString &name, QgsColorRamp *ramp, QDomDocument &doc)
Encodes a color ramp's settings to an XML element.
static bool needMarkerLine(QDomElement &element)
static void externalMarkerToSld(QDomDocument &doc, QDomElement &element, const QString &path, const QString &format, int *markIndex=nullptr, const QColor &color=QColor(), double size=-1)
bool clipFeaturesToExtent() const
Returns whether features drawn by the symbol will be clipped to the render context's extent...
static bool onlineResourceFromSldElement(QDomElement &element, QString &path, QString &format)
static QString encodeMapUnitScale(const QgsMapUnitScale &mapUnitScale)
Container of fields for a vector layer.
static void createDisplacementElement(QDomDocument &doc, QDomElement &element, QPointF offset)
A geometry is the spatial representation of a feature.
static double sizeInPixelsFromSldUom(const QString &uom, double size)
Returns the size scaled in pixels according to the uom attribute.
QgsGeometry buffer(double distance, int segments) const
Returns a buffer region around this geometry having the given width and with a specified number of se...
int symbolLayerCount() const
Returns total number of symbol layers contained in the symbol.
static QgsColorRamp * create(const QgsStringMap &properties=QgsStringMap())
static void clearSymbolMap(QgsSymbolMap &symbols)
static 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.
bool qgsVariantGreaterThan(const QVariant &lhs, const QVariant &rhs)
Compares two QVariant values and returns whether the first is greater than the second.
virtual QgsStringMap properties() const =0
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
virtual QColor color(double value) const =0
Returns the color corresponding to a specified value.
static bool createExpressionElement(QDomDocument &doc, QDomElement &element, const QString &function)
Creates a OGC Expression element based on the provided function expression.
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.
QVector< QgsPolygonXY > QgsMultiPolygonXY
A collection of QgsPolygons that share a common collection of attributes.
static Qt::PenJoinStyle decodePenJoinStyle(const QString &str)
bool qgsVariantLessThan(const QVariant &lhs, const QVariant &rhs)
Compares two QVariant values and returns whether the first is less than the second.
static QColor parseColor(const QString &colorStr, bool strictEval=false)
Attempts to parse a string as a color using a variety of common formats, including hex codes...
static QgsPaintEffectRegistry * paintEffectRegistry()
Returns the application's paint effect registry, used for managing paint effects. ...
bool minSizeMMEnabled
Whether the minimum size in mm should be respected.
bool hasFeature() const
Returns true if the context has a feature associated with it.
static QIcon symbolLayerPreviewIcon(QgsSymbolLayer *layer, QgsUnitTypes::RenderUnit u, QSize size, const QgsMapUnitScale &scale=QgsMapUnitScale())
Draws a symbol layer preview to an icon.
static QString getSvgParametricPath(const QString &basePath, const QColor &fillColor, const QColor &strokeColor, double strokeWidth)
Encodes a reference to a parametric SVG into a path with parameters according to the SVG Parameters s...
static QVector< qreal > decodeRealVector(const QString &s)
static QString encodeColor(const QColor &color)
void setOutputUnit(QgsUnitTypes::RenderUnit unit)
Sets the units to use for sizes and widths within the symbol.
QVector< QgsPolylineXY > QgsMultiPolylineXY
A collection of QgsPolylines that share a common collection of attributes.
QgsMultiPolylineXY asMultiPolyline() const
Returns contents of the geometry as a multi linestring if wkbType is WKBMultiLineString, otherwise an empty list.
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...
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
virtual bool setSubSymbol(QgsSymbol *symbol)
Sets layer's subsymbol. takes ownership of the passed symbol.
static QgsUnitTypes::RenderUnit decodeSldUom(const QString &str, double *scaleFactor)
Decodes a SLD unit of measure string to a render unit.
static QgsNamedColorList importColorsFromGpl(QFile &file, bool &ok, QString &name)
Imports colors from a gpl GIMP palette file.
static QIcon symbolPreviewIcon(QgsSymbol *symbol, QSize size, int padding=0)
Returns an icon preview for a color ramp.
#define QgsDebugMsgLevel(str, level)
static QDomElement saveSymbols(QgsSymbolMap &symbols, const QString &tagName, QDomDocument &doc, const QgsReadWriteContext &context)
Writes a collection of symbols to XML with specified tagName for the top-level element.
static void externalGraphicToSld(QDomDocument &doc, QDomElement &element, const QString &path, const QString &mime, const QColor &color, double size=-1)
static QString encodeSldRealVector(const QVector< qreal > &v)
static bool needEllipseMarker(QDomElement &element)
void setOpacity(qreal opacity)
Sets the opacity for the symbol.
static QgsStringMap getVendorOptionList(QDomElement &element)
QgsPolygonXY asPolygon() const
Returns contents of the geometry as a polygon if wkbType is WKBPolygon, otherwise an empty list...
static QColor parseColorWithAlpha(const QString &colorStr, bool &containsAlpha, bool strictEval=false)
Attempts to parse a string as a color using a variety of common formats, including hex codes...
Calculate scale by the area.
static bool needSvgMarker(QDomElement &element)
static QVariant colorRampToVariant(const QString &name, QgsColorRamp *ramp)
Saves a color ramp to a QVariantMap, wrapped in a QVariant.
static QString colorToName(const QColor &color)
Returns a friendly display name for a color.
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
static QIcon colorRampPreviewIcon(QgsColorRamp *ramp, QSize size, int padding=0)
Returns an icon preview for a color ramp.
static int decodeSldAlpha(const QString &str)
QgsPropertyCollection & dataDefinedProperties()
Returns a reference to the symbol layer's property collection, used for data defined overrides...
virtual double value(int index) const =0
Returns relative value between [0,1] of color at specified index.
static QString encodeSldLineJoinStyle(Qt::PenJoinStyle style)
points (e.g., for font sizes)
static QgsRenderContext fromQPainter(QPainter *painter)
Creates a default render context given a pixel based QPainter destination.
QList< QPair< QColor, QString > > QgsNamedColorList
List of colors paired with a friendly display name identifying the color.
static QgsSymbolLayer * createMarkerLayerFromSld(QDomElement &element)
static void createRotationElement(QDomDocument &doc, QDomElement &element, const QString &rotationFunc)
ArrowType
Possible arrow types.
void drawPreviewIcon(QPainter *painter, QSize size, QgsRenderContext *customContext=nullptr)
Draw icon of the symbol that occupyies area given by size using the painter.
QgsGeometry offsetCurve(double distance, int segments, JoinStyle joinStyle, double miterLimit) const
Returns an offset line at a given distance and side from an input line.
QList< QgsSymbolLayer * > QgsSymbolLayerList
void setPainter(QPainter *p)
Sets the destination QPainter for the render operation.
static QgsColorRamp * loadColorRamp(QDomElement &element)
Creates a color ramp from the settings encoded in an XML element.
static QString encodeSldUom(QgsUnitTypes::RenderUnit unit, double *scaleFactor)
Encodes a render unit into an SLD unit of measure string.
virtual void drawPreviewIcon(QgsSymbolRenderContext &context, QSize size)=0
static QgsSymbolLayer * createFillLayerFromSld(QDomElement &element)
static double estimateMaxSymbolBleed(QgsSymbol *symbol, const QgsRenderContext &context)
Returns the maximum estimated bleed for the symbol.
Abstract base class for all nodes that can appear in an expression.
static QPainter::CompositionMode decodeBlendMode(const QString &s)
static Qt::PenCapStyle decodePenCapStyle(const QString &str)
void setPaintEffect(QgsPaintEffect *effect)
Sets the current paint effect for the layer.
static bool needLinePatternFill(QDomElement &element)
static void parametricSvgToSld(QDomDocument &doc, QDomElement &graphicElem, const QString &path, const QColor &fillColor, double size, const QColor &strokeColor, double strokeWidth)
Encodes a reference to a parametric SVG into SLD, as a succession of parametric SVG using URL paramet...
virtual QString type() const =0
Returns a string representing the color ramp type.
static Q_INVOKABLE QgsUnitTypes::RenderUnit decodeRenderUnit(const QString &string, bool *ok=nullptr)
Decodes a render unit from a string.
QgsGeometry pointOnSurface() const
Returns a point guaranteed to lie on the surface of a geometry.
static bool lineFromSld(QDomElement &element, Qt::PenStyle &penStyle, QColor &color, double &width, Qt::PenJoinStyle *penJoinStyle=nullptr, Qt::PenCapStyle *penCapStyle=nullptr, QVector< qreal > *customDashPattern=nullptr, double *dashOffset=nullptr)
void setEnabled(bool enabled)
Sets whether symbol layer is enabled and should be drawn.
static QString encodeSldFontStyle(QFont::Style style)
static QStringList listSvgFiles()
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 a specific symbol layers contained in the symbol.
static bool opacityFromSldElement(QDomElement &element, QString &alphaFunc)
static Qt::PenStyle decodePenStyle(const QString &str)
static bool externalGraphicFromSld(QDomElement &element, QString &path, QString &mime, QColor &color, double &size)
static void premultiplyColor(QColor &rgb, int alpha)
Converts a QColor into a premultiplied ARGB QColor value using a specified alpha value.
static bool needPointPatternFill(QDomElement &element)
virtual double estimateMaxBleed(const QgsRenderContext &context) const
Returns the estimated maximum distance which the layer style will bleed outside the drawn shape when ...
static bool fillFromSld(QDomElement &element, Qt::BrushStyle &brushStyle, QColor &color)
static QString encodeSldFontWeight(int weight)
static void createGeometryElement(QDomDocument &doc, QDomElement &element, const QString &geomFunc)
static QPixmap colorRampPreviewPixmap(QgsColorRamp *ramp, QSize size, int padding=0)
Returns a pixmap preview for a color ramp.
static bool pointInPolygon(const QPolygonF &points, QPointF point)
Calculate whether a point is within of a QPolygonF.
QString expression() const
Returns the original, unmodified expression string.
QgsExpressionContext & expressionContext()
Gets the expression context.
static QSizeF decodeSize(const QString &string)
Decodes a QSizeF from a string.
static Qt::BrushStyle decodeSldBrushStyle(const QString &str)
static QgsGeometry fromPolygonXY(const QgsPolygonXY &polygon)
Creates a new geometry from a QgsPolygon.
static QString symbolProperties(QgsSymbol *symbol)
Returns a string representing the symbol.
static QString encodeScaleMethod(QgsSymbol::ScaleMethod scaleMethod)
static bool hasExternalGraphic(QDomElement &element)
static bool externalMarkerFromSld(QDomElement &element, QString &path, QString &format, int &markIndex, QColor &color, double &size)
static QList< double > prettyBreaks(double minimum, double maximum, int classes)
Computes a sequence of about 'classes' equally spaced round values which cover the range of values fr...
GeometryType
The geometry types are used to group QgsWkbTypes::Type in a coarse way.
static void sortVariantList(QList< QVariant > &list, Qt::SortOrder order)
Sorts the passed list in requested order.
static QPointF polygonCentroid(const QPolygonF &points)
Calculate the centroid point of a QPolygonF.
static bool convertPolygonSymbolizerToPointMarker(QDomElement &element, QgsSymbolLayerList &layerList)
static QVector< qreal > decodeSldRealVector(const QString &s)
static QgsColorRamp * create(const QgsStringMap &properties=QgsStringMap())
Creates a new QgsColorRamp from a map of properties.
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.
void resolvePaths(const QString &name, QgsStringMap &properties, const QgsPathResolver &pathResolver, bool saving) const
Resolve paths in properties of a particular symbol layer.
static void createOpacityElement(QDomDocument &doc, QDomElement &element, const QString &alphaFunc)
static void labelTextToSld(QDomDocument &doc, QDomElement &element, const QString &label, const QFont &font, const QColor &color=QColor(), double size=-1)
static QPicture symbolLayerPreviewPicture(QgsSymbolLayer *layer, QgsUnitTypes::RenderUnit units, QSize size, const QgsMapUnitScale &scale=QgsMapUnitScale())
Draws a symbol layer preview to a QPicture.
QgsPointXY asPoint() const
Returns contents of the geometry as a point if wkbType is WKBPoint, otherwise returns [0...
static void blurImageInPlace(QImage &image, QRect rect, int radius, bool alphaOnly)
Blurs an image in place, e.g. creating Qt-independent drop shadows.
double maxSizeMM
The maximum size in millimeters, or 0.0 if unset.
bool hasDataDefinedProperties() const
Returns whether the symbol utilizes any data defined properties.
bool enabled() const
Returns true if symbol layer is enabled and will be drawn.
Struct for storing maximum and minimum scales for measurements in map units.
static QString encodeBrushStyle(Qt::BrushStyle style)
const QgsExpressionNode * rootNode() const
Returns root node of the expression. Root node is null is parsing has failed.
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
Gets 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 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 QMimeData * symbolToMimeData(QgsSymbol *symbol)
Creates new mime data from a symbol.
QMap< QString, QgsSymbol *> QgsSymbolMap
static QDomElement saveSymbol(const QString &symbolName, QgsSymbol *symbol, QDomDocument &doc, const QgsReadWriteContext &context)
Writes a symbol definition to XML.
static bool wellKnownMarkerFromSld(QDomElement &element, QString &name, QColor &color, QColor &strokeColor, Qt::PenStyle &strokeStyle, double &strokeWidth, double &size)
QString writePath(const QString &filename) const
Prepare a filename to save it to the project file.
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 contents of the geometry as a polyline if wkbType is WKBLineString, otherwise an empty list...
static void fillToSld(QDomDocument &doc, QDomElement &element, Qt::BrushStyle brushStyle, const QColor &color=QColor())
static void lineToSld(QDomDocument &doc, QDomElement &element, Qt::PenStyle penStyle, const QColor &color, double width=-1, const Qt::PenJoinStyle *penJoinStyle=nullptr, const Qt::PenCapStyle *penCapStyle=nullptr, const QVector< qreal > *customDashPattern=nullptr, double dashOffset=0.0)
static QString svgSymbolNameToPath(const QString &name, const QgsPathResolver &pathResolver)
Determines an SVG symbol's path from its name.
static QString encodePenCapStyle(Qt::PenCapStyle style)
static QPointF polygonPointOnSurface(const QPolygonF &points)
Calculate a point within of a QPolygonF.
void setClipFeaturesToExtent(bool clipFeaturesToExtent)
Sets whether features drawn by the symbol should be clipped to the render context's extent...
qreal opacity() const
Returns the opacity for the symbol.
static const QgsPropertiesDefinition & propertyDefinitions()
Returns the symbol layer property definitions.
Resolves relative paths into absolute paths and vice versa.
static QgsColorRamp * create(const QgsStringMap &properties=QgsStringMap())
Returns a new QgsLimitedRandomColorRamp color ramp created using the properties encoded in a string m...
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.
static void multiplyImageOpacity(QImage *image, qreal opacity)
Multiplies opacity of image pixel values with a (global) transparency value.
QgsMultiPolygonXY asMultiPolygon() const
Returns contents of the geometry as a multi polygon if wkbType is WKBMultiPolygon, otherwise an empty list.
bool maxSizeMMEnabled
Whether the maximum size in mm should be respected.
static void saveProperties(QgsStringMap props, QDomDocument &doc, QDomElement &element)
static Qt::PenJoinStyle decodeSldLineJoinStyle(const QString &str)
static bool createSymbolLayerListFromSld(QDomElement &element, QgsWkbTypes::GeometryType geomType, QgsSymbolLayerList &layers)
static QList< QColor > parseColorList(const QString &colorStr)
Attempts to parse a string as a list of colors using a variety of common formats, including hex codes...
static void drawStippledBackground(QPainter *painter, QRect rect)
static QString encodeSldLineCapStyle(Qt::PenCapStyle style)
static QString encodePenJoinStyle(Qt::PenJoinStyle style)
static QString encodeRealVector(const QVector< qreal > &v)
RenderUnit
Rendering size units.
static QColor decodeColor(const QString &str)
static QColor colorFromMimeData(const QMimeData *data, bool &hasAlpha)
Attempts to parse mime data as a color.
virtual QString layerType() const =0
Returns a string that represents this layer type.
virtual bool saveProperties(QDomDocument &doc, QDomElement &element) const
Saves the current state of the effect to a DOM element.