globe: switch back to QgsMapRenderer

This commit is contained in:
Juergen E. Fischer 2014-03-29 22:35:42 +01:00
parent c4996bb18c
commit 528d70fbc6
4 changed files with 222 additions and 73 deletions

View File

@ -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 )
@ -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()
@ -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()

View File

@ -47,6 +47,10 @@ using namespace osgEarth::Util::Controls;
#endif
#include <osgEarth/Version>
#if 0
#include <iostream>
#endif
class QAction;
class QToolBar;
class QgisInterface;
@ -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 );

View File

@ -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
{
}
@ -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 destCRS;
destCRS.createFromOgcWmsCrs( GEO_EPSG_CRS_AUTHID );
QgsMapCanvas *c = mQGisIface->mapCanvas();
if ( c->mapSettings().destinationCrs().authid().compare( GEO_EPSG_CRS_AUTHID, 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 ) );
mMapSettings.setDestinationCrs( destCRS );
mMapSettings.setCrsTransformEnabled( true );
mCoordTranform = new QgsCoordinateTransform( srcCRS, destCRS );
// 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 )
{
//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( "Tile size too small." );
return ImageUtils::createEmptyImage();
}
QgsRectangle viewExtent = mQGisIface->mapCanvas()->fullExtent();
if ( mCoordTransform )
{
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;
return !( xmin >= extent.xMaximum() || xmax <= extent.xMinimum() || ymin >= extent.yMaximum() || ymax <= extent.yMinimum() );
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;
//apply DPI parameter if present.
#if 0
int dpm = dpi / 0.0254;
qImage->setDotsPerMeterX( dpm );
qImage->setDotsPerMeterY( dpm );
#endif
return qImage;
}

View File

@ -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
@ -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