Пример #1
0
QgsMapCanvasRendererSync::QgsMapCanvasRendererSync( QgsMapCanvas* canvas, QgsMapRenderer* renderer )
    : QObject( canvas )
    , mCanvas( canvas )
    , mRenderer( renderer )
    , mSyncingExtent( false )
{
  connect( mCanvas, SIGNAL( extentsChanged() ), this, SLOT( onExtentC2R() ) );
  connect( mRenderer, SIGNAL( extentsChanged() ), this, SLOT( onExtentR2C() ) );

  connect( mCanvas, SIGNAL( mapUnitsChanged() ), this, SLOT( onMapUnitsC2R() ) );
  connect( mRenderer, SIGNAL( mapUnitsChanged() ), this, SLOT( onMapUnitsR2C() ) );

  connect( mCanvas, SIGNAL( rotationChanged( double ) ), this, SLOT( onMapRotationC2R() ) );
  connect( mRenderer, SIGNAL( rotationChanged( double ) ), this, SLOT( onMapRotationR2C() ) );

  connect( mCanvas, SIGNAL( hasCrsTransformEnabledChanged( bool ) ), this, SLOT( onCrsTransformC2R() ) );
  connect( mRenderer, SIGNAL( hasCrsTransformEnabled( bool ) ), this, SLOT( onCrsTransformR2C() ) );

  connect( mCanvas, SIGNAL( destinationCrsChanged() ), this, SLOT( onDestCrsC2R() ) );
  connect( mRenderer, SIGNAL( destinationSrsChanged() ), this, SLOT( onDestCrsR2C() ) );

  connect( mCanvas, SIGNAL( layersChanged() ), this, SLOT( onLayersC2R() ) );
  // TODO: layers R2C ? (should not happen!)

}
Пример #2
0
void QgsLegendModel::addLayer( QgsMapLayer* theMapLayer )
{
    if ( !theMapLayer )
    {
        return;
    }

    QgsComposerLayerItem* layerItem = new QgsComposerLayerItem( theMapLayer->name() );
    layerItem->setLayerID( theMapLayer->id() );
    layerItem->setDefaultStyle();
    layerItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable );

    QList<QStandardItem *> itemsList;
    itemsList << layerItem << new QgsComposerStyleItem( layerItem );
    invisibleRootItem()->appendRow( itemsList );

    switch ( theMapLayer->type() )
    {
    case QgsMapLayer::VectorLayer:
    {
        QgsVectorLayer* vl = dynamic_cast<QgsVectorLayer*>( theMapLayer );
        if ( vl )
        {
            addVectorLayerItemsV2( layerItem, vl );
        }
        break;
    }
    case QgsMapLayer::RasterLayer:
        addRasterLayerItems( layerItem, theMapLayer );
        break;
    default:
        break;
    }
    emit layersChanged();
}
Пример #3
0
QgsComposerLegend::QgsComposerLegend( QgsComposition* composition )
    : QgsComposerItem( composition )
    , mTitle( tr( "Legend" ) )
    , mFontColor( QColor( 0, 0, 0 ) )
    , mBoxSpace( 2 )
    , mColumnSpace( 2 )
    , mColumnCount( 1 )
    , mComposerMap( 0 )
    , mSplitLayer( false )
    , mEqualColumnWidth( false )
{
  setStyleMargin( QgsComposerLegendStyle::Title, QgsComposerLegendStyle::Bottom, 2 );
  setStyleMargin( QgsComposerLegendStyle::Group, QgsComposerLegendStyle::Top, 2 );
  setStyleMargin( QgsComposerLegendStyle::Subgroup, QgsComposerLegendStyle::Top, 2 );
  setStyleMargin( QgsComposerLegendStyle::Symbol, QgsComposerLegendStyle::Top, 2 );
  setStyleMargin( QgsComposerLegendStyle::SymbolLabel, QgsComposerLegendStyle::Top, 2 );
  setStyleMargin( QgsComposerLegendStyle::SymbolLabel, QgsComposerLegendStyle::Left, 2 );
  rstyle( QgsComposerLegendStyle::Title ).rfont().setPointSizeF( 16.0 );
  rstyle( QgsComposerLegendStyle::Group ).rfont().setPointSizeF( 14.0 );
  rstyle( QgsComposerLegendStyle::Subgroup ).rfont().setPointSizeF( 12.0 );
  rstyle( QgsComposerLegendStyle::SymbolLabel ).rfont().setPointSizeF( 12.0 );

  mSymbolWidth = 7;
  mSymbolHeight = 4;
  mWmsLegendWidth = 50;
  mWmsLegendHeight = 25;
  mWrapChar = "";
  mlineSpacing = 1.5;
  adjustBoxSize();

  connect( &mLegendModel, SIGNAL( layersChanged() ), this, SLOT( synchronizeWithModel() ) );
}
Пример #4
0
QgsComposerLegend::QgsComposerLegend( QgsComposition* composition )
    : QgsComposerItem( composition )
    , mTitle( tr( "Legend" ) )
    , mBoxSpace( 2 )
    , mColumnSpace( 2 )
    , mGroupSpace( 2 )
    , mLayerSpace( 2 )
    , mSymbolSpace( 2 )
    , mIconLabelSpace( 2 )
    , mColumnCount( 1 )
    , mComposerMap( 0 )
    , mSplitLayer( false )
    , mEqualColumnWidth( false )
{
  //QStringList idList = layerIdList();
  //mLegendModel.setLayerSet( idList );

  mTitleFont.setPointSizeF( 16.0 );
  mGroupFont.setPointSizeF( 14.0 );
  mLayerFont.setPointSizeF( 12.0 );
  mItemFont.setPointSizeF( 12.0 );

  mSymbolWidth = 7;
  mSymbolHeight = 4;
  mWrapChar = "";
  mlineSpacing = 1.5;
  adjustBoxSize();

  connect( &mLegendModel, SIGNAL( layersChanged() ), this, SLOT( synchronizeWithModel() ) );
}
Пример #5
0
QgsComposerLegend::QgsComposerLegend( QgsComposition* composition )
    : QgsComposerItem( composition )
    , mComposerMap( 0 )
{

  adjustBoxSize();

  connect( &mLegendModel, SIGNAL( layersChanged() ), this, SLOT( synchronizeWithModel() ) );
}
Пример #6
0
QgsComposerLegend::QgsComposerLegend( QgsComposition* composition )
    : QgsComposerItem( composition )
    , mCustomLayerTree( 0 )
    , mComposerMap( 0 )
{
  mLegendModel2 = new QgsLegendModelV2( QgsProject::instance()->layerTreeRoot() );

  adjustBoxSize();

  connect( &mLegendModel, SIGNAL( layersChanged() ), this, SLOT( synchronizeWithModel() ) );
}
QgsMapToolNodeTool::QgsMapToolNodeTool( QgsMapCanvas* canvas ): QgsMapToolVertexEdit( canvas )
{
  mSelectionFeature = NULL;
  mQRubberBand = NULL;
  mSelectAnother = false;
  mCtrl = false;
  mMoving = true;
  mClicked = false;
  mChangingGeometry = false;
  mIsPoint = false;
  //signal handling change of layer structure
  connect( canvas, SIGNAL( layersChanged() ), this, SLOT( layersChanged() ) );
  //signal when destination srs changed to repaint coordinates
  connect( canvas->mapRenderer(), SIGNAL( destinationSrsChanged() ), this, SLOT( coordinatesChanged() ) );
  //signal changing of coordinate renderer changed to repaint markers
  connect( canvas->mapRenderer(), SIGNAL( hasCrsTransformEnabled( bool ) ), this, SLOT( coordinatesChanged( ) ) );
  //signal changing of current layer
  connect( QgisApp::instance()->legend(), SIGNAL( currentLayerChanged( QgsMapLayer* ) ),
           this, SLOT( currentLayerChanged( QgsMapLayer* ) ) );
}
Пример #8
0
QgsFormAnnotationItem::QgsFormAnnotationItem( QgsMapCanvas* canvas, QgsVectorLayer* vlayer, bool hasFeature, int feature ): \
    QgsAnnotationItem( canvas ), mWidgetContainer( 0 ), mDesignerWidget( 0 ), mVectorLayer( vlayer ), \
    mHasAssociatedFeature( hasFeature ), mFeature( feature )
{
  mWidgetContainer = new QGraphicsProxyWidget( this );
  if ( mVectorLayer && mMapCanvas ) //default to the layers edit form
  {
    mDesignerForm = mVectorLayer->annotationForm();
    QObject::connect( mVectorLayer, SIGNAL( layerModified( bool ) ), this, SLOT( setFeatureForMapPosition() ) );
    QObject::connect( mMapCanvas, SIGNAL( renderComplete( QPainter* ) ), this, SLOT( setFeatureForMapPosition() ) );
    QObject::connect( mMapCanvas, SIGNAL( layersChanged() ), this, SLOT( updateVisibility() ) );
  }
QgsMapCanvasSnappingUtils::QgsMapCanvasSnappingUtils( QgsMapCanvas* canvas, QObject* parent )
    : QgsSnappingUtils( parent )
    , mCanvas( canvas )
    , mProgress( nullptr )
{
  connect( canvas, SIGNAL( extentsChanged() ), this, SLOT( canvasMapSettingsChanged() ) );
  connect( canvas, SIGNAL( destinationCrsChanged() ), this, SLOT( canvasMapSettingsChanged() ) );
  connect( canvas, SIGNAL( layersChanged() ), this, SLOT( canvasMapSettingsChanged() ) );
  connect( canvas, SIGNAL( currentLayerChanged( QgsMapLayer* ) ), this, SLOT( canvasCurrentLayerChanged() ) );
  canvasMapSettingsChanged();
  canvasCurrentLayerChanged();
}
Пример #10
0
void LayerStack::reset()
{
	const QSize oldsize(_width, _height);
	_width = 0;
	_height = 0;
	_xtiles = 0;
	_ytiles = 0;
	for(Layer *l : m_layers)
		delete l;
	m_layers.clear();
	m_annotations->clear();
	emit resized(0, 0, oldsize);
	emit layersChanged(QList<LayerInfo>());
}
Пример #11
0
QgsFormAnnotationItem::QgsFormAnnotationItem( QgsMapCanvas* canvas, QgsVectorLayer* vlayer, bool hasFeature, int feature )
    : QgsAnnotationItem( canvas )
    , mWidgetContainer( nullptr )
    , mDesignerWidget( nullptr )
    , mVectorLayer( vlayer )
    , mHasAssociatedFeature( hasFeature )
    , mFeature( feature )
{
  mWidgetContainer = new QGraphicsProxyWidget( this );
  mWidgetContainer->setData( 0, "AnnotationItem" ); //mark embedded widget as belonging to an annotation item (composer knows it needs to be printed)
  if ( mVectorLayer && mMapCanvas ) //default to the layers edit form
  {
    mDesignerForm = mVectorLayer->annotationForm();
    QObject::connect( mVectorLayer, SIGNAL( layerModified() ), this, SLOT( setFeatureForMapPosition() ) );
    QObject::connect( mMapCanvas, SIGNAL( renderComplete( QPainter* ) ), this, SLOT( setFeatureForMapPosition() ) );
    QObject::connect( mMapCanvas, SIGNAL( layersChanged() ), this, SLOT( updateVisibility() ) );
  }
Пример #12
0
QStandardItem* QgsLegendModel::addGroup( QString text, int position )
{
  if ( text.isNull() )
    text = tr( "Group" );

  QgsComposerGroupItem* groupItem = new QgsComposerGroupItem( text );
  if ( position == -1 )
  {
    invisibleRootItem()->insertRow( invisibleRootItem()->rowCount(), groupItem );
  }
  else
  {
    invisibleRootItem()->insertRow( position, groupItem );
  }
  emit layersChanged();
  return groupItem;
}
Пример #13
0
QStandardItem* QgsLegendModel::addGroup( QString text, int position )
{
    if ( text.isNull() )
        text = tr( "Group" );

    QgsComposerGroupItem* groupItem = new QgsComposerGroupItem( text );

    if ( position == -1 )
    {
        position = invisibleRootItem()->rowCount();
    }
    QList<QStandardItem *> itemsList;
    itemsList << groupItem << new QgsComposerStyleItem( groupItem );
    invisibleRootItem()->insertRow( position, itemsList );

    emit layersChanged();
    return groupItem;
}
Пример #14
0
void QgsLegendModel::removeLayer( const QString& layerId )
{
  int numRootItems = rowCount();
  for ( int i = 0; i < numRootItems ; ++i )
  {
    QgsComposerLayerItem* lItem = dynamic_cast<QgsComposerLayerItem*>( item( i ) );
    if ( !lItem )
    {
      continue;
    }

    if ( layerId == lItem->layerID() )
    {
      removeRow( i ); //todo: also remove the subitems and their symbols...
      emit layersChanged();
      return;
    }
  }
}
Пример #15
0
QgsMapCanvasTracer::QgsMapCanvasTracer( QgsMapCanvas* canvas, QgsMessageBar* messageBar )
    : mCanvas( canvas )
    , mMessageBar( messageBar )
    , mLastMessage( nullptr )
    , mActionEnableTracing( nullptr )
{
  sTracers.insert( canvas, this );

  // when things change we just invalidate the graph - and set up new parameters again only when necessary
  connect( canvas, SIGNAL( destinationCrsChanged() ), this, SLOT( invalidateGraph() ) );
  connect( canvas, SIGNAL( layersChanged() ), this, SLOT( invalidateGraph() ) );
  connect( canvas, SIGNAL( extentsChanged() ), this, SLOT( invalidateGraph() ) );
  connect( canvas, SIGNAL( currentLayerChanged( QgsMapLayer* ) ), this, SLOT( onCurrentLayerChanged() ) );
  connect( canvas->snappingUtils(), SIGNAL( configChanged() ), this, SLOT( invalidateGraph() ) );

  // arbitrarily chosen limit that should allow for fairly fast initialization
  // of the underlying graph structure
  setMaxFeatureCount( QSettings().value( "/qgis/digitizing/tracing_max_feature_count", 10000 ).toInt() );
}
Пример #16
0
void QgsLegendModel::addLayer( QgsMapLayer* theMapLayer )
{
  if ( !theMapLayer )
  {
    return;
  }

  QgsComposerLayerItem* layerItem = new QgsComposerLayerItem( theMapLayer->name() );
  layerItem->setLayerID( theMapLayer->id() );
  layerItem->setFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable );

  invisibleRootItem()->setChild( invisibleRootItem()->rowCount(), layerItem );

  switch ( theMapLayer->type() )
  {
    case QgsMapLayer::VectorLayer:
    {
      QgsVectorLayer* vl = dynamic_cast<QgsVectorLayer*>( theMapLayer );
      if ( vl )
      {
        if ( vl->isUsingRendererV2() )
        {
          addVectorLayerItemsV2( layerItem, vl );
        }
        else
        {
          addVectorLayerItems( layerItem, vl );
        }
      }
      break;
    }
    case QgsMapLayer::RasterLayer:
      addRasterLayerItems( layerItem, theMapLayer );
      break;
    default:
      break;
  }
  emit layersChanged();
}
Пример #17
0
QgsHtmlAnnotationItem::QgsHtmlAnnotationItem( QgsMapCanvas* canvas, QgsVectorLayer* vlayer, bool hasFeature, int feature )
    : QgsAnnotationItem( canvas )
    , mWidgetContainer( 0 )
    , mWebView( 0 )
    , mVectorLayer( vlayer )
    , mHasAssociatedFeature( hasFeature )
    , mFeatureId( feature )
{
  mWebView = new QgsWebView();
  mWebView->page()->setNetworkAccessManager( QgsNetworkAccessManager::instance() );

  mWidgetContainer = new QGraphicsProxyWidget( this );
  mWidgetContainer->setWidget( mWebView );

  QObject::connect( mWebView->page()->mainFrame(), SIGNAL( javaScriptWindowObjectCleared() ), this, SLOT( javascript() ) );

  if ( mVectorLayer && mMapCanvas )
  {
    QObject::connect( mVectorLayer, SIGNAL( layerModified() ), this, SLOT( setFeatureForMapPosition() ) );
    QObject::connect( mMapCanvas, SIGNAL( renderComplete( QPainter* ) ), this, SLOT( setFeatureForMapPosition() ) );
    QObject::connect( mMapCanvas, SIGNAL( layersChanged() ), this, SLOT( updateVisibility() ) );
  }
QgsComposerLegend::QgsComposerLegend( QgsComposition* composition )
    : QgsComposerItem( composition )
    , mTitle( tr( "Legend" ) )
    , mBoxSpace( 2 )
    , mLayerSpace( 2 )
    , mSymbolSpace( 2 )
    , mIconLabelSpace( 2 ), mComposerMap( 0 )
{
  //QStringList idList = layerIdList();
  //mLegendModel.setLayerSet( idList );

  mTitleFont.setPointSizeF( 16.0 );
  mGroupFont.setPointSizeF( 14.0 );
  mLayerFont.setPointSizeF( 12.0 );
  mItemFont.setPointSizeF( 12.0 );

  mSymbolWidth = 7;
  mSymbolHeight = 4;
  adjustBoxSize();

  connect( &mLegendModel, SIGNAL( layersChanged() ), this, SLOT( synchronizeWithModel() ) );
}
Пример #19
0
QgsComposerLegend::QgsComposerLegend( QgsComposition* composition )
    : QgsComposerItem( composition )
    , mCustomLayerTree( 0 )
    , mComposerMap( 0 )
    , mLegendFilterByMap( false )
    , mFilterOutAtlas( false )
    , mFilterAskedForUpdate( false )
    , mInAtlas( false )
{
  mLegendModel2 = new QgsLegendModelV2( QgsProject::instance()->layerTreeRoot() );

  adjustBoxSize();

  connect( &mLegendModel, SIGNAL( layersChanged() ), this, SLOT( synchronizeWithModel() ) );

  connect( &composition->atlasComposition(), SIGNAL( renderEnded() ), this, SLOT( onAtlasEnded() ) );
  connect( &composition->atlasComposition(), SIGNAL( featureChanged( QgsFeature* ) ), this, SLOT( onAtlasFeature( QgsFeature* ) ) );

  // Connect to the main layertreeroot.
  // It serves in "auto update mode" as a medium between the main app legend and this one
  connect( QgsProject::instance()->layerTreeRoot(), SIGNAL( customPropertyChanged( QgsLayerTreeNode*, QString ) ), this, SLOT( nodeCustomPropertyChanged( QgsLayerTreeNode*, QString ) ) );
}
Пример #20
0
void LayerWindow::currentModelChanged(Model * model)
{
    if (model == m_currentModel) {
        return;
    }

    if (m_currentModel != NULL) {
        m_updateSignal.disconnect();
    }

    m_currentModel = model;
    m_treeModel->clear();

    if (m_currentModel == NULL) {
        set_sensitive(false);
        return;
    }

    m_updateSignal = m_currentModel->layersChanged.connect(sigc::mem_fun(*this, &LayerWindow::layersChanged));
    layersChanged();

    set_sensitive(true);
}
Пример #21
0
void QgsMapCanvas::setLayerSet( QList<QgsMapCanvasLayer> &layers )
{
  // create layer set
  QStringList layerSet, layerSetOverview;

  int i;
  for ( i = 0; i < layers.size(); i++ )
  {
    QgsMapCanvasLayer &lyr = layers[i];
    if ( !lyr.layer() )
    {
      continue;
    }

    if ( lyr.isVisible() )
    {
      layerSet.push_back( lyr.layer()->id() );
    }

    if ( lyr.isInOverview() )
    {
      layerSetOverview.push_back( lyr.layer()->id() );
    }
  }

  const QStringList& layerSetOld = mapSettings().layers();

  bool layerSetChanged = layerSetOld != layerSet;

  // update only if needed
  if ( layerSetChanged )
  {
    QgsDebugMsg( "Layers changed to: " + layerSet.join( ", " ) );

    for ( i = 0; i < layerCount(); i++ )
    {
      // Add check if vector layer when disconnecting from selectionChanged slot
      // Ticket #811 - racicot
      QgsMapLayer *currentLayer = layer( i );
      if ( !currentLayer )
        continue;
      disconnect( currentLayer, SIGNAL( repaintRequested() ), this, SLOT( refresh() ) );
      disconnect( currentLayer, SIGNAL( layerCrsChanged() ), this, SLOT( layerCrsChange() ) );
      QgsVectorLayer *isVectLyr = qobject_cast<QgsVectorLayer *>( currentLayer );
      if ( isVectLyr )
      {
        disconnect( currentLayer, SIGNAL( selectionChanged() ), this, SLOT( selectionChangedSlot() ) );
      }
    }

    mSettings.setLayers( layerSet );

    for ( i = 0; i < layerCount(); i++ )
    {
      // Add check if vector layer when connecting to selectionChanged slot
      // Ticket #811 - racicot
      QgsMapLayer *currentLayer = layer( i );
      connect( currentLayer, SIGNAL( repaintRequested() ), this, SLOT( refresh() ) );
      connect( currentLayer, SIGNAL( layerCrsChanged() ), this, SLOT( layerCrsChange() ) );
      QgsVectorLayer *isVectLyr = qobject_cast<QgsVectorLayer *>( currentLayer );
      if ( isVectLyr )
      {
        connect( currentLayer, SIGNAL( selectionChanged() ), this, SLOT( selectionChangedSlot() ) );
      }
    }

    updateDatumTransformEntries();

    QgsDebugMsg( "Layers have changed, refreshing" );
    emit layersChanged();

    refresh();
  }

  if ( mMapOverview )
  {
    const QStringList& layerSetOvOld = mMapOverview->layerSet();
    if ( layerSetOvOld != layerSetOverview )
    {
      mMapOverview->setLayerSet( layerSetOverview );
    }

    // refresh overview maplayers even if layer set is the same
    // because full extent might have changed
    updateOverview();
  }
} // setLayerSet
Пример #22
0
bool QgsLegendModel::dropMimeData( const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent )
{
  Q_UNUSED( action );
  Q_UNUSED( column );

  if ( !data->hasFormat( "text/xml" ) )
  {
    return false;
  }

  QStandardItem* dropIntoItem = 0;
  if ( parent.isValid() )
  {
    dropIntoItem = itemFromIndex( parent );
  }
  else
  {
    dropIntoItem = invisibleRootItem();
  }

  //get XML doc
  QByteArray encodedData = data->data( "text/xml" );
  QDomDocument xmlDoc;
  xmlDoc.setContent( encodedData );

  QDomElement dragDataElem = xmlDoc.documentElement();
  if ( dragDataElem.tagName() != "LegendModelDragData" )
  {
    return false;
  }

  QDomNodeList nodeList = dragDataElem.childNodes();
  int nChildNodes = nodeList.size();
  QDomElement currentElem;
  QString currentTagName;
  QgsComposerLegendItem* currentItem = 0;

  for ( int i = 0; i < nChildNodes; ++i )
  {
    currentElem = nodeList.at( i ).toElement();
    if ( currentElem.isNull() )
    {
      continue;
    }
    currentTagName = currentElem.tagName();
    if ( currentTagName == "LayerItem" )
    {
      currentItem = new QgsComposerLayerItem();
    }
    else if ( currentTagName == "GroupItem" )
    {
      currentItem = new QgsComposerGroupItem();
    }
    else
    {
      continue;
    }
    currentItem->readXML( currentElem );
    if ( row < 0 )
    {
      dropIntoItem->insertRow( dropIntoItem->rowCount(), currentItem );
    }
    else
    {
      dropIntoItem->insertRow( row + i, currentItem );
    }
  }
  emit layersChanged();
  return true;
}
Пример #23
0
void GlobePlugin::run()
{
  if ( mViewerWidget != 0 )
  {
    return;
  }
#ifdef GLOBE_SHOW_TILE_STATS
  QgsGlobeTileStatistics* tileStats = new QgsGlobeTileStatistics();
  connect( tileStats, SIGNAL( changed( int, int ) ), this, SLOT( updateTileStats( int, int ) ) );
#endif
  QSettings settings;

//    osgEarth::setNotifyLevel( osg::DEBUG_INFO );

  mOsgViewer = new osgViewer::Viewer();
  mOsgViewer->setThreadingModel( osgViewer::Viewer::SingleThreaded );
  mOsgViewer->setRunFrameScheme( osgViewer::Viewer::ON_DEMAND );
  // Set camera manipulator with default home position
  osgEarth::Util::EarthManipulator* manip = new osgEarth::Util::EarthManipulator();
  mOsgViewer->setCameraManipulator( manip );
  osgEarth::Util::Viewpoint viewpoint;
  viewpoint.focalPoint() = osgEarth::GeoPoint( osgEarth::SpatialReference::get( "wgs84" ), -90., 0., 0. );
  viewpoint.heading() = 0.;
  viewpoint.pitch() = -90.;
  viewpoint.range() = 2e7;

  manip->setHomeViewpoint( viewpoint, 1. );
  manip->home( 0 );

  setupProxy();

  // Tile stats label
#ifdef GLOBE_SHOW_TILE_STATS
  mStatsLabel = new osgEarth::Util::Controls::LabelControl( "", 10 );
  mStatsLabel->setPosition( 0, 0 );
  osgEarth::Util::Controls::ControlCanvas::get( mOsgViewer )->addControl( mStatsLabel.get() );
#endif

  mDockWidget = new QgsGlobeWidget( mQGisIface, mQGisIface->mainWindow() );
  connect( mDockWidget, SIGNAL( destroyed( QObject* ) ), this, SLOT( reset() ) );
  connect( mDockWidget, SIGNAL( layersChanged() ), this, SLOT( updateLayers() ) );
  connect( mDockWidget, SIGNAL( showSettings() ), this, SLOT( showSettings() ) );
  connect( mDockWidget, SIGNAL( refresh() ), this, SLOT( updateLayers() ) );
  connect( mDockWidget, SIGNAL( syncExtent() ), this, SLOT( syncExtent() ) );
  mQGisIface->addDockWidget( Qt::RightDockWidgetArea, mDockWidget );

  if ( getenv( "GLOBE_MAPXML" ) )
  {
    char* mapxml = getenv( "GLOBE_MAPXML" );
    QgsDebugMsg( mapxml );
    osg::Node* node = osgDB::readNodeFile( mapxml );
    if ( !node )
    {
      QgsDebugMsg( "Failed to load earth file " );
      return;
    }
    mMapNode = osgEarth::MapNode::findMapNode( node );
    mRootNode = new osg::Group();
    mRootNode->addChild( node );
  }
  else
  {
    QString cacheDirectory = settings.value( "cache/directory", QgsApplication::qgisSettingsDirPath() + "cache" ).toString();
    osgEarth::Drivers::FileSystemCacheOptions cacheOptions;
    cacheOptions.rootPath() = cacheDirectory.toStdString();

    osgEarth::MapOptions mapOptions;
    mapOptions.cache() = cacheOptions;
    osgEarth::Map *map = new osgEarth::Map( /*mapOptions*/ );

    // The MapNode will render the Map object in the scene graph.
    osgEarth::MapNodeOptions mapNodeOptions;
    mMapNode = new osgEarth::MapNode( map, mapNodeOptions );

    mRootNode = new osg::Group();
    mRootNode->addChild( mMapNode );

    osgEarth::Registry::instance()->unRefImageDataAfterApply() = false;

    // Add draped layer
    osgEarth::TileSourceOptions opts;
    opts.L2CacheSize() = 0;
    opts.tileSize() = 128;
    mTileSource = new QgsGlobeTileSource( mQGisIface->mapCanvas(), opts );

    osgEarth::ImageLayerOptions options( "QGIS" );
    options.driver()->L2CacheSize() = 0;
    options.cachePolicy() = osgEarth::CachePolicy::USAGE_NO_CACHE;
    mQgisMapLayer = new osgEarth::ImageLayer( options, mTileSource );
    map->addImageLayer( mQgisMapLayer );

    // Add layers to the map
    updateLayers();

    // Create the frustum highlight callback
    mFrustumHighlightCallback = new QgsGlobeFrustumHighlightCallback(
      mOsgViewer, mMapNode->getTerrain(), mQGisIface->mapCanvas(), QColor( 0, 0, 0, 50 ) );
  }

  mRootNode->addChild( osgEarth::Util::Controls::ControlCanvas::get( mOsgViewer ) );

  mAnnotationsGroup = new osg::Group();
  mRootNode->addChild( mAnnotationsGroup );
  foreach ( QgsBillBoardItem* item, QgsProject::instance()->billboardRegistry()->items() )
  {
    addBillboard( item );
  }