33 #include <QTextStream>
34 #include <QDomDocument>
35 #include <QRegularExpression>
73 Q_UNUSED( newVersion )
74 bool returnValue =
false;
107 if ( !mDom.isNull() )
111 if ( transformer.to >= mCurrentVersion && ( transformer.from == mCurrentVersion || transformer.from.
isNull() ) )
114 ( *( transformer.transformFunc ) )( this );
115 mCurrentVersion = transformer.to;
125 QgsDebugMsg( QStringLiteral(
"Current project file version is %1.%2.%3" )
131 std::cout << mDom.toString( 2 ).toLatin1().constData();
142 if ( ! pft->
dom().isNull() )
146 QDomElement mapCanvas;
149 QDomNode qgis = pft->
dom().firstChildElement( QStringLiteral(
"qgis" ) );
150 if ( ! qgis.isNull() )
152 QgsDebugMsg( QStringLiteral(
"Populating new mapcanvas" ) );
155 mapCanvas = pft->
dom().createElement( QStringLiteral(
"mapcanvas" ) );
157 qgis.appendChild( mapCanvas );
159 mapCanvas.appendChild( qgis.namedItem( QStringLiteral(
"units" ) ) );
161 mapCanvas.appendChild( qgis.namedItem( QStringLiteral(
"extent" ) ) );
165 const QDomElement properties = qgis.firstChildElement( QStringLiteral(
"properties" ) );
166 const QDomElement spatial = properties.firstChildElement( QStringLiteral(
"SpatialRefSys" ) );
167 const QDomElement hasCrsTransformEnabled = spatial.firstChildElement( QStringLiteral(
"ProjectionsEnabled" ) );
170 QDomElement projection = pft->
dom().createElement( QStringLiteral(
"projections" ) );
171 QgsDebugMsg( QStringLiteral(
"Projection flag: " ) + hasCrsTransformEnabled.text() );
173 projection.appendChild( pft->
dom().createTextNode( hasCrsTransformEnabled.text() ) );
175 mapCanvas.appendChild( projection );
182 const QDomNodeList mapLayers = pft->
dom().elementsByTagName( QStringLiteral(
"maplayer" ) );
183 bool doneDestination =
false;
184 for (
int i = 0; i < mapLayers.count(); i++ )
186 QDomNode mapLayer = mapLayers.item( i );
188 const QDomNode coordinateTransform = mapLayer.namedItem( QStringLiteral(
"coordinatetransform" ) );
190 const QDomNode sourceCrs = coordinateTransform.namedItem( QStringLiteral(
"sourcesrs" ) );
192 sourceCrs.toElement().setTagName( QStringLiteral(
"srs" ) );
194 mapLayer.appendChild( sourceCrs );
197 if ( ! doneDestination )
200 const QDomNode destinationCRS = coordinateTransform.namedItem( QStringLiteral(
"destinationsrs" ) );
203 mapCanvas.appendChild( destinationCRS );
205 doneDestination =
true;
207 mapLayer.removeChild( coordinateTransform );
214 const QDomNodeList legendLayerFiles = pft->
dom().elementsByTagName( QStringLiteral(
"legendlayerfile" ) );
215 QgsDebugMsg( QStringLiteral(
"Legend layer file entries: " ) + QString::number( legendLayerFiles.count() ) );
216 for (
int i = 0; i < mapLayers.count(); i++ )
219 const QDomElement mapLayer = mapLayers.item( i ).toElement();
221 const QString
id = mapLayer.firstChildElement( QStringLiteral(
"id" ) ).text();
222 QgsDebugMsg( QStringLiteral(
"Handling layer %1" ).arg(
id ) );
224 for (
int j = 0; j < legendLayerFiles.count(); j++ )
226 QDomElement legendLayerFile = legendLayerFiles.item( j ).toElement();
227 if (
id == legendLayerFile.attribute( QStringLiteral(
"layerid" ) ) )
230 QgsDebugMsg( QStringLiteral(
"Found matching id" ) );
233 legendLayerFile.setAttribute( QStringLiteral(
"visible" ), mapLayer.attribute( QStringLiteral(
"visible" ) ) );
236 legendLayerFile.setAttribute( QStringLiteral(
"isInOverview" ), mapLayer.attribute( QStringLiteral(
"showInOverviewFlag" ) ) );
245 if ( ! pft->
dom().isNull() )
248 const QDomNodeList rasterPropertyList = pft->
dom().elementsByTagName( QStringLiteral(
"rasterproperties" ) );
249 QgsDebugMsg( QStringLiteral(
"Raster properties file entries: " ) + QString::number( rasterPropertyList.count() ) );
250 for (
int i = 0; i < rasterPropertyList.count(); i++ )
253 const QDomNode rasterProperty = rasterPropertyList.item( i );
256 rasterProperty.namedItem( QStringLiteral(
"stdDevsToPlotDouble" ) ).toElement().setTagName( QStringLiteral(
"mStandardDeviations" ) );
258 rasterProperty.namedItem( QStringLiteral(
"invertHistogramFlag" ) ).toElement().setTagName( QStringLiteral(
"mInvertPixelsFlag" ) );
259 rasterProperty.namedItem( QStringLiteral(
"showDebugOverLayFlag" ) ).toElement().setTagName( QStringLiteral(
"mDebugOverLayFlag" ) );
261 rasterProperty.namedItem( QStringLiteral(
"redBandNameQString" ) ).toElement().setTagName( QStringLiteral(
"mRedBandName" ) );
262 rasterProperty.namedItem( QStringLiteral(
"blueBandNameQString" ) ).toElement().setTagName( QStringLiteral(
"mBlueBandName" ) );
263 rasterProperty.namedItem( QStringLiteral(
"greenBandNameQString" ) ).toElement().setTagName( QStringLiteral(
"mGreenBandName" ) );
264 rasterProperty.namedItem( QStringLiteral(
"grayBandNameQString" ) ).toElement().setTagName( QStringLiteral(
"mGrayBandName" ) );
268 const QDomNodeList symbolPropertyList = pft->
dom().elementsByTagName( QStringLiteral(
"symbol" ) );
269 for (
int i = 0; i < symbolPropertyList.count(); i++ )
272 QDomNode symbolProperty = symbolPropertyList.item( i );
274 const QDomElement pointSymbol = symbolProperty.firstChildElement( QStringLiteral(
"pointsymbol" ) );
275 if ( pointSymbol.text().startsWith( QLatin1String(
"hard:" ) ) )
278 const int lineWidth = symbolProperty.firstChildElement( QStringLiteral(
"outlinewidth" ) ).text().toInt();
279 int pointSize = symbolProperty.firstChildElement( QStringLiteral(
"pointsize" ) ).text().toInt();
281 if ( pointSize != 0 )
286 pointSize = pointSize + 2 + 2 * lineWidth;
287 QgsDebugMsg( QStringLiteral(
"Setting point size to %1" ).arg( pointSize ) );
288 QDomElement newPointSizeProperty = pft->
dom().createElement( QStringLiteral(
"pointsize" ) );
289 const QDomText newPointSizeTxt = pft->
dom().createTextNode( QString::number( pointSize ) );
290 newPointSizeProperty.appendChild( newPointSizeTxt );
291 symbolProperty.replaceChild( newPointSizeProperty, pointSymbol );
301 if ( ! pft->
dom().isNull() )
303 #ifndef QT_NO_PRINTER
305 const QPrinter myPrinter( QPrinter::ScreenResolution );
306 const int screenDpi = myPrinter.resolution();
307 const double widthScaleFactor = 25.4 / screenDpi;
309 const QDomNodeList outlineWidthList = pft->
dom().elementsByTagName( QStringLiteral(
"outlinewidth" ) );
310 for (
int i = 0; i < outlineWidthList.size(); ++i )
313 QDomElement currentOutlineElem = outlineWidthList.at( i ).toElement();
314 double outlineWidth = currentOutlineElem.text().toDouble();
315 outlineWidth *= widthScaleFactor;
318 const QDomNode outlineTextNode = currentOutlineElem.firstChild();
319 const QDomText newOutlineText = pft->
dom().createTextNode( QString::number( outlineWidth ) );
320 currentOutlineElem.replaceChild( newOutlineText, outlineTextNode );
325 const QDomNodeList pointSizeList = pft->
dom().elementsByTagName( QStringLiteral(
"pointsize" ) );
326 for (
int i = 0; i < pointSizeList.size(); ++i )
329 QDomElement currentPointSizeElem = pointSizeList.at( i ).toElement();
330 double pointSize = currentPointSizeElem.text().toDouble();
331 pointSize *= widthScaleFactor;
334 const QDomNode pointSizeTextNode = currentPointSizeElem.firstChild();
335 const QDomText newPointSizeText = pft->
dom().createTextNode( QString::number(
static_cast< int >( pointSize ) ) );
336 currentPointSizeElem.replaceChild( newPointSizeText, pointSizeTextNode );
344 if ( ! pft->
dom().isNull() )
346 const QDomNodeList layerList = pft->
dom().elementsByTagName( QStringLiteral(
"maplayer" ) );
347 for (
int i = 0; i < layerList.size(); ++i )
349 const QDomElement layerElem = layerList.at( i ).toElement();
350 const QString typeString = layerElem.attribute( QStringLiteral(
"type" ) );
351 if ( typeString != QLatin1String(
"vector" ) )
357 const QDomNode dataSourceNode = layerElem.namedItem( QStringLiteral(
"datasource" ) );
358 if ( dataSourceNode.isNull() )
362 const QString dataSource = dataSourceNode.toElement().text();
365 const QDomNode providerNode = layerElem.namedItem( QStringLiteral(
"provider" ) );
366 if ( providerNode.isNull() )
370 const QString providerKey = providerNode.toElement().text();
374 options.loadDefaultStyle =
false;
390 const QDomNodeList classificationFieldList = layerElem.elementsByTagName( QStringLiteral(
"classificationfield" ) );
391 for (
int j = 0; j < classificationFieldList.size(); ++j )
393 QDomElement classificationFieldElem = classificationFieldList.
at( j ).toElement();
394 const int fieldNumber = classificationFieldElem.text().toInt();
395 if ( fieldNumber >= 0 && fieldNumber < fields.
count() )
397 const QDomText fieldName = pft->
dom().createTextNode( fields.
at( fieldNumber ).
name() );
398 const QDomNode nameNode = classificationFieldElem.firstChild();
399 classificationFieldElem.replaceChild( fieldName, nameNode );
410 if ( pft->
dom().isNull() )
413 const QDomNode qgis = pft->
dom().firstChildElement( QStringLiteral(
"qgis" ) );
417 const QDomElement properties = qgis.firstChildElement( QStringLiteral(
"properties" ) );
418 if ( properties.isNull() )
421 QDomElement digitizing = properties.firstChildElement( QStringLiteral(
"Digitizing" ) );
422 if ( digitizing.isNull() )
425 const QDomElement tolList = digitizing.firstChildElement( QStringLiteral(
"LayerSnappingToleranceList" ) );
426 if ( tolList.isNull() )
429 const QDomElement tolUnitList = digitizing.firstChildElement( QStringLiteral(
"LayerSnappingToleranceUnitList" ) );
430 if ( !tolUnitList.isNull() )
434 for (
int i = 0; i < tolList.childNodes().count(); i++ )
435 units << QStringLiteral(
"0" );
438 value.
writeXml( QStringLiteral(
"LayerSnappingToleranceUnitList" ), digitizing, pft->
dom() );
444 if ( pft->
dom().isNull() )
449 const QDomNodeList layerItemList = pft->
dom().elementsByTagName( QStringLiteral(
"LayerItem" ) );
450 QDomElement currentLayerItemElem;
451 QString currentLayerId;
453 for (
int i = 0; i < layerItemList.size(); ++i )
455 currentLayerItemElem = layerItemList.at( i ).toElement();
456 if ( currentLayerItemElem.isNull() )
460 currentLayerId = currentLayerItemElem.attribute( QStringLiteral(
"layerId" ) );
462 const QDomNodeList vectorClassificationList = currentLayerItemElem.elementsByTagName( QStringLiteral(
"VectorClassificationItem" ) );
463 QDomElement currentClassificationElem;
464 for (
int j = 0; j < vectorClassificationList.size(); ++j )
466 currentClassificationElem = vectorClassificationList.at( j ).toElement();
467 if ( !currentClassificationElem.isNull() )
469 currentClassificationElem.setAttribute( QStringLiteral(
"layerId" ), currentLayerId );
474 const QDomNodeList textItemList = currentLayerItemElem.elementsByTagName( QStringLiteral(
"TextItem" ) );
475 QDomElement currentTextItem;
477 for (
int j = 0; j < textItemList.size(); ++j )
479 currentTextItem = textItemList.at( j ).toElement();
480 if ( currentTextItem.isNull() )
485 QDomElement classificationElement;
486 if ( !vectorClassificationList.isEmpty() )
488 classificationElement = pft->
dom().createElement( QStringLiteral(
"VectorClassificationItem" ) );
492 classificationElement = pft->
dom().createElement( QStringLiteral(
"RasterClassificationItem" ) );
495 classificationElement.setAttribute( QStringLiteral(
"layerId" ), currentLayerId );
496 classificationElement.setAttribute( QStringLiteral(
"text" ), currentTextItem.attribute( QStringLiteral(
"text" ) ) );
497 currentLayerItemElem.replaceChild( classificationElement, currentTextItem );
504 if ( pft->
dom().isNull() )
512 const QDomNodeList layerItemList = pft->
dom().elementsByTagName( QStringLiteral(
"rasterproperties" ) );
513 for (
int i = 0; i < layerItemList.size(); ++i )
515 QDomElement rasterPropertiesElem = layerItemList.at( i ).toElement();
516 QDomNode layerNode = rasterPropertiesElem.parentNode();
517 const QDomElement dataSourceElem = layerNode.firstChildElement( QStringLiteral(
"datasource" ) );
518 const QDomElement layerNameElem = layerNode.firstChildElement( QStringLiteral(
"layername" ) );
522 rasterLayer.
readLayerXml( layerNode.toElement(), context );
528 const QDomNodeList composerMapList = pft->
dom().elementsByTagName( QStringLiteral(
"ComposerMap" ) );
529 for (
int i = 0; i < composerMapList.size(); ++i )
531 const QDomNodeList gridList = composerMapList.at( i ).toElement().elementsByTagName( QStringLiteral(
"Grid" ) );
532 for (
int j = 0; j < gridList.size(); ++j )
534 const QDomNodeList annotationList = gridList.at( j ).toElement().elementsByTagName( QStringLiteral(
"Annotation" ) );
535 for (
int k = 0; k < annotationList.size(); ++k )
537 QDomElement annotationElem = annotationList.at( k ).toElement();
540 if ( annotationElem.hasAttribute( QStringLiteral(
"position" ) ) )
542 const int pos = annotationElem.attribute( QStringLiteral(
"position" ) ).toInt();
543 annotationElem.setAttribute( QStringLiteral(
"leftPosition" ), pos );
544 annotationElem.setAttribute( QStringLiteral(
"rightPosition" ), pos );
545 annotationElem.setAttribute( QStringLiteral(
"topPosition" ), pos );
546 annotationElem.setAttribute( QStringLiteral(
"bottomPosition" ), pos );
547 annotationElem.removeAttribute( QStringLiteral(
"position" ) );
551 if ( annotationElem.hasAttribute( QStringLiteral(
"direction" ) ) )
553 const int dir = annotationElem.attribute( QStringLiteral(
"direction" ) ).toInt();
556 annotationElem.setAttribute( QStringLiteral(
"leftDirection" ), 0 );
557 annotationElem.setAttribute( QStringLiteral(
"rightDirection" ), 0 );
558 annotationElem.setAttribute( QStringLiteral(
"topDirection" ), 1 );
559 annotationElem.setAttribute( QStringLiteral(
"bottomDirection" ), 1 );
563 annotationElem.setAttribute( QStringLiteral(
"leftDirection" ), 1 );
564 annotationElem.setAttribute( QStringLiteral(
"rightDirection" ), 1 );
565 annotationElem.setAttribute( QStringLiteral(
"topDirection" ), 0 );
566 annotationElem.setAttribute( QStringLiteral(
"bottomDirection" ), 0 );
570 annotationElem.setAttribute( QStringLiteral(
"leftDirection" ), dir );
571 annotationElem.setAttribute( QStringLiteral(
"rightDirection" ), dir );
572 annotationElem.setAttribute( QStringLiteral(
"topDirection" ), dir );
573 annotationElem.setAttribute( QStringLiteral(
"bottomDirection" ), dir );
575 annotationElem.removeAttribute( QStringLiteral(
"direction" ) );
582 const QDomNodeList composerList = pft->
dom().elementsByTagName( QStringLiteral(
"Composer" ) );
583 for (
int i = 0; i < composerList.size(); ++i )
585 QDomElement composerElem = composerList.at( i ).toElement();
588 QDomElement compositionElem = composerElem.firstChildElement( QStringLiteral(
"Composition" ) );
589 if ( compositionElem.isNull() )
594 const QDomNodeList composerChildren = composerElem.childNodes();
596 if ( composerChildren.size() < 1 )
601 for (
int j = composerChildren.size() - 1; j >= 0; --j )
603 const QDomElement childElem = composerChildren.at( j ).toElement();
604 if ( childElem.tagName() == QLatin1String(
"Composition" ) )
609 composerElem.removeChild( childElem );
610 compositionElem.appendChild( childElem );
618 const QDomNodeList rendererList = pft->
dom().elementsByTagName( QStringLiteral(
"renderer-v2" ) );
619 for (
int i = 0; i < rendererList.size(); ++i )
621 const QDomNodeList layerList = rendererList.at( i ).toElement().elementsByTagName( QStringLiteral(
"layer" ) );
622 for (
int j = 0; j < layerList.size(); ++j )
624 const QDomElement layerElem = layerList.at( j ).toElement();
625 if ( layerElem.attribute( QStringLiteral(
"class" ) ) == QLatin1String(
"SimpleFill" ) )
627 const QDomNodeList propList = layerElem.elementsByTagName( QStringLiteral(
"prop" ) );
628 for (
int k = 0; k < propList.size(); ++k )
630 QDomElement propElem = propList.at( k ).toElement();
631 if ( propElem.attribute( QStringLiteral(
"k" ) ) == QLatin1String(
"color" ) || propElem.attribute( QStringLiteral(
"k" ) ) == QLatin1String(
"color_border" ) )
633 propElem.setAttribute( QStringLiteral(
"v" ), propElem.attribute( QStringLiteral(
"v" ) ).section(
',', 0, 2 ) +
",255" );
646 const QDomNodeList composerPictureList = pft->
dom().elementsByTagName( QStringLiteral(
"ComposerPicture" ) );
647 for (
int i = 0; i < composerPictureList.size(); ++i )
649 QDomElement picture = composerPictureList.at( i ).toElement();
650 picture.setAttribute( QStringLiteral(
"anchorPoint" ), QString::number( 4 ) );
657 QDomElement propsElem = pft->
dom().firstChildElement( QStringLiteral(
"qgis" ) ).toElement().firstChildElement( QStringLiteral(
"properties" ) );
658 if ( !propsElem.isNull() )
660 const QDomNodeList srsNodes = propsElem.elementsByTagName( QStringLiteral(
"SpatialRefSys" ) );
662 QDomElement projElem;
663 if ( srsNodes.count() > 0 )
665 srsElem = srsNodes.at( 0 ).toElement();
666 const QDomNodeList projNodes = srsElem.elementsByTagName( QStringLiteral(
"ProjectionsEnabled" ) );
667 if ( projNodes.count() == 0 )
669 projElem = pft->
dom().createElement( QStringLiteral(
"ProjectionsEnabled" ) );
670 projElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"int" ) );
671 const QDomText projText = pft->
dom().createTextNode( QStringLiteral(
"0" ) );
672 projElem.appendChild( projText );
673 srsElem.appendChild( projElem );
678 srsElem = pft->
dom().createElement( QStringLiteral(
"SpatialRefSys" ) );
679 projElem = pft->
dom().createElement( QStringLiteral(
"ProjectionsEnabled" ) );
680 projElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"int" ) );
681 const QDomText projText = pft->
dom().createTextNode( QStringLiteral(
"0" ) );
682 projElem.appendChild( projText );
683 srsElem.appendChild( projElem );
684 propsElem.appendChild( srsElem );
690 const QDomNodeList canvasNodes = pft->
dom().elementsByTagName( QStringLiteral(
"mapcanvas" ) );
691 if ( canvasNodes.count() > 0 )
693 const QDomElement canvasElem = canvasNodes.at( 0 ).toElement();
694 const QDomNodeList canvasSrsNodes = canvasElem.elementsByTagName( QStringLiteral(
"spatialrefsys" ) );
695 if ( canvasSrsNodes.count() > 0 )
697 const QDomElement canvasSrsElem = canvasSrsNodes.at( 0 ).toElement();
702 const QDomNodeList proj4Nodes = canvasSrsElem.elementsByTagName( QStringLiteral(
"proj4" ) );
703 if ( proj4Nodes.count() > 0 )
705 const QDomElement proj4Node = proj4Nodes.at( 0 ).toElement();
706 proj = proj4Node.text();
708 const QDomNodeList authidNodes = canvasSrsElem.elementsByTagName( QStringLiteral(
"authid" ) );
709 if ( authidNodes.count() > 0 )
711 const QDomElement authidNode = authidNodes.at( 0 ).toElement();
712 authid = authidNode.text();
714 const QDomNodeList srsidNodes = canvasSrsElem.elementsByTagName( QStringLiteral(
"srsid" ) );
715 if ( srsidNodes.count() > 0 )
717 const QDomElement srsidNode = srsidNodes.at( 0 ).toElement();
718 srsid = srsidNode.text();
722 const QDomNodeList oldProjectProj4Nodes = srsElem.elementsByTagName( QStringLiteral(
"ProjectCRSProj4String" ) );
723 for (
int i = oldProjectProj4Nodes.count(); i >= 0; --i )
725 srsElem.removeChild( oldProjectProj4Nodes.at( i ) );
727 const QDomNodeList oldProjectCrsNodes = srsElem.elementsByTagName( QStringLiteral(
"ProjectCrs" ) );
728 for (
int i = oldProjectCrsNodes.count(); i >= 0; --i )
730 srsElem.removeChild( oldProjectCrsNodes.at( i ) );
732 const QDomNodeList oldProjectCrsIdNodes = srsElem.elementsByTagName( QStringLiteral(
"ProjectCRSID" ) );
733 for (
int i = oldProjectCrsIdNodes.count(); i >= 0; --i )
735 srsElem.removeChild( oldProjectCrsIdNodes.at( i ) );
737 const QDomNodeList projectionsEnabledNodes = srsElem.elementsByTagName( QStringLiteral(
"ProjectionsEnabled" ) );
738 for (
int i = projectionsEnabledNodes.count(); i >= 0; --i )
740 srsElem.removeChild( projectionsEnabledNodes.at( i ) );
743 QDomElement proj4Elem = pft->
dom().createElement( QStringLiteral(
"ProjectCRSProj4String" ) );
744 proj4Elem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"QString" ) );
745 const QDomText proj4Text = pft->
dom().createTextNode( proj );
746 proj4Elem.appendChild( proj4Text );
747 QDomElement projectCrsElem = pft->
dom().createElement( QStringLiteral(
"ProjectCrs" ) );
748 projectCrsElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"QString" ) );
749 const QDomText projectCrsText = pft->
dom().createTextNode( authid );
750 projectCrsElem.appendChild( projectCrsText );
751 QDomElement projectCrsIdElem = pft->
dom().createElement( QStringLiteral(
"ProjectCRSID" ) );
752 projectCrsIdElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"int" ) );
753 const QDomText srsidText = pft->
dom().createTextNode( srsid );
754 projectCrsIdElem.appendChild( srsidText );
755 QDomElement projectionsEnabledElem = pft->
dom().createElement( QStringLiteral(
"ProjectionsEnabled" ) );
756 projectionsEnabledElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"int" ) );
757 const QDomText projectionsEnabledText = pft->
dom().createTextNode( QStringLiteral(
"1" ) );
758 projectionsEnabledElem.appendChild( projectionsEnabledText );
759 srsElem.appendChild( proj4Elem );
760 srsElem.appendChild( projectCrsElem );
761 srsElem.appendChild( projectCrsIdElem );
762 srsElem.appendChild( projectionsEnabledElem );
764 const QDomNodeList srsNodes = propsElem.elementsByTagName( QStringLiteral(
"SpatialRefSys" ) );
765 for (
int i = srsNodes.count(); i >= 0; --i )
767 propsElem.removeChild( srsNodes.at( i ) );
769 propsElem.appendChild( srsElem );
775 const QDomNodeList mapLayers = pft->
dom().elementsByTagName( QStringLiteral(
"maplayer" ) );
777 for (
int mapLayerIndex = 0; mapLayerIndex < mapLayers.count(); ++mapLayerIndex )
779 QDomElement layerElem = mapLayers.at( mapLayerIndex ).toElement();
782 QDomElement fieldConfigurationElement = pft->
dom().createElement( QStringLiteral(
"fieldConfiguration" ) );
783 layerElem.appendChild( fieldConfigurationElement );
785 const QDomNodeList editTypeNodes = layerElem.namedItem( QStringLiteral(
"edittypes" ) ).childNodes();
786 QDomElement constraintExpressionsElem = pft->
dom().createElement( QStringLiteral(
"constraintExpressions" ) );
787 layerElem.appendChild( constraintExpressionsElem );
789 for (
int i = 0; i < editTypeNodes.size(); ++i )
791 const QDomNode editTypeNode = editTypeNodes.at( i );
792 const QDomElement editTypeElement = editTypeNode.toElement();
794 QDomElement fieldElement = pft->
dom().createElement( QStringLiteral(
"field" ) );
795 fieldConfigurationElement.appendChild( fieldElement );
797 const QString name = editTypeElement.attribute( QStringLiteral(
"name" ) );
798 fieldElement.setAttribute( QStringLiteral(
"name" ), name );
799 QDomElement constraintExpressionElem = pft->
dom().createElement( QStringLiteral(
"constraint" ) );
800 constraintExpressionElem.setAttribute( QStringLiteral(
"field" ), name );
801 constraintExpressionsElem.appendChild( constraintExpressionElem );
803 QDomElement editWidgetElement = pft->
dom().createElement( QStringLiteral(
"editWidget" ) );
804 fieldElement.appendChild( editWidgetElement );
806 const QString ewv2Type = editTypeElement.attribute( QStringLiteral(
"widgetv2type" ) );
807 editWidgetElement.setAttribute( QStringLiteral(
"type" ), ewv2Type );
809 const QDomElement ewv2CfgElem = editTypeElement.namedItem( QStringLiteral(
"widgetv2config" ) ).toElement();
811 if ( !ewv2CfgElem.isNull() )
813 QDomElement editWidgetConfigElement = pft->
dom().createElement( QStringLiteral(
"config" ) );
814 editWidgetElement.appendChild( editWidgetConfigElement );
816 QVariantMap editWidgetConfiguration;
818 const QDomNamedNodeMap configAttrs = ewv2CfgElem.attributes();
819 for (
int configIndex = 0; configIndex < configAttrs.count(); ++configIndex )
821 const QDomAttr configAttr = configAttrs.item( configIndex ).toAttr();
822 if ( configAttr.name() == QLatin1String(
"fieldEditable" ) )
824 editWidgetConfigElement.setAttribute( QStringLiteral(
"fieldEditable" ), configAttr.value() );
826 else if ( configAttr.name() == QLatin1String(
"labelOnTop" ) )
828 editWidgetConfigElement.setAttribute( QStringLiteral(
"labelOnTop" ), configAttr.value() );
830 else if ( configAttr.name() == QLatin1String(
"notNull" ) )
832 editWidgetConfigElement.setAttribute( QStringLiteral(
"notNull" ), configAttr.value() );
834 else if ( configAttr.name() == QLatin1String(
"constraint" ) )
836 constraintExpressionElem.setAttribute( QStringLiteral(
"exp" ), configAttr.value() );
838 else if ( configAttr.name() == QLatin1String(
"constraintDescription" ) )
840 constraintExpressionElem.setAttribute( QStringLiteral(
"desc" ), configAttr.value() );
844 editWidgetConfiguration.insert( configAttr.name(), configAttr.value() );
848 if ( ewv2Type == QLatin1String(
"ValueMap" ) )
850 const QDomNodeList configElements = ewv2CfgElem.childNodes();
852 for (
int configIndex = 0; configIndex < configElements.count(); ++configIndex )
854 const QDomElement configElem = configElements.at( configIndex ).toElement();
855 map.insert( configElem.attribute( QStringLiteral(
"key" ) ), configElem.attribute( QStringLiteral(
"value" ) ) );
857 editWidgetConfiguration.insert( QStringLiteral(
"map" ), map );
859 else if ( ewv2Type == QLatin1String(
"Photo" ) )
861 editWidgetElement.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"ExternalResource" ) );
863 editWidgetConfiguration.insert( QStringLiteral(
"DocumentViewer" ), 1 );
864 editWidgetConfiguration.insert( QStringLiteral(
"DocumentViewerHeight" ), editWidgetConfiguration.value( QStringLiteral(
"Height" ) ) );
865 editWidgetConfiguration.insert( QStringLiteral(
"DocumentViewerWidth" ), editWidgetConfiguration.value( QStringLiteral(
"Width" ) ) );
866 editWidgetConfiguration.insert( QStringLiteral(
"RelativeStorage" ), 1 );
868 else if ( ewv2Type == QLatin1String(
"FileName" ) )
870 editWidgetElement.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"ExternalResource" ) );
872 editWidgetConfiguration.insert( QStringLiteral(
"RelativeStorage" ), 1 );
874 else if ( ewv2Type == QLatin1String(
"WebView" ) )
876 editWidgetElement.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"ExternalResource" ) );
878 editWidgetConfiguration.insert( QStringLiteral(
"DocumentViewerHeight" ), editWidgetConfiguration.value( QStringLiteral(
"Height" ) ) );
879 editWidgetConfiguration.insert( QStringLiteral(
"DocumentViewerWidth" ), editWidgetConfiguration.value( QStringLiteral(
"Width" ) ) );
880 editWidgetConfiguration.insert( QStringLiteral(
"RelativeStorage" ), 1 );
894 const QDomNode noDataNode = rasterPropertiesElem.namedItem( QStringLiteral(
"mNoDataValue" ) );
895 const QDomElement noDataElement = noDataNode.toElement();
896 if ( !noDataElement.text().isEmpty() )
898 QgsDebugMsg(
"mNoDataValue = " + noDataElement.text() );
899 QDomElement noDataElem = doc.createElement( QStringLiteral(
"noData" ) );
901 QDomElement noDataRangeList = doc.createElement( QStringLiteral(
"noDataRangeList" ) );
902 noDataRangeList.setAttribute( QStringLiteral(
"bandNo" ), 1 );
904 QDomElement noDataRange = doc.createElement( QStringLiteral(
"noDataRange" ) );
905 noDataRange.setAttribute( QStringLiteral(
"min" ), noDataElement.text() );
906 noDataRange.setAttribute( QStringLiteral(
"max" ), noDataElement.text() );
907 noDataRangeList.appendChild( noDataRange );
909 noDataElem.appendChild( noDataRangeList );
911 parentNode.appendChild( noDataElem );
914 QDomElement rasterRendererElem = doc.createElement( QStringLiteral(
"rasterrenderer" ) );
918 rasterRendererElem.setAttribute( QStringLiteral(
"invertColor" ), QStringLiteral(
"0" ) );
919 const QDomElement invertColorElem = rasterPropertiesElem.firstChildElement( QStringLiteral(
"mInvertColor" ) );
920 if ( !invertColorElem.isNull() )
922 if ( invertColorElem.text() == QLatin1String(
"true" ) )
924 rasterRendererElem.setAttribute( QStringLiteral(
"invertColor" ), QStringLiteral(
"1" ) );
929 rasterRendererElem.setAttribute( QStringLiteral(
"opacity" ), QStringLiteral(
"1" ) );
930 const QDomElement transparencyElem = parentNode.firstChildElement( QStringLiteral(
"transparencyLevelInt" ) );
931 if ( !transparencyElem.isNull() )
933 const double transparency = transparencyElem.text().toInt();
934 rasterRendererElem.setAttribute( QStringLiteral(
"opacity" ), QString::number( transparency / 255.0 ) );
938 rasterRendererElem.setAttribute( QStringLiteral(
"alphaBand" ), -1 );
941 const int grayBand =
rasterBandNumber( rasterPropertiesElem, QStringLiteral(
"mGrayBandName" ), rlayer );
944 QString drawingStyle = rasterPropertiesElem.firstChildElement( QStringLiteral(
"mDrawingStyle" ) ).text();
951 if ( drawingStyle == QLatin1String(
"PalettedColor" ) )
953 const QDomElement customColorRampElem = rasterPropertiesElem.firstChildElement( QStringLiteral(
"customColorRamp" ) );
954 const QDomNodeList colorRampEntryList = customColorRampElem.elementsByTagName( QStringLiteral(
"colorRampEntry" ) );
956 for (
int i = 0; i < colorRampEntryList.size(); ++i )
958 const QDomElement colorRampEntryElem = colorRampEntryList.at( i ).toElement();
959 const QString strValue = colorRampEntryElem.attribute( QStringLiteral(
"value" ) );
960 const double value = strValue.toDouble();
961 if ( value < 0 || value > 10000 || !
qgsDoubleNear( value,
static_cast< int >( value ) ) )
963 QgsDebugMsg( QStringLiteral(
"forcing SingleBandPseudoColor value = %1" ).arg( value ) );
964 drawingStyle = QStringLiteral(
"SingleBandPseudoColor" );
970 if ( drawingStyle == QLatin1String(
"SingleBandGray" ) )
972 rasterRendererElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"singlebandgray" ) );
973 rasterRendererElem.setAttribute( QStringLiteral(
"grayBand" ), grayBand );
976 else if ( drawingStyle == QLatin1String(
"SingleBandPseudoColor" ) )
978 rasterRendererElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"singlebandpseudocolor" ) );
979 rasterRendererElem.setAttribute( QStringLiteral(
"band" ), grayBand );
980 QDomElement newRasterShaderElem = doc.createElement( QStringLiteral(
"rastershader" ) );
981 QDomElement newColorRampShaderElem = doc.createElement( QStringLiteral(
"colorrampshader" ) );
982 newRasterShaderElem.appendChild( newColorRampShaderElem );
983 rasterRendererElem.appendChild( newRasterShaderElem );
986 const QString colorShadingAlgorithm = rasterPropertiesElem.firstChildElement( QStringLiteral(
"mColorShadingAlgorithm" ) ).text();
987 if ( colorShadingAlgorithm == QLatin1String(
"PseudoColorShader" ) || colorShadingAlgorithm == QLatin1String(
"FreakOutShader" ) )
989 newColorRampShaderElem.setAttribute( QStringLiteral(
"colorRampType" ), QStringLiteral(
"INTERPOLATED" ) );
995 const double breakSize = ( maxValue - minValue ) / 3;
997 QStringList colorList;
998 if ( colorShadingAlgorithm == QLatin1String(
"FreakOutShader" ) )
1000 colorList << QStringLiteral(
"#ff00ff" ) << QStringLiteral(
"#00ffff" ) << QStringLiteral(
"#ff0000" ) << QStringLiteral(
"#00ff00" );
1004 colorList << QStringLiteral(
"#0000ff" ) << QStringLiteral(
"#00ffff" ) << QStringLiteral(
"#ffff00" ) << QStringLiteral(
"#ff0000" );
1006 QStringList::const_iterator colorIt = colorList.constBegin();
1007 double boundValue = minValue;
1008 for ( ; colorIt != colorList.constEnd(); ++colorIt )
1010 QDomElement newItemElem = doc.createElement( QStringLiteral(
"item" ) );
1011 newItemElem.setAttribute( QStringLiteral(
"value" ), QString::number( boundValue ) );
1012 newItemElem.setAttribute( QStringLiteral(
"label" ), QString::number( boundValue ) );
1013 newItemElem.setAttribute( QStringLiteral(
"color" ), *colorIt );
1014 newColorRampShaderElem.appendChild( newItemElem );
1015 boundValue += breakSize;
1018 else if ( colorShadingAlgorithm == QLatin1String(
"ColorRampShader" ) )
1020 const QDomElement customColorRampElem = rasterPropertiesElem.firstChildElement( QStringLiteral(
"customColorRamp" ) );
1021 const QString type = customColorRampElem.firstChildElement( QStringLiteral(
"colorRampType" ) ).text();
1022 newColorRampShaderElem.setAttribute( QStringLiteral(
"colorRampType" ), type );
1023 const QDomNodeList colorNodeList = customColorRampElem.elementsByTagName( QStringLiteral(
"colorRampEntry" ) );
1025 QString value, label;
1027 int red, green, blue;
1028 QDomElement currentItemElem;
1029 for (
int i = 0; i < colorNodeList.size(); ++i )
1031 currentItemElem = colorNodeList.at( i ).toElement();
1032 value = currentItemElem.attribute( QStringLiteral(
"value" ) );
1033 label = currentItemElem.attribute( QStringLiteral(
"label" ) );
1034 red = currentItemElem.attribute( QStringLiteral(
"red" ) ).toInt();
1035 green = currentItemElem.attribute( QStringLiteral(
"green" ) ).toInt();
1036 blue = currentItemElem.attribute( QStringLiteral(
"blue" ) ).toInt();
1037 newColor = QColor( red, green, blue );
1038 QDomElement newItemElem = doc.createElement( QStringLiteral(
"item" ) );
1039 newItemElem.setAttribute( QStringLiteral(
"value" ), value );
1040 newItemElem.setAttribute( QStringLiteral(
"label" ), label );
1041 newItemElem.setAttribute( QStringLiteral(
"color" ), newColor.name() );
1042 newColorRampShaderElem.appendChild( newItemElem );
1046 else if ( drawingStyle == QLatin1String(
"PalettedColor" ) )
1048 rasterRendererElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"paletted" ) );
1049 rasterRendererElem.setAttribute( QStringLiteral(
"band" ), grayBand );
1050 const QDomElement customColorRampElem = rasterPropertiesElem.firstChildElement( QStringLiteral(
"customColorRamp" ) );
1051 const QDomNodeList colorRampEntryList = customColorRampElem.elementsByTagName( QStringLiteral(
"colorRampEntry" ) );
1052 QDomElement newColorPaletteElem = doc.createElement( QStringLiteral(
"colorPalette" ) );
1058 QDomElement colorRampEntryElem;
1059 for (
int i = 0; i < colorRampEntryList.size(); ++i )
1061 colorRampEntryElem = colorRampEntryList.at( i ).toElement();
1062 QDomElement newPaletteElem = doc.createElement( QStringLiteral(
"paletteEntry" ) );
1063 value =
static_cast< int >( colorRampEntryElem.attribute( QStringLiteral(
"value" ) ).toDouble() );
1064 newPaletteElem.setAttribute( QStringLiteral(
"value" ), value );
1065 red = colorRampEntryElem.attribute( QStringLiteral(
"red" ) ).toInt();
1066 green = colorRampEntryElem.attribute( QStringLiteral(
"green" ) ).toInt();
1067 blue = colorRampEntryElem.attribute( QStringLiteral(
"blue" ) ).toInt();
1068 newPaletteElem.setAttribute( QStringLiteral(
"color" ), QColor( red, green, blue ).name() );
1069 const QString label = colorRampEntryElem.attribute( QStringLiteral(
"label" ) );
1070 if ( !label.isEmpty() )
1072 newPaletteElem.setAttribute( QStringLiteral(
"label" ), label );
1074 newColorPaletteElem.appendChild( newPaletteElem );
1076 rasterRendererElem.appendChild( newColorPaletteElem );
1078 else if ( drawingStyle == QLatin1String(
"MultiBandColor" ) )
1080 rasterRendererElem.setAttribute( QStringLiteral(
"type" ), QStringLiteral(
"multibandcolor" ) );
1083 const int redBand =
rasterBandNumber( rasterPropertiesElem, QStringLiteral(
"mRedBandName" ), rlayer );
1084 const int greenBand =
rasterBandNumber( rasterPropertiesElem, QStringLiteral(
"mGreenBandName" ), rlayer );
1085 const int blueBand =
rasterBandNumber( rasterPropertiesElem, QStringLiteral(
"mBlueBandName" ), rlayer );
1086 rasterRendererElem.setAttribute( QStringLiteral(
"redBand" ), redBand );
1087 rasterRendererElem.setAttribute( QStringLiteral(
"greenBand" ), greenBand );
1088 rasterRendererElem.setAttribute( QStringLiteral(
"blueBand" ), blueBand );
1098 if ( !parentNode.isNull() )
1100 parentNode.replaceChild( rasterRendererElem, rasterPropertiesElem );
1111 return mCurrentVersion;
1121 const int band = -1;
1122 const QDomElement rasterBandElem = rasterPropertiesElem.firstChildElement( bandName );
1123 if ( !rasterBandElem.isNull() )
1125 const thread_local QRegularExpression re(
"(\\d+)" );
1126 const QRegularExpressionMatch match = re.match( rasterBandElem.text() );
1127 if ( match.hasMatch() )
1129 return match.captured( 1 ).toInt();
1137 if ( rasterproperties.isNull() || rendererElem.isNull() )
1142 double minimumValue = 0;
1143 double maximumValue = 0;
1144 const QDomElement contrastMinMaxElem = rasterproperties.firstChildElement( QStringLiteral(
"contrastEnhancementMinMaxValues" ) );
1145 if ( contrastMinMaxElem.isNull() )
1150 const QDomElement contrastEnhancementAlgorithmElem = rasterproperties.firstChildElement( QStringLiteral(
"mContrastEnhancementAlgorithm" ) );
1151 if ( contrastEnhancementAlgorithmElem.isNull() )
1157 int algorithmEnum = 0;
1158 const QString algorithmString = contrastEnhancementAlgorithmElem.text();
1159 if ( algorithmString == QLatin1String(
"StretchToMinimumMaximum" ) )
1163 else if ( algorithmString == QLatin1String(
"StretchAndClipToMinimumMaximum" ) )
1167 else if ( algorithmString == QLatin1String(
"ClipToMinimumMaximum" ) )
1171 else if ( algorithmString == QLatin1String(
"UserDefinedEnhancement" ) )
1176 const QDomNodeList minMaxEntryList = contrastMinMaxElem.elementsByTagName( QStringLiteral(
"minMaxEntry" ) );
1177 QStringList enhancementNameList;
1178 if ( minMaxEntryList.size() == 1 )
1180 enhancementNameList << QStringLiteral(
"contrastEnhancement" );
1182 if ( minMaxEntryList.size() == 3 )
1184 enhancementNameList << QStringLiteral(
"redContrastEnhancement" ) << QStringLiteral(
"greenContrastEnhancement" ) << QStringLiteral(
"blueContrastEnhancement" );
1186 if ( minMaxEntryList.size() > enhancementNameList.size() )
1191 QDomElement minMaxEntryElem;
1192 for (
int i = 0; i < minMaxEntryList.size(); ++i )
1194 minMaxEntryElem = minMaxEntryList.at( i ).toElement();
1195 const QDomElement minElem = minMaxEntryElem.firstChildElement( QStringLiteral(
"min" ) );
1196 if ( minElem.isNull() )
1200 minimumValue = minElem.text().toDouble();
1202 const QDomElement maxElem = minMaxEntryElem.firstChildElement( QStringLiteral(
"max" ) );
1203 if ( maxElem.isNull() )
1207 maximumValue = maxElem.text().toDouble();
1209 QDomElement newContrastEnhancementElem = doc.createElement( enhancementNameList.at( i ) );
1210 QDomElement newMinValElem = doc.createElement( QStringLiteral(
"minValue" ) );
1211 const QDomText minText = doc.createTextNode( QString::number( minimumValue ) );
1212 newMinValElem.appendChild( minText );
1213 newContrastEnhancementElem.appendChild( newMinValElem );
1214 QDomElement newMaxValElem = doc.createElement( QStringLiteral(
"maxValue" ) );
1215 const QDomText maxText = doc.createTextNode( QString::number( maximumValue ) );
1216 newMaxValElem.appendChild( maxText );
1217 newContrastEnhancementElem.appendChild( newMaxValElem );
1219 QDomElement newAlgorithmElem = doc.createElement( QStringLiteral(
"algorithm" ) );
1220 const QDomText newAlgorithmText = doc.createTextNode( QString::number( algorithmEnum ) );
1221 newAlgorithmElem.appendChild( newAlgorithmText );
1222 newContrastEnhancementElem.appendChild( newAlgorithmElem );
1224 rendererElem.appendChild( newContrastEnhancementElem );
Contains information about the context in which a coordinate transform is executed.
Container of fields for a vector layer.
int count() const
Returns number of items.
QgsField at(int i) const
Returns the field at particular index (must be in range 0..N-1).
bool readLayerXml(const QDomElement &layerElement, QgsReadWriteContext &context, QgsMapLayer::ReadFlags flags=QgsMapLayer::ReadFlags())
Sets state from DOM document.
Project property value node, contains a QgsProjectPropertyKey's value.
bool writeXml(const QString &nodeName, QDomElement &element, QDomDocument &document) override
Writes the property hierarchy to a specified DOM element.
A class to describe the version of a project.
int subVersion() const
Returns the sub version number.
int majorVersion() const
Returns the major version number.
int minorVersion() const
Returns the minor version number.
bool isNull() const
Returns true if this is a NULL project version.
static QgsProject * instance()
Returns the QgsProject singleton instance.
The RasterBandStats struct is a container for statistics about a single raster band.
double minimumValue
The minimum cell value in the raster band.
double maximumValue
The maximum cell value in the raster band.
virtual QgsRasterBandStats bandStatistics(int bandNo, int stats=QgsRasterBandStats::All, const QgsRectangle &extent=QgsRectangle(), int sampleSize=0, QgsRasterBlockFeedback *feedback=nullptr)
Returns the band statistics.
Represents a raster layer.
QgsRasterDataProvider * dataProvider() override
Returns the source data provider.
The class is used as a container of context for various read/write operations on other objects.
void setPathResolver(const QgsPathResolver &resolver)
Sets up path resolver for conversion between relative and absolute paths.
This is the base class for vector data providers.
QgsFields fields() const override=0
Returns the fields associated with this data provider.
Represents a vector layer which manages a vector based data sets.
QgsVectorDataProvider * dataProvider() FINAL
Returns the layer's data provider, it may be nullptr.
static QDomElement writeVariant(const QVariant &value, QDomDocument &doc)
Write a QVariant to a QDomElement.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
#define QgsDebugMsgLevel(str, level)
Setting options for loading vector layers.