37 #include <QDomDocument> 39 #include <QDomElement> 46 #define POINTS_TO_MM 2.83464567 50 return QStringLiteral(
"%1,%2,%3,%4" ).arg( color.red() ).arg( color.green() ).arg( color.blue() ).arg( color.alpha() );
55 QStringList lst = str.split(
',' );
56 if ( lst.count() < 3 )
60 int red, green, blue, alpha;
62 green = lst[1].toInt();
63 blue = lst[2].toInt();
65 if ( lst.count() > 3 )
67 alpha = lst[3].toInt();
69 return QColor( red, green, blue, alpha );
75 result.sprintf(
"%.2g", alpha / 255.0 );
82 double alpha = str.toDouble( &ok );
83 if ( !ok || alpha > 1 )
94 case QFont::StyleNormal:
95 return QStringLiteral(
"normal" );
96 case QFont::StyleItalic:
97 return QStringLiteral(
"italic" );
98 case QFont::StyleOblique:
99 return QStringLiteral(
"oblique" );
107 if ( str == QLatin1String(
"normal" ) )
return QFont::StyleNormal;
108 if ( str == QLatin1String(
"italic" ) )
return QFont::StyleItalic;
109 if ( str == QLatin1String(
"oblique" ) )
return QFont::StyleOblique;
110 return QFont::StyleNormal;
115 if ( weight == 50 )
return QStringLiteral(
"normal" );
116 if ( weight == 75 )
return QStringLiteral(
"bold" );
120 if ( weight < 0 )
return QStringLiteral(
"100" );
121 if ( weight > 99 )
return QStringLiteral(
"900" );
122 return QString::number( weight * 800 / 99 + 100 );
128 int weight = str.toInt( &ok );
130 return static_cast< int >( QFont::Normal );
134 if ( weight > 900 )
return 99;
135 if ( weight < 100 )
return 0;
136 return ( weight - 100 ) * 99 / 800;
144 return QStringLiteral(
"no" );
146 return QStringLiteral(
"solid" );
148 return QStringLiteral(
"dash" );
150 return QStringLiteral(
"dot" );
151 case Qt::DashDotLine:
152 return QStringLiteral(
"dash dot" );
153 case Qt::DashDotDotLine:
154 return QStringLiteral(
"dash dot dot" );
156 return QStringLiteral(
"???" );
162 if ( str == QLatin1String(
"no" ) )
return Qt::NoPen;
163 if ( str == QLatin1String(
"solid" ) )
return Qt::SolidLine;
164 if ( str == QLatin1String(
"dash" ) )
return Qt::DashLine;
165 if ( str == QLatin1String(
"dot" ) )
return Qt::DotLine;
166 if ( str == QLatin1String(
"dash dot" ) )
return Qt::DashDotLine;
167 if ( str == QLatin1String(
"dash dot dot" ) )
return Qt::DashDotDotLine;
168 return Qt::SolidLine;
176 return QStringLiteral(
"bevel" );
178 return QStringLiteral(
"miter" );
180 return QStringLiteral(
"round" );
182 return QStringLiteral(
"???" );
188 if ( str == QLatin1String(
"bevel" ) )
return Qt::BevelJoin;
189 if ( str == QLatin1String(
"miter" ) )
return Qt::MiterJoin;
190 if ( str == QLatin1String(
"round" ) )
return Qt::RoundJoin;
191 return Qt::BevelJoin;
199 return QStringLiteral(
"bevel" );
201 return QStringLiteral(
"mitre" );
203 return QStringLiteral(
"round" );
211 if ( str == QLatin1String(
"bevel" ) )
return Qt::BevelJoin;
212 if ( str == QLatin1String(
"mitre" ) )
return Qt::MiterJoin;
213 if ( str == QLatin1String(
"round" ) )
return Qt::RoundJoin;
214 return Qt::BevelJoin;
222 return QStringLiteral(
"square" );
224 return QStringLiteral(
"flat" );
226 return QStringLiteral(
"round" );
228 return QStringLiteral(
"???" );
234 if ( str == QLatin1String(
"square" ) )
return Qt::SquareCap;
235 if ( str == QLatin1String(
"flat" ) )
return Qt::FlatCap;
236 if ( str == QLatin1String(
"round" ) )
return Qt::RoundCap;
237 return Qt::SquareCap;
245 return QStringLiteral(
"square" );
247 return QStringLiteral(
"butt" );
249 return QStringLiteral(
"round" );
257 if ( str == QLatin1String(
"square" ) )
return Qt::SquareCap;
258 if ( str == QLatin1String(
"butt" ) )
return Qt::FlatCap;
259 if ( str == QLatin1String(
"round" ) )
return Qt::RoundCap;
260 return Qt::SquareCap;
267 case Qt::SolidPattern :
268 return QStringLiteral(
"solid" );
269 case Qt::HorPattern :
270 return QStringLiteral(
"horizontal" );
271 case Qt::VerPattern :
272 return QStringLiteral(
"vertical" );
273 case Qt::CrossPattern :
274 return QStringLiteral(
"cross" );
275 case Qt::BDiagPattern :
276 return QStringLiteral(
"b_diagonal" );
277 case Qt::FDiagPattern :
278 return QStringLiteral(
"f_diagonal" );
279 case Qt::DiagCrossPattern :
280 return QStringLiteral(
"diagonal_x" );
281 case Qt::Dense1Pattern :
282 return QStringLiteral(
"dense1" );
283 case Qt::Dense2Pattern :
284 return QStringLiteral(
"dense2" );
285 case Qt::Dense3Pattern :
286 return QStringLiteral(
"dense3" );
287 case Qt::Dense4Pattern :
288 return QStringLiteral(
"dense4" );
289 case Qt::Dense5Pattern :
290 return QStringLiteral(
"dense5" );
291 case Qt::Dense6Pattern :
292 return QStringLiteral(
"dense6" );
293 case Qt::Dense7Pattern :
294 return QStringLiteral(
"dense7" );
296 return QStringLiteral(
"no" );
298 return QStringLiteral(
"???" );
304 if ( str == QLatin1String(
"solid" ) )
return Qt::SolidPattern;
305 if ( str == QLatin1String(
"horizontal" ) )
return Qt::HorPattern;
306 if ( str == QLatin1String(
"vertical" ) )
return Qt::VerPattern;
307 if ( str == QLatin1String(
"cross" ) )
return Qt::CrossPattern;
308 if ( str == QLatin1String(
"b_diagonal" ) )
return Qt::BDiagPattern;
309 if ( str == QLatin1String(
"f_diagonal" ) )
return Qt::FDiagPattern;
310 if ( str == QLatin1String(
"diagonal_x" ) )
return Qt::DiagCrossPattern;
311 if ( str == QLatin1String(
"dense1" ) )
return Qt::Dense1Pattern;
312 if ( str == QLatin1String(
"dense2" ) )
return Qt::Dense2Pattern;
313 if ( str == QLatin1String(
"dense3" ) )
return Qt::Dense3Pattern;
314 if ( str == QLatin1String(
"dense4" ) )
return Qt::Dense4Pattern;
315 if ( str == QLatin1String(
"dense5" ) )
return Qt::Dense5Pattern;
316 if ( str == QLatin1String(
"dense6" ) )
return Qt::Dense6Pattern;
317 if ( str == QLatin1String(
"dense7" ) )
return Qt::Dense7Pattern;
318 if ( str == QLatin1String(
"no" ) )
return Qt::NoBrush;
319 return Qt::SolidPattern;
326 case Qt::CrossPattern:
327 return QStringLiteral(
"cross" );
328 case Qt::DiagCrossPattern:
329 return QStringLiteral(
"x" );
336 return QStringLiteral(
"horline" );
338 return QStringLiteral(
"line" );
339 case Qt::BDiagPattern:
340 return QStringLiteral(
"slash" );
341 case Qt::FDiagPattern:
342 return QStringLiteral(
"backslash" );
345 case Qt::Dense1Pattern:
346 case Qt::Dense2Pattern:
347 case Qt::Dense3Pattern:
348 case Qt::Dense4Pattern:
349 case Qt::Dense5Pattern:
350 case Qt::Dense6Pattern:
351 case Qt::Dense7Pattern:
361 if ( str == QLatin1String(
"horline" ) )
return Qt::HorPattern;
362 if ( str == QLatin1String(
"line" ) )
return Qt::VerPattern;
363 if ( str == QLatin1String(
"cross" ) )
return Qt::CrossPattern;
364 if ( str == QLatin1String(
"slash" ) )
return Qt::BDiagPattern;
365 if ( str == QLatin1String(
"backshash" ) )
return Qt::FDiagPattern;
366 if ( str == QLatin1String(
"x" ) )
return Qt::DiagCrossPattern;
368 if ( str.startsWith( QLatin1String(
"brush://" ) ) )
380 QString s = value.toString().toLower().trimmed();
381 if ( s == QLatin1String(
"single" ) )
383 else if ( s == QLatin1String(
"reversed" ) )
385 else if ( s == QLatin1String(
"double" ) )
387 else if ( value.toInt() == 1 )
389 else if ( value.toInt() == 2 )
391 else if ( value.toInt( &intOk ) == 0 && intOk )
405 QString s = value.toString().toLower().trimmed();
406 if ( s == QLatin1String(
"plain" ) )
408 else if ( s == QLatin1String(
"lefthalf" ) )
410 else if ( s == QLatin1String(
"righthalf" ) )
412 else if ( value.toInt() == 1 )
414 else if ( value.toInt() == 2 )
416 else if ( value.toInt( &intOk ) == 0 && intOk )
431 QStringList lst = str.split(
',' );
432 if ( lst.count() != 2 )
433 return QPointF( 0, 0 );
434 return QPointF( lst[0].toDouble(), lst[1].toDouble() );
444 QStringList lst =
string.split(
',' );
445 if ( lst.count() != 2 )
446 return QSizeF( 0, 0 );
447 return QSizeF( lst[0].toDouble(), lst[1].toDouble() );
464 if ( str.startsWith( QLatin1String(
"3x:" ) ) )
467 QString chopped = str.mid( 3 );
468 lst = chopped.split(
',' );
472 lst = str.split(
',' );
474 if ( lst.count() < 2 )
477 double minScale = lst[0].toDouble();
479 minScale = minScale != 0 ? 1.0 / minScale : 0;
480 double maxScale = lst[1].toDouble();
482 maxScale = maxScale != 0 ? 1.0 / maxScale : 0;
484 if ( lst.count() < 6 )
504 *scaleFactor = 0.001;
505 return QStringLiteral(
"http://www.opengeospatial.org/se/units/metre" );
512 *scaleFactor = 1 / 0.28;
521 if ( str == QLatin1String(
"http://www.opengeospatial.org/se/units/metre" ) )
524 *scaleFactor = 1000.0;
527 else if ( str == QLatin1String(
"http://www.opengeospatial.org/se/units/foot" ) )
530 *scaleFactor = 304.8;
537 *scaleFactor = 1 / 0.00028;
543 QString vectorString;
544 QVector<qreal>::const_iterator it = v.constBegin();
545 for ( ; it != v.constEnd(); ++it )
547 if ( it != v.constBegin() )
549 vectorString.append(
';' );
551 vectorString.append( QString::number( *it ) );
558 QVector<qreal> resultVector;
560 QStringList realList = s.split(
';' );
561 QStringList::const_iterator it = realList.constBegin();
562 for ( ; it != realList.constEnd(); ++it )
564 resultVector.append( it->toDouble() );
572 QString vectorString;
573 QVector<qreal>::const_iterator it = v.constBegin();
574 for ( ; it != v.constEnd(); ++it )
576 if ( it != v.constBegin() )
578 vectorString.append(
' ' );
580 vectorString.append( QString::number( *it ) );
587 QVector<qreal> resultVector;
589 QStringList realList = s.split(
' ' );
590 QStringList::const_iterator it = realList.constBegin();
591 for ( ; it != realList.constEnd(); ++it )
593 resultVector.append( it->toDouble() );
601 QString encodedValue;
603 switch ( scaleMethod )
606 encodedValue = QStringLiteral(
"diameter" );
609 encodedValue = QStringLiteral(
"area" );
619 if ( str == QLatin1String(
"diameter" ) )
633 if ( s.compare( QLatin1String(
"Lighten" ), Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_Lighten;
634 if ( s.compare( QLatin1String(
"Screen" ), Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_Screen;
635 if ( s.compare( QLatin1String(
"Dodge" ), Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_ColorDodge;
636 if ( s.compare( QLatin1String(
"Addition" ), Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_Plus;
637 if ( s.compare( QLatin1String(
"Darken" ), Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_Darken;
638 if ( s.compare( QLatin1String(
"Multiply" ), Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_Multiply;
639 if ( s.compare( QLatin1String(
"Burn" ), Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_ColorBurn;
640 if ( s.compare( QLatin1String(
"Overlay" ), Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_Overlay;
641 if ( s.compare( QLatin1String(
"SoftLight" ), Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_SoftLight;
642 if ( s.compare( QLatin1String(
"HardLight" ), Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_HardLight;
643 if ( s.compare( QLatin1String(
"Difference" ), Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_Difference;
644 if ( s.compare( QLatin1String(
"Subtract" ), Qt::CaseInsensitive ) == 0 )
return QPainter::CompositionMode_Exclusion;
645 return QPainter::CompositionMode_SourceOver;
656 QPixmap pixmap( size );
657 pixmap.fill( Qt::transparent );
659 painter.begin( &pixmap );
660 painter.setRenderHint( QPainter::Antialiasing );
669 size.setWidth( size.rwidth() - ( padding * 2 ) );
670 size.setHeight( size.rheight() - ( padding * 2 ) );
671 painter.translate( padding, padding );
681 std::unique_ptr<QgsSymbol> symbol_noDD( symbol->
clone( ) );
683 for (
const auto &layer : layers )
685 layer->dataDefinedProperties().clear();
687 symbol_noDD->drawPreviewIcon( &painter, size, customContext );
705 maxBleed = layerMaxBleed > maxBleed ? layerMaxBleed : maxBleed;
715 painter.begin( &picture );
716 painter.setRenderHint( QPainter::Antialiasing );
727 QPixmap pixmap( size );
728 pixmap.fill( Qt::transparent );
730 painter.begin( &pixmap );
731 painter.setRenderHint( QPainter::Antialiasing );
741 return QIcon( pixmap );
751 QPixmap pixmap( size );
752 pixmap.fill( Qt::transparent );
755 painter.begin( &pixmap );
758 drawStippledBackground( &painter, QRect( padding, padding, size.width() - padding * 2, size.height() - padding * 2 ) );
762 for (
int i = 0; i < size.width(); i++ )
764 QPen pen( ramp->
color( static_cast< double >( i ) / size.width() ) );
765 painter.setPen( pen );
766 painter.drawLine( i, 0 + padding, i, size.height() - 1 - padding );
775 uchar pixDataRGB[] = { 255, 255, 255, 255,
780 QImage img( pixDataRGB, 2, 2, 8, QImage::Format_ARGB32 );
782 int width = ( rect.width() < rect.height() ) ?
783 rect.width() / 2.5 : rect.height() / 2.5;
784 QPixmap pix = QPixmap::fromImage( img.scaled( width, width ) );
787 brush.setTexture( pix );
788 painter->fillRect( rect, brush );
793 qreal s = ( markerSize - 1 ) / 2.0;
798 p.setPen( QColor( 50, 100, 120, 200 ) );
799 p.setBrush( QColor( 200, 200, 210, 120 ) );
800 p.drawEllipse( x - s, y - s, s * 2, s * 2 );
803 p.setPen( QColor( 255, 0, 0 ) );
804 p.drawLine( x - s, y + s, x + s, y - s );
805 p.drawLine( x - s, y - s, x + s, y + s );
817 static QPolygonF makeOffsetGeometry(
const QgsPolylineXY &polyline )
819 int i, pointCount = polyline.count();
821 QPolygonF resultLine;
822 resultLine.resize( pointCount );
826 for ( i = 0; i < pointCount; ++i, tempPtr++ )
827 resultLine[i] = QPointF( tempPtr->
x(), tempPtr->
y() );
831 static QList<QPolygonF> makeOffsetGeometry(
const QgsPolygonXY &polygon )
833 QList<QPolygonF> resultGeom;
834 resultGeom.reserve( polygon.size() );
835 for (
int ring = 0; ring < polygon.size(); ++ring )
836 resultGeom.append( makeOffsetGeometry( polygon[ ring ] ) );
842 QList<QPolygonF> resultLine;
844 if ( polyline.count() < 2 )
846 resultLine.append( polyline );
850 unsigned int i, pointCount = polyline.count();
853 QPointF *tempPtr = polyline.data();
854 for ( i = 0; i < pointCount; ++i, tempPtr++ )
855 tempPolyline[i] =
QgsPointXY( tempPtr->rx(), tempPtr->ry() );
858 if ( !tempGeometry.
isNull() )
860 int quadSegments = 0;
861 double miterLimit = 2.0;
869 if ( !offsetGeom.
isNull() )
871 tempGeometry = offsetGeom;
876 resultLine.append( makeOffsetGeometry( line ) );
881 resultLine.append( makeOffsetGeometry( tempGeometry.
asPolygon() ) );
887 resultLine.reserve( tempMPolyline.count() );
888 for (
int part = 0; part < tempMPolyline.count(); ++part )
890 resultLine.append( makeOffsetGeometry( tempMPolyline[ part ] ) );
897 resultLine.reserve( tempMPolygon.count() );
898 for (
int part = 0; part < tempMPolygon.count(); ++part )
900 resultLine.append( makeOffsetGeometry( tempMPolygon[ part ] ) );
908 resultLine.append( polyline );
918 QDomNode layerNode = element.firstChild();
920 while ( !layerNode.isNull() )
922 QDomElement e = layerNode.toElement();
925 if ( e.tagName() != QLatin1String(
"layer" ) )
936 QDomElement s = e.firstChildElement( QStringLiteral(
"symbol" ) );
943 QgsDebugMsg(
"symbol layer refused subsymbol: " + s.attribute(
"name" ) );
946 layers.append( layer );
950 layerNode = layerNode.nextSibling();
953 if ( layers.isEmpty() )
955 QgsDebugMsg( QStringLiteral(
"no layers for symbol" ) );
959 QString symbolType = element.attribute( QStringLiteral(
"type" ) );
962 if ( symbolType == QLatin1String(
"line" ) )
964 else if ( symbolType == QLatin1String(
"fill" ) )
966 else if ( symbolType == QLatin1String(
"marker" ) )
970 QgsDebugMsg(
"unknown symbol type " + symbolType );
974 if ( element.hasAttribute( QStringLiteral(
"outputUnit" ) ) )
978 if ( element.hasAttribute( ( QStringLiteral(
"mapUnitScale" ) ) ) )
981 double oldMin = element.attribute( QStringLiteral(
"mapUnitMinScale" ), QStringLiteral(
"0.0" ) ).toDouble();
982 mapUnitScale.
minScale = oldMin != 0 ? 1.0 / oldMin : 0;
983 double oldMax = element.attribute( QStringLiteral(
"mapUnitMaxScale" ), QStringLiteral(
"0.0" ) ).toDouble();
984 mapUnitScale.
maxScale = oldMax != 0 ? 1.0 / oldMax : 0;
987 symbol->
setOpacity( element.attribute( QStringLiteral(
"alpha" ), QStringLiteral(
"1.0" ) ).toDouble() );
988 symbol->
setClipFeaturesToExtent( element.attribute( QStringLiteral(
"clip_to_extent" ), QStringLiteral(
"1" ) ).toInt() );
989 symbol->
setForceRHR( element.attribute( QStringLiteral(
"force_rhr" ), QStringLiteral(
"0" ) ).toInt() );
995 QString layerClass = element.attribute( QStringLiteral(
"class" ) );
996 bool locked = element.attribute( QStringLiteral(
"locked" ) ).toInt();
997 bool enabled = element.attribute( QStringLiteral(
"enabled" ), QStringLiteral(
"1" ) ).toInt();
998 int pass = element.attribute( QStringLiteral(
"pass" ) ).toInt();
1015 QDomElement effectElem = element.firstChildElement( QStringLiteral(
"effect" ) );
1016 if ( !effectElem.isNull() )
1022 QDomElement ddProps = element.firstChildElement( QStringLiteral(
"data_defined_properties" ) );
1023 if ( !ddProps.isNull() )
1042 return QStringLiteral(
"line" );
1044 return QStringLiteral(
"marker" );
1046 return QStringLiteral(
"fill" );
1055 QDomElement symEl = doc.createElement( QStringLiteral(
"symbol" ) );
1056 symEl.setAttribute( QStringLiteral(
"type" ), _nameForSymbolType( symbol->
type() ) );
1057 symEl.setAttribute( QStringLiteral(
"name" ), name );
1058 symEl.setAttribute( QStringLiteral(
"alpha" ), QString::number( symbol->
opacity() ) );
1059 symEl.setAttribute( QStringLiteral(
"clip_to_extent" ), symbol->
clipFeaturesToExtent() ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
1060 symEl.setAttribute( QStringLiteral(
"force_rhr" ), symbol->
forceRHR() ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
1067 QDomElement layerEl = doc.createElement( QStringLiteral(
"layer" ) );
1068 layerEl.setAttribute( QStringLiteral(
"class" ), layer->
layerType() );
1069 layerEl.setAttribute( QStringLiteral(
"enabled" ), layer->
enabled() );
1070 layerEl.setAttribute( QStringLiteral(
"locked" ), layer->
isLocked() );
1071 layerEl.setAttribute( QStringLiteral(
"pass" ), layer->
renderingPass() );
1082 QDomElement ddProps = doc.createElement( QStringLiteral(
"data_defined_properties" ) );
1084 layerEl.appendChild( ddProps );
1088 QString subname = QStringLiteral(
"@%1@%2" ).arg( name ).arg( i );
1090 layerEl.appendChild( subEl );
1092 symEl.appendChild( layerEl );
1100 QDomDocument doc( QStringLiteral(
"qgis-symbol-definition" ) );
1103 QTextStream stream( &props );
1104 symbolElem.save( stream, -1 );
1114 if ( element.isNull() )
1119 QString symbolizerName = element.localName();
1121 if ( symbolizerName == QLatin1String(
"PointSymbolizer" ) )
1124 QDomElement graphicElem = element.firstChildElement( QStringLiteral(
"Graphic" ) );
1125 if ( graphicElem.isNull() )
1127 QgsDebugMsg( QStringLiteral(
"Graphic element not found in PointSymbolizer" ) );
1163 if ( symbolizerName == QLatin1String(
"LineSymbolizer" ) )
1166 QDomElement strokeElem = element.firstChildElement( QStringLiteral(
"Stroke" ) );
1167 if ( strokeElem.isNull() )
1169 QgsDebugMsg( QStringLiteral(
"Stroke element not found in LineSymbolizer" ) );
1199 if ( symbolizerName == QLatin1String(
"PolygonSymbolizer" ) )
1202 QDomElement fillElem = element.firstChildElement( QStringLiteral(
"Fill" ) );
1203 QDomElement strokeElem = element.firstChildElement( QStringLiteral(
"Stroke" ) );
1204 if ( fillElem.isNull() && strokeElem.isNull() )
1206 QgsDebugMsg( QStringLiteral(
"neither Fill nor Stroke element not found in PolygonSymbolizer" ) );
1224 if ( l->
layerType() == QLatin1String(
"SimpleFill" ) || l->
layerType() == QLatin1String(
"SVGFill" ) )
1260 QDomElement fillElem = element.firstChildElement( QStringLiteral(
"Fill" ) );
1261 if ( fillElem.isNull() )
1263 QgsDebugMsg( QStringLiteral(
"Fill element not found" ) );
1283 QDomElement strokeElem = element.firstChildElement( QStringLiteral(
"Stroke" ) );
1284 if ( strokeElem.isNull() )
1286 QgsDebugMsg( QStringLiteral(
"Stroke element not found" ) );
1302 QDomElement graphicElem = element.firstChildElement( QStringLiteral(
"Graphic" ) );
1303 if ( graphicElem.isNull() )
1305 QgsDebugMsg( QStringLiteral(
"Graphic element not found" ) );
1325 QDomElement graphicElem = element.firstChildElement( QStringLiteral(
"Graphic" ) );
1326 if ( graphicElem.isNull() )
1329 QDomElement externalGraphicElem = graphicElem.firstChildElement( QStringLiteral(
"ExternalGraphic" ) );
1330 if ( externalGraphicElem.isNull() )
1334 QDomElement formatElem = externalGraphicElem.firstChildElement( QStringLiteral(
"Format" ) );
1335 if ( formatElem.isNull() )
1338 QString format = formatElem.firstChild().nodeValue();
1339 if ( format != QLatin1String(
"image/svg+xml" ) )
1341 QgsDebugMsg(
"unsupported External Graphic format found: " + format );
1346 QDomElement onlineResourceElem = externalGraphicElem.firstChildElement( QStringLiteral(
"OnlineResource" ) );
1347 QDomElement inlineContentElem = externalGraphicElem.firstChildElement( QStringLiteral(
"InlineContent" ) );
1348 if ( !onlineResourceElem.isNull() )
1353 else if ( !inlineContentElem.isNull() )
1366 QDomElement graphicElem = element.firstChildElement( QStringLiteral(
"Graphic" ) );
1367 if ( graphicElem.isNull() )
1370 QDomElement markElem = graphicElem.firstChildElement( QStringLiteral(
"Mark" ) );
1371 if ( markElem.isNull() )
1374 QDomElement wellKnownNameElem = markElem.firstChildElement( QStringLiteral(
"WellKnownName" ) );
1375 return !wellKnownNameElem.isNull();
1381 QDomElement graphicElem = element.firstChildElement( QStringLiteral(
"Graphic" ) );
1382 if ( graphicElem.isNull() )
1385 QDomElement markElem = graphicElem.firstChildElement( QStringLiteral(
"Mark" ) );
1386 if ( markElem.isNull() )
1390 QDomElement formatElem = markElem.firstChildElement( QStringLiteral(
"Format" ) );
1391 if ( formatElem.isNull() )
1394 QString format = formatElem.firstChild().nodeValue();
1395 if ( format != QLatin1String(
"ttf" ) )
1397 QgsDebugMsg(
"unsupported Graphic Mark format found: " + format );
1402 QDomElement onlineResourceElem = markElem.firstChildElement( QStringLiteral(
"OnlineResource" ) );
1403 QDomElement inlineContentElem = markElem.firstChildElement( QStringLiteral(
"InlineContent" ) );
1404 if ( !onlineResourceElem.isNull() )
1407 QDomElement markIndexElem = markElem.firstChildElement( QStringLiteral(
"MarkIndex" ) );
1408 if ( !markIndexElem.isNull() )
1411 else if ( !inlineContentElem.isNull() )
1426 QDomElement graphicElem = element.firstChildElement( QStringLiteral(
"Graphic" ) );
1427 if ( graphicElem.isNull() )
1431 for ( QgsStringMap::iterator it = vendorOptions.begin(); it != vendorOptions.end(); ++it )
1433 if ( it.key() == QLatin1String(
"widthHeightFactor" ) )
1444 QDomElement strokeElem = element.firstChildElement( QStringLiteral(
"Stroke" ) );
1445 if ( strokeElem.isNull() )
1448 QDomElement graphicStrokeElem = strokeElem.firstChildElement( QStringLiteral(
"GraphicStroke" ) );
1449 if ( graphicStrokeElem.isNull() )
1457 QDomElement fillElem = element.firstChildElement( QStringLiteral(
"Fill" ) );
1458 if ( fillElem.isNull() )
1461 QDomElement graphicFillElem = fillElem.firstChildElement( QStringLiteral(
"GraphicFill" ) );
1462 if ( graphicFillElem.isNull() )
1465 QDomElement graphicElem = graphicFillElem.firstChildElement( QStringLiteral(
"Graphic" ) );
1466 if ( graphicElem.isNull() )
1472 QColor fillColor, strokeColor;
1473 double size, strokeWidth;
1474 Qt::PenStyle strokeStyle;
1475 if ( !
wellKnownMarkerFromSld( graphicElem, name, fillColor, strokeColor, strokeStyle, strokeWidth, size ) )
1478 if ( name != QLatin1String(
"horline" ) )
1486 double angle = angleFunc.toDouble( &ok );
1492 Q_UNUSED( element );
1498 QDomElement fillElem = element.firstChildElement( QStringLiteral(
"Fill" ) );
1499 if ( fillElem.isNull() )
1502 QDomElement graphicFillElem = fillElem.firstChildElement( QStringLiteral(
"GraphicFill" ) );
1503 if ( graphicFillElem.isNull() )
1523 QDomElement fillElem = element.firstChildElement( QStringLiteral(
"Fill" ) );
1524 QDomElement strokeElem = element.firstChildElement( QStringLiteral(
"Stroke" ) );
1528 bool validFill =
false, validStroke =
false;
1533 Qt::BrushStyle fillStyle;
1535 if (
fillFromSld( fillElem, fillStyle, fillColor ) )
1541 Qt::PenStyle strokeStyle;
1542 double strokeWidth = 1.0, dashOffset = 0.0;
1543 QVector<qreal> customDashPattern;
1545 if (
lineFromSld( strokeElem, strokeStyle, strokeColor, strokeWidth,
1546 nullptr,
nullptr, &customDashPattern, &dashOffset ) )
1549 if ( validFill || validStroke )
1552 map[QStringLiteral(
"name" )] = QStringLiteral(
"square" );
1553 map[QStringLiteral(
"color" )] =
encodeColor( validFill ? fillColor : Qt::transparent );
1554 map[QStringLiteral(
"color_border" )] =
encodeColor( validStroke ? strokeColor : Qt::transparent );
1555 map[QStringLiteral(
"size" )] = QString::number( 6 );
1556 map[QStringLiteral(
"angle" )] = QString::number( 0 );
1557 map[QStringLiteral(
"offset" )] =
encodePoint( QPointF( 0, 0 ) );
1564 bool validFill =
false, validStroke =
false;
1567 QString name, format;
1569 QColor fillColor, strokeColor;
1570 double strokeWidth = 1.0, size = 0.0,
angle = 0.0;
1574 QDomElement graphicFillElem = fillElem.firstChildElement( QStringLiteral(
"GraphicFill" ) );
1575 if ( !graphicFillElem.isNull() )
1578 QDomElement graphicElem = graphicFillElem.firstChildElement( QStringLiteral(
"Graphic" ) );
1579 if ( !graphicElem.isNull() )
1585 QDomElement graphicChildElem = graphicElem.firstChildElement();
1586 while ( !graphicChildElem.isNull() )
1588 if ( graphicChildElem.localName() == QLatin1String(
"Mark" ) )
1591 QDomElement wellKnownNameElem = graphicChildElem.firstChildElement( QStringLiteral(
"WellKnownName" ) );
1592 if ( !wellKnownNameElem.isNull() )
1594 name = wellKnownNameElem.firstChild().nodeValue();
1600 if ( graphicChildElem.localName() == QLatin1String(
"ExternalGraphic" ) || graphicChildElem.localName() == QLatin1String(
"Mark" ) )
1603 QDomElement formatElem = graphicChildElem.firstChildElement( QStringLiteral(
"Format" ) );
1604 if ( formatElem.isNull() )
1607 format = formatElem.firstChild().nodeValue();
1611 if ( graphicChildElem.localName() == QLatin1String(
"ExternalGraphic" ) && format != QLatin1String(
"image/svg+xml" ) )
1616 if ( graphicChildElem.localName() == QLatin1String(
"Mark" ) && format != QLatin1String(
"ttf" ) )
1620 QDomElement onlineResourceElem = graphicChildElem.firstChildElement( QStringLiteral(
"OnlineResource" ) );
1621 QDomElement inlineContentElem = graphicChildElem.firstChildElement( QStringLiteral(
"InlineContent" ) );
1623 if ( !onlineResourceElem.isNull() )
1625 name = onlineResourceElem.attributeNS( QStringLiteral(
"http://www.w3.org/1999/xlink" ), QStringLiteral(
"href" ) );
1627 if ( graphicChildElem.localName() == QLatin1String(
"Mark" ) && format == QLatin1String(
"ttf" ) )
1630 if ( name.startsWith( QLatin1String(
"ttf://" ) ) )
1631 name = name.mid( 6 );
1634 QDomElement markIndexElem = graphicChildElem.firstChildElement( QStringLiteral(
"MarkIndex" ) );
1635 if ( markIndexElem.isNull() )
1639 int v = markIndexElem.firstChild().nodeValue().toInt( &ok );
1650 else if ( !inlineContentElem.isNull() )
1660 if ( graphicChildElem.localName() == QLatin1String(
"Mark" ) )
1662 name = QStringLiteral(
"square" );
1669 if ( found && graphicChildElem.localName() == QLatin1String(
"Mark" ) )
1676 Qt::BrushStyle markFillStyle;
1678 QDomElement markFillElem = graphicChildElem.firstChildElement( QStringLiteral(
"Fill" ) );
1679 if (
fillFromSld( markFillElem, markFillStyle, fillColor ) )
1684 Qt::PenStyle strokeStyle;
1685 double strokeWidth = 1.0, dashOffset = 0.0;
1686 QVector<qreal> customDashPattern;
1688 QDomElement markStrokeElem = graphicChildElem.firstChildElement( QStringLiteral(
"Stroke" ) );
1689 if (
lineFromSld( markStrokeElem, strokeStyle, strokeColor, strokeWidth,
1690 nullptr,
nullptr, &customDashPattern, &dashOffset ) )
1697 QDomElement opacityElem = graphicElem.firstChildElement( QStringLiteral(
"Opacity" ) );
1698 if ( !opacityElem.isNull() )
1699 fillColor.setAlpha(
decodeSldAlpha( opacityElem.firstChild().nodeValue() ) );
1701 QDomElement sizeElem = graphicElem.firstChildElement( QStringLiteral(
"Size" ) );
1702 if ( !sizeElem.isNull() )
1705 double v = sizeElem.firstChild().nodeValue().toDouble( &ok );
1714 double v = angleFunc.toDouble( &ok );
1724 if ( validFill || validStroke )
1726 if ( format == QLatin1String(
"image/svg+xml" ) )
1729 map[QStringLiteral(
"name" )] = name;
1730 map[QStringLiteral(
"fill" )] = fillColor.name();
1731 map[QStringLiteral(
"outline" )] = strokeColor.name();
1732 map[QStringLiteral(
"outline-width" )] = QString::number( strokeWidth );
1734 map[QStringLiteral(
"size" )] = QString::number( size );
1736 map[QStringLiteral(
"angle" )] = QString::number(
angle );
1737 if ( !offset.isNull() )
1738 map[QStringLiteral(
"offset" )] =
encodePoint( offset );
1741 else if ( format == QLatin1String(
"ttf" ) )
1744 map[QStringLiteral(
"font" )] = name;
1745 map[QStringLiteral(
"chr" )] = markIndex;
1746 map[QStringLiteral(
"color" )] =
encodeColor( validFill ? fillColor : Qt::transparent );
1748 map[QStringLiteral(
"size" )] = QString::number( size );
1750 map[QStringLiteral(
"angle" )] = QString::number(
angle );
1751 if ( !offset.isNull() )
1752 map[QStringLiteral(
"offset" )] =
encodePoint( offset );
1758 if ( layers.isEmpty() )
1761 layerList << layers;
1768 QString patternName;
1769 switch ( brushStyle )
1774 case Qt::SolidPattern:
1775 if ( color.isValid() )
1778 if ( color.alpha() < 255 )
1783 case Qt::CrossPattern:
1784 case Qt::DiagCrossPattern:
1785 case Qt::HorPattern:
1786 case Qt::VerPattern:
1787 case Qt::BDiagPattern:
1788 case Qt::FDiagPattern:
1789 case Qt::Dense1Pattern:
1790 case Qt::Dense2Pattern:
1791 case Qt::Dense3Pattern:
1792 case Qt::Dense4Pattern:
1793 case Qt::Dense5Pattern:
1794 case Qt::Dense6Pattern:
1795 case Qt::Dense7Pattern:
1800 element.appendChild( doc.createComment( QStringLiteral(
"Qt::BrushStyle '%1'' not supported yet" ).arg( brushStyle ) ) );
1804 QDomElement graphicFillElem = doc.createElement( QStringLiteral(
"se:GraphicFill" ) );
1805 element.appendChild( graphicFillElem );
1807 QDomElement graphicElem = doc.createElement( QStringLiteral(
"se:Graphic" ) );
1808 graphicFillElem.appendChild( graphicElem );
1810 QColor fillColor = patternName.startsWith( QLatin1String(
"brush://" ) ) ? color : QColor();
1811 QColor strokeColor = !patternName.startsWith( QLatin1String(
"brush://" ) ) ? color : QColor();
1814 wellKnownMarkerToSld( doc, graphicElem, patternName, fillColor, strokeColor, Qt::SolidLine, -1, -1 );
1821 brushStyle = Qt::SolidPattern;
1822 color = QColor( 128, 128, 128 );
1824 if ( element.isNull() )
1826 brushStyle = Qt::NoBrush;
1831 QDomElement graphicFillElem = element.firstChildElement( QStringLiteral(
"GraphicFill" ) );
1833 if ( graphicFillElem.isNull() )
1836 for ( QgsStringMap::iterator it = svgParams.begin(); it != svgParams.end(); ++it )
1838 QgsDebugMsg( QStringLiteral(
"found SvgParameter %1: %2" ).arg( it.key(), it.value() ) );
1840 if ( it.key() == QLatin1String(
"fill" ) )
1841 color = QColor( it.value() );
1842 else if ( it.key() == QLatin1String(
"fill-opacity" ) )
1848 QDomElement graphicElem = graphicFillElem.firstChildElement( QStringLiteral(
"Graphic" ) );
1849 if ( graphicElem.isNull() )
1852 QString patternName = QStringLiteral(
"square" );
1853 QColor fillColor, strokeColor;
1854 double strokeWidth, size;
1855 Qt::PenStyle strokeStyle;
1856 if ( !
wellKnownMarkerFromSld( graphicElem, patternName, fillColor, strokeColor, strokeStyle, strokeWidth, size ) )
1860 if ( brushStyle == Qt::NoBrush )
1863 QColor
c = patternName.startsWith( QLatin1String(
"brush://" ) ) ? fillColor : strokeColor;
1872 Qt::PenStyle penStyle,
const QColor &color,
double width,
1873 const Qt::PenJoinStyle *penJoinStyle,
const Qt::PenCapStyle *penCapStyle,
1874 const QVector<qreal> *customDashPattern,
double dashOffset )
1876 QVector<qreal> dashPattern;
1877 const QVector<qreal> *pattern = &dashPattern;
1879 if ( penStyle == Qt::CustomDashLine && !customDashPattern )
1881 element.appendChild( doc.createComment( QStringLiteral(
"WARNING: Custom dash pattern required but not provided. Using default dash pattern." ) ) );
1882 penStyle = Qt::DashLine;
1894 dashPattern.push_back( 4.0 );
1895 dashPattern.push_back( 2.0 );
1898 dashPattern.push_back( 1.0 );
1899 dashPattern.push_back( 2.0 );
1901 case Qt::DashDotLine:
1902 dashPattern.push_back( 4.0 );
1903 dashPattern.push_back( 2.0 );
1904 dashPattern.push_back( 1.0 );
1905 dashPattern.push_back( 2.0 );
1907 case Qt::DashDotDotLine:
1908 dashPattern.push_back( 4.0 );
1909 dashPattern.push_back( 2.0 );
1910 dashPattern.push_back( 1.0 );
1911 dashPattern.push_back( 2.0 );
1912 dashPattern.push_back( 1.0 );
1913 dashPattern.push_back( 2.0 );
1916 case Qt::CustomDashLine:
1917 Q_ASSERT( customDashPattern );
1918 pattern = customDashPattern;
1922 element.appendChild( doc.createComment( QStringLiteral(
"Qt::BrushStyle '%1'' not supported yet" ).arg( penStyle ) ) );
1926 if ( color.isValid() )
1929 if ( color.alpha() < 255 )
1936 else if ( width == 0 )
1946 if ( !pattern->isEmpty() )
1956 Qt::PenStyle &penStyle, QColor &color,
double &width,
1957 Qt::PenJoinStyle *penJoinStyle, Qt::PenCapStyle *penCapStyle,
1958 QVector<qreal> *customDashPattern,
double *dashOffset )
1962 penStyle = Qt::SolidLine;
1963 color = QColor( 0, 0, 0 );
1966 *penJoinStyle = Qt::BevelJoin;
1968 *penCapStyle = Qt::SquareCap;
1969 if ( customDashPattern )
1970 customDashPattern->clear();
1974 if ( element.isNull() )
1976 penStyle = Qt::NoPen;
1982 for ( QgsStringMap::iterator it = svgParams.begin(); it != svgParams.end(); ++it )
1984 QgsDebugMsg( QStringLiteral(
"found SvgParameter %1: %2" ).arg( it.key(), it.value() ) );
1986 if ( it.key() == QLatin1String(
"stroke" ) )
1988 color = QColor( it.value() );
1990 else if ( it.key() == QLatin1String(
"stroke-opacity" ) )
1994 else if ( it.key() == QLatin1String(
"stroke-width" ) )
1997 double w = it.value().toDouble( &ok );
2001 else if ( it.key() == QLatin1String(
"stroke-linejoin" ) && penJoinStyle )
2005 else if ( it.key() == QLatin1String(
"stroke-linecap" ) && penCapStyle )
2009 else if ( it.key() == QLatin1String(
"stroke-dasharray" ) )
2012 if ( !dashPattern.isEmpty() )
2016 bool dashPatternFound =
false;
2018 if ( dashPattern.count() == 2 )
2020 if ( dashPattern.at( 0 ) == 4.0 &&
2021 dashPattern.at( 1 ) == 2.0 )
2023 penStyle = Qt::DashLine;
2024 dashPatternFound =
true;
2026 else if ( dashPattern.at( 0 ) == 1.0 &&
2027 dashPattern.at( 1 ) == 2.0 )
2029 penStyle = Qt::DotLine;
2030 dashPatternFound =
true;
2033 else if ( dashPattern.count() == 4 )
2035 if ( dashPattern.at( 0 ) == 4.0 &&
2036 dashPattern.at( 1 ) == 2.0 &&
2037 dashPattern.at( 2 ) == 1.0 &&
2038 dashPattern.at( 3 ) == 2.0 )
2040 penStyle = Qt::DashDotLine;
2041 dashPatternFound =
true;
2044 else if ( dashPattern.count() == 6 )
2046 if ( dashPattern.at( 0 ) == 4.0 &&
2047 dashPattern.at( 1 ) == 2.0 &&
2048 dashPattern.at( 2 ) == 1.0 &&
2049 dashPattern.at( 3 ) == 2.0 &&
2050 dashPattern.at( 4 ) == 1.0 &&
2051 dashPattern.at( 5 ) == 2.0 )
2053 penStyle = Qt::DashDotDotLine;
2054 dashPatternFound =
true;
2059 if ( !dashPatternFound )
2061 if ( customDashPattern )
2063 penStyle = Qt::CustomDashLine;
2064 *customDashPattern = dashPattern;
2068 QgsDebugMsg( QStringLiteral(
"custom dash pattern required but not provided. Using default dash pattern." ) );
2069 penStyle = Qt::DashLine;
2074 else if ( it.key() == QLatin1String(
"stroke-dashoffset" ) && dashOffset )
2077 double d = it.value().toDouble( &ok );
2087 const QString &path,
const QString &mime,
2088 const QColor &color,
double size )
2090 QDomElement externalGraphicElem = doc.createElement( QStringLiteral(
"se:ExternalGraphic" ) );
2091 element.appendChild( externalGraphicElem );
2100 QDomElement sizeElem = doc.createElement( QStringLiteral(
"se:Size" ) );
2102 element.appendChild( sizeElem );
2107 const QString &path,
const QColor &fillColor,
double size,
const QColor &strokeColor,
double strokeWidth )
2114 graphicElem.appendChild( doc.createComment( QStringLiteral(
"Parametric SVG" ) ) );
2118 graphicElem.appendChild( doc.createComment( QStringLiteral(
"Plain SVG fallback, no parameters" ) ) );
2121 graphicElem.appendChild( doc.createComment( QStringLiteral(
"Well known marker fallback" ) ) );
2127 QDomElement sizeElem = doc.createElement( QStringLiteral(
"se:Size" ) );
2129 graphicElem.appendChild( sizeElem );
2137 if ( fillColor.isValid() )
2139 url.addQueryItem( QStringLiteral(
"fill" ), fillColor.name() );
2140 url.addQueryItem( QStringLiteral(
"fill-opacity" ),
encodeSldAlpha( fillColor.alpha() ) );
2144 url.addQueryItem( QStringLiteral(
"fill" ), QStringLiteral(
"#000000" ) );
2145 url.addQueryItem( QStringLiteral(
"fill-opacity" ), QStringLiteral(
"1" ) );
2147 if ( strokeColor.isValid() )
2149 url.addQueryItem( QStringLiteral(
"outline" ), strokeColor.name() );
2150 url.addQueryItem( QStringLiteral(
"outline-opacity" ),
encodeSldAlpha( strokeColor.alpha() ) );
2154 url.addQueryItem( QStringLiteral(
"outline" ), QStringLiteral(
"#000000" ) );
2155 url.addQueryItem( QStringLiteral(
"outline-opacity" ), QStringLiteral(
"1" ) );
2157 url.addQueryItem( QStringLiteral(
"outline-width" ), QString::number( strokeWidth ) );
2158 QString params = url.encodedQuery();
2159 if ( params.isEmpty() )
2165 return basePath +
"?" + params;
2170 QString &path, QString &mime,
2171 QColor &color,
double &size )
2176 QDomElement externalGraphicElem = element.firstChildElement( QStringLiteral(
"ExternalGraphic" ) );
2177 if ( externalGraphicElem.isNull() )
2182 QDomElement sizeElem = element.firstChildElement( QStringLiteral(
"Size" ) );
2183 if ( !sizeElem.isNull() )
2186 double s = sizeElem.firstChild().nodeValue().toDouble( &ok );
2195 const QString &path,
const QString &format,
int *markIndex,
2196 const QColor &color,
double size )
2198 QDomElement markElem = doc.createElement( QStringLiteral(
"se:Mark" ) );
2199 element.appendChild( markElem );
2205 QDomElement markIndexElem = doc.createElement( QStringLiteral(
"se:MarkIndex" ) );
2206 markIndexElem.appendChild( doc.createTextNode( QString::number( *markIndex ) ) );
2207 markElem.appendChild( markIndexElem );
2211 QDomElement fillElem = doc.createElement( QStringLiteral(
"se:Fill" ) );
2212 fillToSld( doc, fillElem, Qt::SolidPattern, color );
2213 markElem.appendChild( fillElem );
2218 QDomElement sizeElem = doc.createElement( QStringLiteral(
"se:Size" ) );
2220 element.appendChild( sizeElem );
2225 QString &path, QString &format,
int &markIndex,
2226 QColor &color,
double &size )
2234 QDomElement markElem = element.firstChildElement( QStringLiteral(
"Mark" ) );
2235 if ( markElem.isNull() )
2240 QDomElement markIndexElem = markElem.firstChildElement( QStringLiteral(
"MarkIndex" ) );
2241 if ( !markIndexElem.isNull() )
2244 int i = markIndexElem.firstChild().nodeValue().toInt( &ok );
2250 QDomElement fillElem = markElem.firstChildElement( QStringLiteral(
"Fill" ) );
2251 Qt::BrushStyle b = Qt::SolidPattern;
2256 QDomElement sizeElem = element.firstChildElement( QStringLiteral(
"Size" ) );
2257 if ( !sizeElem.isNull() )
2260 double s = sizeElem.firstChild().nodeValue().toDouble( &ok );
2269 const QString &name,
const QColor &color,
const QColor &strokeColor, Qt::PenStyle strokeStyle,
2270 double strokeWidth,
double size )
2272 QDomElement markElem = doc.createElement( QStringLiteral(
"se:Mark" ) );
2273 element.appendChild( markElem );
2275 QDomElement wellKnownNameElem = doc.createElement( QStringLiteral(
"se:WellKnownName" ) );
2276 wellKnownNameElem.appendChild( doc.createTextNode( name ) );
2277 markElem.appendChild( wellKnownNameElem );
2280 if ( color.isValid() )
2282 QDomElement fillElem = doc.createElement( QStringLiteral(
"se:Fill" ) );
2283 fillToSld( doc, fillElem, Qt::SolidPattern, color );
2284 markElem.appendChild( fillElem );
2288 if ( strokeColor.isValid() )
2290 QDomElement strokeElem = doc.createElement( QStringLiteral(
"se:Stroke" ) );
2291 lineToSld( doc, strokeElem, strokeStyle, strokeColor, strokeWidth );
2292 markElem.appendChild( strokeElem );
2298 QDomElement sizeElem = doc.createElement( QStringLiteral(
"se:Size" ) );
2300 element.appendChild( sizeElem );
2305 QString &name, QColor &color, QColor &strokeColor, Qt::PenStyle &strokeStyle,
2306 double &strokeWidth,
double &size )
2310 name = QStringLiteral(
"square" );
2312 strokeColor = QColor( 0, 0, 0 );
2316 QDomElement markElem = element.firstChildElement( QStringLiteral(
"Mark" ) );
2317 if ( markElem.isNull() )
2320 QDomElement wellKnownNameElem = markElem.firstChildElement( QStringLiteral(
"WellKnownName" ) );
2321 if ( !wellKnownNameElem.isNull() )
2323 name = wellKnownNameElem.firstChild().nodeValue();
2324 QgsDebugMsg(
"found Mark with well known name: " + name );
2328 QDomElement fillElem = markElem.firstChildElement( QStringLiteral(
"Fill" ) );
2329 Qt::BrushStyle b = Qt::SolidPattern;
2334 QDomElement strokeElem = markElem.firstChildElement( QStringLiteral(
"Stroke" ) );
2335 lineFromSld( strokeElem, strokeStyle, strokeColor, strokeWidth );
2339 QDomElement sizeElem = element.firstChildElement( QStringLiteral(
"Size" ) );
2340 if ( !sizeElem.isNull() )
2343 double s = sizeElem.firstChild().nodeValue().toDouble( &ok );
2353 if ( !rotationFunc.isEmpty() )
2355 QDomElement rotationElem = doc.createElement( QStringLiteral(
"se:Rotation" ) );
2357 element.appendChild( rotationElem );
2363 QDomElement rotationElem = element.firstChildElement( QStringLiteral(
"Rotation" ) );
2364 if ( !rotationElem.isNull() )
2374 if ( !alphaFunc.isEmpty() )
2376 QDomElement opacityElem = doc.createElement( QStringLiteral(
"se:Opacity" ) );
2378 element.appendChild( opacityElem );
2384 QDomElement opacityElem = element.firstChildElement( QStringLiteral(
"Opacity" ) );
2385 if ( !opacityElem.isNull() )
2394 if ( offset.isNull() )
2397 QDomElement displacementElem = doc.createElement( QStringLiteral(
"se:Displacement" ) );
2398 element.appendChild( displacementElem );
2400 QDomElement dispXElem = doc.createElement( QStringLiteral(
"se:DisplacementX" ) );
2401 dispXElem.appendChild( doc.createTextNode(
qgsDoubleToString( offset.x(), 2 ) ) );
2403 QDomElement dispYElem = doc.createElement( QStringLiteral(
"se:DisplacementY" ) );
2404 dispYElem.appendChild( doc.createTextNode(
qgsDoubleToString( offset.y(), 2 ) ) );
2406 displacementElem.appendChild( dispXElem );
2407 displacementElem.appendChild( dispYElem );
2414 QDomElement anchorElem = doc.createElement( QStringLiteral(
"se:AnchorPoint" ) );
2415 element.appendChild( anchorElem );
2417 QDomElement anchorXElem = doc.createElement( QStringLiteral(
"se:AnchorPointX" ) );
2418 anchorXElem.appendChild( doc.createTextNode(
qgsDoubleToString( anchor.x() ) ) );
2420 QDomElement anchorYElem = doc.createElement( QStringLiteral(
"se:AnchorPointY" ) );
2421 anchorYElem.appendChild( doc.createTextNode(
qgsDoubleToString( anchor.y() ) ) );
2423 anchorElem.appendChild( anchorXElem );
2424 anchorElem.appendChild( anchorYElem );
2429 offset = QPointF( 0, 0 );
2431 QDomElement displacementElem = element.firstChildElement( QStringLiteral(
"Displacement" ) );
2432 if ( displacementElem.isNull() )
2435 QDomElement dispXElem = displacementElem.firstChildElement( QStringLiteral(
"DisplacementX" ) );
2436 if ( !dispXElem.isNull() )
2439 double offsetX = dispXElem.firstChild().nodeValue().toDouble( &ok );
2441 offset.setX( offsetX );
2444 QDomElement dispYElem = displacementElem.firstChildElement( QStringLiteral(
"DisplacementY" ) );
2445 if ( !dispYElem.isNull() )
2448 double offsetY = dispYElem.firstChild().nodeValue().toDouble( &ok );
2450 offset.setY( offsetY );
2457 const QString &label,
const QFont &font,
2458 const QColor &color,
double size )
2460 QDomElement labelElem = doc.createElement( QStringLiteral(
"se:Label" ) );
2461 labelElem.appendChild( doc.createTextNode( label ) );
2462 element.appendChild( labelElem );
2464 QDomElement fontElem = doc.createElement( QStringLiteral(
"se:Font" ) );
2465 element.appendChild( fontElem );
2469 fontElem.appendChild( createSldParameterElement( doc,
"font-style",
encodeSldFontStyle( font.style() ) ) );
2470 fontElem.appendChild( createSldParameterElement( doc,
"font-weight",
encodeSldFontWeight( font.weight() ) ) );
2475 if ( color.isValid() )
2477 QDomElement fillElem = doc.createElement( QStringLiteral(
"Fill" ) );
2478 fillToSld( doc, fillElem, Qt::SolidPattern, color );
2479 element.appendChild( fillElem );
2484 Qt::PenJoinStyle joinStyle,
2485 Qt::PenCapStyle capStyle,
2487 const QVector<qreal> *dashPattern )
2490 penStyle.append(
"PEN(" );
2491 penStyle.append(
"c:" );
2492 penStyle.append( c.name() );
2493 penStyle.append(
",w:" );
2495 penStyle.append( QString::number( width * mmScaleFactor ) );
2496 penStyle.append(
"mm" );
2499 if ( dashPattern && !dashPattern->isEmpty() )
2501 penStyle.append(
",p:\"" );
2502 QVector<qreal>::const_iterator pIt = dashPattern->constBegin();
2503 for ( ; pIt != dashPattern->constEnd(); ++pIt )
2505 if ( pIt != dashPattern->constBegin() )
2507 penStyle.append(
' ' );
2509 penStyle.append( QString::number( *pIt * mapUnitScaleFactor ) );
2510 penStyle.append(
'g' );
2512 penStyle.append(
'\"' );
2516 penStyle.append(
",cap:" );
2520 penStyle.append(
'p' );
2523 penStyle.append(
'r' );
2527 penStyle.append(
'b' );
2531 penStyle.append(
",j:" );
2532 switch ( joinStyle )
2535 penStyle.append(
'b' );
2538 penStyle.append(
'r' );
2542 penStyle.append(
'm' );
2548 penStyle.append(
",dp:" );
2549 penStyle.append( QString::number( offset * mapUnitScaleFactor ) );
2550 penStyle.append(
'g' );
2553 penStyle.append(
')' );
2560 brushStyle.append(
"BRUSH(" );
2561 brushStyle.append(
"fc:" );
2562 brushStyle.append( fillColor.name() );
2563 brushStyle.append(
')' );
2569 if ( geomFunc.isEmpty() )
2572 QDomElement geometryElem = doc.createElement( QStringLiteral(
"Geometry" ) );
2573 element.appendChild( geometryElem );
2603 QDomElement geometryElem = element.firstChildElement( QStringLiteral(
"Geometry" ) );
2604 if ( geometryElem.isNull() )
2616 element.appendChild( doc.createComment(
"Parser Error: " + expr.
parserErrorString() +
" - Expression was: " + function ) );
2620 if ( !filterElem.isNull() )
2621 element.appendChild( filterElem );
2632 element.appendChild( doc.createComment(
"Parser Error: " + expr.
parserErrorString() +
" - Expression was: " + function ) );
2636 if ( !filterElem.isNull() )
2637 element.appendChild( filterElem );
2644 QDomElement elem = element;
2645 if ( element.tagName() != QLatin1String(
"Filter" ) )
2647 QDomNodeList filterNodes = element.elementsByTagName( QStringLiteral(
"Filter" ) );
2648 if ( !filterNodes.isEmpty() )
2650 elem = filterNodes.at( 0 ).toElement();
2654 if ( elem.isNull() )
2679 const QString &path,
const QString &format )
2683 QDomElement onlineResourceElem = doc.createElement( QStringLiteral(
"se:OnlineResource" ) );
2684 onlineResourceElem.setAttribute( QStringLiteral(
"xlink:type" ), QStringLiteral(
"simple" ) );
2685 onlineResourceElem.setAttribute( QStringLiteral(
"xlink:href" ), url );
2686 element.appendChild( onlineResourceElem );
2688 QDomElement formatElem = doc.createElement( QStringLiteral(
"se:Format" ) );
2689 formatElem.appendChild( doc.createTextNode( format ) );
2690 element.appendChild( formatElem );
2697 QDomElement onlineResourceElem = element.firstChildElement( QStringLiteral(
"OnlineResource" ) );
2698 if ( onlineResourceElem.isNull() )
2701 path = onlineResourceElem.attributeNS( QStringLiteral(
"http://www.w3.org/1999/xlink" ), QStringLiteral(
"href" ) );
2703 QDomElement formatElem = element.firstChildElement( QStringLiteral(
"Format" ) );
2704 if ( formatElem.isNull() )
2707 format = formatElem.firstChild().nodeValue();
2714 QDomElement nodeElem = doc.createElement( QStringLiteral(
"se:SvgParameter" ) );
2715 nodeElem.setAttribute( QStringLiteral(
"name" ), name );
2716 nodeElem.appendChild( doc.createTextNode( value ) );
2725 QDomElement paramElem = element.firstChildElement();
2726 while ( !paramElem.isNull() )
2728 if ( paramElem.localName() == QLatin1String(
"SvgParameter" ) || paramElem.localName() == QLatin1String(
"CssParameter" ) )
2730 QString name = paramElem.attribute( QStringLiteral(
"name" ) );
2731 if ( paramElem.firstChild().nodeType() == QDomNode::TextNode )
2733 value = paramElem.firstChild().nodeValue();
2737 if ( paramElem.firstChild().nodeType() == QDomNode::ElementNode &&
2738 paramElem.firstChild().localName() == QLatin1String(
"Literal" ) )
2740 QgsDebugMsg( paramElem.firstChild().localName() );
2741 value = paramElem.firstChild().firstChild().nodeValue();
2745 QgsDebugMsg( QStringLiteral(
"unexpected child of %1" ).arg( paramElem.localName() ) );
2749 if ( !name.isEmpty() && !value.isEmpty() )
2750 params[ name ] = value;
2753 paramElem = paramElem.nextSiblingElement();
2761 QDomElement nodeElem = doc.createElement( QStringLiteral(
"se:VendorOption" ) );
2762 nodeElem.setAttribute( QStringLiteral(
"name" ), name );
2763 nodeElem.appendChild( doc.createTextNode( value ) );
2771 QDomElement paramElem = element.firstChildElement( QStringLiteral(
"VendorOption" ) );
2772 while ( !paramElem.isNull() )
2774 QString name = paramElem.attribute( QStringLiteral(
"name" ) );
2775 QString value = paramElem.firstChild().nodeValue();
2777 if ( !name.isEmpty() && !value.isEmpty() )
2778 params[ name ] = value;
2780 paramElem = paramElem.nextSiblingElement( QStringLiteral(
"VendorOption" ) );
2790 QDomElement e = element.firstChildElement();
2791 while ( !e.isNull() )
2793 if ( e.tagName() == QLatin1String(
"prop" ) )
2795 QString propKey = e.attribute( QStringLiteral(
"k" ) );
2796 QString propValue = e.attribute( QStringLiteral(
"v" ) );
2797 props[propKey] = propValue;
2799 e = e.nextSiblingElement();
2807 for ( QgsStringMap::iterator it = props.begin(); it != props.end(); ++it )
2809 QDomElement propEl = doc.createElement( QStringLiteral(
"prop" ) );
2810 propEl.setAttribute( QStringLiteral(
"k" ), it.key() );
2811 propEl.setAttribute( QStringLiteral(
"v" ), it.value() );
2812 element.appendChild( propEl );
2821 QDomElement e = element.firstChildElement();
2823 while ( !e.isNull() )
2825 if ( e.tagName() == QLatin1String(
"symbol" ) )
2829 symbols.insert( e.attribute( QStringLiteral(
"name" ) ), symbol );
2835 e = e.nextSiblingElement();
2842 QStringList subsymbols;
2844 for ( QMap<QString, QgsSymbol *>::iterator it = symbols.begin(); it != symbols.end(); ++it )
2846 if ( it.key()[0] !=
'@' )
2850 subsymbols.append( it.key() );
2852 QStringList parts = it.key().split(
'@' );
2853 if ( parts.count() < 3 )
2855 QgsDebugMsg(
"found subsymbol with invalid name: " + it.key() );
2859 QString symname = parts[1];
2860 int symlayer = parts[2].toInt();
2862 if ( !symbols.contains( symname ) )
2864 QgsDebugMsg(
"subsymbol references invalid symbol: " + symname );
2872 QgsDebugMsg(
"subsymbol references invalid symbol layer: " + QString::number( symlayer ) );
2881 QgsDebugMsg(
"symbol layer refused subsymbol: " + it.key() );
2888 for (
int i = 0; i < subsymbols.count(); i++ )
2889 symbols.take( subsymbols[i] );
2896 QDomElement symbolsElem = doc.createElement( tagName );
2899 for ( QMap<QString, QgsSymbol *>::iterator its = symbols.begin(); its != symbols.end(); ++its )
2901 QDomElement symEl =
saveSymbol( its.key(), its.value(), doc, context );
2902 symbolsElem.appendChild( symEl );
2910 qDeleteAll( symbols );
2919 std::unique_ptr< QMimeData >mimeData(
new QMimeData );
2921 QDomDocument symbolDoc;
2923 symbolDoc.appendChild( symbolElem );
2924 mimeData->setText( symbolDoc.toString() );
2927 mimeData->setColorData( symbol->
color() );
2929 return mimeData.release();
2937 QString text = data->text();
2938 if ( !text.isEmpty() )
2943 if ( doc.setContent( text ) )
2945 elem = doc.documentElement();
2947 if ( elem.nodeName() != QStringLiteral(
"symbol" ) )
2948 elem = elem.firstChildElement( QStringLiteral(
"symbol" ) );
2959 QString rampType = element.attribute( QStringLiteral(
"type" ) );
2964 if ( rampType == QLatin1String(
"gradient" ) )
2966 else if ( rampType == QLatin1String(
"random" ) )
2968 else if ( rampType == QLatin1String(
"colorbrewer" ) )
2970 else if ( rampType == QLatin1String(
"cpt-city" ) )
2972 else if ( rampType == QLatin1String(
"preset" ) )
2976 QgsDebugMsg(
"unknown colorramp type " + rampType );
2984 QDomElement rampEl = doc.createElement( QStringLiteral(
"colorramp" ) );
2985 rampEl.setAttribute( QStringLiteral(
"type" ), ramp->
type() );
2986 rampEl.setAttribute( QStringLiteral(
"name" ), name );
2994 QVariantMap rampMap;
2996 rampMap.insert( QStringLiteral(
"type" ), ramp->
type() );
2997 rampMap.insert( QStringLiteral(
"name" ), name );
3001 QVariantMap propertyMap;
3002 for (
auto property = properties.constBegin();
property != properties.constEnd(); ++property )
3004 propertyMap.insert( property.key(),
property.value() );
3007 rampMap.insert( QStringLiteral(
"properties" ), propertyMap );
3013 QVariantMap rampMap = value.toMap();
3015 QString rampType = rampMap.
value( QStringLiteral(
"type" ) ).toString();
3018 QVariantMap propertyMap = rampMap.value( QStringLiteral(
"properties" ) ).toMap();
3021 for (
auto property = propertyMap.constBegin();
property != propertyMap.constEnd(); ++property )
3023 props.insert( property.key(),
property.value().toString() );
3026 if ( rampType == QLatin1String(
"gradient" ) )
3028 else if ( rampType == QLatin1String(
"random" ) )
3030 else if ( rampType == QLatin1String(
"colorbrewer" ) )
3032 else if ( rampType == QLatin1String(
"cpt-city" ) )
3034 else if ( rampType == QLatin1String(
"preset" ) )
3038 QgsDebugMsg(
"unknown colorramp type " + rampType );
3045 if ( !color.isValid() )
3052 return color.name();
3057 QList<QColor> colors;
3060 QStringList components = colorStr.simplified().split( QRegExp(
"(,|\\s)" ) );
3061 QStringList::iterator it = components.begin();
3062 for ( ; it != components.end(); ++it )
3065 if ( result.isValid() )
3070 if ( colors.length() > 0 )
3076 components = colorStr.split( QRegExp(
"(,|\n)" ) );
3077 it = components.begin();
3078 for ( ; it != components.end(); ++it )
3081 if ( result.isValid() )
3086 if ( colors.length() > 0 )
3092 components = colorStr.simplified().split( QString(
' ' ) );
3093 it = components.begin();
3094 for ( ; it != components.end(); ++it )
3097 if ( result.isValid() )
3102 if ( colors.length() > 0 )
3108 components = colorStr.split(
'\n' );
3109 it = components.begin();
3110 for ( ; it != components.end(); ++it )
3113 if ( result.isValid() )
3126 QMimeData *mimeData =
new QMimeData;
3127 mimeData->setColorData( QVariant( color ) );
3128 mimeData->setText( color.name() );
3135 QColor mimeColor = mimeData->colorData().value<QColor>();
3136 if ( mimeColor.isValid() )
3145 if ( textColor.isValid() )
3159 if ( data->hasFormat( QStringLiteral(
"text/xml" ) ) )
3162 QByteArray encodedData = data->data( QStringLiteral(
"text/xml" ) );
3163 QDomDocument xmlDoc;
3164 xmlDoc.setContent( encodedData );
3166 QDomElement dragDataElem = xmlDoc.documentElement();
3167 if ( dragDataElem.tagName() == QLatin1String(
"ColorSchemeModelDragData" ) )
3169 QDomNodeList nodeList = dragDataElem.childNodes();
3170 int nChildNodes = nodeList.size();
3171 QDomElement currentElem;
3173 for (
int i = 0; i < nChildNodes; ++i )
3175 currentElem = nodeList.at( i ).toElement();
3176 if ( currentElem.isNull() )
3181 QPair< QColor, QString> namedColor;
3183 namedColor.second = currentElem.attribute( QStringLiteral(
"label" ), QString() );
3185 mimeColors << namedColor;
3190 if ( mimeColors.length() == 0 && data->hasFormat( QStringLiteral(
"application/x-colorobject-list" ) ) )
3193 QByteArray encodedData = data->data( QStringLiteral(
"application/x-colorobject-list" ) );
3194 QDomDocument xmlDoc;
3195 xmlDoc.setContent( encodedData );
3197 QDomNodeList colorsNodes = xmlDoc.elementsByTagName( QStringLiteral(
"colors" ) );
3198 if ( colorsNodes.length() > 0 )
3200 QDomElement colorsElem = colorsNodes.at( 0 ).toElement();
3201 QDomNodeList colorNodeList = colorsElem.childNodes();
3202 int nChildNodes = colorNodeList.size();
3203 QDomElement currentElem;
3205 for (
int i = 0; i < nChildNodes; ++i )
3208 currentElem = colorNodeList.at( i ).toElement();
3209 if ( currentElem.isNull() )
3214 QDomNodeList colorNodes = currentElem.elementsByTagName( QStringLiteral(
"color" ) );
3215 QDomNodeList nameNodes = currentElem.elementsByTagName( QStringLiteral(
"name" ) );
3217 if ( colorNodes.length() > 0 )
3219 QDomElement colorElem = colorNodes.at( 0 ).toElement();
3221 QStringList colorParts = colorElem.text().simplified().split(
' ' );
3222 if ( colorParts.length() < 3 )
3227 int red = colorParts.at( 0 ).toDouble() * 255;
3228 int green = colorParts.at( 1 ).toDouble() * 255;
3229 int blue = colorParts.at( 2 ).toDouble() * 255;
3230 QPair< QColor, QString> namedColor;
3231 namedColor.first = QColor( red, green, blue );
3232 if ( nameNodes.length() > 0 )
3234 QDomElement nameElem = nameNodes.at( 0 ).toElement();
3235 namedColor.second = nameElem.text();
3237 mimeColors << namedColor;
3243 if ( mimeColors.length() == 0 && data->hasText() )
3247 QList< QColor >::iterator it = parsedColors.begin();
3248 for ( ; it != parsedColors.end(); ++it )
3250 mimeColors << qMakePair( *it, QString() );
3254 if ( mimeColors.length() == 0 && data->hasColor() )
3257 QColor mimeColor = data->colorData().value<QColor>();
3258 if ( mimeColor.isValid() )
3260 mimeColors << qMakePair( mimeColor, QString() );
3270 QMimeData *mimeData =
new QMimeData();
3271 QDomDocument xmlDoc;
3272 QDomElement xmlRootElement = xmlDoc.createElement( QStringLiteral(
"ColorSchemeModelDragData" ) );
3273 xmlDoc.appendChild( xmlRootElement );
3275 QgsNamedColorList::const_iterator colorIt = colorList.constBegin();
3276 for ( ; colorIt != colorList.constEnd(); ++colorIt )
3278 QDomElement namedColor = xmlDoc.createElement( QStringLiteral(
"NamedColor" ) );
3280 namedColor.setAttribute( QStringLiteral(
"label" ), ( *colorIt ).second );
3281 xmlRootElement.appendChild( namedColor );
3283 mimeData->setData( QStringLiteral(
"text/xml" ), xmlDoc.toByteArray() );
3291 colorIt = colorList.constBegin();
3292 QStringList colorListString;
3293 for ( ; colorIt != colorList.constEnd(); ++colorIt )
3295 colorListString << ( *colorIt ).first.name();
3297 mimeData->setText( colorListString.join( QStringLiteral(
"\n" ) ) );
3300 if ( colorList.length() > 0 )
3302 mimeData->setColorData( QVariant( colorList.at( 0 ).first ) );
3310 if ( !file.open( QIODevice::WriteOnly | QIODevice::Truncate ) )
3315 QTextStream stream( &file );
3316 stream <<
"GIMP Palette" << endl;
3317 if ( paletteName.isEmpty() )
3319 stream <<
"Name: QGIS Palette" << endl;
3323 stream <<
"Name: " << paletteName << endl;
3325 stream <<
"Columns: 4" << endl;
3326 stream <<
'#' << endl;
3328 for ( QgsNamedColorList::ConstIterator colorIt = colors.constBegin(); colorIt != colors.constEnd(); ++colorIt )
3330 QColor color = ( *colorIt ).first;
3331 if ( !color.isValid() )
3335 stream << QStringLiteral(
"%1 %2 %3" ).arg( color.red(), 3 ).arg( color.green(), 3 ).arg( color.blue(), 3 );
3336 stream <<
"\t" << ( ( *colorIt ).second.isEmpty() ? color.name() : ( *colorIt ).second ) << endl;
3347 if ( !file.open( QIODevice::ReadOnly ) )
3350 return importedColors;
3353 QTextStream in( &file );
3355 QString line = in.readLine();
3356 if ( !line.startsWith( QLatin1String(
"GIMP Palette" ) ) )
3359 return importedColors;
3363 while ( !in.atEnd() && !line.startsWith( QLatin1String(
"Name:" ) ) && !line.startsWith(
'#' ) )
3365 line = in.readLine();
3367 if ( line.startsWith( QLatin1String(
"Name:" ) ) )
3369 QRegExp nameRx(
"Name:\\s*(\\S.*)$" );
3370 if ( nameRx.indexIn( line ) != -1 )
3372 name = nameRx.cap( 1 );
3377 while ( !in.atEnd() && !line.startsWith(
'#' ) )
3379 line = in.readLine();
3384 return importedColors;
3388 QRegExp rx(
"^\\s*(\\d+)\\s+(\\d+)\\s+(\\d+)(\\s.*)?$" );
3389 while ( !in.atEnd() )
3391 line = in.readLine();
3392 if ( rx.indexIn( line ) == -1 )
3396 int red = rx.cap( 1 ).toInt();
3397 int green = rx.cap( 2 ).toInt();
3398 int blue = rx.cap( 3 ).toInt();
3399 QColor color = QColor( red, green, blue );
3400 if ( !color.isValid() )
3407 if ( rx.captureCount() > 3 )
3409 label = rx.cap( 4 ).simplified();
3416 importedColors << qMakePair( color, label );
3421 return importedColors;
3434 QRegExp hexColorAlphaRx(
"^\\s*#?([0-9a-fA-F]{6})([0-9a-fA-F]{2})\\s*$" );
3435 int hexColorIndex = hexColorAlphaRx.indexIn( colorStr );
3438 if ( hexColorIndex == -1 && QColor::isValidColor( colorStr ) )
3441 parsedColor.setNamedColor( colorStr );
3442 if ( parsedColor.isValid() )
3444 containsAlpha =
false;
3450 if ( hexColorIndex > -1 )
3452 QString hexColor = hexColorAlphaRx.cap( 1 );
3453 parsedColor.setNamedColor( QStringLiteral(
"#" ) + hexColor );
3455 int alphaHex = hexColorAlphaRx.cap( 2 ).toInt( &alphaOk, 16 );
3457 if ( parsedColor.isValid() && alphaOk )
3459 parsedColor.setAlpha( alphaHex );
3460 containsAlpha =
true;
3468 QRegExp hexColorRx2(
"^\\s*(?:[0-9a-fA-F]{3}){1,2}\\s*$" );
3469 if ( hexColorRx2.indexIn( colorStr ) != -1 )
3472 parsedColor.setNamedColor( QStringLiteral(
"#" ) + colorStr );
3473 if ( parsedColor.isValid() )
3475 containsAlpha =
false;
3482 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*$" );
3483 if ( rgbFormatRx.indexIn( colorStr ) != -1 )
3485 int r = rgbFormatRx.cap( 1 ).toInt();
3486 int g = rgbFormatRx.cap( 2 ).toInt();
3487 int b = rgbFormatRx.cap( 3 ).toInt();
3488 parsedColor.setRgb( r, g, b );
3489 if ( parsedColor.isValid() )
3491 containsAlpha =
false;
3497 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*$" );
3498 if ( rgbPercentFormatRx.indexIn( colorStr ) != -1 )
3500 int r = std::round( rgbPercentFormatRx.cap( 1 ).toDouble() * 2.55 );
3501 int g = std::round( rgbPercentFormatRx.cap( 2 ).toDouble() * 2.55 );
3502 int b = std::round( rgbPercentFormatRx.cap( 3 ).toDouble() * 2.55 );
3503 parsedColor.setRgb( r, g, b );
3504 if ( parsedColor.isValid() )
3506 containsAlpha =
false;
3512 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*$" );
3513 if ( rgbaFormatRx.indexIn( colorStr ) != -1 )
3515 int r = rgbaFormatRx.cap( 1 ).toInt();
3516 int g = rgbaFormatRx.cap( 2 ).toInt();
3517 int b = rgbaFormatRx.cap( 3 ).toInt();
3518 int a = std::round( rgbaFormatRx.cap( 4 ).toDouble() * 255.0 );
3519 parsedColor.setRgb( r, g, b, a );
3520 if ( parsedColor.isValid() )
3522 containsAlpha =
true;
3528 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*$" );
3529 if ( rgbaPercentFormatRx.indexIn( colorStr ) != -1 )
3531 int r = std::round( rgbaPercentFormatRx.cap( 1 ).toDouble() * 2.55 );
3532 int g = std::round( rgbaPercentFormatRx.cap( 2 ).toDouble() * 2.55 );
3533 int b = std::round( rgbaPercentFormatRx.cap( 3 ).toDouble() * 2.55 );
3534 int a = std::round( rgbaPercentFormatRx.cap( 4 ).toDouble() * 255.0 );
3535 parsedColor.setRgb( r, g, b, a );
3536 if ( parsedColor.isValid() )
3538 containsAlpha =
true;
3555 QImage::Format format = image->format();
3556 if ( format != QImage::Format_ARGB32_Premultiplied && format != QImage::Format_ARGB32 )
3558 QgsDebugMsg( QStringLiteral(
"no alpha channel." ) );
3563 for (
int heightIndex = 0; heightIndex < image->height(); ++heightIndex )
3565 QRgb *scanLine =
reinterpret_cast< QRgb *
>( image->scanLine( heightIndex ) );
3566 for (
int widthIndex = 0; widthIndex < image->width(); ++widthIndex )
3568 myRgb = scanLine[widthIndex];
3569 if ( format == QImage::Format_ARGB32_Premultiplied )
3570 scanLine[widthIndex] = qRgba( opacity * qRed( myRgb ), opacity * qGreen( myRgb ), opacity * qBlue( myRgb ), opacity * qAlpha( myRgb ) );
3572 scanLine[widthIndex] = qRgba( qRed( myRgb ), qGreen( myRgb ), qBlue( myRgb ), opacity * qAlpha( myRgb ) );
3580 int tab[] = { 14, 10, 8, 6, 5, 5, 4, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2 };
3581 int alpha = ( radius < 1 ) ? 16 : ( radius > 17 ) ? 1 : tab[radius - 1];
3583 if ( image.format() != QImage::Format_ARGB32_Premultiplied
3584 && image.format() != QImage::Format_RGB32 )
3586 image = image.convertToFormat( QImage::Format_ARGB32_Premultiplied );
3589 int r1 = rect.top();
3590 int r2 = rect.bottom();
3591 int c1 = rect.left();
3592 int c2 = rect.right();
3594 int bpl = image.bytesPerLine();
3602 i1 = i2 = ( QSysInfo::ByteOrder == QSysInfo::BigEndian ? 0 : 3 );
3604 for (
int col = c1; col <= c2; col++ )
3606 p = image.scanLine( r1 ) + col * 4;
3607 for (
int i = i1; i <= i2; i++ )
3608 rgba[i] = p[i] << 4;
3611 for (
int j = r1; j < r2; j++, p += bpl )
3612 for (
int i = i1; i <= i2; i++ )
3613 p[i] = ( rgba[i] += ( ( p[i] << 4 ) - rgba[i] ) * alpha / 16 ) >> 4;
3616 for (
int row = r1; row <= r2; row++ )
3618 p = image.scanLine( row ) + c1 * 4;
3619 for (
int i = i1; i <= i2; i++ )
3620 rgba[i] = p[i] << 4;
3623 for (
int j = c1; j < c2; j++, p += 4 )
3624 for (
int i = i1; i <= i2; i++ )
3625 p[i] = ( rgba[i] += ( ( p[i] << 4 ) - rgba[i] ) * alpha / 16 ) >> 4;
3628 for (
int col = c1; col <= c2; col++ )
3630 p = image.scanLine( r2 ) + col * 4;
3631 for (
int i = i1; i <= i2; i++ )
3632 rgba[i] = p[i] << 4;
3635 for (
int j = r1; j < r2; j++, p -= bpl )
3636 for (
int i = i1; i <= i2; i++ )
3637 p[i] = ( rgba[i] += ( ( p[i] << 4 ) - rgba[i] ) * alpha / 16 ) >> 4;
3640 for (
int row = r1; row <= r2; row++ )
3642 p = image.scanLine( row ) + c2 * 4;
3643 for (
int i = i1; i <= i2; i++ )
3644 rgba[i] = p[i] << 4;
3647 for (
int j = c1; j < c2; j++, p -= 4 )
3648 for (
int i = i1; i <= i2; i++ )
3649 p[i] = ( rgba[i] += ( ( p[i] << 4 ) - rgba[i] ) * alpha / 16 ) >> 4;
3655 if ( alpha != 255 && alpha > 0 )
3659 double alphaFactor = alpha / 255.;
3660 int r = 0, g = 0, b = 0;
3661 rgb.getRgb( &r, &g, &b );
3666 rgb.setRgb( r, g, b, alpha );
3668 else if ( alpha == 0 )
3670 rgb.setRgb( 0, 0, 0, 0 );
3676 if ( order == Qt::AscendingOrder )
3690 double dx = directionPoint.x() - startPoint.x();
3691 double dy = directionPoint.y() - startPoint.y();
3692 double length = std::sqrt( dx * dx + dy * dy );
3693 double scaleFactor = distance / length;
3694 return QPointF( startPoint.x() + dx * scaleFactor, startPoint.y() + dy * scaleFactor );
3704 for (
int i = 0; i < svgPaths.size(); i++ )
3706 QDir dir( svgPaths[i] );
3707 Q_FOREACH (
const QString &item, dir.entryList( QDir::Dirs | QDir::NoDotAndDotDot ) )
3709 svgPaths.insert( i + 1, dir.path() +
'/' + item );
3712 Q_FOREACH (
const QString &item, dir.entryList( QStringList(
"*.svg" ), QDir::Files ) )
3715 list.append( dir.path() +
'/' + item );
3727 QStringList svgPaths;
3728 svgPaths.append( directory );
3730 for (
int i = 0; i < svgPaths.size(); i++ )
3732 QDir dir( svgPaths[i] );
3733 Q_FOREACH (
const QString &item, dir.entryList( QDir::Dirs | QDir::NoDotAndDotDot ) )
3735 svgPaths.insert( i + 1, dir.path() +
'/' + item );
3738 Q_FOREACH (
const QString &item, dir.entryList( QStringList(
"*.svg" ), QDir::Files ) )
3740 list.append( dir.path() +
'/' + item );
3752 if ( n.startsWith( QLatin1String(
"base64:" ) ) )
3756 if ( QFileInfo::exists( n ) )
3757 return QFileInfo( n ).canonicalFilePath();
3761 if ( name.contains( QLatin1String(
"://" ) ) )
3764 if ( url.isValid() && !url.scheme().isEmpty() )
3766 if ( url.scheme().compare( QLatin1String(
"file" ), Qt::CaseInsensitive ) == 0 )
3769 name = url.toLocalFile();
3770 if ( QFile( name ).exists() )
3772 return QFileInfo( name ).canonicalFilePath();
3786 for (
int i = 0; i < svgPaths.size(); i++ )
3788 QString svgPath = svgPaths[i];
3789 if ( svgPath.endsWith( QChar(
'/' ) ) )
3800 QString myLocalPath = svgPath + QDir::separator() + name;
3803 if ( QFile( myLocalPath ).exists() )
3806 return QFileInfo( myLocalPath ).canonicalFilePath();
3810 return pathResolver.
readPath( name );
3818 if ( p.startsWith( QLatin1String(
"base64:" ) ) )
3821 if ( !QFileInfo::exists( p ) )
3824 QString path = QFileInfo( p ).canonicalFilePath();
3828 bool isInSvgPaths =
false;
3829 for (
int i = 0; i < svgPaths.size(); i++ )
3831 QString dir = QFileInfo( svgPaths[i] ).canonicalFilePath();
3833 if ( !dir.isEmpty() && path.startsWith( dir ) )
3835 path = path.mid( dir.size() + 1 );
3836 isInSvgPaths =
true;
3851 double cx = 0, cy = 0;
3852 double area, sum = 0;
3853 for (
int i = points.count() - 1, j = 0; j < points.count(); i = j++ )
3855 const QPointF &p1 = points[i];
3856 const QPointF &p2 = points[j];
3857 area = p1.x() * p2.y() - p1.y() * p2.x();
3859 cx += ( p1.x() + p2.x() ) * area;
3860 cy += ( p1.y() + p2.y() ) * area;
3867 if ( points.count() >= 2 )
3868 return QPointF( ( points[0].x() + points[1].x() ) / 2, ( points[0].y() + points[1].y() ) / 2 );
3869 else if ( points.count() == 1 )
3877 return QPointF( cx, cy );
3884 if ( ( rings && rings->count() > 0 ) || !
pointInPolygon( points, centroid ) )
3886 unsigned int i, pointCount = points.count();
3888 for ( i = 0; i < pointCount; ++i ) polyline[i] =
QgsPointXY( points[i].x(), points[i].y() );
3894 QList<QPolygonF>::const_iterator ringIt = rings->constBegin();
3895 for ( ; ringIt != rings->constEnd(); ++ringIt )
3897 pointCount = ( *ringIt ).count();
3899 for ( i = 0; i < pointCount; ++i ) polyline[i] =
QgsPointXY( ( *ringIt )[i].x(), ( *ringIt )[i].y() );
3905 if ( !pointOnSurfaceGeom.
isNull() )
3908 centroid.
setX( point.
x() );
3909 centroid.setY( point.
y() );
3914 return QPointF( centroid.x(), centroid.y() );
3919 bool inside =
false;
3921 double x = point.x();
3922 double y = point.y();
3924 for (
int i = 0, j = points.count() - 1; i < points.count(); i++ )
3926 const QPointF &p1 = points[i];
3927 const QPointF &p2 = points[j];
3932 if ( ( p1.y() < y && p2.y() >= y ) || ( p2.y() < y && p1.y() >= y ) )
3934 if ( p1.x() + ( y - p1.y() ) / ( p2.y() - p1.y() ) * ( p2.x() - p1.x() ) <= x )
3945 if ( fieldOrExpression.isEmpty() )
3964 return static_cast<const QgsExpressionNodeColumnRef *>( n )->name();
3980 QList<double> breaks;
3983 breaks.append( maximum );
3987 int minimumCount =
static_cast< int >( classes ) / 3;
3988 double shrink = 0.75;
3989 double highBias = 1.5;
3990 double adjustBias = 0.5 + 1.5 * highBias;
3991 int divisions = classes;
3992 double h = highBias;
3995 double dx = maximum - minimum;
4005 cell = std::max( std::fabs( minimum ), std::fabs( maximum ) );
4006 if ( adjustBias >= 1.5 * h + 0.5 )
4008 U = 1 + ( 1.0 / ( 1 + h ) );
4012 U = 1 + ( 1.5 / ( 1 + adjustBias ) );
4014 small = dx < ( cell * U * std::max( 1, divisions ) * 1e-07 * 3.0 );
4021 cell = 9 + cell / 10;
4022 cell = cell * shrink;
4024 if ( minimumCount > 1 )
4026 cell = cell / minimumCount;
4032 if ( divisions > 1 )
4034 cell = cell / divisions;
4037 if ( cell < 20 * 1e-07 )
4042 double base = std::pow( 10.0, std::floor( std::log10( cell ) ) );
4044 if ( ( 2 * base ) - cell < h * ( cell - unit ) )
4047 if ( ( 5 * base ) - cell < adjustBias * ( cell - unit ) )
4050 if ( ( 10.0 * base ) - cell < h * ( cell - unit ) )
4057 int start = std::floor( minimum / unit + 1e-07 );
4058 int end = std::ceil( maximum / unit - 1e-07 );
4061 while ( start * unit > minimum + ( 1e-07 * unit ) )
4065 while ( end * unit < maximum - ( 1e-07 * unit ) )
4069 QgsDebugMsg( QStringLiteral(
"pretty classes: %1" ).arg( end ) );
4073 int k = std::floor( 0.5 + end - start );
4074 if ( k < minimumCount )
4076 k = minimumCount - k;
4080 start = start - k / 2 + k % 2;
4084 start = start - k / 2;
4085 end = end + k / 2 + k % 2;
4088 double minimumBreak = start * unit;
4090 int count = end - start;
4092 breaks.reserve( count );
4093 for (
int i = 1; i < count + 1; i++ )
4095 breaks.append( minimumBreak + i * unit );
4098 if ( breaks.isEmpty() )
4101 if ( breaks.first() < minimum )
4103 breaks[0] = minimum;
4105 if ( breaks.last() > maximum )
4107 breaks[breaks.count() - 1] = maximum;
4112 if ( minimum < 0.0 && maximum > 0.0 )
4114 QList<double> breaksMinusZero;
4115 for (
int i = 0; i < breaks.count(); i++ )
4117 breaksMinusZero.append( breaks[i] - 0.0 );
4120 for (
int i = 1; i < breaks.count(); i++ )
4122 if ( std::abs( breaksMinusZero[i] ) < std::abs( breaksMinusZero[i - 1] ) )
4125 breaks[posOfMin] = 0.0;
4134 bool roundToUnit =
false;
4137 if ( props.contains( QStringLiteral(
"uomScale" ) ) )
4140 scale = props.value( QStringLiteral(
"uomScale" ) ).toDouble( &ok );
4149 if ( props.value( QStringLiteral(
"uom" ) ) == QLatin1String(
"http://www.opengeospatial.org/se/units/metre" ) )
4174 scale = 1 / 0.28 * 25.4;
4198 double rescaled = size * scale;
4203 rescaled = std::round( rescaled );
4210 double x =
rescaleUom( point.x(), unit, props );
4211 double y =
rescaleUom( point.y(), unit, props );
4212 return QPointF( x, y );
4217 QVector<qreal> result;
4218 QVector<qreal>::const_iterator it = array.constBegin();
4219 for ( ; it != array.constEnd(); ++it )
4221 result.append(
rescaleUom( *it, unit, props ) );
4228 if ( !props.value( QStringLiteral(
"scaleMinDenom" ), QString() ).isEmpty() )
4230 QDomElement scaleMinDenomElem = doc.createElement( QStringLiteral(
"se:MinScaleDenominator" ) );
4231 scaleMinDenomElem.appendChild( doc.createTextNode(
qgsDoubleToString( props.value( QStringLiteral(
"scaleMinDenom" ) ).toDouble() ) ) );
4232 ruleElem.appendChild( scaleMinDenomElem );
4235 if ( !props.value( QStringLiteral(
"scaleMaxDenom" ), QString() ).isEmpty() )
4237 QDomElement scaleMaxDenomElem = doc.createElement( QStringLiteral(
"se:MaxScaleDenominator" ) );
4238 scaleMaxDenomElem.appendChild( doc.createTextNode(
qgsDoubleToString( props.value( QStringLiteral(
"scaleMaxDenom" ) ).toDouble() ) ) );
4239 ruleElem.appendChild( scaleMaxDenomElem );
4248 double parentScaleMinDenom = props.value( QStringLiteral(
"scaleMinDenom" ), QStringLiteral(
"0" ) ).toDouble( &ok );
4249 if ( !ok || parentScaleMinDenom <= 0 )
4250 props[ QStringLiteral(
"scaleMinDenom" )] = QString::number( mScaleMinDenom );
4252 props[ QStringLiteral(
"scaleMinDenom" )] = QString::number( std::max( parentScaleMinDenom, mScaleMinDenom ) );
4258 double parentScaleMaxDenom = props.value( QStringLiteral(
"scaleMaxDenom" ), QStringLiteral(
"0" ) ).toDouble( &ok );
4259 if ( !ok || parentScaleMaxDenom <= 0 )
4260 props[ QStringLiteral(
"scaleMaxDenom" )] = QString::number( mScaleMaxDenom );
4262 props[ QStringLiteral(
"scaleMaxDenom" )] = QString::number( std::min( parentScaleMaxDenom, mScaleMaxDenom ) );
4270 if ( uom == QLatin1String(
"http://www.opengeospatial.org/se/units/metre" ) )
4272 scale = 1.0 / 0.00028;
4274 else if ( uom == QLatin1String(
"http://www.opengeospatial.org/se/units/foot" ) )
4276 scale = 304.8 / 0.28;
4283 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)
Sets whether rendering operations should use vector operations instead of any faster raster shortcuts...
static QgsSymbolLayerRegistry * symbolLayerRegistry()
Returns the application's symbol layer registry, used for managing symbol layers. ...
The class is used as a container of context for various read/write operations on other objects...
static QgsSymbol * symbolFromMimeData(const QMimeData *data)
Attempts to parse mime data as a symbol.
Meters value as Map units.
static QPixmap symbolPreviewPixmap(QgsSymbol *symbol, QSize size, int padding=0, QgsRenderContext *customContext=nullptr)
Returns a pixmap preview for a color ramp.
static QgsStringMap parseProperties(QDomElement &element)
static QgsSymbolLayer * loadSymbolLayer(QDomElement &element, const QgsReadWriteContext &context)
Reads and returns symbol layer from XML. Caller is responsible for deleting the returned object...
double minSizeMM
The minimum size in millimeters, or 0.0 if unset.
static QgsSymbol::ScaleMethod decodeScaleMethod(const QString &str)
QgsGeometry pointOnSurface() const
Returns a point guaranteed to lie on the surface of a geometry.
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)
bool hasParserError() const
Returns true if an error occurred when parsing the input expression.
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.
virtual bool writeXml(QDomElement &collectionElem, const QgsPropertiesDefinition &definitions) const
Writes the current state of the property collection into an XML element.
Calculate scale by the diameter.
static bool createFunctionElement(QDomDocument &doc, QDomElement &element, const QString &function)
static QString encodeSldAlpha(int alpha)
bool isNull() const
Returns true if the geometry is null (ie, contains no underlying geometry accessible via geometry() )...
Abstract base class for all rendered symbols.
bool clipFeaturesToExtent() const
Returns whether features drawn by the symbol will be clipped to the render context's extent...
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.
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)
int symbolLayerCount() const
Returns the total number of symbol layers contained in the symbol.
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.
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.
QString writePath(const QString &filename) const
Prepare a filename to save it to the project file.
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.
QString readPath(const QString &filename) const
Turn filename read from the project file to an absolute path.
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 enabled() const
Returns true if symbol layer is enabled and will be drawn.
static QPointF polygonPointOnSurface(const QPolygonF &points, QList< QPolygonF > *rings=nullptr)
Calculate a point on the surface of a QPolygonF.
bool forceRHR() const
Returns true if polygon features drawn by the symbol will be reoriented to follow the standard right-...
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.
static QgsColorRamp * create(const QgsStringMap &properties=QgsStringMap())
static void clearSymbolMap(QgsSymbolMap &symbols)
OperationResult addRing(const QVector< QgsPointXY > &ring)
Adds a new ring to this geometry.
static QFont::Style decodeSldFontStyle(const QString &str)
bool hasFeature() const
Returns true if the context has a feature associated with it.
QgsPointXY asPoint() const
Returns the contents of the geometry as a 2-dimensional point.
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.
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.
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...
static bool createExpressionElement(QDomDocument &doc, QDomElement &element, const QString &function)
Creates a OGC Expression element based on the provided function expression.
QMap< QString, QString > QgsStringMap
qreal opacity() const
Returns the opacity for the symbol.
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.
static QIcon symbolLayerPreviewIcon(QgsSymbolLayer *layer, QgsUnitTypes::RenderUnit u, QSize size, const QgsMapUnitScale &scale=QgsMapUnitScale())
Draws a symbol layer preview to an icon.
static QString getSvgParametricPath(const QString &basePath, const QColor &fillColor, const QColor &strokeColor, double strokeWidth)
Encodes a reference to a parametric SVG into a path with parameters according to the SVG Parameters s...
static QVector< qreal > decodeRealVector(const QString &s)
static QString encodeColor(const QColor &color)
QgsMultiPolygonXY asMultiPolygon() const
Returns contents of the geometry as a multi polygon if wkbType is WKBMultiPolygon, otherwise an empty list.
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.
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)
bool hasDataDefinedProperties() const
Returns whether the symbol utilizes any data defined properties.
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)
virtual bool setSubSymbol(QgsSymbol *symbol)
Sets layer's subsymbol. takes ownership of the passed symbol.
static QgsUnitTypes::RenderUnit decodeSldUom(const QString &str, double *scaleFactor)
Decodes a SLD unit of measure string to a render unit.
static QgsNamedColorList importColorsFromGpl(QFile &file, bool &ok, QString &name)
Imports colors from a gpl GIMP palette file.
static QIcon symbolPreviewIcon(QgsSymbol *symbol, QSize size, int padding=0)
Returns an icon preview for a color ramp.
#define QgsDebugMsgLevel(str, level)
QgsSymbolLayer * createSymbolLayer(const QString &name, const QgsStringMap &properties=QgsStringMap()) const
create a new instance of symbol layer given symbol layer name and properties
static QDomElement saveSymbols(QgsSymbolMap &symbols, const QString &tagName, QDomDocument &doc, const QgsReadWriteContext &context)
Writes a collection of symbols to XML with specified tagName for the top-level element.
static void externalGraphicToSld(QDomDocument &doc, QDomElement &element, const QString &path, const QString &mime, const QColor &color, double size=-1)
static QString encodeSldRealVector(const QVector< qreal > &v)
static bool needEllipseMarker(QDomElement &element)
void setOpacity(qreal opacity)
Sets the opacity for the symbol.
static QgsStringMap getVendorOptionList(QDomElement &element)
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.
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.
QgsPolylineXY asPolyline() const
Returns the contents of the geometry as a polyline.
static QString encodeSldLineJoinStyle(Qt::PenJoinStyle style)
points (e.g., for font sizes)
static QgsRenderContext fromQPainter(QPainter *painter)
Creates a default render context given a pixel based QPainter destination.
QList< QPair< QColor, QString > > QgsNamedColorList
List of colors paired with a friendly display name identifying the color.
static QgsSymbolLayer * createMarkerLayerFromSld(QDomElement &element)
static void createRotationElement(QDomDocument &doc, QDomElement &element, const QString &rotationFunc)
ArrowType
Possible arrow types.
void drawPreviewIcon(QPainter *painter, QSize size, QgsRenderContext *customContext=nullptr)
Draws an icon of the symbol that occupies an area given by size using the specified painter...
QList< QgsSymbolLayer * > QgsSymbolLayerList
void setPainter(QPainter *p)
Sets the destination QPainter for the render operation.
QgsSymbolLayer * createSymbolLayerFromSld(const QString &name, QDomElement &element) const
create a new instance of symbol layer given symbol layer name and SLD
static QgsColorRamp * loadColorRamp(QDomElement &element)
Creates a color ramp from the settings encoded in an XML element.
static QString encodeSldUom(QgsUnitTypes::RenderUnit unit, double *scaleFactor)
Encodes a render unit into an SLD unit of measure string.
virtual void drawPreviewIcon(QgsSymbolRenderContext &context, QSize size)=0
static QgsSymbolLayer * createFillLayerFromSld(QDomElement &element)
int renderingPass() const
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.
QgsMultiPolylineXY asMultiPolyline() const
Returns contents of the geometry as a multi linestring if wkbType is WKBMultiLineString, otherwise an empty list.
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.
static bool lineFromSld(QDomElement &element, Qt::PenStyle &penStyle, QColor &color, double &width, Qt::PenJoinStyle *penJoinStyle=nullptr, Qt::PenCapStyle *penCapStyle=nullptr, QVector< qreal > *customDashPattern=nullptr, double *dashOffset=nullptr)
void setEnabled(bool enabled)
Sets whether symbol layer is enabled and should be drawn.
static QString encodeSldFontStyle(QFont::Style style)
static QStringList listSvgFiles()
Returns a list of all available svg files.
static QgsExpression * fieldOrExpressionToExpression(const QString &fieldOrExpression)
Returns a new valid expression instance for given field or expression string.
static QgsSymbolMap loadSymbols(QDomElement &element, const QgsReadWriteContext &context)
Reads a collection of symbols from XML and returns them in a map. Caller is responsible for deleting ...
QgsSymbolLayer * symbolLayer(int layer)
Returns a specific symbol 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)
static bool fillFromSld(QDomElement &element, Qt::BrushStyle &brushStyle, QColor &color)
void setX(double x)
Sets the x value of the point.
static QString encodeSldFontWeight(int weight)
static void createGeometryElement(QDomDocument &doc, QDomElement &element, const QString &geomFunc)
static QPixmap colorRampPreviewPixmap(QgsColorRamp *ramp, QSize size, int padding=0)
Returns a pixmap preview for a color ramp.
static bool pointInPolygon(const QPolygonF &points, QPointF point)
Calculate whether a point is within of a QPolygonF.
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.
virtual bool saveProperties(QDomDocument &doc, QDomElement &element) const
Saves the current state of the effect to a DOM element.
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.
static void createOpacityElement(QDomDocument &doc, QDomElement &element, const QString &alphaFunc)
static void labelTextToSld(QDomDocument &doc, QDomElement &element, const QString &label, const QFont &font, const QColor &color=QColor(), double size=-1)
static QPicture symbolLayerPreviewPicture(QgsSymbolLayer *layer, QgsUnitTypes::RenderUnit units, QSize size, const QgsMapUnitScale &scale=QgsMapUnitScale())
Draws a symbol layer preview to a QPicture.
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.
Struct for storing maximum and minimum scales for measurements in map units.
static QString encodeBrushStyle(Qt::BrushStyle style)
static void createAnchorPointElement(QDomDocument &doc, QDomElement &element, QPointF anchor)
Creates a SE 1.1 anchor point element as a child of the specified element.
virtual QgsSymbol * clone() const =0
Returns a deep copy of this symbol.
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.
QgsPaintEffect * paintEffect() const
Returns the current paint effect for the layer.
SymbolType type() const
Returns the symbol's type.
virtual double estimateMaxBleed(const QgsRenderContext &context) const
Returns the estimated maximum distance which the layer style will bleed outside the drawn shape when ...
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)
const QgsExpressionNode * rootNode() const
Returns root node of the expression. Root node is null is parsing has failed.
const QgsPathResolver & pathResolver() const
Returns path resolver for conversion between relative and absolute paths.
static QMimeData * colorListToMimeData(const QgsNamedColorList &colorList, bool allFormats=true)
Creates mime data from a list of named colors.
QString expression() const
Returns the original, unmodified expression string.
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)
A fill symbol type, for rendering Polygon and MultiPolygon geometries.
static void fillToSld(QDomDocument &doc, QDomElement &element, Qt::BrushStyle brushStyle, const QColor &color=QColor())
static void lineToSld(QDomDocument &doc, QDomElement &element, Qt::PenStyle penStyle, const QColor &color, double width=-1, const Qt::PenJoinStyle *penJoinStyle=nullptr, const Qt::PenCapStyle *penCapStyle=nullptr, const QVector< qreal > *customDashPattern=nullptr, double dashOffset=0.0)
static QString svgSymbolNameToPath(const QString &name, const QgsPathResolver &pathResolver)
Determines an SVG symbol's path from its name.
void resolvePaths(const QString &name, QgsStringMap &properties, const QgsPathResolver &pathResolver, bool saving) const
Resolve paths in properties of a particular symbol layer.
static QString encodePenCapStyle(Qt::PenCapStyle style)
void appendScopes(const QList< QgsExpressionContextScope * > &scopes)
Appends a list of scopes to the end of the context.
void setClipFeaturesToExtent(bool clipFeaturesToExtent)
Sets whether features drawn by the symbol should be clipped to the render context's extent...
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.
QColor color() const
Returns the symbol's color.
double minScale
The minimum scale, or 0.0 if unset.
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.
QString parserErrorString() const
Returns parser error.
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.
QgsWkbTypes::Type wkbType() const
Returns type of the geometry as a WKB type (point / linestring / polygon etc.)
bool maxSizeMMEnabled
Whether the maximum size in mm should be respected.
static void saveProperties(QgsStringMap props, QDomDocument &doc, QDomElement &element)
static Qt::PenJoinStyle decodeSldLineJoinStyle(const QString &str)
static bool createSymbolLayerListFromSld(QDomElement &element, QgsWkbTypes::GeometryType geomType, QgsSymbolLayerList &layers)
static QList< QColor > parseColorList(const QString &colorStr)
Attempts to parse a string as a list of colors using a variety of common formats, including hex codes...
static void drawStippledBackground(QPainter *painter, QRect rect)
static QString encodeSldLineCapStyle(Qt::PenCapStyle style)
static QString encodePenJoinStyle(Qt::PenJoinStyle style)
static QString encodeRealVector(const QVector< qreal > &v)
RenderUnit
Rendering size units.
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.
QgsPolygonXY asPolygon() const
Returns the contents of the geometry as a polygon.