void testSnapModeAll() { QgsMapSettings mapSettings; mapSettings.setOutputSize( QSize( 100, 100 ) ); mapSettings.setExtent( QgsRectangle( 0, 0, 1, 1 ) ); QVERIFY( mapSettings.hasValidSettings() ); QgsSnappingUtils u; QgsSnappingConfig snappingConfig = u.config(); u.setMapSettings( mapSettings ); snappingConfig.setMode( QgsSnappingConfig::AllLayers ); u.setConfig( snappingConfig ); // right now there are no layers in map settings - snapping will fail QgsPointLocator::Match m = u.snapToMap( QPoint( 100, 100 ) ); QVERIFY( !m.isValid() ); // now check with our layer mapSettings.setLayers( QStringList() << mVL->id() ); u.setMapSettings( mapSettings ); QgsPointLocator::Match m2 = u.snapToMap( QPoint( 100, 100 ) ); QVERIFY( m2.isValid() ); QCOMPARE( m2.point(), QgsPoint( 1, 0 ) ); }
void testSnapOnIntersection() { // testing with a layer with two crossing linestrings // (0,1) x x (1,1) // \/ // /\ . // (0,0) x x (1,0) QgsVectorLayer* vl = new QgsVectorLayer( QStringLiteral( "LineString" ), QStringLiteral( "x" ), QStringLiteral( "memory" ) ); QgsPolyline polyline1, polyline2; polyline1 << QgsPoint( 0, 0 ) << QgsPoint( 1, 1 ); polyline2 << QgsPoint( 1, 0 ) << QgsPoint( 0, 1 ); QgsFeature f1; QgsGeometry f1g = QgsGeometry::fromPolyline( polyline1 ) ; f1.setGeometry( f1g ); QgsFeature f2; QgsGeometry f2g = QgsGeometry::fromPolyline( polyline2 ); f2.setGeometry( f2g ); QgsFeatureList flist; flist << f1 << f2; vl->dataProvider()->addFeatures( flist ); QVERIFY( vl->dataProvider()->featureCount() == 2 ); QgsMapSettings mapSettings; mapSettings.setOutputSize( QSize( 100, 100 ) ); mapSettings.setExtent( QgsRectangle( 0, 0, 1, 1 ) ); QVERIFY( mapSettings.hasValidSettings() ); QgsSnappingUtils u; u.setMapSettings( mapSettings ); QgsSnappingConfig snappingConfig = u.config(); snappingConfig.setMode( QgsSnappingConfig::AdvancedConfiguration ); QgsSnappingConfig::IndividualLayerSettings layerSettings( true, QgsSnappingConfig::Vertex, 0.1, QgsTolerance::ProjectUnits ); snappingConfig.setIndividualLayerSettings( vl, layerSettings ); u.setConfig( snappingConfig ); // no snapping on intersections by default - should find nothing QgsPointLocator::Match m = u.snapToMap( QgsPoint( 0.45, 0.5 ) ); QVERIFY( !m.isValid() ); snappingConfig.setIntersectionSnapping( true ); u.setConfig( snappingConfig ); QgsPointLocator::Match m2 = u.snapToMap( QgsPoint( 0.45, 0.5 ) ); QVERIFY( m2.isValid() ); QCOMPARE( m2.type(), QgsPointLocator::Vertex ); QCOMPARE( m2.point(), QgsPoint( 0.5, 0.5 ) ); delete vl; }
void testSnapModeCurrent() { QgsMapSettings mapSettings; mapSettings.setOutputSize( QSize( 100, 100 ) ); mapSettings.setExtent( QgsRectangle( 0, 0, 1, 1 ) ); QVERIFY( mapSettings.hasValidSettings() ); QgsSnappingUtils u; u.setMapSettings( mapSettings ); u.setCurrentLayer( mVL ); // first try with no snapping enabled QgsSnappingConfig snappingConfig = u.config(); snappingConfig.setEnabled( false ); snappingConfig.setTolerance( 10 ); snappingConfig.setUnits( QgsTolerance::Pixels ); snappingConfig.setMode( QgsSnappingConfig::ActiveLayer ); u.setConfig( snappingConfig ); QgsPointLocator::Match m0 = u.snapToMap( QPoint( 100, 100 ) ); QVERIFY( !m0.isValid() ); QVERIFY( !m0.hasVertex() ); // now enable snapping snappingConfig.setEnabled( true ); snappingConfig.setType( QgsSnappingConfig::Vertex ); u.setConfig( snappingConfig ); QgsPointLocator::Match m = u.snapToMap( QPoint( 100, 100 ) ); QVERIFY( m.isValid() ); QVERIFY( m.hasVertex() ); QCOMPARE( m.point(), QgsPoint( 1, 0 ) ); QgsPointLocator::Match m2 = u.snapToMap( QPoint( 0, 100 ) ); QVERIFY( !m2.isValid() ); QVERIFY( !m2.hasVertex() ); // do not consider edges in the following test - on 32-bit platforms // result was an edge match very close to (1,0) instead of being exactly (1,0) snappingConfig.setType( QgsSnappingConfig::Vertex ); u.setConfig( snappingConfig ); // test with filtering FilterExcludePoint myFilter( QgsPoint( 1, 0 ) ); QgsPointLocator::Match m3 = u.snapToMap( QPoint( 100, 100 ), &myFilter ); QVERIFY( !m3.isValid() ); }
QgsMapSettings QgsGlobeTileImage::createSettings( int dpi, const QList<QgsMapLayer *> &layers ) const { QgsMapSettings settings; settings.setBackgroundColor( QColor( Qt::transparent ) ); settings.setDestinationCrs( QgsCoordinateReferenceSystem::fromOgcWmsCrs( GEO_EPSG_CRS_AUTHID ) ); settings.setExtent( mTileExtent ); settings.setLayers( layers ); settings.setFlag( QgsMapSettings::DrawEditingInfo, false ); settings.setFlag( QgsMapSettings::DrawLabeling, false ); settings.setFlag( QgsMapSettings::DrawSelection, false ); settings.setOutputSize( QSize( mTileSize, mTileSize ) ); settings.setOutputImageFormat( QImage::Format_ARGB32_Premultiplied ); settings.setOutputDpi( dpi ); settings.setCustomRenderFlags( "globe" ); return settings; }
void QgsMeshCalcUtils::updateMesh() const { if ( ! mMeshLayer->nativeMesh() ) { // we do not care about triangles, // we just want transformed coordinates // of the native mesh. So create // some dummy triangular mesh. QgsMapSettings mapSettings; mapSettings.setExtent( mMeshLayer->extent() ); mapSettings.setDestinationCrs( mMeshLayer->crs() ); mapSettings.setOutputDpi( 96 ); QgsRenderContext context = QgsRenderContext::fromMapSettings( mapSettings ); mMeshLayer->createMapRenderer( context ); } }
void QgsComposerLegend::paint( QPainter* painter, const QStyleOptionGraphicsItem* itemStyle, QWidget* pWidget ) { Q_UNUSED( itemStyle ); Q_UNUSED( pWidget ); if ( !painter ) return; int dpi = painter->device()->logicalDpiX(); double dotsPerMM = dpi / 25.4; if ( mComposition ) { mSettings.setUseAdvancedEffects( mComposition->useAdvancedEffects() ); mSettings.setDpi( dpi ); } if ( mComposerMap ) { mSettings.setMmPerMapUnit( mComposerMap->mapUnitsToMM() ); // use a temporary QgsMapSettings to find out real map scale QgsMapSettings ms = mComposerMap->composition()->mapSettings(); ms.setOutputSize( QSizeF( mComposerMap->rect().width() * dotsPerMM, mComposerMap->rect().height() * dotsPerMM ).toSize() ); ms.setExtent( *mComposerMap->currentMapExtent() ); ms.setOutputDpi( dpi ); mSettings.setMapScale( ms.scale() ); } drawBackground( painter ); painter->save(); //antialiasing on painter->setRenderHint( QPainter::Antialiasing, true ); painter->setPen( QPen( QColor( 0, 0, 0 ) ) ); QgsLegendRenderer legendRenderer( mLegendModel2, mSettings ); legendRenderer.setLegendSize( rect().size() ); legendRenderer.drawLegend( painter ); painter->restore(); //draw frame and selection boxes if necessary drawFrame( painter ); if ( isSelected() ) { drawSelectionBoxes( painter ); } }
QgsMapSettings QgsGlobeTileImage::createSettings( int dpi , const QStringList &layerSet ) const { QgsMapSettings settings; settings.setBackgroundColor( QColor( Qt::transparent ) ); settings.setDestinationCrs( QgsCRSCache::instance()->crsByAuthId( GEO_EPSG_CRS_AUTHID ) ); settings.setCrsTransformEnabled( true ); settings.setExtent( mTileExtent ); settings.setLayers( layerSet ); settings.setFlag( QgsMapSettings::DrawEditingInfo, false ); settings.setFlag( QgsMapSettings::DrawLabeling, false ); settings.setFlag( QgsMapSettings::DrawSelection, false ); settings.setMapUnits( QGis::Degrees ); settings.setOutputSize( QSize( mTileSize, mTileSize ) ); settings.setOutputImageFormat( QImage::Format_ARGB32_Premultiplied ); settings.setOutputDpi( dpi ); settings.setCustomRenderFlags( "globe" ); return settings; }
void testSnapModeAdvanced() { QgsMapSettings mapSettings; mapSettings.setOutputSize( QSize( 100, 100 ) ); mapSettings.setExtent( QgsRectangle( 0, 0, 1, 1 ) ); QVERIFY( mapSettings.hasValidSettings() ); QgsSnappingUtils u; u.setMapSettings( mapSettings ); u.setSnapToMapMode( QgsSnappingUtils::SnapAdvanced ); QList<QgsSnappingUtils::LayerConfig> layers; layers << QgsSnappingUtils::LayerConfig( mVL, QgsPointLocator::Vertex, 10, QgsTolerance::Pixels ); u.setLayers( layers ); QgsPointLocator::Match m = u.snapToMap( QPoint( 100, 100 ) ); QVERIFY( m.isValid() ); QVERIFY( m.hasVertex() ); QCOMPARE( m.point(), QgsPoint( 1, 0 ) ); // test with filtering FilterExcludePoint myFilter( QgsPoint( 1, 0 ) ); QgsPointLocator::Match m2 = u.snapToMap( QPoint( 100, 100 ), &myFilter ); QVERIFY( !m2.isValid() ); }
void testSnapModeAdvanced() { QgsMapSettings mapSettings; mapSettings.setOutputSize( QSize( 100, 100 ) ); mapSettings.setExtent( QgsRectangle( 0, 0, 1, 1 ) ); QVERIFY( mapSettings.hasValidSettings() ); QgsSnappingUtils u; QgsSnappingConfig snappingConfig = u.config(); u.setMapSettings( mapSettings ); snappingConfig.setMode( QgsSnappingConfig::AdvancedConfiguration ); snappingConfig.setIndividualLayerSettings( mVL, QgsSnappingConfig::IndividualLayerSettings( true, QgsSnappingConfig::Vertex, 10, QgsTolerance::Pixels ) ); u.setConfig( snappingConfig ); QgsPointLocator::Match m = u.snapToMap( QPoint( 100, 100 ) ); QVERIFY( m.isValid() ); QVERIFY( m.hasVertex() ); QCOMPARE( m.point(), QgsPoint( 1, 0 ) ); // test with filtering FilterExcludePoint myFilter( QgsPoint( 1, 0 ) ); QgsPointLocator::Match m2 = u.snapToMap( QPoint( 100, 100 ), &myFilter ); QVERIFY( !m2.isValid() ); }
void QgsComposerMapOverview::draw( QPainter *painter ) { if ( !mEnabled || mFrameMapId == -1 || !mComposerMap || !mComposerMap->composition() ) { return; } if ( !painter ) { return; } const QgsComposerMap* overviewFrameMap = mComposerMap->composition()->getComposerMapById( mFrameMapId ); if ( !overviewFrameMap ) { return; } //get polygon for other overview frame map's extent (use visibleExtentPolygon as it accounts for map rotation) QPolygonF otherExtent = overviewFrameMap->visibleExtentPolygon(); //get current map's extent as a QPolygonF QPolygonF thisExtent = mComposerMap->visibleExtentPolygon(); //intersect the two QPolygonF intersectExtent = thisExtent.intersected( otherExtent ); //setup painter scaling to dots so that raster symbology is drawn to scale double dotsPerMM = painter->device()->logicalDpiX() / 25.4; //setup render context QgsMapSettings ms = mComposerMap->composition()->mapSettings(); //context units should be in dots ms.setOutputSize( QSizeF( mComposerMap->rect().width() * dotsPerMM, mComposerMap->rect().height() * dotsPerMM ).toSize() ); ms.setExtent( *mComposerMap->currentMapExtent() ); ms.setOutputDpi( painter->device()->logicalDpiX() ); QgsRenderContext context = QgsRenderContext::fromMapSettings( ms ); context.setForceVectorOutput( true ); context.setPainter( painter ); QgsExpressionContext* expressionContext = createExpressionContext(); context.setExpressionContext( *expressionContext ); delete expressionContext; painter->save(); painter->setCompositionMode( mBlendMode ); painter->translate( mComposerMap->mXOffset, mComposerMap->mYOffset ); painter->scale( 1 / dotsPerMM, 1 / dotsPerMM ); // scale painter from mm to dots painter->setRenderHint( QPainter::Antialiasing ); mFrameSymbol->startRender( context ); //construct a polygon corresponding to the intersecting map extent //need to scale line to dots, rather then mm, since the painter has been scaled to dots QTransform mapTransform; QPolygonF thisRectPoly = QPolygonF( QRectF( 0, 0, dotsPerMM * mComposerMap->rect().width(), dotsPerMM * mComposerMap->rect().height() ) ); //workaround QT Bug #21329 thisRectPoly.pop_back(); thisExtent.pop_back(); //create transform from map coordinates to painter coordinates QTransform::quadToQuad( thisExtent, thisRectPoly, mapTransform ); QPolygonF intersectPolygon; intersectPolygon = mapTransform.map( intersectExtent ); QList<QPolygonF> rings; //empty list if ( !mInverted ) { //Render the intersecting map extent mFrameSymbol->renderPolygon( intersectPolygon, &rings, nullptr, context ); } else { //We are inverting the overview frame (ie, shading outside the intersecting extent) //Construct a polygon corresponding to the overview map extent QPolygonF outerPolygon; outerPolygon << QPointF( 0, 0 ) << QPointF( mComposerMap->rect().width() * dotsPerMM, 0 ) << QPointF( mComposerMap->rect().width() * dotsPerMM, mComposerMap->rect().height() * dotsPerMM ) << QPointF( 0, mComposerMap->rect().height() * dotsPerMM ) << QPointF( 0, 0 ); //Intersecting extent is an inner ring for the shaded area rings.append( intersectPolygon ); mFrameSymbol->renderPolygon( outerPolygon, &rings, nullptr, context ); } mFrameSymbol->stopRender( context ); painter->restore(); }
void QgsComposerLegend::paint( QPainter* painter, const QStyleOptionGraphicsItem* itemStyle, QWidget* pWidget ) { Q_UNUSED( itemStyle ); Q_UNUSED( pWidget ); if ( !painter ) return; if ( !shouldDrawItem() ) { return; } if ( mFilterAskedForUpdate ) { mFilterAskedForUpdate = false; doUpdateFilterByMap(); } int dpi = painter->device()->logicalDpiX(); double dotsPerMM = dpi / 25.4; if ( mComposition ) { mSettings.setUseAdvancedEffects( mComposition->useAdvancedEffects() ); mSettings.setDpi( dpi ); } if ( mComposerMap ) { mSettings.setMmPerMapUnit( mComposerMap->mapUnitsToMM() ); // use a temporary QgsMapSettings to find out real map scale QgsMapSettings ms = mComposerMap->composition()->mapSettings(); ms.setOutputSize( QSizeF( mComposerMap->rect().width() * dotsPerMM, mComposerMap->rect().height() * dotsPerMM ).toSize() ); ms.setExtent( *mComposerMap->currentMapExtent() ); ms.setOutputDpi( dpi ); mSettings.setMapScale( ms.scale() ); } drawBackground( painter ); painter->save(); //antialiasing on painter->setRenderHint( QPainter::Antialiasing, true ); painter->setPen( QPen( QColor( 0, 0, 0 ) ) ); QgsLegendRenderer legendRenderer( mLegendModel2, mSettings ); legendRenderer.setLegendSize( rect().size() ); //adjust box if width or height is too small QSizeF size = legendRenderer.minimumSize(); if ( size.height() > rect().height() || size.width() > rect().width() ) { //need to resize box QRectF targetRect = QRectF( pos().x(), pos().y(), rect().width(), rect().height() ); if ( size.height() > targetRect.height() ) targetRect.setHeight( size.height() ); if ( size.width() > rect().width() ) targetRect.setWidth( size.width() ); //set new rect, respecting position mode and data defined size/position setSceneRect( evalItemRect( targetRect, true ) ); } legendRenderer.drawLegend( painter ); painter->restore(); //draw frame and selection boxes if necessary drawFrame( painter ); if ( isSelected() ) { drawSelectionBoxes( painter ); } }