Skip to content

Commit

Permalink
r.pops.spread: update from development repo (#130)
Browse files Browse the repository at this point in the history
  • Loading branch information
petrasovaa committed Mar 24, 2020
1 parent d06ae70 commit 74ed920
Show file tree
Hide file tree
Showing 24 changed files with 1,643 additions and 454 deletions.
192 changes: 164 additions & 28 deletions grass7/raster/r.pops.spread/graster.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@ extern "C" {
}

#include <string>
#include <type_traits>


/** Convert pops::Date to GRASS GIS TimeStamp */
void date_to_grass(pops::Date date, struct TimeStamp* timestamp)
{
struct DateTime date_time;
Expand Down Expand Up @@ -60,6 +63,32 @@ inline void grass_raster_get_row(int fd, CELL* buffer, int row)
Rast_get_c_row(fd, buffer, row);
}

/** Overload for is null value function */
inline bool grass_raster_is_null_value(const DCELL* value)
{
return Rast_is_d_null_value(value);
}

/** Overload for is null value function */
inline bool grass_raster_is_null_value(const FCELL* value)
{
return Rast_is_f_null_value(value);
}

/** Overload for is null value function */
inline bool grass_raster_is_null_value(const CELL* value)
{
return Rast_is_c_null_value(value);
}

/** Set a value to zero (0) if it is null (GRASS GIS NULL) */
template <typename Number>
inline void set_null_to_zero(Number* value)
{
if (grass_raster_is_null_value(value))
*value = 0;
}

/** Overload for put row function */
inline void grass_raster_put_row(int fd, DCELL* buffer)
{
Expand All @@ -78,6 +107,46 @@ inline void grass_raster_put_row(int fd, CELL* buffer)
Rast_put_c_row(fd, buffer);
}

/** Overload for set null value function */
inline void grass_raster_set_null(DCELL* buffer, int num_values = 1)
{
Rast_set_d_null_value(buffer, num_values);
}

/** Overload for set null value function */
inline void grass_raster_set_null(FCELL* buffer, int num_values = 1)
{
Rast_set_f_null_value(buffer, num_values);
}

/** Overload for set null value function */
inline void grass_raster_set_null(CELL* buffer, int num_values = 1)
{
Rast_set_c_null_value(buffer, num_values);
}

/** Policy settings for handling null values in the input */
enum class NullInputPolicy
{
NullsAsZeros, ///< Convert null values to zeros
NoConversions ///< Don't do any conversions
};

// Null values in all inputs we have mean 0 for the model, so using it
// as our default everywhere.
constexpr auto DefaultNullInputPolicy = NullInputPolicy::NullsAsZeros;

/** Policy settings for handling null values in the output */
enum class NullOutputPolicy
{
ZerosAsNulls, ///< Convert zeros to null values
NoConversions ///< Don't do any conversions
};

// We are not producing any null values in the model, so there is no
// point in doing any conversions, so using it as default.
constexpr auto DefaultNullOutputPolicy = NullOutputPolicy::NoConversions;

/** Read a GRASS GIS raster map to the Raster
*
* The caller is required to specify the type of the raster as a
Expand All @@ -91,7 +160,10 @@ inline void grass_raster_put_row(int fd, CELL* buffer)
* int, float, and double (CELL, FCELL, and DCELL).
*/
template<typename Number>
inline pops::Raster<Number> raster_from_grass(const char* name)
inline pops::Raster<Number> raster_from_grass(
const char* name,
NullInputPolicy null_policy = DefaultNullInputPolicy
)
{
unsigned rows = Rast_window_rows();
unsigned cols = Rast_window_cols();
Expand All @@ -100,7 +172,13 @@ inline pops::Raster<Number> raster_from_grass(const char* name)

int fd = Rast_open_old(name, "");
for (unsigned row = 0; row < rows; row++) {
grass_raster_get_row(fd, data + (row * cols), row);
auto row_pointer = data + (row * cols);
grass_raster_get_row(fd, row_pointer, row);
if (null_policy == NullInputPolicy::NullsAsZeros) {
for (unsigned col = 0; col < cols; ++col) {
set_null_to_zero(row_pointer + col);
}
}
}
Rast_close(fd);

Expand All @@ -109,28 +187,70 @@ inline pops::Raster<Number> raster_from_grass(const char* name)

/** Overload of raster_from_grass(const char *) */
template<typename Number>
inline pops::Raster<Number> raster_from_grass(const std::string& name)
inline pops::Raster<Number> raster_from_grass(
const std::string& name,
NullInputPolicy null_policy = DefaultNullInputPolicy
)
{
return raster_from_grass<Number>(name.c_str());
return raster_from_grass<Number>(name.c_str(), null_policy);
}

/** Converts type to GRASS GIS raster map type identifier.
*
* Use `::value` to obtain the map type identifier.
* When conversion is not possible, compile error about `value` not
* being a member of this struct is issued.
*/
template <typename Number>
struct GrassRasterMapType
{};

/** Specialization for GRASS GIS raster map type convertor */
template <>
struct GrassRasterMapType<CELL>
: std::integral_constant<RASTER_MAP_TYPE, CELL_TYPE>
{};

/** Specialization for GRASS GIS raster map type convertor */
template <>
struct GrassRasterMapType<FCELL>
: std::integral_constant<RASTER_MAP_TYPE, FCELL_TYPE>
{};

/** Specialization for GRASS GIS raster map type convertor */
template <>
struct GrassRasterMapType<DCELL>
: std::integral_constant<RASTER_MAP_TYPE, DCELL_TYPE>
{};

/** Write a Raster to a GRASS GIS raster map.
*
* When used, the template is resolved based on the parameter.
*/
template<typename Number>
void inline raster_to_grass(pops::Raster<Number> raster,
const char* name,
const char* title = nullptr,
struct TimeStamp* timestamp = nullptr)
void inline raster_to_grass(
pops::Raster<Number> raster,
const char* name,
NullOutputPolicy null_policy = DefaultNullOutputPolicy,
const char* title = nullptr,
struct TimeStamp* timestamp = nullptr
)
{
Number* data = raster.data();
unsigned rows = raster.rows();
unsigned cols = raster.cols();

int fd = Rast_open_new(name, DCELL_TYPE);
for (unsigned i = 0; i < rows; i++)
grass_raster_put_row(fd, data + (i * cols));
int fd = Rast_open_new(name, GrassRasterMapType<Number>::value);
for (unsigned i = 0; i < rows; i++) {
auto row_pointer = data + (i * cols);
if (null_policy == NullOutputPolicy::ZerosAsNulls) {
for (unsigned j = 0; j < cols; ++j) {
if (*(row_pointer + j) == 0)
grass_raster_set_null(row_pointer + j);
}
}
grass_raster_put_row(fd, row_pointer);
}
Rast_close(fd);

// writing map title and history
Expand All @@ -150,35 +270,45 @@ void inline raster_to_grass(pops::Raster<Number> raster,

/** Overload of raster_to_grass() */
template<typename Number>
inline void raster_to_grass(pops::Raster<Number> raster,
const std::string& name)
inline void raster_to_grass(
pops::Raster<Number> raster,
const std::string& name,
NullOutputPolicy null_policy = DefaultNullOutputPolicy
)
{
raster_to_grass<Number>(raster, name.c_str());
raster_to_grass<Number>(raster, name.c_str(), null_policy);
}

/** Overload of raster_to_grass() */
template<typename Number>
inline void raster_to_grass(pops::Raster<Number> raster,
const std::string& name,
const std::string& title)
inline void raster_to_grass(
pops::Raster<Number> raster,
const std::string& name,
const std::string& title,
NullOutputPolicy null_policy = DefaultNullOutputPolicy
)
{
raster_to_grass<Number>(raster, name.c_str(), title.c_str());
raster_to_grass<Number>(raster, name.c_str(), null_policy,
title.c_str());
}

/** Overload of raster_to_grass()
*
* Converts PoPS date to GRASS GIS timestamp.
*/
template<typename Number>
inline void raster_to_grass(pops::Raster<Number> raster,
const std::string& name,
const std::string& title,
const pops::Date& date)
inline void raster_to_grass(
pops::Raster<Number> raster,
const std::string& name,
const std::string& title,
const pops::Date& date,
NullOutputPolicy null_policy = DefaultNullOutputPolicy
)
{
struct TimeStamp timestamp;
date_to_grass(date, &timestamp);
raster_to_grass<Number>(raster, name.c_str(), title.c_str(),
&timestamp);
raster_to_grass<Number>(raster, name.c_str(), null_policy,
title.c_str(), &timestamp);
}

// these two determine the types of numbers used to represent the
Expand All @@ -196,16 +326,22 @@ typedef int Integer;

/** Wrapper to read GRASS GIS raster into floating point Raster */
template<typename String>
inline pops::Raster<Float> raster_from_grass_float(String name)
inline pops::Raster<Float> raster_from_grass_float(
String name,
NullInputPolicy null_policy = DefaultNullInputPolicy
)
{
return raster_from_grass<Float>(name);
return raster_from_grass<Float>(name, null_policy);
}

/** Wrapper to read GRASS GIS raster into integer type Raster */
template<typename String>
inline pops::Raster<Integer> raster_from_grass_integer(String name)
inline pops::Raster<Integer> raster_from_grass_integer(
String name,
NullInputPolicy null_policy = DefaultNullInputPolicy
)
{
return raster_from_grass<Integer>(name);
return raster_from_grass<Integer>(name, null_policy);
}

// TODO: update names
Expand Down

0 comments on commit 74ed920

Please sign in to comment.