Subversion Repositories public iLand

Rev

Rev 1218 | Rev 1221 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

/********************************************************************************************
**    iLand - an individual based forest landscape and disturbance model
**    http://iland.boku.ac.at
**    Copyright (C) 2009-  Werner Rammer, Rupert Seidl
**
**    This program is free software: you can redistribute it and/or modify
**    it under the terms of the GNU General Public License as published by
**    the Free Software Foundation, either version 3 of the License, or
**    (at your option) any later version.
**
**    This program is distributed in the hope that it will be useful,
**    but WITHOUT ANY WARRANTY; without even the implied warranty of
**    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
**    GNU General Public License for more details.
**
**    You should have received a copy of the GNU General Public License
**    along with this program.  If not, see <http://www.gnu.org/licenses/>.
********************************************************************************************/



#ifndef GISGRID_H
#define GISGRID_H

#include <QString>
#include <QPointF>
#include <QRectF>

#include "grid.h"

struct SCoordTrans {
    SCoordTrans() { setupTransformation(0.,0.,0.,0.); }
    double RotationAngle;
    double sinRotate, cosRotate;
    double sinRotateReverse, cosRotateReverse;
    double offsetX, offsetY, offsetZ;
    void setupTransformation(double new_offsetx, double new_offsety, double new_offsetz, double angle_degree)
    {
        offsetX = new_offsetx;
        offsetY = new_offsety;
        offsetZ = new_offsetz;
        RotationAngle=angle_degree * M_PI / 180.;
        sinRotate=sin(RotationAngle);
        cosRotate=cos(RotationAngle);
        sinRotateReverse=sin(-RotationAngle);
        cosRotateReverse=cos(-RotationAngle);
    }
};

/** GIS Transformation
    The transformation is defined by three offsets (x,y,z) and a rotation information.
    the (x/y) denotes the real-world coordinates of the left lower edge of the grid (at least for the northern hemisphere), i.e. the (0/0).
    The z-offset is currently not used.

  */

// setup routine -- give a vector with offsets [m] and rotation angle.
void setupGISTransformation(const double offsetx,
                            const double offsety,
                            const double offsetz,
                            const double angle_degree);
// transformation routines.
void worldToModel(const Vector3D &From, Vector3D &To);
void modelToWorld(const Vector3D &From, Vector3D &To);
QPointF modelToWorld(QPointF model_coordinates);
QPointF worldToModel(QPointF world_coordinates);


class GisGrid
{
public:
    GisGrid();
    ~GisGrid();
    // maintenance
    bool loadFromFile(const QString &fileName); ///< load ESRI style text file
    // access
    int dataSize() const { return mDataSize; }   ///< number of data items (rows*cols)
    int rows() const { return mNRows; } ///< number of rows
    int cols() const { return mNCols; } ///< number of columns
    QPointF origin() const { return mOrigin; } ///< coordinates of the lower left corner of the grid
    double cellSize() const { return mCellSize; } ///< size of a cell (meters)
    double minValue() const { return min_value; } ///< minimum data value
    double maxValue() const { return max_value; } ///< maximum data value
    int noDataValue() const { return mNODATAValue; } ///< no data value of the grid
    /// get grid value at local coordinates (X/Y); returs NODATAValue if out of range
    /// @p X and @p Y are local coordinates.
    double value(const QPointF &p) const {return value(p.x(), p.y());}
    double value(const double X, const double Y) const;
    double value(const int indexx, const int indexy) const; ///< get value of grid at index positions
    double value(const int Index) const; ///< get value of grid at index positions
    /// get coordinates of the center of the cell with 'Index'
    Vector3D coord(const int Index) const;
    Vector3D coord(const int indexx, const int indexy) const;
    QRectF rectangle(const int indexx, const int indexy) const;
    void clip(const QRectF & box); ///< clip the grid to 'Box' (set values outside to -1)

    // special operations
    //QRectF GetBoundingBox(int LookFor, SBoundingBox &Result, double x_m, double y_m);
    QList<double> distinctValues(); ///< returns a list of distinct values
    //void GetDistinctValues(TStringList *ResultList, double x_m, double y_m);
    //void CountOccurence(int intID, int & Count, int & left, int &upper, int &right, int &lower, SBoundingBox *OuterBox);
    //S3dVector GetNthOccurence(int ID, int N, int left, int upper, int right, int lower);
    //void ExportToTable(AnsiString OutFileName);

    // global conversion functions between local and world coordinates
    // the world-context is created by calling setupGISTransformation() (once).
    /// convert model to world coordinates (metric)
    static QPointF modelToWorld(QPointF model_coordinates);
    /// convert world (i.e. GIS) to model coordinates (metric) (with 0/0 at lower left edge of project area)
    static QPointF worldToModel(QPointF world_coordinates);


private:

    int mDataSize;  ///< number of data items (rows*cols)
    double mCellSize;   // size of cells [m]
    double max_value;
    double min_value;
    QPointF mOrigin; // lowerleftcorner
    QPointF xAxis;  // transformed axis (moved, rotated)
    QPointF yAxis;
    int mNRows;
    int mNCols;     // count of rows and cols
    double *mData;
    int mNODATAValue;
};


// Cached GIS - Dataset
// template class.
/*
template <class T> class TGISData
{
public:
        TTypedList<T> *Items;

        TGISGrid *Grid;
        TGISData() {
           Items = new TTypedList<T>(true);
           Grid=0;
        }
        ~TGISData() {
           delete Items;
           //if (Grid)
           //  delete Grid;
        }
        int Add(T* Item) {
            return Items->Add(Item);
        }
        void Clear() { Items->Clear(); }
//        template <class T> * Select(int ID);
        T* Select(int ID) {
            for (int i=0;i<Items->Count;i++)
                      if (Items->Items[i]->ID == ID)
                         return Items->Items[i];
                   return 0;
        }
        T* SelectAt(double X, double Y) {
           if (!Grid)
              return 0;
           int CellValue = Grid->value(X,Y);
           return Select(CellValue);
        }
        //bool Select(int ID);
};

*/

//---------------------------------------------------------------------------
#endif