2020-10-01 18:59:18 +08:00
|
|
|
// Copyright 2020 Google LLC
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
//
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
|
|
|
|
2020-10-07 16:33:20 +08:00
|
|
|
#include "get_raster_data.h" // NOLINT(build/include)
|
2020-10-01 18:59:18 +08:00
|
|
|
|
|
|
|
#include <memory>
|
|
|
|
|
2020-10-19 23:08:03 +08:00
|
|
|
#include "gdal.h" // NOLINT(build/include)
|
2020-10-01 18:59:18 +08:00
|
|
|
|
2020-10-14 04:03:04 +08:00
|
|
|
namespace gdal::sandbox::parser {
|
2020-10-01 18:59:18 +08:00
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
inline constexpr int kGeoTransformSize = 6;
|
|
|
|
|
|
|
|
} // namespace
|
|
|
|
|
|
|
|
RasterDataset GetRasterBandsFromFile(const std::string& filename) {
|
|
|
|
GDALAllRegister();
|
|
|
|
GDALDatasetH dataset = GDALOpen(filename.data(), GA_ReadOnly);
|
|
|
|
GDALDriverH driver = GDALGetDatasetDriver(dataset);
|
|
|
|
|
2020-10-19 23:08:03 +08:00
|
|
|
RasterDataset result_dataset = {GDALGetRasterXSize(dataset),
|
|
|
|
GDALGetRasterYSize(dataset)};
|
2020-10-01 18:59:18 +08:00
|
|
|
|
|
|
|
if (GDALGetProjectionRef(dataset) != nullptr) {
|
|
|
|
result_dataset.wkt_projection = std::string(GDALGetProjectionRef(dataset));
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<double> geo_transform(kGeoTransformSize, 0.0);
|
|
|
|
|
|
|
|
if (GDALGetGeoTransform(dataset, geo_transform.data()) == CE_None) {
|
|
|
|
result_dataset.geo_transform = std::move(geo_transform);
|
|
|
|
}
|
|
|
|
|
|
|
|
int bands_count = GDALGetRasterCount(dataset);
|
|
|
|
|
|
|
|
std::vector<RasterBandData> bands_data;
|
|
|
|
bands_data.reserve(bands_count);
|
|
|
|
|
|
|
|
for (int i = 1; i <= bands_count; ++i) {
|
|
|
|
GDALRasterBandH band = GDALGetRasterBand(dataset, i);
|
|
|
|
int width = GDALGetRasterBandXSize(band);
|
|
|
|
int height = GDALGetRasterBandYSize(band);
|
|
|
|
|
|
|
|
std::unique_ptr<int> no_data_result = nullptr;
|
|
|
|
double no_data_value = GDALGetRasterNoDataValue(band, no_data_result.get());
|
2020-10-19 23:08:03 +08:00
|
|
|
std::optional<double> no_data_value_holder =
|
|
|
|
no_data_result.get() == nullptr
|
|
|
|
? std::nullopt
|
|
|
|
: std::make_optional<double>(no_data_value);
|
2020-10-01 18:59:18 +08:00
|
|
|
|
2020-10-19 23:08:03 +08:00
|
|
|
int data_type = static_cast<int>(GDALGetRasterDataType(band));
|
2020-10-01 18:59:18 +08:00
|
|
|
int color_interp = static_cast<int>(GDALGetRasterColorInterpretation(band));
|
|
|
|
|
2020-10-15 23:13:11 +08:00
|
|
|
std::vector<int32_t> band_raster_data(width * height);
|
2020-10-01 18:59:18 +08:00
|
|
|
|
2020-10-06 02:01:15 +08:00
|
|
|
// GDALRasterIO with GF_Write should use the same type (GDT_Int32)
|
2020-10-01 18:59:18 +08:00
|
|
|
GDALRasterIO(band, GF_Read, 0, 0, width, height, band_raster_data.data(),
|
2020-10-19 23:08:03 +08:00
|
|
|
width, height, GDT_Int32, 0, 0);
|
|
|
|
|
|
|
|
bands_data.push_back({width, height, std::move(band_raster_data), data_type,
|
|
|
|
color_interp, std::move(no_data_value_holder)});
|
2020-10-01 18:59:18 +08:00
|
|
|
}
|
2020-10-19 23:08:03 +08:00
|
|
|
|
2020-10-01 18:59:18 +08:00
|
|
|
result_dataset.bands = std::move(bands_data);
|
|
|
|
|
2020-10-14 04:03:04 +08:00
|
|
|
GDALClose(dataset);
|
|
|
|
|
2020-10-01 18:59:18 +08:00
|
|
|
return result_dataset;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool operator==(const RasterBandData& lhs, const RasterBandData& rhs) {
|
2020-10-19 23:08:03 +08:00
|
|
|
return lhs.width == rhs.width && lhs.height == rhs.height &&
|
|
|
|
lhs.data == rhs.data && lhs.data_type == rhs.data_type &&
|
|
|
|
lhs.color_interp == rhs.color_interp &&
|
|
|
|
lhs.no_data_value == rhs.no_data_value;
|
2020-10-01 18:59:18 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
bool operator==(const RasterDataset& lhs, const RasterDataset& rhs) {
|
2020-10-19 23:08:03 +08:00
|
|
|
return lhs.width == rhs.width && lhs.height == rhs.height &&
|
|
|
|
lhs.bands == rhs.bands && lhs.wkt_projection == rhs.wkt_projection &&
|
|
|
|
lhs.geo_transform == rhs.geo_transform;
|
2020-10-01 18:59:18 +08:00
|
|
|
}
|
|
|
|
|
2020-10-14 04:03:04 +08:00
|
|
|
} // namespace gdal::sandbox::parser
|