js css html

QGIS地图分析

2022-10-20  本文已影响0人  NullUser

QgsMapCanvas:QGraphicsView
|- 成员变量:

 QImage img = mJob->renderedImage();
 mMap->setContent( img, imageRect( img, mSettings ) );

渲染

QgsMapCanvas通过Timer对象控制渲染。

 connect( &mMapUpdateTimer, &QTimer::timeout, this, &QgsMapCanvas::mapUpdateTimeout );
  mMapUpdateTimer.setInterval( 250 );

在构造函数中将timer的超时信号连接到槽QgsMapCanvas::mapUpdateTimeout(),并设置间隔为250ms.

void QgsMapCanvas::mapUpdateTimeout()
{
  if ( mJob )
  {
    const QImage &img = mJob->renderedImage();
    mMap->setContent( img, imageRect( img, mSettings ) );
  }
}

在槽函数mapUpdateTimeout()中,调用QgsMapRendererQImageJob::renderedImage()输出渲染好的Image对象,并赋值给mMap.
QgsMapRendererQImageJob::renderedImage()是个纯虚函数,分别在子类QgsMapRendererParallelJobQgsMapRendererSequentialJob中实现。

QImage QgsMapRendererParallelJob::renderedImage()
{
  // if status == Idle we are either waiting for the render to start, OR have finished the render completely.
  // We can differentiate between those states by checking whether mFinalImage is null -- at the "waiting for
  // render to start" state mFinalImage has not yet been created.
  const bool jobIsComplete = mStatus == Idle && !mFinalImage.isNull();

  if ( !jobIsComplete )
    return composeImage( mSettings, mLayerJobs, mLabelJob, mCache );
  else
    return mFinalImage; // when rendering labels or idle
}

QImage QgsMapRendererSequentialJob::renderedImage()
{
  if ( isActive() && mCache )
    // this will allow immediate display of cached layers and at the same time updates of the layer being rendered
    return composeImage( mSettings, mInternalJob->jobs(), LabelRenderJob() );
  else
    return mImage;
}

从renderedImage()的实现可知,其通过composeImage()生成QImage对象。composeImage()在QgsMapRendererJob中实现。

QImage QgsMapRendererJob::composeImage( const QgsMapSettings &settings,
                                        const std::vector<LayerRenderJob> &jobs,
                                        const LabelRenderJob &labelJob,
                                        const QgsMapRendererCache *cache
                                      )
{
  QImage image( settings.deviceOutputSize(), settings.outputImageFormat() );
  image.setDevicePixelRatio( settings.devicePixelRatio() );
  image.setDotsPerMeterX( static_cast<int>( settings.outputDpi() * 39.37 ) );
  image.setDotsPerMeterY( static_cast<int>( settings.outputDpi() * 39.37 ) );
  image.fill( settings.backgroundColor().rgba() );

  QPainter painter( &image );

composeImage()中创建Image对象时,传入了QgsMapSettings::deviceOutputSize()。

QSize QgsMapSettings::deviceOutputSize() const
{
  return outputSize() * mDevicePixelRatio;
}
QSize QgsMapSettings::outputSize() const
{
  return mSize;
}
void QgsMapSettings::setOutputSize( QSize size )
{
  mSize = size;

  updateDerived();
}

QgsMapSettings::deviceOutputSize()的实现可知,其返回的size是成员变量mSize*mDevicePixelRatio。而mSize的赋值由setOutputSize()实现。
继续回到QgsMapCanvas类,查看其调用QgsMapSettings::setOutputSize()的地方:

setOutputSize()调用.png
  QSize s = viewport()->size();
  mSettings.setOutputSize( s );

传入的size大小其实是QGraphicsView的大小。
再回到QgsMapSettings中对mDevicePixelRatio的使用,对其赋值是通过setDevicePixelRatio()实现:

QgsMapSettings::mDevicePixelRatio
回到QgsMapCanvas中查找对QgsMapSettings::setDevicePixelRatio()的调用
void QgsMapCanvas::updateDevicePixelFromScreen()
{
  mSettings.setDevicePixelRatio( devicePixelRatio() );
  ......
}

其值是有QPaintDevice::devicePixelRatio()传入。

Layers

~Layers: QgsMapLayer : QObject

MapCanvasMap : QgsMapCanvasItem : QGraphicsItem
重写paint(),利用QPainter::drawImage

ps:
图元unit : QGraphicsItem
图层Layer:QGraphicsItemGroup
地图:Map:QGraphcisScene

上一篇 下一篇

猜你喜欢

热点阅读