[Marble-commits] KDE/kdeedu/marble/src/lib
Bernhard Beschow
bbeschow at cs.tu-berlin.de
Thu Jul 15 16:21:43 CEST 2010
SVN commit 1150267 by beschow:
support Equirectangular *and* Mercator projection for WMS
Since WMS query items are overridable in Marble, this allows to cheat with projections at
high zoom levels: Although most maps seem to be provided in Equirectangular projection,
one can tell Marble to interpret a map as Mercator-projected by specifying "Mercator" in
the DGML file and adding a WMS query item "srs=EPSG:4326" (Equirectangular projection) in
the download URL.
This allows for blending WMS maps onto OpenStreetMap and using WMS maps on devices that
only support Mercator projection.
M +71 -17 ServerLayout.cpp
M +13 -7 ServerLayout.h
M +1 -1 geodata/handlers/dgml/DgmlStorageLayoutTagHandler.cpp
--- trunk/KDE/kdeedu/marble/src/lib/ServerLayout.cpp #1150266:1150267
@@ -20,13 +20,27 @@
namespace Marble
{
+ServerLayout::ServerLayout( GeoSceneTexture *textureLayer )
+ : m_textureLayer( textureLayer )
+{
+}
+
ServerLayout::~ServerLayout()
{
}
+qint64 ServerLayout::numTilesX( const Marble::TileId& tileId ) const
+{
+ return ( 1 << tileId.zoomLevel() ) * m_textureLayer->levelZeroColumns();
+}
+qint64 ServerLayout::numTilesY( const Marble::TileId& tileId ) const
+{
+ return ( 1 << tileId.zoomLevel() ) * m_textureLayer->levelZeroRows();
+}
+
MarbleServerLayout::MarbleServerLayout( GeoSceneTexture *textureLayer )
- : m_textureLayer( textureLayer )
+ : ServerLayout( textureLayer )
{
}
@@ -40,7 +54,7 @@
OsmServerLayout::OsmServerLayout( GeoSceneTexture *textureLayer )
- : m_textureLayer( textureLayer )
+ : ServerLayout( textureLayer )
{
}
@@ -59,6 +73,11 @@
}
+CustomServerLayout::CustomServerLayout( GeoSceneTexture *texture )
+ : ServerLayout( texture )
+{
+}
+
QUrl CustomServerLayout::downloadUrl( const QUrl &prototypeUrl, const TileId &id ) const
{
QString urlStr = prototypeUrl.toString();
@@ -71,18 +90,15 @@
}
WmsServerLayout::WmsServerLayout( GeoSceneTexture *texture )
- : m_textureLayer( texture )
+ : ServerLayout( texture )
{
}
QUrl WmsServerLayout::downloadUrl( const QUrl &prototypeUrl, const Marble::TileId &tileId ) const
{
- const qint64 radius = ( 1 << ( tileId.zoomLevel() - 1 ) );
+ const qint64 radius = numTilesX( tileId ) / 2;
const qint64 x = tileId.x();
- const qint64 y = tileId.y();
- const qreal latBottom = ( radius - y - 1 ) / (double)radius * 90.0;
- const qreal latTop = ( radius - y ) / (double)radius * 90.0;
const qreal lonLeft = ( x - radius ) / (double)radius * 180.0;
const qreal lonRight = ( x - radius + 1 ) / (double)radius * 180.0;
@@ -99,25 +115,63 @@
url.addQueryItem( "format", "image/" + m_textureLayer->fileFormat().toLower() );
}
if ( !url.hasQueryItem( "srs" ) ) {
- switch ( m_textureLayer->projection() ) {
- case GeoSceneTexture::Equirectangular:
- url.addQueryItem( "srs", "EPSG:4326" );
- break;
- case GeoSceneTexture::Mercator:
- url.addQueryItem( "srs", "EPSG:3785" );
- break;
+ url.addQueryItem( "srs", epsgCode() );
}
- }
if ( !url.hasQueryItem( "layers" ) )
url.addQueryItem( "layers", m_textureLayer->name() );
url.addQueryItem( "width", QString::number( m_textureLayer->tileSize().width() ) );
url.addQueryItem( "height", QString::number( m_textureLayer->tileSize().height() ) );
url.addQueryItem( "bbox", QString( "%1,%2,%3,%4" ).arg( QString::number( lonLeft, 'f', 12 ) )
- .arg( QString::number( latBottom, 'f', 12 ) )
+ .arg( QString::number( latBottom( tileId ), 'f', 12 ) )
.arg( QString::number( lonRight, 'f', 12 ) )
- .arg( QString::number( latTop, 'f', 12 ) ) );
+ .arg( QString::number( latTop( tileId ), 'f', 12 ) ) );
return url;
}
+qreal WmsServerLayout::latBottom( const Marble::TileId &tileId ) const
+{
+ const qint64 radius = numTilesY( tileId ) / 2;
+
+ switch( m_textureLayer->projection() )
+ {
+ case GeoSceneTexture::Equirectangular:
+ return ( radius - tileId.y() - 1 ) / (double)radius * 90.0;
+ case GeoSceneTexture::Mercator:
+ return atan( sinh( ( radius - tileId.y() - 1 ) / (double)radius * M_PI ) ) * 180.0 / M_PI;
}
+
+ Q_ASSERT( false ); // not reached
+ return 0.0;
+}
+
+qreal WmsServerLayout::latTop( const Marble::TileId &tileId ) const
+{
+ const qint64 radius = numTilesY( tileId ) / 2;
+
+ switch( m_textureLayer->projection() )
+ {
+ case GeoSceneTexture::Equirectangular:
+ return ( radius - tileId.y() ) / (double)radius * 90.0;
+ case GeoSceneTexture::Mercator:
+ return atan( sinh( ( radius - tileId.y() ) / (double)radius * M_PI ) ) * 180.0 / M_PI;
+ }
+
+ Q_ASSERT( false ); // not reached
+ return 0.0;
+}
+
+QString WmsServerLayout::epsgCode() const
+{
+ switch ( m_textureLayer->projection() ) {
+ case GeoSceneTexture::Equirectangular:
+ return "EPSG:4326";
+ case GeoSceneTexture::Mercator:
+ return "EPSG:3785";
+ }
+
+ Q_ASSERT( false ); // not reached
+ return QString();
+}
+
+}
--- trunk/KDE/kdeedu/marble/src/lib/ServerLayout.h #1150266:1150267
@@ -21,6 +21,7 @@
class ServerLayout
{
public:
+ ServerLayout( GeoSceneTexture *textureLayer );
virtual ~ServerLayout();
/**
@@ -32,6 +33,13 @@
* @return completed URL for requested tile id
*/
virtual QUrl downloadUrl( const QUrl &prototypeUrl, const TileId &id ) const = 0;
+
+protected:
+ qint64 numTilesX( const Marble::TileId &tileId ) const;
+ qint64 numTilesY( const Marble::TileId &tileId ) const;
+
+protected:
+ GeoSceneTexture *const m_textureLayer;
};
class MarbleServerLayout : public ServerLayout
@@ -43,9 +51,6 @@
* Completes the path of the @p prototypeUrl and returns it.
*/
virtual QUrl downloadUrl( const QUrl &prototypeUrl, const TileId & ) const;
-
-private:
- GeoSceneTexture *const m_textureLayer;
};
class OsmServerLayout : public ServerLayout
@@ -58,14 +63,13 @@
* the result.
*/
virtual QUrl downloadUrl( const QUrl &prototypeUrl, const TileId & ) const;
-
-private:
- GeoSceneTexture *const m_textureLayer;
};
class CustomServerLayout : public ServerLayout
{
public:
+ CustomServerLayout( GeoSceneTexture *texture );
+
/**
* Replaces escape sequences in the @p prototypeUrl by the values in @p id
* and returns the result.
@@ -91,7 +95,9 @@
virtual QUrl downloadUrl( const QUrl &prototypeUrl, const Marble::TileId &tileId ) const;
private:
- GeoSceneTexture *const m_textureLayer;
+ qreal latBottom( const Marble::TileId &tileId ) const;
+ qreal latTop( const Marble::TileId &tileId ) const;
+ QString epsgCode() const;
};
}
--- trunk/KDE/kdeedu/marble/src/lib/geodata/handlers/dgml/DgmlStorageLayoutTagHandler.cpp #1150266:1150267
@@ -73,7 +73,7 @@
if ( modeStr == "OpenStreetMap" )
serverLayout = new OsmServerLayout( texture );
else if ( modeStr == "Custom" )
- serverLayout = new CustomServerLayout();
+ serverLayout = new CustomServerLayout( texture );
else if ( modeStr == "WebMapService" )
serverLayout = new WmsServerLayout( texture );
else {
More information about the Marble-commits
mailing list