예제 #1
0
void QgsLayoutItemGroup::setSceneRect( const QRectF &rectangle )
{
  mItemPosition = mLayout->convertFromLayoutUnits( rectangle.topLeft(), positionWithUnits().units() );
  mItemSize = mLayout->convertFromLayoutUnits( rectangle.size(), sizeWithUnits().units() );
  setScenePos( rectangle.topLeft() );
  setRect( 0, 0, rectangle.width(), rectangle.height() );
}
예제 #2
0
void QgsLayoutItemScaleBar::resizeToMinimumWidth()
{
  if ( !mStyle )
    return;

  double widthMM = mStyle->calculateBoxSize( mSettings, createScaleContext() ).width();
  QgsLayoutSize currentSize = sizeWithUnits();
  currentSize.setWidth( mLayout->renderContext().measurementConverter().convert( QgsLayoutMeasurement( widthMM, QgsUnitTypes::LayoutMillimeters ), currentSize.units() ).length() );
  attemptResize( currentSize );
  update();
  emit changed();
}
예제 #3
0
void QgsLayoutItemLegend::adjustBoxSize()
{
  if ( !mSizeToContents )
    return;

  if ( !mInitialMapScaleCalculated )
  {
    // this is messy - but until we have painted the item we have no knowledge of the current DPI
    // and so cannot correctly calculate the map scale. This results in incorrect size calculations
    // for marker symbols with size in map units, causing the legends to initially expand to huge
    // sizes if we attempt to calculate the box size first.
    return;
  }

  QgsLegendRenderer legendRenderer( mLegendModel.get(), mSettings );
  QSizeF size = legendRenderer.minimumSize();
  QgsDebugMsg( QStringLiteral( "width = %1 height = %2" ).arg( size.width() ).arg( size.height() ) );
  if ( size.isValid() )
  {
    QgsLayoutSize newSize = mLayout->convertFromLayoutUnits( size, sizeWithUnits().units() );
    //set new rect, respecting position mode and data defined size/position
    attemptResize( newSize );
  }
}
예제 #4
0
void QgsLayoutItemLegend::paint( QPainter *painter, const QStyleOptionGraphicsItem *itemStyle, QWidget *pWidget )
{
  if ( !painter )
    return;

  if ( mFilterAskedForUpdate )
  {
    mFilterAskedForUpdate = false;
    doUpdateFilterByMap();
  }

  int dpi = painter->device()->logicalDpiX();
  double dotsPerMM = dpi / 25.4;

  if ( mLayout )
  {
    mSettings.setUseAdvancedEffects( mLayout->renderContext().flags() & QgsLayoutRenderContext::FlagUseAdvancedEffects );
    mSettings.setDpi( dpi );
  }
  if ( mMap && mLayout )
  {
    mSettings.setMmPerMapUnit( mLayout->convertFromLayoutUnits( mMap->mapUnitsToLayoutUnits(), QgsUnitTypes::LayoutMillimeters ).length() );

    // use a temporary QgsMapSettings to find out real map scale
    QSizeF mapSizePixels = QSizeF( mMap->rect().width() * dotsPerMM, mMap->rect().height() * dotsPerMM );
    QgsRectangle mapExtent = mMap->extent();

    QgsMapSettings ms = mMap->mapSettings( mapExtent, mapSizePixels, dpi, false );
    mSettings.setMapScale( ms.scale() );
  }
  mInitialMapScaleCalculated = true;

  QgsLegendRenderer legendRenderer( mLegendModel.get(), mSettings );
  legendRenderer.setLegendSize( mForceResize && mSizeToContents ? QSize() : rect().size() );

  //adjust box if width or height is too small
  if ( mSizeToContents )
  {
    QSizeF size = legendRenderer.minimumSize();
    if ( mForceResize )
    {
      mForceResize = false;

      //set new rect, respecting position mode and data defined size/position
      QgsLayoutSize newSize = mLayout->convertFromLayoutUnits( size, sizeWithUnits().units() );
      attemptResize( newSize );
    }
    else if ( size.height() > rect().height() || size.width() > rect().width() )
    {
      //need to resize box
      QSizeF targetSize = rect().size();
      if ( size.height() > targetSize.height() )
        targetSize.setHeight( size.height() );
      if ( size.width() > targetSize.width() )
        targetSize.setWidth( size.width() );

      QgsLayoutSize newSize = mLayout->convertFromLayoutUnits( targetSize, sizeWithUnits().units() );
      //set new rect, respecting position mode and data defined size/position
      attemptResize( newSize );
    }
  }
  QgsLayoutItem::paint( painter, itemStyle, pWidget );
}
예제 #5
0
void QgsLayoutItem3DMap::draw( QgsLayoutItemRenderContext &context )
{
  QgsRenderContext &ctx = context.renderContext();
  QPainter *painter = ctx.painter();

  int w = static_cast<int>( std::ceil( rect().width() * ctx.scaleFactor() ) );
  int h = static_cast<int>( std::ceil( rect().height() * ctx.scaleFactor() ) );
  QRect r( 0, 0, w, h );

  painter->save();

  if ( !mSettings )
  {
    painter->drawText( r, Qt::AlignCenter, tr( "Scene not set" ) );
    painter->restore();
    return;
  }

  if ( mSettings->backgroundColor() != backgroundColor() )
  {
    mSettings->setBackgroundColor( backgroundColor() );
    mCapturedImage = QImage();
  }

  if ( !mCapturedImage.isNull() )
  {
    painter->drawImage( r, mCapturedImage );
    painter->restore();
    return;
  }

  // we do not have a cached image of the rendered scene - let's request one from the engine

  if ( mLayout->renderContext().isPreviewRender() )
  {
    painter->drawText( r, Qt::AlignCenter, tr( "Loading" ) );
    painter->restore();
  }

  QSizeF sizePixels = mLayout->renderContext().measurementConverter().convert( sizeWithUnits(), QgsUnitTypes::LayoutPixels ).toQSizeF();
  QSize sizePixelsInt = QSize( static_cast<int>( std::ceil( sizePixels.width() ) ),
                               static_cast<int>( std::ceil( sizePixels.height() ) ) );

  if ( !mEngine )
  {
    mEngine.reset( new QgsOffscreen3DEngine );
    connect( mEngine.get(), &QgsAbstract3DEngine::imageCaptured, this, &QgsLayoutItem3DMap::onImageCaptured );

    mEngine->setSize( sizePixelsInt );

    mScene = new Qgs3DMapScene( *mSettings, mEngine.get() );
    connect( mScene, &Qgs3DMapScene::sceneStateChanged, this, &QgsLayoutItem3DMap::onSceneStateChanged );

    mEngine->setRootEntity( mScene );
  }

  if ( mEngine->size() != sizePixelsInt )
    mEngine->setSize( sizePixelsInt );

  mScene->cameraController()->setCameraPose( mCameraPose );

  if ( mLayout->renderContext().isPreviewRender() )
  {
    onSceneStateChanged();
  }
  else
  {
    // we can't just request a capture and hope it will arrive at some point later.
    // this is not a preview, we need the rendered scene now!
    if ( mDrawing )
      return;
    mDrawing = true;
    Qgs3DUtils::captureSceneImage( *mEngine.get(), mScene );
    QImage img = Qgs3DUtils::captureSceneImage( *mEngine.get(), mScene );
    painter->drawImage( r, img );
    painter->restore();
    mDrawing = false;
  }
}