From b0f064c682c8ac78b205e5907602af40e042fbca Mon Sep 17 00:00:00 2001 From: mhugent Date: Wed, 26 Jan 2011 13:49:53 +0000 Subject: [PATCH] Support relative project pathes in wms server git-svn-id: http://svn.osgeo.org/qgis/trunk/qgis@15086 c8812cc2-4d05-0410-92ff-de0c093fc19c --- src/mapserver/qgsconfigcache.cpp | 2 +- src/mapserver/qgsprojectparser.cpp | 70 ++++++++++++++++++++++++++++-- src/mapserver/qgsprojectparser.h | 8 +++- 3 files changed, 74 insertions(+), 6 deletions(-) diff --git a/src/mapserver/qgsconfigcache.cpp b/src/mapserver/qgsconfigcache.cpp index aedc04c3dc6c..6a89e7d2e838 100644 --- a/src/mapserver/qgsconfigcache.cpp +++ b/src/mapserver/qgsconfigcache.cpp @@ -86,7 +86,7 @@ QgsConfigParser* QgsConfigCache::insertConfiguration( const QString& filePath ) } else if ( documentElem.tagName() == "qgis" ) { - configParser = new QgsProjectParser( configDoc ); + configParser = new QgsProjectParser( configDoc, filePath ); } else { diff --git a/src/mapserver/qgsprojectparser.cpp b/src/mapserver/qgsprojectparser.cpp index 01eaf4f918e7..60da0c8e51ba 100644 --- a/src/mapserver/qgsprojectparser.cpp +++ b/src/mapserver/qgsprojectparser.cpp @@ -34,7 +34,7 @@ #include "qgscomposershape.h" -QgsProjectParser::QgsProjectParser( QDomDocument* xmlDoc ): QgsConfigParser(), mXMLDoc( xmlDoc ) +QgsProjectParser::QgsProjectParser( QDomDocument* xmlDoc, const QString& filePath ): QgsConfigParser(), mXMLDoc( xmlDoc ), mProjectPath( filePath ) { mOutputUnits = QgsMapRenderer::Millimeters; setLegendParametersFromProject(); @@ -673,7 +673,7 @@ QMap< QString, QDomElement > QgsProjectParser::projectLayerElementsByName() cons QgsMapLayer* QgsProjectParser::createLayerFromElement( const QDomElement& elem ) const { - if ( elem.isNull() ) + if ( elem.isNull() || !mXMLDoc ) { return 0; } @@ -684,14 +684,22 @@ QgsMapLayer* QgsProjectParser::createLayerFromElement( const QDomElement& elem ) return 0; } + //convert relative pathes to absolute ones if necessary QString uri = dataSourceElem.text(); + QString absoluteUri = convertToAbsolutePath( uri ); + if ( uri != absoluteUri ) + { + QDomText absoluteTextNode = mXMLDoc->createTextNode( absoluteUri ); + dataSourceElem.replaceChild( absoluteTextNode, dataSourceElem.firstChild() ); + } + QString id = layerId( elem ); if ( id.isNull() ) { return 0; } - QgsMapLayer* layer = QgsMSLayerCache::instance()->searchLayer( uri, id ); + QgsMapLayer* layer = QgsMSLayerCache::instance()->searchLayer( absoluteUri, id ); if ( layer ) { //reading symbology every time is necessary because it could have been changed by a user SLD based request @@ -714,7 +722,7 @@ QgsMapLayer* QgsProjectParser::createLayerFromElement( const QDomElement& elem ) { layer->readXML( const_cast( elem ) ); //should be changed to const in QgsMapLayer layer->setLayerName( layerName( elem ) ); - QgsMSLayerCache::instance()->insertLayer( uri, id, layer ); + QgsMSLayerCache::instance()->insertLayer( absoluteUri, id, layer ); } return layer; } @@ -930,6 +938,8 @@ QgsComposition* QgsProjectParser::initComposition( const QString& composerTempla { QgsComposerPicture* picture = new QgsComposerPicture( composition ); picture->readXML( currentElem, *mXMLDoc ); + //qgis mapserver needs an absolute file path + picture->setPictureFile( convertToAbsolutePath( picture->pictureFile() ) ); composition->addItem( picture ); } else if ( elemName == "ComposerScaleBar" ) @@ -1138,3 +1148,55 @@ void QgsProjectParser::serviceCapabilities( QDomElement& parentElement, QDomDocu parentElement.appendChild( contactInfoElem ); } +QString QgsProjectParser::convertToAbsolutePath( const QString& file ) const +{ + if ( !file.startsWith( "./" ) && !file.startsWith( "../" ) ) + { + return file; + } + + QString srcPath = file; + QString projPath = mProjectPath; + +#if defined(Q_OS_WIN) + srcPath.replace( "\\", "/" ); + projPath.replace( "\\", "/" ); + + bool uncPath = projPath.startsWith( "//" ); +#endif + + QStringList srcElems = file.split( "/", QString::SkipEmptyParts ); + QStringList projElems = mProjectPath.split( "/", QString::SkipEmptyParts ); + +#if defined(Q_OS_WIN) + if ( uncPath ) + { + projElems.insert( 0, "" ); + projElems.insert( 0, "" ); + } +#endif + + // remove project file element + projElems.removeLast(); + + // append source path elements + projElems << srcElems; + projElems.removeAll( "." ); + + // resolve .. + int pos; + while (( pos = projElems.indexOf( ".." ) ) > 0 ) + { + // remove preceding element and .. + projElems.removeAt( pos - 1 ); + projElems.removeAt( pos - 1 ); + } + +#if !defined(Q_OS_WIN) + // make path absolute + projElems.prepend( "" ); +#endif + + return projElems.join( "/" ); +} + diff --git a/src/mapserver/qgsprojectparser.h b/src/mapserver/qgsprojectparser.h index 872a672010b1..c27bd59042aa 100644 --- a/src/mapserver/qgsprojectparser.h +++ b/src/mapserver/qgsprojectparser.h @@ -32,7 +32,7 @@ class QgsProjectParser: public QgsConfigParser { public: /**Constructor. Takes ownership of xml document*/ - QgsProjectParser( QDomDocument* xmlDoc ); + QgsProjectParser( QDomDocument* xmlDoc, const QString& filePath ); virtual ~QgsProjectParser(); /**Adds layer and style specific capabilities elements to the parent node. This includes the individual layers and styles, their description, native CRS, bounding boxes, etc.*/ @@ -100,6 +100,9 @@ class QgsProjectParser: public QgsConfigParser /**Content of project file*/ QDomDocument* mXMLDoc; + /**Absolute project file path (including file name)*/ + QString mProjectPath; + /**Get all layers of the project (ordered same as in the project file)*/ QList projectLayerElements() const; /**Returns all legend group elements*/ @@ -134,6 +137,9 @@ class QgsProjectParser: public QgsConfigParser /**Returns dom element of composer (identified by composer title) or a null element in case of error*/ QDomElement composerByName( const QString& composerName ) const; + + /**Converts a (possibly relative) path to absolute*/ + QString convertToAbsolutePath( const QString& file ) const; }; #endif // QGSPROJECTPARSER_H