Skip to content
This repository was archived by the owner on Aug 2, 2022. It is now read-only.

Commit e76db2d

Browse files
committed
refactor code, fix overlaps check
1 parent ef71a3f commit e76db2d

File tree

1 file changed

+67
-48
lines changed

1 file changed

+67
-48
lines changed

operators/source/gdal_source.cpp

Lines changed: 67 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,10 @@ std::unique_ptr<GenericRaster> RasterGDALSourceOperator::getRaster(const QueryRe
102102
return raster->flip(false, true);
103103
}
104104

105+
bool overlaps (double a_start, double a_end, double b_start, double b_end) {
106+
return a_end > a_start && b_end > b_start && a_end >= b_start && a_start <= b_end;
107+
}
108+
105109
// loads the raster and read the wanted raster data section into a GenericRaster
106110
std::unique_ptr<GenericRaster> RasterGDALSourceOperator::loadRaster(GDALDataset *dataset, int rasteridx, double origin_x,
107111
double origin_y, double scale_x, double scale_y,
@@ -164,42 +168,44 @@ std::unique_ptr<GenericRaster> RasterGDALSourceOperator::loadRaster(GDALDataset
164168
pixel_height = pixel_y2 - pixel_y1 + 1;
165169
}
166170

167-
double x1 = origin_x + scale_x * pixel_x1;
168-
double y1 = origin_y + scale_y * pixel_y1;
169-
double x2 = x1 + scale_x * pixel_width;
170-
double y2 = y1 + scale_y * pixel_height;
171+
double x1 = origin_x + scale_x * pixel_x1;
172+
double y1 = origin_y + scale_y * pixel_y1;
173+
double x2 = x1 + scale_x * pixel_width;
174+
double y2 = y1 + scale_y * pixel_height;
175+
176+
if (x1 > x2)
177+
std::swap(x1, x2);
178+
if (y1 > y2)
179+
std::swap(y1, y2);
171180

172-
if (x1 > x2)
173-
std::swap(x1, x2);
174-
if (y1 > y2)
175-
std::swap(y1, y2);
181+
// load raster from gdal if (some) requested pixels are inside raster
182+
bool loadGdal = overlaps(pixel_x1, pixel_x2, 0, nXSize - 1) && overlaps(pixel_y1, pixel_y2, 0, nYSize - 1);
183+
if (loadGdal) {
184+
// limit to (0, nXSize), (0, nySize) for gdal
185+
int gdal_pixel_x1 = std::min(nXSize - 1, std::max(0, pixel_x1));
186+
int gdal_pixel_y1 = std::min(nYSize - 1, std::max(0, pixel_y1));
176187

177-
// limit to (0, nXSize), (0, nySize) for gdal
178-
int gdal_pixel_x1 = std::min(nXSize - 1, std::max(0, pixel_x1));
179-
int gdal_pixel_y1 = std::min(nYSize - 1, std::max(0, pixel_y1));
180-
int gdal_pixel_x2 = std::min(nXSize - 1, std::max(0, pixel_x2));
181-
int gdal_pixel_y2 = std::min(nYSize - 1, std::max(0, pixel_y2));
188+
int gdal_pixel_x2 = std::min(nXSize - 1, std::max(0, pixel_x2));
189+
int gdal_pixel_y2 = std::min(nYSize - 1, std::max(0, pixel_y2));
182190

183-
int gdal_pixel_width = gdal_pixel_x2 - gdal_pixel_x1 + 1;
184-
int gdal_pixel_height = gdal_pixel_y2 - gdal_pixel_y1 + 1;
191+
int gdal_pixel_width = gdal_pixel_x2 - gdal_pixel_x1 + 1;
192+
int gdal_pixel_height = gdal_pixel_y2 - gdal_pixel_y1 + 1;
185193

186-
// compute the rectangle for the gdal raster
187-
double gdal_x1 = origin_x + scale_x * gdal_pixel_x1;
188-
double gdal_y1 = origin_y + scale_y * gdal_pixel_y1;
189-
double gdal_x2 = gdal_x1 + scale_x * gdal_pixel_width;
190-
double gdal_y2 = gdal_y1 + scale_y * gdal_pixel_height;
194+
// compute the rectangle for the gdal raster
195+
double gdal_x1 = origin_x + scale_x * gdal_pixel_x1;
196+
double gdal_y1 = origin_y + scale_y * gdal_pixel_y1;
197+
double gdal_x2 = gdal_x1 + scale_x * gdal_pixel_width;
198+
double gdal_y2 = gdal_y1 + scale_y * gdal_pixel_height;
191199

192-
// query scale and factor
193-
double query_scale_x = (qrect.x2 - qrect.x1) / qrect.xres;
194-
double query_scale_y = (qrect.y2 - qrect.y1) / qrect.yres;
200+
// query scale and factor
201+
double query_scale_x = (qrect.x2 - qrect.x1) / qrect.xres;
202+
double query_scale_y = (qrect.y2 - qrect.y1) / qrect.yres;
195203

196-
double query_scale_factor_x = std::abs(scale_x / query_scale_x);
197-
double query_scale_factor_y = std::abs(scale_y / query_scale_y);
204+
double query_scale_factor_x = std::abs(scale_x / query_scale_x);
205+
double query_scale_factor_y = std::abs(scale_y / query_scale_y);
198206

199-
// load raster from gdal
200-
std::unique_ptr<GenericRaster> raster;
201-
if (gdal_pixel_width > 0 && gdal_pixel_height > 0) {
202207

208+
std::unique_ptr<GenericRaster> raster;
203209
SpatioTemporalReference stref(
204210
SpatialReference(qrect.epsg, gdal_x1, gdal_y1, gdal_x2, gdal_y2, flipx, flipy),
205211
TemporalReference(tref.timetype, tref.t1, tref.t2)
@@ -225,33 +231,46 @@ std::unique_ptr<GenericRaster> RasterGDALSourceOperator::loadRaster(GDALDataset
225231
GDALClose(dataset);
226232
throw OperatorException("GDAL Source: RasterIO failed");
227233
}
228-
}
229234

230-
// check if requested query rectangle exceed the data returned from GDAL
231-
if (pixel_width > gdal_pixel_width || pixel_height > gdal_pixel_height) {
232-
// loaded raster has to be filled up with nodata
233-
SpatioTemporalReference stref(
234-
SpatialReference(qrect.epsg, x1, y1, x2, y2, flipx, flipy),
235-
TemporalReference(tref.timetype, tref.t1, tref.t2)
236-
);
237235

238-
DataDescription dd(type, loadingInfo.unit, hasnodata, nodata);
236+
// check if requested query rectangle exceed the data returned from GDAL
237+
if (pixel_width > gdal_pixel_width || pixel_height > gdal_pixel_height) {
238+
// loaded raster has to be filled up with nodata
239+
SpatioTemporalReference stref(
240+
SpatialReference(qrect.epsg, x1, y1, x2, y2, flipx, flipy),
241+
TemporalReference(tref.timetype, tref.t1, tref.t2)
242+
);
239243

240-
auto raster2 = GenericRaster::create(dd, stref, qrect.xres, qrect.yres);
244+
DataDescription dd(type, loadingInfo.unit, hasnodata, nodata);
241245

242-
if (raster) {
243-
int gdal_pixel_offset_x = gdal_pixel_x1 - pixel_x1;
244-
int gdal_pixel_offset_y = gdal_pixel_y1 - pixel_y1;
245-
int blit_offset_x = static_cast<int>(gdal_pixel_offset_x * query_scale_factor_x);
246-
int blit_offset_y = static_cast<int>(gdal_pixel_offset_y * query_scale_factor_y);
247-
raster2->blit(raster.get(), blit_offset_x, blit_offset_y);
248-
}
246+
auto raster2 = GenericRaster::create(dd, stref, qrect.xres, qrect.yres);
249247

250-
return raster2;
251-
}
248+
if (raster) {
249+
int gdal_pixel_offset_x = gdal_pixel_x1 - pixel_x1;
250+
int gdal_pixel_offset_y = gdal_pixel_y1 - pixel_y1;
251+
int blit_offset_x = static_cast<int>(gdal_pixel_offset_x * query_scale_factor_x);
252+
int blit_offset_y = static_cast<int>(gdal_pixel_offset_y * query_scale_factor_y);
253+
raster2->blit(raster.get(), blit_offset_x, blit_offset_y);
254+
}
255+
256+
return raster2;
257+
} else {
258+
return raster;
259+
}
260+
261+
} else {
262+
// return empty raster
263+
SpatioTemporalReference stref(
264+
SpatialReference(qrect.epsg, x1, y1, x2, y2, flipx, flipy),
265+
TemporalReference(tref.timetype, tref.t1, tref.t2)
266+
);
267+
268+
DataDescription dd(type, loadingInfo.unit, hasnodata, nodata);
269+
270+
return GenericRaster::create(dd, stref, qrect.xres, qrect.yres);
271+
}
252272

253273
//GDALRasterBand is not to be freed, is owned by GDALDataset that will be closed later
254-
return raster;
255274
}
256275

257276
//load the GDALDataset from disk

0 commit comments

Comments
 (0)