mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-15 00:04:00 -04:00
* Write layers to projects files in the proper order by iterating over the
zOrder in the map canvas. Fixes bug #1054332. * Remove the <zorder> tag from the dtd. It is superfluous. git-svn-id: http://svn.osgeo.org/qgis/trunk@2179 c8812cc2-4d05-0410-92ff-de0c093fc19c
This commit is contained in:
parent
53ec7a8b08
commit
fa9e3fe6e7
3
qgis.dtd
3
qgis.dtd
@ -26,10 +26,9 @@
|
||||
-- General Map Layer Properties
|
||||
-- (apply to both vector and raster)
|
||||
-->
|
||||
<!ELEMENT maplayer (layername, datasource, zorder, (singlesymbol|singlemarker|graduatedsymbol|continuoussymbol|graduatedmarker|rasterproperties) >
|
||||
<!ELEMENT maplayer (layername, datasource, (singlesymbol|singlemarker|graduatedsymbol|continuoussymbol|graduatedmarker|rasterproperties) >
|
||||
<!ELEMENT layername (#PCDATA) >
|
||||
<!ELEMENT datasource (#PCDATA) >
|
||||
<!ELEMENT zorder (#PCDATA) >
|
||||
<!-- Attribute Lists -->
|
||||
<!--Raster : flag indicating whether the layer should be represented in overview or not -->
|
||||
<!ELEMENT showInOverviewFlag>
|
||||
|
@ -30,6 +30,10 @@
|
||||
// #include <qguardedptr.h>
|
||||
// #endif
|
||||
|
||||
#ifndef QDOM_H
|
||||
#include <qdom.h>
|
||||
#endif
|
||||
|
||||
#ifndef QLISTVIEW_H
|
||||
#include <qlistview.h>
|
||||
#endif
|
||||
@ -1748,3 +1752,51 @@ void QgsMapCanvas::connectNotify( const char * signal )
|
||||
#endif
|
||||
} // QgsMapCanvas::connectNotify( const char * signal )
|
||||
|
||||
|
||||
bool QgsMapCanvas::writeXML(QDomNode & layerNode, QDomDocument & doc)
|
||||
{
|
||||
// Write current view extents
|
||||
QDomElement extentNode = doc.createElement("extent");
|
||||
layerNode.appendChild(extentNode);
|
||||
|
||||
QDomElement xMin = doc.createElement("xmin");
|
||||
QDomElement yMin = doc.createElement("ymin");
|
||||
QDomElement xMax = doc.createElement("xmax");
|
||||
QDomElement yMax = doc.createElement("ymax");
|
||||
|
||||
QDomText xMinText = doc.createTextNode(QString::number(mCanvasProperties->currentExtent.xMin(), 'f'));
|
||||
QDomText yMinText = doc.createTextNode(QString::number(mCanvasProperties->currentExtent.yMin(), 'f'));
|
||||
QDomText xMaxText = doc.createTextNode(QString::number(mCanvasProperties->currentExtent.xMax(), 'f'));
|
||||
QDomText yMaxText = doc.createTextNode(QString::number(mCanvasProperties->currentExtent.yMax(), 'f'));
|
||||
|
||||
xMin.appendChild(xMinText);
|
||||
yMin.appendChild(yMinText);
|
||||
xMax.appendChild(xMaxText);
|
||||
yMax.appendChild(yMaxText);
|
||||
|
||||
extentNode.appendChild(xMin);
|
||||
extentNode.appendChild(yMin);
|
||||
extentNode.appendChild(xMax);
|
||||
extentNode.appendChild(yMax);
|
||||
|
||||
// Iterate over layers in zOrder
|
||||
// Call writeXML() on each
|
||||
QDomElement projectLayersNode = doc.createElement("projectlayers");
|
||||
projectLayersNode.setAttribute("layercount", mCanvasProperties->layers.size());
|
||||
|
||||
std::list < QString >::iterator li = mCanvasProperties->zOrder.begin();
|
||||
while (li != mCanvasProperties->zOrder.end())
|
||||
{
|
||||
QgsMapLayer *ml = mCanvasProperties->layers[*li];
|
||||
|
||||
if (ml)
|
||||
{
|
||||
ml->writeXML(projectLayersNode, doc);
|
||||
}
|
||||
li++;
|
||||
}
|
||||
|
||||
layerNode.appendChild(projectLayersNode);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -24,6 +24,10 @@
|
||||
|
||||
// double sentinals to get round gcc 3.3.3 pre-processor bug
|
||||
|
||||
#ifndef QDOM_H
|
||||
#include <qdom.h>
|
||||
#endif
|
||||
|
||||
#ifndef QWIDGET_H
|
||||
#include <qwidget.h>
|
||||
#endif
|
||||
@ -158,6 +162,18 @@ class QgsMapCanvas : public QWidget
|
||||
//! Declare the legend class as a friend of the map canvas
|
||||
//friend class QgsLegend;
|
||||
|
||||
/** stores state in DOM node
|
||||
layerNode is DOM node corresponding to ``qgis'' tag
|
||||
|
||||
The DOM node corresponds to a DOM document project file XML element to be
|
||||
written by QgsProject.
|
||||
|
||||
Invoked by QgsProject::write().
|
||||
|
||||
returns true if successful
|
||||
*/
|
||||
bool writeXML( QDomNode & layerNode, QDomDocument & doc );
|
||||
|
||||
public slots:
|
||||
|
||||
/*! Adds a layer to the map canvas.
|
||||
|
@ -241,19 +241,8 @@ bool QgsMapLayer::writeXML( QDomNode & layer_node, QDomDocument & document )
|
||||
maplayer.appendChild( layerName );
|
||||
|
||||
// zorder
|
||||
|
||||
// XXX Where do I get this information? Since it's not map layer
|
||||
// XXX specific, and specific to map canvas, shouldn't that be in
|
||||
// XXX QgsMapCanvas::writeXML() instead? For that matter, if we read and
|
||||
// XXX write layers in a known order, then we don't need to store a z order,
|
||||
// XXX right?
|
||||
|
||||
QDomElement zOrder = document.createElement( "zorder" );
|
||||
QDomText zOrderText = document.createTextNode( "0" ); // XXX hard-coded to zero
|
||||
zOrder.appendChild( zOrderText );
|
||||
|
||||
maplayer.appendChild( zOrder );
|
||||
|
||||
// This is no longer stored in the project file. It is superflous since the layers
|
||||
// are written and read in the proper order.
|
||||
|
||||
// now append layer node to map layer node
|
||||
|
||||
|
@ -220,7 +220,7 @@ _getExtents( QDomDocument const & doc, QgsRect & aoi )
|
||||
|
||||
|
||||
/**
|
||||
Get the project title
|
||||
Get the project map units
|
||||
|
||||
XML in file has this form:
|
||||
<units>feet</units>
|
||||
@ -363,6 +363,44 @@ _findQgisApp()
|
||||
|
||||
|
||||
|
||||
/**
|
||||
locate a qgsMapCanvas object
|
||||
*/
|
||||
static QgsMapCanvas *_findMapCanvas(QString const &canonicalMapCanvasName)
|
||||
{
|
||||
QgsMapCanvas *theMapCanvas;
|
||||
|
||||
QWidgetList *list = QApplication::topLevelWidgets();
|
||||
QWidgetListIt it(*list); // iterate over the widgets
|
||||
QWidget *w;
|
||||
|
||||
while ((w = it.current()) != 0)
|
||||
{ // for each top level widget...
|
||||
++it;
|
||||
theMapCanvas = dynamic_cast < QgsMapCanvas * >(w->child(canonicalMapCanvasName, 0, true));
|
||||
|
||||
if (theMapCanvas)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
delete list; // delete the list, not the widgets
|
||||
|
||||
if (theMapCanvas)
|
||||
{
|
||||
return theMapCanvas;
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug("Unable to find canvas widget " + canonicalMapCanvasName);
|
||||
|
||||
return 0x0; // XXX some sort of error value? Exception?
|
||||
}
|
||||
|
||||
} // _findMapCanvas
|
||||
|
||||
|
||||
|
||||
/**
|
||||
Read map layers from project file
|
||||
|
||||
@ -408,6 +446,8 @@ static
|
||||
bool
|
||||
_getMapLayers( QDomDocument const & doc )
|
||||
{
|
||||
// Layer order is implicit in the order they are stored in the project file
|
||||
|
||||
QDomNodeList nl = doc.elementsByTagName("maplayer");
|
||||
|
||||
// XXX what is this used for? QString layerCount( QString::number(nl.count()) );
|
||||
@ -469,9 +509,6 @@ _getMapLayers( QDomDocument const & doc )
|
||||
// }
|
||||
// }
|
||||
|
||||
// XXX set z order here? Or in readXML()? Leaning to latter.
|
||||
// XXX Or, how about Z order being implicit in order of layer
|
||||
// XXX information stored in project file?
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -491,24 +528,8 @@ static
|
||||
void
|
||||
_setCanvasExtent( QString const & canonicalMapCanvasName, QgsRect const & newExtent )
|
||||
{
|
||||
// first find the canonical map canvas
|
||||
|
||||
QgsMapCanvas * theMapCanvas;
|
||||
|
||||
QWidgetList * list = QApplication::topLevelWidgets();
|
||||
QWidgetListIt it( *list ); // iterate over the widgets
|
||||
QWidget * w;
|
||||
|
||||
while ( (w=it.current()) != 0 )
|
||||
{ // for each top level widget...
|
||||
++it;
|
||||
theMapCanvas = dynamic_cast<QgsMapCanvas*>(w->child( canonicalMapCanvasName, 0, true ));
|
||||
|
||||
if ( theMapCanvas )
|
||||
{ break; }
|
||||
}
|
||||
delete list; // delete the list, not the widgets
|
||||
|
||||
// first find the canonical map canvas
|
||||
QgsMapCanvas *theMapCanvas = _findMapCanvas(canonicalMapCanvasName);
|
||||
|
||||
if( ! theMapCanvas )
|
||||
{
|
||||
@ -544,24 +565,8 @@ QgsRect _getFullExtent( QString const & canonicalMapCanvasName )
|
||||
{
|
||||
// XXX since this is a cut-n-paste from above, maybe generalize to a
|
||||
// XXX separate function?
|
||||
// first find the canonical map canvas
|
||||
|
||||
QgsMapCanvas * theMapCanvas;
|
||||
|
||||
QWidgetList * list = QApplication::topLevelWidgets();
|
||||
QWidgetListIt it( *list ); // iterate over the widgets
|
||||
QWidget * w;
|
||||
|
||||
while ( (w=it.current()) != 0 )
|
||||
{ // for each top level widget...
|
||||
++it;
|
||||
theMapCanvas = dynamic_cast<QgsMapCanvas*>(w->child( canonicalMapCanvasName, 0, true ));
|
||||
|
||||
if ( theMapCanvas )
|
||||
{ break; }
|
||||
}
|
||||
delete list; // delete the list, not the widgets
|
||||
|
||||
// first find the canonical map canvas
|
||||
QgsMapCanvas *theMapCanvas = _findMapCanvas(canonicalMapCanvasName);
|
||||
|
||||
if( ! theMapCanvas )
|
||||
{
|
||||
@ -596,24 +601,8 @@ QgsRect _getExtent( QString const & canonicalMapCanvasName )
|
||||
{
|
||||
// XXX since this is a cut-n-paste from above, maybe generalize to a
|
||||
// XXX separate function?
|
||||
// first find the canonical map canvas
|
||||
|
||||
QgsMapCanvas * theMapCanvas;
|
||||
|
||||
QWidgetList * list = QApplication::topLevelWidgets();
|
||||
QWidgetListIt it( *list ); // iterate over the widgets
|
||||
QWidget * w;
|
||||
|
||||
while ( (w=it.current()) != 0 )
|
||||
{ // for each top level widget...
|
||||
++it;
|
||||
theMapCanvas = dynamic_cast<QgsMapCanvas*>(w->child( canonicalMapCanvasName, 0, true ));
|
||||
|
||||
if ( theMapCanvas )
|
||||
{ break; }
|
||||
}
|
||||
delete list; // delete the list, not the widgets
|
||||
|
||||
// first find the canonical map canvas
|
||||
QgsMapCanvas *theMapCanvas = _findMapCanvas(canonicalMapCanvasName);
|
||||
|
||||
if( ! theMapCanvas )
|
||||
{
|
||||
@ -706,9 +695,6 @@ QgsProject::read( )
|
||||
return false;
|
||||
}
|
||||
|
||||
// XXX insert code for handling z order
|
||||
|
||||
|
||||
// restore the canvas' area of interest
|
||||
|
||||
// restor the area of interest, or extent
|
||||
@ -785,17 +771,17 @@ QgsProject::write( )
|
||||
|
||||
QDomDocumentType documentType = DOMImplementation.createDocumentType("qgis","http://mrcc.com/qgis.dtd","SYSTEM");
|
||||
std::auto_ptr<QDomDocument> doc =
|
||||
std::auto_ptr<QDomDocument>( new QDomDocument( documentType ) );
|
||||
std::auto_ptr<QDomDocument>( new QDomDocument( documentType ) );
|
||||
|
||||
|
||||
QDomElement qgis = doc->createElement( "qgis" );
|
||||
qgis.setAttribute( "projectname", title() );
|
||||
QDomElement qgisNode = doc->createElement( "qgis" );
|
||||
qgisNode.setAttribute( "projectname", title() );
|
||||
|
||||
doc->appendChild( qgis );
|
||||
doc->appendChild( qgisNode );
|
||||
|
||||
// title
|
||||
QDomElement titleNode = doc->createElement( "title" );
|
||||
qgis.appendChild( titleNode );
|
||||
qgisNode.appendChild( titleNode );
|
||||
|
||||
QDomText titleText = doc->createTextNode( title() ); // XXX why have title TWICE?
|
||||
titleNode.appendChild( titleText );
|
||||
@ -803,7 +789,7 @@ QgsProject::write( )
|
||||
// units
|
||||
|
||||
QDomElement unitsNode = doc->createElement( "units" );
|
||||
qgis.appendChild( unitsNode );
|
||||
qgisNode.appendChild( unitsNode );
|
||||
|
||||
QString unitsString;
|
||||
|
||||
@ -825,52 +811,17 @@ QgsProject::write( )
|
||||
|
||||
QDomText unitsText = doc->createTextNode( unitsString );
|
||||
unitsNode.appendChild( unitsText );
|
||||
|
||||
// extent
|
||||
|
||||
// XXX there should eventually be a QgsMapCanvas::writeXML() that does this
|
||||
QDomElement extentNode = doc->createElement( "extent" );
|
||||
qgis.appendChild( extentNode );
|
||||
|
||||
QDomElement xMin = doc->createElement( "xmin" );
|
||||
QDomElement yMin = doc->createElement( "ymin" );
|
||||
QDomElement xMax = doc->createElement( "xmax" );
|
||||
QDomElement yMax = doc->createElement( "ymax" );
|
||||
|
||||
QgsRect mapCanvasExtent = _getExtent( "theMapCanvas" );
|
||||
QDomText xMinText = doc->createTextNode( QString::number(mapCanvasExtent.xMin(),'f') );
|
||||
QDomText yMinText = doc->createTextNode( QString::number(mapCanvasExtent.yMin(),'f') );
|
||||
QDomText xMaxText = doc->createTextNode( QString::number(mapCanvasExtent.xMax(),'f') );
|
||||
QDomText yMaxText = doc->createTextNode( QString::number(mapCanvasExtent.yMax(),'f') );
|
||||
|
||||
xMin.appendChild( xMinText );
|
||||
yMin.appendChild( yMinText );
|
||||
xMax.appendChild( xMaxText );
|
||||
yMax.appendChild( yMaxText );
|
||||
|
||||
extentNode.appendChild( xMin );
|
||||
extentNode.appendChild( yMin );
|
||||
extentNode.appendChild( xMax );
|
||||
extentNode.appendChild( yMax );
|
||||
|
||||
// layers
|
||||
|
||||
// XXX QgsMapLayerRegistry should have a writeXML(), which then calls
|
||||
// XXX QgsMapLayer::writeXML()
|
||||
QDomElement projectLayersNode = doc->createElement( "projectlayers" );
|
||||
projectLayersNode.setAttribute( "layercount",
|
||||
QgsMapLayerRegistry::instance()->mapLayers().size() );
|
||||
|
||||
qgis.appendChild( projectLayersNode );
|
||||
|
||||
|
||||
for ( std::map<QString,QgsMapLayer*>::iterator i =
|
||||
QgsMapLayerRegistry::instance()->mapLayers().begin();
|
||||
i != QgsMapLayerRegistry::instance()->mapLayers().end();
|
||||
i++ )
|
||||
|
||||
// extents and layers info are written by the map canvas
|
||||
// find the canonical map canvas
|
||||
QgsMapCanvas *theMapCanvas = _findMapCanvas( "theMapCanvas" );
|
||||
theMapCanvas->writeXML(qgisNode, *doc);
|
||||
|
||||
if( ! theMapCanvas )
|
||||
{
|
||||
if ( i->first )
|
||||
{ i->second->writeXML( projectLayersNode, *doc ); }
|
||||
qDebug( "Unable to find canvas widget theMapCanvas" );
|
||||
|
||||
return false; // XXX some sort of error value? Exception?
|
||||
}
|
||||
|
||||
doc->normalize(); // XXX I'm not entirely sure what this does
|
||||
@ -900,6 +851,3 @@ QgsProject::properties()
|
||||
{
|
||||
return imp_->properties_;
|
||||
} // QgsProject::properties
|
||||
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user