예제 #1
0
void QgsComposerPolygon::_draw( QPainter *painter )
{
  //setup painter scaling to dots so that raster symbology is drawn to scale
  const double dotsPerMM = painter->device()->logicalDpiX() / 25.4;

  QgsMapSettings ms = mComposition->mapSettings();
  ms.setOutputDpi( painter->device()->logicalDpiX() );

  QgsRenderContext context = QgsRenderContext::fromMapSettings( ms );
  context.setPainter( painter );
  context.setForceVectorOutput( true );

  QScopedPointer<QgsExpressionContext> expressionContext;
  expressionContext.reset( createExpressionContext() );
  context.setExpressionContext( *expressionContext.data() );

  painter->scale( 1 / dotsPerMM, 1 / dotsPerMM ); // scale painter from mm to dots
  QTransform t = QTransform::fromScale( dotsPerMM, dotsPerMM );

  QList<QPolygonF> rings; //empty
  QPainterPath polygonPath;
  polygonPath.addPolygon( mPolygon );

  mPolygonStyleSymbol->startRender( context );
  mPolygonStyleSymbol->renderPolygon( polygonPath.toFillPolygon( t ), &rings,
                                      nullptr, context );
  mPolygonStyleSymbol->stopRender( context );
  painter->scale( dotsPerMM, dotsPerMM );
}
예제 #2
0
double QgsTolerance::computeMapUnitPerPixel( QgsMapLayer* layer, const QgsMapSettings& mapSettings )
{
  if ( ! mapSettings.hasCrsTransformEnabled() )
  {
    // if the on-the-fly projections are not enabled, layer units pre pixel are the same as map units per pixel
    return mapSettings.mapUnitsPerPixel();
  }

  // the layer is projected. Find out how many pixels are in one map unit - either horizontal and vertical direction
  // this check might not work correctly in some cases
  // (on a large area the pixels projected around "0,0" can have different properties from the actual point)
  QgsPoint p1 = toLayerCoordinates( layer, mapSettings, QPoint( 0, 1 ) );
  QgsPoint p2 = toLayerCoordinates( layer, mapSettings, QPoint( 0, 2 ) );
  QgsPoint p3 = toLayerCoordinates( layer, mapSettings, QPoint( 1, 0 ) );
  QgsPoint p4 = toLayerCoordinates( layer, mapSettings, QPoint( 2, 0 ) );
  double x = p1.sqrDist( p2 );
  double y = p3.sqrDist( p4 );
  if ( x > y )
  {
    return sqrt( x );
  }
  else
  {
    return sqrt( y );
  }
}
예제 #3
0
void QgsComposerNodesItem::drawNodes( QPainter *painter ) const
{
  double rectSize = 3.0 / horizontalViewScaleFactor();

  QgsStringMap properties;
  properties.insert( "name", "cross" );
  properties.insert( "color_border", "red" );

  QScopedPointer<QgsMarkerSymbolV2> symbol;
  symbol.reset( QgsMarkerSymbolV2::createSimple( properties ) );
  symbol.data()->setSize( rectSize );
  symbol.data()->setAngle( 45 );

  QgsMapSettings ms = mComposition->mapSettings();
  ms.setOutputDpi( painter->device()->logicalDpiX() );

  QgsRenderContext context = QgsRenderContext::fromMapSettings( ms );
  context.setPainter( painter );
  context.setForceVectorOutput( true );

  QScopedPointer<QgsExpressionContext> expressionContext;
  expressionContext.reset( createExpressionContext() );
  context.setExpressionContext( *expressionContext.data() );

  symbol.data()->startRender( context );

  Q_FOREACH ( QPointF pt, mPolygon )
    symbol.data()->renderPoint( pt, nullptr, context );

  symbol.data()->stopRender( context );

  if ( mSelectedNode >= 0 && mSelectedNode < mPolygon.size() )
    drawSelectedNode( painter );
}
예제 #4
0
    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 ) );
    }
예제 #5
0
void QgsComposerArrow::drawLine( QPainter *painter )
{
  if ( ! mLineSymbol || ! mComposition )
  {
    return;
  }

  QPaintDevice* thePaintDevice = painter->device();
  painter->save();
  //setup painter scaling to dots so that raster symbology is drawn to scale
  double dotsPerMM = thePaintDevice->logicalDpiX() / 25.4;
  painter->scale( 1 / dotsPerMM, 1 / dotsPerMM ); //scale painter from mm to dots

  //setup render context
  QgsMapSettings ms = mComposition->mapSettings();
  //context units should be in dots
  ms.setOutputDpi( painter->device()->logicalDpiX() );
  QgsRenderContext context = QgsRenderContext::fromMapSettings( ms );
  context.setForceVectorOutput( true );
  context.setPainter( painter );
  QgsExpressionContext expressionContext = createExpressionContext();
  context.setExpressionContext( expressionContext );

  //line scaled to dots
  QPolygonF line;
  line << QPointF( mStartPoint.x() - pos().x(), mStartPoint.y() - pos().y() ) * dotsPerMM
  << QPointF( mStopPoint.x() - pos().x(), mStopPoint.y() - pos().y() ) * dotsPerMM;

  mLineSymbol->startRender( context );
  mLineSymbol->renderPolyline( line, nullptr, context );
  mLineSymbol->stopRender( context );
  painter->restore();

}
예제 #6
0
void QgsComposerNodesItem::drawSelectedNode( QPainter *painter ) const
{
  double rectSize = 3.0 / horizontalViewScaleFactor();

  QgsStringMap properties;
  properties.insert( "name", "square" );
  properties.insert( "color", "0, 0, 0, 0" );
  properties.insert( "color_border", "blue" );
  properties.insert( "width_border", "4" );

  QScopedPointer<QgsMarkerSymbolV2> symbol;
  symbol.reset( QgsMarkerSymbolV2::createSimple( properties ) );
  symbol.data()->setSize( rectSize );

  QgsMapSettings ms = mComposition->mapSettings();
  ms.setOutputDpi( painter->device()->logicalDpiX() );

  QgsRenderContext context = QgsRenderContext::fromMapSettings( ms );
  context.setPainter( painter );
  context.setForceVectorOutput( true );

  QScopedPointer<QgsExpressionContext> expressionContext;
  expressionContext.reset( createExpressionContext() );
  context.setExpressionContext( *expressionContext.data() );

  symbol.data()->startRender( context );
  symbol.data()->renderPoint( mPolygon.at( mSelectedNode ), nullptr, context );
  symbol.data()->stopRender( context );
}
예제 #7
0
QgsRenderContext QgsPointMarkerItem::renderContext( QPainter* painter )
{
  QgsExpressionContext context;
  context << QgsExpressionContextUtils::globalScope()
  << QgsExpressionContextUtils::projectScope()
  << QgsExpressionContextUtils::atlasScope( nullptr );
  if ( mMapCanvas )
  {
    context << QgsExpressionContextUtils::mapSettingsScope( mMapCanvas->mapSettings() )
    << new QgsExpressionContextScope( mMapCanvas->expressionContextScope() );
  }
  else
  {
    context << QgsExpressionContextUtils::mapSettingsScope( QgsMapSettings() );
  }
  //context << QgsExpressionContextUtils::layerScope( mLayer );
  context.setFeature( mFeature );

  //setup render context
  QgsMapSettings ms = mMapCanvas->mapSettings();
  ms.setExpressionContext( context );
  QgsRenderContext rc = QgsRenderContext::fromMapSettings( ms );
  rc.setPainter( painter );

  return rc;
}
예제 #8
0
void QgsPaperItem::paint( QPainter* painter, const QStyleOptionGraphicsItem* itemStyle, QWidget* pWidget )
{
  Q_UNUSED( itemStyle );
  Q_UNUSED( pWidget );
  if ( !painter || !mComposition || !mComposition->pagesVisible() )
  {
    return;
  }

  //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 = mComposition->mapSettings();
  //context units should be in dots
  ms.setOutputDpi( painter->device()->logicalDpiX() );
  QgsRenderContext context = QgsRenderContext::fromMapSettings( ms );
  context.setPainter( painter );
  context.setForceVectorOutput( true );
  QgsExpressionContext* expressionContext = createExpressionContext();
  context.setExpressionContext( *expressionContext );
  delete expressionContext;

  painter->save();

  if ( mComposition->plotStyle() ==  QgsComposition::Preview )
  {
    //if in preview mode, draw page border and shadow so that it's
    //still possible to tell where pages with a transparent style begin and end
    painter->setRenderHint( QPainter::Antialiasing, false );

    //shadow
    painter->setBrush( QBrush( QColor( 150, 150, 150 ) ) );
    painter->setPen( Qt::NoPen );
    painter->drawRect( QRectF( 1, 1, rect().width() + 1, rect().height() + 1 ) );

    //page area
    painter->setBrush( QColor( 215, 215, 215 ) );
    painter->setPen( QPen( QColor( 100, 100, 100 ) ) );
    painter->drawRect( QRectF( 0, 0, rect().width(), rect().height() ) );
  }

  painter->scale( 1 / dotsPerMM, 1 / dotsPerMM ); // scale painter from mm to dots

  painter->setRenderHint( QPainter::Antialiasing );
  mComposition->pageStyleSymbol()->startRender( context );

  calculatePageMargin();
  QPolygonF pagePolygon = QPolygonF( QRectF( mPageMargin * dotsPerMM, mPageMargin * dotsPerMM,
                                     ( rect().width() - 2 * mPageMargin ) * dotsPerMM, ( rect().height() - 2 * mPageMargin ) * dotsPerMM ) );
  QList<QPolygonF> rings; //empty list

  mComposition->pageStyleSymbol()->renderPolygon( pagePolygon, &rings, nullptr, context );
  mComposition->pageStyleSymbol()->stopRender( context );
  painter->restore();
}
예제 #9
0
// return ratio [mu/lu] between map units and layer units
// this is of course only an approximation
double _ratioMU2LU( const QgsMapSettings& mapSettings, QgsMapLayer* layer )
{
  double distMU = mapSettings.mapUnitsPerPixel();
  QgsPoint ptMapCenterMU = mapSettings.visibleExtent().center();
  QgsPoint ptMapCenterRightMU( ptMapCenterMU.x() + distMU, ptMapCenterMU.y() );
  QgsPoint ptMapCenterLU = mapSettings.mapToLayerCoordinates( layer, ptMapCenterMU );
  QgsPoint ptMapCenterRightLU = mapSettings.mapToLayerCoordinates( layer, ptMapCenterRightMU );
  double distLU = sqrt( ptMapCenterLU.sqrDist( ptMapCenterRightLU ) );
  double ratio = distMU / distLU;
  return ratio;
}
예제 #10
0
void QgsExtentGroupBox::setOutputExtentFromCurrent()
{
  if ( mCanvas )
  {
    // Use unrotated visible extent to insure output size and scale matches canvas
    QgsMapSettings ms = mCanvas->mapSettings();
    ms.setRotation( 0 );
    setOutputExtent( ms.visibleExtent(), ms.destinationCrs(), CurrentExtent );
  }
  else
  {
    setOutputExtent( mCurrentExtent, mCurrentCrs, CurrentExtent );
  }
}
예제 #11
0
QgsMapSaveDialog::QgsMapSaveDialog( QWidget *parent, QgsMapCanvas *mapCanvas, const QList<QgsDecorationItem *> &decorations, const QList< QgsAnnotation *> &annotations, DialogType type )
  : QDialog( parent )
  , mDialogType( type )
  , mMapCanvas( mapCanvas )
  , mAnnotations( annotations )
{
  setupUi( this );

  // Use unrotated visible extent to insure output size and scale matches canvas
  QgsMapSettings ms = mMapCanvas->mapSettings();
  ms.setRotation( 0 );
  mExtent = ms.visibleExtent();
  mDpi = ms.outputDpi();
  mSize = ms.outputSize();

  mResolutionSpinBox->setValue( mDpi );

  mExtentGroupBox->setOutputCrs( ms.destinationCrs() );
  mExtentGroupBox->setCurrentExtent( mExtent, ms.destinationCrs() );
  mExtentGroupBox->setOutputExtentFromCurrent();
  mExtentGroupBox->setMapCanvas( mapCanvas );

  mScaleWidget->setScale( ms.scale() );
  mScaleWidget->setMapCanvas( mMapCanvas );
  mScaleWidget->setShowCurrentScaleButton( true );

  QString activeDecorations;
  Q_FOREACH ( QgsDecorationItem *decoration, decorations )
  {
    mDecorations << decoration;
    if ( activeDecorations.isEmpty() )
      activeDecorations = decoration->name().toLower();
    else
      activeDecorations += QStringLiteral( ", %1" ).arg( decoration->name().toLower() );
  }
예제 #12
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;
    }
예제 #13
0
    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() );
    }
void QgsMapRendererJob::drawLabeling( const QgsMapSettings& settings, QgsRenderContext& renderContext, QgsPalLabeling* labelingEngine, QgsLabelingEngineV2* labelingEngine2, QPainter* painter )
{
  QgsDebugMsg( "Draw labeling start" );

  QTime t;
  t.start();

  // Reset the composition mode before rendering the labels
  painter->setCompositionMode( QPainter::CompositionMode_SourceOver );

  // TODO: this is not ideal - we could override rendering stopped flag that has been set in meanwhile
  renderContext = QgsRenderContext::fromMapSettings( settings );
  renderContext.setPainter( painter );
  renderContext.setLabelingEngine( labelingEngine );

#if !defined(QGIS_DISABLE_DEPRECATED)
  // old labeling - to be removed at some point...
  drawOldLabeling( settings, renderContext );
#endif
  drawNewLabeling( settings, renderContext, labelingEngine );

  if ( labelingEngine2 )
  {
    // set correct extent
    renderContext.setExtent( settings.visibleExtent() );
    renderContext.setCoordinateTransform( nullptr );

    labelingEngine2->run( renderContext );
  }

  QgsDebugMsg( QString( "Draw labeling took (seconds): %1" ).arg( t.elapsed() / 1000. ) );
}
예제 #15
0
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 );
  }
}
예제 #16
0
void QgsMapRendererJob::drawLabeling( const QgsMapSettings& settings, QgsRenderContext& renderContext, QgsLabelingEngine* labelingEngine2, QPainter* painter )
{
  QgsDebugMsg( "Draw labeling start" );

  QTime t;
  t.start();

  // Reset the composition mode before rendering the labels
  painter->setCompositionMode( QPainter::CompositionMode_SourceOver );

  // TODO: this is not ideal - we could override rendering stopped flag that has been set in meanwhile
  renderContext = QgsRenderContext::fromMapSettings( settings );
  renderContext.setPainter( painter );

  if ( labelingEngine2 )
  {
    // set correct extent
    renderContext.setExtent( settings.visibleExtent() );
    renderContext.setCoordinateTransform( QgsCoordinateTransform() );

    labelingEngine2->run( renderContext );
  }

  QgsDebugMsg( QString( "Draw labeling took (seconds): %1" ).arg( t.elapsed() / 1000. ) );
}
예제 #17
0
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 );
  }
}
예제 #18
0
int QgsDecorationGrid::yGridLines( const QgsMapSettings &mapSettings, QList< QPair< qreal, QLineF > > &lines ) const
{
  // prepare vertical lines

  lines.clear();
  if ( mGridIntervalX <= 0.0 )
  {
    return 1;
  }

  const QgsMapToPixel &m2p = mapSettings.mapToPixel();

  // draw nothing if the distance between grid lines would be less than 1px
  // otherwise the grid lines would completely cover the whole map
  //if ( mapBoundingRect.height() / mGridIntervalY >= p->device()->height() )
  if ( mGridIntervalX / mapSettings.mapUnitsPerPixel() < 1 )
    return 1;

  const QPolygonF &canvasPoly = canvasPolygon( mapSettings );
  const QPolygonF &mapPolygon = canvasExtent( mapSettings );
  QLineF lineSouth( mapPolygon[3], mapPolygon[2] );
  QLineF lineNorth( mapPolygon[0], mapPolygon[1] );

  double len = lineSouth.length();
  Q_ASSERT( std::fabs( len - lineNorth.length() ) < 1e-6 ); // no shear

  const QRectF &mapBoundingRect = mapPolygon.boundingRect();
  double roundCorrection = mapBoundingRect.left() > 0 ? 1.0 : 0.0;
  double dist = static_cast< int >( ( mapBoundingRect.left() - mGridOffsetX ) / mGridIntervalX + roundCorrection ) * mGridIntervalX + mGridOffsetX;
  dist = dist - mapBoundingRect.left();
  while ( dist < len )
  {
    double t = dist / len;
    QPointF p0( lineNorth.pointAt( t ) );
    QPointF p1( lineSouth.pointAt( t ) );
    QLineF line( p0, p1 );
    clipByRect( line, canvasPoly );
    line = QLineF( m2p.transform( QgsPointXY( line.pointAt( 0 ) ) ).toQPointF(), m2p.transform( QgsPointXY( line.pointAt( 1 ) ) ).toQPointF() );
    lines.push_back( qMakePair( p0.x(), line ) );
    dist += mGridIntervalX;
  }

  return 0;
}
예제 #19
0
QPolygonF canvasExtent( const QgsMapSettings &mapSettings )
{
  QPolygonF poly;
  QgsRectangle extent = mapSettings.visibleExtent();
  poly << QPointF( extent.xMinimum(), extent.yMaximum() );
  poly << QPointF( extent.xMaximum(), extent.yMaximum() );
  poly << QPointF( extent.xMaximum(), extent.yMinimum() );
  poly << QPointF( extent.xMinimum(), extent.yMinimum() );
  return poly;
}
예제 #20
0
QgsRectangle QgsMapCanvas::imageRect( const QImage& img, const QgsMapSettings& mapSettings )
{
  // This is a hack to pass QgsMapCanvasItem::setRect what it
  // expects (encoding of position and size of the item)
  const QgsMapToPixel& m2p = mapSettings.mapToPixel();
  QgsPoint topLeft = m2p.toMapPoint( 0, 0 );
  double res = m2p.mapUnitsPerPixel();
  QgsRectangle rect( topLeft.x(), topLeft.y(), topLeft.x() + img.width()*res, topLeft.y() - img.height()*res );
  return rect;
}
예제 #21
0
QImage QgsMapRendererJob::composeImage( const QgsMapSettings& settings, const LayerRenderJobs& jobs )
{
  QImage image( settings.outputSize(), settings.outputImageFormat() );
  image.fill( settings.backgroundColor().rgb() );

  QPainter painter( &image );

  for ( LayerRenderJobs::const_iterator it = jobs.constBegin(); it != jobs.constEnd(); ++it )
  {
    const LayerRenderJob& job = *it;

    painter.setCompositionMode( job.blendMode );

    Q_ASSERT( job.img != 0 );
    painter.drawImage( 0, 0, *job.img );
  }

  painter.end();
  return image;
}
예제 #22
0
void QgsMapRendererJob::drawNewLabeling( const QgsMapSettings& settings, QgsRenderContext& renderContext, QgsPalLabeling* labelingEngine )
{
  if ( labelingEngine && !renderContext.renderingStopped() )
  {
    // set correct extent
    renderContext.setExtent( settings.visibleExtent() );
    renderContext.setCoordinateTransform( NULL );

    labelingEngine->drawLabeling( renderContext );
    labelingEngine->exit();
  }
}
void QgsMapRendererJob::drawOldLabeling( const QgsMapSettings& settings, QgsRenderContext& renderContext )
{
    // render all labels for vector layers in the stack, starting at the base
    QListIterator<QString> li( settings.layers() );
    li.toBack();
    while ( li.hasPrevious() )
    {
        if ( renderContext.renderingStopped() )
        {
            break;
        }

        QString layerId = li.previous();

        QgsMapLayer *ml = QgsMapLayerRegistry::instance()->mapLayer( layerId );

        if ( !ml || ( ml->type() != QgsMapLayer::VectorLayer ) )
            continue;

        // only make labels if the layer is visible
        // after scale dep viewing settings are checked
        if ( ml->hasScaleBasedVisibility() && ( settings.scale() < ml->minimumScale() || settings.scale() > ml->maximumScale() ) )
            continue;

        const QgsCoordinateTransform* ct = 0;
        QgsRectangle r1 = settings.visibleExtent(), r2;

        if ( settings.hasCrsTransformEnabled() )
        {
            ct = settings.layerTransform( ml );
            if ( ct )
                reprojectToLayerExtent( ct, ml->crs().geographicFlag(), r1, r2 );
        }

        renderContext.setCoordinateTransform( ct );
        renderContext.setExtent( r1 );

        ml->drawLabels( renderContext );
    }
}
예제 #24
0
void QgsComposerPolyline::_draw( QPainter *painter )
{
  double dotsPerMM = painter->device()->logicalDpiX() / 25.4;

  QgsMapSettings ms = mComposition->mapSettings();
  ms.setOutputDpi( painter->device()->logicalDpiX() );

  QgsRenderContext context = QgsRenderContext::fromMapSettings( ms );
  context.setPainter( painter );
  context.setForceVectorOutput( true );

  QgsExpressionContext expressionContext = createExpressionContext();
  context.setExpressionContext( expressionContext );

  painter->scale( 1 / dotsPerMM, 1 / dotsPerMM ); // scale painter from mm to dots
  QTransform t = QTransform::fromScale( dotsPerMM, dotsPerMM );

  mPolylineStyleSymbol->startRender( context );
  mPolylineStyleSymbol->renderPolyline( t.map( mPolygon ), nullptr, context );
  mPolylineStyleSymbol->stopRender( context );
  painter->scale( dotsPerMM, dotsPerMM );
}
예제 #25
0
QgsRenderContext QgsRenderContext::fromMapSettings( const QgsMapSettings& mapSettings )
{
  QgsRenderContext ctx;
  ctx.setMapToPixel( mapSettings.mapToPixel() );
  ctx.setExtent( mapSettings.visibleExtent() );
  ctx.setDrawEditingInformation( mapSettings.testFlag( QgsMapSettings::DrawEditingInfo ) );
  ctx.setForceVectorOutput( mapSettings.testFlag( QgsMapSettings::ForceVectorOutput ) );
  ctx.setUseAdvancedEffects( mapSettings.testFlag( QgsMapSettings::UseAdvancedEffects ) );
  ctx.setUseRenderingOptimization( mapSettings.testFlag( QgsMapSettings::UseRenderingOptimization ) );
  ctx.setCoordinateTransform( 0 );
  ctx.setSelectionColor( mapSettings.selectionColor() );
  ctx.setShowSelection( mapSettings.testFlag( QgsMapSettings::DrawSelection ) );
  ctx.setRasterScaleFactor( 1.0 );
  ctx.setScaleFactor( mapSettings.outputDpi() / 25.4 ); // = pixels per mm
  ctx.setRendererScale( mapSettings.scale() );

  //this flag is only for stopping during the current rendering progress,
  //so must be false at every new render operation
  ctx.setRenderingStopped( false );

  return ctx;
}
예제 #26
0
static QgsQuickFeatureLayerPair _closestFeature( const QgsQuickFeatureLayerPairs &results, const QgsMapSettings &mapSettings, const QPointF &point )
{
  QgsPointXY mapPoint = mapSettings.mapToPixel().toMapCoordinates( point.toPoint() );
  QgsGeometry mapPointGeom( QgsGeometry::fromPointXY( mapPoint ) );

  double distMin = 1e10;
  int iMin = -1;
  for ( int i = 0; i < results.count(); ++i )
  {
    const QgsQuickFeatureLayerPair &res = results.at( i );
    QgsGeometry geom( res.feature().geometry() );
    try
    {
      geom.transform( mapSettings.layerTransform( res.layer() ) );
    }
    catch ( QgsCsException &e )
    {
      Q_UNUSED( e );
      // Caught an error in transform
      continue;
    }

    double dist = geom.distance( mapPointGeom );
    if ( dist < distMin )
    {
      iMin = i;
      distMin = dist;
    }
  }

  if ( results.empty() )
  {
    return QgsQuickFeatureLayerPair();
  }
  else
  {
    return results.at( iMin );
  }
}
QgsMapRendererSequentialJob::QgsMapRendererSequentialJob( const QgsMapSettings& settings )
    : QgsMapRendererQImageJob( settings )
    , mInternalJob( nullptr )
    , mPainter( nullptr )
    , mLabelingResults( nullptr )
{
  QgsDebugMsg( "SEQUENTIAL construct" );

  mImage = QImage( mSettings.outputSize(), mSettings.outputImageFormat() );
  mImage.setDotsPerMeterX( 1000 * settings.outputDpi() / 25.4 );
  mImage.setDotsPerMeterY( 1000 * settings.outputDpi() / 25.4 );
  mImage.fill( Qt::transparent );
}
예제 #28
0
double QgsTolerance::toleranceInProjectUnits( double tolerance, QgsMapLayer* layer, const QgsMapSettings& mapSettings, QgsTolerance::UnitType units )
{
  // converts to map units
  if ( units == ProjectUnits )
    return tolerance;
  else if ( units == Pixels )
    return tolerance * mapSettings.mapUnitsPerPixel();
  else // units == LayerUnits
  {
    // [mu] = [lu] * [mu/lu]
    return tolerance * _ratioMU2LU( mapSettings, layer );
  }
}
예제 #29
0
    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() );
    }
예제 #30
0
    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() );
    }