osg::Image* QgsOsgEarthTileSource::createImage( const TileKey& key, ProgressCallback* progress )
{
  Q_UNUSED( key );
  Q_UNUSED( progress );
  osg::ref_ptr<osg::Image> image;
  if ( intersects( &key ) )
  {
    //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;
    }

    QImage* qImage = createImage( target_width, target_height );
    if ( !qImage )
    {
      return 0;
    }

    QgsMapRenderer* mainRenderer = mQGisIface->mapCanvas()->mapRenderer();
    mMapRenderer->setLayerSet( mainRenderer->layerSet() );

    mMapRenderer->setOutputSize( QSize( qImage->width(), qImage->height() ), qImage->logicalDpiX() );

    QgsRectangle mapExtent( xmin, ymin, xmax, ymax );
    mMapRenderer->setExtent( mapExtent );

    QPainter thePainter( qImage );
    //thePainter.setRenderHint(QPainter::Antialiasing); //make it look nicer
    mMapRenderer->render( &thePainter );

    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();
  }

  //Create a transparent image if we don't have an image
  if ( !image.valid() )
  {
    return ImageUtils::createEmptyImage();
  }
  return image.release();
}
osg::Image* QgsOsgEarthTileSource::createImage( const TileKey& key, ProgressCallback* progress )
{
  QString kname = key.str().c_str();
  kname.replace( '/', '_' );

  Q_UNUSED( progress );

  //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 )
  {
    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();
}