void QgsMapCanvas::zoomByFactor( double scaleFactor, const QgsPoint* center ) { QgsRectangle r = mapSettings().extent(); r.scale( scaleFactor, center ); setExtent( r ); refresh(); }
void QgsLayoutViewToolZoom::layoutReleaseEvent( QgsLayoutViewMouseEvent *event ) { if ( !mMarqueeZoom || event->button() != Qt::LeftButton ) { event->ignore(); return; } mMarqueeZoom = false; QRectF newBoundsRect = mRubberBand->finish( event->layoutPoint() ); // click? or click-and-drag? if ( !isClickAndDrag( mMousePressStartPos, event->pos() ) ) { //just a click, so zoom to clicked point and recenter double scaleFactor = 0.5; //get current visible part of scene QRect viewportRect( 0, 0, view()->viewport()->width(), view()->viewport()->height() ); QgsRectangle visibleRect = QgsRectangle( view()->mapToScene( viewportRect ).boundingRect() ); visibleRect.scale( scaleFactor, event->layoutPoint().x(), event->layoutPoint().y() ); newBoundsRect = visibleRect.toRectF(); } //zoom view to fit desired bounds view()->fitInView( newBoundsRect, Qt::KeepAspectRatio ); view()->emitZoomLevelChanged(); view()->updateRulers(); }
void QgsLayoutViewToolZoom::layoutPressEvent( QgsLayoutViewMouseEvent *event ) { if ( event->button() != Qt::LeftButton ) { event->ignore(); return; } mMousePressStartPos = event->pos(); if ( event->modifiers() & Qt::AltModifier ) { //zoom out action, so zoom out and recenter on clicked point double scaleFactor = 2; //get current visible part of scene QRect viewportRect( 0, 0, view()->viewport()->width(), view()->viewport()->height() ); QgsRectangle visibleRect = QgsRectangle( view()->mapToScene( viewportRect ).boundingRect() ); visibleRect.scale( scaleFactor, event->layoutPoint().x(), event->layoutPoint().y() ); QRectF boundsRect = visibleRect.toRectF(); //zoom view to fit desired bounds view()->fitInView( boundsRect, Qt::KeepAspectRatio ); view()->emitZoomLevelChanged(); view()->updateRulers(); } else { //zoom in action startMarqueeZoom( event->layoutPoint() ); } }
void SWGISBrowser::updateCurrentTab() { Tab currentTab = this->activeTab(); if(currentTab == Metadata && this->m_DirtyMetadata) { if(this->m_Layer && this->m_Layer->isValid()) { QString myStyle = QgsApplication::reportStyleSheet(); ui->metaTextBrowser->document()->setDefaultStyleSheet(myStyle); ui->metaTextBrowser->setHtml(this->m_Layer->metadata()); } else ui->metaTextBrowser->setHtml(QString()); this->m_DirtyMetadata = false; } if(currentTab == Preview && this->m_DirtyPreview) { if (this->m_Layer && this->m_Layer->isValid()) { // Create preview: add to map canvas QList<QgsMapCanvasLayer> layers; layers << QgsMapCanvasLayer( this->m_Layer ); ui->mapCanvas->setLayerSet( layers ); QgsRectangle fullExtent = this->m_Layer->extent(); fullExtent.scale( 1.05 ); // add some border ui->mapCanvas->setExtent( fullExtent ); ui->mapCanvas->refresh(); QgsRasterLayer *rlayer = qobject_cast<QgsRasterLayer *>(this->m_Layer); if (rlayer) { connect(rlayer->dataProvider(), SIGNAL(dataChanged()), rlayer, SLOT(triggerRepaint())); connect(rlayer->dataProvider(), SIGNAL(dataChanged()), ui->mapCanvas, SLOT(refresh())); } } this->m_DirtyPreview = false; } if (currentTab == Attributes && this->m_DirtyAttributes) { if (this->m_Layer && this->m_Layer->isValid() && this->m_Layer->type() == QgsMapLayer::VectorLayer) { QgsVectorLayer* vlayer = qobject_cast<QgsVectorLayer*>(this->m_Layer); QApplication::setOverrideCursor(Qt::WaitCursor); this->setLayer(vlayer); QApplication::restoreOverrideCursor(); } else { this->setLayer(nullptr); } this->m_DirtyAttributes = false; } }
void QgsMapSettings::setExtent( const QgsRectangle& extent, bool magnified ) { QgsRectangle magnifiedExtent = extent; if ( !magnified ) magnifiedExtent.scale( 1 / mMagnificationFactor ); mExtent = magnifiedExtent; updateDerived(); }
void QgsMapCanvas::zoomWithCenter( int x, int y, bool zoomIn ) { double scaleFactor = ( zoomIn ? 1 / mWheelZoomFactor : mWheelZoomFactor ); // transform the mouse pos to map coordinates QgsPoint center = getCoordinateTransform()->toMapPoint( x, y ); QgsRectangle r = mapSettings().visibleExtent(); r.scale( scaleFactor, ¢er ); setExtent( r ); refresh(); }
void QgsMapCanvas::zoomToSelected( QgsVectorLayer* layer ) { if ( layer == NULL ) { // use current layer by default layer = qobject_cast<QgsVectorLayer *>( mCurrentLayer ); } if ( layer == NULL ) { return; } if ( layer->selectedFeatureCount() == 0 ) { return; } QgsRectangle rect = mapSettings().layerExtentToOutputExtent( layer, layer->boundingBoxOfSelected() ); // no selected features, only one selected point feature //or two point features with the same x- or y-coordinates if ( rect.isEmpty() ) { // zoom in QgsPoint c = rect.center(); rect = extent(); rect.scale( 1.0, &c ); } //zoom to an area else { // Expand rect to give a bit of space around the selected // objects so as to keep them clear of the map boundaries // The same 5% should apply to all margins. rect.scale( 1.05 ); } setExtent( rect ); refresh(); } // zoomToSelected
void QgsRelationReferenceWidget::highlightFeature( QgsFeature f, CanvasExtent canvasExtent ) { if ( !mCanvas ) return; if ( !f.isValid() ) { f = referencedFeature(); if ( !f.isValid() ) return; } if ( !f.hasGeometry() ) { return; } QgsGeometry geom = f.geometry(); // scale or pan if ( canvasExtent == Scale ) { QgsRectangle featBBox = geom.boundingBox(); featBBox = mCanvas->mapSettings().layerToMapCoordinates( mReferencedLayer, featBBox ); QgsRectangle extent = mCanvas->extent(); if ( !extent.contains( featBBox ) ) { extent.combineExtentWith( featBBox ); extent.scale( 1.1 ); mCanvas->setExtent( extent ); mCanvas->refresh(); } } else if ( canvasExtent == Pan ) { QgsGeometry centroid = geom.centroid(); QgsPointXY center = centroid.asPoint(); center = mCanvas->mapSettings().layerToMapCoordinates( mReferencedLayer, center ); mCanvas->zoomByFactor( 1.0, ¢er ); // refresh is done in this method } // highlight deleteHighlight(); mHighlight = new QgsHighlight( mCanvas, f, mReferencedLayer ); QgsIdentifyMenu::styleHighlight( mHighlight ); mHighlight->show(); QTimer *timer = new QTimer( this ); timer->setSingleShot( true ); connect( timer, &QTimer::timeout, this, &QgsRelationReferenceWidget::deleteHighlight ); timer->start( 3000 ); }
void QgsMapCanvas::zoomToFullExtent() { QgsRectangle extent = fullExtent(); // If the full extent is an empty set, don't do the zoom if ( !extent.isEmpty() ) { // Add a 5% margin around the full extent extent.scale( 1.05 ); setExtent( extent ); } refresh(); } // zoomToFullExtent
void QgsMapOverviewCanvas::updateFullExtent() { QgsRectangle rect; if ( mSettings.hasValidSettings() ) rect = mSettings.fullExtent(); else rect = mMapCanvas->fullExtent(); // expand a bit to keep features on margin rect.scale( 1.1 ); mSettings.setExtent( rect ); drawExtentRect(); }
void QgsProjectionSelectionTreeWidget::updateBoundsPreview() { QTreeWidgetItem *lvi = lstCoordinateSystems->currentItem(); if ( !lvi || lvi->text( QgisCrsIdColumn ).isEmpty() ) return; QgsCoordinateReferenceSystem currentCrs = crs(); if ( !currentCrs.isValid() ) return; QgsRectangle rect = currentCrs.bounds(); if ( !qgsDoubleNear( rect.area(), 0.0 ) ) { QgsGeometry geom; if ( rect.xMinimum() > rect.xMaximum() ) { QgsRectangle rect1 = QgsRectangle( -180, rect.yMinimum(), rect.xMaximum(), rect.yMaximum() ); QgsRectangle rect2 = QgsRectangle( rect.xMinimum(), rect.yMinimum(), 180, rect.yMaximum() ); geom = QgsGeometry::fromRect( rect1 ); geom.addPart( QgsGeometry::fromRect( rect2 ) ); } else { geom = QgsGeometry::fromRect( rect ); } mPreviewBand->setToGeometry( geom, nullptr ); mPreviewBand->setColor( QColor( 255, 0, 0, 65 ) ); QgsRectangle extent = geom.boundingBox(); extent.scale( 1.1 ); mAreaCanvas->setExtent( extent ); mAreaCanvas->refresh(); mPreviewBand->show(); QString extentString = tr( "Extent: %1, %2, %3, %4" ) .arg( rect.xMinimum(), 0, 'f', 2 ) .arg( rect.yMinimum(), 0, 'f', 2 ) .arg( rect.xMaximum(), 0, 'f', 2 ) .arg( rect.yMaximum(), 0, 'f', 2 ); QString proj4String = tr( "Proj4: %1" ).arg( selectedProj4String() ); teProjection->setText( extentString + "\n" + proj4String ); } else { mPreviewBand->hide(); mAreaCanvas->zoomToFullExtent(); QString extentString = tr( "Extent: Extent not known" ); QString proj4String = tr( "Proj4: %1" ).arg( selectedProj4String() ); teProjection->setText( extentString + "\n" + proj4String ); } }
void QgsMapSettings::setMagnificationFactor( double factor ) { double ratio = mMagnificationFactor / factor; mMagnificationFactor = factor; double rot = rotation(); setRotation( 0.0 ); QgsRectangle ext = visibleExtent(); ext.scale( ratio ); mRotation = rot; mExtent = ext; mDpi = outputDpi() / ratio; updateDerived(); }
void QgsMapSettings::setMagnificationFactor( double factor ) { double ratio = mMagnificationFactor / factor; mMagnificationFactor = factor; double rot = rotation(); setRotation( 0.0 ); QgsRectangle ext = visibleExtent(); ext.scale( ratio ); mRotation = rot; mExtent = ext; mDpi = mDpi / ratio; QgsDebugMsg( QStringLiteral( "Magnification factor: %1 dpi: %2 ratio: %3" ).arg( factor ).arg( mDpi ).arg( ratio ) ); updateDerived(); }
void QgsComposerView::endMarqueeZoom( QMouseEvent* e ) { mMarqueeZoom = false; QRectF boundsRect; if ( !mRubberBandItem || ( mRubberBandItem->rect().width() < 0.1 && mRubberBandItem->rect().height() < 0.1 ) ) { //just a click, so zoom to clicked point and recenter double scaleFactor = 0.5; //get current visible part of scene QRect viewportRect( 0, 0, viewport()->width(), viewport()->height() ); QgsRectangle visibleRect = QgsRectangle( mapToScene( viewportRect ).boundingRect() ); //transform the mouse pos to scene coordinates QPointF scenePoint = mapToScene( e->pos() ); visibleRect.scale( scaleFactor, scenePoint.x(), scenePoint.y() ); boundsRect = visibleRect.toRectF(); } else { //marquee zoom //zoom bounds are size marquee object boundsRect = QRectF( mRubberBandItem->transform().dx(), mRubberBandItem->transform().dy(), mRubberBandItem->rect().width(), mRubberBandItem->rect().height() ); } removeRubberBand(); //zoom view to fit desired bounds fitInView( boundsRect, Qt::KeepAspectRatio ); if ( mTemporaryZoomStatus == QgsComposerView::ActiveUntilMouseRelease ) { //user was using the temporary keyboard activated zoom tool //and the control or space key was released before mouse button, so end temporary zoom mTemporaryZoomStatus = QgsComposerView::Inactive; setCurrentTool( mPreviousTool ); } }
void QgsMapToolPan::pinchTriggered( QPinchGesture* gesture ) { if ( gesture->state() == Qt::GestureFinished ) { //a very small totalScaleFactor indicates a two finger tap (pinch gesture without pinching) if ( 0.98 < gesture->totalScaleFactor() && gesture->totalScaleFactor() < 1.02 ) { mCanvas->zoomOut(); } else { //Transfor global coordinates to widget coordinates QPoint pos = gesture->centerPoint().toPoint(); pos = mCanvas->mapFromGlobal( pos ); // transform the mouse pos to map coordinates QgsPoint center = mCanvas->getCoordinateTransform()->toMapPoint( pos.x(), pos.y() ); QgsRectangle r = mCanvas->extent(); r.scale( 1 / gesture->totalScaleFactor(), ¢er ); mCanvas->setExtent( r ); mCanvas->refresh(); } mPinching = false; } }
void QgsComposerView::mouseReleaseEvent( QMouseEvent* e ) { if ( !composition() ) { return; } QPoint mousePressStopPoint = e->pos(); int diffX = mousePressStopPoint.x() - mMousePressStartPos.x(); int diffY = mousePressStopPoint.y() - mMousePressStartPos.y(); //was this just a click? or a click and drag? bool clickOnly = false; if ( qAbs( diffX ) < 2 && qAbs( diffY ) < 2 ) { clickOnly = true; } QPointF scenePoint = mapToScene( e->pos() ); if ( mPanning ) { mPanning = false; if ( clickOnly && e->button() == Qt::MidButton ) { //middle mouse button click = recenter on point //get current visible part of scene QRect viewportRect( 0, 0, viewport()->width(), viewport()->height() ); QgsRectangle visibleRect = QgsRectangle( mapToScene( viewportRect ).boundingRect() ); visibleRect.scale( 1, scenePoint.x(), scenePoint.y() ); QRectF boundsRect = visibleRect.toRectF(); //zoom view to fit desired bounds fitInView( boundsRect, Qt::KeepAspectRatio ); } //set new cursor if ( mCurrentTool == Pan ) { viewport()->setCursor( Qt::OpenHandCursor ); } else { if ( composition() ) { //allow composer items to change cursor composition()->setPreventCursorChange( false ); } viewport()->setCursor( Qt::ArrowCursor ); } } if ( mMarqueeSelect ) { endMarqueeSelect( e ); return; } switch ( mCurrentTool ) { case Select: { QGraphicsView::mouseReleaseEvent( e ); break; } case Zoom: { if ( mMarqueeZoom ) { endMarqueeZoom( e ); } break; } case MoveItemContent: { if ( mMoveContentItem ) { //update map preview if composer map QgsComposerMap* composerMap = dynamic_cast<QgsComposerMap *>( mMoveContentItem ); if ( composerMap ) { composerMap->setOffset( 0, 0 ); } double moveX = scenePoint.x() - mMoveContentStartPos.x(); double moveY = scenePoint.y() - mMoveContentStartPos.y(); composition()->beginCommand( mMoveContentItem, tr( "Move item content" ) ); mMoveContentItem->moveContent( -moveX, -moveY ); composition()->endCommand(); mMoveContentItem = 0; } break; } case AddArrow: if ( composition() ) { QPointF scenePoint = mapToScene( e->pos() ); QPointF snappedScenePoint = composition()->snapPointToGrid( scenePoint ); QgsComposerArrow* composerArrow = new QgsComposerArrow( mRubberBandStartPos, QPointF( snappedScenePoint.x(), snappedScenePoint.y() ), composition() ); composition()->addComposerArrow( composerArrow ); composition()->clearSelection(); composerArrow->setSelected( true ); emit selectedItemChanged( composerArrow ); scene()->removeItem( mRubberBandLineItem ); delete mRubberBandLineItem; mRubberBandLineItem = 0; emit actionFinished(); composition()->pushAddRemoveCommand( composerArrow, tr( "Arrow added" ) ); } break; case AddRectangle: case AddTriangle: case AddEllipse: addShape( mCurrentTool ); break; case AddMap: if ( !mRubberBandItem || ( mRubberBandItem->rect().width() < 0.1 && mRubberBandItem->rect().height() < 0.1 ) ) { removeRubberBand(); return; } if ( composition() ) { QgsComposerMap* composerMap = new QgsComposerMap( composition(), mRubberBandItem->transform().dx(), mRubberBandItem->transform().dy(), mRubberBandItem->rect().width(), mRubberBandItem->rect().height() ); composition()->addComposerMap( composerMap ); composition()->clearSelection(); composerMap->setSelected( true ); emit selectedItemChanged( composerMap ); removeRubberBand(); emit actionFinished(); composition()->pushAddRemoveCommand( composerMap, tr( "Map added" ) ); } break; case AddHtml: if ( composition() ) { QgsComposerHtml* composerHtml = new QgsComposerHtml( composition(), true ); QgsAddRemoveMultiFrameCommand* command = new QgsAddRemoveMultiFrameCommand( QgsAddRemoveMultiFrameCommand::Added, composerHtml, composition(), tr( "Html item added" ) ); composition()->undoStack()->push( command ); QgsComposerFrame* frame = new QgsComposerFrame( composition(), composerHtml, mRubberBandItem->transform().dx(), mRubberBandItem->transform().dy(), mRubberBandItem->rect().width(), mRubberBandItem->rect().height() ); composition()->beginMultiFrameCommand( composerHtml, tr( "Html frame added" ) ); composerHtml->addFrame( frame ); composition()->endMultiFrameCommand(); composition()->clearSelection(); frame->setSelected( true ); emit selectedItemChanged( frame ); removeRubberBand(); emit actionFinished(); } default: break; } }
void QgsComposerView::mousePressEvent( QMouseEvent* e ) { if ( !composition() ) { return; } QPointF scenePoint = mapToScene( e->pos() ); QPointF snappedScenePoint = composition()->snapPointToGrid( scenePoint ); mMousePressStartPos = e->pos(); //lock/unlock position of item with right click if ( e->button() == Qt::RightButton ) { QgsComposerItem* selectedItem = composition()->composerItemAt( scenePoint ); if ( selectedItem ) { bool lock = selectedItem->positionLock() ? false : true; selectedItem->setPositionLock( lock ); selectedItem->update(); } return; } else if ( e->button() == Qt::MidButton ) { //pan composer with middle button mPanning = true; mMouseLastXY = e->pos(); if ( composition() ) { //lock cursor to closed hand cursor composition()->setPreventCursorChange( true ); } viewport()->setCursor( Qt::ClosedHandCursor ); return; } switch ( mCurrentTool ) { //select/deselect items and pass mouse event further case Select: { //check if we are clicking on a selection handle if ( composition()->selectionHandles()->isVisible() ) { //selection handles are being shown, get mouse action for current cursor position QgsComposerMouseHandles::MouseAction mouseAction = composition()->selectionHandles()->mouseActionForScenePos( scenePoint ); if ( mouseAction != QgsComposerMouseHandles::MoveItem && mouseAction != QgsComposerMouseHandles::NoAction && mouseAction != QgsComposerMouseHandles::SelectItem ) { //mouse is over a resize handle, so propagate event onward QGraphicsView::mousePressEvent( e ); return; } } QgsComposerItem* selectedItem = 0; QgsComposerItem* previousSelectedItem = 0; if ( e->modifiers() & Qt::ControlModifier ) { //CTRL modifier, so we are trying to select the next item below the current one //first, find currently selected item QList<QgsComposerItem*> selectedItems = composition()->selectedComposerItems(); if ( selectedItems.size() > 0 ) { previousSelectedItem = selectedItems.at( 0 ); } } if ( previousSelectedItem ) { //select highest item just below previously selected item at position of event selectedItem = composition()->composerItemAt( scenePoint, previousSelectedItem ); //if we didn't find a lower item we'll use the top-most as fall-back //this duplicates mapinfo/illustrator/etc behaviour where ctrl-clicks are "cyclic" if ( !selectedItem ) { selectedItem = composition()->composerItemAt( scenePoint ); } } else { //select topmost item at position of event selectedItem = composition()->composerItemAt( scenePoint ); } if ( !selectedItem ) { //not clicking over an item, so start marquee selection startMarqueeSelect( scenePoint ); break; } if (( !selectedItem->selected() ) && //keep selection if an already selected item pressed !( e->modifiers() & Qt::ShiftModifier ) ) //keep selection if shift key pressed { composition()->clearSelection(); } if (( e->modifiers() & Qt::ShiftModifier ) && ( selectedItem->selected() ) ) { //SHIFT-clicking a selected item deselects it selectedItem->setSelected( false ); //Check if we have any remaining selected items, and if so, update the item panel QList<QgsComposerItem*> selectedItems = composition()->selectedComposerItems(); if ( selectedItems.size() > 0 ) { emit selectedItemChanged( selectedItems.at( 0 ) ); } } else { selectedItem->setSelected( true ); QGraphicsView::mousePressEvent( e ); emit selectedItemChanged( selectedItem ); } break; } case Zoom: { if ( !( e->modifiers() & Qt::ShiftModifier ) ) { //zoom in action startMarqueeZoom( scenePoint ); } else { //zoom out action, so zoom out and recenter on clicked point double scaleFactor = 2; //get current visible part of scene QRect viewportRect( 0, 0, viewport()->width(), viewport()->height() ); QgsRectangle visibleRect = QgsRectangle( mapToScene( viewportRect ).boundingRect() ); //transform the mouse pos to scene coordinates QPointF scenePoint = mapToScene( e->pos() ); visibleRect.scale( scaleFactor, scenePoint.x(), scenePoint.y() ); QRectF boundsRect = visibleRect.toRectF(); //zoom view to fit desired bounds fitInView( boundsRect, Qt::KeepAspectRatio ); } break; } case Pan: { //pan action mPanning = true; mMouseLastXY = e->pos(); viewport()->setCursor( Qt::ClosedHandCursor ); break; } case MoveItemContent: { //get a list of items at clicked position QList<QGraphicsItem *> itemsAtCursorPos = items( e->pos() ); if ( itemsAtCursorPos.size() == 0 ) { //no items at clicked position return; } //find highest QgsComposerItem at clicked position //(other graphics items may be higher, eg selection handles) QList<QGraphicsItem*>::iterator itemIter = itemsAtCursorPos.begin(); for ( ; itemIter != itemsAtCursorPos.end(); ++itemIter ) { QgsComposerItem* item = dynamic_cast<QgsComposerItem *>(( *itemIter ) ); if ( item ) { //we've found the highest QgsComposerItem mMoveContentStartPos = scenePoint; mMoveContentItem = item; break; } } //no QgsComposerItem at clicked position return; } case AddArrow: { mRubberBandStartPos = QPointF( snappedScenePoint.x(), snappedScenePoint.y() ); mRubberBandLineItem = new QGraphicsLineItem( snappedScenePoint.x(), snappedScenePoint.y(), snappedScenePoint.x(), snappedScenePoint.y() ); mRubberBandLineItem->setZValue( 1000 ); scene()->addItem( mRubberBandLineItem ); scene()->update(); break; } //create rubber band for map and ellipse items case AddMap: case AddRectangle: case AddTriangle: case AddEllipse: case AddHtml: { QTransform t; mRubberBandItem = new QGraphicsRectItem( 0, 0, 0, 0 ); mRubberBandStartPos = QPointF( snappedScenePoint.x(), snappedScenePoint.y() ); t.translate( snappedScenePoint.x(), snappedScenePoint.y() ); mRubberBandItem->setTransform( t ); mRubberBandItem->setZValue( 1000 ); scene()->addItem( mRubberBandItem ); scene()->update(); } break; case AddLabel: if ( composition() ) { QgsComposerLabel* newLabelItem = new QgsComposerLabel( composition() ); newLabelItem->setText( tr( "QGIS" ) ); newLabelItem->adjustSizeToText(); newLabelItem->setSceneRect( QRectF( snappedScenePoint.x(), snappedScenePoint.y(), newLabelItem->rect().width(), newLabelItem->rect().height() ) ); composition()->addComposerLabel( newLabelItem ); composition()->clearSelection(); newLabelItem->setSelected( true ); emit selectedItemChanged( newLabelItem ); emit actionFinished(); composition()->pushAddRemoveCommand( newLabelItem, tr( "Label added" ) ); } break; case AddScalebar: if ( composition() ) { QgsComposerScaleBar* newScaleBar = new QgsComposerScaleBar( composition() ); newScaleBar->setSceneRect( QRectF( snappedScenePoint.x(), snappedScenePoint.y(), 20, 20 ) ); composition()->addComposerScaleBar( newScaleBar ); QList<const QgsComposerMap*> mapItemList = composition()->composerMapItems(); if ( mapItemList.size() > 0 ) { newScaleBar->setComposerMap( mapItemList.at( 0 ) ); } newScaleBar->applyDefaultSize(); //4 segments, 1/5 of composer map width composition()->clearSelection(); newScaleBar->setSelected( true ); emit selectedItemChanged( newScaleBar ); emit actionFinished(); composition()->pushAddRemoveCommand( newScaleBar, tr( "Scale bar added" ) ); } break; case AddLegend: { if ( composition() ) { QgsComposerLegend* newLegend = new QgsComposerLegend( composition() ); newLegend->setSceneRect( QRectF( snappedScenePoint.x(), snappedScenePoint.y(), newLegend->rect().width(), newLegend->rect().height() ) ); composition()->addComposerLegend( newLegend ); newLegend->updateLegend(); composition()->clearSelection(); newLegend->setSelected( true ); emit selectedItemChanged( newLegend ); emit actionFinished(); composition()->pushAddRemoveCommand( newLegend, tr( "Legend added" ) ); } break; } case AddPicture: if ( composition() ) { QgsComposerPicture* newPicture = new QgsComposerPicture( composition() ); newPicture->setSceneRect( QRectF( snappedScenePoint.x(), snappedScenePoint.y(), 30, 30 ) ); composition()->addComposerPicture( newPicture ); composition()->clearSelection(); newPicture->setSelected( true ); emit selectedItemChanged( newPicture ); emit actionFinished(); composition()->pushAddRemoveCommand( newPicture, tr( "Picture added" ) ); } break; case AddTable: if ( composition() ) { QgsComposerAttributeTable* newTable = new QgsComposerAttributeTable( composition() ); newTable->setSceneRect( QRectF( snappedScenePoint.x(), snappedScenePoint.y(), 50, 50 ) ); composition()->addComposerTable( newTable ); composition()->clearSelection(); newTable->setSelected( true ); emit selectedItemChanged( newTable ); emit actionFinished(); composition()->pushAddRemoveCommand( newTable, tr( "Table added" ) ); } break; default: break; } }
void QgsAtlasComposition::prepareMap( QgsComposerMap* map ) { if ( !map->atlasDriven() || mCoverageLayer->wkbType() == QgsWkbTypes::NoGeometry ) { return; } if ( mTransformedFeatureBounds.isEmpty() ) { //transformed extent of current feature hasn't been calculated yet. This can happen if //a map has been set to be atlas controlled after prepare feature was called computeExtent( map ); } double xa1 = mTransformedFeatureBounds.xMinimum(); double xa2 = mTransformedFeatureBounds.xMaximum(); double ya1 = mTransformedFeatureBounds.yMinimum(); double ya2 = mTransformedFeatureBounds.yMaximum(); QgsRectangle newExtent = mTransformedFeatureBounds; QgsRectangle mOrigExtent( map->extent() ); //sanity check - only allow fixed scale mode for point layers bool isPointLayer = false; switch ( mCoverageLayer->wkbType() ) { case QgsWkbTypes::Point: case QgsWkbTypes::Point25D: case QgsWkbTypes::MultiPoint: case QgsWkbTypes::MultiPoint25D: isPointLayer = true; break; default: isPointLayer = false; break; } if ( map->atlasScalingMode() == QgsComposerMap::Fixed || map->atlasScalingMode() == QgsComposerMap::Predefined || isPointLayer ) { QgsScaleCalculator calc; calc.setMapUnits( composition()->mapSettings().mapUnits() ); calc.setDpi( 25.4 ); double originalScale = calc.calculate( mOrigExtent, map->rect().width() ); double geomCenterX = ( xa1 + xa2 ) / 2.0; double geomCenterY = ( ya1 + ya2 ) / 2.0; if ( map->atlasScalingMode() == QgsComposerMap::Fixed || isPointLayer ) { // only translate, keep the original scale (i.e. width x height) double xMin = geomCenterX - mOrigExtent.width() / 2.0; double yMin = geomCenterY - mOrigExtent.height() / 2.0; newExtent = QgsRectangle( xMin, yMin, xMin + mOrigExtent.width(), yMin + mOrigExtent.height() ); //scale newExtent to match original scale of map //this is required for geographic coordinate systems, where the scale varies by extent double newScale = calc.calculate( newExtent, map->rect().width() ); newExtent.scale( originalScale / newScale ); } else if ( map->atlasScalingMode() == QgsComposerMap::Predefined ) { // choose one of the predefined scales double newWidth = mOrigExtent.width(); double newHeight = mOrigExtent.height(); const QVector<qreal>& scales = mPredefinedScales; for ( int i = 0; i < scales.size(); i++ ) { double ratio = scales[i] / originalScale; newWidth = mOrigExtent.width() * ratio; newHeight = mOrigExtent.height() * ratio; // compute new extent, centered on feature double xMin = geomCenterX - newWidth / 2.0; double yMin = geomCenterY - newHeight / 2.0; newExtent = QgsRectangle( xMin, yMin, xMin + newWidth, yMin + newHeight ); //scale newExtent to match desired map scale //this is required for geographic coordinate systems, where the scale varies by extent double newScale = calc.calculate( newExtent, map->rect().width() ); newExtent.scale( scales[i] / newScale ); if (( newExtent.width() >= mTransformedFeatureBounds.width() ) && ( newExtent.height() >= mTransformedFeatureBounds.height() ) ) { // this is the smallest extent that embeds the feature, stop here break; } } } } else if ( map->atlasScalingMode() == QgsComposerMap::Auto ) { // auto scale double geomRatio = mTransformedFeatureBounds.width() / mTransformedFeatureBounds.height(); double mapRatio = mOrigExtent.width() / mOrigExtent.height(); // geometry height is too big if ( geomRatio < mapRatio ) { // extent the bbox's width double adjWidth = ( mapRatio * mTransformedFeatureBounds.height() - mTransformedFeatureBounds.width() ) / 2.0; xa1 -= adjWidth; xa2 += adjWidth; } // geometry width is too big else if ( geomRatio > mapRatio ) { // extent the bbox's height double adjHeight = ( mTransformedFeatureBounds.width() / mapRatio - mTransformedFeatureBounds.height() ) / 2.0; ya1 -= adjHeight; ya2 += adjHeight; } newExtent = QgsRectangle( xa1, ya1, xa2, ya2 ); if ( map->atlasMargin() > 0.0 ) { newExtent.scale( 1 + map->atlasMargin() ); } } // set the new extent (and render) map->setNewAtlasFeatureExtent( newExtent ); }
void checkDock::errorListClicked(const QModelIndex& index) { int row = index.row(); QgsRectangle r = mErrorList[row]->boundingBox(); r.scale(1.5); mQgisApp->mapCanvas()->setExtent(r); mQgisApp->mapCanvas()->refresh(); mFixBox->clear(); mFixBox->addItems(mErrorList[row]->fixNames()); mFixBox->setCurrentIndex(mFixBox->findText("Select automatic fix")); QgsFeature f; QgsGeometry* g; FeatureLayer fl = mErrorList[row]->featurePairs().first(); if (!fl.layer) { std::cout << "invalid layer 1\n"; return; } fl.layer->featureAtId(fl.feature.id(), f, true, false); g = f.geometry(); if (!g) { std::cout << "invalid geometry 1\n"<<std::flush; QMessageBox::information(this, "Topology test", "Feature not found in the layer.\nThe layer has probably changed.\nRun topology check again."); return; } clearVertexMarkers(); // use vertex marker when highlighting a point // and rubber band otherwise if (g->type() == QGis::Point) { mVMFeature1 = new QgsVertexMarker(mQgisApp->mapCanvas()); mVMFeature1->setIconType(QgsVertexMarker::ICON_BOX); mVMConflict->setPenWidth(5); mVMFeature1->setIconSize(5); mVMFeature1->setColor("blue"); mVMFeature1->setCenter(g->asPoint()); } else mRBFeature1->setToGeometry(g, fl.layer); fl = mErrorList[row]->featurePairs()[1]; if (!fl.layer) { std::cout << "invalid layer 2\n"; return; } fl.layer->featureAtId(fl.feature.id(), f, true, false); g = f.geometry(); if (!g) { std::cout << "invalid geometry 2\n" << std::flush; QMessageBox::information(this, "Topology test", "Feature not found in the layer.\nThe layer has probably changed.\nRun topology check again."); return; } if (g->type() == QGis::Point) { mVMFeature2 = new QgsVertexMarker(mQgisApp->mapCanvas()); mVMFeature2->setIconType(QgsVertexMarker::ICON_BOX); mVMConflict->setPenWidth(5); mVMConflict->setIconSize(5); mVMFeature2->setColor("red"); mVMFeature2->setCenter(g->asPoint()); } else mRBFeature2->setToGeometry(g, fl.layer); if (!mErrorList[row]->conflict()) { std::cout << "invalid conflict\n" << std::flush; return; } if (mErrorList[row]->conflict()->type() == QGis::Point) { mVMConflict = new QgsVertexMarker(mQgisApp->mapCanvas()); mVMConflict->setIconType(QgsVertexMarker::ICON_BOX); mVMConflict->setPenWidth(5); mVMConflict->setIconSize(5); mVMConflict->setColor("gold"); mVMConflict->setCenter(mErrorList[row]->conflict()->asPoint()); } else mRBConflict->setToGeometry(mErrorList[row]->conflict(), fl.layer); }
void checkDock::errorListClicked( const QModelIndex& index ) { int row = index.row(); QgsRectangle r = mErrorList[row]->boundingBox(); r.scale( 1.5 ); QgsMapCanvas* canvas = qgsInterface->mapCanvas(); canvas->setExtent( r ); canvas->refresh(); mFixBox->clear(); mFixBox->addItems( mErrorList[row]->fixNames() ); mFixBox->setCurrentIndex( mFixBox->findText( tr( "Select automatic fix" ) ) ); QgsFeature f; QgsGeometry* g; FeatureLayer fl = mErrorList[row]->featurePairs().first(); if ( !fl.layer ) { QgsMessageLog::logMessage( tr( "Invalid first layer" ), tr( "Topology plugin" ) ); return; } //fl1.layer->getFeatures( QgsFeatureRequest().setFilterFid( fl1.feature.id() ) ).nextFeature( f1 ); fl.layer->getFeatures( QgsFeatureRequest().setFilterFid( fl.feature.id() ) ).nextFeature( f ); g = f.geometry(); if ( !g ) { QgsMessageLog::logMessage( tr( "Invalid first geometry" ), tr( "Topology plugin" ) ); QMessageBox::information( this, tr( "Topology test" ), tr( "Feature not found in the layer.\nThe layer has probably changed.\nRun topology check again." ) ); return; } clearVertexMarkers(); // use vertex marker when highlighting a point // and rubber band otherwise if ( g->type() == QGis::Point ) { mVMFeature1 = new QgsVertexMarker( canvas ); mVMFeature1->setIconType( QgsVertexMarker::ICON_X ); mVMFeature1->setPenWidth( 5 ); mVMFeature1->setIconSize( 5 ); mVMFeature1->setColor( "blue" ); mVMFeature1->setCenter( g->asPoint() ); } else mRBFeature1->setToGeometry( g, fl.layer ); fl = mErrorList[row]->featurePairs()[1]; if ( !fl.layer ) { QgsMessageLog::logMessage( tr( "Invalid second layer" ), tr( "Topology plugin" ) ); return; } fl.layer->getFeatures( QgsFeatureRequest().setFilterFid( fl.feature.id() ) ).nextFeature( f ); g = f.geometry(); if ( !g ) { QgsMessageLog::logMessage( tr( "Invalid second geometry" ), tr( "Topology plugin" ) ); QMessageBox::information( this, tr( "Topology test" ), tr( "Feature not found in the layer.\nThe layer has probably changed.\nRun topology check again." ) ); return; } if ( g->type() == QGis::Point ) { mVMFeature2 = new QgsVertexMarker( canvas ); mVMFeature2->setIconType( QgsVertexMarker::ICON_BOX ); mVMFeature2->setPenWidth( 5 ); mVMFeature2->setIconSize( 5 ); mVMFeature2->setColor( "green" ); mVMFeature2->setCenter( g->asPoint() ); } else mRBFeature2->setToGeometry( g, fl.layer ); if ( !mErrorList[row]->conflict() ) { QgsMessageLog::logMessage( tr( "Invalid conflict" ), tr( "Topology plugin" ) ); return; } if ( mErrorList[row]->conflict()->type() == QGis::Point ) { mVMConflict = new QgsVertexMarker( canvas ); mVMConflict->setIconType( QgsVertexMarker::ICON_BOX ); mVMConflict->setPenWidth( 5 ); mVMConflict->setIconSize( 5 ); mVMConflict->setColor( "red" ); mVMConflict->setCenter( mErrorList[row]->conflict()->asPoint() ); } else mRBConflict->setToGeometry( mErrorList[row]->conflict(), fl.layer ); }
void QgsComposerView::wheelZoom( QWheelEvent * event ) { //get mouse wheel zoom behaviour settings QSettings mySettings; int wheelAction = mySettings.value( "/qgis/wheel_action", 2 ).toInt(); double zoomFactor = mySettings.value( "/qgis/zoom_factor", 2 ).toDouble(); //caculate zoom scale factor bool zoomIn = event->delta() > 0; double scaleFactor = ( zoomIn ? 1 / zoomFactor : zoomFactor ); //get current visible part of scene QRect viewportRect( 0, 0, viewport()->width(), viewport()->height() ); QgsRectangle visibleRect = QgsRectangle( mapToScene( viewportRect ).boundingRect() ); //transform the mouse pos to scene coordinates QPointF scenePoint = mapToScene( event->pos() ); //zoom composition, respecting wheel action setting switch (( QgsMapCanvas::WheelAction )wheelAction ) { case QgsMapCanvas::WheelZoom: // zoom without changing extent if ( zoomIn ) { scale( zoomFactor, zoomFactor ); } else { scale( 1 / zoomFactor, 1 / zoomFactor ); } break; case QgsMapCanvas::WheelZoomAndRecenter: { visibleRect.scale( scaleFactor, scenePoint.x(), scenePoint.y() ); fitInView( visibleRect.toRectF(), Qt::KeepAspectRatio ); break; } case QgsMapCanvas::WheelZoomToMouseCursor: { QgsPoint oldCenter( visibleRect.center() ); QgsPoint newCenter( scenePoint.x() + (( oldCenter.x() - scenePoint.x() ) * scaleFactor ), scenePoint.y() + (( oldCenter.y() - scenePoint.y() ) * scaleFactor ) ); visibleRect.scale( scaleFactor, newCenter.x(), newCenter.y() ); fitInView( visibleRect.toRectF(), Qt::KeepAspectRatio ); break; } case QgsMapCanvas::WheelNothing: return; } //update composition for new zoom updateRulers(); update(); //redraw cached map items QList<QGraphicsItem *> itemList = composition()->items(); QList<QGraphicsItem *>::iterator itemIt = itemList.begin(); for ( ; itemIt != itemList.end(); ++itemIt ) { QgsComposerMap* mypItem = dynamic_cast<QgsComposerMap *>( *itemIt ); if (( mypItem ) && ( mypItem->previewMode() == QgsComposerMap::Render ) ) { mypItem->updateCachedImage(); } } }
void QgsComposerView::mouseReleaseEvent( QMouseEvent* e ) { if ( !composition() ) { return; } if ( e->button() != Qt::LeftButton && ( composition()->selectionHandles()->isDragging() || composition()->selectionHandles()->isResizing() ) ) { //ignore clicks while dragging/resizing items return; } QPoint mousePressStopPoint = e->pos(); int diffX = mousePressStopPoint.x() - mMousePressStartPos.x(); int diffY = mousePressStopPoint.y() - mMousePressStartPos.y(); //was this just a click? or a click and drag? bool clickOnly = false; if ( qAbs( diffX ) < 2 && qAbs( diffY ) < 2 ) { clickOnly = true; } QPointF scenePoint = mapToScene( e->pos() ); if ( mMousePanning || mToolPanning ) { mMousePanning = false; mToolPanning = false; if ( clickOnly && e->button() == Qt::MidButton ) { //middle mouse button click = recenter on point //get current visible part of scene QRect viewportRect( 0, 0, viewport()->width(), viewport()->height() ); QgsRectangle visibleRect = QgsRectangle( mapToScene( viewportRect ).boundingRect() ); visibleRect.scale( 1, scenePoint.x(), scenePoint.y() ); QRectF boundsRect = visibleRect.toRectF(); //zoom view to fit desired bounds fitInView( boundsRect, Qt::KeepAspectRatio ); } //set new cursor if ( mCurrentTool != Pan ) { if ( composition() ) { //allow composer items to change cursor composition()->setPreventCursorChange( false ); } } viewport()->setCursor( defaultCursorForTool( mCurrentTool ) ); } //for every other tool, ignore clicks of non-left button if ( e->button() != Qt::LeftButton ) { return; } if ( mMarqueeSelect ) { endMarqueeSelect( e ); return; } switch ( mCurrentTool ) { case Select: { QGraphicsView::mouseReleaseEvent( e ); break; } case Zoom: { if ( mMarqueeZoom ) { endMarqueeZoom( e ); } break; } case MoveItemContent: { if ( mMoveContentItem ) { //update map preview if composer map QgsComposerMap* composerMap = dynamic_cast<QgsComposerMap *>( mMoveContentItem ); if ( composerMap ) { composerMap->setOffset( 0, 0 ); } double moveX = scenePoint.x() - mMoveContentStartPos.x(); double moveY = scenePoint.y() - mMoveContentStartPos.y(); composition()->beginCommand( mMoveContentItem, tr( "Move item content" ) ); mMoveContentItem->moveContent( -moveX, -moveY ); composition()->endCommand(); mMoveContentItem = 0; mMovingItemContent = false; } break; } case AddArrow: if ( !composition() || !mRubberBandLineItem ) { scene()->removeItem( mRubberBandLineItem ); delete mRubberBandLineItem; mRubberBandLineItem = 0; return; } else { QgsComposerArrow* composerArrow = new QgsComposerArrow( mRubberBandLineItem->line().p1(), mRubberBandLineItem->line().p2(), composition() ); composition()->addComposerArrow( composerArrow ); composition()->clearSelection(); composerArrow->setSelected( true ); emit selectedItemChanged( composerArrow ); scene()->removeItem( mRubberBandLineItem ); delete mRubberBandLineItem; mRubberBandLineItem = 0; emit actionFinished(); composition()->pushAddRemoveCommand( composerArrow, tr( "Arrow added" ) ); } break; case AddRectangle: case AddTriangle: case AddEllipse: addShape( mCurrentTool ); break; case AddMap: if ( !composition() || !mRubberBandItem || ( mRubberBandItem->rect().width() < 0.1 && mRubberBandItem->rect().height() < 0.1 ) ) { removeRubberBand(); return; } else { QgsComposerMap* composerMap = new QgsComposerMap( composition(), mRubberBandItem->transform().dx(), mRubberBandItem->transform().dy(), mRubberBandItem->rect().width(), mRubberBandItem->rect().height() ); composition()->addComposerMap( composerMap ); composition()->clearSelection(); composerMap->setSelected( true ); emit selectedItemChanged( composerMap ); removeRubberBand(); emit actionFinished(); composition()->pushAddRemoveCommand( composerMap, tr( "Map added" ) ); } break; case AddPicture: if ( !composition() || !mRubberBandItem || ( mRubberBandItem->rect().width() < 0.1 && mRubberBandItem->rect().height() < 0.1 ) ) { removeRubberBand(); return; } else { QgsComposerPicture* newPicture = new QgsComposerPicture( composition() ); newPicture->setSceneRect( QRectF( mRubberBandItem->transform().dx(), mRubberBandItem->transform().dy(), mRubberBandItem->rect().width(), mRubberBandItem->rect().height() ) ); composition()->addComposerPicture( newPicture ); composition()->clearSelection(); newPicture->setSelected( true ); emit selectedItemChanged( newPicture ); removeRubberBand(); emit actionFinished(); composition()->pushAddRemoveCommand( newPicture, tr( "Picture added" ) ); } break; case AddLabel: if ( !composition() || !mRubberBandItem ) { removeRubberBand(); return; } else { QgsComposerLabel* newLabelItem = new QgsComposerLabel( composition() ); newLabelItem->setText( tr( "QGIS" ) ); newLabelItem->adjustSizeToText(); //make sure label size is sufficient to fit text double labelWidth = qMax( mRubberBandItem->rect().width(), newLabelItem->rect().width() ); double labelHeight = qMax( mRubberBandItem->rect().height(), newLabelItem->rect().height() ); newLabelItem->setSceneRect( QRectF( mRubberBandItem->transform().dx(), mRubberBandItem->transform().dy(), labelWidth, labelHeight ) ); composition()->addComposerLabel( newLabelItem ); composition()->clearSelection(); newLabelItem->setSelected( true ); emit selectedItemChanged( newLabelItem ); removeRubberBand(); emit actionFinished(); composition()->pushAddRemoveCommand( newLabelItem, tr( "Label added" ) ); } break; case AddLegend: if ( !composition() || !mRubberBandItem ) { removeRubberBand(); return; } else { QgsComposerLegend* newLegend = new QgsComposerLegend( composition() ); newLegend->setSceneRect( QRectF( mRubberBandItem->transform().dx(), mRubberBandItem->transform().dy(), mRubberBandItem->rect().width(), mRubberBandItem->rect().height() ) ); composition()->addComposerLegend( newLegend ); newLegend->updateLegend(); composition()->clearSelection(); newLegend->setSelected( true ); emit selectedItemChanged( newLegend ); removeRubberBand(); emit actionFinished(); composition()->pushAddRemoveCommand( newLegend, tr( "Legend added" ) ); } break; case AddTable: if ( !composition() || !mRubberBandItem ) { removeRubberBand(); return; } else { QgsComposerAttributeTable* newTable = new QgsComposerAttributeTable( composition() ); newTable->setSceneRect( QRectF( mRubberBandItem->transform().dx(), mRubberBandItem->transform().dy(), mRubberBandItem->rect().width(), qMax( mRubberBandItem->rect().height(), 15.0 ) ) ); QList<const QgsComposerMap*> mapItemList = composition()->composerMapItems(); if ( mapItemList.size() > 0 ) { newTable->setComposerMap( mapItemList.at( 0 ) ); } composition()->addComposerTable( newTable ); composition()->clearSelection(); newTable->setSelected( true ); emit selectedItemChanged( newTable ); removeRubberBand(); emit actionFinished(); composition()->pushAddRemoveCommand( newTable, tr( "Table added" ) ); } break; case AddHtml: if ( !composition() || !mRubberBandItem || ( mRubberBandItem->rect().width() < 0.1 && mRubberBandItem->rect().height() < 0.1 ) ) { removeRubberBand(); return; } else { QgsComposerHtml* composerHtml = new QgsComposerHtml( composition(), true ); QgsAddRemoveMultiFrameCommand* command = new QgsAddRemoveMultiFrameCommand( QgsAddRemoveMultiFrameCommand::Added, composerHtml, composition(), tr( "Html item added" ) ); composition()->undoStack()->push( command ); QgsComposerFrame* frame = new QgsComposerFrame( composition(), composerHtml, mRubberBandItem->transform().dx(), mRubberBandItem->transform().dy(), mRubberBandItem->rect().width(), mRubberBandItem->rect().height() ); composition()->beginMultiFrameCommand( composerHtml, tr( "Html frame added" ) ); composerHtml->addFrame( frame ); composition()->endMultiFrameCommand(); composition()->clearSelection(); frame->setSelected( true ); emit selectedItemChanged( frame ); removeRubberBand(); emit actionFinished(); } default: break; } }