mirror of
				https://github.com/qgis/QGIS.git
				synced 2025-11-04 00:04:25 -05:00 
			
		
		
		
	Add api to allow redrawing of previously collected results for a single
elevation profile source And use this to just redraw the existing results whenever a setting relating only to the appearance of the profile chart is changed, instead of regenerating the whole chart
This commit is contained in:
		
							parent
							
								
									1ecf9dce5e
								
							
						
					
					
						commit
						a35e74c656
					
				@ -140,6 +140,16 @@ Returns the range of the retrieved elevation values
 | 
			
		||||
    virtual QgsProfileSnapResult snapPoint( const QgsProfilePoint &point, const QgsProfileSnapContext &context );
 | 
			
		||||
%Docstring
 | 
			
		||||
Snaps a ``point`` to the generated elevation profile.
 | 
			
		||||
%End
 | 
			
		||||
 | 
			
		||||
    virtual void updateFromGenerator( const QgsAbstractProfileGenerator *generator );
 | 
			
		||||
%Docstring
 | 
			
		||||
Updates the results to match the properties from the specified ``generator``.
 | 
			
		||||
 | 
			
		||||
For instance, this method can be used to replace any stored properties relating to rendering
 | 
			
		||||
the gathered results to reflect the ``generator``'s current properties.
 | 
			
		||||
 | 
			
		||||
The base class method does nothing.
 | 
			
		||||
%End
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -46,6 +46,11 @@ results.
 | 
			
		||||
 | 
			
		||||
    ~QgsProfilePlotRenderer();
 | 
			
		||||
 | 
			
		||||
    QStringList sourceIds() const;
 | 
			
		||||
%Docstring
 | 
			
		||||
Returns the ordered list of source IDs for the sources used by the renderer.
 | 
			
		||||
%End
 | 
			
		||||
 | 
			
		||||
    void startGeneration();
 | 
			
		||||
%Docstring
 | 
			
		||||
Start the generation job and immediately return.
 | 
			
		||||
@ -73,6 +78,13 @@ Block until the current job has finished.
 | 
			
		||||
    bool isActive() const;
 | 
			
		||||
%Docstring
 | 
			
		||||
Returns ``True`` if the generation job is currently running in background.
 | 
			
		||||
%End
 | 
			
		||||
 | 
			
		||||
    void replaceSource( QgsAbstractProfileSource *source );
 | 
			
		||||
%Docstring
 | 
			
		||||
Replaces the existing source with matching ID.
 | 
			
		||||
 | 
			
		||||
The matching stored source will be deleted and replaced with ``source``.
 | 
			
		||||
%End
 | 
			
		||||
 | 
			
		||||
    bool invalidateResults( QgsAbstractProfileSource *source );
 | 
			
		||||
@ -100,14 +112,18 @@ Does nothing if the generation is already in progress.
 | 
			
		||||
Returns the limits of the retrieved elevation values.
 | 
			
		||||
%End
 | 
			
		||||
 | 
			
		||||
    QImage renderToImage( int width, int height, double distanceMin, double distanceMax, double zMin, double zMax );
 | 
			
		||||
    QImage renderToImage( int width, int height, double distanceMin, double distanceMax, double zMin, double zMax, const QString &sourceId = QString() );
 | 
			
		||||
%Docstring
 | 
			
		||||
Renders a portion of the profile to an image with the given ``width`` and ``height``.
 | 
			
		||||
 | 
			
		||||
If ``sourceId`` is empty then all sources will be rendered, otherwise only the matching source will be rendered.
 | 
			
		||||
%End
 | 
			
		||||
 | 
			
		||||
    void render( QgsRenderContext &context, double width, double height, double distanceMin, double distanceMax, double zMin, double zMax );
 | 
			
		||||
    void render( QgsRenderContext &context, double width, double height, double distanceMin, double distanceMax, double zMin, double zMax, const QString &sourceId = QString() );
 | 
			
		||||
%Docstring
 | 
			
		||||
Renders a portion of the profile using the specified render ``context``.
 | 
			
		||||
 | 
			
		||||
If ``sourceId`` is empty then all sources will be rendered, otherwise only the matching source will be rendered.
 | 
			
		||||
%End
 | 
			
		||||
 | 
			
		||||
    QgsProfileSnapResult snapPoint( const QgsProfilePoint &point, const QgsProfileSnapContext &context );
 | 
			
		||||
 | 
			
		||||
@ -63,3 +63,8 @@ QgsProfileSnapResult QgsAbstractProfileResults::snapPoint( const QgsProfilePoint
 | 
			
		||||
{
 | 
			
		||||
  return QgsProfileSnapResult();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void QgsAbstractProfileResults::updateFromGenerator( const QgsAbstractProfileGenerator * )
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -116,6 +116,7 @@ class CORE_EXPORT QgsProfileRenderContext
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class QgsAbstractProfileGenerator;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * \brief Abstract base class for storage of elevation profiles.
 | 
			
		||||
@ -164,6 +165,16 @@ class CORE_EXPORT QgsAbstractProfileResults
 | 
			
		||||
     * Snaps a \a point to the generated elevation profile.
 | 
			
		||||
     */
 | 
			
		||||
    virtual QgsProfileSnapResult snapPoint( const QgsProfilePoint &point, const QgsProfileSnapContext &context );
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Updates the results to match the properties from the specified \a generator.
 | 
			
		||||
     *
 | 
			
		||||
     * For instance, this method can be used to replace any stored properties relating to rendering
 | 
			
		||||
     * the gathered results to reflect the \a generator's current properties.
 | 
			
		||||
     *
 | 
			
		||||
     * The base class method does nothing.
 | 
			
		||||
     */
 | 
			
		||||
    virtual void updateFromGenerator( const QgsAbstractProfileGenerator *generator );
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 | 
			
		||||
@ -46,6 +46,17 @@ QgsProfilePlotRenderer::~QgsProfilePlotRenderer()
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QStringList QgsProfilePlotRenderer::sourceIds() const
 | 
			
		||||
{
 | 
			
		||||
  QStringList res;
 | 
			
		||||
  res.reserve( mGenerators.size() );
 | 
			
		||||
  for ( const auto &it : mGenerators )
 | 
			
		||||
  {
 | 
			
		||||
    res.append( it->sourceId() );
 | 
			
		||||
  }
 | 
			
		||||
  return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void QgsProfilePlotRenderer::startGeneration()
 | 
			
		||||
{
 | 
			
		||||
  if ( isActive() )
 | 
			
		||||
@ -125,7 +136,17 @@ bool QgsProfilePlotRenderer::isActive() const
 | 
			
		||||
  return mStatus != Idle;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void QgsProfilePlotRenderer::replaceSource( QgsAbstractProfileSource *source )
 | 
			
		||||
{
 | 
			
		||||
  replaceSourceInternal( source, false );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool QgsProfilePlotRenderer::invalidateResults( QgsAbstractProfileSource *source )
 | 
			
		||||
{
 | 
			
		||||
  return replaceSourceInternal( source, true );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool QgsProfilePlotRenderer::replaceSourceInternal( QgsAbstractProfileSource *source, bool clearPreviousResults )
 | 
			
		||||
{
 | 
			
		||||
  if ( !source )
 | 
			
		||||
    return false;
 | 
			
		||||
@ -141,9 +162,16 @@ bool QgsProfilePlotRenderer::invalidateResults( QgsAbstractProfileSource *source
 | 
			
		||||
    if ( job.generator && job.generator->sourceId() == sourceId )
 | 
			
		||||
    {
 | 
			
		||||
      res = true;
 | 
			
		||||
      job.results.reset();
 | 
			
		||||
      if ( clearPreviousResults )
 | 
			
		||||
      {
 | 
			
		||||
        job.results.reset();
 | 
			
		||||
        job.complete = false;
 | 
			
		||||
      }
 | 
			
		||||
      else if ( job.results )
 | 
			
		||||
      {
 | 
			
		||||
        job.results->updateFromGenerator( generator.get() );
 | 
			
		||||
      }
 | 
			
		||||
      job.generator = generator.get();
 | 
			
		||||
      job.complete = false;
 | 
			
		||||
      for ( auto it = mGenerators.begin(); it != mGenerators.end(); )
 | 
			
		||||
      {
 | 
			
		||||
        if ( ( *it )->sourceId() == sourceId )
 | 
			
		||||
@ -186,7 +214,7 @@ QgsDoubleRange QgsProfilePlotRenderer::zRange() const
 | 
			
		||||
  return QgsDoubleRange( min, max );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QImage QgsProfilePlotRenderer::renderToImage( int width, int height, double distanceMin, double distanceMax, double zMin, double zMax )
 | 
			
		||||
QImage QgsProfilePlotRenderer::renderToImage( int width, int height, double distanceMin, double distanceMax, double zMin, double zMax, const QString &sourceId )
 | 
			
		||||
{
 | 
			
		||||
  QImage res( width, height, QImage::Format_ARGB32_Premultiplied );
 | 
			
		||||
  res.fill( Qt::transparent );
 | 
			
		||||
@ -196,13 +224,13 @@ QImage QgsProfilePlotRenderer::renderToImage( int width, int height, double dist
 | 
			
		||||
  QgsRenderContext context = QgsRenderContext::fromQPainter( &p );
 | 
			
		||||
  context.setFlag( Qgis::RenderContextFlag::Antialiasing, true );
 | 
			
		||||
  context.setPainterFlagsUsingContext( &p );
 | 
			
		||||
  render( context, width, height, distanceMin, distanceMax, zMin, zMax );
 | 
			
		||||
  render( context, width, height, distanceMin, distanceMax, zMin, zMax, sourceId );
 | 
			
		||||
  p.end();
 | 
			
		||||
 | 
			
		||||
  return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void QgsProfilePlotRenderer::render( QgsRenderContext &context, double width, double height, double distanceMin, double distanceMax, double zMin, double zMax )
 | 
			
		||||
void QgsProfilePlotRenderer::render( QgsRenderContext &context, double width, double height, double distanceMin, double distanceMax, double zMin, double zMax, const QString &sourceId )
 | 
			
		||||
{
 | 
			
		||||
  QPainter *painter = context.painter();
 | 
			
		||||
  if ( !painter )
 | 
			
		||||
@ -221,7 +249,7 @@ void QgsProfilePlotRenderer::render( QgsRenderContext &context, double width, do
 | 
			
		||||
 | 
			
		||||
  for ( const ProfileJob &job : mJobs )
 | 
			
		||||
  {
 | 
			
		||||
    if ( job.complete && job.results )
 | 
			
		||||
    if ( job.complete && job.results && ( sourceId.isEmpty() || job.generator->sourceId() == sourceId ) )
 | 
			
		||||
      job.results->renderResults( profileRenderContext );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@ -272,3 +300,4 @@ void QgsProfilePlotRenderer::generateProfileStatic( ProfileJob &job )
 | 
			
		||||
  job.results.reset( job.generator->takeResults() );
 | 
			
		||||
  job.complete = true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -70,6 +70,11 @@ class CORE_EXPORT QgsProfilePlotRenderer : public QObject
 | 
			
		||||
 | 
			
		||||
    ~QgsProfilePlotRenderer() override;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns the ordered list of source IDs for the sources used by the renderer.
 | 
			
		||||
     */
 | 
			
		||||
    QStringList sourceIds() const;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Start the generation job and immediately return.
 | 
			
		||||
     * Does nothing if the generation is already in progress.
 | 
			
		||||
@ -95,6 +100,13 @@ class CORE_EXPORT QgsProfilePlotRenderer : public QObject
 | 
			
		||||
    //! Returns TRUE if the generation job is currently running in background.
 | 
			
		||||
    bool isActive() const;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Replaces the existing source with matching ID.
 | 
			
		||||
     *
 | 
			
		||||
     * The matching stored source will be deleted and replaced with \a source.
 | 
			
		||||
     */
 | 
			
		||||
    void replaceSource( QgsAbstractProfileSource *source );
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Invalidates the profile results from the source with matching ID.
 | 
			
		||||
     *
 | 
			
		||||
@ -122,13 +134,17 @@ class CORE_EXPORT QgsProfilePlotRenderer : public QObject
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Renders a portion of the profile to an image with the given \a width and \a height.
 | 
			
		||||
     *
 | 
			
		||||
     * If \a sourceId is empty then all sources will be rendered, otherwise only the matching source will be rendered.
 | 
			
		||||
     */
 | 
			
		||||
    QImage renderToImage( int width, int height, double distanceMin, double distanceMax, double zMin, double zMax );
 | 
			
		||||
    QImage renderToImage( int width, int height, double distanceMin, double distanceMax, double zMin, double zMax, const QString &sourceId = QString() );
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Renders a portion of the profile using the specified render \a context.
 | 
			
		||||
     *
 | 
			
		||||
     * If \a sourceId is empty then all sources will be rendered, otherwise only the matching source will be rendered.
 | 
			
		||||
     */
 | 
			
		||||
    void render( QgsRenderContext &context, double width, double height, double distanceMin, double distanceMax, double zMin, double zMax );
 | 
			
		||||
    void render( QgsRenderContext &context, double width, double height, double distanceMin, double distanceMax, double zMin, double zMax, const QString &sourceId = QString() );
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Snap a \a point to the results.
 | 
			
		||||
@ -154,6 +170,7 @@ class CORE_EXPORT QgsProfilePlotRenderer : public QObject
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    static void generateProfileStatic( ProfileJob &job );
 | 
			
		||||
    bool replaceSourceInternal( QgsAbstractProfileSource *source, bool clearPreviousResults );
 | 
			
		||||
 | 
			
		||||
    std::vector< std::unique_ptr< QgsAbstractProfileGenerator > > mGenerators;
 | 
			
		||||
    QgsProfileRequest mRequest;
 | 
			
		||||
 | 
			
		||||
@ -135,6 +135,13 @@ QgsProfileSnapResult QgsMeshLayerProfileResults::snapPoint( const QgsProfilePoin
 | 
			
		||||
  return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void QgsMeshLayerProfileResults::updateFromGenerator( const QgsAbstractProfileGenerator *generator )
 | 
			
		||||
{
 | 
			
		||||
  const QgsMeshLayerProfileGenerator *mlGenerator = qgis::down_cast<  const QgsMeshLayerProfileGenerator * >( generator );
 | 
			
		||||
 | 
			
		||||
  lineSymbol.reset( mlGenerator->mLineSymbol->clone() );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// QgsMeshLayerProfileGenerator
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
@ -63,6 +63,7 @@ class CORE_EXPORT QgsMeshLayerProfileResults : public QgsAbstractProfileResults
 | 
			
		||||
    QVector< QgsGeometry > asGeometries() const override;
 | 
			
		||||
    void renderResults( QgsProfileRenderContext &context ) override;
 | 
			
		||||
    QgsProfileSnapResult snapPoint( const QgsProfilePoint &point, const QgsProfileSnapContext &context ) override;
 | 
			
		||||
    void updateFromGenerator( const QgsAbstractProfileGenerator *generator ) override;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -116,6 +117,8 @@ class CORE_EXPORT QgsMeshLayerProfileGenerator : public QgsAbstractProfileGenera
 | 
			
		||||
 | 
			
		||||
    std::unique_ptr< QgsMeshLayerProfileResults > mResults;
 | 
			
		||||
 | 
			
		||||
    friend class QgsMeshLayerProfileResults;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -138,6 +138,13 @@ void QgsRasterLayerProfileResults::renderResults( QgsProfileRenderContext &conte
 | 
			
		||||
  lineSymbol->stopRender( context.renderContext() );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void QgsRasterLayerProfileResults::updateFromGenerator( const QgsAbstractProfileGenerator *generator )
 | 
			
		||||
{
 | 
			
		||||
  const QgsRasterLayerProfileGenerator *rlGenerator = qgis::down_cast<  const QgsRasterLayerProfileGenerator * >( generator );
 | 
			
		||||
 | 
			
		||||
  lineSymbol.reset( rlGenerator->mLineSymbol->clone() );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// QgsRasterLayerProfileGenerator
 | 
			
		||||
 | 
			
		||||
@ -62,6 +62,7 @@ class CORE_EXPORT QgsRasterLayerProfileResults : public QgsAbstractProfileResult
 | 
			
		||||
    QVector< QgsGeometry > asGeometries() const override;
 | 
			
		||||
    QgsProfileSnapResult snapPoint( const QgsProfilePoint &point, const QgsProfileSnapContext &context ) override;
 | 
			
		||||
    void renderResults( QgsProfileRenderContext &context ) override;
 | 
			
		||||
    void updateFromGenerator( const QgsAbstractProfileGenerator *generator ) override;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -113,6 +114,8 @@ class CORE_EXPORT QgsRasterLayerProfileGenerator : public QgsAbstractProfileGene
 | 
			
		||||
 | 
			
		||||
    double mStepDistance = std::numeric_limits<double>::quiet_NaN();
 | 
			
		||||
 | 
			
		||||
    friend class QgsRasterLayerProfileResults;
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // QGSRASTERLAYERPROFILEGENERATOR_H
 | 
			
		||||
 | 
			
		||||
@ -398,6 +398,16 @@ void QgsVectorLayerProfileResults::renderResults( QgsProfileRenderContext &conte
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void QgsVectorLayerProfileResults::updateFromGenerator( const QgsAbstractProfileGenerator *generator )
 | 
			
		||||
{
 | 
			
		||||
  const QgsVectorLayerProfileGenerator *vlGenerator = qgis::down_cast<  const QgsVectorLayerProfileGenerator * >( generator );
 | 
			
		||||
 | 
			
		||||
  respectLayerSymbology = vlGenerator->mRespectLayerSymbology;
 | 
			
		||||
  profileLineSymbol.reset( vlGenerator->mProfileLineSymbol->clone() );
 | 
			
		||||
  profileFillSymbol.reset( vlGenerator->mProfileFillSymbol->clone() );
 | 
			
		||||
  profileMarkerSymbol.reset( vlGenerator->mProfileMarkerSymbol->clone() );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//
 | 
			
		||||
// QgsVectorLayerProfileGenerator
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
@ -85,6 +85,7 @@ class CORE_EXPORT QgsVectorLayerProfileResults : public QgsAbstractProfileResult
 | 
			
		||||
    QVector< QgsGeometry > asGeometries() const override;
 | 
			
		||||
    QgsProfileSnapResult snapPoint( const QgsProfilePoint &point, const QgsProfileSnapContext &context ) override;
 | 
			
		||||
    void renderResults( QgsProfileRenderContext &context ) override;
 | 
			
		||||
    void updateFromGenerator( const QgsAbstractProfileGenerator *generator ) override;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -168,6 +169,8 @@ class CORE_EXPORT QgsVectorLayerProfileGenerator : public QgsAbstractProfileGene
 | 
			
		||||
    // NOT for use in the background thread!
 | 
			
		||||
    QPointer< QgsVectorLayer > mLayer;
 | 
			
		||||
 | 
			
		||||
    friend class QgsVectorLayerProfileResults;
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // QGSVECTORLAYERPROFILEGENERATOR_H
 | 
			
		||||
 | 
			
		||||
@ -64,6 +64,7 @@ class QgsElevationProfilePlotItem : public Qgs2DPlot, public QgsPlotCanvasItem
 | 
			
		||||
      setPos( mRect.topLeft() );
 | 
			
		||||
 | 
			
		||||
      mImage = QImage();
 | 
			
		||||
      mCachedImages.clear();
 | 
			
		||||
      mPlotArea = QRectF();
 | 
			
		||||
      update();
 | 
			
		||||
    }
 | 
			
		||||
@ -71,10 +72,22 @@ class QgsElevationProfilePlotItem : public Qgs2DPlot, public QgsPlotCanvasItem
 | 
			
		||||
    void updatePlot()
 | 
			
		||||
    {
 | 
			
		||||
      mImage = QImage();
 | 
			
		||||
      mCachedImages.clear();
 | 
			
		||||
      mPlotArea = QRectF();
 | 
			
		||||
      update();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool redrawResults( const QString &sourceId )
 | 
			
		||||
    {
 | 
			
		||||
      auto it = mCachedImages.find( sourceId );
 | 
			
		||||
      if ( it == mCachedImages.end() )
 | 
			
		||||
        return false;
 | 
			
		||||
 | 
			
		||||
      mCachedImages.erase( it );
 | 
			
		||||
      mImage = QImage();
 | 
			
		||||
      return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    QRectF boundingRect() const override
 | 
			
		||||
    {
 | 
			
		||||
      return mRect;
 | 
			
		||||
@ -92,7 +105,7 @@ class QgsElevationProfilePlotItem : public Qgs2DPlot, public QgsPlotCanvasItem
 | 
			
		||||
      return mPlotArea;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    QgsProfilePoint canvasPointToPlotPoint( const QPointF &point )
 | 
			
		||||
    QgsProfilePoint canvasPointToPlotPoint( QPointF point )
 | 
			
		||||
    {
 | 
			
		||||
      if ( !mPlotArea.contains( point.x(), point.y() ) )
 | 
			
		||||
        return QgsProfilePoint();
 | 
			
		||||
@ -119,8 +132,22 @@ class QgsElevationProfilePlotItem : public Qgs2DPlot, public QgsPlotCanvasItem
 | 
			
		||||
      if ( !mRenderer )
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
      const QImage plot = mRenderer->renderToImage( plotArea.width(), plotArea.height(), xMinimum(), xMaximum(), yMinimum(), yMaximum() );
 | 
			
		||||
      rc.painter()->drawImage( plotArea.left(), plotArea.top(), plot );
 | 
			
		||||
      const QStringList sourceIds = mRenderer->sourceIds();
 | 
			
		||||
      for ( const QString &source : sourceIds )
 | 
			
		||||
      {
 | 
			
		||||
        QImage plot;
 | 
			
		||||
        auto it = mCachedImages.constFind( source );
 | 
			
		||||
        if ( it != mCachedImages.constEnd() )
 | 
			
		||||
        {
 | 
			
		||||
          plot = it.value();
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
          plot = mRenderer->renderToImage( plotArea.width(), plotArea.height(), xMinimum(), xMaximum(), yMinimum(), yMaximum(), source );
 | 
			
		||||
          mCachedImages.insert( source, plot );
 | 
			
		||||
        }
 | 
			
		||||
        rc.painter()->drawImage( plotArea.left(), plotArea.top(), plot );
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void paint( QPainter *painter ) override
 | 
			
		||||
@ -149,6 +176,9 @@ class QgsElevationProfilePlotItem : public Qgs2DPlot, public QgsPlotCanvasItem
 | 
			
		||||
  private:
 | 
			
		||||
 | 
			
		||||
    QImage mImage;
 | 
			
		||||
 | 
			
		||||
    QMap< QString, QImage > mCachedImages;
 | 
			
		||||
 | 
			
		||||
    QRectF mRect;
 | 
			
		||||
    QRectF mPlotArea;
 | 
			
		||||
    QgsProfilePlotRenderer *mRenderer = nullptr;
 | 
			
		||||
@ -290,6 +320,11 @@ QgsElevationProfileCanvas::QgsElevationProfileCanvas( QWidget *parent )
 | 
			
		||||
  mDeferredUpdateTimer->stop();
 | 
			
		||||
  connect( mDeferredUpdateTimer, &QTimer::timeout, this, &QgsElevationProfileCanvas::startDeferredUpdate );
 | 
			
		||||
 | 
			
		||||
  mDeferredRedrawTimer = new QTimer( this );
 | 
			
		||||
  mDeferredRedrawTimer->setSingleShot( true );
 | 
			
		||||
  mDeferredRedrawTimer->stop();
 | 
			
		||||
  connect( mDeferredRedrawTimer, &QTimer::timeout, this, &QgsElevationProfileCanvas::startDeferredRedraw );
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QgsElevationProfileCanvas::~QgsElevationProfileCanvas()
 | 
			
		||||
@ -375,11 +410,13 @@ void QgsElevationProfileCanvas::setupLayerConnections( QgsMapLayer *layer, bool
 | 
			
		||||
  if ( isDisconnect )
 | 
			
		||||
  {
 | 
			
		||||
    disconnect( layer->elevationProperties(), &QgsMapLayerElevationProperties::profileGenerationPropertyChanged, this, &QgsElevationProfileCanvas::onLayerProfileGenerationPropertyChanged );
 | 
			
		||||
    disconnect( layer->elevationProperties(), &QgsMapLayerElevationProperties::renderingPropertyChanged, this, &QgsElevationProfileCanvas::onLayerProfileRendererPropertyChanged );
 | 
			
		||||
    disconnect( layer, &QgsMapLayer::dataChanged, this, &QgsElevationProfileCanvas::updateResultsForLayer );
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
    connect( layer->elevationProperties(), &QgsMapLayerElevationProperties::profileGenerationPropertyChanged, this, &QgsElevationProfileCanvas::onLayerProfileGenerationPropertyChanged );
 | 
			
		||||
    connect( layer->elevationProperties(), &QgsMapLayerElevationProperties::renderingPropertyChanged, this, &QgsElevationProfileCanvas::onLayerProfileRendererPropertyChanged );
 | 
			
		||||
    connect( layer, &QgsMapLayer::dataChanged, this, &QgsElevationProfileCanvas::updateResultsForLayer );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -412,7 +449,6 @@ void QgsElevationProfileCanvas::setupLayerConnections( QgsMapLayer *layer, bool
 | 
			
		||||
    case QgsMapLayerType::PointCloudLayer:
 | 
			
		||||
    case QgsMapLayerType::GroupLayer:
 | 
			
		||||
      break;
 | 
			
		||||
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -622,6 +658,27 @@ void QgsElevationProfileCanvas::onLayerProfileGenerationPropertyChanged()
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void QgsElevationProfileCanvas::onLayerProfileRendererPropertyChanged()
 | 
			
		||||
{
 | 
			
		||||
  // TODO -- handle nicely when existing job is in progress
 | 
			
		||||
  if ( !mCurrentJob || mCurrentJob->isActive() )
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  QgsMapLayerElevationProperties *properties = qobject_cast< QgsMapLayerElevationProperties * >( sender() );
 | 
			
		||||
  if ( !properties )
 | 
			
		||||
    return;
 | 
			
		||||
 | 
			
		||||
  if ( QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( properties->parent() ) )
 | 
			
		||||
  {
 | 
			
		||||
    if ( QgsAbstractProfileSource *source = dynamic_cast< QgsAbstractProfileSource * >( layer ) )
 | 
			
		||||
    {
 | 
			
		||||
      mCurrentJob->replaceSource( source );
 | 
			
		||||
    }
 | 
			
		||||
    if ( mPlotItem->redrawResults( layer->id() ) )
 | 
			
		||||
      scheduleDeferredRedraw();
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void QgsElevationProfileCanvas::updateResultsForLayer()
 | 
			
		||||
{
 | 
			
		||||
  if ( QgsMapLayer *layer = qobject_cast< QgsMapLayer * >( sender() ) )
 | 
			
		||||
@ -643,6 +700,15 @@ void QgsElevationProfileCanvas::scheduleDeferredUpdate()
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void QgsElevationProfileCanvas::scheduleDeferredRedraw()
 | 
			
		||||
{
 | 
			
		||||
  if ( !mDeferredRedrawScheduled )
 | 
			
		||||
  {
 | 
			
		||||
    mDeferredRedrawTimer->start( 1 );
 | 
			
		||||
    mDeferredRedrawScheduled = true;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void QgsElevationProfileCanvas::startDeferredUpdate()
 | 
			
		||||
{
 | 
			
		||||
  if ( mCurrentJob && !mCurrentJob->isActive() )
 | 
			
		||||
@ -653,6 +719,12 @@ void QgsElevationProfileCanvas::startDeferredUpdate()
 | 
			
		||||
  mDeferredUpdateScheduled = false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void QgsElevationProfileCanvas::startDeferredRedraw()
 | 
			
		||||
{
 | 
			
		||||
  mPlotItem->update();
 | 
			
		||||
  mDeferredRedrawScheduled = false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QgsProfilePoint QgsElevationProfileCanvas::canvasPointToPlotPoint( QPointF point ) const
 | 
			
		||||
{
 | 
			
		||||
  if ( !mPlotItem->plotArea().contains( point.x(), point.y() ) )
 | 
			
		||||
 | 
			
		||||
@ -205,9 +205,12 @@ class GUI_EXPORT QgsElevationProfileCanvas : public QgsPlotCanvas
 | 
			
		||||
 | 
			
		||||
    void generationFinished();
 | 
			
		||||
    void onLayerProfileGenerationPropertyChanged();
 | 
			
		||||
    void onLayerProfileRendererPropertyChanged();
 | 
			
		||||
    void updateResultsForLayer();
 | 
			
		||||
    void scheduleDeferredUpdate();
 | 
			
		||||
    void scheduleDeferredRedraw();
 | 
			
		||||
    void startDeferredUpdate();
 | 
			
		||||
    void startDeferredRedraw();
 | 
			
		||||
 | 
			
		||||
  private:
 | 
			
		||||
 | 
			
		||||
@ -236,6 +239,8 @@ class GUI_EXPORT QgsElevationProfileCanvas : public QgsPlotCanvas
 | 
			
		||||
    QgsProfilePlotRenderer *mCurrentJob = nullptr;
 | 
			
		||||
    QTimer *mDeferredUpdateTimer = nullptr;
 | 
			
		||||
    bool mDeferredUpdateScheduled = false;
 | 
			
		||||
    QTimer *mDeferredRedrawTimer = nullptr;
 | 
			
		||||
    bool mDeferredRedrawScheduled = false;
 | 
			
		||||
 | 
			
		||||
    std::unique_ptr< QgsCurve > mProfileCurve;
 | 
			
		||||
    double mTolerance = 0;
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user