QGIS API Documentation 4.3.0-Master (0ff9723465c)
Loading...
Searching...
No Matches
qgsvectorfieldstreamfield.h
Go to the documentation of this file.
1/***************************************************************************
2 qgsvectorfieldstreamfield.h
3 ---------------------------
4 begin : November 2019
5 copyright : (C) 2019 by Vincent Cloarec
6 email : vcloarec at gmail dot com
7 ***************************************************************************/
8
9/***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17
18#ifndef QGSVECTORFIELDSTREAMFIELD_H
19#define QGSVECTORFIELDSTREAMFIELD_H
20
21#include <list>
22#include <memory>
23
25#include "qgsmaptopixel.h"
26#include "qgsrendercontext.h"
28
29#include <QImage>
30#include <QPainter>
31#include <QSize>
32#include <QVector>
33
34#define SIP_NO_FILE
35
37
39
55class QgsVectorFieldStreamField
56{
57 public:
58 struct FieldData
59 {
60 double magnitude;
61 float time;
62 int directionX;
63 int directionY;
64 };
65
67 QgsVectorFieldStreamField( std::unique_ptr<QgsVectorFieldValueSource> source, const QgsRenderContext &rendererContext, const QgsInterpolatedLineColor &vectorColoring, int resolution = 1 );
68
69 QgsVectorFieldStreamField( const QgsVectorFieldStreamField &other );
70 virtual ~QgsVectorFieldStreamField();
71
78 void updateSize( const QgsRenderContext &renderContext );
79
84 void updateSize( const QgsRenderContext &renderContext, int resolution );
85
87 bool isValid() const;
88
90 QSize size() const;
91
93 QPoint topLeft() const;
94
96 void addTrace( QPoint startPixel );
97
99 void addTrace( QgsPointXY startPoint );
100
102 void addRandomTraces();
103
105 void addRandomTrace();
106
108 void addGriddedTraces( int dx, int dy );
109
116 void addTracesOnDataPoints( const QgsRectangle &extent );
117
119 void setResolution( int width );
120
122 int resolution() const;
123
125 QSize imageSize() const;
126
128 virtual QImage image() const;
129
131 void setPixelFillingDensity( double maxFilling );
132
134 void setColor( QColor color );
135
137 void setLineWidth( double width );
138
140 void setFilter( double min, double max );
141
143 void setMinimizeFieldSize( bool minimizeFieldSize );
144
146 QgsVectorFieldStreamField &operator=( const QgsVectorFieldStreamField &other );
147
148 protected:
149 virtual void initImage();
150 QPointF fieldToDevice( const QPoint &pixel ) const;
151
159 bool filterMag( double value ) const;
160 bool isTraceOutside( const QPoint &pixel ) const;
161
162 private:
163 QgsPointXY positionToMapCoordinates( const QPoint &pixelPosition, const QgsPointXY &positionInPixel );
164 bool addPixelToChunkTrace( QPoint &pixel, QgsVectorFieldStreamField::FieldData &data, std::list<QPair<QPoint, QgsVectorFieldStreamField::FieldData> > &chunkTrace );
165 void setChunkTrace( std::list<QPair<QPoint, FieldData>> &chunkTrace );
166 virtual void drawTrace( const QPoint & ) const {}
167 void clearChunkTrace( std::list<QPair<QPoint, FieldData>> &chunkTrace );
168 virtual void storeInField( const QPair<QPoint, FieldData> pixelData ) = 0;
169 virtual void initField() = 0;
170 void simplifyChunkTrace( std::list<QPair<QPoint, FieldData>> &shunkTrace );
171
172 virtual bool isTraceExists( const QPoint &pixel ) const = 0;
173
174 protected:
175 QSize mFieldSize;
176 std::unique_ptr<QPainter> mPainter = std::unique_ptr<QPainter>( nullptr );
177 int mFieldResolution = 1;
178 QPen mPen;
179 QImage mTraceImage;
180
181 QgsMapToPixel mMapToFieldPixel;
182 QgsRectangle mOutputExtent = QgsRectangle();
183 QgsInterpolatedLineColor mVectorColoring;
184
185 /*the direction for a pixel is defined with a char value
186 *
187 * 1 2 3
188 * 4 5 6
189 * 7 8 9
190 *
191 * convenient to retrieve the indexes of the next pixel from the direction d:
192 * Xnext= (d-1)%3-1
193 * Ynext = (d-1)/3-1
194 *
195 * and the direction is defined by :
196 * d=incX + 2 + (incY+1)*3
197 */
198 QVector<unsigned char> mDirectionField;
199 QgsRenderContext mRenderContext;
200
201 std::unique_ptr<QgsVectorFieldValueSource> mSource;
202
203 private:
204 int mPixelFillingCount = 0;
205 int mMaxPixelFillingCount = 0;
206 QgsRectangle mMapExtent;
207 QPoint mFieldTopLeftInDeviceCoordinates;
208 bool mValid = false;
209 double mPixelFillingDensity = 0;
210 double mMinMagFilter = -1;
211 double mMaxMagFilter = -1;
212 bool mMinimizeFieldSize = true; //
213};
214
223class QgsVectorFieldStreamlinesField : public QgsVectorFieldStreamField
224{
225 public:
227 QgsVectorFieldStreamlinesField(
228 std::unique_ptr<QgsVectorFieldValueSource> source, QgsRenderContext &rendererContext, const QgsInterpolatedLineColor &vectorColoring, QgsRasterBlockFeedback *feedBack = nullptr
229 );
230
231 void compose();
232
233 private:
234 void storeInField( const QPair<QPoint, FieldData> pixelData ) override;
235 void initField() override;
236 void initImage() override;
237 bool isTraceExists( const QPoint &pixel ) const override;
238 void drawTrace( const QPoint &start ) const override;
239
240 QVector<bool> mField;
241 QImage mDrawingTraceImage;
242 std::unique_ptr<QPainter> mDrawingTracePainter;
243
244 QgsRasterBlockFeedback *mFeedBack = nullptr;
245};
246
255struct QgsVectorFieldTraceParticle
256{
257 double lifeTime = 0;
258 QPoint position;
259 std::list<QPoint> tail;
260 double remainingTime = 0; //time remaining to spend in the current pixel at the end of the time step
261};
262
271class QgsVectorFieldParticleTracesField : public QgsVectorFieldStreamField
272{
273 public:
275 QgsVectorFieldParticleTracesField( std::unique_ptr<QgsVectorFieldValueSource> source, const QgsRenderContext &rendererContext, const QgsInterpolatedLineColor &vectorColoring );
276
277 QgsVectorFieldParticleTracesField( const QgsVectorFieldParticleTracesField &other );
278
280 void addParticle( const QPoint &startPoint, double lifeTime );
281
283 void addParticleXY( const QgsPointXY &startPoint, double lifeTime );
284
286 void addRandomParticles();
287
289 void moveParticles();
290
292 QImage imageRendered() const;
293
295 void setParticlesCount( int particlesCount );
296
298 void setParticlesLifeTime( double particlesLifeTime );
299
301 void stump();
302
308 void setStumpFactor( int sf );
309
311 void setTimeStep( double timeStep );
312
314 void setParticleSize( double particleSize );
315
317 void setTailFactor( double tailFactor );
318
320 void setMinTailLength( int minTailLength );
321
323 void setStumpParticleWithLifeTime( bool stumpParticleWithLifeTime );
324
326 void setParticlesColor( const QColor &c );
327
328 QgsVectorFieldParticleTracesField &operator=( const QgsVectorFieldParticleTracesField &other );
329
330 private:
331 QPoint direction( QPoint position ) const;
332
333 float time( QPoint position ) const;
334 float magnitude( QPoint position ) const;
335
336 void drawParticleTrace( const QgsVectorFieldTraceParticle &particle );
337
338 void storeInField( const QPair<QPoint, FieldData> pixelData ) override;
339 void initField() override;
340 bool isTraceExists( const QPoint &pixel ) const override;
341
342 /* Nondimensional time
343 * This field store the time spent by the particle in the pixel
344 *
345 * This time is nondimensional and value 1 is equivalent to the time spent by the particle in a pixel
346 * for Vmax, the maximum magnitude of the vector field.
347 *
348 */
349 QVector<float> mTimeField;
350 QVector<float> mMagnitudeField;
351
352 QList<QgsVectorFieldTraceParticle> mParticles;
353 QImage mStumpImage;
354
355 double mTimeStep = 200;
356 double mParticlesLifeTime = 5000;
357 int mParticlesCount = 1000;
358 double mTailFactor = 5;
359 int mMinTailLength = 3;
360 QColor mParticleColor = Qt::white;
361 double mParticleSize = 2.5;
362 int mStumpFactor = 50;
363 bool mStumpParticleWithLifeTime = true;
364};
365
367
368#endif // QGSVECTORFIELDSTREAMFIELD_H
Feedback object tailored for raster block reading.
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c