38 #include <QDomDocument> 40 #include <QDomElement> 47 #define POINTS_TO_MM 2.83464567 51 return QStringLiteral(
"%1,%2,%3,%4" ).arg( color.red() ).arg( color.green() ).arg( color.blue() ).arg( color.alpha() );
56 QStringList lst = str.split(
',' );
57 if ( lst.count() < 3 )
61 int red, green, blue, alpha;
63 green = lst[1].toInt();
64 blue = lst[2].toInt();
66 if ( lst.count() > 3 )
68 alpha = lst[3].toInt();
70 return QColor( red, green, blue, alpha );
76 result.sprintf(
"%.2g", alpha / 255.0 );
83 double alpha = str.toDouble( &ok );
84 if ( !ok || alpha > 1 )
95 case QFont::StyleNormal:
96 return QStringLiteral(
"normal" );
97 case QFont::StyleItalic:
98 return QStringLiteral(
"italic" );
99 case QFont::StyleOblique:
100 return QStringLiteral(
"oblique" );
108 if ( str == QLatin1String(
"normal" ) )
return QFont::StyleNormal;
109 if ( str == QLatin1String(
"italic" ) )
return QFont::StyleItalic;
110 if ( str == QLatin1String(
"oblique" ) )
return QFont::StyleOblique;
111 return QFont::StyleNormal;
116 if ( weight == 50 )
return QStringLiteral(
"normal" );
117 if ( weight == 75 )
return QStringLiteral(
"bold" );
121 if ( weight < 0 )
return QStringLiteral(
"100" );
122 if ( weight > 99 )
return QStringLiteral(
"900" );
123 return QString::number( weight * 800 / 99 + 100 );
129 int weight = str.toInt( &ok );
131 return static_cast< int >( QFont::Normal );
135 if ( weight > 900 )
return 99;
136 if ( weight < 100 )
return 0;
137 return ( weight - 100 ) * 99 / 800;
145 return QStringLiteral(
"no" );
147 return QStringLiteral(
"solid" );
149 return QStringLiteral(
"dash" );
151 return QStringLiteral(
"dot" );
152 case Qt::DashDotLine:
153 return QStringLiteral(
"dash dot" );
154 case Qt::DashDotDotLine:
155 return QStringLiteral(
"dash dot dot" );
157 return QStringLiteral(
"???" );
163 if ( str == QLatin1String(
"no" ) )
return Qt::NoPen;
164 if ( str == QLatin1String(
"solid" ) )
return Qt::SolidLine;
165 if ( str == QLatin1String(
"dash" ) )
return Qt::DashLine;
166 if ( str == QLatin1String(
"dot" ) )
return Qt::DotLine;
167 if ( str == QLatin1String(
"dash dot" ) )
return Qt::DashDotLine;
168 if ( str == QLatin1String(
"dash dot dot" ) )
return Qt::DashDotDotLine;
169 return Qt::SolidLine;
177 return QStringLiteral(
"bevel" );
179 return QStringLiteral(
"miter" );
181 return QStringLiteral(
"round" );
183 return QStringLiteral(
"???" );
189 if ( str == QLatin1String(
"bevel" ) )
return Qt::BevelJoin;
190 if ( str == QLatin1String(
"miter" ) )
return Qt::MiterJoin;
191 if ( str == QLatin1String(
"round" ) )
return Qt::RoundJoin;
192 return Qt::BevelJoin;
200 return QStringLiteral(
"bevel" );
202 return QStringLiteral(
"mitre" );
204 return QStringLiteral(
"round" );
212 if ( str == QLatin1String(
"bevel" ) )
return Qt::BevelJoin;
213 if ( str == QLatin1String(
"mitre" ) )
return Qt::MiterJoin;
214 if ( str == QLatin1String(
"round" ) )
return Qt::RoundJoin;
215 return Qt::BevelJoin;
223 return QStringLiteral(
"square" );
225 return QStringLiteral(
"flat" );
227 return QStringLiteral(
"round" );
229 return QStringLiteral(
"???" );
235 if ( str == QLatin1String(
"square" ) )
return Qt::SquareCap;
236 if ( str == QLatin1String(
"flat" ) )
return Qt::FlatCap;
237 if ( str == QLatin1String(
"round" ) )
return Qt::RoundCap;
238 return Qt::SquareCap;
246 return QStringLiteral(
"square" );
248 return QStringLiteral(
"butt" );
250 return QStringLiteral(
"round" );
258 if ( str == QLatin1String(
"square" ) )
return Qt::SquareCap;
259 if ( str == QLatin1String(
"butt" ) )
return Qt::FlatCap;
260 if ( str == QLatin1String(
"round" ) )
return Qt::RoundCap;
261 return Qt::SquareCap;
268 case Qt::SolidPattern :
269 return QStringLiteral(
"solid" );
270 case Qt::HorPattern :
271 return QStringLiteral(
"horizontal" );
272 case Qt::VerPattern :
273 return QStringLiteral(
"vertical" );
274 case Qt::CrossPattern :
275 return QStringLiteral(
"cross" );
276 case Qt::BDiagPattern :
277 return QStringLiteral(
"b_diagonal" );
278 case Qt::FDiagPattern :
279 return QStringLiteral(
"f_diagonal" );
280 case Qt::DiagCrossPattern :
281 return QStringLiteral(
"diagonal_x" );
282 case Qt::Dense1Pattern :
283 return QStringLiteral(
"dense1" );
284 case Qt::Dense2Pattern :
285 return QStringLiteral(
"dense2" );
286 case Qt::Dense3Pattern :
287 return QStringLiteral(
"dense3" );
288 case Qt::Dense4Pattern :
289 return QStringLiteral(
"dense4" );
290 case Qt::Dense5Pattern :
291 return QStringLiteral(
"dense5" );
292 case Qt::Dense6Pattern :
293 return QStringLiteral(
"dense6" );
294 case Qt::Dense7Pattern :
295 return QStringLiteral(
"dense7" );
297 return QStringLiteral(
"no" );
299 return QStringLiteral(
"???" );
305 if ( str == QLatin1String(
"solid" ) )
return Qt::SolidPattern;
306 if ( str == QLatin1String(
"horizontal" ) )
return Qt::HorPattern;
307 if ( str == QLatin1String(
"vertical" ) )
return Qt::VerPattern;
308 if ( str == QLatin1String(
"cross" ) )
return Qt::CrossPattern;
309 if ( str == QLatin1String(
"b_diagonal" ) )
return Qt::BDiagPattern;
310 if ( str == QLatin1String(
"f_diagonal" ) )
return Qt::FDiagPattern;
311 if ( str == QLatin1String(
"diagonal_x" ) )
return Qt::DiagCrossPattern;
312 if ( str == QLatin1String(
"dense1" ) )
return Qt::Dense1Pattern;
313 if ( str == QLatin1String(
"dense2" ) )
return Qt::Dense2Pattern;
314 if ( str == QLatin1String(
"dense3" ) )
return Qt::Dense3Pattern;
315 if ( str == QLatin1String(
"dense4" ) )
return Qt::Dense4Pattern;
316 if ( str == QLatin1String(
"dense5" ) )
return Qt::Dense5Pattern;
317 if ( str == QLatin1String(
"dense6" ) )
return Qt::Dense6Pattern;
318 if ( str == QLatin1String(
"dense7" ) )
return Qt::Dense7Pattern;
319 if ( str == QLatin1String(
"no" ) )
return Qt::NoBrush;
320 return Qt::SolidPattern;
327 case Qt::CrossPattern:
328 return QStringLiteral(
"cross" );
329 case Qt::DiagCrossPattern:
330 return QStringLiteral(
"x" );
337 return QStringLiteral(
"horline" );
339 return QStringLiteral(
"line" );
340 case Qt::BDiagPattern:
341 return QStringLiteral(
"slash" );
342 case Qt::FDiagPattern:
343 return QStringLiteral(
"backslash" );
346 case Qt::Dense1Pattern:
347 case Qt::Dense2Pattern:
348 case Qt::Dense3Pattern:
349 case Qt::Dense4Pattern:
350 case Qt::Dense5Pattern:
351 case Qt::Dense6Pattern:
352 case Qt::Dense7Pattern:
362 if ( str == QLatin1String(
"horline" ) )
return Qt::HorPattern;
363 if ( str == QLatin1String(
"line" ) )
return Qt::VerPattern;
364 if ( str == QLatin1String(
"cross" ) )
return Qt::CrossPattern;
365 if ( str == QLatin1String(
"slash" ) )
return Qt::BDiagPattern;
366 if ( str == QLatin1String(
"backshash" ) )
return Qt::FDiagPattern;
367 if ( str == QLatin1String(
"x" ) )
return Qt::DiagCrossPattern;
369 if ( str.startsWith( QLatin1String(
"brush://" ) ) )
381 QString s = value.toString().toLower().trimmed();
382 if ( s == QLatin1String(
"single" ) )
384 else if ( s == QLatin1String(
"reversed" ) )
386 else if ( s == QLatin1String(
"double" ) )
388 else if ( value.toInt() == 1 )
390 else if ( value.toInt() == 2 )
392 else if ( value.toInt( &intOk ) == 0 && intOk )
406 QString s = value.toString().toLower().trimmed();
407 if ( s == QLatin1String(
"plain" ) )
409 else if ( s == QLatin1String(
"lefthalf" ) )
411 else if ( s == QLatin1String(
"righthalf" ) )
413 else if ( value.toInt() == 1 )
415 else if ( value.toInt() == 2 )
417 else if ( value.toInt( &intOk ) == 0 && intOk )
432 QStringList lst = str.split(
',' );
433 if ( lst.count() != 2 )
434 return QPointF( 0, 0 );
435 return QPointF( lst[0].toDouble(), lst[1].toDouble() );
445 QStringList lst =
string.split(
',' );
446 if ( lst.count() != 2 )
447 return QSizeF( 0, 0 );
448 return QSizeF( lst[0].toDouble(), lst[1].toDouble() );
465 if ( str.startsWith( QLatin1String(
"3x:" ) ) )
468 QString chopped = str.mid( 3 );
469 lst = chopped.split(
',' );
473 lst = str.split(
',' );
475 if ( lst.count() < 2 )
478 double minScale = lst[0].toDouble();
480 minScale = minScale != 0 ? 1.0 / minScale : 0;
481 double maxScale = lst[1].toDouble();
483 maxScale = maxScale != 0 ? 1.0 / maxScale : 0;
485 if ( lst.count() < 6 )
505 *scaleFactor = 0.001;
506 return QStringLiteral(
"http://www.opengeospatial.org/se/units/metre" );
513 *scaleFactor = 1 / 0.28;
522 if ( str == QLatin1String(
"http://www.opengeospatial.org/se/units/metre" ) )
525 *scaleFactor = 1000.0;
528 else if ( str == QLatin1String(
"http://www.opengeospatial.org/se/units/foot" ) )
531 *scaleFactor = 304.8;
538 *scaleFactor = 1 / 0.00028;
544 QString vectorString;
545 QVector<qreal>::const_iterator it = v.constBegin();
546 for ( ; it != v.constEnd(); ++it )
548 if ( it != v.constBegin() )
550 vectorString.append(
';' );
552 vectorString.append( QString::number( *it ) );
559 QVector<qreal> resultVector;
561 QStringList realList = s.split(
';' );
562 QStringList::const_iterator it = realList.constBegin();
563 for ( ; it != realList.constEnd(); ++it )
565 resultVector.append( it->toDouble() );
573 QString vectorString;
574 QVector<qreal>::const_iterator it = v.constBegin();
575 for ( ; it != v.constEnd(); ++it )
577 if ( it != v.constBegin() )
579 vectorString.append(
' ' );
581 vectorString.append( QString::number( *it ) );
588 QVector<qreal> resultVector;
590 QStringList realList = s.split(
' ' );
591 QStringList::const_iterator it = realList.constBegin();
592 for ( ; it != realList.constEnd(); ++it )
594 resultVector.append( it->toDouble() );
602 QString encodedValue;
604 switch ( scaleMethod )
607 encodedValue = QStringLiteral(
"diameter" );
610 encodedValue = QStringLiteral(
"area" );
620 if ( str == QLatin1String(
"diameter" ) )
634 if ( s.compare( QLatin1String(
"Lighten" ), Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_Lighten;
635 if ( s.compare( QLatin1String(
"Screen" ), Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_Screen;
636 if ( s.compare( QLatin1String(
"Dodge" ), Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_ColorDodge;
637 if ( s.compare( QLatin1String(
"Addition" ), Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_Plus;
638 if ( s.compare( QLatin1String(
"Darken" ), Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_Darken;
639 if ( s.compare( QLatin1String(
"Multiply" ), Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_Multiply;
640 if ( s.compare( QLatin1String(
"Burn" ), Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_ColorBurn;
641 if ( s.compare( QLatin1String(
"Overlay" ), Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_Overlay;
642 if ( s.compare( QLatin1String(
"SoftLight" ), Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_SoftLight;
643 if ( s.compare( QLatin1String(
"HardLight" ), Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_HardLight;
644 if ( s.compare( QLatin1String(
"Difference" ), Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_Difference;
645 if ( s.compare( QLatin1String(
"Subtract" ), Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_Exclusion;
646 return QPainter::CompositionMode_SourceOver;
657 QPixmap pixmap( size );
658 pixmap.fill( Qt::transparent );
660 painter.begin( &pixmap );
661 painter.setRenderHint( QPainter::Antialiasing );
670 size.setWidth( size.rwidth() - ( padding * 2 ) );
671 size.setHeight( size.rheight() - ( padding * 2 ) );
672 painter.translate( padding, padding );
682 std::unique_ptr<QgsSymbol> symbol_noDD( symbol->
clone( ) );
684 for (
const auto &layer : layers )
686 for (
int i = 0; i < layer->dataDefinedProperties().count(); ++i )
688 QgsProperty &prop = layer->dataDefinedProperties().property( i );
694 symbol_noDD->drawPreviewIcon( &painter, size, customContext );
698 std::unique_ptr<QgsSymbol> symbolClone( symbol->
clone( ) );
699 symbolClone->drawPreviewIcon( &painter, size, customContext );
713 maxBleed = layerMaxBleed > maxBleed ? layerMaxBleed : maxBleed;
723 painter.begin( &picture );
724 painter.setRenderHint( QPainter::Antialiasing );
728 std::unique_ptr< QgsSymbolLayer > layerClone( layer->
clone() );
729 layerClone->drawPreviewIcon( symbolContext, size );
736 QPixmap pixmap( size );
737 pixmap.fill( Qt::transparent );
739 painter.begin( &pixmap );
740 painter.setRenderHint( QPainter::Antialiasing );
748 std::unique_ptr< QgsSymbolLayer > layerClone( layer->
clone() );
749 layerClone->drawPreviewIcon( symbolContext, size );
751 return QIcon( pixmap );
761 QPixmap pixmap( size );
762 pixmap.fill( Qt::transparent );
765 painter.begin( &pixmap );
768 drawStippledBackground( &painter, QRect( padding, padding, size.width() - padding * 2, size.height() - padding * 2 ) );
772 for (
int i = 0; i < size.width(); i++ )
774 QPen pen( ramp->
color( static_cast< double >( i ) / size.width() ) );
775 painter.setPen( pen );
776 painter.drawLine( i, 0 + padding, i, size.height() - 1 - padding );
785 uchar pixDataRGB[] = { 255, 255, 255, 255,
790 QImage img( pixDataRGB, 2, 2, 8, QImage::Format_ARGB32 );
792 int width = ( rect.width() < rect.height() ) ?
793 rect.width() / 2.5 : rect.height() / 2.5;
794 QPixmap pix = QPixmap::fromImage( img.scaled( width, width ) );
797 brush.setTexture( pix );
798 painter->fillRect( rect, brush );
803 qreal s = ( markerSize - 1 ) / 2.0;
808 p.setPen( QColor( 50, 100, 120, 200 ) );
809 p.setBrush( QColor( 200, 200, 210, 120 ) );
810 p.drawEllipse( x - s, y - s, s * 2, s * 2 );
813 p.setPen( QColor( 255, 0, 0 ) );
814 p.drawLine( x - s, y + s, x + s, y - s );
815 p.drawLine( x - s, y - s, x + s, y + s );
827 static QPolygonF makeOffsetGeometry(
const QgsPolylineXY &polyline )
829 int i, pointCount = polyline.count();
831 QPolygonF resultLine;
832 resultLine.resize( pointCount );
836 for ( i = 0; i < pointCount; ++i, tempPtr++ )
837 resultLine[i] = QPointF( tempPtr->
x(), tempPtr->
y() );
841 static QList<QPolygonF> makeOffsetGeometry(
const QgsPolygonXY &polygon )
843 QList<QPolygonF> resultGeom;
844 resultGeom.reserve( polygon.size() );
845 for (
int ring = 0; ring < polygon.size(); ++ring )
846 resultGeom.append( makeOffsetGeometry( polygon[ ring ] ) );
852 QList<QPolygonF> resultLine;
854 if ( polyline.count() < 2 )
856 resultLine.append( polyline );
860 unsigned int i, pointCount = polyline.count();
863 QPointF *tempPtr = polyline.data();
864 for ( i = 0; i < pointCount; ++i, tempPtr++ )
865 tempPolyline[i] =
QgsPointXY( tempPtr->rx(), tempPtr->ry() );
868 if ( !tempGeometry.
isNull() )
870 int quadSegments = 0;
871 double miterLimit = 2.0;
879 if ( !offsetGeom.
isNull() )
881 tempGeometry = offsetGeom;
886 resultLine.append( makeOffsetGeometry( line ) );
891 resultLine.append( makeOffsetGeometry( tempGeometry.
asPolygon() ) );
897 resultLine.reserve( tempMPolyline.count() );
898 for (
int part = 0; part < tempMPolyline.count(); ++part )
900 resultLine.append( makeOffsetGeometry( tempMPolyline[ part ] ) );
907 resultLine.reserve( tempMPolygon.count() );
908 for (
int part = 0; part < tempMPolygon.count(); ++part )
910 resultLine.append( makeOffsetGeometry( tempMPolygon[ part ] ) );
918 resultLine.append( polyline );
928 QDomNode layerNode = element.firstChild();
930 while ( !layerNode.isNull() )
932 QDomElement e = layerNode.toElement();
935 if ( e.tagName() != QLatin1String(
"layer" ) )
946 QDomElement s = e.firstChildElement( QStringLiteral(
"symbol" ) );
953 QgsDebugMsg(
"symbol layer refused subsymbol: " + s.attribute(
"name" ) );
956 layers.append( layer );
960 layerNode = layerNode.nextSibling();
963 if ( layers.isEmpty() )
965 QgsDebugMsg( QStringLiteral(
"no layers for symbol" ) );
969 QString symbolType = element.attribute( QStringLiteral(
"type" ) );
972 if ( symbolType == QLatin1String(
"line" ) )
974 else if ( symbolType == QLatin1String(
"fill" ) )
976 else if ( symbolType == QLatin1String(
"marker" ) )
980 QgsDebugMsg(
"unknown symbol type " + symbolType );
984 if ( element.hasAttribute( QStringLiteral(
"outputUnit" ) ) )
988 if ( element.hasAttribute( ( QStringLiteral(
"mapUnitScale" ) ) ) )
991 double oldMin = element.attribute( QStringLiteral(
"mapUnitMinScale" ), QStringLiteral(
"0.0" ) ).toDouble();
992 mapUnitScale.
minScale = oldMin != 0 ? 1.0 / oldMin : 0;
993 double oldMax = element.attribute( QStringLiteral(
"mapUnitMaxScale" ), QStringLiteral(
"0.0" ) ).toDouble();
994 mapUnitScale.
maxScale = oldMax != 0 ? 1.0 / oldMax : 0;
997 symbol->
setOpacity( element.attribute( QStringLiteral(
"alpha" ), QStringLiteral(
"1.0" ) ).toDouble() );
998 symbol->
setClipFeaturesToExtent( element.attribute( QStringLiteral(
"clip_to_extent" ), QStringLiteral(
"1" ) ).toInt() );
999 symbol->
setForceRHR( element.attribute( QStringLiteral(
"force_rhr" ), QStringLiteral(
"0" ) ).toInt() );
1005 QString layerClass = element.attribute( QStringLiteral(
"class" ) );
1006 bool locked = element.attribute( QStringLiteral(
"locked" ) ).toInt();
1007 bool enabled = element.attribute( QStringLiteral(
"enabled" ), QStringLiteral(
"1" ) ).toInt();
1008 int pass = element.attribute( QStringLiteral(
"pass" ) ).toInt();
1025 QDomElement effectElem = element.firstChildElement( QStringLiteral(
"effect" ) );
1026 if ( !effectElem.isNull() )
1032 QDomElement ddProps = element.firstChildElement( QStringLiteral(
"data_defined_properties" ) );
1033 if ( !ddProps.isNull() )
1052 return QStringLiteral(
"line" );
1054 return QStringLiteral(
"marker" );
1056 return QStringLiteral(
"fill" );
1065 QDomElement symEl = doc.createElement( QStringLiteral(
"symbol" ) );
1066 symEl.setAttribute( QStringLiteral(
"type" ), _nameForSymbolType( symbol->
type() ) );
1067 symEl.setAttribute( QStringLiteral(
"name" ), name );
1068 symEl.setAttribute( QStringLiteral(
"alpha" ), QString::number( symbol->
opacity() ) );
1069 symEl.setAttribute( QStringLiteral(
"clip_to_extent" ), symbol->
clipFeaturesToExtent() ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
1070 symEl.setAttribute( QStringLiteral(
"force_rhr" ), symbol->
forceRHR() ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
1077 QDomElement layerEl = doc.createElement( QStringLiteral(
"layer" ) );
1078 layerEl.setAttribute( QStringLiteral(
"class" ), layer->
layerType() );
1079 layerEl.setAttribute( QStringLiteral(
"enabled" ), layer->
enabled() );
1080 layerEl.setAttribute( QStringLiteral(
"locked" ), layer->
isLocked() );
1081 layerEl.setAttribute( QStringLiteral(
"pass" ), layer->
renderingPass() );
1092 QDomElement ddProps = doc.createElement( QStringLiteral(
"data_defined_properties" ) );
1094 layerEl.appendChild( ddProps );
1098 QString subname = QStringLiteral(
"@%1@%2" ).arg( name ).arg( i );
1100 layerEl.appendChild( subEl );
1102 symEl.appendChild( layerEl );
1110 QDomDocument doc( QStringLiteral(
"qgis-symbol-definition" ) );
1113 QTextStream stream( &props );
1114 symbolElem.save( stream, -1 );
1124 if ( element.isNull() )
1129 QString symbolizerName = element.localName();
1131 if ( symbolizerName == QLatin1String(
"PointSymbolizer" ) )
1134 QDomElement graphicElem = element.firstChildElement( QStringLiteral(
"Graphic" ) );
1135 if ( graphicElem.isNull() )
1137 QgsDebugMsg( QStringLiteral(
"Graphic element not found in PointSymbolizer" ) );
1173 if ( symbolizerName == QLatin1String(
"LineSymbolizer" ) )
1176 QDomElement strokeElem = element.firstChildElement( QStringLiteral(
"Stroke" ) );
1177 if ( strokeElem.isNull() )
1179 QgsDebugMsg( QStringLiteral(
"Stroke element not found in LineSymbolizer" ) );
1209 if ( symbolizerName == QLatin1String(
"PolygonSymbolizer" ) )
1212 QDomElement fillElem = element.firstChildElement( QStringLiteral(
"Fill" ) );
1213 QDomElement strokeElem = element.firstChildElement( QStringLiteral(
"Stroke" ) );
1214 if ( fillElem.isNull() && strokeElem.isNull() )
1216 QgsDebugMsg( QStringLiteral(
"neither Fill nor Stroke element not found in PolygonSymbolizer" ) );
1234 if ( l->
layerType() == QLatin1String(
"SimpleFill" ) || l->
layerType() == QLatin1String(
"SVGFill" ) )
1270 QDomElement fillElem = element.firstChildElement( QStringLiteral(
"Fill" ) );
1271 if ( fillElem.isNull() )
1273 QgsDebugMsg( QStringLiteral(
"Fill element not found" ) );
1293 QDomElement strokeElem = element.firstChildElement( QStringLiteral(
"Stroke" ) );
1294 if ( strokeElem.isNull() )
1296 QgsDebugMsg( QStringLiteral(
"Stroke element not found" ) );
1312 QDomElement graphicElem = element.firstChildElement( QStringLiteral(
"Graphic" ) );
1313 if ( graphicElem.isNull() )
1315 QgsDebugMsg( QStringLiteral(
"Graphic element not found" ) );
1335 QDomElement graphicElem = element.firstChildElement( QStringLiteral(
"Graphic" ) );
1336 if ( graphicElem.isNull() )
1339 QDomElement externalGraphicElem = graphicElem.firstChildElement( QStringLiteral(
"ExternalGraphic" ) );
1340 if ( externalGraphicElem.isNull() )
1344 QDomElement formatElem = externalGraphicElem.firstChildElement( QStringLiteral(
"Format" ) );
1345 if ( formatElem.isNull() )
1348 QString format = formatElem.firstChild().nodeValue();
1349 if ( format != QLatin1String(
"image/svg+xml" ) )
1351 QgsDebugMsg(
"unsupported External Graphic format found: " + format );
1356 QDomElement onlineResourceElem = externalGraphicElem.firstChildElement( QStringLiteral(
"OnlineResource" ) );
1357 QDomElement inlineContentElem = externalGraphicElem.firstChildElement( QStringLiteral(
"InlineContent" ) );
1358 if ( !onlineResourceElem.isNull() )
1363 else if ( !inlineContentElem.isNull() )
1376 QDomElement graphicElem = element.firstChildElement( QStringLiteral(
"Graphic" ) );
1377 if ( graphicElem.isNull() )
1380 QDomElement markElem = graphicElem.firstChildElement( QStringLiteral(
"Mark" ) );
1381 if ( markElem.isNull() )
1384 QDomElement wellKnownNameElem = markElem.firstChildElement( QStringLiteral(
"WellKnownName" ) );
1385 return !wellKnownNameElem.isNull();
1391 QDomElement graphicElem = element.firstChildElement( QStringLiteral(
"Graphic" ) );
1392 if ( graphicElem.isNull() )
1395 QDomElement markElem = graphicElem.firstChildElement( QStringLiteral(
"Mark" ) );
1396 if ( markElem.isNull() )
1400 QDomElement formatElem = markElem.firstChildElement( QStringLiteral(
"Format" ) );
1401 if ( formatElem.isNull() )
1404 QString format = formatElem.firstChild().nodeValue();
1405 if ( format != QLatin1String(
"ttf" ) )
1407 QgsDebugMsg(
"unsupported Graphic Mark format found: " + format );
1412 QDomElement onlineResourceElem = markElem.firstChildElement( QStringLiteral(
"OnlineResource" ) );
1413 QDomElement inlineContentElem = markElem.firstChildElement( QStringLiteral(
"InlineContent" ) );
1414 if ( !onlineResourceElem.isNull() )
1417 QDomElement markIndexElem = markElem.firstChildElement( QStringLiteral(
"MarkIndex" ) );
1418 if ( !markIndexElem.isNull() )
1421 else if ( !inlineContentElem.isNull() )
1436 QDomElement graphicElem = element.firstChildElement( QStringLiteral(
"Graphic" ) );
1437 if ( graphicElem.isNull() )
1441 for ( QgsStringMap::iterator it = vendorOptions.begin(); it != vendorOptions.end(); ++it )
1443 if ( it.key() == QLatin1String(
"widthHeightFactor" ) )
1454 QDomElement strokeElem = element.firstChildElement( QStringLiteral(
"Stroke" ) );
1455 if ( strokeElem.isNull() )
1458 QDomElement graphicStrokeElem = strokeElem.firstChildElement( QStringLiteral(
"GraphicStroke" ) );
1459 if ( graphicStrokeElem.isNull() )
1467 QDomElement fillElem = element.firstChildElement( QStringLiteral(
"Fill" ) );
1468 if ( fillElem.isNull() )
1471 QDomElement graphicFillElem = fillElem.firstChildElement( QStringLiteral(
"GraphicFill" ) );
1472 if ( graphicFillElem.isNull() )
1475 QDomElement graphicElem = graphicFillElem.firstChildElement( QStringLiteral(
"Graphic" ) );
1476 if ( graphicElem.isNull() )
1482 QColor fillColor, strokeColor;
1483 double size, strokeWidth;
1484 Qt::PenStyle strokeStyle;
1485 if ( !
wellKnownMarkerFromSld( graphicElem, name, fillColor, strokeColor, strokeStyle, strokeWidth, size ) )
1488 if ( name != QLatin1String(
"horline" ) )
1496 double angle = angleFunc.toDouble( &ok );
1502 Q_UNUSED( element );
1508 QDomElement fillElem = element.firstChildElement( QStringLiteral(
"Fill" ) );
1509 if ( fillElem.isNull() )
1512 QDomElement graphicFillElem = fillElem.firstChildElement( QStringLiteral(
"GraphicFill" ) );
1513 if ( graphicFillElem.isNull() )
1533 QDomElement fillElem = element.firstChildElement( QStringLiteral(
"Fill" ) );
1534 QDomElement strokeElem = element.firstChildElement( QStringLiteral(
"Stroke" ) );
1538 bool validFill =
false, validStroke =
false;
1543 Qt::BrushStyle fillStyle;
1545 if (
fillFromSld( fillElem, fillStyle, fillColor ) )
1551 Qt::PenStyle strokeStyle;
1552 double strokeWidth = 1.0, dashOffset = 0.0;
1553 QVector<qreal> customDashPattern;
1555 if (
lineFromSld( strokeElem, strokeStyle, strokeColor, strokeWidth,
1556 nullptr,
nullptr, &customDashPattern, &dashOffset ) )
1559 if ( validFill || validStroke )
1562 map[QStringLiteral(
"name" )] = QStringLiteral(
"square" );
1563 map[QStringLiteral(
"color" )] =
encodeColor( validFill ? fillColor : Qt::transparent );
1564 map[QStringLiteral(
"color_border" )] =
encodeColor( validStroke ? strokeColor : Qt::transparent );
1565 map[QStringLiteral(
"size" )] = QString::number( 6 );
1566 map[QStringLiteral(
"angle" )] = QString::number( 0 );
1567 map[QStringLiteral(
"offset" )] =
encodePoint( QPointF( 0, 0 ) );
1574 bool validFill =
false, validStroke =
false;
1577 QString name, format;
1579 QColor fillColor, strokeColor;
1580 double strokeWidth = 1.0, size = 0.0,
angle = 0.0;
1584 QDomElement graphicFillElem = fillElem.firstChildElement( QStringLiteral(
"GraphicFill" ) );
1585 if ( !graphicFillElem.isNull() )
1588 QDomElement graphicElem = graphicFillElem.firstChildElement( QStringLiteral(
"Graphic" ) );
1589 if ( !graphicElem.isNull() )
1595 QDomElement graphicChildElem = graphicElem.firstChildElement();
1596 while ( !graphicChildElem.isNull() )
1598 if ( graphicChildElem.localName() == QLatin1String(
"Mark" ) )
1601 QDomElement wellKnownNameElem = graphicChildElem.firstChildElement( QStringLiteral(
"WellKnownName" ) );
1602 if ( !wellKnownNameElem.isNull() )
1604 name = wellKnownNameElem.firstChild().nodeValue();
1610 if ( graphicChildElem.localName() == QLatin1String(
"ExternalGraphic" ) || graphicChildElem.localName() == QLatin1String(
"Mark" ) )
1613 QDomElement formatElem = graphicChildElem.firstChildElement( QStringLiteral(
"Format" ) );
1614 if ( formatElem.isNull() )
1617 format = formatElem.firstChild().nodeValue();
1621 if ( graphicChildElem.localName() == QLatin1String(
"ExternalGraphic" ) && format != QLatin1String(
"image/svg+xml" ) )
1626 if ( graphicChildElem.localName() == QLatin1String(
"Mark" ) && format != QLatin1String(
"ttf" ) )
1630 QDomElement onlineResourceElem = graphicChildElem.firstChildElement( QStringLiteral(
"OnlineResource" ) );
1631 QDomElement inlineContentElem = graphicChildElem.firstChildElement( QStringLiteral(
"InlineContent" ) );
1633 if ( !onlineResourceElem.isNull() )
1635 name = onlineResourceElem.attributeNS( QStringLiteral(
"http://www.w3.org/1999/xlink" ), QStringLiteral(
"href" ) );
1637 if ( graphicChildElem.localName() == QLatin1String(
"Mark" ) && format == QLatin1String(
"ttf" ) )
1640 if ( name.startsWith( QLatin1String(
"ttf://" ) ) )
1641 name = name.mid( 6 );
1644 QDomElement markIndexElem = graphicChildElem.firstChildElement( QStringLiteral(
"MarkIndex" ) );
1645 if ( markIndexElem.isNull() )
1649 int v = markIndexElem.firstChild().nodeValue().toInt( &ok );
1660 else if ( !inlineContentElem.isNull() )
1670 if ( graphicChildElem.localName() == QLatin1String(
"Mark" ) )
1672 name = QStringLiteral(
"square" );
1679 if ( found && graphicChildElem.localName() == QLatin1String(
"Mark" ) )
1686 Qt::BrushStyle markFillStyle;
1688 QDomElement markFillElem = graphicChildElem.firstChildElement( QStringLiteral(
"Fill" ) );
1689 if (
fillFromSld( markFillElem, markFillStyle, fillColor ) )
1694 Qt::PenStyle strokeStyle;
1695 double strokeWidth = 1.0, dashOffset = 0.0;
1696 QVector<qreal> customDashPattern;
1698 QDomElement markStrokeElem = graphicChildElem.firstChildElement( QStringLiteral(
"Stroke" ) );
1699 if (
lineFromSld( markStrokeElem, strokeStyle, strokeColor, strokeWidth,
1700 nullptr,
nullptr, &customDashPattern, &dashOffset ) )
1707 QDomElement opacityElem = graphicElem.firstChildElement( QStringLiteral(
"Opacity" ) );
1708 if ( !opacityElem.isNull() )
1709 fillColor.setAlpha(
decodeSldAlpha( opacityElem.firstChild().nodeValue() ) );
1711 QDomElement sizeElem = graphicElem.firstChildElement( QStringLiteral(
"Size" ) );
1712 if ( !sizeElem.isNull() )
1715 double v = sizeElem.firstChild().nodeValue().toDouble( &ok );
1724 double v = angleFunc.toDouble( &ok );
1734 if ( validFill || validStroke )
1736 if ( format == QLatin1String(
"image/svg+xml" ) )
1739 map[QStringLiteral(
"name" )] = name;
1740 map[QStringLiteral(
"fill" )] = fillColor.name();
1741 map[QStringLiteral(
"outline" )] = strokeColor.name();
1742 map[QStringLiteral(
"outline-width" )] = QString::number( strokeWidth );
1744 map[QStringLiteral(
"size" )] = QString::number( size );
1746 map[QStringLiteral(
"angle" )] = QString::number(
angle );
1747 if ( !offset.isNull() )
1748 map[QStringLiteral(
"offset" )] =
encodePoint( offset );
1751 else if ( format == QLatin1String(
"ttf" ) )
1754 map[QStringLiteral(
"font" )] = name;
1755 map[QStringLiteral(
"chr" )] = markIndex;
1756 map[QStringLiteral(
"color" )] =
encodeColor( validFill ? fillColor : Qt::transparent );
1758 map[QStringLiteral(
"size" )] = QString::number( size );
1760 map[QStringLiteral(
"angle" )] = QString::number(
angle );
1761 if ( !offset.isNull() )
1762 map[QStringLiteral(
"offset" )] =
encodePoint( offset );
1768 if ( layers.isEmpty() )
1771 layerList << layers;
1778 QString patternName;
1779 switch ( brushStyle )
1784 case Qt::SolidPattern:
1785 if ( color.isValid() )
1788 if ( color.alpha() < 255 )
1793 case Qt::CrossPattern:
1794 case Qt::DiagCrossPattern:
1795 case Qt::HorPattern:
1796 case Qt::VerPattern:
1797 case Qt::BDiagPattern:
1798 case Qt::FDiagPattern:
1799 case Qt::Dense1Pattern:
1800 case Qt::Dense2Pattern:
1801 case Qt::Dense3Pattern:
1802 case Qt::Dense4Pattern:
1803 case Qt::Dense5Pattern:
1804 case Qt::Dense6Pattern:
1805 case Qt::Dense7Pattern:
1810 element.appendChild( doc.createComment( QStringLiteral(
"Qt::BrushStyle '%1'' not supported yet" ).arg( brushStyle ) ) );
1814 QDomElement graphicFillElem = doc.createElement( QStringLiteral(
"se:GraphicFill" ) );
1815 element.appendChild( graphicFillElem );
1817 QDomElement graphicElem = doc.createElement( QStringLiteral(
"se:Graphic" ) );
1818 graphicFillElem.appendChild( graphicElem );
1820 QColor fillColor = patternName.startsWith( QLatin1String(
"brush://" ) ) ? color : QColor();
1821 QColor strokeColor = !patternName.startsWith( QLatin1String(
"brush://" ) ) ? color : QColor();
1824 wellKnownMarkerToSld( doc, graphicElem, patternName, fillColor, strokeColor, Qt::SolidLine, -1, -1 );
1831 brushStyle = Qt::SolidPattern;
1832 color = QColor( 128, 128, 128 );
1834 if ( element.isNull() )
1836 brushStyle = Qt::NoBrush;
1841 QDomElement graphicFillElem = element.firstChildElement( QStringLiteral(
"GraphicFill" ) );
1843 if ( graphicFillElem.isNull() )
1846 for ( QgsStringMap::iterator it = svgParams.begin(); it != svgParams.end(); ++it )
1848 QgsDebugMsg( QStringLiteral(
"found SvgParameter %1: %2" ).arg( it.key(), it.value() ) );
1850 if ( it.key() == QLatin1String(
"fill" ) )
1851 color = QColor( it.value() );
1852 else if ( it.key() == QLatin1String(
"fill-opacity" ) )
1858 QDomElement graphicElem = graphicFillElem.firstChildElement( QStringLiteral(
"Graphic" ) );
1859 if ( graphicElem.isNull() )
1862 QString patternName = QStringLiteral(
"square" );
1863 QColor fillColor, strokeColor;
1864 double strokeWidth, size;
1865 Qt::PenStyle strokeStyle;
1866 if ( !
wellKnownMarkerFromSld( graphicElem, patternName, fillColor, strokeColor, strokeStyle, strokeWidth, size ) )
1870 if ( brushStyle == Qt::NoBrush )
1873 QColor
c = patternName.startsWith( QLatin1String(
"brush://" ) ) ? fillColor : strokeColor;
1882 Qt::PenStyle penStyle,
const QColor &color,
double width,
1883 const Qt::PenJoinStyle *penJoinStyle,
const Qt::PenCapStyle *penCapStyle,
1884 const QVector<qreal> *customDashPattern,
double dashOffset )
1886 QVector<qreal> dashPattern;
1887 const QVector<qreal> *pattern = &dashPattern;
1889 if ( penStyle == Qt::CustomDashLine && !customDashPattern )
1891 element.appendChild( doc.createComment( QStringLiteral(
"WARNING: Custom dash pattern required but not provided. Using default dash pattern." ) ) );
1892 penStyle = Qt::DashLine;
1904 dashPattern.push_back( 4.0 );
1905 dashPattern.push_back( 2.0 );
1908 dashPattern.push_back( 1.0 );
1909 dashPattern.push_back( 2.0 );
1911 case Qt::DashDotLine:
1912 dashPattern.push_back( 4.0 );
1913 dashPattern.push_back( 2.0 );
1914 dashPattern.push_back( 1.0 );
1915 dashPattern.push_back( 2.0 );
1917 case Qt::DashDotDotLine:
1918 dashPattern.push_back( 4.0 );
1919 dashPattern.push_back( 2.0 );
1920 dashPattern.push_back( 1.0 );
1921 dashPattern.push_back( 2.0 );
1922 dashPattern.push_back( 1.0 );
1923 dashPattern.push_back( 2.0 );
1926 case Qt::CustomDashLine:
1927 Q_ASSERT( customDashPattern );
1928 pattern = customDashPattern;
1932 element.appendChild( doc.createComment( QStringLiteral(
"Qt::BrushStyle '%1'' not supported yet" ).arg( penStyle ) ) );
1936 if ( color.isValid() )
1939 if ( color.alpha() < 255 )
1946 else if ( width == 0 )
1956 if ( !pattern->isEmpty() )
1966 Qt::PenStyle &penStyle, QColor &color,
double &width,
1967 Qt::PenJoinStyle *penJoinStyle, Qt::PenCapStyle *penCapStyle,
1968 QVector<qreal> *customDashPattern,
double *dashOffset )
1972 penStyle = Qt::SolidLine;
1973 color = QColor( 0, 0, 0 );
1976 *penJoinStyle = Qt::BevelJoin;
1978 *penCapStyle = Qt::SquareCap;
1979 if ( customDashPattern )
1980 customDashPattern->clear();
1984 if ( element.isNull() )
1986 penStyle = Qt::NoPen;
1992 for ( QgsStringMap::iterator it = svgParams.begin(); it != svgParams.end(); ++it )
1994 QgsDebugMsg( QStringLiteral(
"found SvgParameter %1: %2" ).arg( it.key(), it.value() ) );
1996 if ( it.key() == QLatin1String(
"stroke" ) )
1998 color = QColor( it.value() );
2000 else if ( it.key() == QLatin1String(
"stroke-opacity" ) )
2004 else if ( it.key() == QLatin1String(
"stroke-width" ) )
2007 double w = it.value().toDouble( &ok );
2011 else if ( it.key() == QLatin1String(
"stroke-linejoin" ) && penJoinStyle )
2015 else if ( it.key() == QLatin1String(
"stroke-linecap" ) && penCapStyle )
2019 else if ( it.key() == QLatin1String(
"stroke-dasharray" ) )
2022 if ( !dashPattern.isEmpty() )
2026 bool dashPatternFound =
false;
2028 if ( dashPattern.count() == 2 )
2030 if ( dashPattern.at( 0 ) == 4.0 &&
2031 dashPattern.at( 1 ) == 2.0 )
2033 penStyle = Qt::DashLine;
2034 dashPatternFound =
true;
2036 else if ( dashPattern.at( 0 ) == 1.0 &&
2037 dashPattern.at( 1 ) == 2.0 )
2039 penStyle = Qt::DotLine;
2040 dashPatternFound =
true;
2043 else if ( dashPattern.count() == 4 )
2045 if ( dashPattern.at( 0 ) == 4.0 &&
2046 dashPattern.at( 1 ) == 2.0 &&
2047 dashPattern.at( 2 ) == 1.0 &&
2048 dashPattern.at( 3 ) == 2.0 )
2050 penStyle = Qt::DashDotLine;
2051 dashPatternFound =
true;
2054 else if ( dashPattern.count() == 6 )
2056 if ( dashPattern.at( 0 ) == 4.0 &&
2057 dashPattern.at( 1 ) == 2.0 &&
2058 dashPattern.at( 2 ) == 1.0 &&
2059 dashPattern.at( 3 ) == 2.0 &&
2060 dashPattern.at( 4 ) == 1.0 &&
2061 dashPattern.at( 5 ) == 2.0 )
2063 penStyle = Qt::DashDotDotLine;
2064 dashPatternFound =
true;
2069 if ( !dashPatternFound )
2071 if ( customDashPattern )
2073 penStyle = Qt::CustomDashLine;
2074 *customDashPattern = dashPattern;
2078 QgsDebugMsg( QStringLiteral(
"custom dash pattern required but not provided. Using default dash pattern." ) );
2079 penStyle = Qt::DashLine;
2084 else if ( it.key() == QLatin1String(
"stroke-dashoffset" ) && dashOffset )
2087 double d = it.value().toDouble( &ok );
2097 const QString &path,
const QString &mime,
2098 const QColor &color,
double size )
2100 QDomElement externalGraphicElem = doc.createElement( QStringLiteral(
"se:ExternalGraphic" ) );
2101 element.appendChild( externalGraphicElem );
2110 QDomElement sizeElem = doc.createElement( QStringLiteral(
"se:Size" ) );
2112 element.appendChild( sizeElem );
2117 const QString &path,
const QColor &fillColor,
double size,
const QColor &strokeColor,
double strokeWidth )
2124 graphicElem.appendChild( doc.createComment( QStringLiteral(
"Parametric SVG" ) ) );
2128 graphicElem.appendChild( doc.createComment( QStringLiteral(
"Plain SVG fallback, no parameters" ) ) );
2131 graphicElem.appendChild( doc.createComment( QStringLiteral(
"Well known marker fallback" ) ) );
2137 QDomElement sizeElem = doc.createElement( QStringLiteral(
"se:Size" ) );
2139 graphicElem.appendChild( sizeElem );
2147 if ( fillColor.isValid() )
2149 url.addQueryItem( QStringLiteral(
"fill" ), fillColor.name() );
2150 url.addQueryItem( QStringLiteral(
"fill-opacity" ),
encodeSldAlpha( fillColor.alpha() ) );
2154 url.addQueryItem( QStringLiteral(
"fill" ), QStringLiteral(
"#000000" ) );
2155 url.addQueryItem( QStringLiteral(
"fill-opacity" ), QStringLiteral(
"1" ) );
2157 if ( strokeColor.isValid() )
2159 url.addQueryItem( QStringLiteral(
"outline" ), strokeColor.name() );
2160 url.addQueryItem( QStringLiteral(
"outline-opacity" ),
encodeSldAlpha( strokeColor.alpha() ) );
2164 url.addQueryItem( QStringLiteral(
"outline" ), QStringLiteral(
"#000000" ) );
2165 url.addQueryItem( QStringLiteral(
"outline-opacity" ), QStringLiteral(
"1" ) );
2167 url.addQueryItem( QStringLiteral(
"outline-width" ), QString::number( strokeWidth ) );
2168 QString params = url.encodedQuery();
2169 if ( params.isEmpty() )
2175 return basePath +
"?" + params;
2180 QString &path, QString &mime,
2181 QColor &color,
double &size )
2186 QDomElement externalGraphicElem = element.firstChildElement( QStringLiteral(
"ExternalGraphic" ) );
2187 if ( externalGraphicElem.isNull() )
2192 QDomElement sizeElem = element.firstChildElement( QStringLiteral(
"Size" ) );
2193 if ( !sizeElem.isNull() )
2196 double s = sizeElem.firstChild().nodeValue().toDouble( &ok );
2205 const QString &path,
const QString &format,
int *markIndex,
2206 const QColor &color,
double size )
2208 QDomElement markElem = doc.createElement( QStringLiteral(
"se:Mark" ) );
2209 element.appendChild( markElem );
2215 QDomElement markIndexElem = doc.createElement( QStringLiteral(
"se:MarkIndex" ) );
2216 markIndexElem.appendChild( doc.createTextNode( QString::number( *markIndex ) ) );
2217 markElem.appendChild( markIndexElem );
2221 QDomElement fillElem = doc.createElement( QStringLiteral(
"se:Fill" ) );
2222 fillToSld( doc, fillElem, Qt::SolidPattern, color );
2223 markElem.appendChild( fillElem );
2228 QDomElement sizeElem = doc.createElement( QStringLiteral(
"se:Size" ) );
2230 element.appendChild( sizeElem );
2235 QString &path, QString &format,
int &markIndex,
2236 QColor &color,
double &size )
2244 QDomElement markElem = element.firstChildElement( QStringLiteral(
"Mark" ) );
2245 if ( markElem.isNull() )
2250 QDomElement markIndexElem = markElem.firstChildElement( QStringLiteral(
"MarkIndex" ) );
2251 if ( !markIndexElem.isNull() )
2254 int i = markIndexElem.firstChild().nodeValue().toInt( &ok );
2260 QDomElement fillElem = markElem.firstChildElement( QStringLiteral(
"Fill" ) );
2261 Qt::BrushStyle b = Qt::SolidPattern;
2266 QDomElement sizeElem = element.firstChildElement( QStringLiteral(
"Size" ) );
2267 if ( !sizeElem.isNull() )
2270 double s = sizeElem.firstChild().nodeValue().toDouble( &ok );
2279 const QString &name,
const QColor &color,
const QColor &strokeColor, Qt::PenStyle strokeStyle,
2280 double strokeWidth,
double size )
2282 QDomElement markElem = doc.createElement( QStringLiteral(
"se:Mark" ) );
2283 element.appendChild( markElem );
2285 QDomElement wellKnownNameElem = doc.createElement( QStringLiteral(
"se:WellKnownName" ) );
2286 wellKnownNameElem.appendChild( doc.createTextNode( name ) );
2287 markElem.appendChild( wellKnownNameElem );
2290 if ( color.isValid() )
2292 QDomElement fillElem = doc.createElement( QStringLiteral(
"se:Fill" ) );
2293 fillToSld( doc, fillElem, Qt::SolidPattern, color );
2294 markElem.appendChild( fillElem );
2298 if ( strokeColor.isValid() )
2300 QDomElement strokeElem = doc.createElement( QStringLiteral(
"se:Stroke" ) );
2301 lineToSld( doc, strokeElem, strokeStyle, strokeColor, strokeWidth );
2302 markElem.appendChild( strokeElem );
2308 QDomElement sizeElem = doc.createElement( QStringLiteral(
"se:Size" ) );
2310 element.appendChild( sizeElem );
2315 QString &name, QColor &color, QColor &strokeColor, Qt::PenStyle &strokeStyle,
2316 double &strokeWidth,
double &size )
2320 name = QStringLiteral(
"square" );
2322 strokeColor = QColor( 0, 0, 0 );
2326 QDomElement markElem = element.firstChildElement( QStringLiteral(
"Mark" ) );
2327 if ( markElem.isNull() )
2330 QDomElement wellKnownNameElem = markElem.firstChildElement( QStringLiteral(
"WellKnownName" ) );
2331 if ( !wellKnownNameElem.isNull() )
2333 name = wellKnownNameElem.firstChild().nodeValue();
2334 QgsDebugMsg(
"found Mark with well known name: " + name );
2338 QDomElement fillElem = markElem.firstChildElement( QStringLiteral(
"Fill" ) );
2339 Qt::BrushStyle b = Qt::SolidPattern;
2344 QDomElement strokeElem = markElem.firstChildElement( QStringLiteral(
"Stroke" ) );
2345 lineFromSld( strokeElem, strokeStyle, strokeColor, strokeWidth );
2349 QDomElement sizeElem = element.firstChildElement( QStringLiteral(
"Size" ) );
2350 if ( !sizeElem.isNull() )
2353 double s = sizeElem.firstChild().nodeValue().toDouble( &ok );
2363 if ( !rotationFunc.isEmpty() )
2365 QDomElement rotationElem = doc.createElement( QStringLiteral(
"se:Rotation" ) );
2367 element.appendChild( rotationElem );
2373 QDomElement rotationElem = element.firstChildElement( QStringLiteral(
"Rotation" ) );
2374 if ( !rotationElem.isNull() )
2384 if ( !alphaFunc.isEmpty() )
2386 QDomElement opacityElem = doc.createElement( QStringLiteral(
"se:Opacity" ) );
2388 element.appendChild( opacityElem );
2394 QDomElement opacityElem = element.firstChildElement( QStringLiteral(
"Opacity" ) );
2395 if ( !opacityElem.isNull() )
2404 if ( offset.isNull() )
2407 QDomElement displacementElem = doc.createElement( QStringLiteral(
"se:Displacement" ) );
2408 element.appendChild( displacementElem );
2410 QDomElement dispXElem = doc.createElement( QStringLiteral(
"se:DisplacementX" ) );
2411 dispXElem.appendChild( doc.createTextNode(
qgsDoubleToString( offset.x(), 2 ) ) );
2413 QDomElement dispYElem = doc.createElement( QStringLiteral(
"se:DisplacementY" ) );
2414 dispYElem.appendChild( doc.createTextNode(
qgsDoubleToString( offset.y(), 2 ) ) );
2416 displacementElem.appendChild( dispXElem );
2417 displacementElem.appendChild( dispYElem );
2424 QDomElement anchorElem = doc.createElement( QStringLiteral(
"se:AnchorPoint" ) );
2425 element.appendChild( anchorElem );
2427 QDomElement anchorXElem = doc.createElement( QStringLiteral(
"se:AnchorPointX" ) );
2428 anchorXElem.appendChild( doc.createTextNode(
qgsDoubleToString( anchor.x() ) ) );
2430 QDomElement anchorYElem = doc.createElement( QStringLiteral(
"se:AnchorPointY" ) );
2431 anchorYElem.appendChild( doc.createTextNode(
qgsDoubleToString( anchor.y() ) ) );
2433 anchorElem.appendChild( anchorXElem );
2434 anchorElem.appendChild( anchorYElem );
2439 offset = QPointF( 0, 0 );
2441 QDomElement displacementElem = element.firstChildElement( QStringLiteral(
"Displacement" ) );
2442 if ( displacementElem.isNull() )
2445 QDomElement dispXElem = displacementElem.firstChildElement( QStringLiteral(
"DisplacementX" ) );
2446 if ( !dispXElem.isNull() )
2449 double offsetX = dispXElem.firstChild().nodeValue().toDouble( &ok );
2451 offset.setX( offsetX );
2454 QDomElement dispYElem = displacementElem.firstChildElement( QStringLiteral(
"DisplacementY" ) );
2455 if ( !dispYElem.isNull() )
2458 double offsetY = dispYElem.firstChild().nodeValue().toDouble( &ok );
2460 offset.setY( offsetY );
2467 const QString &label,
const QFont &font,
2468 const QColor &color,
double size )
2470 QDomElement labelElem = doc.createElement( QStringLiteral(
"se:Label" ) );
2471 labelElem.appendChild( doc.createTextNode( label ) );
2472 element.appendChild( labelElem );
2474 QDomElement fontElem = doc.createElement( QStringLiteral(
"se:Font" ) );
2475 element.appendChild( fontElem );
2479 fontElem.appendChild( createSldParameterElement( doc,
"font-style",
encodeSldFontStyle( font.style() ) ) );
2480 fontElem.appendChild( createSldParameterElement( doc,
"font-weight",
encodeSldFontWeight( font.weight() ) ) );
2485 if ( color.isValid() )
2487 QDomElement fillElem = doc.createElement( QStringLiteral(
"Fill" ) );
2488 fillToSld( doc, fillElem, Qt::SolidPattern, color );
2489 element.appendChild( fillElem );
2494 Qt::PenJoinStyle joinStyle,
2495 Qt::PenCapStyle capStyle,
2497 const QVector<qreal> *dashPattern )
2500 penStyle.append(
"PEN(" );
2501 penStyle.append(
"c:" );
2502 penStyle.append( c.name() );
2503 penStyle.append(
",w:" );
2505 penStyle.append( QString::number( width * mmScaleFactor ) );
2506 penStyle.append(
"mm" );
2509 if ( dashPattern && !dashPattern->isEmpty() )
2511 penStyle.append(
",p:\"" );
2512 QVector<qreal>::const_iterator pIt = dashPattern->constBegin();
2513 for ( ; pIt != dashPattern->constEnd(); ++pIt )
2515 if ( pIt != dashPattern->constBegin() )
2517 penStyle.append(
' ' );
2519 penStyle.append( QString::number( *pIt * mapUnitScaleFactor ) );
2520 penStyle.append(
'g' );
2522 penStyle.append(
'\"' );
2526 penStyle.append(
",cap:" );
2530 penStyle.append(
'p' );
2533 penStyle.append(
'r' );
2537 penStyle.append(
'b' );
2541 penStyle.append(
",j:" );
2542 switch ( joinStyle )
2545 penStyle.append(
'b' );
2548 penStyle.append(
'r' );
2552 penStyle.append(
'm' );
2558 penStyle.append(
",dp:" );
2559 penStyle.append( QString::number( offset * mapUnitScaleFactor ) );
2560 penStyle.append(
'g' );
2563 penStyle.append(
')' );
2570 brushStyle.append(
"BRUSH(" );
2571 brushStyle.append(
"fc:" );
2572 brushStyle.append( fillColor.name() );
2573 brushStyle.append(
')' );
2579 if ( geomFunc.isEmpty() )
2582 QDomElement geometryElem = doc.createElement( QStringLiteral(
"Geometry" ) );
2583 element.appendChild( geometryElem );
2613 QDomElement geometryElem = element.firstChildElement( QStringLiteral(
"Geometry" ) );
2614 if ( geometryElem.isNull() )
2626 element.appendChild( doc.createComment(
"Parser Error: " + expr.
parserErrorString() +
" - Expression was: " + function ) );
2630 if ( !filterElem.isNull() )
2631 element.appendChild( filterElem );
2642 element.appendChild( doc.createComment(
"Parser Error: " + expr.
parserErrorString() +
" - Expression was: " + function ) );
2646 if ( !filterElem.isNull() )
2647 element.appendChild( filterElem );
2654 QDomElement elem = element;
2655 if ( element.tagName() != QLatin1String(
"Filter" ) )
2657 QDomNodeList filterNodes = element.elementsByTagName( QStringLiteral(
"Filter" ) );
2658 if ( !filterNodes.isEmpty() )
2660 elem = filterNodes.at( 0 ).toElement();
2664 if ( elem.isNull() )
2689 const QString &path,
const QString &format )
2693 QDomElement onlineResourceElem = doc.createElement( QStringLiteral(
"se:OnlineResource" ) );
2694 onlineResourceElem.setAttribute( QStringLiteral(
"xlink:type" ), QStringLiteral(
"simple" ) );
2695 onlineResourceElem.setAttribute( QStringLiteral(
"xlink:href" ), url );
2696 element.appendChild( onlineResourceElem );
2698 QDomElement formatElem = doc.createElement( QStringLiteral(
"se:Format" ) );
2699 formatElem.appendChild( doc.createTextNode( format ) );
2700 element.appendChild( formatElem );
2707 QDomElement onlineResourceElem = element.firstChildElement( QStringLiteral(
"OnlineResource" ) );
2708 if ( onlineResourceElem.isNull() )
2711 path = onlineResourceElem.attributeNS( QStringLiteral(
"http://www.w3.org/1999/xlink" ), QStringLiteral(
"href" ) );
2713 QDomElement formatElem = element.firstChildElement( QStringLiteral(
"Format" ) );
2714 if ( formatElem.isNull() )
2717 format = formatElem.firstChild().nodeValue();
2724 QDomElement nodeElem = doc.createElement( QStringLiteral(
"se:SvgParameter" ) );
2725 nodeElem.setAttribute( QStringLiteral(
"name" ), name );
2726 nodeElem.appendChild( doc.createTextNode( value ) );
2735 QDomElement paramElem = element.firstChildElement();
2736 while ( !paramElem.isNull() )
2738 if ( paramElem.localName() == QLatin1String(
"SvgParameter" ) || paramElem.localName() == QLatin1String(
"CssParameter" ) )
2740 QString name = paramElem.attribute( QStringLiteral(
"name" ) );
2741 if ( paramElem.firstChild().nodeType() == QDomNode::TextNode )
2743 value = paramElem.firstChild().nodeValue();
2747 if ( paramElem.firstChild().nodeType() == QDomNode::ElementNode &&
2748 paramElem.firstChild().localName() == QLatin1String(
"Literal" ) )
2750 QgsDebugMsg( paramElem.firstChild().localName() );
2751 value = paramElem.firstChild().firstChild().nodeValue();
2755 QgsDebugMsg( QStringLiteral(
"unexpected child of %1" ).arg( paramElem.localName() ) );
2759 if ( !name.isEmpty() && !value.isEmpty() )
2760 params[ name ] = value;
2763 paramElem = paramElem.nextSiblingElement();
2771 QDomElement nodeElem = doc.createElement( QStringLiteral(
"se:VendorOption" ) );
2772 nodeElem.setAttribute( QStringLiteral(
"name" ), name );
2773 nodeElem.appendChild( doc.createTextNode( value ) );
2781 QDomElement paramElem = element.firstChildElement( QStringLiteral(
"VendorOption" ) );
2782 while ( !paramElem.isNull() )
2784 QString name = paramElem.attribute( QStringLiteral(
"name" ) );
2785 QString value = paramElem.firstChild().nodeValue();
2787 if ( !name.isEmpty() && !value.isEmpty() )
2788 params[ name ] = value;
2790 paramElem = paramElem.nextSiblingElement( QStringLiteral(
"VendorOption" ) );
2800 QDomElement e = element.firstChildElement();
2801 while ( !e.isNull() )
2803 if ( e.tagName() == QLatin1String(
"prop" ) )
2805 QString propKey = e.attribute( QStringLiteral(
"k" ) );
2806 QString propValue = e.attribute( QStringLiteral(
"v" ) );
2807 props[propKey] = propValue;
2809 e = e.nextSiblingElement();
2817 for ( QgsStringMap::iterator it = props.begin(); it != props.end(); ++it )
2819 QDomElement propEl = doc.createElement( QStringLiteral(
"prop" ) );
2820 propEl.setAttribute( QStringLiteral(
"k" ), it.key() );
2821 propEl.setAttribute( QStringLiteral(
"v" ), it.value() );
2822 element.appendChild( propEl );
2831 QDomElement e = element.firstChildElement();
2833 while ( !e.isNull() )
2835 if ( e.tagName() == QLatin1String(
"symbol" ) )
2839 symbols.insert( e.attribute( QStringLiteral(
"name" ) ), symbol );
2845 e = e.nextSiblingElement();
2852 QStringList subsymbols;
2854 for ( QMap<QString, QgsSymbol *>::iterator it = symbols.begin(); it != symbols.end(); ++it )
2856 if ( it.key()[0] !=
'@' )
2860 subsymbols.append( it.key() );
2862 QStringList parts = it.key().split(
'@' );
2863 if ( parts.count() < 3 )
2865 QgsDebugMsg(
"found subsymbol with invalid name: " + it.key() );
2869 QString symname = parts[1];
2870 int symlayer = parts[2].toInt();
2872 if ( !symbols.contains( symname ) )
2874 QgsDebugMsg(
"subsymbol references invalid symbol: " + symname );
2882 QgsDebugMsg(
"subsymbol references invalid symbol layer: " + QString::number( symlayer ) );
2891 QgsDebugMsg(
"symbol layer refused subsymbol: " + it.key() );
2898 for (
int i = 0; i < subsymbols.count(); i++ )
2899 symbols.take( subsymbols[i] );
2906 QDomElement symbolsElem = doc.createElement( tagName );
2909 for ( QMap<QString, QgsSymbol *>::iterator its = symbols.begin(); its != symbols.end(); ++its )
2911 QDomElement symEl =
saveSymbol( its.key(), its.value(), doc, context );
2912 symbolsElem.appendChild( symEl );
2920 qDeleteAll( symbols );
2929 std::unique_ptr< QMimeData >mimeData(
new QMimeData );
2931 QDomDocument symbolDoc;
2933 symbolDoc.appendChild( symbolElem );
2934 mimeData->setText( symbolDoc.toString() );
2937 mimeData->setColorData( symbol->
color() );
2939 return mimeData.release();
2947 QString text = data->text();
2948 if ( !text.isEmpty() )
2953 if ( doc.setContent( text ) )
2955 elem = doc.documentElement();
2957 if ( elem.nodeName() != QStringLiteral(
"symbol" ) )
2958 elem = elem.firstChildElement( QStringLiteral(
"symbol" ) );
2969 QString rampType = element.attribute( QStringLiteral(
"type" ) );
2974 if ( rampType == QLatin1String(
"gradient" ) )
2976 else if ( rampType == QLatin1String(
"random" ) )
2978 else if ( rampType == QLatin1String(
"colorbrewer" ) )
2980 else if ( rampType == QLatin1String(
"cpt-city" ) )
2982 else if ( rampType == QLatin1String(
"preset" ) )
2986 QgsDebugMsg(
"unknown colorramp type " + rampType );
2994 QDomElement rampEl = doc.createElement( QStringLiteral(
"colorramp" ) );
2995 rampEl.setAttribute( QStringLiteral(
"type" ), ramp->
type() );
2996 rampEl.setAttribute( QStringLiteral(
"name" ), name );
3004 QVariantMap rampMap;
3006 rampMap.insert( QStringLiteral(
"type" ), ramp->
type() );
3007 rampMap.insert( QStringLiteral(
"name" ), name );
3011 QVariantMap propertyMap;
3012 for (
auto property = properties.constBegin();
property != properties.constEnd(); ++property )
3014 propertyMap.insert( property.key(),
property.value() );
3017 rampMap.insert( QStringLiteral(
"properties" ), propertyMap );
3023 QVariantMap rampMap = value.toMap();
3025 QString rampType = rampMap.
value( QStringLiteral(
"type" ) ).toString();
3028 QVariantMap propertyMap = rampMap.value( QStringLiteral(
"properties" ) ).toMap();
3031 for (
auto property = propertyMap.constBegin();
property != propertyMap.constEnd(); ++property )
3033 props.insert( property.key(),
property.value().toString() );
3036 if ( rampType == QLatin1String(
"gradient" ) )
3038 else if ( rampType == QLatin1String(
"random" ) )
3040 else if ( rampType == QLatin1String(
"colorbrewer" ) )
3042 else if ( rampType == QLatin1String(
"cpt-city" ) )
3044 else if ( rampType == QLatin1String(
"preset" ) )
3048 QgsDebugMsg(
"unknown colorramp type " + rampType );
3055 if ( !color.isValid() )
3062 return color.name();
3067 QList<QColor> colors;
3070 QStringList components = colorStr.simplified().split( QRegExp(
"(,|\\s)" ) );
3071 QStringList::iterator it = components.begin();
3072 for ( ; it != components.end(); ++it )
3075 if ( result.isValid() )
3080 if ( colors.length() > 0 )
3086 components = colorStr.split( QRegExp(
"(,|\n)" ) );
3087 it = components.begin();
3088 for ( ; it != components.end(); ++it )
3091 if ( result.isValid() )
3096 if ( colors.length() > 0 )
3102 components = colorStr.simplified().split( QString(
' ' ) );
3103 it = components.begin();
3104 for ( ; it != components.end(); ++it )
3107 if ( result.isValid() )
3112 if ( colors.length() > 0 )
3118 components = colorStr.split(
'\n' );
3119 it = components.begin();
3120 for ( ; it != components.end(); ++it )
3123 if ( result.isValid() )
3136 QMimeData *mimeData =
new QMimeData;
3137 mimeData->setColorData( QVariant( color ) );
3138 mimeData->setText( color.name() );
3145 QColor mimeColor = mimeData->colorData().value<QColor>();
3146 if ( mimeColor.isValid() )
3155 if ( textColor.isValid() )
3169 if ( data->hasFormat( QStringLiteral(
"text/xml" ) ) )
3172 QByteArray encodedData = data->data( QStringLiteral(
"text/xml" ) );
3173 QDomDocument xmlDoc;
3174 xmlDoc.setContent( encodedData );
3176 QDomElement dragDataElem = xmlDoc.documentElement();
3177 if ( dragDataElem.tagName() == QLatin1String(
"ColorSchemeModelDragData" ) )
3179 QDomNodeList nodeList = dragDataElem.childNodes();
3180 int nChildNodes = nodeList.size();
3181 QDomElement currentElem;
3183 for (
int i = 0; i < nChildNodes; ++i )
3185 currentElem = nodeList.at( i ).toElement();
3186 if ( currentElem.isNull() )
3191 QPair< QColor, QString> namedColor;
3193 namedColor.second = currentElem.attribute( QStringLiteral(
"label" ), QString() );
3195 mimeColors << namedColor;
3200 if ( mimeColors.length() == 0 && data->hasFormat( QStringLiteral(
"application/x-colorobject-list" ) ) )
3203 QByteArray encodedData = data->data( QStringLiteral(
"application/x-colorobject-list" ) );
3204 QDomDocument xmlDoc;
3205 xmlDoc.setContent( encodedData );
3207 QDomNodeList colorsNodes = xmlDoc.elementsByTagName( QStringLiteral(
"colors" ) );
3208 if ( colorsNodes.length() > 0 )
3210 QDomElement colorsElem = colorsNodes.at( 0 ).toElement();
3211 QDomNodeList colorNodeList = colorsElem.childNodes();
3212 int nChildNodes = colorNodeList.size();
3213 QDomElement currentElem;
3215 for (
int i = 0; i < nChildNodes; ++i )
3218 currentElem = colorNodeList.at( i ).toElement();
3219 if ( currentElem.isNull() )
3224 QDomNodeList colorNodes = currentElem.elementsByTagName( QStringLiteral(
"color" ) );
3225 QDomNodeList nameNodes = currentElem.elementsByTagName( QStringLiteral(
"name" ) );
3227 if ( colorNodes.length() > 0 )
3229 QDomElement colorElem = colorNodes.at( 0 ).toElement();
3231 QStringList colorParts = colorElem.text().simplified().split(
' ' );
3232 if ( colorParts.length() < 3 )
3237 int red = colorParts.at( 0 ).toDouble() * 255;
3238 int green = colorParts.at( 1 ).toDouble() * 255;
3239 int blue = colorParts.at( 2 ).toDouble() * 255;
3240 QPair< QColor, QString> namedColor;
3241 namedColor.first = QColor( red, green, blue );
3242 if ( nameNodes.length() > 0 )
3244 QDomElement nameElem = nameNodes.at( 0 ).toElement();
3245 namedColor.second = nameElem.text();
3247 mimeColors << namedColor;
3253 if ( mimeColors.length() == 0 && data->hasText() )
3257 QList< QColor >::iterator it = parsedColors.begin();
3258 for ( ; it != parsedColors.end(); ++it )
3260 mimeColors << qMakePair( *it, QString() );
3264 if ( mimeColors.length() == 0 && data->hasColor() )
3267 QColor mimeColor = data->colorData().value<QColor>();
3268 if ( mimeColor.isValid() )
3270 mimeColors << qMakePair( mimeColor, QString() );
3280 QMimeData *mimeData =
new QMimeData();
3281 QDomDocument xmlDoc;
3282 QDomElement xmlRootElement = xmlDoc.createElement( QStringLiteral(
"ColorSchemeModelDragData" ) );
3283 xmlDoc.appendChild( xmlRootElement );
3285 QgsNamedColorList::const_iterator colorIt = colorList.constBegin();
3286 for ( ; colorIt != colorList.constEnd(); ++colorIt )
3288 QDomElement namedColor = xmlDoc.createElement( QStringLiteral(
"NamedColor" ) );
3290 namedColor.setAttribute( QStringLiteral(
"label" ), ( *colorIt ).second );
3291 xmlRootElement.appendChild( namedColor );
3293 mimeData->setData( QStringLiteral(
"text/xml" ), xmlDoc.toByteArray() );
3301 colorIt = colorList.constBegin();
3302 QStringList colorListString;
3303 for ( ; colorIt != colorList.constEnd(); ++colorIt )
3305 colorListString << ( *colorIt ).first.name();
3307 mimeData->setText( colorListString.join( QStringLiteral(
"\n" ) ) );
3310 if ( colorList.length() > 0 )
3312 mimeData->setColorData( QVariant( colorList.at( 0 ).first ) );
3320 if ( !file.open( QIODevice::WriteOnly | QIODevice::Truncate ) )
3325 QTextStream stream( &file );
3326 stream <<
"GIMP Palette" << endl;
3327 if ( paletteName.isEmpty() )
3329 stream <<
"Name: QGIS Palette" << endl;
3333 stream <<
"Name: " << paletteName << endl;
3335 stream <<
"Columns: 4" << endl;
3336 stream <<
'#' << endl;
3338 for ( QgsNamedColorList::ConstIterator colorIt = colors.constBegin(); colorIt != colors.constEnd(); ++colorIt )
3340 QColor color = ( *colorIt ).first;
3341 if ( !color.isValid() )
3345 stream << QStringLiteral(
"%1 %2 %3" ).arg( color.red(), 3 ).arg( color.green(), 3 ).arg( color.blue(), 3 );
3346 stream <<
"\t" << ( ( *colorIt ).second.isEmpty() ? color.name() : ( *colorIt ).second ) << endl;
3357 if ( !file.open( QIODevice::ReadOnly ) )
3360 return importedColors;
3363 QTextStream in( &file );
3365 QString line = in.readLine();
3366 if ( !line.startsWith( QLatin1String(
"GIMP Palette" ) ) )
3369 return importedColors;
3373 while ( !in.atEnd() && !line.startsWith( QLatin1String(
"Name:" ) ) && !line.startsWith(
'#' ) )
3375 line = in.readLine();
3377 if ( line.startsWith( QLatin1String(
"Name:" ) ) )
3379 QRegExp nameRx(
"Name:\\s*(\\S.*)$" );
3380 if ( nameRx.indexIn( line ) != -1 )
3382 name = nameRx.cap( 1 );
3387 while ( !in.atEnd() && !line.startsWith(
'#' ) )
3389 line = in.readLine();
3394 return importedColors;
3398 QRegExp rx(
"^\\s*(\\d+)\\s+(\\d+)\\s+(\\d+)(\\s.*)?$" );
3399 while ( !in.atEnd() )
3401 line = in.readLine();
3402 if ( rx.indexIn( line ) == -1 )
3406 int red = rx.cap( 1 ).toInt();
3407 int green = rx.cap( 2 ).toInt();
3408 int blue = rx.cap( 3 ).toInt();
3409 QColor color = QColor( red, green, blue );
3410 if ( !color.isValid() )
3417 if ( rx.captureCount() > 3 )
3419 label = rx.cap( 4 ).simplified();
3426 importedColors << qMakePair( color, label );
3431 return importedColors;
3444 QRegExp hexColorAlphaRx(
"^\\s*#?([0-9a-fA-F]{6})([0-9a-fA-F]{2})\\s*$" );
3445 int hexColorIndex = hexColorAlphaRx.indexIn( colorStr );
3448 if ( hexColorIndex == -1 && QColor::isValidColor( colorStr ) )
3451 parsedColor.setNamedColor( colorStr );
3452 if ( parsedColor.isValid() )
3454 containsAlpha =
false;
3460 if ( hexColorIndex > -1 )
3462 QString hexColor = hexColorAlphaRx.cap( 1 );
3463 parsedColor.setNamedColor( QStringLiteral(
"#" ) + hexColor );
3465 int alphaHex = hexColorAlphaRx.cap( 2 ).toInt( &alphaOk, 16 );
3467 if ( parsedColor.isValid() && alphaOk )
3469 parsedColor.setAlpha( alphaHex );
3470 containsAlpha =
true;
3478 QRegExp hexColorRx2(
"^\\s*(?:[0-9a-fA-F]{3}){1,2}\\s*$" );
3479 if ( hexColorRx2.indexIn( colorStr ) != -1 )
3482 parsedColor.setNamedColor( QStringLiteral(
"#" ) + colorStr );
3483 if ( parsedColor.isValid() )
3485 containsAlpha =
false;
3492 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*$" );
3493 if ( rgbFormatRx.indexIn( colorStr ) != -1 )
3495 int r = rgbFormatRx.cap( 1 ).toInt();
3496 int g = rgbFormatRx.cap( 2 ).toInt();
3497 int b = rgbFormatRx.cap( 3 ).toInt();
3498 parsedColor.setRgb( r, g, b );
3499 if ( parsedColor.isValid() )
3501 containsAlpha =
false;
3507 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*$" );
3508 if ( rgbPercentFormatRx.indexIn( colorStr ) != -1 )
3510 int r = std::round( rgbPercentFormatRx.cap( 1 ).toDouble() * 2.55 );
3511 int g = std::round( rgbPercentFormatRx.cap( 2 ).toDouble() * 2.55 );
3512 int b = std::round( rgbPercentFormatRx.cap( 3 ).toDouble() * 2.55 );
3513 parsedColor.setRgb( r, g, b );
3514 if ( parsedColor.isValid() )
3516 containsAlpha =
false;
3522 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*$" );
3523 if ( rgbaFormatRx.indexIn( colorStr ) != -1 )
3525 int r = rgbaFormatRx.cap( 1 ).toInt();
3526 int g = rgbaFormatRx.cap( 2 ).toInt();
3527 int b = rgbaFormatRx.cap( 3 ).toInt();
3528 int a = std::round( rgbaFormatRx.cap( 4 ).toDouble() * 255.0 );
3529 parsedColor.setRgb( r, g, b, a );
3530 if ( parsedColor.isValid() )
3532 containsAlpha =
true;
3538 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*$" );
3539 if ( rgbaPercentFormatRx.indexIn( colorStr ) != -1 )
3541 int r = std::round( rgbaPercentFormatRx.cap( 1 ).toDouble() * 2.55 );
3542 int g = std::round( rgbaPercentFormatRx.cap( 2 ).toDouble() * 2.55 );
3543 int b = std::round( rgbaPercentFormatRx.cap( 3 ).toDouble() * 2.55 );
3544 int a = std::round( rgbaPercentFormatRx.cap( 4 ).toDouble() * 255.0 );
3545 parsedColor.setRgb( r, g, b, a );
3546 if ( parsedColor.isValid() )
3548 containsAlpha =
true;
3565 QImage::Format format = image->format();
3566 if ( format != QImage::Format_ARGB32_Premultiplied && format != QImage::Format_ARGB32 )
3568 QgsDebugMsg( QStringLiteral(
"no alpha channel." ) );
3573 for (
int heightIndex = 0; heightIndex < image->height(); ++heightIndex )
3575 QRgb *scanLine =
reinterpret_cast< QRgb *
>( image->scanLine( heightIndex ) );
3576 for (
int widthIndex = 0; widthIndex < image->width(); ++widthIndex )
3578 myRgb = scanLine[widthIndex];
3579 if ( format == QImage::Format_ARGB32_Premultiplied )
3580 scanLine[widthIndex] = qRgba( opacity * qRed( myRgb ), opacity * qGreen( myRgb ), opacity * qBlue( myRgb ), opacity * qAlpha( myRgb ) );
3582 scanLine[widthIndex] = qRgba( qRed( myRgb ), qGreen( myRgb ), qBlue( myRgb ), opacity * qAlpha( myRgb ) );
3590 int tab[] = { 14, 10, 8, 6, 5, 5, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2 };
3591 int alpha = ( radius < 1 ) ? 16 : ( radius > 17 ) ? 1 : tab[radius - 1];
3593 if ( image.format() != QImage::Format_ARGB32_Premultiplied
3594 && image.format() != QImage::Format_RGB32 )
3596 image = image.convertToFormat( QImage::Format_ARGB32_Premultiplied );
3599 int r1 = rect.top();
3600 int r2 = rect.bottom();
3601 int c1 = rect.left();
3602 int c2 = rect.right();
3604 int bpl = image.bytesPerLine();
3612 i1 = i2 = ( QSysInfo::ByteOrder == QSysInfo::BigEndian ? 0 : 3 );
3614 for (
int col = c1; col <= c2; col++ )
3616 p = image.scanLine( r1 ) + col * 4;
3617 for (
int i = i1; i <= i2; i++ )
3618 rgba[i] = p[i] << 4;
3621 for (
int j = r1; j < r2; j++, p += bpl )
3622 for (
int i = i1; i <= i2; i++ )
3623 p[i] = ( rgba[i] += ( ( p[i] << 4 ) - rgba[i] ) * alpha / 16 ) >> 4;
3626 for (
int row = r1; row <= r2; row++ )
3628 p = image.scanLine( row ) + c1 * 4;
3629 for (
int i = i1; i <= i2; i++ )
3630 rgba[i] = p[i] << 4;
3633 for (
int j = c1; j < c2; j++, p += 4 )
3634 for (
int i = i1; i <= i2; i++ )
3635 p[i] = ( rgba[i] += ( ( p[i] << 4 ) - rgba[i] ) * alpha / 16 ) >> 4;
3638 for (
int col = c1; col <= c2; col++ )
3640 p = image.scanLine( r2 ) + col * 4;
3641 for (
int i = i1; i <= i2; i++ )
3642 rgba[i] = p[i] << 4;
3645 for (
int j = r1; j < r2; j++, p -= bpl )
3646 for (
int i = i1; i <= i2; i++ )
3647 p[i] = ( rgba[i] += ( ( p[i] << 4 ) - rgba[i] ) * alpha / 16 ) >> 4;
3650 for (
int row = r1; row <= r2; row++ )
3652 p = image.scanLine( row ) + c2 * 4;
3653 for (
int i = i1; i <= i2; i++ )
3654 rgba[i] = p[i] << 4;
3657 for (
int j = c1; j < c2; j++, p -= 4 )
3658 for (
int i = i1; i <= i2; i++ )
3659 p[i] = ( rgba[i] += ( ( p[i] << 4 ) - rgba[i] ) * alpha / 16 ) >> 4;
3665 if ( alpha != 255 && alpha > 0 )
3669 double alphaFactor = alpha / 255.;
3670 int r = 0, g = 0, b = 0;
3671 rgb.getRgb( &r, &g, &b );
3676 rgb.setRgb( r, g, b, alpha );
3678 else if ( alpha == 0 )
3680 rgb.setRgb( 0, 0, 0, 0 );
3686 if ( order == Qt::AscendingOrder )
3700 double dx = directionPoint.x() - startPoint.x();
3701 double dy = directionPoint.y() - startPoint.y();
3702 double length = std::sqrt( dx * dx + dy * dy );
3703 double scaleFactor = distance / length;
3704 return QPointF( startPoint.x() + dx * scaleFactor, startPoint.y() + dy * scaleFactor );
3714 for (
int i = 0; i < svgPaths.size(); i++ )
3716 QDir dir( svgPaths[i] );
3717 Q_FOREACH (
const QString &item, dir.entryList( QDir::Dirs | QDir::NoDotAndDotDot ) )
3719 svgPaths.insert( i + 1, dir.path() +
'/' + item );
3722 Q_FOREACH (
const QString &item, dir.entryList( QStringList(
"*.svg" ), QDir::Files ) )
3725 list.append( dir.path() +
'/' + item );
3737 QStringList svgPaths;
3738 svgPaths.append( directory );
3740 for (
int i = 0; i < svgPaths.size(); i++ )
3742 QDir dir( svgPaths[i] );
3743 Q_FOREACH (
const QString &item, dir.entryList( QDir::Dirs | QDir::NoDotAndDotDot ) )
3745 svgPaths.insert( i + 1, dir.path() +
'/' + item );
3748 Q_FOREACH (
const QString &item, dir.entryList( QStringList(
"*.svg" ), QDir::Files ) )
3750 list.append( dir.path() +
'/' + item );
3763 if ( QFileInfo::exists( n ) )
3764 return QFileInfo( n ).canonicalFilePath();
3768 if ( name.contains( QLatin1String(
"://" ) ) )
3771 if ( url.isValid() && !url.scheme().isEmpty() )
3773 if ( url.scheme().compare( QLatin1String(
"file" ), Qt::CaseInsensitive ) == 0 )
3776 name = url.toLocalFile();
3777 if ( QFile( name ).exists() )
3779 return QFileInfo( name ).canonicalFilePath();
3793 for (
int i = 0; i < svgPaths.size(); i++ )
3795 QString svgPath = svgPaths[i];
3796 if ( svgPath.endsWith( QChar(
'/' ) ) )
3807 QString myLocalPath = svgPath + QDir::separator() + name;
3810 if ( QFile( myLocalPath ).exists() )
3813 return QFileInfo( myLocalPath ).canonicalFilePath();
3817 return pathResolver.
readPath( name );
3825 if ( !QFileInfo::exists( p ) )
3828 QString path = QFileInfo( p ).canonicalFilePath();
3832 bool isInSvgPaths =
false;
3833 for (
int i = 0; i < svgPaths.size(); i++ )
3835 QString dir = QFileInfo( svgPaths[i] ).canonicalFilePath();
3837 if ( !dir.isEmpty() && path.startsWith( dir ) )
3839 path = path.mid( dir.size() + 1 );
3840 isInSvgPaths =
true;
3855 double cx = 0, cy = 0;
3856 double area, sum = 0;
3857 for (
int i = points.count() - 1, j = 0; j < points.count(); i = j++ )
3859 const QPointF &p1 = points[i];
3860 const QPointF &p2 = points[j];
3861 area = p1.x() * p2.y() - p1.y() * p2.x();
3863 cx += ( p1.x() + p2.x() ) * area;
3864 cy += ( p1.y() + p2.y() ) * area;
3871 if ( points.count() >= 2 )
3872 return QPointF( ( points[0].x() + points[1].x() ) / 2, ( points[0].y() + points[1].y() ) / 2 );
3873 else if ( points.count() == 1 )
3881 return QPointF( cx, cy );
3891 unsigned int i, pointCount = points.count();
3894 for ( i = 0; i < pointCount; ++i ) polyline[i] =
QgsPointXY( points[i].x(), points[i].y() );
3901 if ( !pointOnSurfaceGeom.
isNull() )
3905 return QPointF( point.
x(), point.
y() );
3914 bool inside =
false;
3916 double x = point.x();
3917 double y = point.y();
3919 for (
int i = 0, j = points.count() - 1; i < points.count(); i++ )
3921 const QPointF &p1 = points[i];
3922 const QPointF &p2 = points[j];
3927 if ( ( p1.y() < y && p2.y() >= y ) || ( p2.y() < y && p1.y() >= y ) )
3929 if ( p1.x() + ( y - p1.y() ) / ( p2.y() - p1.y() ) * ( p2.x() - p1.x() ) <= x )
3940 if ( fieldOrExpression.isEmpty() )
3959 return static_cast<const QgsExpressionNodeColumnRef *>( n )->name();
3975 QList<double> breaks;
3978 breaks.append( maximum );
3982 int minimumCount =
static_cast< int >( classes ) / 3;
3983 double shrink = 0.75;
3984 double highBias = 1.5;
3985 double adjustBias = 0.5 + 1.5 * highBias;
3986 int divisions = classes;
3987 double h = highBias;
3990 double dx = maximum - minimum;
4000 cell = std::max( std::fabs( minimum ), std::fabs( maximum ) );
4001 if ( adjustBias >= 1.5 * h + 0.5 )
4003 U = 1 + ( 1.0 / ( 1 + h ) );
4007 U = 1 + ( 1.5 / ( 1 + adjustBias ) );
4009 small = dx < ( cell * U * std::max( 1, divisions ) * 1e-07 * 3.0 );
4016 cell = 9 + cell / 10;
4017 cell = cell * shrink;
4019 if ( minimumCount > 1 )
4021 cell = cell / minimumCount;
4027 if ( divisions > 1 )
4029 cell = cell / divisions;
4032 if ( cell < 20 * 1e-07 )
4037 double base = std::pow( 10.0, std::floor( std::log10( cell ) ) );
4039 if ( ( 2 * base ) - cell < h * ( cell - unit ) )
4042 if ( ( 5 * base ) - cell < adjustBias * ( cell - unit ) )
4045 if ( ( 10.0 * base ) - cell < h * ( cell - unit ) )
4052 int start = std::floor( minimum / unit + 1e-07 );
4053 int end = std::ceil( maximum / unit - 1e-07 );
4056 while ( start * unit > minimum + ( 1e-07 * unit ) )
4060 while ( end * unit < maximum - ( 1e-07 * unit ) )
4064 QgsDebugMsg( QStringLiteral(
"pretty classes: %1" ).arg( end ) );
4068 int k = std::floor( 0.5 + end - start );
4069 if ( k < minimumCount )
4071 k = minimumCount - k;
4075 start = start - k / 2 + k % 2;
4079 start = start - k / 2;
4080 end = end + k / 2 + k % 2;
4083 double minimumBreak = start * unit;
4085 int count = end - start;
4087 breaks.reserve( count );
4088 for (
int i = 1; i < count + 1; i++ )
4090 breaks.append( minimumBreak + i * unit );
4093 if ( breaks.isEmpty() )
4096 if ( breaks.first() < minimum )
4098 breaks[0] = minimum;
4100 if ( breaks.last() > maximum )
4102 breaks[breaks.count() - 1] = maximum;
4107 if ( minimum < 0.0 && maximum > 0.0 )
4109 QList<double> breaksMinusZero;
4110 for (
int i = 0; i < breaks.count(); i++ )
4112 breaksMinusZero.append( breaks[i] - 0.0 );
4115 for (
int i = 1; i < breaks.count(); i++ )
4117 if ( std::abs( breaksMinusZero[i] ) < std::abs( breaksMinusZero[i - 1] ) )
4120 breaks[posOfMin] = 0.0;
4129 bool roundToUnit =
false;
4132 if ( props.contains( QStringLiteral(
"uomScale" ) ) )
4135 scale = props.value( QStringLiteral(
"uomScale" ) ).toDouble( &ok );
4144 if ( props.value( QStringLiteral(
"uom" ) ) == QLatin1String(
"http://www.opengeospatial.org/se/units/metre" ) )
4169 scale = 1 / 0.28 * 25.4;
4193 double rescaled = size * scale;
4198 rescaled = std::round( rescaled );
4205 double x =
rescaleUom( point.x(), unit, props );
4206 double y =
rescaleUom( point.y(), unit, props );
4207 return QPointF( x, y );
4212 QVector<qreal> result;
4213 QVector<qreal>::const_iterator it = array.constBegin();
4214 for ( ; it != array.constEnd(); ++it )
4216 result.append(
rescaleUom( *it, unit, props ) );
4223 if ( !props.value( QStringLiteral(
"scaleMinDenom" ), QString() ).isEmpty() )
4225 QDomElement scaleMinDenomElem = doc.createElement( QStringLiteral(
"se:MinScaleDenominator" ) );
4226 scaleMinDenomElem.appendChild( doc.createTextNode(
qgsDoubleToString( props.value( QStringLiteral(
"scaleMinDenom" ) ).toDouble() ) ) );
4227 ruleElem.appendChild( scaleMinDenomElem );
4230 if ( !props.value( QStringLiteral(
"scaleMaxDenom" ), QString() ).isEmpty() )
4232 QDomElement scaleMaxDenomElem = doc.createElement( QStringLiteral(
"se:MaxScaleDenominator" ) );
4233 scaleMaxDenomElem.appendChild( doc.createTextNode(
qgsDoubleToString( props.value( QStringLiteral(
"scaleMaxDenom" ) ).toDouble() ) ) );
4234 ruleElem.appendChild( scaleMaxDenomElem );
4243 double parentScaleMinDenom = props.value( QStringLiteral(
"scaleMinDenom" ), QStringLiteral(
"0" ) ).toDouble( &ok );
4244 if ( !ok || parentScaleMinDenom <= 0 )
4245 props[ QStringLiteral(
"scaleMinDenom" )] = QString::number( mScaleMinDenom );
4247 props[ QStringLiteral(
"scaleMinDenom" )] = QString::number( std::max( parentScaleMinDenom, mScaleMinDenom ) );
4253 double parentScaleMaxDenom = props.value( QStringLiteral(
"scaleMaxDenom" ), QStringLiteral(
"0" ) ).toDouble( &ok );
4254 if ( !ok || parentScaleMaxDenom <= 0 )
4255 props[ QStringLiteral(
"scaleMaxDenom" )] = QString::number( mScaleMaxDenom );
4257 props[ QStringLiteral(
"scaleMaxDenom" )] = QString::number( std::min( parentScaleMaxDenom, mScaleMaxDenom ) );
4265 if ( uom == QLatin1String(
"http://www.opengeospatial.org/se/units/metre" ) )
4267 scale = 1.0 / 0.00028;
4269 else if ( uom == QLatin1String(
"http://www.opengeospatial.org/se/units/foot" ) )
4271 scale = 304.8 / 0.28;
4278 return size * scale;
static void mergeScaleDependencies(double mScaleMinDenom, double mScaleMaxDenom, QgsStringMap &props)
Merges the local scale limits, if any, with the ones already in the map, if any.
static void wellKnownMarkerToSld(QDomDocument &doc, QDomElement &element, const QString &name, const QColor &color, const QColor &strokeColor, Qt::PenStyle strokeStyle, double strokeWidth=-1, double size=-1)
Class for parsing and evaluation of expressions (formerly called "search strings").
void setForceVectorOutput(bool force)
bool hasParserError() const
Returns true if an error occurred when parsing the input expression.
static QgsSymbolLayerRegistry * symbolLayerRegistry()
Returns the application's symbol layer registry, used for managing symbol layers. ...
The class is used as a container of context for various read/write operations on other objects...
static QgsSymbol * symbolFromMimeData(const QMimeData *data)
Attempts to parse mime data as a symbol.
Meters value as Map units.
static QIcon symbolLayerPreviewIcon(const QgsSymbolLayer *layer, QgsUnitTypes::RenderUnit u, QSize size, const QgsMapUnitScale &scale=QgsMapUnitScale())
Draws a symbol layer preview to an icon.
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)
Sets the map unit scale for the symbol.
static QPicture symbolLayerPreviewPicture(const QgsSymbolLayer *layer, QgsUnitTypes::RenderUnit units, QSize size, const QgsMapUnitScale &scale=QgsMapUnitScale())
Draws a symbol layer preview to a QPicture.
QgsPaintEffect * paintEffect() const
Returns the current paint effect for the layer.
Calculate scale by the diameter.
static bool createFunctionElement(QDomDocument &doc, QDomElement &element, const QString &function)
static QString encodeSldAlpha(int alpha)
Abstract base class for all rendered symbols.
static QgsArrowSymbolLayer::ArrowType decodeArrowType(const QVariant &value, bool *ok=nullptr)
Decodes a value representing an arrow type.
static QString encodeSldBrushStyle(Qt::BrushStyle style)
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 QIcon symbolPreviewIcon(const QgsSymbol *symbol, QSize size, int padding=0)
Returns an icon preview for a color ramp.
static bool isDefaultStack(QgsPaintEffect *effect)
Tests whether a paint effect matches the default effects stack.
static bool displacementFromSldElement(QDomElement &element, QPointF &offset)
static QPointF decodePoint(const QString &string)
Decodes a QSizeF from a string.
QVector< QgsPolylineXY > QgsPolygonXY
Polygon: first item of the list is outer ring, inner rings (if any) start from second item...
static QDomElement saveColorRamp(const QString &name, QgsColorRamp *ramp, QDomDocument &doc)
Encodes a color ramp's settings to an XML element.
static bool needMarkerLine(QDomElement &element)
static void externalMarkerToSld(QDomDocument &doc, QDomElement &element, const QString &path, const QString &format, int *markIndex=nullptr, const QColor &color=QColor(), double size=-1)
bool clipFeaturesToExtent() const
Returns whether features drawn by the symbol will be clipped to the render context's extent...
static 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 the 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.
A marker symbol type, for rendering Point and MultiPoint geometries.
QVector< QgsPolygonXY > QgsMultiPolygonXY
A collection of QgsPolygons that share a common collection of attributes.
static Qt::PenJoinStyle decodePenJoinStyle(const QString &str)
bool qgsVariantLessThan(const QVariant &lhs, const QVariant &rhs)
Compares two QVariant values and returns whether the first is less than the second.
A line symbol type, for rendering LineString and MultiLineString geometries.
static QColor parseColor(const QString &colorStr, bool strictEval=false)
Attempts to parse a string as a color using a variety of common formats, including hex codes...
static QgsPaintEffectRegistry * paintEffectRegistry()
Returns the application's paint effect registry, used for managing paint effects. ...
bool minSizeMMEnabled
Whether the minimum size in mm should be respected.
bool hasFeature() const
Returns true if the context has a feature associated with it.
static QString getSvgParametricPath(const QString &basePath, const QColor &fillColor, const QColor &strokeColor, double strokeWidth)
Encodes a reference to a parametric SVG into a path with parameters according to the SVG Parameters s...
static QVector< qreal > decodeRealVector(const QString &s)
static QString encodeColor(const QColor &color)
void setOutputUnit(QgsUnitTypes::RenderUnit unit)
Sets the units to use for sizes and widths within the symbol.
QVector< QgsPolylineXY > QgsMultiPolylineXY
A collection of QgsPolylines that share a common collection of attributes.
QgsMultiPolylineXY asMultiPolyline() const
Returns the contents of the geometry as a multi-linestring.
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
static QPointF pointOnLineWithDistance(QPointF startPoint, QPointF directionPoint, double distance)
Returns a point on the line from startPoint to directionPoint that is a certain distance away from th...
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.
bool isProjectColor() const
Returns true if the property is set to a linked project color.
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.
#define QgsDebugMsgLevel(str, level)
static QDomElement saveSymbols(QgsSymbolMap &symbols, const QString &tagName, QDomDocument &doc, const QgsReadWriteContext &context)
Writes a collection of symbols to XML with specified tagName for the top-level element.
bool forceRHR() const
Returns true if polygon features drawn by the symbol will be reoriented to follow the standard right-...
static void externalGraphicToSld(QDomDocument &doc, QDomElement &element, const QString &path, const QString &mime, const QColor &color, double size=-1)
static QString encodeSldRealVector(const QVector< qreal > &v)
static bool needEllipseMarker(QDomElement &element)
void setOpacity(qreal opacity)
Sets the opacity for the symbol.
static QgsStringMap getVendorOptionList(QDomElement &element)
QgsPolygonXY asPolygon() const
Returns the contents of the geometry as a polygon.
static QColor parseColorWithAlpha(const QString &colorStr, bool &containsAlpha, bool strictEval=false)
Attempts to parse a string as a color using a variety of common formats, including hex codes...
Calculate scale by the area.
static bool needSvgMarker(QDomElement &element)
static QVariant colorRampToVariant(const QString &name, QgsColorRamp *ramp)
Saves a color ramp to a QVariantMap, wrapped in a QVariant.
static QString colorToName(const QColor &color)
Returns a friendly display name for a color.
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
void setActive(bool active)
Sets whether the property is currently active.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
static QIcon colorRampPreviewIcon(QgsColorRamp *ramp, QSize size, int padding=0)
Returns an icon preview for a color ramp.
static int decodeSldAlpha(const QString &str)
QgsPropertyCollection & dataDefinedProperties()
Returns a reference to the symbol layer's property collection, used for data defined overrides...
virtual double value(int index) const =0
Returns relative value between [0,1] of color at specified index.
static QString encodeSldLineJoinStyle(Qt::PenJoinStyle style)
points (e.g., for font sizes)
virtual QgsSymbolLayer * clone() const =0
Shall be reimplemented by subclasses to create a deep copy of the instance.
static QgsRenderContext fromQPainter(QPainter *painter)
Creates a default render context given a pixel based QPainter destination.
QList< QPair< QColor, QString > > QgsNamedColorList
List of colors paired with a friendly display name identifying the color.
static QgsSymbolLayer * createMarkerLayerFromSld(QDomElement &element)
static void createRotationElement(QDomDocument &doc, QDomElement &element, const QString &rotationFunc)
ArrowType
Possible arrow types.
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.
QColor color() const
Returns the symbol's color.
static QgsSymbolLayer * createFillLayerFromSld(QDomElement &element)
static double estimateMaxSymbolBleed(QgsSymbol *symbol, const QgsRenderContext &context)
Returns the maximum estimated bleed for the symbol.
Abstract base class for all nodes that can appear in an expression.
static QList< QgsExpressionContextScope * > globalProjectLayerScopes(const QgsMapLayer *layer)
Creates a list of three scopes: global, layer's project and layer.
static QPainter::CompositionMode decodeBlendMode(const QString &s)
static Qt::PenCapStyle decodePenCapStyle(const QString &str)
void setPaintEffect(QgsPaintEffect *effect)
Sets the current paint effect for the layer.
static bool needLinePatternFill(QDomElement &element)
static void parametricSvgToSld(QDomDocument &doc, QDomElement &graphicElem, const QString &path, const QColor &fillColor, double size, const QColor &strokeColor, double strokeWidth)
Encodes a reference to a parametric SVG into SLD, as a succession of parametric SVG using URL paramet...
virtual QString type() const =0
Returns a string representing the color ramp type.
static Q_INVOKABLE QgsUnitTypes::RenderUnit decodeRenderUnit(const QString &string, bool *ok=nullptr)
Decodes a render unit from a string.
QgsGeometry pointOnSurface() const
Returns a point guaranteed to lie on the surface of a geometry.
static bool lineFromSld(QDomElement &element, Qt::PenStyle &penStyle, QColor &color, double &width, Qt::PenJoinStyle *penJoinStyle=nullptr, Qt::PenCapStyle *penCapStyle=nullptr, QVector< qreal > *customDashPattern=nullptr, double *dashOffset=nullptr)
void setEnabled(bool enabled)
Sets whether symbol layer is enabled and should be drawn.
A store for object properties.
static QString encodeSldFontStyle(QFont::Style style)
static QStringList listSvgFiles()
Returns a list of all available svg files.
static QgsExpression * fieldOrExpressionToExpression(const QString &fieldOrExpression)
Returns a new valid expression instance for given field or expression string.
static QgsSymbolMap loadSymbols(QDomElement &element, const QgsReadWriteContext &context)
Reads a collection of symbols from XML and returns them in a map. Caller is responsible for deleting ...
QgsSymbolLayer * symbolLayer(int layer)
Returns a specific symbol layer 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.
VertexMarkerType
Editing vertex markers.
static bool convertPolygonSymbolizerToPointMarker(QDomElement &element, QgsSymbolLayerList &layerList)
static void drawVertexMarker(double x, double y, QPainter &p, QgsSymbolLayerUtils::VertexMarkerType type, int markerSize)
Draws a vertex symbol at (painter) coordinates x, y.
static QVector< qreal > decodeSldRealVector(const QString &s)
static QgsColorRamp * create(const QgsStringMap &properties=QgsStringMap())
Creates a new QgsColorRamp from a map of properties.
const QgsPathResolver & pathResolver() const
Returns path resolver for conversion between relative and absolute paths.
QVector< QgsPointXY > QgsPolylineXY
Polyline as represented as a vector of two-dimensional points.
static bool saveColorsToGpl(QFile &file, const QString &paletteName, const QgsNamedColorList &colors)
Exports colors to a gpl GIMP palette file.
Contains information about the context of a rendering operation.
void resolvePaths(const QString &name, QgsStringMap &properties, const QgsPathResolver &pathResolver, bool saving) const
Resolve paths in properties of a particular symbol layer.
static void createOpacityElement(QDomDocument &doc, QDomElement &element, const QString &alphaFunc)
static void labelTextToSld(QDomDocument &doc, QDomElement &element, const QString &label, const QFont &font, const QColor &color=QColor(), double size=-1)
QgsPointXY asPoint() const
Returns the contents of the geometry as a 2-dimensional point.
static void blurImageInPlace(QImage &image, QRect rect, int radius, bool alphaOnly)
Blurs an image in place, e.g. creating Qt-independent drop shadows.
double maxSizeMM
The maximum size in millimeters, or 0.0 if unset.
bool hasDataDefinedProperties() const
Returns whether the symbol utilizes any data defined properties.
bool enabled() const
Returns true if symbol layer is enabled and will be drawn.
SymbolType type() const
Returns the symbol's type.
Struct for storing maximum and minimum scales for measurements in map units.
static QString encodeBrushStyle(Qt::BrushStyle style)
const QgsExpressionNode * rootNode() const
Returns 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
Returns a deep copy of this symbol.
QgsSymbolLayer * createSymbolLayerFromSld(const QString &name, QDomElement &element) const
create a new instance of symbol layer given symbol layer name and SLD
static QDomElement expressionToOgcFilter(const QgsExpression &exp, QDomDocument &doc, QString *errorMessage=nullptr)
Creates OGC filter XML element.
static QMimeData * colorToMimeData(const QColor &color)
Creates mime data from a color.
static 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 the contents of the geometry as a polyline.
A fill symbol type, for rendering Polygon and MultiPolygon geometries.
static void fillToSld(QDomDocument &doc, QDomElement &element, Qt::BrushStyle brushStyle, const QColor &color=QColor())
void appendScopes(const QList< QgsExpressionContextScope *> &scopes)
Appends a list of scopes to the end of the context.
static void lineToSld(QDomDocument &doc, QDomElement &element, Qt::PenStyle penStyle, const QColor &color, double width=-1, const Qt::PenJoinStyle *penJoinStyle=nullptr, const Qt::PenCapStyle *penCapStyle=nullptr, const QVector< qreal > *customDashPattern=nullptr, double dashOffset=0.0)
static QString svgSymbolNameToPath(const QString &name, const QgsPathResolver &pathResolver)
Determines an SVG symbol's path from its name.
static QString encodePenCapStyle(Qt::PenCapStyle style)
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.
void setForceRHR(bool force)
Sets whether polygon features drawn by the symbol should be reoriented to follow the standard right-h...
static QgsColorRamp * create(const QgsStringMap &properties=QgsStringMap())
Returns a new QgsLimitedRandomColorRamp color ramp created using the properties encoded in a string m...
HeadType
Possible head types.
Flat cap (in line with start/end of line)
static QgsExpression * expressionFromOgcFilter(const QDomElement &element, QgsVectorLayer *layer=nullptr)
Parse XML with OGC filter into QGIS expression.
double minScale
The minimum scale, or 0.0 if unset.
virtual bool writeXml(QDomElement &collectionElem, const QgsPropertiesDefinition &definitions) const
Writes the current state of the property collection into an XML element.
static Type flatType(Type type)
Returns the flat type for a WKB type.
static QString ogrFeatureStylePen(double width, double mmScaleFactor, double mapUnitsScaleFactor, const QColor &c, Qt::PenJoinStyle joinStyle=Qt::MiterJoin, Qt::PenCapStyle capStyle=Qt::FlatCap, double offset=0.0, const QVector< qreal > *dashPattern=nullptr)
Create ogr feature style string for pen.
virtual QgsExpressionNode::NodeType nodeType() const =0
Gets the type of this node.
static void multiplyImageOpacity(QImage *image, qreal opacity)
Multiplies opacity of image pixel values with a (global) transparency value.
QgsMultiPolygonXY asMultiPolygon() const
Returns the contents of the geometry as a multi-polygon.
bool maxSizeMMEnabled
Whether the maximum size in mm should be respected.
static void saveProperties(QgsStringMap props, QDomDocument &doc, QDomElement &element)
static Qt::PenJoinStyle decodeSldLineJoinStyle(const QString &str)
static bool createSymbolLayerListFromSld(QDomElement &element, QgsWkbTypes::GeometryType geomType, QgsSymbolLayerList &layers)
static QList< QColor > parseColorList(const QString &colorStr)
Attempts to parse a string as a list of colors using a variety of common formats, including hex codes...
static void drawStippledBackground(QPainter *painter, QRect rect)
static QString encodeSldLineCapStyle(Qt::PenCapStyle style)
static QString encodePenJoinStyle(Qt::PenJoinStyle style)
bool isActive() const
Returns whether the property is currently active.
static QString encodeRealVector(const QVector< qreal > &v)
RenderUnit
Rendering size units.
void setExpressionContext(const QgsExpressionContext &context)
Sets the expression context.
static QColor decodeColor(const QString &str)
static QColor colorFromMimeData(const QMimeData *data, bool &hasAlpha)
Attempts to parse mime data as a color.
virtual QString layerType() const =0
Returns a string that represents this layer type.
virtual bool saveProperties(QDomDocument &doc, QDomElement &element) const
Saves the current state of the effect to a DOM element.
static QPixmap symbolPreviewPixmap(const QgsSymbol *symbol, QSize size, int padding=0, QgsRenderContext *customContext=nullptr)
Returns a pixmap preview for a color ramp.