Make map canvas independent from overview canvas, simplify QgsMapCanvas API

This commit is contained in:
Martin Dobias 2016-12-11 15:42:23 +08:00
parent 20cdd4f0e6
commit 2c9f1ff579
14 changed files with 89 additions and 217 deletions

View File

@ -249,6 +249,7 @@ should now call QgsCoordinateReferenceSystem::invalidateCache() and QgsCoordinat
- addLegendLayerActionForLayer() moved to QgisInterface::addCustomActionForLayer()
- removeLegendLayerAction() moved to QgisInterface::removeCustomActionForLayerType()
- QgsLegendModel was removed.
- QgsMapCanvasLayer. Map canvas and overview canvas are updated separately with their own setLayers() calls.
- QgsMapCanvasMap. It is an internal class used by map canvas.
- QgsMapLayerRegistry. Its functionality has been moved to QgsProject.
- QgsMapRenderer. It has been replaced by QgsMapRendererJob with subclasses and QgsMapSettings.
@ -1069,6 +1070,7 @@ and the new ramp can be retrieved after executing the dialog by calling ramp().
QgsMapCanvas {#qgis_api_break_3_0_QgsMapCanvas}
------------
- setLayerSet() has been replaced by setLayers() which accepts list of QgsMapLayer objects instead of QgsMapCanvasLayer objects
- rotationEnabled() and enableRotation() have been removed, since map rotation is now always supported
- The "name" parameter has been removed from constructor. Use QObject::setObjectName() to set canvas name if necessary.
- map() has been removed because QgsMapCanvasMap is not available in API anymore.
@ -1081,6 +1083,7 @@ QgsMapCanvas {#qgis_api_break_3_0_QgsMapCanvas}
- setWheelAction() and WheelAction enum have been removed. Custom wheel actions are not supported anymore.
- updateMap(), showError(), useImageToRender() have been removed. They did nothing since 2.4.
- setProgress() signal has been removed. It was not emitted since 2.0.
- enableOverviewMode() and updateOverview() have been removed. Map canvas does not keep pointer to overview canvas anymore. Use QgsLayerTreeMapCanvasBridge::setOverviewCanvas() to set up updates of overview canvas together with main canvas.
QgsMapCanvasItem {#qgis_api_break_3_0_QgsMapCanvasItem}

View File

@ -28,6 +28,13 @@ class QgsLayerTreeMapCanvasBridge : QObject
QgsLayerTreeGroup* rootGroup() const;
QgsMapCanvas* mapCanvas() const;
//! Associates overview canvas with the bridge, so the overview will be updated whenever main canvas is updated
//! @note added in 3.0
void setOvervewCanvas( QgsMapOverviewCanvas* overviewCanvas );
//! Returns associated overview canvas (may be null)
//! @note added in 3.0
QgsMapOverviewCanvas* overviewCanvas() const;
bool hasCustomLayerOrder() const;
QStringList customLayerOrder() const;
@ -61,7 +68,7 @@ class QgsLayerTreeMapCanvasBridge : QObject
void defaultLayerOrder( QgsLayerTreeNode* node, QStringList& order ) const;
void setCanvasLayers( QgsLayerTreeNode* node, QList<QgsMapCanvasLayer>& layers );
void setCanvasLayers( QgsLayerTreeNode* node, QList<QgsMapLayer*> &canvasLayers, QList<QgsMapLayer*>& overviewLayers );
void deferredSetCanvasLayers();

View File

@ -1,28 +1,5 @@
%Feature HAVE_TOUCH
/** \ingroup gui
* A class that stores visibility and presence in overview flags together
* with pointer to the layer.
*
*/
class QgsMapCanvasLayer
{
%TypeHeaderCode
#include <qgsmapcanvas.h>
%End
public:
QgsMapCanvasLayer( QgsMapLayer* layer, bool visible = true, bool isInOverview = false );
void setVisible( bool visible );
void setInOverview( bool isInOverview );
bool isVisible() const;
bool isInOverview() const;
const QgsMapLayer* layer() const;
};
/** \ingroup gui
* Map canvas is a class for displaying all GIS data types on a canvas.
*/
@ -52,16 +29,12 @@ class QgsMapCanvas : QGraphicsView
//! @note added in 2.16
double magnificationFactor() const;
void setLayerSet( QList<QgsMapCanvasLayer>& layers );
//! Set list of layers that should be shown in the canvas
//! @note added in 3.0
void setLayers( const QList<QgsMapLayer*>& layers );
void setCurrentLayer( QgsMapLayer* layer );
// ### QGIS 3: make QgsMapCanvas independent from overview
void updateOverview();
// ### QGIS 3: make QgsMapCanvas independent from overview
void enableOverviewMode( QgsMapOverviewCanvas* overview );
//! Get access to properties used for map rendering
//! @note added in 2.4
const QgsMapSettings& mapSettings() const /KeepReference/;

View File

@ -2968,7 +2968,7 @@ void QgisApp::createOverview()
// add to the Panel submenu
mPanelMenu->addAction( mOverviewDock->toggleViewAction() );
mMapCanvas->enableOverviewMode( mOverviewCanvas );
mLayerTreeCanvasBridge->setOvervewCanvas( mOverviewCanvas );
// moved here to set anti aliasing to both map canvas and overview
QSettings mySettings;
@ -9622,9 +9622,9 @@ void QgisApp::closeProject()
removeAnnotationItems();
// clear out any stuff from project
mMapCanvas->freeze( true );
QList<QgsMapCanvasLayer> emptyList;
mMapCanvas->setLayerSet( emptyList );
mMapCanvas->setLayers( QList<QgsMapLayer*>() );
mMapCanvas->clearCache();
mOverviewCanvas->setLayers( QList<QgsMapLayer*>() );
removeAllLayers();
}

View File

@ -134,8 +134,7 @@ void QgsBrowser::itemClicked( const QModelIndex& index )
// clear the previous stuff
setLayer( nullptr );
QList<QgsMapCanvasLayer> nolayers;
mapCanvas->setLayerSet( nolayers );
mapCanvas->setLayers( QList<QgsMapLayer*>() );
metaTextBrowser->clear();
if ( mParamWidget )
{
@ -431,9 +430,7 @@ void QgsBrowser::updateCurrentTab()
if ( mLayer && mLayer->isValid() )
{
// Create preview: add to map canvas
QList<QgsMapCanvasLayer> layers;
layers << QgsMapCanvasLayer( mLayer );
mapCanvas->setLayerSet( layers );
mapCanvas->setLayers( QList<QgsMapLayer*>() << mLayer );
QgsRectangle fullExtent = mLayer->extent();
fullExtent.scale( 1.05 ); // add some border
mapCanvas->setExtent( fullExtent );

View File

@ -20,12 +20,14 @@
#include "qgsmaplayer.h"
#include "qgsvectorlayer.h"
#include "qgsmapcanvas.h"
#include "qgsmapoverviewcanvas.h"
#include "qgsproject.h"
QgsLayerTreeMapCanvasBridge::QgsLayerTreeMapCanvasBridge( QgsLayerTreeGroup *root, QgsMapCanvas *canvas, QObject* parent )
: QObject( parent )
, mRoot( root )
, mCanvas( canvas )
, mOverviewCanvas( nullptr )
, mPendingCanvasUpdate( false )
, mHasCustomLayerOrder( false )
, mAutoSetupOnFirstLayer( true )
@ -116,7 +118,7 @@ void QgsLayerTreeMapCanvasBridge::setCustomLayerOrder( const QStringList& order
void QgsLayerTreeMapCanvasBridge::setCanvasLayers()
{
QList<QgsMapCanvasLayer> layers;
QList<QgsMapLayer*> canvasLayers, overviewLayers;
if ( mHasCustomLayerOrder )
{
@ -124,11 +126,16 @@ void QgsLayerTreeMapCanvasBridge::setCanvasLayers()
{
QgsLayerTreeLayer* nodeLayer = mRoot->findLayer( layerId );
if ( nodeLayer )
layers << QgsMapCanvasLayer( nodeLayer->layer(), nodeLayer->isVisible() == Qt::Checked, nodeLayer->customProperty( QStringLiteral( "overview" ), 0 ).toInt() );
{
if ( nodeLayer->isVisible() == Qt::Checked )
canvasLayers << nodeLayer->layer();
if ( nodeLayer->customProperty( QStringLiteral( "overview" ), 0 ).toInt() )
overviewLayers << nodeLayer->layer();
}
}
}
else
setCanvasLayers( mRoot, layers );
setCanvasLayers( mRoot, canvasLayers, overviewLayers );
QList<QgsLayerTreeLayer*> layerNodes = mRoot->findLayers();
int currentLayerCount = layerNodes.count();
@ -155,7 +162,9 @@ void QgsLayerTreeMapCanvasBridge::setCanvasLayers()
}
}
mCanvas->setLayerSet( layers );
mCanvas->setLayers( canvasLayers );
if ( mOverviewCanvas )
mOverviewCanvas->setLayers( overviewLayers );
if ( firstLayers )
{
@ -248,16 +257,19 @@ void QgsLayerTreeMapCanvasBridge::writeProject( QDomDocument& doc )
doc.documentElement().appendChild( elem );
}
void QgsLayerTreeMapCanvasBridge::setCanvasLayers( QgsLayerTreeNode *node, QList<QgsMapCanvasLayer> &layers )
void QgsLayerTreeMapCanvasBridge::setCanvasLayers( QgsLayerTreeNode *node, QList<QgsMapLayer*> &canvasLayers, QList<QgsMapLayer*>& overviewLayers )
{
if ( QgsLayerTree::isLayer( node ) )
{
QgsLayerTreeLayer* nodeLayer = QgsLayerTree::toLayer( node );
layers << QgsMapCanvasLayer( nodeLayer->layer(), nodeLayer->isVisible() == Qt::Checked, nodeLayer->customProperty( QStringLiteral( "overview" ), 0 ).toInt() );
if ( nodeLayer->isVisible() == Qt::Checked )
canvasLayers << nodeLayer->layer();
if ( nodeLayer->customProperty( QStringLiteral( "overview" ), 0 ).toInt() )
overviewLayers << nodeLayer->layer();
}
Q_FOREACH ( QgsLayerTreeNode* child, node->children() )
setCanvasLayers( child, layers );
setCanvasLayers( child, canvasLayers, overviewLayers );
}
void QgsLayerTreeMapCanvasBridge::deferredSetCanvasLayers()

View File

@ -22,7 +22,8 @@
#include "qgscoordinatereferencesystem.h"
class QgsMapCanvas;
class QgsMapCanvasLayer;
class QgsMapLayer;
class QgsMapOverviewCanvas;
class QgsLayerTreeGroup;
class QgsLayerTreeNode;
@ -54,6 +55,13 @@ class GUI_EXPORT QgsLayerTreeMapCanvasBridge : public QObject
QgsLayerTreeGroup* rootGroup() const { return mRoot; }
QgsMapCanvas* mapCanvas() const { return mCanvas; }
//! Associates overview canvas with the bridge, so the overview will be updated whenever main canvas is updated
//! @note added in 3.0
void setOvervewCanvas( QgsMapOverviewCanvas* overviewCanvas ) { mOverviewCanvas = overviewCanvas; }
//! Returns associated overview canvas (may be null)
//! @note added in 3.0
QgsMapOverviewCanvas* overviewCanvas() const { return mOverviewCanvas; }
bool hasCustomLayerOrder() const { return mHasCustomLayerOrder; }
QStringList customLayerOrder() const { return mCustomLayerOrder; }
@ -87,7 +95,7 @@ class GUI_EXPORT QgsLayerTreeMapCanvasBridge : public QObject
void defaultLayerOrder( QgsLayerTreeNode* node, QStringList& order ) const;
void setCanvasLayers( QgsLayerTreeNode* node, QList<QgsMapCanvasLayer>& layers );
void setCanvasLayers( QgsLayerTreeNode* node, QList<QgsMapLayer*> &canvasLayers, QList<QgsMapLayer*>& overviewLayers );
void deferredSetCanvasLayers();
@ -100,6 +108,7 @@ class GUI_EXPORT QgsLayerTreeMapCanvasBridge : public QObject
protected:
QgsLayerTreeGroup* mRoot;
QgsMapCanvas* mCanvas;
QgsMapOverviewCanvas* mOverviewCanvas;
bool mPendingCanvasUpdate;

View File

@ -97,7 +97,6 @@ QgsMapCanvas::QgsMapCanvas( QWidget * parent )
: QGraphicsView( parent )
, mCanvasProperties( new CanvasProperties )
, mMap( nullptr )
, mMapOverview( nullptr )
, mFrozen( false )
, mRefreshScheduled( false )
, mRenderFlag( true ) // by default, the canvas is rendered
@ -245,9 +244,6 @@ double QgsMapCanvas::magnificationFactor() const
void QgsMapCanvas::enableAntiAliasing( bool theFlag )
{
mSettings.setFlag( QgsMapSettings::Antialiasing, theFlag );
if ( mMapOverview )
mMapOverview->enableAntiAliasing( theFlag );
} // anti aliasing
void QgsMapCanvas::enableMapTileRendering( bool theFlag )
@ -288,118 +284,45 @@ const QgsMapToPixel * QgsMapCanvas::getCoordinateTransform()
return &mapSettings().mapToPixel();
}
void QgsMapCanvas::setLayerSet( QList<QgsMapCanvasLayer> &layers )
void QgsMapCanvas::setLayers( const QList<QgsMapLayer*>& layers )
{
// create layer set
QList<QgsMapLayer*> 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() );
}
if ( lyr.isInOverview() )
{
layerSetOverview.push_back( lyr.layer() );
}
}
QList<QgsMapLayer*> layerSetOld = mapSettings().layers();
bool layerSetChanged = layerSetOld != layerSet;
QList<QgsMapLayer*> oldLayers = mSettings.layers();
// update only if needed
if ( layerSetChanged )
if ( layers == oldLayers )
return;
Q_FOREACH ( QgsMapLayer* layer, oldLayers )
{
for ( i = 0; i < layerCount(); i++ )
disconnect( layer, &QgsMapLayer::repaintRequested, this, &QgsMapCanvas::refresh );
disconnect( layer, &QgsMapLayer::crsChanged, this, &QgsMapCanvas::layerCrsChange );
if ( QgsVectorLayer* vlayer = qobject_cast<QgsVectorLayer *>( layer ) )
{
// 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( crsChanged() ), this, SLOT( layerCrsChange() ) );
QgsVectorLayer *isVectLyr = qobject_cast<QgsVectorLayer *>( currentLayer );
if ( isVectLyr )
{
disconnect( isVectLyr, &QgsVectorLayer::selectionChanged, this, &QgsMapCanvas::selectionChangedSlot );
}
disconnect( vlayer, &QgsVectorLayer::selectionChanged, this, &QgsMapCanvas::selectionChangedSlot );
}
}
mSettings.setLayers( layerSet );
mSettings.setLayers( layers );
for ( i = 0; i < layerCount(); i++ )
Q_FOREACH ( QgsMapLayer* layer, layers )
{
connect( layer, &QgsMapLayer::repaintRequested, this, &QgsMapCanvas::refresh );
connect( layer, &QgsMapLayer::crsChanged, this, &QgsMapCanvas::layerCrsChange );
if ( QgsVectorLayer* vlayer = qobject_cast<QgsVectorLayer *>( layer ) )
{
// Add check if vector layer when connecting to selectionChanged slot
// Ticket #811 - racicot
QgsMapLayer *currentLayer = layer( i );
if ( !currentLayer )
continue;
connect( currentLayer, SIGNAL( repaintRequested() ), this, SLOT( refresh() ) );
connect( currentLayer, SIGNAL( crsChanged() ), this, SLOT( layerCrsChange() ) );
QgsVectorLayer *isVectLyr = qobject_cast<QgsVectorLayer *>( currentLayer );
if ( isVectLyr )
{
connect( isVectLyr, &QgsVectorLayer::selectionChanged, this, &QgsMapCanvas::selectionChangedSlot );
}
connect( vlayer, &QgsVectorLayer::selectionChanged, this, &QgsMapCanvas::selectionChangedSlot );
}
updateDatumTransformEntries();
QgsDebugMsg( "Layers have changed, refreshing" );
emit layersChanged();
refresh();
}
if ( mMapOverview )
{
if ( mMapOverview->layers() != layerSetOverview )
{
mMapOverview->setLayers( layerSetOverview );
}
updateDatumTransformEntries();
// refresh overview maplayers even if layer set is the same
// because full extent might have changed
updateOverview();
}
} // setLayerSet
QgsDebugMsg( "Layers have changed, refreshing" );
emit layersChanged();
void QgsMapCanvas::enableOverviewMode( QgsMapOverviewCanvas* overview )
{
if ( mMapOverview )
{
// disconnect old map overview if exists
disconnect( this, SIGNAL( hasCrsTransformEnabledChanged( bool ) ),
mMapOverview, SLOT( hasCrsTransformEnabled( bool ) ) );
disconnect( this, SIGNAL( destinationCrsChanged() ),
mMapOverview, SLOT( destinationCrsChanged() ) );
// map overview is not owned by map canvas so don't delete it...
}
mMapOverview = overview;
if ( overview )
{
// connect to the map render to copy its projection settings
connect( this, SIGNAL( hasCrsTransformEnabledChanged( bool ) ),
overview, SLOT( hasCrsTransformEnabled( bool ) ) );
connect( this, SIGNAL( destinationCrsChanged() ),
overview, SLOT( destinationCrsChanged() ) );
}
refresh();
}
const QgsMapSettings &QgsMapCanvas::mapSettings() const
{
return mSettings;
@ -518,16 +441,6 @@ int QgsMapCanvas::mapUpdateInterval() const
}
void QgsMapCanvas::updateOverview()
{
// redraw overview
if ( mMapOverview )
{
mMapOverview->refresh();
}
}
QgsMapLayer* QgsMapCanvas::currentLayer()
{
return mCurrentLayer;

View File

@ -65,39 +65,6 @@ class QgsMapTool;
class QgsSnappingUtils;
class QgsRubberBand;
/** \ingroup gui
* A class that stores visibility and presence in overview flags together
* with pointer to the layer.
*
*/
class GUI_EXPORT QgsMapCanvasLayer
{
public:
QgsMapCanvasLayer( QgsMapLayer* layer, bool visible = true, bool isInOverview = false )
: mLayer( layer )
, mVisible( visible )
, mInOverview( isInOverview )
{}
void setVisible( bool visible ) { mVisible = visible; }
void setInOverview( bool isInOverview ) { mInOverview = isInOverview; }
bool isVisible() const { return mVisible; }
bool isInOverview() const { return mInOverview; }
QgsMapLayer* layer() { return mLayer; }
const QgsMapLayer* layer() const { return mLayer; }
private:
QgsMapLayer* mLayer;
//! Flag whether layer is visible
bool mVisible;
//! Flag whether layer is shown in overview
bool mInOverview;
};
/** \ingroup gui
* Map canvas is a class for displaying all GIS data types on a canvas.
@ -119,16 +86,12 @@ class GUI_EXPORT QgsMapCanvas : public QGraphicsView
//! @note added in 2.16
double magnificationFactor() const;
void setLayerSet( QList<QgsMapCanvasLayer>& layers );
//! Set list of layers that should be shown in the canvas
//! @note added in 3.0
void setLayers( const QList<QgsMapLayer*>& layers );
void setCurrentLayer( QgsMapLayer* layer );
// ### QGIS 3: make QgsMapCanvas independent from overview
void updateOverview();
// ### QGIS 3: make QgsMapCanvas independent from overview
void enableOverviewMode( QgsMapOverviewCanvas* overview );
//! Get access to properties used for map rendering
//! @note added in 2.4
const QgsMapSettings& mapSettings() const;
@ -666,9 +629,6 @@ class GUI_EXPORT QgsMapCanvas : public QGraphicsView
//! owns pixmap with rendered map and controls rendering
QgsMapCanvasMap* mMap;
//! map overview widget - it's controlled by QgsMapCanvas
QgsMapOverviewCanvas* mMapOverview;
//! Flag indicating if the map canvas is frozen.
bool mFrozen;

View File

@ -42,7 +42,9 @@ QgsMapOverviewCanvas::QgsMapOverviewCanvas( QWidget * parent, QgsMapCanvas* mapC
mSettings.setFlag( QgsMapSettings::DrawLabeling, false );
connect( mMapCanvas, SIGNAL( extentsChanged() ), this, SLOT( drawExtentRect() ) );
connect( mMapCanvas, &QgsMapCanvas::extentsChanged, this, &QgsMapOverviewCanvas::drawExtentRect );
connect( mMapCanvas, &QgsMapCanvas::hasCrsTransformEnabledChanged, this, &QgsMapOverviewCanvas::hasCrsTransformEnabled );
connect( mMapCanvas, &QgsMapCanvas::destinationCrsChanged, this, &QgsMapOverviewCanvas::destinationCrsChanged );
}
QgsMapOverviewCanvas::~QgsMapOverviewCanvas()
@ -240,6 +242,8 @@ void QgsMapOverviewCanvas::setLayers( const QList<QgsMapLayer*>& layers )
}
updateFullExtent();
refresh();
}
void QgsMapOverviewCanvas::updateFullExtent()

View File

@ -1168,9 +1168,7 @@ void QgsGeorefPluginGui::addRaster( const QString& file )
QList<QgsMapLayer *>() << mLayer, false, false );
// add layer to map canvas
QList<QgsMapCanvasLayer> layers;
layers.append( QgsMapCanvasLayer( mLayer ) );
mCanvas->setLayerSet( layers );
mCanvas->setLayers( QList<QgsMapLayer*>() << mLayer );
mAgainAddRaster = false;

View File

@ -69,15 +69,15 @@ void TestProjectionIssues::initTestCase()
QgsProject::instance()->addMapLayers( mapLayers );
// Add all layers in registry to the canvas
QList<QgsMapCanvasLayer> canvasLayers;
QList<QgsMapLayer*> canvasLayers;
Q_FOREACH ( QgsMapLayer* layer, QgsProject::instance()->mapLayers() )
{
canvasLayers.append( QgsMapCanvasLayer( layer ) );
canvasLayers.append( layer );
}
// create canvas
mMapCanvas = new QgsMapCanvas();
mMapCanvas->setLayerSet( canvasLayers );
mMapCanvas->setLayers( canvasLayers );
//reproject to SWEDREF 99 TM
QgsCoordinateReferenceSystem destCRS;

View File

@ -140,9 +140,7 @@ void TestQgsMapCanvas::testMagnification()
myPointFileInfo.completeBaseName(), QStringLiteral( "ogr" ) );
// prepare map canvas
QList<QgsMapCanvasLayer> layers;
layers.append( layer );
mCanvas->setLayerSet( layers );
mCanvas->setLayers( QList<QgsMapLayer*>() << layer );
QgsProject::instance()->addMapLayers( QList<QgsMapLayer *>() << layer );
mCanvas->setExtent( layer->extent() );
@ -219,9 +217,7 @@ void TestQgsMapCanvas::testMagnificationExtent()
myPointFileInfo.completeBaseName(), QStringLiteral( "ogr" ) );
// prepare map canvas
QList<QgsMapCanvasLayer> layers;
layers.append( layer );
mCanvas->setLayerSet( layers );
mCanvas->setLayers( QList<QgsMapLayer *>() << layer );
QgsProject::instance()->addMapLayers( QList<QgsMapLayer *>() << layer );
// zoomToFullExtent

View File

@ -42,14 +42,14 @@ TestRendererGUI::TestRendererGUI( QWidget *parent ) :
void TestRendererGUI::loadLayers()
{
// load just first vector layer
QList<QgsMapCanvasLayer> canvasLayers;
QList<QgsMapLayer*> canvasLayers;
foreach ( QgsMapLayer* layer, QgsProject::instance()->mapLayers().values() )
{
if ( layer->type() == QgsMapLayer::VectorLayer )
canvasLayers << QgsMapCanvasLayer( layer );
canvasLayers << layer;
}
mMapCanvas->setLayerSet( canvasLayers );
mMapCanvas->setLayers( canvasLayers );
}
void TestRendererGUI::setRenderer()