@@ -102,6 +102,10 @@ std::unique_ptr<GenericRaster> RasterGDALSourceOperator::getRaster(const QueryRe
102
102
return raster->flip (false , true );
103
103
}
104
104
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
+
105
109
// loads the raster and read the wanted raster data section into a GenericRaster
106
110
std::unique_ptr<GenericRaster> RasterGDALSourceOperator::loadRaster (GDALDataset *dataset, int rasteridx, double origin_x,
107
111
double origin_y, double scale_x, double scale_y,
@@ -164,42 +168,44 @@ std::unique_ptr<GenericRaster> RasterGDALSourceOperator::loadRaster(GDALDataset
164
168
pixel_height = pixel_y2 - pixel_y1 + 1 ;
165
169
}
166
170
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);
171
180
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));
176
187
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));
182
190
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 ;
185
193
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;
191
199
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 ;
195
203
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);
198
206
199
- // load raster from gdal
200
- std::unique_ptr<GenericRaster> raster;
201
- if (gdal_pixel_width > 0 && gdal_pixel_height > 0 ) {
202
207
208
+ std::unique_ptr<GenericRaster> raster;
203
209
SpatioTemporalReference stref (
204
210
SpatialReference (qrect.epsg , gdal_x1, gdal_y1, gdal_x2, gdal_y2, flipx, flipy),
205
211
TemporalReference (tref.timetype , tref.t1 , tref.t2 )
@@ -225,33 +231,46 @@ std::unique_ptr<GenericRaster> RasterGDALSourceOperator::loadRaster(GDALDataset
225
231
GDALClose (dataset);
226
232
throw OperatorException (" GDAL Source: RasterIO failed" );
227
233
}
228
- }
229
234
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
- );
237
235
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
+ );
239
243
240
- auto raster2 = GenericRaster::create (dd, stref, qrect. xres , qrect. yres );
244
+ DataDescription dd (type, loadingInfo. unit , hasnodata, nodata );
241
245
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 );
249
247
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
+ }
252
272
253
273
// GDALRasterBand is not to be freed, is owned by GDALDataset that will be closed later
254
- return raster;
255
274
}
256
275
257
276
// load the GDALDataset from disk
0 commit comments