Skip to content

Commit

Permalink
Use CRS cache for faster lookup of crs by authid. Important especiall…
Browse files Browse the repository at this point in the history
…y for wms server. Replaces wmsserver/epsgcache.cpp and .h
  • Loading branch information
mhugent committed Sep 6, 2011
1 parent 05cdd52 commit 15b4843
Show file tree
Hide file tree
Showing 7 changed files with 56 additions and 72 deletions.
1 change: 1 addition & 0 deletions src/core/CMakeLists.txt
Expand Up @@ -48,6 +48,7 @@ SET(QGIS_CORE_SRCS
qgsclipper.cpp
qgscontexthelp.cpp
qgscoordinatetransform.cpp
qgscrscache.cpp
qgsdatasourceuri.cpp
qgsdataitem.cpp
qgsdiagram.cpp
Expand Down
15 changes: 13 additions & 2 deletions src/core/qgscoordinatereferencesystem.cpp
Expand Up @@ -27,6 +27,7 @@
#include <QTextStream>

#include "qgsapplication.h"
#include "qgscrscache.h"
#include "qgslogger.h"
#include "qgsmessageoutput.h"
#include "qgis.h" //const vals declared here
Expand Down Expand Up @@ -1001,14 +1002,24 @@ bool QgsCoordinateReferenceSystem::readXML( QDomNode & theNode )
QDomNode myNode = srsNode.namedItem( "authid" );
if ( !myNode.isNull() )
{
initialized = createFromOgcWmsCrs( myNode.toElement().text() );
operator=( QgsCRSCache::instance()->crsByAuthId( myNode.toElement().text() ) );
if ( isValid() )
{
initialized = true;
}
}

if ( !initialized )
{
myNode = srsNode.namedItem( "epsg" );
if ( !myNode.isNull() )
initialized = createFromOgcWmsCrs( QString( "EPSG:%1" ).arg( myNode.toElement().text().toLong() ) );
{
operator=( QgsCRSCache::instance()->crsByEpsgId( myNode.toElement().text().toLong() ) );
if ( isValid() )
{
initialized = true;
}
}
}

if ( initialized )
Expand Down
33 changes: 18 additions & 15 deletions src/mapserver/qgsepsgcache.cpp → src/core/qgscrscache.cpp
@@ -1,8 +1,8 @@
/***************************************************************************
qgsepsgcache.cpp
----------------
begin : June 9th, 2010
copyright : (C) 2010 by Marco Hugentobler
qgscrscache.cpp
---------------
begin : September 6th, 2011
copyright : (C) 2011 by Marco Hugentobler
email : marco dot hugentobler at sourcepole dot ch
***************************************************************************/

Expand All @@ -15,44 +15,47 @@
* *
***************************************************************************/

#include "qgsepsgcache.h"
#include "qgscrscache.h"

QgsEPSGCache* QgsEPSGCache::mInstance = 0;
QgsCRSCache* QgsCRSCache::mInstance = 0;

QgsEPSGCache* QgsEPSGCache::instance()
QgsCRSCache* QgsCRSCache::instance()
{
if ( !mInstance )
{
mInstance = new QgsEPSGCache();
mInstance = new QgsCRSCache();
}
return mInstance;
}

QgsEPSGCache::QgsEPSGCache()
QgsCRSCache::QgsCRSCache()
{
}

QgsEPSGCache::~QgsEPSGCache()
QgsCRSCache::~QgsCRSCache()
{
delete mInstance;
}

const QgsCoordinateReferenceSystem& QgsEPSGCache::searchCRS( long epsg )
const QgsCoordinateReferenceSystem& QgsCRSCache::crsByAuthId( const QString& authid )
{
QHash< long, QgsCoordinateReferenceSystem >::const_iterator crsIt = mCRS.find( epsg );
QHash< QString, QgsCoordinateReferenceSystem >::const_iterator crsIt = mCRS.find( authid );
if ( crsIt == mCRS.constEnd() )
{
QgsCoordinateReferenceSystem s;
if ( ! s.createFromOgcWmsCrs( QString( "EPSG:%1" ).arg( epsg ) ) )
if ( ! s.createFromOgcWmsCrs( authid ) )
{
return mInvalidCRS;
}
return mCRS.insert( epsg, s ).value();
return mCRS.insert( authid, s ).value();
}
else
{
return crsIt.value();
}
}


const QgsCoordinateReferenceSystem& QgsCRSCache::crsByEpsgId( long epsg )
{
return crsByAuthId( "EPSG:" + QString::number( epsg ) );
}
32 changes: 16 additions & 16 deletions src/mapserver/qgsepsgcache.h → src/core/qgscrscache.h
@@ -1,8 +1,8 @@
/***************************************************************************
qgsepsgcache.h
qgscrscache.h
--------------
begin : June 9th, 2010
copyright : (C) 2010 by Marco Hugentobler
begin : September 6th, 2011
copyright : (C) 2011 by Marco Hugentobler
email : marco dot hugentobler at sourcepole dot ch
***************************************************************************/

Expand All @@ -15,29 +15,29 @@
* *
***************************************************************************/

#ifndef QGSEPSGCACHE_H
#define QGSEPSGCACHE_H
#ifndef QGSCRSCACHE_H
#define QGSCRSCACHE_H

#include "qgscoordinatereferencesystem.h"
#include <QHash>

/**A class that cashes QgsCoordinateReferenceSystem instances and allows fast searching by epsg numbers*/
class QgsEPSGCache
class QgsCRSCache
{
public:
static QgsEPSGCache* instance();
~QgsEPSGCache();
/**Returns the CRS for an epsg number (or an invalid CRS in case of error)*/
const QgsCoordinateReferenceSystem& searchCRS( long epsg );
static QgsCRSCache* instance();
~QgsCRSCache();
/**Returns the CRS for authid, e.g. 'EPSG:4326' (or an invalid CRS in case of error)*/
const QgsCoordinateReferenceSystem& crsByAuthId( const QString& authid );
const QgsCoordinateReferenceSystem& crsByEpsgId( long epgs );

protected:
QgsEPSGCache();
QgsCRSCache();

private:
static QgsEPSGCache* mInstance;
QHash< long, QgsCoordinateReferenceSystem > mCRS;
/**CRS that is not initialised (is returned in case of error)*/
static QgsCRSCache* mInstance;
QHash< QString, QgsCoordinateReferenceSystem > mCRS;
/**CRS that is not initialised (returned in case of error)*/
QgsCoordinateReferenceSystem mInvalidCRS;
};

#endif // QGSEPSGCACHE_H
#endif // QGSCRSCACHE_H
1 change: 0 additions & 1 deletion src/mapserver/CMakeLists.txt
Expand Up @@ -20,7 +20,6 @@ SET ( qgis_mapserv_SRCS
qgscapabilitiescache.cpp
qgsconfigcache.cpp
qgsconfigparser.cpp
qgsepsgcache.cpp
qgsprojectparser.cpp
qgshttprequesthandler.cpp
qgsgetrequesthandler.cpp
Expand Down
31 changes: 6 additions & 25 deletions src/mapserver/qgsprojectparser.cpp
Expand Up @@ -17,7 +17,7 @@

#include "qgsprojectparser.h"
#include "qgsconfigcache.h"
#include "qgsepsgcache.h"
#include "qgscrscache.h"
#include "qgsmslayercache.h"
#include "qgslogger.h"
#include "qgsmapserviceexception.h"
Expand Down Expand Up @@ -1450,20 +1450,10 @@ const QgsCoordinateReferenceSystem& QgsProjectParser::projectCRS() const
firstChildElement( "spatialrefsys" ).firstChildElement( "authid" );
if ( !authIdElem.isNull() )
{
QString authId = authIdElem.text();
QStringList authIdSplit = authId.split( ":" );
if ( authIdSplit.size() == 2 && authIdSplit.at( 0 ).compare( "EPSG", Qt::CaseInsensitive ) == 0 )
{
bool ok;
int id = authIdSplit.at( 1 ).toInt( &ok );
if ( ok )
{
return QgsEPSGCache::instance()->searchCRS( id );
}
}
return QgsCRSCache::instance()->crsByAuthId( authIdElem.text() );
}
}
return QgsEPSGCache::instance()->searchCRS( GEO_EPSG_CRS_ID );
return QgsCRSCache::instance()->crsByEpsgId( GEO_EPSG_CRS_ID );
}

QgsRectangle QgsProjectParser::layerBoundingBoxInProjectCRS( const QDomElement& layerElem ) const
Expand Down Expand Up @@ -1504,22 +1494,13 @@ QgsRectangle QgsProjectParser::layerBoundingBoxInProjectCRS( const QDomElement&
return BBox;
}

int authId;
QString authIdString = boundingBoxElem.attribute( "CRS" );
QStringList authIdSplit = authIdString.split( ":" );
if ( authIdSplit.size() < 2 )
{
return BBox;
}
authId = authIdSplit.at( 1 ).toInt( &conversionOk );
if ( !conversionOk )
//create layer crs
const QgsCoordinateReferenceSystem& layerCrs = QgsCRSCache::instance()->crsByAuthId( boundingBoxElem.attribute( "CRS" ) );
if ( !layerCrs.isValid() )
{
return BBox;
}

//create layer crs
const QgsCoordinateReferenceSystem& layerCrs = QgsEPSGCache::instance()->searchCRS( authId );

//get project crs
const QgsCoordinateReferenceSystem& projectCrs = projectCRS();
QgsCoordinateTransform t( layerCrs, projectCrs );
Expand Down
15 changes: 2 additions & 13 deletions src/mapserver/qgswmsserver.cpp
Expand Up @@ -16,7 +16,7 @@
***************************************************************************/
#include "qgswmsserver.h"
#include "qgsconfigparser.h"
#include "qgsepsgcache.h"
#include "qgscrscache.h"
#include "qgsfield.h"
#include "qgsgeometry.h"
#include "qgsmaplayer.h"
Expand Down Expand Up @@ -1043,19 +1043,8 @@ int QgsWMSServer::configureMapRender( const QPaintDevice* paintDevice ) const
QgsDebugMsg( "enable on the fly projection" );
QgsProject::instance()->writeEntry( "SpatialRefSys", "/ProjectionsEnabled", 1 );

QString crsString = crsIt->second;
if ( !( crsString.left( 4 ) == "EPSG" ) )
{
return 3; // only EPSG ids supported
}
long epsgId = crsString.section( ":", 1, 1 ).toLong( &conversionSuccess );
if ( !conversionSuccess )
{
return 4;
}

//destination SRS
outputCRS = QgsEPSGCache::instance()->searchCRS( epsgId );
outputCRS = QgsCRSCache::instance()->crsByAuthId( crsIt->second );
if ( !outputCRS.isValid() )
{
QgsDebugMsg( "Error, could not create output CRS from EPSG" );
Expand Down

0 comments on commit 15b4843

Please sign in to comment.