Skip to content

Commit 48a45b3

Browse files
committedNov 7, 2017
Restore serialization for map items
1 parent e539022 commit 48a45b3

14 files changed

+290
-78
lines changed
 

‎python/core/layout/qgslayoutitemmap.sip

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,10 @@ Returns true if the map contains layers with blend modes or flattened layers for
409409

410410
virtual void draw( QgsRenderContext &context, const QStyleOptionGraphicsItem *itemStyle = 0 );
411411

412+
virtual bool writePropertiesToElement( QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context ) const;
413+
414+
virtual bool readPropertiesFromElement( const QDomElement &element, const QDomDocument &document, const QgsReadWriteContext &context );
415+
412416

413417
QgsMapSettings mapSettings( const QgsRectangle &extent, QSizeF size, int dpi ) const;
414418
%Docstring
@@ -423,7 +427,6 @@ True if a draw is already in progress
423427
%End
424428

425429

426-
427430
virtual QRectF boundingRect() const;
428431

429432

‎python/core/layout/qgslayoutitemmapgrid.sip

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ class QgsLayoutItemMapGridStack : QgsLayoutItemMapItemStack
9494
:rtype: list of QgsLayoutItemMapGrid
9595
%End
9696

97-
virtual bool readXml( const QDomElement &elem, const QDomDocument &doc );
97+
virtual bool readXml( const QDomElement &elem, const QDomDocument &doc, const QgsReadWriteContext &context );
9898

9999

100100
double maxGridExtension() const;
@@ -222,9 +222,9 @@ class QgsLayoutItemMapGrid : QgsLayoutItemMapItem
222222

223223
virtual void draw( QPainter *painter );
224224

225-
virtual bool writeXml( QDomElement &elem, QDomDocument &doc ) const;
225+
virtual bool writeXml( QDomElement &elem, QDomDocument &doc, const QgsReadWriteContext &context ) const;
226226

227-
virtual bool readXml( const QDomElement &itemElem, const QDomDocument &doc );
227+
virtual bool readXml( const QDomElement &itemElem, const QDomDocument &doc, const QgsReadWriteContext &context );
228228

229229

230230
void setCrs( const QgsCoordinateReferenceSystem &crs );

‎python/core/layout/qgslayoutitemmapitem.sip

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,15 @@ class QgsLayoutItemMapItem : QgsLayoutObject
3333
Draws the item on to a destination ``painter``.
3434
%End
3535

36-
virtual bool writeXml( QDomElement &element, QDomDocument &document ) const;
36+
virtual bool writeXml( QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context ) const;
3737
%Docstring
3838
Stores map item state in a DOM element, where ``element`` is the DOM element
3939
corresponding to a 'LayoutMap' tag.
4040
.. seealso:: readXml()
4141
:rtype: bool
4242
%End
4343

44-
virtual bool readXml( const QDomElement &element, const QDomDocument &doc );
44+
virtual bool readXml( const QDomElement &element, const QDomDocument &doc, const QgsReadWriteContext &context );
4545
%Docstring
4646
Sets the map item state from a DOM document, where ``element`` is the DOM
4747
node corresponding to a 'LayoutMapGrid' tag.
@@ -139,15 +139,15 @@ class QgsLayoutItemMapItemStack
139139
:rtype: int
140140
%End
141141

142-
virtual bool writeXml( QDomElement &element, QDomDocument &doc ) const;
142+
virtual bool writeXml( QDomElement &element, QDomDocument &doc, const QgsReadWriteContext &context ) const;
143143
%Docstring
144144
Stores the state of the item stack in a DOM node, where ``element`` is the DOM element corresponding to a 'LayoutMap' tag.
145145
Returns true if write was successful.
146146
.. seealso:: readXml()
147147
:rtype: bool
148148
%End
149149

150-
virtual bool readXml( const QDomElement &element, const QDomDocument &doc ) = 0;
150+
virtual bool readXml( const QDomElement &element, const QDomDocument &doc, const QgsReadWriteContext &context ) = 0;
151151
%Docstring
152152
Sets the item stack's state from a DOM document, where ``element`` is a DOM node corresponding to a 'LayoutMap' tag.
153153
Returns true if read was successful.

‎python/core/layout/qgslayoutitemmapoverview.sip

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ class QgsLayoutItemMapOverviewStack : QgsLayoutItemMapItemStack
9494
Returns a list of QgsLayoutItemMapOverviews contained by the stack.
9595
:rtype: list of QgsLayoutItemMapOverview
9696
%End
97-
virtual bool readXml( const QDomElement &elem, const QDomDocument &doc );
97+
virtual bool readXml( const QDomElement &elem, const QDomDocument &doc, const QgsReadWriteContext &context );
9898

9999

100100
};
@@ -122,9 +122,9 @@ class QgsLayoutItemMapOverview : QgsLayoutItemMapItem
122122

123123
virtual void draw( QPainter *painter );
124124

125-
virtual bool writeXml( QDomElement &elem, QDomDocument &doc ) const;
125+
virtual bool writeXml( QDomElement &elem, QDomDocument &doc, const QgsReadWriteContext &context ) const;
126126

127-
virtual bool readXml( const QDomElement &itemElem, const QDomDocument &doc );
127+
virtual bool readXml( const QDomElement &itemElem, const QDomDocument &doc, const QgsReadWriteContext &context );
128128

129129
virtual bool usesAdvancedEffects() const;
130130

‎python/core/layout/qgslayoutitempicture.sip

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,6 @@ class QgsLayoutItemPicture: QgsLayoutItem
8080
:rtype: str
8181
%End
8282

83-
8483
double pictureRotation() const;
8584
%Docstring
8685
Returns the rotation used for drawing the picture within the item's frame,

‎src/core/layout/qgslayoutitemmap.cpp

Lines changed: 244 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,250 @@ void QgsLayoutItemMap::draw( QgsRenderContext &, const QStyleOptionGraphicsItem
478478
{
479479
}
480480

481+
bool QgsLayoutItemMap::writePropertiesToElement( QDomElement &composerMapElem, QDomDocument &doc, const QgsReadWriteContext &context ) const
482+
{
483+
#if 0 //TODO - is this needed?
484+
composerMapElem.setAttribute( QStringLiteral( "id" ), mId );
485+
#endif
486+
487+
if ( mKeepLayerSet )
488+
{
489+
composerMapElem.setAttribute( QStringLiteral( "keepLayerSet" ), QStringLiteral( "true" ) );
490+
}
491+
else
492+
{
493+
composerMapElem.setAttribute( QStringLiteral( "keepLayerSet" ), QStringLiteral( "false" ) );
494+
}
495+
496+
if ( mDrawAnnotations )
497+
{
498+
composerMapElem.setAttribute( QStringLiteral( "drawCanvasItems" ), QStringLiteral( "true" ) );
499+
}
500+
else
501+
{
502+
composerMapElem.setAttribute( QStringLiteral( "drawCanvasItems" ), QStringLiteral( "false" ) );
503+
}
504+
505+
//extent
506+
QDomElement extentElem = doc.createElement( QStringLiteral( "Extent" ) );
507+
extentElem.setAttribute( QStringLiteral( "xmin" ), qgsDoubleToString( mExtent.xMinimum() ) );
508+
extentElem.setAttribute( QStringLiteral( "xmax" ), qgsDoubleToString( mExtent.xMaximum() ) );
509+
extentElem.setAttribute( QStringLiteral( "ymin" ), qgsDoubleToString( mExtent.yMinimum() ) );
510+
extentElem.setAttribute( QStringLiteral( "ymax" ), qgsDoubleToString( mExtent.yMaximum() ) );
511+
composerMapElem.appendChild( extentElem );
512+
513+
if ( mCrs.isValid() )
514+
{
515+
QDomElement crsElem = doc.createElement( QStringLiteral( "crs" ) );
516+
mCrs.writeXml( crsElem, doc );
517+
composerMapElem.appendChild( crsElem );
518+
}
519+
520+
// follow map theme
521+
composerMapElem.setAttribute( QStringLiteral( "followPreset" ), mFollowVisibilityPreset ? "true" : "false" );
522+
composerMapElem.setAttribute( QStringLiteral( "followPresetName" ), mFollowVisibilityPresetName );
523+
524+
//map rotation
525+
composerMapElem.setAttribute( QStringLiteral( "mapRotation" ), QString::number( mMapRotation ) );
526+
527+
//layer set
528+
QDomElement layerSetElem = doc.createElement( QStringLiteral( "LayerSet" ) );
529+
for ( const QgsMapLayerRef &layerRef : mLayers )
530+
{
531+
if ( !layerRef )
532+
continue;
533+
QDomElement layerElem = doc.createElement( QStringLiteral( "Layer" ) );
534+
QDomText layerIdText = doc.createTextNode( layerRef.layerId );
535+
layerElem.appendChild( layerIdText );
536+
537+
layerElem.setAttribute( QStringLiteral( "name" ), layerRef.name );
538+
layerElem.setAttribute( QStringLiteral( "source" ), layerRef.source );
539+
layerElem.setAttribute( QStringLiteral( "provider" ), layerRef.provider );
540+
541+
layerSetElem.appendChild( layerElem );
542+
}
543+
composerMapElem.appendChild( layerSetElem );
544+
545+
// override styles
546+
if ( mKeepLayerStyles )
547+
{
548+
QDomElement stylesElem = doc.createElement( QStringLiteral( "LayerStyles" ) );
549+
for ( auto styleIt = mLayerStyleOverrides.constBegin(); styleIt != mLayerStyleOverrides.constEnd(); ++styleIt )
550+
{
551+
QDomElement styleElem = doc.createElement( QStringLiteral( "LayerStyle" ) );
552+
553+
QgsMapLayerRef ref( styleIt.key() );
554+
ref.resolve( mLayout->project() );
555+
556+
styleElem.setAttribute( QStringLiteral( "layerid" ), ref.layerId );
557+
styleElem.setAttribute( QStringLiteral( "name" ), ref.name );
558+
styleElem.setAttribute( QStringLiteral( "source" ), ref.source );
559+
styleElem.setAttribute( QStringLiteral( "provider" ), ref.provider );
560+
561+
QgsMapLayerStyle style( styleIt.value() );
562+
style.writeXml( styleElem );
563+
stylesElem.appendChild( styleElem );
564+
}
565+
composerMapElem.appendChild( stylesElem );
566+
}
567+
568+
//grids
569+
mGridStack->writeXml( composerMapElem, doc, context );
570+
571+
//overviews
572+
mOverviewStack->writeXml( composerMapElem, doc, context );
573+
574+
//atlas
575+
QDomElement atlasElem = doc.createElement( QStringLiteral( "AtlasMap" ) );
576+
atlasElem.setAttribute( QStringLiteral( "atlasDriven" ), mAtlasDriven );
577+
atlasElem.setAttribute( QStringLiteral( "scalingMode" ), mAtlasScalingMode );
578+
atlasElem.setAttribute( QStringLiteral( "margin" ), qgsDoubleToString( mAtlasMargin ) );
579+
composerMapElem.appendChild( atlasElem );
580+
581+
return true;
582+
}
583+
584+
bool QgsLayoutItemMap::readPropertiesFromElement( const QDomElement &itemElem, const QDomDocument &doc, const QgsReadWriteContext &context )
585+
{
586+
mUpdatesEnabled = false;
587+
#if 0 //TODO
588+
QString idRead = itemElem.attribute( QStringLiteral( "id" ), QStringLiteral( "not found" ) );
589+
if ( idRead != QLatin1String( "not found" ) )
590+
{
591+
mId = idRead.toInt();
592+
updateToolTip();
593+
}
594+
#endif
595+
596+
//extent
597+
QDomNodeList extentNodeList = itemElem.elementsByTagName( QStringLiteral( "Extent" ) );
598+
if ( !extentNodeList.isEmpty() )
599+
{
600+
QDomElement extentElem = extentNodeList.at( 0 ).toElement();
601+
double xmin, xmax, ymin, ymax;
602+
xmin = extentElem.attribute( QStringLiteral( "xmin" ) ).toDouble();
603+
xmax = extentElem.attribute( QStringLiteral( "xmax" ) ).toDouble();
604+
ymin = extentElem.attribute( QStringLiteral( "ymin" ) ).toDouble();
605+
ymax = extentElem.attribute( QStringLiteral( "ymax" ) ).toDouble();
606+
setExtent( QgsRectangle( xmin, ymin, xmax, ymax ) );
607+
}
608+
609+
QDomNodeList crsNodeList = itemElem.elementsByTagName( QStringLiteral( "crs" ) );
610+
if ( !crsNodeList.isEmpty() )
611+
{
612+
QDomElement crsElem = crsNodeList.at( 0 ).toElement();
613+
mCrs.readXml( crsElem );
614+
}
615+
else
616+
{
617+
mCrs = QgsCoordinateReferenceSystem();
618+
}
619+
620+
//map rotation
621+
mMapRotation = itemElem.attribute( QStringLiteral( "mapRotation" ), QStringLiteral( "0" ) ).toDouble();
622+
623+
// follow map theme
624+
mFollowVisibilityPreset = itemElem.attribute( QStringLiteral( "followPreset" ) ).compare( QLatin1String( "true" ) ) == 0;
625+
mFollowVisibilityPresetName = itemElem.attribute( QStringLiteral( "followPresetName" ) );
626+
627+
//mKeepLayerSet flag
628+
QString keepLayerSetFlag = itemElem.attribute( QStringLiteral( "keepLayerSet" ) );
629+
if ( keepLayerSetFlag.compare( QLatin1String( "true" ), Qt::CaseInsensitive ) == 0 )
630+
{
631+
mKeepLayerSet = true;
632+
}
633+
else
634+
{
635+
mKeepLayerSet = false;
636+
}
637+
638+
QString drawCanvasItemsFlag = itemElem.attribute( QStringLiteral( "drawCanvasItems" ), QStringLiteral( "true" ) );
639+
if ( drawCanvasItemsFlag.compare( QLatin1String( "true" ), Qt::CaseInsensitive ) == 0 )
640+
{
641+
mDrawAnnotations = true;
642+
}
643+
else
644+
{
645+
mDrawAnnotations = false;
646+
}
647+
648+
mLayerStyleOverrides.clear();
649+
650+
//mLayers
651+
mLayers.clear();
652+
QDomNodeList layerSetNodeList = itemElem.elementsByTagName( QStringLiteral( "LayerSet" ) );
653+
if ( !layerSetNodeList.isEmpty() )
654+
{
655+
QDomElement layerSetElem = layerSetNodeList.at( 0 ).toElement();
656+
QDomNodeList layerIdNodeList = layerSetElem.elementsByTagName( QStringLiteral( "Layer" ) );
657+
mLayers.reserve( layerIdNodeList.size() );
658+
for ( int i = 0; i < layerIdNodeList.size(); ++i )
659+
{
660+
QDomElement layerElem = layerIdNodeList.at( i ).toElement();
661+
QString layerId = layerElem.text();
662+
QString layerName = layerElem.attribute( QStringLiteral( "name" ) );
663+
QString layerSource = layerElem.attribute( QStringLiteral( "source" ) );
664+
QString layerProvider = layerElem.attribute( QStringLiteral( "provider" ) );
665+
666+
QgsMapLayerRef ref( layerId, layerName, layerSource, layerProvider );
667+
ref.resolveWeakly( mLayout->project() );
668+
mLayers << ref;
669+
}
670+
}
671+
672+
// override styles
673+
QDomNodeList layerStylesNodeList = itemElem.elementsByTagName( QStringLiteral( "LayerStyles" ) );
674+
mKeepLayerStyles = !layerStylesNodeList.isEmpty();
675+
if ( mKeepLayerStyles )
676+
{
677+
QDomElement layerStylesElem = layerStylesNodeList.at( 0 ).toElement();
678+
QDomNodeList layerStyleNodeList = layerStylesElem.elementsByTagName( QStringLiteral( "LayerStyle" ) );
679+
for ( int i = 0; i < layerStyleNodeList.size(); ++i )
680+
{
681+
const QDomElement &layerStyleElement = layerStyleNodeList.at( i ).toElement();
682+
QString layerId = layerStyleElement.attribute( QStringLiteral( "layerid" ) );
683+
QString layerName = layerStyleElement.attribute( QStringLiteral( "name" ) );
684+
QString layerSource = layerStyleElement.attribute( QStringLiteral( "source" ) );
685+
QString layerProvider = layerStyleElement.attribute( QStringLiteral( "provider" ) );
686+
QgsMapLayerRef ref( layerId, layerName, layerSource, layerProvider );
687+
ref.resolveWeakly( mLayout->project() );
688+
689+
QgsMapLayerStyle style;
690+
style.readXml( layerStyleElement );
691+
mLayerStyleOverrides.insert( ref.layerId, style.xmlData() );
692+
}
693+
}
694+
695+
mDrawing = false;
696+
mNumCachedLayers = 0;
697+
mCacheInvalidated = true;
698+
699+
//overviews
700+
mOverviewStack->readXml( itemElem, doc, context );
701+
702+
//grids
703+
mGridStack->readXml( itemElem, doc, context );
704+
705+
//atlas
706+
QDomNodeList atlasNodeList = itemElem.elementsByTagName( QStringLiteral( "AtlasMap" ) );
707+
if ( !atlasNodeList.isEmpty() )
708+
{
709+
QDomElement atlasElem = atlasNodeList.at( 0 ).toElement();
710+
mAtlasDriven = ( atlasElem.attribute( QStringLiteral( "atlasDriven" ), QStringLiteral( "0" ) ) != QLatin1String( "0" ) );
711+
if ( atlasElem.hasAttribute( QStringLiteral( "fixedScale" ) ) ) // deprecated XML
712+
{
713+
mAtlasScalingMode = ( atlasElem.attribute( QStringLiteral( "fixedScale" ), QStringLiteral( "0" ) ) != QLatin1String( "0" ) ) ? Fixed : Auto;
714+
}
715+
else if ( atlasElem.hasAttribute( QStringLiteral( "scalingMode" ) ) )
716+
{
717+
mAtlasScalingMode = static_cast<AtlasScalingMode>( atlasElem.attribute( QStringLiteral( "scalingMode" ) ).toInt() );
718+
}
719+
mAtlasMargin = atlasElem.attribute( QStringLiteral( "margin" ), QStringLiteral( "0.1" ) ).toDouble();
720+
}
721+
mUpdatesEnabled = true;
722+
return true;
723+
}
724+
481725
void QgsLayoutItemMap::paint( QPainter *painter, const QStyleOptionGraphicsItem *style, QWidget * )
482726
{
483727
if ( !mLayout || !painter || !painter->device() || !mUpdatesEnabled )

‎src/core/layout/qgslayoutitemmap.h

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,8 @@ class CORE_EXPORT QgsLayoutItemMap : public QgsLayoutItem
399399
protected:
400400

401401
void draw( QgsRenderContext &context, const QStyleOptionGraphicsItem *itemStyle = nullptr ) override;
402+
bool writePropertiesToElement( QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context ) const override;
403+
bool readPropertiesFromElement( const QDomElement &element, const QDomDocument &document, const QgsReadWriteContext &context ) override;
402404

403405
/**
404406
* Return map settings that will be used for drawing of the map.
@@ -415,23 +417,8 @@ class CORE_EXPORT QgsLayoutItemMap : public QgsLayoutItem
415417
Atlas preview extents are only temporary, and are regenerated whenever the atlas feature changes
416418
*/
417419
void setNewAtlasFeatureExtent( const QgsRectangle &extent );
418-
419-
/**
420-
* Stores state in Dom node
421-
* \param elem is Dom element corresponding to 'Composer' tag
422-
* \param doc Dom document
423-
*/
424-
bool writeXml( QDomElement &elem, QDomDocument &doc ) const override;
425-
426-
/**
427-
* Sets state from Dom document
428-
* \param itemElem is Dom node corresponding to 'ComposerMap' tag
429-
* \param doc is Dom document
430-
*/
431-
bool readXml( const QDomElement &itemElem, const QDomDocument &doc ) override;
432420
#endif
433421

434-
435422
// In case of annotations, the bounding rectangle can be larger than the map item rectangle
436423
QRectF boundingRect() const override;
437424

0 commit comments

Comments
 (0)
Please sign in to comment.