Skip to content

Commit

Permalink
globe: switch back to QgsMapRenderer
Browse files Browse the repository at this point in the history
  • Loading branch information
jef-n committed Mar 30, 2014
1 parent c4996bb commit 528d70f
Show file tree
Hide file tree
Showing 4 changed files with 222 additions and 73 deletions.
43 changes: 43 additions & 0 deletions src/plugins/globe/globe_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,37 @@ static const QgisPlugin::PLUGINTYPE sPluginType = QgisPlugin::UI;
static const QString sIcon = ":/globe/globe.png";
static const QString sExperimental = QString( "true" );

#if 0
#include <qgsmessagelog.h>

class QgsMsgTrap : public std::streambuf
{
public:
inline virtual int_type overflow( int_type c = std::streambuf::traits_type::eof() )
{
if ( c == std::streambuf::traits_type::eof() )
return std::streambuf::traits_type::not_eof( c );

switch ( c )
{
case '\r':
break;
case '\n':
QgsMessageLog::logMessage( buf, QObject::tr( "Globe" ) );
buf.clear();
break;
default:
buf += c;
break;
}
return c;
}

private:
QString buf;
} msgTrap;
#endif


//constructor
GlobePlugin::GlobePlugin( QgisInterface* theQgisInterface )
Expand Down Expand Up @@ -255,6 +286,11 @@ void GlobePlugin::initGui()
SLOT( blankProjectReady() ) );
connect( this, SIGNAL( xyCoordinates( const QgsPoint & ) ),
mQGisIface->mapCanvas(), SIGNAL( xyCoordinates( const QgsPoint & ) ) );

#if 0
mCoutRdBuf = std::cout.rdbuf( &msgTrap );
mCerrRdBuf = std::cerr.rdbuf( &msgTrap );
#endif
}

void GlobePlugin::run()
Expand Down Expand Up @@ -939,6 +975,13 @@ void GlobePlugin::unload()
mQGisIface->removeToolBarIcon( mQActionPointer );

delete mQActionPointer;

#if 0
if ( mCoutRdBuf )
std::cout.rdbuf( mCoutRdBuf );
if ( mCerrRdBuf )
std::cerr.rdbuf( mCerrRdBuf );
#endif
}

void GlobePlugin::help()
Expand Down
8 changes: 8 additions & 0 deletions src/plugins/globe/globe_plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ using namespace osgEarth::Util::Controls;
#endif
#include <osgEarth/Version>

#if 0
#include <iostream>
#endif

class QAction;
class QToolBar;
class QgisInterface;
Expand Down Expand Up @@ -178,6 +182,10 @@ class GlobePlugin : public QObject, public QgisPlugin
//! coordinates of the right-clicked point on the globe
double mSelectedLat, mSelectedLon, mSelectedElevation;

#if 0
std::streambuf *mCoutRdBuf, *mCerrRdBuf;
#endif

signals:
//! emits current mouse position
void xyCoordinates( const QgsPoint & p );
Expand Down
224 changes: 155 additions & 69 deletions src/plugins/globe/qgsosgearthtilesource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,29 +23,35 @@
#include <osgDB/Registry>
#include <osgDB/ReadFile>
#include <osgDB/WriteFile>
#include <sstream>

#include "qgsosgearthtilesource.h"

#include "qgsapplication.h"
#include <qgsapplication.h>
#include <qgslogger.h>
#include <qgisinterface.h>
#include <qgsmapcanvas.h>
#include "qgsproviderregistry.h"
#include "qgsmaplayerregistry.h"
#include "qgsmaptopixel.h"
#include "qgspallabeling.h"
#include "qgsproject.h"
#include "qgsmaprendererjob.h"

#ifdef USE_RENDERER
#include <qgsmaprenderer.h>
#else
#include <qgsmaprendererjob.h>
#endif

#include <QFile>
#include <QPainter>
#include <QImage>
#include <QDesktopWidget>

using namespace osgEarth;
using namespace osgEarth::Drivers;


QgsOsgEarthTileSource::QgsOsgEarthTileSource( QgisInterface* theQgisInterface, const TileSourceOptions& options ) : TileSource( options ), mQGisIface( theQgisInterface ), mCoordTranform( 0 )
QgsOsgEarthTileSource::QgsOsgEarthTileSource( QgisInterface* theQgisInterface, const TileSourceOptions& options )
: TileSource( options )
, mQGisIface( theQgisInterface )
, mCoordTransform( 0 )
#ifdef USE_RENDERER
, mMapRenderer( 0 )
#endif
{
}

Expand All @@ -56,84 +62,164 @@ void QgsOsgEarthTileSource::initialize( const std::string& referenceURI, const P

setProfile( osgEarth::Registry::instance()->getGlobalGeodeticProfile() );

long epsgGlobe = 4326;
if ( mQGisIface->mapCanvas()->mapSettings().destinationCrs().authid().compare( QString( "EPSG:%1" ).arg( epsgGlobe ), Qt::CaseInsensitive ) != 0 )
{
QgsCoordinateReferenceSystem srcCRS( mQGisIface->mapCanvas()->mapSettings().destinationCrs() ); //FIXME: crs from canvas or first layer?
QgsCoordinateReferenceSystem destCRS;
destCRS.createFromOgcWmsCrs( QString( "EPSG:%1" ).arg( epsgGlobe ) );
QgsCoordinateReferenceSystem destCRS;
destCRS.createFromOgcWmsCrs( GEO_EPSG_CRS_AUTHID );

mMapSettings.setDestinationCrs( destCRS );
mMapSettings.setCrsTransformEnabled( true );
mCoordTranform = new QgsCoordinateTransform( srcCRS, destCRS );
QgsMapCanvas *c = mQGisIface->mapCanvas();
if ( c->mapSettings().destinationCrs().authid().compare( GEO_EPSG_CRS_AUTHID, Qt::CaseInsensitive ) != 0 )
{
// FIXME: crs from canvas or first layer?
QgsCoordinateReferenceSystem srcCRS( c->mapSettings().destinationCrs() );
QgsDebugMsg( QString( "transforming from %1 to %2" ).arg( srcCRS.authid() ).arg( destCRS.authid() ) );
mCoordTransform = new QgsCoordinateTransform( srcCRS, destCRS );
}
else
{
mCoordTransform = 0;
}
// mMapSettings.setOutputUnits( mQGisIface->mapCanvas()->mapSettings().outputUnits() );
mMapSettings.setMapUnits( QGis::Degrees );

//mMapRenderer->setLabelingEngine( new QgsPalLabeling() );
#ifdef USE_RENDERER
mMapRenderer = new QgsMapRenderer();
mMapRenderer->setDestinationCrs( destCRS );
mMapRenderer->setProjectionsEnabled( true );
mMapRenderer->setOutputUnits( c->mapRenderer()->outputUnits() );
mMapRenderer->setMapUnits( QGis::Degrees );
#else
mMapSettings.setDestinationCrs( destCRS );
mMapSettings.setCrsTransformEnabled( true );
mMapSettings.setMapUnits( QGis::Degrees );
#endif
}

osg::Image* QgsOsgEarthTileSource::createImage( const TileKey& key, ProgressCallback* progress )
{
Q_UNUSED( key );
QString kname = key.str().c_str();
kname.replace( '/', '_' );

Q_UNUSED( progress );
osg::ref_ptr<osg::Image> image;
if ( intersects( &key ) )

//Get the extents of the tile
int tileSize = getPixelsPerTile();
if ( tileSize <= 0 )
{
QgsDebugMsg( "Tile size too small." );
return ImageUtils::createEmptyImage();
}

QgsRectangle viewExtent = mQGisIface->mapCanvas()->fullExtent();
if ( mCoordTransform )
{
//Get the extents of the tile
double xmin, ymin, xmax, ymax;
key.getExtent().getBounds( xmin, ymin, xmax, ymax );

int tileSize = getPixelsPerTile();
int target_width = tileSize;
int target_height = tileSize;

QgsDebugMsg( "QGIS: xmin:" + QString::number( xmin ) + " ymin:" + QString::number( ymin ) + " ymax:" + QString::number( ymax ) + " ymax " + QString::number( ymax ) );

//Return if parameters are out of range.
if ( target_width <= 0 || target_height <= 0 )
{
return 0;
}

mMapSettings.setOutputSize( QSize( tileSize, tileSize ) );
mMapSettings.setExtent( QgsRectangle( xmin, ymin, xmax, ymax ) );
mMapSettings.setLayers( mQGisIface->mapCanvas()->mapSettings().layers() );

QgsMapRendererSequentialJob job( mMapSettings );
job.start();
job.waitForFinished();

QImage qImage( job.renderedImage() );

unsigned char *data = qImage.bits();

image = new osg::Image;
//The pixel format is always RGBA to support transparency
image->setImage( qImage.width(), qImage.height(), 1,
4,
GL_BGRA, GL_UNSIGNED_BYTE, //Why not GL_RGBA - QGIS bug?
data,
osg::Image::NO_DELETE, 1 );
image->flipVertical();
QgsDebugMsg( QString( "vext0:%1" ).arg( viewExtent.toString( 5 ) ) );
viewExtent = mCoordTransform->transformBoundingBox( viewExtent );
}

QgsDebugMsg( QString( "vext1:%1" ).arg( viewExtent.toString( 5 ) ) );

double xmin, ymin, xmax, ymax;
key.getExtent().getBounds( xmin, ymin, xmax, ymax );
QgsRectangle tileExtent( xmin, ymin, xmax, ymax );

QgsDebugMsg( QString( "text0:%1" ).arg( tileExtent.toString( 5 ) ) );
if ( !viewExtent.intersects( tileExtent ) )
{
QgsDebugMsg( QString( "earth tile key:%1 ext:%2: NO INTERSECT" ).arg( kname ).arg( tileExtent.toString( 5 ) ) );
return ImageUtils::createEmptyImage();
}

#ifdef USE_RENDERER
QImage *qImage = createQImage( tileSize, tileSize );
if ( !qImage )
{
QgsDebugMsg( QString( "earth tile key:%1 ext:%2: EMPTY IMAGE" ).arg( kname ).arg( tileExtent.toString( 5 ) ) );
return ImageUtils::createEmptyImage();
}

mMapRenderer->setLayerSet( mQGisIface->mapCanvas()->mapRenderer()->layerSet() );
mMapRenderer->setOutputSize( QSize( tileSize, tileSize ), qImage->logicalDpiX() );
mMapRenderer->setExtent( tileExtent );

QPainter thePainter( qImage );
mMapRenderer->render( &thePainter );
#else
mMapSettings.setLayers( mQGisIface->mapCanvas()->mapSettings().layers() );
mMapSettings.setOutputSize( QSize( tileSize, tileSize ) );
mMapSettings.setOutputDpi( QgsApplication::desktop()->logicalDpiX() );
mMapSettings.setExtent( tileExtent );
mMapSettings.setBackgroundColor( QColor( 0, 0, 0, 0 ) );

QgsMapRendererSequentialJob job( mMapSettings );
job.start();
job.waitForFinished();

QImage *qImage = new QImage( job.renderedImage() );
if ( !qImage )
{
QgsDebugMsg( QString( "earth tile key:%1 ext:%2: EMPTY IMAGE" ).arg( kname ).arg( tileExtent.toString( 5 ) ) );
return ImageUtils::createEmptyImage();
}

Q_ASSERT( qImage->logicalDpiX() == QgsApplication::desktop()->logicalDpiX() );
Q_ASSERT( qImage->format() == QImage::Format_ARGB32_Premultiplied );
#endif

QgsDebugMsg( QString( "earth tile key:%1 ext:%2" ).arg( kname ).arg( tileExtent.toString( 5 ) ) );
#if 0
qImage->save( QString( "/tmp/tile-%1.png" ).arg( kname ) );
#endif

osg::ref_ptr<osg::Image> image = new osg::Image;

//The pixel format is always RGBA to support transparency
image->setImage( tileSize, tileSize, 1, 4, // width, height, depth, pixelFormat?
GL_BGRA, GL_UNSIGNED_BYTE, //Why not GL_RGBA - Qt bug?
qImage->bits(),
osg::Image::NO_DELETE, 1 );

image->flipVertical();

//Create a transparent image if we don't have an image
if ( !image.valid() )
{
QgsDebugMsg( "image is invalid" );
return ImageUtils::createEmptyImage();
}

QgsDebugMsg( "returning image" );
return image.release();
}

bool QgsOsgEarthTileSource::intersects( const TileKey* key )
QImage* QgsOsgEarthTileSource::createQImage( int width, int height ) const
{
//Get the native extents of the tile
double xmin, ymin, xmax, ymax;
key->getExtent().getBounds( xmin, ymin, xmax, ymax );
QgsRectangle extent = mQGisIface->mapCanvas()->fullExtent();
if ( mCoordTranform )
extent = mCoordTranform->transformBoundingBox( extent );
if ( width < 0 || height < 0 )
return 0;

QImage *qImage = 0;

//is format jpeg?
bool jpeg = false;
//transparent parameter
bool transparent = true;

//use alpha channel only if necessary because it slows down performance
if ( transparent && !jpeg )
{
qImage = new QImage( width, height, QImage::Format_ARGB32_Premultiplied );
qImage->fill( 0 );
}
else
{
qImage = new QImage( width, height, QImage::Format_RGB32 );
qImage->fill( qRgb( 255, 255, 255 ) );
}

if ( !qImage )
return 0;

return !( xmin >= extent.xMaximum() || xmax <= extent.xMinimum() || ymin >= extent.yMaximum() || ymax <= extent.yMinimum() );
//apply DPI parameter if present.
#if 0
int dpm = dpi / 0.0254;
qImage->setDotsPerMeterX( dpm );
qImage->setDotsPerMeterY( dpm );
#endif
return qImage;
}
20 changes: 16 additions & 4 deletions src/plugins/globe/qgsosgearthtilesource.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,22 @@
#ifndef OSGEARTH_DRIVER_QGIS_DRIVEROPTIONS
#define OSGEARTH_DRIVER_QGIS_DRIVEROPTIONS 1

#include "qgsmaprenderer.h"
#include <QtGlobal>

#include <QImage>
class QgisInterface;
class QgsMapRenderer;
class QgsCoordinateTransform;
class QImage;

#include <osgEarth/Common>
#include <osgEarth/TileSource>

#define USE_RENDERER

#ifndef USE_RENDERER
#include "qgsmapsettings.h"
#endif

using namespace osgEarth;

namespace osgEarth
Expand Down Expand Up @@ -60,12 +68,16 @@ namespace osgEarth
}

private:
bool intersects( const TileKey* key );
QImage* createQImage( int width, int height ) const;

//! Pointer to the QGIS interface object
QgisInterface *mQGisIface;
QgsCoordinateTransform *mCoordTranform;
QgsCoordinateTransform *mCoordTransform;
#ifndef USE_RENDERER
QgsMapSettings mMapSettings;
#else
QgsMapRenderer *mMapRenderer;
#endif
};
}
} // namespace osgEarth::Drivers
Expand Down

0 comments on commit 528d70f

Please sign in to comment.