iLand
grid.h
Go to the documentation of this file.
1/********************************************************************************************
2** iLand - an individual based forest landscape and disturbance model
3** http://iland-model.org
4** Copyright (C) 2009- Werner Rammer, Rupert Seidl
5**
6** This program is free software: you can redistribute it and/or modify
7** it under the terms of the GNU General Public License as published by
8** the Free Software Foundation, either version 3 of the License, or
9** (at your option) any later version.
10**
11** This program is distributed in the hope that it will be useful,
12** but WITHOUT ANY WARRANTY; without even the implied warranty of
13** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14** GNU General Public License for more details.
15**
16** You should have received a copy of the GNU General Public License
17** along with this program. If not, see <http://www.gnu.org/licenses/>.
18********************************************************************************************/
19
20#ifndef GRID_H
21#define GRID_H
22
23#include <QtCore>
24
25
26#include <stdexcept>
27#include <limits>
28#include <cstring>
29
30#include "global.h"
31
43template <class T>
44class Grid {
45public:
46
48 Grid(float cellsize, int sizex, int sizey) { mData=0; setup(cellsize, sizex, sizey); }
50 Grid(const QRectF rect_metric, const float cellsize) { mData=0; setup(rect_metric,cellsize); }
53 bool loadGridFromFile(const QString &fileName);
54 // copy ctor
55 Grid(const Grid<T>& toCopy);
56 ~Grid() { clear(); }
57 void clear() { if (mData) delete[] mData; mData=0; }
58
59 bool setup(const float cellsize, const int sizex, const int sizey);
60 bool setup(const QRectF& rect, const double cellsize);
61 bool setup(const Grid<T>& source) { clear(); mRect = source.mRect; return setup(source.mRect, source.mCellsize); }
62 void initialize(const T& value) {for( T *p = begin();p!=end(); ++p) *p=value; }
63 void wipe();
64 void wipe(const T value);
67 void copy(const Grid<T> &source) { if (source.count()==count()) memcpy(mData, source.mData, count()*sizeof(T)); }
71
72 // get the number of cells in x and y direction
73 int sizeX() const { return mSizeX; }
74 int sizeY() const { return mSizeY; }
75 // get the size of the grid in metric coordinates (x and y direction)
76 float metricSizeX() const { return mSizeX*mCellsize; }
77 float metricSizeY() const { return mSizeY*mCellsize; }
79 QRectF metricRect() const { return mRect; }
81 void setMetricRect(QRectF rect) { mRect = rect; }
83 QRect rectangle() const { return QRect(QPoint(0,0), QPoint(sizeX(), sizeY())); }
85 float cellsize() const { return mCellsize; }
86 int count() const { return mCount; }
87 bool isEmpty() const { return mData==NULL; }
88 // operations
89 // query
91 inline const T& operator()(const int ix, const int iy) const { return constValueAtIndex(ix, iy); }
93 inline const T& operator()(const float x, const float y) const { return constValueAt(x, y); }
95 inline const T& operator[](const QPoint &p) const { return constValueAtIndex(p); }
97 inline T& operator[](const int idx) const { return mData[idx]; }
99 inline T& operator[] (const QPointF &p) { return valueAt(p); }
101 inline T& operator[] (const QPoint &p) { return valueAtIndex(p); }
102
103 inline T& valueAtIndex(const QPoint& pos) {return valueAtIndex(pos.x(), pos.y());}
104 T& valueAtIndex(const int ix, const int iy) { return mData[iy*mSizeX + ix]; }
105 T& valueAtIndex(const int index) {return mData[index]; }
106 inline int index(const int ix, const int iy) { return iy*mSizeX + ix; }
107 inline int index(const QPoint &pos) { return pos.y()*mSizeX + pos.x(); }
109 inline const T& constValueAtIndex(const QPoint& pos) const {return constValueAtIndex(pos.x(), pos.y()); }
111 inline const T& constValueAtIndex(const int ix, const int iy) const { return mData[iy*mSizeX + ix]; }
113 const T& constValueAtIndex(const int index) const {return mData[index]; }
114
115 T& valueAt(const QPointF& posf);
116 const T& constValueAt(const QPointF& posf) const;
117
118 T& valueAt(const float x, const float y);
119 const T& constValueAt(const float x, const float y) const;
120
121
122 bool coordValid(const float x, const float y) const { return x>=mRect.left() && x<mRect.right() && y>=mRect.top() && y<mRect.bottom(); }
123 bool coordValid(const QPointF &pos) const { return coordValid(pos.x(), pos.y()); }
124
125 QPoint indexAt(const QPointF& pos) const { return QPoint(int((pos.x()-mRect.left()) / mCellsize), int((pos.y()-mRect.top())/mCellsize)); }
127 QPoint indexOf(const int index) const {return QPoint(index % mSizeX, index / mSizeX); }
128 bool isIndexValid(const QPoint& pos) const { return (pos.x()>=0 && pos.x()<mSizeX && pos.y()>=0 && pos.y()<mSizeY); }
129 bool isIndexValid(const int x, const int y) const {return (x>=0 && x<mSizeX && y>=0 && y<mSizeY); }
130
132 int index2(int idx) const {return ((idx/mSizeX)/2)*(mSizeX/2) + (idx%mSizeX)/2; }
134 int index5(int idx) const {return ((idx/mSizeX)/5)*(mSizeX/5) + (idx%mSizeX)/5; }
136 int index10(int idx) const {return ((idx/mSizeX)/10)*(mSizeX/10) + (idx%mSizeX)/10; }
137
139 void validate(QPoint &pos) const{ pos.setX( qMax(qMin(pos.x(), mSizeX-1), 0) ); pos.setY( qMax(qMin(pos.y(), mSizeY-1), 0) );}
141 QPointF cellCenterPoint(const QPoint &pos) const { return QPointF( (pos.x()+0.5)*mCellsize+mRect.left(), (pos.y()+0.5)*mCellsize + mRect.top());}
143 QPointF cellCenterPoint(const int &index) const { QPoint pos=indexOf(index); return QPointF( (pos.x()+0.5)*mCellsize+mRect.left(), (pos.y()+0.5)*mCellsize + mRect.top());}
145 QPointF cellCenterPoint(T* ptr) { QPoint pos = indexOf(ptr); return cellCenterPoint(pos); }
147 QRectF cellRect(const QPoint &pos) const { QRectF r( QPointF(mRect.left() + mCellsize*pos.x(), mRect.top() + pos.y()*mCellsize),
148 QSizeF(mCellsize, mCellsize)); return r; }
149
150 inline T* begin() const { return mData; }
151 inline T* end() const { return mEnd; }
152 inline QPoint indexOf(const T* element) const;
153 // special queries
154 T max() const;
155 T min() const;
156 T sum() const;
157 T avg() const;
158 // modifying operations
159 void add(const T& summand);
160 void multiply(const T& factor);
162 void limit(const T min_value, const T max_value);
163
168 Grid<T> averaged(const int factor, const int offsetx=0, const int offsety=0) const;
171 Grid<T> normalized(const T targetvalue) const;
172 T* ptr(int x, int y) { return &(mData[y*mSizeX + x]); }
173 inline double distance(const QPoint &p1, const QPoint &p2);
174 const QPoint randomPosition() const;
178 int floodFill(QPoint start, T old_color, T color, int max_fill=-1);
179private:
180
181 T* mData;
182 T* mEnd;
183 QRectF mRect;
184 float mCellsize;
185 int mSizeX;
186 int mSizeY;
187 int mCount;
188};
189
190
192
196
199template <class T>
201public:
202 // constructors with a QRectF (metric coordinates)
203 GridRunner(Grid<T> &target_grid, const QRectF &rectangle) {setup(&target_grid, rectangle);}
204 GridRunner(const Grid<T> &target_grid, const QRectF &rectangle) {setup(&target_grid, rectangle);}
205 GridRunner(Grid<T> *target_grid, const QRectF &rectangle) {setup(target_grid, rectangle);}
206 // constructors with a QRect (indices within the grid)
207 GridRunner(Grid<T> &target_grid, const QRect &rectangle) {setup(&target_grid, rectangle);}
208 GridRunner(const Grid<T> &target_grid, const QRect &rectangle) {setup(&target_grid, rectangle);}
209 GridRunner(Grid<T> *target_grid, const QRect &rectangle) {setup(target_grid, rectangle);}
210 GridRunner(Grid<T> *target_grid) {setup(target_grid, target_grid->rectangle()); }
211 T* next();
213 T* current() const { return mCurrent; }
215 T* first() const { return mFirst; }
217 T* last() const { return mLast; }
219 bool isValid() const {return mCurrent>=mFirst && mCurrent<=mLast; }
221 QPoint currentIndex() const { return mGrid->indexOf(mCurrent); }
223 QPointF currentCoord() const {return mGrid->cellCenterPoint(mGrid->indexOf(mCurrent));}
224 void reset() { mCurrent = mFirst-1; mCurrentCol = -1; }
226 void setPosition(QPoint new_index) { if (mGrid->isIndexValid(new_index)) mCurrent = const_cast<Grid<T> *>(mGrid)->ptr(new_index.x(), new_index.y()); else mCurrent=0; }
227 // helpers
231 void neighbors4(T** rArray);
232 void neighbors8(T** rArray);
233private:
234 void setup(const Grid<T> *target_grid, const QRectF &rectangle);
235 void setup(const Grid<T> *target_grid, const QRect &rectangle);
236 const Grid<T> *mGrid;
237 T* mFirst; // points to the first element of the grid
238 T* mLast; // points to the last element of the grid
239 T* mCurrent;
240 size_t mLineLength;
241 size_t mCols;
242 int mCurrentCol;
243};
244
249{
250 public:
251 Vector3D(): mX(0.), mY(0.), mZ(0.) {}
252 Vector3D(const double x, const double y, const double z): mX(x), mY(y), mZ(z) {}
253 double x() const { return mX; }
254 double y() const { return mY; }
255 double z() const { return mZ; }
256 // set variables
257 void setX(const double x) { mX=x; }
258 void setY(const double y) { mY=y; }
259 void setZ(const double z) { mZ=z; }
260private:
261 double mX;
262 double mY;
263 double mZ;
264};
265
266// copy constructor
267template <class T>
268Grid<T>::Grid(const Grid<T>& toCopy)
269{
270 mData = 0;
271 mRect = toCopy.mRect;
272 setup(toCopy.metricRect(), toCopy.cellsize());
273 //setup(toCopy.cellsize(), toCopy.sizeX(), toCopy.sizeY());
274 const T* end = toCopy.end();
275 T* ptr = begin();
276 for (T* i= toCopy.begin(); i!=end; ++i, ++ptr)
277 *ptr = *i;
278}
279
280// normalize function
281template <class T>
282Grid<T> Grid<T>::normalized(const T targetvalue) const
283{
284 Grid<T> target(*this);
285 T total = sum();
286 T multiplier;
287 if (total)
288 multiplier = targetvalue / total;
289 else
290 return target;
291 for (T* p=target.begin();p!=target.end();++p)
292 *p *= multiplier;
293 return target;
294}
295
296
297template <class T>
298Grid<T> Grid<T>::averaged(const int factor, const int offsetx, const int offsety) const
299{
300 Grid<T> target;
301 target.setup(metricRect(), cellsize()*factor);
302 int x,y;
303 T sum=0;
304 target.initialize(sum);
305 // sum over array of 2x2, 3x3, 4x4, ...
306 for (x=offsetx;x<mSizeX;x++)
307 for (y=offsety;y<mSizeY;y++) {
308 target.valueAtIndex((x-offsetx)/factor, (y-offsety)/factor) += constValueAtIndex(x,y);
309 }
310 // divide
311 double fsquare = factor*factor;
312 for (T* p=target.begin();p!=target.end();++p)
313 *p /= fsquare;
314 return target;
315}
316
317
318template <class T>
319T& Grid<T>::valueAt(const float x, const float y)
320{
321 return valueAtIndex( indexAt(QPointF(x,y)) );
322}
323
324template <class T>
325const T& Grid<T>::constValueAt(const float x, const float y) const
326{
327 return constValueAtIndex( indexAt(QPointF(x,y)) );
328}
329
330template <class T>
331T& Grid<T>::valueAt(const QPointF& posf)
332{
333 return valueAtIndex( indexAt(posf) );
334}
335
336template <class T>
337const T& Grid<T>::constValueAt(const QPointF& posf) const
338{
339 return constValueAtIndex( indexAt(posf) );
340}
341
342template <class T>
344{
345 mData = 0; mCellsize=0.f;
346 mEnd = 0;
347 mSizeX=0; mSizeY=0; mCount=0;
348}
349
350template <class T>
351bool Grid<T>::setup(const float cellsize, const int sizex, const int sizey)
352{
353 mSizeX=sizex; mSizeY=sizey;
354 if (mRect.isNull()) // only set rect if not set before (e.g. by call to setup(QRectF, double))
355 mRect.setCoords(0., 0., cellsize*sizex, cellsize*sizey);
356
357 if (mData) {
358 // test if we can re-use the allocated memory.
359 if (mSizeX*mSizeY > mCount || mCellsize != cellsize) {
360 // we cannot re-use the memory - create new data
361 delete[] mData; mData=NULL;
362 }
363 }
364 mCellsize=cellsize;
365 mCount = mSizeX*mSizeY;
366 if (mCount==0)
367 return false;
368 if (mData==NULL)
369 mData = new T[mCount];
370 mEnd = &(mData[mCount]);
371 return true;
372}
373
374template <class T>
375bool Grid<T>::setup(const QRectF& rect, const double cellsize)
376{
377 mRect = rect;
378 int dx = int(rect.width()/cellsize);
379 if (mRect.left()+cellsize*dx<rect.right())
380 dx++;
381 int dy = int(rect.height()/cellsize);
382 if (mRect.top()+cellsize*dy<rect.bottom())
383 dy++;
384 return setup(cellsize, dx, dy);
385}
386
393template <class T> inline
394QPoint Grid<T>::indexOf(const T* element) const
395{
396// QPoint result(-1,-1);
397 if (element==NULL || element<mData || element>=end())
398 return QPoint(-1, -1);
399 int idx = element - mData;
400 return QPoint(idx % mSizeX, idx / mSizeX);
401// result.setX( idx % mSizeX);
402// result.setY( idx / mSizeX);
403// return result;
404}
405
406template <class T>
408{
409 T maxv = -std::numeric_limits<T>::max();
410 T* p;
411 T* pend = end();
412 for (p=begin(); p!=pend;++p)
413 maxv = std::max(maxv, *p);
414 return maxv;
415}
416
417template <class T>
419{
420 T maxv = std::numeric_limits<T>::max();
421 T* p;
422 T* pend = end();
423 for (p=begin(); p!=pend;++p)
424 maxv = std::min(maxv, *p);
425 return maxv;
426}
427
428template <class T>
430{
431 T* pend = end();
432 T total = 0;
433 for (T *p=begin(); p!=pend;++p)
434 total += *p;
435 return total;
436}
437
438template <class T>
440{
441 if (count())
442 return sum() / T(count());
443 else return 0;
444}
445
446template <class T>
447void Grid<T>::add(const T& summand)
448{
449 T* pend = end();
450 for (T *p=begin(); p!=pend;*p+=summand,++p)
451 ;
452}
453
454template <class T>
455void Grid<T>::multiply(const T& factor)
456{
457 T* pend = end();
458 for (T *p=begin(); p!=pend;*p*=factor,++p)
459 ;
460}
461
462template <class T>
463void Grid<T>::limit(const T min_value, const T max_value)
464{
465 T* pend = end();
466 for (T *p=begin(); p!=pend;++p)
467 *p = *p < min_value ? min_value : (*p>max_value? max_value : *p);
468}
469
470
471
472template <class T>
474{
475 memset(mData, 0, mCount*sizeof(T));
476}
477template <class T>
478void Grid<T>::wipe(const T value)
479{
480 /* this does not work properly !!! */
481 if (sizeof(T)==sizeof(int)) {
482 float temp = value;
483 float *pf = &temp;
484
485 memset(mData, *((int*)pf), mCount*sizeof(T));
486 } else
487 initialize(value);
488}
489
490template <class T>
492{
493 Grid<double> *g = new Grid<double>();
494 g->setup(metricRect(), cellsize());
495 if (g->isEmpty())
496 return g;
497 double *dp = g->begin();
498 for (T *p=begin(); p!=end(); ++p, ++dp)
499 *dp = *p;
500 return g;
501}
502
503template <class T>
504double Grid<T>::distance(const QPoint &p1, const QPoint &p2)
505{
506 QPointF fp1=cellCenterPoint(p1);
507 QPointF fp2=cellCenterPoint(p2);
508 double distance = sqrt( (fp1.x()-fp2.x())*(fp1.x()-fp2.x()) + (fp1.y()-fp2.y())*(fp1.y()-fp2.y()));
509 return distance;
510}
511
512template <class T>
513const QPoint Grid<T>::randomPosition() const
514{
515 return QPoint(irandom(0,mSizeX), irandom(0, mSizeY));
516}
517
518
519// quick and dirty implementation of the flood fill algroithm.
520// based on: http://en.wikipedia.org/wiki/Flood_fill
521// returns the number of pixels colored
522template<class T>
523int Grid<T>::floodFill(QPoint start, T old_color, T color, int max_fill)
524{
525
526 QQueue<QPoint> pqueue;
527 pqueue.enqueue(start);
528 int found = 0;
529 while (!pqueue.isEmpty()) {
530 QPoint p = pqueue.dequeue();
531 if (!isIndexValid(p))
532 continue;
533 if (valueAtIndex(p)==old_color) {
534 valueAtIndex(p) = color;
535 pqueue.enqueue(p+QPoint(-1,0));
536 pqueue.enqueue(p+QPoint(1,0));
537 pqueue.enqueue(p+QPoint(0,-1));
538 pqueue.enqueue(p+QPoint(0,1));
539 pqueue.enqueue(p+QPoint(1,1));
540 pqueue.enqueue(p+QPoint(1,-1));
541 pqueue.enqueue(p+QPoint(-1,1));
542 pqueue.enqueue(p+QPoint(-1,-1));
543 ++found;
544 if (max_fill > 0 && found>=max_fill)
545 break;
546 }
547 }
548 return found;
549
550}
551
553// grid runner
555template <class T>
556void GridRunner<T>::setup(const Grid<T> *target_grid, const QRect &rectangle)
557{
558 QPoint upper_left = rectangle.topLeft();
559 // due to the strange behavior of QRect::bottom() and right():
560 QPoint lower_right = rectangle.bottomRight();
561 mCurrent = const_cast<Grid<T> *>(target_grid)->ptr(upper_left.x(), upper_left.y());
562 mFirst = mCurrent;
563 mCurrent--; // point to first element -1
564 mLast = const_cast<Grid<T> *>(target_grid)->ptr(lower_right.x()-1, lower_right.y()-1);
565 mCols = lower_right.x() - upper_left.x(); //
566 mLineLength = target_grid->sizeX() - mCols;
567 mCurrentCol = -1;
568 mGrid = target_grid;
569// qDebug() << "GridRunner: rectangle:" << rectangle
570// << "upper_left:" << target_grid.cellCenterPoint(target_grid.indexOf(mCurrent))
571// << "lower_right:" << target_grid.cellCenterPoint(target_grid.indexOf(mLast));
572}
573
574template <class T>
575void GridRunner<T>::setup(const Grid<T> *target_grid, const QRectF &rectangle_metric)
576{
577 QRect rect(target_grid->indexAt(rectangle_metric.topLeft()),
578 target_grid->indexAt(rectangle_metric.bottomRight()) );
579 setup (target_grid, rect);
580}
581
582template <class T>
584{
585 if (mCurrent>mLast)
586 return NULL;
587 mCurrent++;
588 mCurrentCol++;
589
590 if (mCurrentCol >= int(mCols)) {
591 mCurrent += mLineLength; // skip to next line
592 mCurrentCol = 0;
593 }
594 if (mCurrent>mLast)
595 return NULL;
596 else
597 return mCurrent;
598}
599
600template <class T>
605{
606 // north:
607 rArray[0] = mCurrent + mCols + mLineLength > mLast?0: mCurrent + mCols + mLineLength;
608 // south:
609 rArray[3] = mCurrent - (mCols + mLineLength) < mFirst?0: mCurrent - (mCols + mLineLength);
610 // east / west
611 rArray[1] = mCurrentCol+1<int(mCols)? mCurrent + 1 : 0;
612 rArray[2] = mCurrentCol>0? mCurrent-1 : 0;
613}
614
618template <class T>
620{
621 neighbors4(rArray);
622 // north-east
623 rArray[4] = rArray[0] && rArray[1]? rArray[0]+1: 0;
624 // north-west
625 rArray[5] = rArray[0] && rArray[2]? rArray[0]-1: 0;
626 // south-east
627 rArray[6] = rArray[3] && rArray[1]? rArray[3]+1: 0;
628 // south-west
629 rArray[7] = rArray[3] && rArray[2]? rArray[3]-1: 0;
630
631}
632
634// global functions
636
639QString gridToString(const FloatGrid &grid, const QChar sep=QChar(';'), const int newline_after=-1);
640
646QImage gridToImage(const FloatGrid &grid,
647 bool black_white=false,
648 double min_value=0., double max_value=1.,
649 bool reverse=false);
650
651
655bool loadGridFromImage(const QString &fileName, FloatGrid &rGrid);
656
660template <class T>
661 QString gridToString(const Grid<T> &grid, const QChar sep=QChar(';'), const int newline_after=-1)
662{
663 QString res;
664 QTextStream ts(&res);
665
666 int newl_counter = newline_after;
667 for (int y=grid.sizeY()-1;y>=0;--y){
668 for (int x=0;x<grid.sizeX();x++){
669 ts << grid.constValueAtIndex(x,y) << sep;
670 if (--newl_counter==0) {
671 ts << "\r\n";
672 newl_counter = newline_after;
673 }
674 }
675 ts << "\r\n";
676 }
677
678 return res;
679}
680
685template <class T>
686 QString gridToString(const Grid<T> &grid, QString (*valueFunction)(const T& value), const QChar sep=QChar(';'), const int newline_after=-1 )
687 {
688 QString res;
689 QTextStream ts(&res);
690
691 int newl_counter = newline_after;
692 for (int y=grid.sizeY()-1;y>=0;--y){
693 for (int x=0;x<grid.sizeX();x++){
694 ts << (*valueFunction)(grid.constValueAtIndex(x,y)) << sep;
695
696 if (--newl_counter==0) {
697 ts << "\r\n";
698 newl_counter = newline_after;
699 }
700 }
701 ts << "\r\n";
702 }
703
704 return res;
705 }
706void modelToWorld(const Vector3D &From, Vector3D &To);
707
708template <class T>
709 QString gridToESRIRaster(const Grid<T> &grid, QString (*valueFunction)(const T& value) )
710{
711 Vector3D model(grid.metricRect().left(), grid.metricRect().top(), 0.);
712 Vector3D world;
713 modelToWorld(model, world);
714 QString result = QString("ncols %1\r\nnrows %2\r\nxllcorner %3\r\nyllcorner %4\r\ncellsize %5\r\nNODATA_value %6\r\n")
715 .arg(grid.sizeX())
716 .arg(grid.sizeY())
717 .arg(world.x(),0,'f').arg(world.y(),0,'f')
718 .arg(grid.cellsize()).arg(-9999);
719 QString line = gridToString(grid, valueFunction, QChar(' ')); // for special grids
720 return result + line;
721}
722
723 template <class T>
724 QString gridToESRIRaster(const Grid<T> &grid )
725{
726 Vector3D model(grid.metricRect().left(), grid.metricRect().top(), 0.);
727 Vector3D world;
728 modelToWorld(model, world);
729 QString result = QString("ncols %1\r\nnrows %2\r\nxllcorner %3\r\nyllcorner %4\r\ncellsize %5\r\nNODATA_value %6\r\n")
730 .arg(grid.sizeX())
731 .arg(grid.sizeY())
732 .arg(world.x(),0,'f').arg(world.y(),0,'f')
733 .arg(grid.cellsize()).arg(-9999);
734 QString line = gridToString(grid, QChar(' ')); // for normal grids (e.g. float)
735 return result + line;
736}
737
738
739template <class T>
740 bool Grid<T>::loadGridFromFile(const QString &fileName)
741 {
742 double min_value = 1000000000;
743 double max_value = -1000000000;
744
745 // loads from a ESRI-Grid [RasterToFile] File.
746 QFile file(fileName);
747
748 if (!file.open(QIODevice::ReadOnly)) {
749 qDebug() << "Grid::loadGridFromFile: " << fileName << "does not exist!";
750 return false;
751 }
752 QTextStream s(&file);
753 //s.setCodec("UTF-8");
754 QByteArray file_content=s.readAll().toLatin1();
755
756 if (file_content.isEmpty()) {
757 qDebug() << "GISGrid: file" << fileName << "not present or empty.";
758 return false;
759 }
760 QList<QByteArray> lines = file_content.split('\n');
761
762 // processing of header-data
763 bool header=true;
764 int pos=0;
765 QString line;
766 QString key;
767 double value;
768 int ncol=0, nrow=0;
769 double cellsize=0;
770 double ox=0., oy=0.;
771 double no_data_val=0.;
772 do {
773 if (pos>lines.count())
774 throw IException("Grid load from ASCII file: unexpected end of file. File: " + fileName);
775 line=lines[pos].simplified();
776 if (line.length()==0 || line.at(0)=='#') {
777 pos++; // skip comments
778 continue;
779 }
780 key=line.left(line.indexOf(' ')).toLower();
781 if (key.length()>0 && (key.at(0).isNumber() || key.at(0)=='-')) {
782 header=false;
783 } else {
784 value = line.mid(line.indexOf(' ')).toDouble();
785 if (key=="ncols")
786 ncol=(int)value;
787 else if (key=="nrows")
788 nrow=int(value);
789 else if (key=="xllcorner")
790 ox = value;
791 else if (key=="yllcorner")
792 oy = value;
793 else if (key=="cellsize")
794 cellsize = value;
795 else if (key=="nodata_value")
796 no_data_val=value;
797 else
798 throw IException( QString("GISGrid: invalid key %1.").arg(key));
799 pos++;
800 }
801 } while (header);
802
803 // create the grid
804 QRectF rect(ox, oy, ncol*cellsize, nrow*cellsize);
805 setup( rect, cellsize );
806
807
808 // loop thru datalines
809 int i,j;
810 char *p=nullptr;
811 char *p2;
812 pos--;
813 for (i=nrow-1;i>=0;i--)
814 for (j=0;j<ncol;j++) {
815 // copy next value to buffer, change "," to "."
816 if (!p || *p==0) {
817 pos++;
818 if (pos>=lines.count())
819 throw std::logic_error("GISGrid: Unexpected End of File!");
820 p=lines[pos].data();
821 // replace chars
822 p2=p;
823 while (*p2) {
824 if (*p2==',')
825 *p2='.';
826 p2++;
827 }
828 }
829 // skip spaces
830 while (*p && strchr(" \r\n\t", *p))
831 p++;
832 if (*p) {
833 value = atof(p);
834 if (value!=no_data_val) {
835 min_value=std::min(min_value, value);
836 max_value=std::max(max_value, value);
837 }
838 valueAtIndex(j,i) = value;
839 // skip text...
840 while (*p && !strchr(" \r\n\t", *p))
841 p++;
842 } else
843 j--;
844 }
845
846 return true;
847 }
848
849
850#endif // GRID_H
Grid class (template).
Definition: grid.h:44
Grid< double > * toDouble() const
create a double grid (same size as this grid) and convert this grid to double values.
Definition: grid.h:491
QRectF metricRect() const
get the metric rectangle of the grid
Definition: grid.h:79
void setMetricRect(QRectF rect)
set the metric rectangle. Use with care! No further checks are executed!
Definition: grid.h:81
~Grid()
Definition: grid.h:56
T & valueAtIndex(const int index)
get a ref ot value at (one-dimensional) index 'index'.
Definition: grid.h:105
int count() const
returns the number of elements of the grid
Definition: grid.h:86
T min() const
retrieve the minimum value of a grid
Definition: grid.h:418
bool loadGridFromFile(const QString &fileName)
load a grid from an ASCII grid file the coordinates and cell size remain as in the grid file.
Definition: grid.h:740
QPointF cellCenterPoint(const int &index) const
get the metric cell center point of the cell given by index 'index'
Definition: grid.h:143
const T & operator[](const QPoint &p) const
access value of grid with a QPoint
Definition: grid.h:95
T * ptr(int x, int y)
get a pointer to the element indexed by "x" and "y"
Definition: grid.h:172
bool setup(const float cellsize, const int sizex, const int sizey)
Definition: grid.h:351
void validate(QPoint &pos) const
force
Definition: grid.h:139
T * begin() const
get "iterator" pointer
Definition: grid.h:150
QPointF cellCenterPoint(const QPoint &pos) const
get the (metric) centerpoint of cell with index pos
Definition: grid.h:141
Grid< T > averaged(const int factor, const int offsetx=0, const int offsety=0) const
creates a grid with lower resolution and averaged cell values.
Definition: grid.h:298
float metricSizeY() const
Definition: grid.h:77
int index2(int idx) const
returns the index of an aligned grid (with the same size and matching origin) with the double cell si...
Definition: grid.h:132
void multiply(const T &factor)
Definition: grid.h:455
Grid(const Grid< T > &toCopy)
Definition: grid.h:268
T avg() const
retrieve the average value of a grid
Definition: grid.h:439
QRectF cellRect(const QPoint &pos) const
get the metric rectangle of the cell with index @pos
Definition: grid.h:147
const T & operator()(const int ix, const int iy) const
access (const) with index variables. use int.
Definition: grid.h:91
QPoint indexAt(const QPointF &pos) const
get index of value at position pos (metric)
Definition: grid.h:125
Grid(const QRectF rect_metric, const float cellsize)
create from a metric rect
Definition: grid.h:50
const T & constValueAtIndex(const int index) const
value at position defined by the index within the grid
Definition: grid.h:113
void clear()
Definition: grid.h:57
Grid(float cellsize, int sizex, int sizey)
Definition: grid.h:48
Grid()
Definition: grid.h:343
bool setup(const Grid< T > &source)
Definition: grid.h:61
int index10(int idx) const
returns the index of an aligned grid (the same size) with the 10 times bigger cells (e....
Definition: grid.h:136
int sizeX() const
Definition: grid.h:73
const T & constValueAt(const QPointF &posf) const
value at position defined by metric coordinates (QPointF)
Definition: grid.h:337
const T & operator()(const float x, const float y) const
access (const) using metric variables. use float.
Definition: grid.h:93
int index(const QPoint &pos)
get the 0-based index of the cell at 'pos'.
Definition: grid.h:107
void initialize(const T &value)
Definition: grid.h:62
T & valueAtIndex(const int ix, const int iy)
const value at position defined by indices (x,y)
Definition: grid.h:104
void wipe(const T value)
overwrite the whole area with "value" size of T must be the size of "int" ERRORNOUS!...
Definition: grid.h:478
QPoint indexOf(const T *element) const
retrieve index (x/y) of the pointer element. returns -1/-1 if element is not valid.
Definition: grid.h:394
bool coordValid(const float x, const float y) const
Definition: grid.h:122
const T & constValueAtIndex(const QPoint &pos) const
value at position defined by a (integer) QPoint
Definition: grid.h:109
void wipe()
write 0-bytes with memcpy to the whole area
Definition: grid.h:473
T sum() const
retrieve the sum of the grid
Definition: grid.h:429
bool coordValid(const QPointF &pos) const
Definition: grid.h:123
T & valueAt(const QPointF &posf)
value at position defined by metric coordinates (QPointF)
Definition: grid.h:331
int index(const int ix, const int iy)
get the 0-based index of the cell with indices ix and iy.
Definition: grid.h:106
const QPoint randomPosition() const
returns a (valid) random position within the grid
Definition: grid.h:513
const T & constValueAtIndex(const int ix, const int iy) const
value at position defined by a pair of integer coordinates
Definition: grid.h:111
const T & constValueAt(const float x, const float y) const
value at position defined by metric coordinates (x,y)
Definition: grid.h:325
T & operator[](const int idx) const
use the square brackets to access by index
Definition: grid.h:97
T & valueAtIndex(const QPoint &pos)
value at position defined by a QPoint defining the two indices (x,y)
Definition: grid.h:103
int sizeY() const
Definition: grid.h:74
int index5(int idx) const
returns the index of an aligned grid (the same size) with the 5 times bigger cells (e....
Definition: grid.h:134
bool setup(const QRectF &rect, const double cellsize)
Definition: grid.h:375
bool isIndexValid(const QPoint &pos) const
return true, if position is within the grid
Definition: grid.h:128
T * end() const
get iterator end-pointer
Definition: grid.h:151
float cellsize() const
get the length of one pixel of the grid
Definition: grid.h:85
QPoint indexOf(const int index) const
get index (x/y) of the (linear) index 'index' (0..count-1)
Definition: grid.h:127
int floodFill(QPoint start, T old_color, T color, int max_fill=-1)
applies a flood fill algorithm to the grid starting at 'start' fills the contingent area with value '...
Definition: grid.h:523
QRect rectangle() const
get the rectangle of the grid in terms of indices
Definition: grid.h:83
T max() const
retrieve the maximum value of a grid
Definition: grid.h:407
void limit(const T min_value, const T max_value)
limit each cell value to (including) min_value and (including) max_value
Definition: grid.h:463
Grid< T > normalized(const T targetvalue) const
normalized returns a normalized grid, in a way that the sum() =
Definition: grid.h:282
double distance(const QPoint &p1, const QPoint &p2)
distance (metric) between p1 and p2
Definition: grid.h:504
float metricSizeX() const
Definition: grid.h:76
bool isEmpty() const
returns false if the grid was not setup
Definition: grid.h:87
void copy(const Grid< T > &source)
copies the content of the source grid to this grid.
Definition: grid.h:67
void add(const T &summand)
Definition: grid.h:447
QPointF cellCenterPoint(T *ptr)
get the metric cell center point of the cell given py the pointer
Definition: grid.h:145
bool isIndexValid(const int x, const int y) const
return true, if index is within the grid
Definition: grid.h:129
T & valueAt(const float x, const float y)
value at position defined by metric coordinates (x,y)
Definition: grid.h:319
helper class to iterate over a rectangular fraction of a grid
Definition: grid.h:200
GridRunner(Grid< T > *target_grid, const QRectF &rectangle)
Definition: grid.h:205
GridRunner(Grid< T > &target_grid, const QRect &rectangle)
Definition: grid.h:207
GridRunner(Grid< T > *target_grid, const QRect &rectangle)
Definition: grid.h:209
void neighbors8(T **rArray)
get pointers to the 8-neighbor-hood north/east/west/south/NE/NW/SE/SW 0-pointers are returned for edg...
Definition: grid.h:619
T * current() const
return the current element, or NULL
Definition: grid.h:213
T * first() const
return the first element
Definition: grid.h:215
QPoint currentIndex() const
return the (index) - coordinates of the current position in the grid
Definition: grid.h:221
GridRunner(const Grid< T > &target_grid, const QRectF &rectangle)
Definition: grid.h:204
void neighbors4(T **rArray)
fill array with pointers to neighbors (north, east, west, south) or Null-pointers if out of range.
Definition: grid.h:604
GridRunner(Grid< T > &target_grid, const QRectF &rectangle)
Definition: grid.h:203
GridRunner(const Grid< T > &target_grid, const QRect &rectangle)
Definition: grid.h:208
bool isValid() const
checks if the state of the GridRunner is valid, returns false if out of scope
Definition: grid.h:219
T * last() const
return the last element (not one element behind the last element!)
Definition: grid.h:217
void reset()
Definition: grid.h:224
T * next()
to to next element, return NULL if finished
Definition: grid.h:583
void setPosition(QPoint new_index)
set the internal pointer to the pixel at index 'new_index'. The index is relative to the base grid!
Definition: grid.h:226
QPointF currentCoord() const
return the coordinates of the cell center point of the current position in the grid.
Definition: grid.h:223
GridRunner(Grid< T > *target_grid)
Definition: grid.h:210
Exception IException is the iLand model exception class.
Definition: exception.h:27
simple 3d vector.
Definition: grid.h:249
Vector3D()
Definition: grid.h:251
double y() const
get y-coordinate
Definition: grid.h:254
void setZ(const double z)
set value of the z-coordinate
Definition: grid.h:259
Vector3D(const double x, const double y, const double z)
Definition: grid.h:252
void setX(const double x)
set value of the x-coordinate
Definition: grid.h:257
double x() const
get x-coordinate
Definition: grid.h:253
void setY(const double y)
set value of the y-coordinate
Definition: grid.h:258
double z() const
get z-coordinate
Definition: grid.h:255
double distance(const QPointF &a, const QPointF &b)
Definition: mainwindow.cpp:30
QString gridToESRIRaster(const Grid< T > &grid, QString(*valueFunction)(const T &value))
Definition: grid.h:709
void modelToWorld(const Vector3D &From, Vector3D &To)
Definition: gisgrid.cpp:54
bool loadGridFromImage(const QString &fileName, FloatGrid &rGrid)
load into 'rGrid' the content of the image pointed at by 'fileName'.
Definition: grid.cpp:97
GridViewType
Definition: grid.h:193
@ GridViewGrayReverse
Definition: grid.h:193
@ GridViewBrewerDiv
Definition: grid.h:195
@ GridViewGray
Definition: grid.h:193
@ GridViewTerrain
Definition: grid.h:195
@ GridViewRainbow
Definition: grid.h:193
@ GridViewRainbowReverse
Definition: grid.h:193
@ GridViewBlues
Definition: grid.h:194
@ GridViewGreens
Definition: grid.h:194
@ GridViewReds
Definition: grid.h:194
@ GridViewBrewerQual
Definition: grid.h:195
@ GridViewCustom
Definition: grid.h:195
@ GridViewHeat
Definition: grid.h:193
@ GridViewTurbo
Definition: grid.h:194
Grid< float > FloatGrid
Definition: grid.h:191
QImage gridToImage(const FloatGrid &grid, bool black_white=false, double min_value=0., double max_value=1., bool reverse=false)
creates and return a QImage from Grid-Data.
QString gridToString(const FloatGrid &grid, const QChar sep=QChar(';'), const int newline_after=-1)
dumps a FloatGrid to a String.
Definition: grid.cpp:23
int irandom(int from, int to)
return a random number from "from" to "to" (excluding 'to'.), i.e. irandom(3,6) results in 3,...
Definition: randomgenerator.h:81