Modified projectio (serialisation and deserialisation of project files) to use maplayerregistry and not mapcanvas.

Implemented state handling of 'showInOverview' property in project io.


git-svn-id: http://svn.osgeo.org/qgis/trunk@1554 c8812cc2-4d05-0410-92ff-de0c093fc19c
This commit is contained in:
timlinux 2004-06-10 23:10:16 +00:00
parent 077dcef119
commit 3fb49d8efd
10 changed files with 509 additions and 413 deletions

View File

@ -1,8 +1,11 @@
QGIS Change Log QGIS Change Log
ChangeLog,v 1.122 2004/06/10 15:38:53 sbr00pwb Exp ChangeLog,v 1.123 2004/06/10 23:10:16 timlinux Exp
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
Version 0.3 'Madison' .... development version Version 0.3 'Madison' .... development version
2004-06-10 [ts] 0.3.0devel27
** Modified projectio (serialisation and deserialisation of project files) to use maplayerregistry and not mapcanvas.
** Implemented state handling of 'showInOverview' property in project io.
2004-06-10 [petebr] 0.3.0devel26 2004-06-10 [petebr] 0.3.0devel26
Tidied up the SPIT gui to match the plugin template. Tidied up the SPIT gui to match the plugin template.
Fixed bug in scale bar which displayed the bar the wrong size! Fixed bug in scale bar which displayed the bar the wrong size!

View File

@ -1,6 +1,6 @@
dnl Process this file with autoconf to produce a configure script. dnl Process this file with autoconf to produce a configure script.
dnl configure.in,v 1.125 2004/06/10 15:38:53 sbr00pwb Exp dnl configure.in,v 1.126 2004/06/10 23:10:16 timlinux Exp
AC_INIT AC_INIT
@ -24,7 +24,7 @@ dnl ---------------------------------------------------------------------------
MAJOR_VERSION=0 MAJOR_VERSION=0
MINOR_VERSION=3 MINOR_VERSION=3
MICRO_VERSION=0 MICRO_VERSION=0
EXTRA_VERSION=26 EXTRA_VERSION=27
if test $EXTRA_VERSION -eq 0; then if test $EXTRA_VERSION -eq 0; then
VERSION=${MAJOR_VERSION}.${MINOR_VERSION}.${MICRO_VERSION} VERSION=${MAJOR_VERSION}.${MINOR_VERSION}.${MICRO_VERSION}
else else

View File

@ -31,7 +31,11 @@
<!ELEMENT datasource (#PCDATA) > <!ELEMENT datasource (#PCDATA) >
<!ELEMENT zorder (#PCDATA) > <!ELEMENT zorder (#PCDATA) >
<!-- Attribute Lists --> <!-- Attribute Lists -->
<!ATTLIST maplayer <!--Raster : flag indicating whether the layer should be represented in overview or not -->
<!ELEMENT showInOverviewFlag>
<!-- Attribute lists -->
<!ATTLIST showInOverViewFlag boolean (1|0|true|false) "false">
<!ATTLIST maplayer
type (vector|raster|database) "vector" type (vector|raster|database) "vector"
visible (1|0) "0" visible (1|0) "0"
> >

View File

@ -9,7 +9,7 @@
<ignoreparts/> <ignoreparts/>
<projectdirectory>.</projectdirectory> <projectdirectory>.</projectdirectory>
<absoluteprojectpath>false</absoluteprojectpath> <absoluteprojectpath>false</absoluteprojectpath>
<description></description> <description/>
<secondaryLanguages/> <secondaryLanguages/>
</general> </general>
<kdevautoproject> <kdevautoproject>
@ -21,7 +21,7 @@
<mainprogram>src/qgis</mainprogram> <mainprogram>src/qgis</mainprogram>
<directoryradio>executable</directoryradio> <directoryradio>executable</directoryradio>
<customdirectory>/</customdirectory> <customdirectory>/</customdirectory>
<programargs></programargs> <programargs/>
<terminal>false</terminal> <terminal>false</terminal>
<autocompile>true</autocompile> <autocompile>true</autocompile>
<envvars/> <envvars/>
@ -61,19 +61,19 @@
</debug> </debug>
<default> <default>
<configargs>--prefix=$HOME --enable-debug</configargs> <configargs>--prefix=$HOME --enable-debug</configargs>
<builddir></builddir> <builddir/>
<topsourcedir></topsourcedir> <topsourcedir/>
<cppflags></cppflags> <cppflags/>
<ldflags></ldflags> <ldflags/>
<ccompiler>kdevgccoptions</ccompiler> <ccompiler>kdevgccoptions</ccompiler>
<cxxcompiler>kdevgppoptions</cxxcompiler> <cxxcompiler>kdevgppoptions</cxxcompiler>
<f77compiler>kdevpgf77options</f77compiler> <f77compiler>kdevpgf77options</f77compiler>
<ccompilerbinary></ccompilerbinary> <ccompilerbinary/>
<cxxcompilerbinary></cxxcompilerbinary> <cxxcompilerbinary/>
<f77compilerbinary></f77compilerbinary> <f77compilerbinary/>
<cflags></cflags> <cflags/>
<cxxflags>-O0 -g3</cxxflags> <cxxflags>-O0 -g3</cxxflags>
<f77flags></f77flags> <f77flags/>
</default> </default>
</configurations> </configurations>
<make> <make>
@ -84,17 +84,17 @@
<abortonerror>true</abortonerror> <abortonerror>true</abortonerror>
<numberofjobs>1</numberofjobs> <numberofjobs>1</numberofjobs>
<dontact>false</dontact> <dontact>false</dontact>
<makebin></makebin> <makebin/>
</make> </make>
</kdevautoproject> </kdevautoproject>
<kdevdebugger> <kdevdebugger>
<general> <general>
<dbgshell>libtool</dbgshell> <dbgshell>libtool</dbgshell>
<programargs></programargs> <programargs/>
<gdbpath></gdbpath> <gdbpath/>
<configGdbScript></configGdbScript> <configGdbScript/>
<runShellScript></runShellScript> <runShellScript/>
<runGdbScript></runGdbScript> <runGdbScript/>
<breakonloadinglibs>true</breakonloadinglibs> <breakonloadinglibs>true</breakonloadinglibs>
<separatetty>false</separatetty> <separatetty>false</separatetty>
<floatingtoolbar>false</floatingtoolbar> <floatingtoolbar>false</floatingtoolbar>
@ -142,16 +142,24 @@
<argumentsHintDelay>400</argumentsHintDelay> <argumentsHintDelay>400</argumentsHintDelay>
<headerCompletionDelay>250</headerCompletionDelay> <headerCompletionDelay>250</headerCompletionDelay>
</codecompletion> </codecompletion>
<references> <references/>
<pcs>Qt</pcs>
<pcs>GDAL</pcs>
</references>
</kdevcppsupport> </kdevcppsupport>
<kdevfileview> <kdevfileview>
<groups/> <groups>
<hidenonprojectfiles>false</hidenonprojectfiles>
<hidenonlocation>false</hidenonlocation>
</groups>
<tree> <tree>
<hidepatterns>*.o,*.lo,CVS</hidepatterns> <hidepatterns>*.o,*.lo,CVS</hidepatterns>
<hidenonprojectfiles>false</hidenonprojectfiles> <hidenonprojectfiles>false</hidenonprojectfiles>
<showvcsfields>false</showvcsfields>
</tree> </tree>
</kdevfileview> </kdevfileview>
<kdevcvsservice>
<recursivewhenupdate>true</recursivewhenupdate>
<prunedirswhenupdate>true</prunedirswhenupdate>
<createdirswhenupdate>true</createdirswhenupdate>
<recursivewhencommitremove>true</recursivewhencommitremove>
<revertoptions>-C</revertoptions>
</kdevcvsservice>
</kdevelop> </kdevelop>

View File

@ -1612,7 +1612,7 @@ void QgisApp::fileOpen()
if (answer != QMessageBox::Cancel) if (answer != QMessageBox::Cancel)
{ {
mMapCanvas->freeze(true); mMapCanvas->freeze(true);
QgsProjectIo *pio = new QgsProjectIo(mMapCanvas, QgsProjectIo::OPEN, this); QgsProjectIo *pio = new QgsProjectIo( QgsProjectIo::OPEN, this);
if (pio->read()) if (pio->read())
{ {
@ -1630,9 +1630,9 @@ void QgisApp::fileOpen()
void QgisApp::fileSave() void QgisApp::fileSave()
{ {
QgsProjectIo *pio = new QgsProjectIo(mMapCanvas, QgsProjectIo::SAVE); QgsProjectIo *pio = new QgsProjectIo( QgsProjectIo::SAVE);
pio->setFileName(mFullPathName); pio->setFileName(mFullPathName);
if (pio->write()) if (pio->write(mMapCanvas->extent()))
{ {
setCaption(tr("Quantum GIS --") + " " + pio->baseName()); setCaption(tr("Quantum GIS --") + " " + pio->baseName());
statusBar()->message(tr("Saved map to:") + " " + pio->fullPathName()); statusBar()->message(tr("Saved map to:") + " " + pio->fullPathName());
@ -1644,8 +1644,8 @@ void QgisApp::fileSave()
void QgisApp::fileSaveAs() void QgisApp::fileSaveAs()
{ {
QgsProjectIo *pio = new QgsProjectIo(mMapCanvas, QgsProjectIo::SAVEAS); QgsProjectIo *pio = new QgsProjectIo( QgsProjectIo::SAVEAS);
if (pio->write()) if (pio->write(mMapCanvas->extent()))
{ {
setCaption(tr("Quantum GIS --") + " " + pio->baseName()); setCaption(tr("Quantum GIS --") + " " + pio->baseName());
statusBar()->message(tr("Saved map to:") + " " + pio->fullPathName()); statusBar()->message(tr("Saved map to:") + " " + pio->fullPathName());
@ -1782,7 +1782,7 @@ bool QgisApp::addProject(QString projectFile)
// adds a saved project to qgis, usually called on startup by // adds a saved project to qgis, usually called on startup by
// specifying a project file on the command line // specifying a project file on the command line
bool returnValue = false; bool returnValue = false;
QgsProjectIo *pio = new QgsProjectIo(mMapCanvas, QgsProjectIo::OPEN, this); QgsProjectIo *pio = new QgsProjectIo(QgsProjectIo::OPEN, this);
#ifdef QGISDEBUG #ifdef QGISDEBUG
std::cout << "Loading Project - about to call ProjectIO->read()" << std::endl; std::cout << "Loading Project - about to call ProjectIO->read()" << std::endl;
#endif #endif
@ -2086,6 +2086,17 @@ void QgisApp::removeLayer()
mMapCanvas->clear(); mMapCanvas->clear();
mMapCanvas->render(); mMapCanvas->render();
} }
void QgisApp::removeAllLayers()
{
std::map<QString, QgsMapLayer *> myMapLayers = mMapLayerRegistry->mapLayers();
std::map<QString, QgsMapLayer *>::iterator myMapIterator;
for ( myMapIterator = myMapLayers.begin(); myMapIterator != myMapLayers.end(); ++myMapIterator )
{
mMapLayerRegistry->removeMapLayer( myMapIterator->first );
}
mOverviewCanvas->clear();
mMapCanvas->clear();
} //remove all layers
void QgisApp::zoomToLayerExtent() void QgisApp::zoomToLayerExtent()
{ {
@ -2789,6 +2800,47 @@ void QgisApp::addVectorLayer(QString vectorLayerPath, QString baseName, QString
} }
void QgisApp::addMapLayer(QgsMapLayer *theMapLayer)
{
mMapCanvas->freeze();
QApplication::setOverrideCursor(Qt::WaitCursor);
if(theMapLayer->isValid())
{
// Register this layer with the layers registry
mMapLayerRegistry->addMapLayer(theMapLayer);
// init the context menu so it can connect to slots in main app
theMapLayer->initContextMenu(this);
// add it to the mapcanvas collection
mMapCanvas->addLayer(theMapLayer);
//connect up a request from the raster layer to show in overview map
QObject::connect(theMapLayer,
SIGNAL(showInOverview(QString,bool)),
this,
SLOT(setLayerOverviewStatus(QString,bool)));
mProjectIsDirtyFlag = true;
statusBar()->message(mMapCanvas->extent().stringRep(2));
}else
{
QMessageBox::critical(this,"Layer is not valid",
"The layer is not a valid layer and can not be added to the map");
}
qApp->processEvents();
mMapCanvas->freeze(false);
mMapCanvas->render();
QApplication::restoreOverrideCursor();
}
void QgisApp::setExtent(QgsRect theRect)
{
mMapCanvas->setExtent(theRect);
}
int QgisApp::saveDirty() int QgisApp::saveDirty()
{ {
int answer = 0; int answer = 0;

View File

@ -115,6 +115,14 @@ public:
*/ */
bool addRasterLayer(QFileInfo const & rasterFile); bool addRasterLayer(QFileInfo const & rasterFile);
/** Add a 'pre-made' map layer to the project */
void addMapLayer(QgsMapLayer *theMapLayer);
/** Set the extents of the map canvas */
void setExtent(QgsRect theRect);
//! Remove all layers from the map and legend
void removeAllLayers();
/** opens a qgis project file /** opens a qgis project file
@returns false if unable to open the project @returns false if unable to open the project

View File

@ -91,3 +91,8 @@ void QgsMapLayerRegistry::removeAllMapLayers()
//delete mMapLayers[theLayerId]; //delete mMapLayers[theLayerId];
//mMapLayers.erase(theLayerId); //mMapLayers.erase(theLayerId);
} }
std::map<QString,QgsMapLayer*> QgsMapLayerRegistry::mapLayers()
{
return mMapLayers;
}

View File

@ -39,6 +39,8 @@ public:
QStringList mapLayerList(); QStringList mapLayerList();
//! Retrieve a pointer to a loaded plugin by id //! Retrieve a pointer to a loaded plugin by id
QgsMapLayer * mapLayer(QString theLayerId); QgsMapLayer * mapLayer(QString theLayerId);
//! Retrieve the mapLayers collection (mainly intended for use by projectio)
std::map<QString,QgsMapLayer*> mapLayers();
//! Add a layer to the map of loaded layers //! Add a layer to the map of loaded layers
void addMapLayer(QgsMapLayer * theMapLayer); void addMapLayer(QgsMapLayer * theMapLayer);
//! Remove a layer from qgis - any canvases using that layer will need to remove it //! Remove a layer from qgis - any canvases using that layer will need to remove it

View File

@ -1,10 +1,10 @@
/*************************************************************************** /***************************************************************************
qgsprojectio.cpp - Save/Restore QGIS project qgsprojectio.cpp - Save/Restore QGIS project
-------------------------------------- --------------------------------------
Date : 19-Oct-2003 Date : 19-Oct-2003
Copyright : (C) 2003 by Gary E.Sherman Copyright : (C) 2003 by Gary E.Sherman
email : sherman at mrcc.com email : sherman at mrcc.com
/*************************************************************************** ***************************************************************************
* * * *
* This program is free software; you can redistribute it and/or modify * * This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by * * it under the terms of the GNU General Public License as published by *
@ -12,7 +12,7 @@
* (at your option) any later version. * * (at your option) any later version. *
* * * *
***************************************************************************/ ***************************************************************************/
/* qgsprojectio.cpp,v 1.38 2004/06/09 15:02:33 timlinux Exp */ /* qgsprojectio.cpp,v 1.39 2004/06/10 23:07:08 timlinux Exp */
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
#include <qfiledialog.h> #include <qfiledialog.h>
@ -40,9 +40,11 @@
#include "qgsdlgvectorlayerproperties.h" #include "qgsdlgvectorlayerproperties.h"
#include "qgisapp.h" #include "qgisapp.h"
#include "qgsmarkersymbol.h" #include "qgsmarkersymbol.h"
#include "qgsmaplayerregistry.h"
#include <map>
QgsProjectIo::QgsProjectIo(QgsMapCanvas * _map, int _action, QgisApp * qgis) QgsProjectIo::QgsProjectIo(int _action, QgisApp * qgis)
: map(_map), action(_action), qgisApp(qgis) : action(_action), qgisApp(qgis)
{} {}
@ -56,30 +58,30 @@ QString QgsProjectIo::baseName()
return fi.baseName(true); return fi.baseName(true);
} }
bool QgsProjectIo::write() bool QgsProjectIo::write(QgsRect theRect)
{ {
if (fullPath.isEmpty()) if (fullPath.isEmpty())
{ {
selectFileName(); selectFileName();
} }
//QMessageBox::information(0,"Full Path",fullPath); //QMessageBox::information(0,"Full Path",fullPath);
int okToSave = 0; int okToSave = 0;
if (QFile::exists(fullPath) && (action == SAVEAS)) if (QFile::exists(fullPath) && (action == SAVEAS))
{ {
okToSave = okToSave =
QMessageBox::warning(0, QObject::tr("Overwrite File?"), QMessageBox::warning(0, QObject::tr("Overwrite File?"),
QObject::tr("%1 exists.%2Do you want to overwrite it?").arg(fullPath).arg("\n"), QObject::tr("Yes"), QObject::tr("%1 exists.%2Do you want to overwrite it?").arg(fullPath).arg("\n"), QObject::tr("Yes"),
QObject::tr("No")); QObject::tr("No"));
} }
if (okToSave == 0) if (okToSave == 0)
{ {
// write the project information to the selected file // write the project information to the selected file
writeXML(); writeXML(theRect);
return true; return true;
} else } else
{ {
return false; return false;
} }
} }
bool QgsProjectIo::read(QString path) bool QgsProjectIo::read(QString path)
@ -92,232 +94,240 @@ bool QgsProjectIo::read(QString path)
std::auto_ptr<QDomDocument> doc; std::auto_ptr<QDomDocument> doc;
if (!path.isEmpty()) if (!path.isEmpty())
{
doc = std::auto_ptr<QDomDocument>(new QDomDocument("qgisdocument"));
QFile file(path);
if (!file.open(IO_ReadOnly))
{ {
doc = std::auto_ptr<QDomDocument>(new QDomDocument("qgisdocument")); return false;
QFile file(path);
if (!file.open(IO_ReadOnly))
{
return false;
}
if (!doc->setContent(&file))
{
file.close();
return false;
}
file.close();
qWarning("opened document" + file.name());
// clear the map canvas
map->removeAll();
// get the extent
QDomNodeList extents = doc->elementsByTagName("extent");
QDomNode extentNode = extents.item(0);
QDomNode xminNode = extentNode.namedItem("xmin");
QDomNode yminNode = extentNode.namedItem("ymin");
QDomNode xmaxNode = extentNode.namedItem("xmax");
QDomNode ymaxNode = extentNode.namedItem("ymax");
QDomElement exElement = xminNode.toElement();
double xmin = exElement.text().toDouble();
exElement = yminNode.toElement();
double ymin = exElement.text().toDouble();
exElement = xmaxNode.toElement();
double xmax = exElement.text().toDouble();
exElement = ymaxNode.toElement();
double ymax = exElement.text().toDouble();
QgsRect savedExtent(xmin, ymin, xmax, ymax);
QDomNodeList nl = doc->elementsByTagName("maplayer");
QString layerCount;
layerCount = layerCount.setNum(nl.count());
//QMessageBox::information(0, "Number of map layers", layerCount);
QString wk;
// process the map layer nodes
for (int i = 0; i < nl.count(); i++)
{
QDomNode node = nl.item(i);
QDomElement element = node.toElement();
QString type = element.attribute("type");
QString visible = element.attribute("visible");
QString showInOverview = element.attribute("showInOverviewFlag");
//QMessageBox::information(0,"Type of map layer", type);
// process layer name
QDomNode mnl = node.namedItem("layername");
QTextStream ts(&wk, IO_WriteOnly);
ts << mnl.nodeType();
//QMessageBox::information(0,"Node Type", wk);
QDomElement mne = mnl.toElement();
//QMessageBox::information(0,"Layer Name", mne.text());
QString layerName = mne.text();
//process data source
mnl = node.namedItem("datasource");
mne = mnl.toElement();
//QMessageBox::information(0,"Datasource Name", mne.text());
QString dataSource = mne.text();
//process zorder
mnl = node.namedItem("zorder");
mne = mnl.toElement();
//QMessageBox::information(0,"Zorder", mne.text());
// XXX I strongly suggest that much of this be pushed into the
// XXX provider objects. There just be just enough here to dispatch the
// XXX read to a provider. --MAC
// add the layer to the maplayer
if (type == "vector")
{
QString provider;
// determine type of vector layer
if ((dataSource.find("host=") > -1) && (dataSource.find("dbname=") > -1))
{
provider = "postgres";
} else
{
provider = "ogr";
}
QgsVectorLayer *dbl = new QgsVectorLayer(dataSource, layerName, provider);
Q_CHECK_PTR( dbl );
if ( ! dbl )
{
#ifdef QGISDEBUG
std::cerr << __FILE__ << ":" << __LINE__
<< " unable to create vector layer for "
<< dataSource << "\n";
#endif
return false;
}
if ( ! dbl->isValid() )
{
#ifdef QGISDEBUG
std::cerr << __FILE__ << ":" << __LINE__
<< " created vector layer for "
<< dataSource << "is invalid ... skipping\n";
#endif
delete dbl; // discard bogus layer
// XXX naturally we could be smart and ask the user for the
// XXX new location of the data, but for now we'll just
// XXX ignore the missing data and move on. Perhaps this
// XXX will be revisited when the architecture is refactored.
return false;
}
QDomNode singlenode = node.namedItem("singlesymbol");
QDomNode graduatednode = node.namedItem("graduatedsymbol");
QDomNode continuousnode = node.namedItem("continuoussymbol");
QDomNode singlemarkernode = node.namedItem("singlemarker");
QDomNode graduatedmarkernode = node.namedItem("graduatedmarker");
QgsRenderer* renderer;
if (!singlenode.isNull())
{
renderer = new QgsSingleSymRenderer();
renderer->readXML(singlenode,*dbl);
}
else if (!graduatednode.isNull())
{
renderer = new QgsGraduatedSymRenderer();
renderer->readXML(graduatednode,*dbl);
}
else if (!continuousnode.isNull())
{
renderer = new QgsContinuousColRenderer();
renderer->readXML(continuousnode,*dbl);
}
else if(!singlemarkernode.isNull())
{
renderer = new QgsSiMaRenderer();
renderer->readXML(singlemarkernode,*dbl);
}
else if(!graduatedmarkernode.isNull())
{
renderer = new QgsGraduatedMaRenderer();
renderer->readXML(graduatedmarkernode,*dbl);
}
dbl->setVisible(visible == "1");
dbl->initContextMenu(qgisApp);
map->addLayer(dbl);
} else if (type == "raster")
{
QgsRasterLayer *myRasterLayer = new QgsRasterLayer(dataSource, layerName);
myRasterLayer->initContextMenu(qgisApp);
map->addLayer(myRasterLayer);
myRasterLayer->setVisible(visible == "1");
mnl = node.namedItem("rasterproperties");
QDomNode snode = mnl.namedItem("showDebugOverlayFlag");
QDomElement myElement = snode.toElement();
QVariant myQVariant = (QVariant) myElement.attribute("boolean");
myRasterLayer->setShowDebugOverlayFlag(myQVariant.toBool());
snode = mnl.namedItem("drawingStyle");
myElement = snode.toElement();
myRasterLayer->setDrawingStyle(myElement.text());
snode = mnl.namedItem("invertHistogramFlag");
myElement = snode.toElement();
myQVariant = (QVariant) myElement.attribute("boolean");
myRasterLayer->setInvertHistogramFlag(myQVariant.toBool());
snode = mnl.namedItem("stdDevsToPlotDouble");
myElement = snode.toElement();
myRasterLayer->setStdDevsToPlot(myElement.text().toDouble());
snode = mnl.namedItem("transparencyLevelInt");
myElement = snode.toElement();
myRasterLayer->setTransparency(myElement.text().toInt());
snode = mnl.namedItem("redBandNameQString");
myElement = snode.toElement();
myRasterLayer->setRedBandName(myElement.text());
snode = mnl.namedItem("greenBandNameQString");
myElement = snode.toElement();
myRasterLayer->setGreenBandName(myElement.text());
snode = mnl.namedItem("blueBandNameQString");
myElement = snode.toElement();
myRasterLayer->setBlueBandName(myElement.text());
snode = mnl.namedItem("grayBandNameQString");
myElement = snode.toElement();
myRasterLayer->setGrayBandName(myElement.text());
}
map->setExtent(savedExtent);
}
return true;
} }
if (!doc->setContent(&file))
{
file.close();
return false;
}
file.close();
qWarning("opened document" + file.name());
// clear the map canvas
qgisApp->removeAllLayers();
// get the extent
QDomNodeList extents = doc->elementsByTagName("extent");
QDomNode extentNode = extents.item(0);
QDomNode xminNode = extentNode.namedItem("xmin");
QDomNode yminNode = extentNode.namedItem("ymin");
QDomNode xmaxNode = extentNode.namedItem("xmax");
QDomNode ymaxNode = extentNode.namedItem("ymax");
QDomElement exElement = xminNode.toElement();
double xmin = exElement.text().toDouble();
exElement = yminNode.toElement();
double ymin = exElement.text().toDouble();
exElement = xmaxNode.toElement();
double xmax = exElement.text().toDouble();
exElement = ymaxNode.toElement();
double ymax = exElement.text().toDouble();
QgsRect savedExtent(xmin, ymin, xmax, ymax);
QDomNodeList nl = doc->elementsByTagName("maplayer");
QString layerCount;
layerCount = layerCount.setNum(nl.count());
//QMessageBox::information(0, "Number of map layers", layerCount);
QString wk;
// process the map layer nodes
for (int i = 0; i < nl.count(); i++)
{
QDomNode node = nl.item(i);
QDomElement element = node.toElement();
QString type = element.attribute("type");
QString visible = element.attribute("visible");
QString showInOverview = element.attribute("showInOverviewFlag");
//QMessageBox::information(0,"Type of map layer", type);
// process layer name
QDomNode mnl = node.namedItem("layername");
QTextStream ts(&wk, IO_WriteOnly);
ts << mnl.nodeType();
//QMessageBox::information(0,"Node Type", wk);
QDomElement mne = mnl.toElement();
//QMessageBox::information(0,"Layer Name", mne.text());
QString layerName = mne.text();
//process data source
mnl = node.namedItem("datasource");
mne = mnl.toElement();
//QMessageBox::information(0,"Datasource Name", mne.text());
QString dataSource = mne.text();
//process zorder
mnl = node.namedItem("zorder");
mne = mnl.toElement();
//QMessageBox::information(0,"Zorder", mne.text());
// XXX I strongly suggest that much of this be pushed into the
// XXX provider objects. There just be just enough here to dispatch the
// XXX read to a provider. --MAC
// add the layer to the maplayer
if (type == "vector")
{
QString provider;
// determine type of vector layer
if ((dataSource.find("host=") > -1) && (dataSource.find("dbname=") > -1))
{
provider = "postgres";
} else
{
provider = "ogr";
}
QgsVectorLayer *dbl = new QgsVectorLayer(dataSource, layerName, provider);
Q_CHECK_PTR( dbl );
if ( ! dbl )
{
#ifdef QGISDEBUG
std::cerr << __FILE__ << ":" << __LINE__
<< " unable to create vector layer for "
<< dataSource << "\n";
#endif
return false;
}
if ( ! dbl->isValid() )
{
#ifdef QGISDEBUG
std::cerr << __FILE__ << ":" << __LINE__
<< " created vector layer for "
<< dataSource << "is invalid ... skipping\n";
#endif
delete dbl; // discard bogus layer
// XXX naturally we could be smart and ask the user for the
// XXX new location of the data, but for now we'll just
// XXX ignore the missing data and move on. Perhaps this
// XXX will be revisited when the architecture is refactored.
return false;
}
QDomNode singlenode = node.namedItem("singlesymbol");
QDomNode graduatednode = node.namedItem("graduatedsymbol");
QDomNode continuousnode = node.namedItem("continuoussymbol");
QDomNode singlemarkernode = node.namedItem("singlemarker");
QDomNode graduatedmarkernode = node.namedItem("graduatedmarker");
QgsRenderer* renderer;
if (!singlenode.isNull())
{
renderer = new QgsSingleSymRenderer();
renderer->readXML(singlenode,*dbl);
}
else if (!graduatednode.isNull())
{
renderer = new QgsGraduatedSymRenderer();
renderer->readXML(graduatednode,*dbl);
}
else if (!continuousnode.isNull())
{
renderer = new QgsContinuousColRenderer();
renderer->readXML(continuousnode,*dbl);
}
else if(!singlemarkernode.isNull())
{
renderer = new QgsSiMaRenderer();
renderer->readXML(singlemarkernode,*dbl);
}
else if(!graduatedmarkernode.isNull())
{
renderer = new QgsGraduatedMaRenderer();
renderer->readXML(graduatedmarkernode,*dbl);
}
dbl->setVisible(visible == "1");
if (showInOverview == "1")
{
dbl->toggleShowInOverview();
}
dbl->initContextMenu(qgisApp);
qgisApp->addMapLayer(dbl);
}
else if (type == "raster")
{
QgsRasterLayer *myRasterLayer = new QgsRasterLayer(dataSource, layerName);
qgisApp->addMapLayer(myRasterLayer);
myRasterLayer->setVisible(visible == "1");
if (showInOverview == "1")
{
myRasterLayer->toggleShowInOverview();
}
mnl = node.namedItem("rasterproperties");
QDomNode snode = mnl.namedItem("showDebugOverlayFlag");
QDomElement myElement = snode.toElement();
QVariant myQVariant = (QVariant) myElement.attribute("boolean");
myRasterLayer->setShowDebugOverlayFlag(myQVariant.toBool());
snode = mnl.namedItem("drawingStyle");
myElement = snode.toElement();
myRasterLayer->setDrawingStyle(myElement.text());
snode = mnl.namedItem("invertHistogramFlag");
myElement = snode.toElement();
myQVariant = (QVariant) myElement.attribute("boolean");
myRasterLayer->setInvertHistogramFlag(myQVariant.toBool());
snode = mnl.namedItem("stdDevsToPlotDouble");
myElement = snode.toElement();
myRasterLayer->setStdDevsToPlot(myElement.text().toDouble());
snode = mnl.namedItem("transparencyLevelInt");
myElement = snode.toElement();
myRasterLayer->setTransparency(myElement.text().toInt());
snode = mnl.namedItem("redBandNameQString");
myElement = snode.toElement();
myRasterLayer->setRedBandName(myElement.text());
snode = mnl.namedItem("greenBandNameQString");
myElement = snode.toElement();
myRasterLayer->setGreenBandName(myElement.text());
snode = mnl.namedItem("blueBandNameQString");
myElement = snode.toElement();
myRasterLayer->setBlueBandName(myElement.text());
snode = mnl.namedItem("grayBandNameQString");
myElement = snode.toElement();
myRasterLayer->setGrayBandName(myElement.text());
}
qgisApp->setExtent(savedExtent);
}
return true;
}
} }
QString QgsProjectIo::selectFileName() QString QgsProjectIo::selectFileName()
{ {
if (action == SAVE && fullPath.isEmpty()) if (action == SAVE && fullPath.isEmpty())
{ {
action = SAVEAS; action = SAVEAS;
} }
switch (action) switch (action)
{ {
case OPEN: case OPEN:
fullPath = fullPath =
QFileDialog::getOpenFileName("./", QObject::tr("QGis files (*.qgs)"), 0, 0, QFileDialog::getOpenFileName("./", QObject::tr("QGis files (*.qgs)"), 0, 0,
QObject::tr("Choose a QGIS project file to open")); QObject::tr("Choose a QGIS project file to open"));
break; break;
case SAVEAS: case SAVEAS:
fullPath = fullPath =
QFileDialog::getSaveFileName("./", QObject::tr("QGis files (*.qgs)"), 0, 0, QObject::tr("Choose a filename to save")); QFileDialog::getSaveFileName("./", QObject::tr("QGis files (*.qgs)"), 0, 0, QObject::tr("Choose a filename to save"));
break; break;
} }
return fullPath; return fullPath;
} }
@ -333,145 +343,149 @@ QString QgsProjectIo::fullPathName()
void QgsProjectIo::writeXML() void QgsProjectIo::writeXML(QgsRect theExtent)
{ {
std::ofstream xml(fullPath); std::ofstream xml(fullPath);
if (!xml.fail()) if (!xml.fail())
{
xml << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << std::endl;
xml << "<!DOCTYPE qgis SYSTEM \"http://mrcc.com/qgis.dtd\">" << std::endl;
xml << "<qgis projectname=\"default project\">\n";
xml << "<title>QGis Project File</title>\n";
xml << "<extent>\n";
xml << "\t<xmin>" << theExtent.xMin() << "</xmin>\n";
xml << "\t<ymin>" << theExtent.yMin() << "</ymin>\n";
xml << "\t<xmax>" << theExtent.xMax() << "</xmax>\n";
xml << "\t<ymax>" << theExtent.yMax() << "</ymax>\n";
xml << "</extent>\n";
// get the layer registry so we can write the layer data to disk
// the registry is a singleton so
// it will be the same registry data as used by the map canvas
QgsMapLayerRegistry * myMapLayerRegistry = QgsMapLayerRegistry::instance();
std::map<QString, QgsMapLayer *> myMapLayers = myMapLayerRegistry->mapLayers();
xml << "<projectlayers layercount=\"" << myMapLayers.size() << "\"> \n";
int i=0;
std::map<QString, QgsMapLayer *>::iterator myMapIterator;
for ( myMapIterator = myMapLayers.begin(); myMapIterator != myMapLayers.end(); ++myMapIterator )
{ {
xml << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << std::endl; QgsMapLayer *lyr = myMapIterator->second;
xml << "<!DOCTYPE qgis SYSTEM \"http://mrcc.com/qgis.dtd\">" << std::endl; bool isDatabase = false;
xml << "<qgis projectname=\"default project\">\n"; xml << "\t<maplayer type=\"";
xml << "<title>QGis Project File</title>\n"; switch (lyr->type())
{
case QgsMapLayer::VECTOR:
xml << "vector";
break;
case QgsMapLayer::RASTER:
xml << "raster";
break;
case QgsMapLayer::DATABASE:
xml << "database";
isDatabase = true;
break;
}
//
// layer visibility
//
xml << "\" visible=\"";
if (lyr->visible())
{
xml << "1";
} else
{
xml << "0";
}
//
// layer is shown in overview?
//
xml << "\" showInOverviewFlag=\"";
if (lyr->showInOverviewStatus())
{
xml << "1";
} else
{
xml << "0";
}
xml << "\">\n";
xml << "<extent>\n"; if (isDatabase)
QgsRect extent = map->extent(); {
// cast the layer to a qgsdatabaselayer
xml << "\t<xmin>" << extent.xMin() << "</xmin>\n"; // TODO fix this so database layers are properly saved/restored
xml << "\t<ymin>" << extent.yMin() << "</ymin>\n"; // when name is changed in legend
xml << "\t<xmax>" << extent.xMax() << "</xmax>\n"; /* QgsDatabaseLayer *dblyr = (QgsDatabaseLayer *)lyr;
xml << "\t<ymax>" << extent.yMax() << "</ymax>\n"; xml << "\t\t<layername>" + dblyr->schemaName() << "." <<
xml << "</extent>\n"; dblyr->geometryTableName() << "</layername>\n"; */
xml << "\t\t<layername>" + lyr->name() + "</layername>\n";
xml << "<projectlayers layercount=\"" << map->layerCount() << "\"> \n"; } else
// write the layers {
for (int i = 0; i < map->layerCount(); i++) xml << "\t\t<layername>" + lyr->name() + "</layername>\n";
}
xml << "\t\t<datasource>" + lyr->source() + "</datasource>\n";
xml << "\t\t<zorder>" << i << "</zorder>\n";
if (lyr->type() != QgsMapLayer::RASTER)
{
QgsVectorLayer *layer = dynamic_cast < QgsVectorLayer * >(lyr);
if (!layer)
{ {
QgsMapLayer *lyr = map->getZpos(i); qWarning("Warning, cast failed in QgsProjectIo, line 309");
bool isDatabase = false;
xml << "\t<maplayer type=\"";
switch (lyr->type())
{
case QgsMapLayer::VECTOR:
xml << "vector";
break;
case QgsMapLayer::RASTER:
xml << "raster";
break;
case QgsMapLayer::DATABASE:
xml << "database";
isDatabase = true;
break;
}
//
// layer visibility
//
xml << "\" visible=\"";
if (lyr->visible())
{
xml << "1";
} else
{
xml << "0";
}
//
// layer is shown in overview?
//
xml << "\" showInOverviewFlag=\"";
if (lyr->showInOverviewStatus())
{
xml << "1";
} else
{
xml << "0";
}
xml << "\">\n";
if (isDatabase)
{
// cast the layer to a qgsdatabaselayer
// TODO fix this so database layers are properly saved/restored
// when name is changed in legend
/* QgsDatabaseLayer *dblyr = (QgsDatabaseLayer *)lyr;
xml << "\t\t<layername>" + dblyr->schemaName() << "." <<
dblyr->geometryTableName() << "</layername>\n"; */
xml << "\t\t<layername>" + lyr->name() + "</layername>\n";
} else
{
xml << "\t\t<layername>" + lyr->name() + "</layername>\n";
}
xml << "\t\t<datasource>" + lyr->source() + "</datasource>\n";
xml << "\t\t<zorder>" << i << "</zorder>\n";
if (lyr->type() != QgsMapLayer::RASTER)
{
QgsVectorLayer *layer = dynamic_cast < QgsVectorLayer * >(lyr);
if (!layer)
{
qWarning("Warning, cast failed in QgsProjectIo, line 309");
}
QgsRenderer* renderer;
if(renderer=layer->renderer())
{
renderer->writeXML(xml);
}
} else //raster layer properties
{
//cast the maplayer to rasterlayer
QgsRasterLayer *myRasterLayer = (QgsRasterLayer *) lyr;
//Raster flag to indicate whether debug infor overlay should be rendered onto the raster
xml << "\t\t<rasterproperties>\n";
xml << "\t\t\t<showDebugOverlayFlag boolean=\"";
if (myRasterLayer->getShowDebugOverlayFlag())
{
xml << "true\"/>\n";
} else
{
xml << "false\"/>\n";
}
// The drawing style for the layer
xml << "\t\t\t<drawingStyle>" << myRasterLayer->getDrawingStyleAsQString() << "</drawingStyle>\n";
//Raster : flag indicating whether the histogram should be inverted or not
xml << "\t\t\t<invertHistogramFlag boolean=\"";
if (myRasterLayer->getInvertHistogramFlag())
{
xml << "true\"/>\n";
} else
{
xml << "false\"/>\n";
}
//Raster : Number of stddev to plot (0) to ignore -->
xml << "\t\t\t<stdDevsToPlotDouble>" << myRasterLayer->getStdDevsToPlot() << "</stdDevsToPlotDouble>\n";
//Raster transparency for this layer should be 0-255 -->
xml << "\t\t\t<transparencyLevelInt>" << myRasterLayer->getTransparency() << "</transparencyLevelInt>\n";
//Raster : the band to be associated with the color red - usually red -->
xml << "\t\t\t<redBandNameQString>" << myRasterLayer->getRedBandName() << "</redBandNameQString>\n";
//Raster : the band to be associated with the color green - usually green -->
xml << "\t\t\t<greenBandNameQString>" << myRasterLayer->getGreenBandName() << "</greenBandNameQString>\n";
//Raster : the band to be associated with the color blue - usually blue -->
xml << "\t\t\t<blueBandNameQString>" << myRasterLayer->getBlueBandName() << "</blueBandNameQString>\n";
//Raster : the band to be associated with the grayscale only ouput - usually gray -->
xml << "\t\t\t<grayBandNameQString>" << myRasterLayer->getGrayBandName() << "</grayBandNameQString>\n";
xml << "\t\t</rasterproperties>\n";
}
xml << "\t</maplayer>\n";
} }
xml << "</projectlayers>\n";
xml << "</qgis>\n"; QgsRenderer* renderer;
xml.close(); if(renderer=layer->renderer())
} else {
{ renderer->writeXML(xml);
}
} else //raster layer properties
{
//cast the maplayer to rasterlayer
QgsRasterLayer *myRasterLayer = (QgsRasterLayer *) lyr;
//Raster flag to indicate whether debug infor overlay should be rendered onto the raster
xml << "\t\t<rasterproperties>\n";
xml << "\t\t\t<showDebugOverlayFlag boolean=\"";
if (myRasterLayer->getShowDebugOverlayFlag())
{
xml << "true\"/>\n";
} else
{
xml << "false\"/>\n";
}
// The drawing style for the layer
xml << "\t\t\t<drawingStyle>" << myRasterLayer->getDrawingStyleAsQString() << "</drawingStyle>\n";
//Raster : flag indicating whether the histogram should be inverted or not
xml << "\t\t\t<invertHistogramFlag boolean=\"";
if (myRasterLayer->getInvertHistogramFlag())
{
xml << "true\"/>\n";
} else
{
xml << "false\"/>\n";
}
//Raster : Number of stddev to plot (0) to ignore -->
xml << "\t\t\t<stdDevsToPlotDouble>" << myRasterLayer->getStdDevsToPlot() << "</stdDevsToPlotDouble>\n";
//Raster transparency for this layer should be 0-255 -->
xml << "\t\t\t<transparencyLevelInt>" << myRasterLayer->getTransparency() << "</transparencyLevelInt>\n";
//Raster : the band to be associated with the color red - usually red -->
xml << "\t\t\t<redBandNameQString>" << myRasterLayer->getRedBandName() << "</redBandNameQString>\n";
//Raster : the band to be associated with the color green - usually green -->
xml << "\t\t\t<greenBandNameQString>" << myRasterLayer->getGreenBandName() << "</greenBandNameQString>\n";
//Raster : the band to be associated with the color blue - usually blue -->
xml << "\t\t\t<blueBandNameQString>" << myRasterLayer->getBlueBandName() << "</blueBandNameQString>\n";
//Raster : the band to be associated with the grayscale only ouput - usually gray -->
xml << "\t\t\t<grayBandNameQString>" << myRasterLayer->getGrayBandName() << "</grayBandNameQString>\n";
xml << "\t\t</rasterproperties>\n";
}
xml << "\t</maplayer>\n";
i++;
} }
xml << "</projectlayers>\n";
xml << "</qgis>\n";
xml.close();
}
} }

View File

@ -12,13 +12,14 @@
* (at your option) any later version. * * (at your option) any later version. *
* * * *
***************************************************************************/ ***************************************************************************/
/* qgsprojectio.h,v 1.5 2004/02/21 20:54:26 gsherman Exp */ /* qgsprojectio.h,v 1.6 2004/06/10 23:07:08 timlinux Exp */
#ifndef _QGSPROJECTIO_H_ #ifndef _QGSPROJECTIO_H_
#define _QGSPROJECTIO_H_ #define _QGSPROJECTIO_H_
class QgsMapCanvas;
class QgisApp; class QgisApp;
class QgsMapLayerRegistry;
class QgsRect;
/*! \class QgsProjectIo /*! \class QgsProjectIo
* \brief Class to handle reading and writing a Qgis project file * \brief Class to handle reading and writing a Qgis project file
*/ */
@ -26,13 +27,12 @@ class QgsProjectIo
{ {
public: public:
QgsProjectIo(QgsMapCanvas *map=0, int action=SAVE, QgisApp *qgis=0); QgsProjectIo(int action=SAVE, QgisApp *qgis=0);
~QgsProjectIo(); ~QgsProjectIo();
//! Read the file and create the map //! Read the file and create the map
bool read(QString path=0); bool read(QString path=0);
//! Write the contents of the map to a file //! Write the contents of the map to a file
bool write(); bool write(QgsRect theExtent);
void setMapCanvas(QgsMapCanvas *map);
//! Open a file dialog, the type determined by action (SAVE AS or OPEN) //! Open a file dialog, the type determined by action (SAVE AS or OPEN)
QString selectFileName(); QString selectFileName();
//! get the basename of the file (no path, just the file name) //! get the basename of the file (no path, just the file name)
@ -47,13 +47,13 @@ public:
OPEN OPEN
}; };
private: private:
void writeXML(void); void writeXML(QgsRect theExtent);
QString fileName; QString fileName;
QString fullPath; QString fullPath;
bool neverSaved; bool neverSaved;
QgsMapCanvas *map;
//! pointer to the main app for connecting slots //! pointer to the main app for connecting slots
QgisApp *qgisApp; QgisApp *qgisApp;
QgsMapLayerRegistry * mMapLayerRegistry;
int action; int action;
}; };