xref: /aosp_15_r20/external/sandboxed-api/oss-internship-2020/gdal/raster_to_gtiff/get_raster_data.cc (revision ec63e07ab9515d95e79c211197c445ef84cefa6a)
1 // Copyright 2020 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "get_raster_data.h"  // NOLINT(build/include)
16 
17 #include <memory>
18 
19 #include "gdal.h"  // NOLINT(build/include)
20 
21 namespace gdal::sandbox::parser {
22 
23 namespace {
24 
25 inline constexpr int kGeoTransformSize = 6;
26 
27 }  // namespace
28 
GetRasterBandsFromFile(const std::string & filename)29 RasterDataset GetRasterBandsFromFile(const std::string& filename) {
30   GDALAllRegister();
31   GDALDatasetH dataset = GDALOpen(filename.data(), GA_ReadOnly);
32   GDALDriverH driver = GDALGetDatasetDriver(dataset);
33 
34   RasterDataset result_dataset = {GDALGetRasterXSize(dataset),
35                                   GDALGetRasterYSize(dataset)};
36 
37   if (GDALGetProjectionRef(dataset) != nullptr) {
38     result_dataset.wkt_projection = std::string(GDALGetProjectionRef(dataset));
39   }
40 
41   std::vector<double> geo_transform(kGeoTransformSize, 0.0);
42 
43   if (GDALGetGeoTransform(dataset, geo_transform.data()) == CE_None) {
44     result_dataset.geo_transform = std::move(geo_transform);
45   }
46 
47   int bands_count = GDALGetRasterCount(dataset);
48 
49   std::vector<RasterBandData> bands_data;
50   bands_data.reserve(bands_count);
51 
52   for (int i = 1; i <= bands_count; ++i) {
53     GDALRasterBandH band = GDALGetRasterBand(dataset, i);
54     int width = GDALGetRasterBandXSize(band);
55     int height = GDALGetRasterBandYSize(band);
56 
57     std::unique_ptr<int> no_data_result = nullptr;
58     double no_data_value = GDALGetRasterNoDataValue(band, no_data_result.get());
59     std::optional<double> no_data_value_holder =
60         no_data_result.get() == nullptr
61             ? std::nullopt
62             : std::make_optional<double>(no_data_value);
63 
64     int data_type = static_cast<int>(GDALGetRasterDataType(band));
65     int color_interp = static_cast<int>(GDALGetRasterColorInterpretation(band));
66 
67     std::vector<int32_t> band_raster_data(width * height);
68 
69     // GDALRasterIO with GF_Write should use the same type (GDT_Int32)
70     GDALRasterIO(band, GF_Read, 0, 0, width, height, band_raster_data.data(),
71                  width, height, GDT_Int32, 0, 0);
72 
73     bands_data.push_back({width, height, std::move(band_raster_data), data_type,
74                           color_interp, std::move(no_data_value_holder)});
75   }
76 
77   result_dataset.bands = std::move(bands_data);
78 
79   GDALClose(dataset);
80 
81   return result_dataset;
82 }
83 
operator ==(const RasterBandData & lhs,const RasterBandData & rhs)84 bool operator==(const RasterBandData& lhs, const RasterBandData& rhs) {
85   return lhs.width == rhs.width && lhs.height == rhs.height &&
86          lhs.data == rhs.data && lhs.data_type == rhs.data_type &&
87          lhs.color_interp == rhs.color_interp &&
88          lhs.no_data_value == rhs.no_data_value;
89 }
90 
operator ==(const RasterDataset & lhs,const RasterDataset & rhs)91 bool operator==(const RasterDataset& lhs, const RasterDataset& rhs) {
92   return lhs.width == rhs.width && lhs.height == rhs.height &&
93          lhs.bands == rhs.bands && lhs.wkt_projection == rhs.wkt_projection &&
94          lhs.geo_transform == rhs.geo_transform;
95 }
96 
97 }  // namespace gdal::sandbox::parser
98