Subversion Repositories public iLand

Rev

Rev 1221 | 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 MAPGRID_H
#define MAPGRID_H
#include <QtCore/QHash>
#include <QRectF>
#include "grid.h"
#include "gisgrid.h"
class ResourceUnit; // forward
class Tree; // forward
class SaplingTreeOld; // forward
class ResourceUnitSpecies; // forward

class MapGrid
{
public:
    MapGrid();
    /// create a MapGrid. the optional parameter "create_index" indicates if a spatial index (e.g. to query all pixels with a given value) should be built.
    MapGrid(const GisGrid &source_grid) { loadFromGrid(source_grid); }
    MapGrid(const QString &fileName, const bool create_index=true) { loadFromFile(fileName, create_index); }
    bool loadFromFile(const QString &fileName, const bool create_index=true); ///< load ESRI style text file
    bool loadFromGrid(const GisGrid &source_grid, const bool create_index=true); ///< load from an already present GisGrid
    void createEmptyGrid(); ///< create an empty grid with the size of the height grid of iLand (all values are 0, no index is created)
    void createIndex(); ///< (re-)creates the internal index (mRUIndex, mRectIndex, ...)

    // access
    const QString &name() const { return mName; }
    bool isValid() const { return !mGrid.isEmpty(); }
    const Grid<int> &grid() const { return mGrid; }
    // access
    /// returns true, if 'id' is a valid id in the grid, false otherwise.
    bool isValid(const int id) const { return mRectIndex.contains(id); }
    QRectF boundingBox(const int id) const { return isValid(id)?mRectIndex[id].first: QRectF(); } ///< returns the bounding box of a polygon
    double area(const int id) const {return isValid(id)?mRectIndex[id].second : 0.;} ///< return the area (m2) covered by the polygon
    /// returns the list of resource units with at least one pixel within the area designated by 'id'
    QList<ResourceUnit*> resourceUnits(const int id) const;
    /// returns a list with resource units and area factors per 'id'.
    /// the area is '1' if the resource unit is fully covered by the grid-value.
    QList<QPair<ResourceUnit*, double> > resourceUnitAreas(const int id) const { return mRUIndex.values(id); }
    /// return a list of all living trees on the area 'id'
    QList<Tree*> trees(const int id) const;
    /// load trees and store in list 'rList'. If 'filter'<>"", then the filter criterion is applied
    int loadTrees(const int id,  QVector<QPair<Tree *, double> > &rList, const QString filter, int n_estimate=0) const;
    /// free locks for a given stand
    static void freeLocksForStand(const int id);
    /// return a list of grid-indices of a given stand-id
    QList<int> gridIndices(const int id) const;
    /// extract a list of neighborhood relationships between all the polygons of the grid
    const QMultiHash<int, int> neighborList() const { return mNeighborList; }
    void updateNeighborList(); ///< scan the map and fill the mNeighborList
    QList<int> neighborsOf(const int index) const;
    /// return true, if the point 'lif_grid_coords' (x/y integer key within the LIF-Grid)
    inline bool hasValue(const int id, const QPoint &lif_grid_coords) const { return mGrid.constValueAtIndex(lif_grid_coords.x()/cPxPerHeight, lif_grid_coords.y()/cPxPerHeight) == id; }
    /// return the stand-ID at the coordinates *from* the LIF-Grid (i.e., 2m grid).
    inline int standIDFromLIFCoord(const QPoint &lif_grid_coords) const  { return mGrid.constValueAtIndex(lif_grid_coords.x()/cPxPerHeight, lif_grid_coords.y()/cPxPerHeight); }

private:
    QString mName; ///< file name of the grid
    Grid<int> mGrid;
    QHash<int, QPair<QRectF,double> > mRectIndex; ///< holds the extent and area for each map-id
    QMultiHash<int, QPair<ResourceUnit*, double> > mRUIndex; ///< holds a list of resource units + areas per map-id
    QMultiHash<int, int> mNeighborList; ///< a list of neighboring polygons; for each ID all neighboring IDs are stored.
};

#endif // MAPGRID_H