Geo-Raster
view release on metacpan or search on metacpan
lib/Geo/Raster.pm view on Meta::CPAN
# @brief Get or set the bounding box.
# @param[in] params Named parameters:
# - \a min_x The min x of the bounding box.
# - \a min_y The min y of the bounding box.
# - \a max_x The max x of the bounding box.
# - \a max_y The max y of the bounding box.
# - \a cell_size Length of the edges of the cells.
# if there is one.
# @note At least three parameters are needed to define the bounding box.
# @return (min_x, min_y, max_x, max_y) if possible
sub world {
my $self = shift;
if (@_) {
my($cell_size,$minx,$miny,$maxx,$maxy);
my %o = @_;
for (keys %o) {
my $k = $_;
s/_//g;
$cell_size = $o{$k} if /cellsize/i;
$minx = $o{$k} if /minx/i;
$miny = $o{$k} if /miny/i;
$maxx = $o{$k} if /maxx/i;
$maxy = $o{$k} if /maxy/i;
}
if ($cell_size and defined($minx) and defined($miny)) {
ral_grid_set_bounds_csnn($self->{GRID}, $cell_size, $minx, $miny);
} elsif ($cell_size and defined($minx) and defined($maxy)) {
ral_grid_set_bounds_csnx($self->{GRID}, $cell_size, $minx, $maxy);
} elsif ($cell_size and defined($maxx) and defined($miny)) {
ral_grid_set_bounds_csxn($self->{GRID}, $cell_size, $maxx, $miny);
} elsif ($cell_size and defined($maxx) and defined($maxy)) {
ral_grid_set_bounds_csxx($self->{GRID}, $cell_size, $maxx, $maxy);
} elsif (defined($minx) and defined($maxx) and defined($miny)) {
ral_grid_set_bounds_nxn($self->{GRID}, $minx, $maxx, $miny);
} elsif (defined($minx) and defined($maxx) and defined($maxy)) {
ral_grid_set_bounds_nxx($self->{GRID}, $minx, $maxx, $maxy);
} elsif (defined($minx) and defined($miny) and defined($maxy)) {
ral_grid_set_bounds_nnx($self->{GRID}, $minx, $miny, $maxy);
} elsif (defined($maxx) and defined($miny) and defined($maxy)) {
ral_grid_set_bounds_xnx($self->{GRID}, $maxx, $miny, $maxy);
}
} elsif ($self->{GDAL}) {
my $dataset = $self->{GDAL}->{dataset};
my @t = $dataset->GeoTransform();
my $h = $dataset->{RasterYSize};
my $w = $dataset->{RasterXSize};
my $min_x = $t[1] > 0 ? $t[0] : $t[0]+$w*$t[1];
my $max_x = $t[1] > 0 ? $t[0]+$w*$t[1] : $t[0];
my $min_y = $t[5] > 0 ? $t[3] : $t[3]+$h*$t[5];
my $max_y = $t[5] > 0 ? $t[3]+$h*$t[5] : $t[3];
return ($min_x, $min_y, $max_x, $max_y);
} elsif (!$self->{GRID}) {
return ();
} else {
my $w = ral_grid_get_world($self->{GRID});
return @$w;
}
#$self->_attributes;
}
## @method overlayable(Geo::Raster other)
#
# @brief Test if two rasters are overlayable.
sub overlayable {
my($self, $other) = @_;
ral_grid_overlayable($self->{GRID}, $other->{GRID});
}
## @ignore
*bounding_box = *world;
## @method copy_world_to(Geo::Raster to)
#
# @brief The method copies the bounding box to the given raster.
# @param[out] to A raster to which the world is copied to.
# @note copy_world_to is a deprecated alias to copy_bounding_box_to
sub copy_bounding_box_to {
my($self, $to) = @_;
ral_grid_copy_bounds($self->{GRID}, $to->{GRID});
}
## @ignore
sub flip_horizontal {
my($self) = @_;
ral_grid_flip_horizontal($self->{GRID});
}
## @ignore
sub flip_vertical {
my($self) = @_;
ral_grid_flip_vertical($self->{GRID});
}
## @ignore
*copy_world_to = *copy_bounding_box_to;
## @method boolean cell_in(@cell)
#
# @brief Whether a cell is in this raster.
# @param[in] cell The cell.
# @return boolean value.
sub cell_in {
my($self, @cell) = @_;
return ($cell[0] >= 0 and $cell[0] < $self->{M} and
$cell[1] >= 0 and $cell[1] < $self->{N})
}
## @method boolean point_in(@point)
#
# @brief Whether a point is in the bounding box of this raster.
# @param[in] point The point (x, y)
# @return boolean value.
sub point_in {
my($self, @point) = @_;
my $world = ral_grid_get_world($self->{GRID});
return ($point[0] >= $world->[0] and
$point[0] <= $world->[2] and
$point[1] >= $world->[1] and
$point[1] <= $world->[3])
}
## @method @g2w(@cell)
#
# @brief Convert cell coordinates to world coordinates.
# @param[in] cell The cell coordinates (row, column).
lib/Geo/Raster.pm view on Meta::CPAN
return $range->[0];
}
}
return $self if defined wantarray;
}
## @method Geo::Raster max($param)
#
# @brief Set each cell to the maximum of its value and the parameter
# value.
#
# @param[in] param Number to compare with the raster cell values.
# @return A new raster. In void context changes this raster.
## @method Geo::Raster max(Geo::Raster second)
#
# @brief Set each cell to the maximum of its value and the value of
# the respective cell in the parameter raster.
#
# @param[in] second A raster, whose values are compared the values of
# this raster.
# @return A new raster. In void context changes this raster.
sub max {
my $self = shift;
my $second = shift;
$self = Geo::Raster->new($self) if defined wantarray;
if (ref($second)) {
ral_grid_max_grid($self->{GRID}, $second->{GRID});
} else {
if (defined($second)) {
if (ral_grid_get_datatype($self->{GRID}) == $INTEGER_GRID and $second =~ /^-?\d+$/) {
ral_grid_max_integer($self->{GRID}, $second);
} else {
ral_grid_max_real($self->{GRID}, $second);
}
} else {
my $range = ral_grid_get_value_range($self->{GRID});
return $range->[1];
}
}
return $self if defined wantarray;
}
## @method Geo::Raster random()
# @brief Return a random part of values of the values of this raster.
# @return a new raster. In void context changes the values of this raster.
sub random {
my $self = shift;
$self = Geo::Raster->new($self) if defined wantarray;
ral_grid_random($self->{GRID});
return $self if defined wantarray;
}
## @method Geo::Raster cross(Geo::Raster b)
#
# @brief Cross product of rasters.
#
# Creates a new Geo::Raster whose values represent distinct
# combinations of values of the two operand rasters. May be used as
# lvalue or in-place. The operand rasters must be integer rasters and
# the rasters must be overlayable.
# @code
# $c = $a->cross($b);
# $a->cross($b);
# @endcode
#
# If a has values A = a(1), ..., a(n) (a(i) < a(j) if i < j) and b has
# values B = b(1), ..., b(m) (b(i) < b(j) if i < j) then c will have
# max n * m distinct values. The values in c are i(b) + i(a)*n + 1,
# where i(a) is the index of the value of a in array A minus 1 and
# i(b) is the index of the value of b in array B minus 1. c will be
# nodata if either a or b is nodata.
#
# @param[in] b A reference to an another Geo::Raster object.
# @return A new raster if requested.
sub cross {
my($a, $b) = @_;
my $c = ral_grid_cross($a->{GRID}, $b->{GRID});
return new Geo::Raster ($c) if defined wantarray;
$a->_new_grid($c) if $c;
}
## @method Geo::Raster if(Geo::Raster b, Geo::Raster c)
#
# @brief If...then statement construct for rasters.
#
# Example of usage:
# @code
# $a->if($b, $c);
# @endcode
# where $a and $b are rasters and $c can be a raster or a scalar. The
# effect of this subroutine is:
# @code
# for all cells k: if (b[k]) then a[k]=c[k]
# @endcode
#
# If a return value is requested:
# @code
# $d = $a->if($b, $c);
# @endcode
# @code
# for all cells k: if (b[k]) then d[k]=c[k] else d[k]=a[k]
# @endcode
#
# - If $c is a reference to a hash of key=>value pairs, where key is
# an integer and value is a number, then
# @code
# for all cells k and keys key: if (b[k]==key) then a[k]=c[key]
# @endcode
#
# @param[in] b Raster, whose values are used as boolean values.
# @param[in] c Value raster, reference to a hash, or value.
# @return a raster whose values are the results of the if
# statement. In void context changes the values of this raster.
## @method Geo::Raster if(Geo::Raster b, Geo::Raster c, Geo::Raster d)
#
# @brief If...then...else statement construct for rasters.
#
# Example of usage:
# @code
lib/Geo/Raster.pm view on Meta::CPAN
# @brief Computes and stores into nodata cells the distance
# (in world units) to the nearest data cell.
# @return If a return value is wanted, then the method returns a new raster with
# values only in this rasters \a nodata cells having the distance
# to the nearest data cell.
sub distances {
my($self) = @_;
if (defined wantarray) {
my $g = new Geo::Raster(ral_grid_distances($self->{GRID}));
return $g;
} else {
$self->_new_grid(ral_grid_distances($self->{GRID}));
}
}
## @method Geo::Raster directions()
#
# @brief Computes and stores into nodata cells the direction to the nearest
# data cell into nodata cells.
#
# Directions are given in radians and direction zero is to the direction of
# x-axis, Pi/2 is to the direction of y-axis.
# @return If a return value is wanted, then the method returns a new raster, with
# values only in this rasters \a nodata cells, having the direction
# to the nearest data cell.
sub directions {
my($self) = @_;
if (defined wantarray) {
my $g = new Geo::Raster(ral_grid_directions($self->{GRID}));
return $g;
} else {
$self->_new_grid(ral_grid_directions($self->{GRID}));
}
}
## @method Geo::Raster clip($i1, $j1, $i2, $j2)
#
# @brief Clips a part of the raster according the given rectangle.
#
# Example of clipping a raster:
# @code
# $g2 = $g1->clip($i1, $j1, $i2, $j2);
# @endcode
#
# @param[in] i1 Upper left corners i-coordinate of the rectangle to clip.
# @param[in] j1 Upper left corners j-coordinate of the rectangle to clip.
# @param[in] i2 Bottom right corners i-coordinate of the rectangle to clip.
# @param[in] j2 Bottom right corners j-coordinate of the rectangle to clip.
# @return If a return value is wanted, then the method returns a new raster with
# size defined by the parameters.
## @method Geo::Raster clip(Geo::Raster area_to_clip)
#
# @brief Clips a part of the raster according the given rasters real
# world boundaries.
#
# Example of clipping a raster:
# @code
# $g2 = $g1->clip($g3);
# @endcode
# The example clips from $g1 a piece which is overlayable with $g3.
# If there is no lvalue, $g1 is clipped.
#
# @param[in] area_to_clip A Geo::Raster, which defines the area to clip.
# @return If a return value is wanted, then the method returns a new raster with
# size defined by the parameter.
sub clip {
my $self = shift;
if (@_ == 4) {
my($i1, $j1, $i2, $j2) = @_;
if (defined wantarray) {
my $g = new Geo::Raster(ral_grid_clip($self->{GRID}, $i1, $j1, $i2, $j2));
return $g;
} else {
$self->_new_grid(ral_grid_clip($self->{GRID}, $i1, $j1, $i2, $j2));
}
} else {
my $gd = shift;
return unless blessed($gd) and $gd->isa('Geo::Raster');
my @a = $gd->_attributes;
my($i1,$j1) = $self->w2g($a[4],$a[7]);
my($i2,$j2) = ($i1+$a[1]-1,$j1+$a[2]-1);
if (defined wantarray) {
my $g = new Geo::Raster(ral_grid_clip($self->{GRID}, $i1, $j1, $i2, $j2));
return $g;
} else {
$self->_new_grid(ral_grid_clip($self->{GRID}, $i1, $j1, $i2, $j2));
}
}
}
## @method Geo::Raster join(Geo::Raster second)
#
# @brief The method joins the two given rasters.
#
# - The upper and left world boundaries must must have equal values.
# - If both rasters are of type real, then the joined raster will have
# real as type.
#
# Example of joining
# @code
# $g3 = $g1->join($g2);
# @endcode
#
# The joining is based on the world coordinates of the rasters. clip and
# join without assignment clip or join the original raster, so
# @code
# $a->clip($i1, $j1, $i2, $j2);
#
# $a->join($b);
# @endcode
#
# @param[in] second A raster to join to this raster.
# @return If a return value is wanted, then the method returns a new raster.
# @exception The rasters have a different cell size.
sub join {
my $self = shift;
my $second = shift;
if (defined wantarray) {
my $g = new Geo::Raster(ral_grid_join($self->{GRID}, $second->{GRID}));
return $g;
( run in 2.911 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )