@@ -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
106110std::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