20 #include <QApplication>
24 #include <QGraphicsItem>
25 #include <QGraphicsScene>
26 #include <QGraphicsView>
28 #include <QMouseEvent>
30 #include <QPaintEvent>
34 #include <QTextStream>
35 #include <QResizeEvent>
37 #include <QStringList>
38 #include <QWheelEvent>
85 : QGraphicsView( parent )
89 , mAntiAliasing( false )
91 setObjectName( name );
92 mScene =
new QGraphicsScene();
94 setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
95 setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
112 setMouseTracking(
true );
113 setFocusPolicy( Qt::StrongFocus );
116 connect(
mMapRenderer, SIGNAL( datumTransformInfoRequested(
const QgsMapLayer*,
const QString&,
const QString& ) ),
136 this, SLOT(
readProject(
const QDomDocument & ) ) );
144 grabGesture( Qt::PinchGesture );
145 viewport()->setAttribute( Qt::WA_AcceptTouchEvents );
162 QList<QGraphicsItem*> list =
mScene->items();
163 QList<QGraphicsItem*>::iterator it = list.begin();
164 while ( it != list.end() )
166 QGraphicsItem* item = *it;
207 if ( index >= 0 && index < (
int ) layers.size() )
253 QgsDebugMsg(
"NOT updating layer set while drawing" );
258 QStringList layerSet, layerSetOverview;
261 for ( i = 0; i < layers.size(); i++ )
271 layerSet.push_back( lyr.
layer()->
id() );
276 layerSetOverview.push_back( lyr.
layer()->
id() );
282 bool layerSetChanged = layerSetOld != layerSet;
285 if ( layerSetChanged )
287 QgsDebugMsg(
"Layers changed to: " + layerSet.join(
", " ) );
294 disconnect( currentLayer, SIGNAL( repaintRequested() ),
this, SLOT(
refresh() ) );
295 disconnect( currentLayer, SIGNAL( screenUpdateRequested() ),
this, SLOT(
updateMap() ) );
310 connect( currentLayer, SIGNAL( repaintRequested() ),
this, SLOT(
refresh() ) );
311 connect( currentLayer, SIGNAL( screenUpdateRequested() ),
this, SLOT(
updateMap() ) );
328 if ( layerSetOvOld != layerSetOverview )
344 disconnect(
mMapRenderer, SIGNAL( hasCrsTransformEnabledChanged(
bool ) ),
346 disconnect(
mMapRenderer, SIGNAL( destinationSrsChanged() ),
357 connect(
mMapRenderer, SIGNAL( hasCrsTransformEnabledChanged(
bool ) ),
359 connect(
mMapRenderer, SIGNAL( destinationSrsChanged() ),
360 overview, SLOT( destinationSrsChanged() ) );
390 bool logRefresh = settings.value(
"/Map/logCanvasRefreshEvent",
false ).toBool();
398 bool enableBackbufferSetting = settings.value(
"/Map/enableBackbuffer", 1 ).toBool();
408 qDebug() <<
"Enable back buffering: " << enableBackbufferSetting;
409 if ( enableBackbufferSetting )
411 viewport()->setAttribute( Qt::WA_PaintOnScreen,
false );
415 viewport()->setAttribute( Qt::WA_PaintOnScreen,
true );
433 QApplication::setOverrideCursor( Qt::WaitCursor );
452 QApplication::restoreOverrideCursor();
462 QString logMsg =
tr(
"Canvas refresh: %1 ms" ).arg( t.elapsed() );
463 QObject* senderObj = QObject::sender();
466 logMsg +=
tr(
", sender '%1'" ).arg( senderObj->metaObject()->className() );
487 if ( theQPixmap != NULL )
491 painter.begin( theQPixmap );
496 theQPixmap->save( theFileName, theFormat.toLocal8Bit().data() );
504 pixmap->save( theFileName, theFormat.toLocal8Bit().data() );
513 myHeader +=
"0 \r\n";
515 myHeader +=
"0 \r\n";
523 QFileInfo myInfo = QFileInfo( theFileName );
525 QString myWorldFileName = myInfo.absolutePath() +
"/" + myInfo.completeBaseName() +
"." + theFormat +
"w";
526 QFile myWorldFile( myWorldFileName );
527 if ( !myWorldFile.open( QIODevice::WriteOnly ) )
531 QTextStream myStream( &myWorldFile );
532 myStream << myHeader;
568 QgsDebugMsg(
"Empty extent - keeping old extent with new center!" );
639 extent.
scale( 1.05 );
762 rect.
scale( 1.0, &c );
820 QPen pen( Qt::gray );
828 double dx = qAbs(( currentExtent.
xMaximum() - currentExtent.
xMinimum() ) / 4 );
829 double dy = qAbs(( currentExtent.
yMaximum() - currentExtent.
yMinimum() ) / 4 );
875 if ( ! e->isAutoRepeat() )
887 case Qt::Key_PageDown:
900 QgsDebugMsg(
"Ignoring key: " + QString::number( e->key() ) );
937 QgsDebugMsg(
"Ignoring key release: " + QString::number( e->key() ) );
966 if ( e->button() == Qt::MidButton )
998 if ( e->button() == Qt::MidButton )
1011 QgsDebugMsg(
"Right click in map tool zoom or pan, last tool is " +
1054 if ( theRenderContext )
1072 mScene->setSceneRect( QRectF( 0, 0, lastSize.width(), lastSize.height() ) );
1087 QGraphicsView::paintEvent( e );
1092 QList<QGraphicsItem*> list =
mScene->items();
1093 QList<QGraphicsItem*>::iterator it = list.begin();
1094 while ( it != list.end() )
1113 QgsDebugMsg(
"Wheel event delta " + QString::number( e->delta() ) );
1125 if ( QgsApplication::keyboardModifiers() )
1135 if ( e->delta() > 0 )
1153 QgsPoint newCenter( mousePos.x() + (( oldCenter.x() - mousePos.x() ) * scaleFactor ),
1154 mousePos.y() + (( oldCenter.y() - mousePos.y() ) * scaleFactor ) );
1158 extent.
scale( scaleFactor, &newCenter );
1203 r.
scale( scaleFactor, ¢er );
1229 QPoint xy = e->pos();
1278 setCursor( Qt::ArrowCursor );
1294 QBrush bgBrush( theColor );
1295 setBackgroundBrush( bgBrush );
1298 palette.setColor( backgroundRole(), theColor );
1299 setPalette( palette );
1303 mScene->setBackgroundBrush( bgBrush );
1308 return mScene->backgroundBrush().color();
1319 QList<QgsMapLayer*> lst;
1324 lst.append( layer );
1364 QgsDebugMsg(
"Setting map units to " + QString::number( static_cast<int>( u ) ) );
1396 QgsDebugMsg(
"QgsMapCanvas connected to " + QString( signal ) );
1420 double dx = qAbs( end.
x() - start.
x() );
1421 double dy = qAbs( end.
y() - start.
y() );
1426 if ( end.
x() < start.
x() )
1429 r.setXMaximum( r.xMaximum() + dx );
1433 r.setXMinimum( r.xMinimum() - dx );
1434 r.setXMaximum( r.xMaximum() - dx );
1437 if ( end.
y() < start.
y() )
1439 r.setYMaximum( r.yMaximum() + dy );
1440 r.setYMinimum( r.yMinimum() + dy );
1445 r.setYMaximum( r.yMaximum() - dy );
1446 r.setYMinimum( r.yMinimum() - dy );
1483 QList<QGraphicsItem*> list =
mScene->items();
1484 QList<QGraphicsItem*>::iterator it = list.begin();
1485 while ( it != list.end() )
1487 QGraphicsItem* item = *it;
1508 QMessageBox::warning(
1511 tr(
"Could not draw %1 because:\n%2",
"COMMENTED OUT" ).arg( mapLayer->
name() ).arg( mapLayer->
lastError() )
1532 QDomNodeList nodes = doc.elementsByTagName(
"mapcanvas" );
1533 if ( nodes.count() )
1535 QDomNode node = nodes.item( 0 );
1541 QgsDebugMsg(
"Couldn't read mapcanvas information from project" );
1549 QDomNodeList nl = doc.elementsByTagName(
"qgis" );
1552 QgsDebugMsg(
"Unable to find qgis element in project file" );
1555 QDomNode qgisNode = nl.item( 0 );
1557 QDomElement mapcanvasNode = doc.createElement(
"mapcanvas" );
1558 qgisNode.appendChild( mapcanvasNode );
1572 QString settingsString =
"/Projections/" + srcAuthId +
"//" + destAuthId;
1573 QVariant defaultSrcTransform = s.value( settingsString +
"_srcTransform" );
1574 QVariant defaultDestTransform = s.value( settingsString +
"_destTransform" );
1575 if ( defaultSrcTransform.isValid() && defaultDestTransform.isValid() )
1584 if ( !s.value(
"/Projections/showDatumTransformDialog",
false ).toBool() )
1593 if ( dt.size() < 2 )
1600 if (
mMapRenderer && ( d.exec() == QDialog::Accepted ) )
1602 int srcTransform = -1;
1603 int destTransform = -1;
1607 srcTransform = t.at( 0 );
1611 destTransform = t.at( 1 );
1614 if ( d.rememberSelection() )
1616 s.setValue( settingsString +
"_srcTransform", srcTransform );
1617 s.setValue( settingsString +
"_destTransform", destTransform );
1634 r.
scale( scaleFactor );
1659 QgsDebugMsg(
"refreshing after reprojection was enabled" );
1674 bool QgsMapCanvas::event( QEvent * e )
1681 if ( e->type() == QEvent::Gesture )
1686 done =
mMapTool->gestureEvent( static_cast<QGestureEvent*>( e ) );
1692 done = QGraphicsView::event( e );
void unsetMapTool(QgsMapTool *mapTool)
Unset the current map tool or last non zoom tool.
QgsMapCanvasMap * mMap
owns pixmap with rendered map and controls rendering
const QgsMapToPixel * coordinateTransform()
void zoomToSelected(QgsVectorLayer *layer=NULL)
Zoom to the extent of the selected features of current (vector) layer.
void updateCanvasItemPositions()
called on resize or changed extent to notify canvas items to change their rectangle ...
QPoint mouseLastXY
Last seen point of the mouse.
void setRenderingStopped(bool stopped)
virtual QColor canvasColor() const
Read property of QColor bgColor.
A rectangle specified with double values.
Base class for all map layer types.
void render(QPainter *painter, double *forceWidthScale=0)
starts rendering @ param forceWidthScale Force a specific scale factor for line widths and marker siz...
const QgsCoordinateReferenceSystem & crsByAuthId(const QString &authid)
Returns the CRS for authid, e.g.
bool isEmpty() const
test if rectangle is empty
void zoomToNextExtent()
Zoom to the next extent (view)
QGraphicsScene * mScene
graphics scene manages canvas items
void zoomWithCenter(int x, int y, bool zoomIn)
Zooms in/out with a given center.
bool isDirty() const
Return the state of the canvas (dirty or not)
void freeze(bool frz=true)
QgsRenderContext * rendererContext()
Accessor for render context.
virtual void setCanvasColor(const QColor &_newVal)
Write property of QColor bgColor.
void enableOverviewMode(QgsMapOverviewCanvas *overview)
double mapUnitsPerPixel() const
Returns the mapUnitsPerPixel (map units per pixel) for the canvas.
int layerCount() const
return number of layers on the map
A widget that displays an overview map.
void setXMaximum(double x)
Set the maximum x value.
void clearExtentHistory()
void resize(QSize size)
resize canvas item and pixmap
QgsMapRenderer * mMapRenderer
all map rendering is done in this class
bool mouseButtonDown
Flag to indicate status of mouse button.
double yMaximum() const
Get the y maximum value (top side of rectangle)
virtual QString lastError()
If an operation returns 0 (e.g.
void zoomByFactor(double scaleFactor)
Zoom with the factor supplied. Factor > 1 zooms out, interval (0,1) zooms in.
void mouseReleaseEvent(QMouseEvent *e)
Overridden mouse release event.
QgsRectangle extent() const
returns current extent
void setExtent(const QgsRectangle &r)
Set the extent of the map canvas.
QString qgsDoubleToString(const double &a)
void addLayerCoordinateTransform(const QString &layerId, const QString &srcAuthId, const QString &destAuthId, int srcDatumTransform=-1, int destDatumTransform=-1)
An abstract class for items that can be placed on the map canvas.
A class that stores visibility and presence in overview flags together with pointer to the layer...
bool hasCrsTransformEnabled()
A simple helper method to find out if on the fly projections are enabled or not.
void setCurrentLayer(QgsMapLayer *layer)
QList< QgsMapLayer * > layers() const
return list of layers within map canvas. Added in v1.5
void moveCanvasContents(bool reset=false)
called when panning is in action, reset indicates end of panning
WheelAction mWheelAction
Mouse wheel action.
void readProject(const QDomDocument &)
called to read map canvas settings from project
bool panSelectorDown
Flag to indicate the pan selector key is held down by user.
QgsMapOverviewCanvas * mMapOverview
map overview widget - it's controlled by QgsMapCanvas
void refresh()
Repaints the canvas map.
void renderComplete(QPainter *)
Emitted when the canvas has rendered.
~QgsMapCanvas()
Destructor.
void keyReleaseEvent(QKeyEvent *e)
Overridden key release event.
QgsMapTool * mapTool()
Returns the currently active tool.
void setPanningOffset(const QPoint &point)
sets current offset, to be called from QgsMapCanvas
void setLayerSet(const QStringList &layers)
change current layer set
A non GUI class for rendering a map layer set onto a QPainter.
void updateContents()
Update contents - can be called while drawing to show the status.
void resizeEvent(QResizeEvent *e)
Overridden resize event.
QgsMapTool * mMapTool
pointer to current map tool
void zoomLastStatusChanged(bool)
Emitted when zoom last status changed.
bool mAntiAliasing
indicates whether antialiasing will be used for rendering
static void logMessage(QString message, QString tag=QString::null, MessageLevel level=WARNING)
add a message to the instance (and create it if necessary)
void updateScale()
Emits signal scaleChanged to update scale in main window.
void mouseDoubleClickEvent(QMouseEvent *e)
Overridden mouse double click event.
QgsMapLayer * mCurrentLayer
current layer in legend
QSize mNewSize
resize canvas size
void setMapTool(QgsMapTool *mapTool)
Sets the map tool currently being used on the canvas.
void enableAntiAliasing(bool flag)
const QString & name() const
Get the display name of the layer.
void paintEvent(QPaintEvent *e)
Overridden paint event.
Perform transforms between map coordinates and device coordinates.
void showError(QgsMapLayer *mapLayer)
show whatever error is exposed by the QgsMapLayer.
A rectangular graphics item representing the map on the canvas.
void clear()
Clear the map canvas.
void mapCanvasRefreshed()
Emitted when canvas finished a refresh request.
double yMinimum() const
Get the y minimum value (bottom side of rectangle)
double scale()
Get the last reported scale of the canvas.
double xMaximum() const
Get the x maximum value (right side of rectangle)
bool mBackbufferEnabled
If backbuffering is currently enabled.
void setBackgroundColor(const QColor &color)
void zoomNextStatusChanged(bool)
Emitted when zoom next status changed.
QgsMapTool * mLastNonZoomMapTool
previous tool if current is for zooming/panning
bool hasCrsTransformEnabled() const
returns true if projections are enabled for this layer set
void mousePressEvent(QMouseEvent *e)
Overridden mouse press event.
double mapUnitsPerPixel() const
void render()
renders map using QgsMapRenderer to mPixmap
bool mDirty
Flag to track the state of the Map canvas.
void panToSelected(QgsVectorLayer *layer=NULL)
Pan to the selected features of current (vector) layer keeping same extent.
void setLayerSet(QList< QgsMapCanvasLayer > &layers)
void setYMinimum(double y)
Set the minimum y value.
double scale() const
Scale denominator.
void keyReleased(QKeyEvent *e)
Emit key release event.
QPaintDevice & paintDevice()
void mapToolDestroyed()
called when current maptool is destroyed
bool setExtent(const QgsRectangle &extent)
sets extent and checks whether suitable (returns false if not)
void setMapUnits(QGis::UnitType u)
void getDatumTransformInfo(const QgsMapLayer *ml, const QString &srcAuthId, const QString &destAuthId)
ask user about datum transformation
QPaintDevice & canvasPaintDevice()
Accessor for the canvas paint device.
void setMessageAsPlainText(const QString &msg)
bool mPainting
currently in paint event
QString id() const
Get this layer's unique ID, this ID is used to access this layer from map layer registry.
void wheelEvent(QWheelEvent *e)
Overridden mouse wheel event.
virtual QString lastErrorTitle()
If an operation returns 0 (e.g.
void setRenderFlag(bool theFlag)
Whether to suppress rendering or not.
QGis::UnitType mapUnits() const
Get the current canvas map units.
void refresh()
renders overview and updates panning widget
void renderStarting()
Emitted when the canvas is about to be rendered.
A class to represent a point geometry.
void saveAsImage(QString theFileName, QPixmap *QPixmap=0, QString="PNG")
Save the convtents of the map canvas to disk as an image.
void keyPressed(QKeyEvent *e)
Emit key press event.
void updateFullExtent()
updates extent of the layer set
void zoomOut()
Zoom out with fixed factor.
void zoomToPreviousExtent()
Zoom to the previous extent (view)
void xyCoordinates(const QgsPoint &p)
emits current mouse position
bool isDrawing()
true if canvas currently drawing
bool writeXML(QDomNode &theNode, QDomDocument &theDoc)
write settings
QPoint mouseLastXY()
returns last position of mouse cursor
QgsMapLayer * currentLayer()
returns current layer (set by legend widget)
void setWheelAction(WheelAction action, double factor=2)
set wheel action and zoom factor (should be greater than 1)
void selectionChanged(QgsMapLayer *layer)
Emitted when selection in any layer gets changed.
QgsPoint toMapCoordinates(int x, int y) const
bool mDrawing
Flag indicating a map refresh is in progress.
void selectionChangedSlot()
Receives signal about selection change, and pass it on with layer info.
double mWheelZoomFactor
Scale factor multiple for default zoom in/out.
bool mFrozen
Flag indicating if the map canvas is frozen.
QgsRectangle fullExtent()
returns current extent of layer set
Contains information about the context of a rendering operation.
static QgsMapLayerRegistry * instance()
Returns the instance pointer, creating the object on the first call.
void useImageToRender(bool theFlag)
Select which Qt class to render with.
bool isInOverview() const
void setLayerSet(const QStringList &layerSet)
updates layer set for overview
void setYMaximum(double y)
Set the maximum y value.
void writeProject(QDomDocument &)
called to write map canvas settings to project
void panAction(QMouseEvent *event)
Called when mouse is moving and pan is activated.
static QgsProject * instance()
access to canonical QgsProject instance
QgsMapRenderer * mapRenderer()
void zoomToFullExtent()
Zoom to the full extent of all layers.
void enableAntiAliasing(bool flag)
bool mRenderFlag
determines whether user has requested to suppress rendering
Class for storing a coordinate reference system (CRS)
A generic message view for displaying QGIS messages.
void zoomScale(double scale)
Zoom to a specific scale.
UnitType
Map units that qgis supports.
const QgsMapToPixel * getCoordinateTransform()
Get the current coordinate transform.
void scaleChanged(double)
Emitted when the scale of the map changes.
void enableAntiAliasing(bool theFlag)
used to determine if anti-aliasing is enabled or not
QgsMapLayer * mapLayer(QString theLayerId)
Retrieve a pointer to a loaded layer by id.
void useImageToRender(bool flag)
void layerStateChange()
This slot is connected to the visibility change of one or more layers.
QgsRectangle extent() const
Returns the current zoom exent of the map canvas.
QgsMapCanvas(QWidget *parent=0, const char *name=0)
Constructor.
void setMapUnits(QGis::UnitType mapUnits)
Set map units (needed by project properties dialog)
void connectNotify(const char *signal)
debugging member invoked when a connect() is made to this object
void crsTransformEnabled(bool)
void setDirty(bool _dirty)
Flag the canvas as dirty and needed a refresh.
static void setSpecialColumn(const QString &name, QVariant value)
Assign a special column.
void setPanningOffset(const QPoint &point)
QPoint rubberStartPoint
Beginning point of a rubber band.
double width() const
Width of the rectangle.
void zoomIn()
Zoom in with fixed factor.
virtual bool isEditable() const
Returns true if the provider is in editing mode.
QGis::UnitType mapUnits() const
Represents a vector layer which manages a vector based data sets.
virtual void updatePosition()
called on changed extent or resize event to update position of the item
bool readXML(QDomNode &theNode)
read settings
int selectedFeatureCount()
The number of features that are selected in this layer.
double xMinimum() const
Get the x minimum value (left side of rectangle)
QList< QgsRectangle > mLastExtent
recently used extent
void updateFullExtent()
Updates the full extent.
static QgsCRSCache * instance()
QStringList & layerSet()
returns current layer set
QgsPoint center() const
Center point of the rectangle.
void extentsChanged()
Emitted when the extents of the map change.
std::auto_ptr< CanvasProperties > mCanvasProperties
Handle pattern for implementation object.
void mouseMoveEvent(QMouseEvent *e)
Overridden mouse move event.
QgsMapLayer * layer(int index)
return the map layer at position index in the layer stack
void updateMap()
updates pixmap on render progress
void setXMinimum(double x)
Set the minimum x value.
QgsRectangle layerExtentToOutputExtent(QgsMapLayer *theLayer, QgsRectangle extent)
transform bounding box from layer's CRS to output CRS
void keyPressEvent(QKeyEvent *e)
Overridden key press event.
double height() const
Height of the rectangle.
void dragEnterEvent(QDragEnterEvent *e)
Overridden drag enter event.
QgsPoint toMapPoint(double x, double y) const
void drawExtentRect()
used for overview canvas to reflect changed extent in main map canvas
void panActionEnd(QPoint releasePoint)
Ends pan action and redraws the canvas.
void mapUnitsChanged()
The map units may have changed, so cope with that.
QgsRectangle fullExtent() const
Returns the combined exent for all layers on the map canvas.
void layersChanged()
Emitted when a new set of layers has been received.
QgsRectangle boundingBoxOfSelected()
Returns the bounding box of the selected features.
void mapToolSet(QgsMapTool *tool)
Emit map tool changed event.
void scale(double scaleFactor, const QgsPoint *c=0)
Scale the rectangle around its center point.