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 )