Skip to content

Commit

Permalink
Merge pull request #81 from tuto193/tuto193_minor-refactoring
Browse files Browse the repository at this point in the history
Added extra functions to extract individual layers from GDALDatasets and more
  • Loading branch information
kb173 authored Jul 31, 2023
2 parents e6d22d1 + 5a27d24 commit 12cead5
Show file tree
Hide file tree
Showing 11 changed files with 496 additions and 206 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ build/
**/.sconsign.dblite
**/.vscode/
demo/.import/
**/.godot/*
2 changes: 1 addition & 1 deletion demo/geodata/vienna-test-ortho.jpg.import
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ dest_files=["res://.godot/imported/vienna-test-ortho.jpg-5325b663943c1c2e87bc1a6
[params]

compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/bptc_ldr=0
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
Expand Down
2 changes: 1 addition & 1 deletion demo/project.godot
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ config_version=5

config/name="Demo"
run/main_scene="res://RasterDemo.tscn"
config/features=PackedStringArray("4.0")
config/features=PackedStringArray("4.1")
config/icon="res://icon.png"

[autoload]
Expand Down
76 changes: 59 additions & 17 deletions src/geodata.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "vector-extractor/VectorExtractor.h"

#include <godot_cpp/variant/utility_functions.hpp>
#include <vector>

namespace godot {

Expand Down Expand Up @@ -49,8 +50,9 @@ Array GeoDataset::get_raster_layers() {
Array layers = Array();

std::vector<std::string> names = dataset->get_raster_layer_names();

for (std::string name : names) {
int total_names = names.size();
for (int i = 0; i < total_names; i++ ) {
std::string name = names[i];
layers.append(get_raster_layer(name.c_str()));
}

Expand Down Expand Up @@ -276,10 +278,15 @@ void GeoRasterLayer::_bind_methods() {
ClassDB::bind_method(D_METHOD("has_write_access"), &GeoRasterLayer::has_write_access);
ClassDB::bind_method(D_METHOD("get_file_info"), &GeoRasterLayer::get_file_info);
ClassDB::bind_method(D_METHOD("get_format"), &GeoRasterLayer::get_format);
ClassDB::bind_method(D_METHOD("get_band_count"), &GeoRasterLayer::get_band_count);
ClassDB::bind_method(D_METHOD("get_band_descriptions"), &GeoRasterLayer::get_band_descriptions);
ClassDB::bind_method(D_METHOD("get_dataset"), &GeoRasterLayer::get_dataset);
ClassDB::bind_method(D_METHOD("get_image", "top_left_x", "top_left_y", "size_meters",
"img_size", "interpolation_type"),
&GeoRasterLayer::get_image);
ClassDB::bind_method(D_METHOD("get_band_image", "top_left_x", "top_left_y", "size_meters",
"img_size", "interpolation_type"),
&GeoRasterLayer::get_band_image);
ClassDB::bind_method(D_METHOD("get_value_at_position", "pos_x", "pos_y"),
&GeoRasterLayer::get_value_at_position);
ClassDB::bind_method(D_METHOD("get_value_at_position_with_resolution"),
Expand Down Expand Up @@ -309,6 +316,18 @@ bool GeoRasterLayer::has_write_access() {
return write_access;
}

Array GeoRasterLayer::get_band_descriptions() {
Array result = Array();

std::vector<std::string> descriptions = dataset->get_raster_band_descriptions();
for (int i = 0; i < descriptions.size(); i++) {
std::string description = descriptions[i];
result.append(description.c_str());
}

return result;
}

Dictionary GeoRasterLayer::get_file_info() {
Dictionary info;

Expand All @@ -330,20 +349,25 @@ Dictionary GeoRasterLayer::get_file_info() {
Image::Format GeoRasterLayer::get_format() {
GeoRaster::FORMAT format = GeoRaster::get_format_for_dataset(dataset->dataset);

if (format == GeoRaster::BYTE) {
return Image::FORMAT_R8;
} else if (format == GeoRaster::RF) {
return Image::FORMAT_RF;
} else if (format == GeoRaster::RGB) {
return Image::FORMAT_RGB8;
} else if (format == GeoRaster::RGBA) {
return Image::FORMAT_RGBA8;
} else {
// FORMAT_MAX is returned as a fallback
return Image::FORMAT_MAX;
switch (format) {
case GeoRaster::BYTE:
return Image::FORMAT_R8;
case GeoRaster::RF:
return Image::FORMAT_RF;
case GeoRaster::RGB:
return Image::FORMAT_RGB8;
case GeoRaster::RGBA:
return Image::FORMAT_RGBA8;
default:
// FORMAT_MAX is returned as a fallback for mixed, and unknown
return Image::FORMAT_MAX;
}
}

int GeoRasterLayer::get_band_count() {
return dataset->dataset->GetRasterCount();
}

Ref<GeoDataset> GeoRasterLayer::get_dataset() {
return origin_dataset;
}
Expand Down Expand Up @@ -376,6 +400,26 @@ Ref<GeoImage> GeoRasterLayer::get_image(double top_left_x, double top_left_y, do
return image;
}

Ref<GeoImage> GeoRasterLayer::get_band_image(double top_left_x, double top_left_y, double size_meters,
int img_size, int interpolation_type, int band_index) {
Ref<GeoImage> image;
image.instantiate();
if (dataset == nullptr || !dataset->is_valid()) {
UtilityFunctions::push_error("Raster layer '", get_name(), "', index '",
band_index, "', is invalid. cannot get_band_image!");
return image;
}
GeoRaster *raster = RasterTileExtractor::get_tile_from_dataset(
dataset->dataset, top_left_x, top_left_y, size_meters, img_size, interpolation_type);
if (raster == nullptr) {
UtilityFunctions::push_error("No valid data was available in the raster layer '",
get_name(), "', index '", band_index, "', at the requested position position!");
return image;
}
image->set_raster_from_band(raster, interpolation_type, band_index);
return image;
}

float GeoRasterLayer::get_value_at_position(double pos_x, double pos_y) {
// 0.0001 meters are used for the size because it can't be 0, but should be a pinpoint value.
return get_value_at_position_with_resolution(pos_x, pos_y, 0.0001);
Expand Down Expand Up @@ -435,7 +479,7 @@ void GeoRasterLayer::set_value_at_position(double pos_x, double pos_y, Variant v

delete[] values;
} else {
// TODO: Output an error since there was apparently a type mis-match
std::cout << "Type mismatch: value of type " << value.get_type() << " and dataset of type " << get_format() << std::endl;
}

dataset->dataset->FlushCache();
Expand All @@ -444,7 +488,7 @@ void GeoRasterLayer::set_value_at_position(double pos_x, double pos_y, Variant v
void GeoRasterLayer::smooth_add_value_at_position(double pos_x, double pos_y, double summand,
double radius) {
// FIXME: Like overlay_image_at_position, this could be done much more efficiently by batch-reading and writing

float resolution = get_pixel_size();

for (float offset_x = -radius; offset_x <= radius; offset_x += resolution) {
Expand Down Expand Up @@ -527,7 +571,6 @@ void GeoRasterLayer::overlay_image_at_position(double pos_x, double pos_y, Ref<I
set_value_at_position(pos_in_image_x, pos_in_image_y, value);
}
} else {
// TODO: Output an error since there was apparently a type mis-match
std::cout << "Type mismatch: image of type " << image->get_format() << " and dataset of type " << get_format() << std::endl;
}
}
Expand Down Expand Up @@ -571,7 +614,6 @@ Ref<GeoRasterLayer> GeoRasterLayer::clone() {

void GeoRasterLayer::load_from_file(String file_path, bool write_access) {
this->write_access = write_access;

dataset = VectorExtractor::open_dataset(file_path.utf8().get_data(), write_access);

// TODO: Might be better to produce a hard crash here, but CRASH_COND doesn't have the desired
Expand Down
16 changes: 16 additions & 0 deletions src/geodata.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,14 @@ class EXPORT GeoRasterLayer : public Resource {
/// Returns the Image format which corresponds to the data within this raster layer.
Image::Format get_format();

/// @brief Get the total amount of raster bands contained in the layer.
/// Returns 0 if layer is not valid
/// @return the total amount of raster bands in the layer.
int get_band_count();

/// Returns the descriptions of the individual raster bands as strings in an array.
Array get_band_descriptions();

/// Returns the dataset which this layer was opened from or null if it was opened directly, e.g.
/// from a GeoTIFF.
Ref<GeoDataset> get_dataset();
Expand All @@ -129,6 +137,14 @@ class EXPORT GeoRasterLayer : public Resource {
Ref<GeoImage> get_image(double top_left_x, double top_left_y, double size_meters, int img_size,
int interpolation_type);

/// Like get_image but only returns the GeoImage of a single Band.
/// Each GeoRasterLayer has an index that represents the RasterBand index from where the
/// the information is taken in the Dataset. Bands that have been initialized without a specific
/// index will (probably erroneously) be assigned index 1.
/// TODO: Make sure that all layers get a correctly assigned index.
Ref<GeoImage> get_band_image(double top_left_x, double top_left_y, double size_meters, int img_size,
int interpolation_type, int band_index);

/// Returns the value in the GeoRasterLayer at exactly the given position.
/// Note that when reading many values from a confined area, it is more efficient to call
/// get_image and read the pixels from there.
Expand Down
Loading

0 comments on commit 12cead5

Please sign in to comment.