isce3 0.25.0
Loading...
Searching...
No Matches
Raster.icc
1//-*- C++ -*-
2//-*- coding: utf-8 -*-
3//
4// Author: Marco Lavalle
5// Original code: Joshua Cohen
6// Copyright 2018
7//
8
9#if !defined(ISCE_IO_RASTER_ICC)
10#error "Raster.icc is an implementation detail of class Raster"
11#endif
12
13#include <iostream>
14#include <isce3/except/Error.h>
15
16//Constructor to map a raw stream to a Raster
17inline void isce3::io::Raster::initFromPointer(void* ptr, //Raw pointer
18 GDALDataType dtype, //GDAL datatype
19 size_t width, //width of raster
20 size_t length, //length of raster
21 size_t pixeloffset, //pixeloffset in bytes
22 size_t lineoffset) //lineoffset in bytes
23{
24 //Get mem driver
25 GDALDriver* memDriver = (GDALDriver*) GDALGetDriverByName("MEM");
26
27 //Create an empty dataset of requested size
28 //Update with pyre error logging
29 dataset(memDriver->Create("MEM::::", width, length, 0, dtype, nullptr));
30
31 //Add the band information as needed
32 char** memdsOptions = nullptr;
33
34 {
35 char szTmp[64];
36
37 //Set data pointer
38 memset(szTmp, 0, sizeof(szTmp));
39 CPLPrintPointer(szTmp, ptr, sizeof(szTmp));
40 memdsOptions = CSLSetNameValue(memdsOptions, "DATAPOINTER", szTmp);
41
42 //Set line offset
43 memset(szTmp, 0, sizeof(szTmp));
44 CPLPrintUIntBig(szTmp, lineoffset, sizeof(szTmp));
45 memdsOptions = CSLSetNameValue(memdsOptions, "LINEOFFSET", szTmp);
46
47 //Set pixel offset
48 memset(szTmp, 0, sizeof(szTmp));
49 CPLPrintUIntBig(szTmp, pixeloffset, sizeof(szTmp));
50 memdsOptions = CSLSetNameValue(memdsOptions, "PIXELOFFSET", szTmp);
51 }
52
53 dataset()->AddBand(dtype, memdsOptions);
54}
55
56
57// Constructor for a 1 band dataset from isce3::core::Matrix<T> view type
58template <typename Derived>
59isce3::io::Raster::Raster(Eigen::PlainObjectBase<Derived>& view)
60{
61 using Scalar = typename Eigen::PlainObjectBase<Derived>::value_type;
62
63 //Get the packing. Update with pyre error logging.
64 if (!view.IsRowMajor)
65 {
66 throw std::runtime_error("Input view is not packed in row major order");
67 }
68
69 //Size of each element
70 size_t bytesperunit = sizeof(Scalar);
71
72 //Pointer and offset math
73 size_t pixeloffset = (char*) &view(0, 1) - (char*) &view(0, 0);
74 size_t lineoffset = (char*) &view(1, 0) - (char*) &view(0, 0);
75
76 //Update with pyre error logging
77 if ((pixeloffset < bytesperunit) || (lineoffset < bytesperunit))
78 {
79 throw std::runtime_error("Something looks fishy in the offset estimation");
80 }
81
82 initFromPointer(view.data(),
83 asGDT<Scalar>,
84 view.cols(),
85 view.rows(),
86 pixeloffset,
87 lineoffset);
88}
89
90
91// Copy constructor
93
94 if (not rhs._owner) {
95 throw isce3::except::RuntimeError(ISCE_SRCINFO(), "cannot copy non-owning raster");
96 }
97
98 if (_owner) {
99 GDALClose(_dataset);
100 }
101
102 dataset( rhs._dataset ); // weak-copy pointer
103 dataset()->Reference(); // increment GDALDataset reference counter
104 return *this;
105}
106
107
108
112inline void isce3::io::Raster::open(const std::string &fname,
113 GDALAccess access=GA_ReadOnly) {
114 GDALClose( _dataset );
115 dataset( static_cast<GDALDataset*>(GDALOpenShared( fname.c_str(), access )) );
116}
117
118
122 if (!match(rast)) // if rasters do not have the same size
123 throw isce3::except::LengthError(ISCE_SRCINFO(), "Rasters have different sizes.");
124
125 for (size_t b = 1; b <= rast.numBands(); ++b) // for each band in input Raster
126 addBandToVRT(rast.dataset()->GetRasterBand(b)); // add GDALRasterBand to VRT
127}
128
129
132inline void isce3::io::Raster::addBandToVRT(GDALRasterBand * inBand) {
133 if (strcmp(dataset()->GetDriverName(), "VRT")) // dataset is not VRT
134 throw isce3::except::RuntimeError(ISCE_SRCINFO(), "GDAL driver must be VRT.");
135
136 dataset()->AddBand(inBand->GetRasterDataType(), nullptr); // add band to VRT dataset
137 GDALRasterBand *rastBand = dataset()->GetRasterBand(numBands()); // get last band
138 VRTAddSimpleSource(rastBand, inBand,
139 0, 0, inBand->GetXSize(), inBand->GetYSize(),
140 0, 0, inBand->GetXSize(), inBand->GetYSize(),
141 nullptr, VRT_NODATA_UNSET);
142}
143
144
148inline void isce3::io::Raster::addRawBandToVRT(const std::string &fname, GDALDataType dtype) {
149 if (strcmp(dataset()->GetDriverName(), "VRT"))
150 throw isce3::except::LengthError(ISCE_SRCINFO(), "GDAL driver must be VRT.");
151
152 char** papszOptions = nullptr;
153 std::string srcName = fname.substr(0, fname.find_last_of("."));
154 papszOptions = CSLAddNameValue(papszOptions, "subclass", "VRTRawRasterBand");
155 papszOptions = CSLAddNameValue(papszOptions, "SourceFilename", srcName.c_str());
156 papszOptions = CSLAddNameValue(papszOptions, "RelativeToVRT", "true");
157 dataset()->AddBand(dtype, papszOptions);
158 CSLDestroy(papszOptions);
159}
160
161
162
163
164/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
165 * PIXEL OPERATIONS
166 * = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
167 */
176template<typename T>
177void isce3::io::Raster::getSetValue(T & buffer, // i/o buffer of type T
178 size_t xidx, // 0-indexed line within band
179 size_t yidx, // 0-indexed column within band
180 size_t band, // 1-indexed band number
181 GDALRWFlag iodir) { // i/o direction (GF_Read or GF_Write)
182
183 auto iostat = _dataset->GetRasterBand(band)->RasterIO(
184 iodir, xidx, yidx, 1, 1, &buffer, 1, 1, asGDT<T>, 0, 0);
185
186 if (iostat != CPLE_None) // RasterIO returned error
187 std::cout << "In isce3::io::Raster::getSetValue() - error in RasterIO." << std::endl;
188}
189
190
196template<typename T>
197void isce3::io::Raster::getValue(T &buffer, size_t xidx, size_t yidx, size_t band) {
198 getSetValue(buffer, xidx, yidx, band, GF_Read);
199}
200
201
207template<typename T>
208void isce3::io::Raster::setValue(T &buffer, size_t xidx, size_t yidx, size_t band) {
209 getSetValue(buffer, xidx, yidx, band, GF_Write);
210}
211
212
213/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
214 * LINE OPERATIONS
215 * = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
216 */
225template<typename T>
226void isce3::io::Raster::getSetLine(T *buffer, // i/o buffer of type T
227 size_t yidx, // line location within band (0-indexed)
228 size_t iowidth, // width of i/o buffer
229 size_t band, // band number (1-indexed)
230 GDALRWFlag iodir) { // i/o direction (GF_Read or GF_Write)
231
232 size_t rdwidth = std::min(iowidth, width()); // read the requested iowidth up to width()
233 auto iostat = _dataset->GetRasterBand(band)->RasterIO(iodir, 0, yidx, rdwidth, 1, buffer,
234 rdwidth, 1, asGDT<T>, 0, 0);
235
236 if (iostat != CPLE_None) // RasterIO returned errors
237 std::cout << "In isce3::io::Raster::get/setLine() - error in RasterIO." << std::endl;
238}
239
240
246template<typename T>
247void isce3::io::Raster::getLine(T *buffer, size_t yidx, size_t iowidth, size_t band) {
248 getSetLine(buffer, yidx, iowidth, band, GF_Read);
249}
250
251
252// Get a line of data for given line position and band to std::vector.
253template<typename T>
254void isce3::io::Raster::getLine(std::vector<T> &buffer, size_t yidx, size_t band) {
255 getLine(buffer.data(), yidx, buffer.size(), band);
256}
257
258
259// Set a line of data for given line position and band from a std::valarray.
260template<typename T>
261void isce3::io::Raster::getLine(std::valarray<T> &buffer, size_t yidx, size_t band) {
262 getLine(&buffer[0], yidx, buffer.size(), band);
263}
264
265
271template<typename T>
272void isce3::io::Raster::setLine(T* buffer, size_t yidx, size_t iowidth, size_t band) {
273 getSetLine(buffer, yidx, iowidth, band, GF_Write);
274}
275
276
277// Set a line of data for given line position and band from a std::vector.
278template<typename T>
279void isce3::io::Raster::setLine(std::vector<T> &buffer, size_t yidx, size_t band) {
280 setLine(buffer.data(), yidx, buffer.size(), band);
281}
282
283
284// Set a line of data for given line position and band from a std::valarray.
285template<typename T>
286void isce3::io::Raster::setLine(std::valarray<T> &buffer, size_t yidx, size_t band) {
287 setLine(&buffer[0], yidx, buffer.size(), band);
288}
289
290
291/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
292 * BLOCK OPERATIONS
293 * = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
294 */
295// Get or set a 2D data block of width iowidth and length iolength given xidx/yidx positions in band
296// and to/from 1D contigous buffer of width iowidth*iolength.
305template<typename T>
306void isce3::io::Raster::getSetBlock(T *buffer, // i/o buffer of size iowidth*iolength
307 size_t xidx, // column location within band (0-indexed)
308 size_t yidx, // row location within band (0-indexed)
309 size_t iowidth, // requested width of block of data
310 size_t iolength, // requested length of block of data
311 size_t band, // band number (1-indexed)
312 GDALRWFlag iodir) { // i/o direction (GF_Read or GF_Write)
313
314 auto iostat = _dataset->GetRasterBand(band)->RasterIO(iodir, xidx, yidx, iowidth,
315 iolength, buffer, iowidth,
316 iolength, asGDT<T>,
317 0, 0);
318
319 if (iostat != CPLE_None) // RasterIO returned errors
320 std::cout << "In isce3::io::Raster::get/setValue() - error in RasterIO." << std::endl;
321}
322
323
331template<typename T>
332void isce3::io::Raster::getBlock(T *buffer, size_t xidx, size_t yidx,
333 size_t iowidth, size_t iolength, size_t band) {
334 getSetBlock(buffer, xidx, yidx, iowidth, iolength, band, GF_Read);
335}
336
337// Get a block of data starting from given x/y position and size in band to std::vector.
338template<typename T>
339void isce3::io::Raster::getBlock(std::vector<T> &buffer, size_t xidx, size_t yidx,
340 size_t iowidth, size_t iolength, size_t band) {
341
342 if ((iolength * iowidth) > buffer.size()) // requested block is larger than buffer
343 throw isce3::except::LengthError(ISCE_SRCINFO(), "Requested more elements than buffer size.");
344
345 getBlock(buffer.data(), xidx, yidx, iowidth, iolength, band);
346
347 if ((iolength * iowidth) < buffer.size()) // buffer is larger than requested block
348 std::cout << "WARNING: In isce3::io::Raster::getBlock() - Requested fewer elements than buffer size. " << std::endl;
349}
350
351
352// Get a block of data starting from given x/y position and size in band to std::valarray.
353template<typename T>
354void isce3::io::Raster::getBlock(std::valarray<T> &buffer, size_t xidx, size_t yidx,
355 size_t iowidth, size_t iolength, size_t band) {
356
357 if ((iolength * iowidth) > buffer.size()) // requested block is larger than buffer
358 throw isce3::except::LengthError(ISCE_SRCINFO(), "Requested more elements than buffer size.");
359
360 getBlock(&buffer[0], xidx, yidx, iowidth, iolength, band);
361
362 if ((iolength * iowidth) < buffer.size()) // buffer is larger than requested block
363 std::cout << "WARNING: In isce3::io::Raster::getBlock() - Requested fewer elements than buffer size. " << std::endl;
364}
365
366
367// Get a block of data starting from given x/y position in band to Matrix<T>
368template<typename T>
369void isce3::io::Raster::getBlock(isce3::core::Matrix<T> &mat, size_t xidx, size_t yidx,
370 size_t band) {
371 getBlock(mat.data(), xidx, yidx, mat.width(), mat.length(), band);
372}
373
374// Get a block of data starting from given x/y position in band to EArray2D<T>
375template<typename T>
376void isce3::io::Raster::getBlock(isce3::core::EArray2D<T> &mat, size_t xidx, size_t yidx,
377 size_t band) {
378 getBlock(mat.data(), xidx, yidx, mat.cols(), mat.rows(), band);
379}
380
381// Get a block of data starting from given x/y position in band to EMatrix2D<T>
382template<typename T>
383void isce3::io::Raster::getBlock(isce3::core::EMatrix2D<T> &mat, size_t xidx, size_t yidx,
384 size_t band) {
385 getBlock(mat.data(), xidx, yidx, mat.cols(), mat.rows(), band);
386}
387
395template<typename T>
396void isce3::io::Raster::setBlock(T *buffer, size_t xidx, size_t yidx,
397 size_t iowidth, size_t iolength, size_t band) {
398 getSetBlock(buffer, xidx, yidx, iowidth, iolength, band, GF_Write);
399}
400
401
402// Set a block of data for given x/y position and size in band from a std::vector.
403template<typename T>
404void isce3::io::Raster::setBlock(std::vector<T> &buffer, size_t xidx, size_t yidx,
405 size_t iowidth, size_t iolength, size_t band) {
406
407 if ((iolength * iowidth) > buffer.size()) // buffer is smaller than requested block
408 throw isce3::except::LengthError(ISCE_SRCINFO(), "Requested more elements than buffer size.");
409
410 setBlock(buffer.data(), xidx, yidx, iowidth, iolength, band);
411
412 if ((iolength * iowidth) < buffer.size()) // buffer is larger than requested block
413 std::cout << "WARNING: In isce3::io::Raster::getBlock() - Requested fewer elements than buffer size. " << std::endl;
414}
415
416
417// Set a block of data for given x/y position and size in band from a std::vector.
418template<typename T>
419void isce3::io::Raster::setBlock(std::valarray<T> &buffer, size_t xidx, size_t yidx,
420 size_t iowidth, size_t iolength, size_t band) {
421
422 if ((iolength * iowidth) > buffer.size()) // buffer is smaller than requested block
423 throw isce3::except::LengthError(ISCE_SRCINFO(), "Requested more elements than buffer size.");
424
425 setBlock(&buffer[0], xidx, yidx, iowidth, iolength, band);
426
427 if ((iolength * iowidth) < buffer.size()) // buffer is larger than requested block
428 std::cout << "WARNING: In isce3::io::Raster::getBlock() - Requested fewer elements than buffer size. " << std::endl;
429}
430
431
432// Set a block of data for given x/y position and band from Matrix<T>
433template<typename T>
434void isce3::io::Raster::setBlock(isce3::core::Matrix<T>& mat, size_t xidx, size_t yidx,
435 size_t band) {
436 setBlock(mat.data(), xidx, yidx, mat.width(), mat.length(), band);
437}
438
439// Set a block of data for given x/y position and band from EArray2D<T>
440template<typename T>
441void isce3::io::Raster::setBlock(isce3::core::EArray2D<T>& mat, size_t xidx, size_t yidx,
442 size_t band) {
443 setBlock(mat.data(), xidx, yidx, mat.cols(), mat.rows(), band);
444}
445
446// Set a block of data for given x/y position and band from EMatrix2D<T>
447template<typename T>
448void isce3::io::Raster::setBlock(isce3::core::EMatrix2D<T>& mat, size_t xidx, size_t yidx,
449 size_t band) {
450 setBlock(mat.data(), xidx, yidx, mat.cols(), mat.rows(), band);
451}
452
458{
459 int status = _dataset->SetGeoTransform(arr);
460 if (status != 0) {
461 throw isce3::except::RuntimeError(ISCE_SRCINFO(), "Could not set GDAL GeoTransform");
462 }
463}
464
467inline void isce3::io::Raster::setGeoTransform(std::vector<double>& arr)
468{
469 if (arr.size() != 6) {
470 throw isce3::except::LengthError(ISCE_SRCINFO(), "vector is not of size 6");
471 }
472 setGeoTransform(arr.data());
473}
474
477inline void isce3::io::Raster::setGeoTransform(std::valarray<double>& arr)
478{
479 if (arr.size() != 6) {
480 throw isce3::except::LengthError(ISCE_SRCINFO(), "valarray is not of size 6");
481 }
482 setGeoTransform(&arr[0]);
483}
484
489inline void isce3::io::Raster::getGeoTransform(double *arr) const
490{
491 int status = _dataset->GetGeoTransform(arr);
492 if (status != 0) {
493 throw isce3::except::RuntimeError(ISCE_SRCINFO(), "Could not fetch GDAL GeoTransform");
494 }
495}
496
499inline void isce3::io::Raster::getGeoTransform(std::vector<double>& arr) const
500{
501 if (arr.size() != 6) {
502 throw isce3::except::LengthError(ISCE_SRCINFO(), "vector is not of size 6");
503 }
504 getGeoTransform(arr.data());
505}
506
509inline void isce3::io::Raster::getGeoTransform(std::valarray<double>& arr) const
510{
511 if (arr.size() != 6) {
512 throw isce3::except::LengthError(ISCE_SRCINFO(), "valarray is not of size 6");
513 }
514 getGeoTransform(&arr[0]);
515}
516
517//Return western edge
518inline double isce3::io::Raster::x0() const
519{
520 double trans[6];
521 getGeoTransform(trans);
522 return trans[0];
523}
524
525//Return northern edge
526inline double isce3::io::Raster::y0() const
527{
528 double trans[6];
529 getGeoTransform(trans);
530 return trans[3];
531}
532
533//Return EW pixel spacing
534inline double isce3::io::Raster::dx() const
535{
536 double trans[6];
537 getGeoTransform(trans);
538 return trans[1];
539}
540
541//Return NS pixel spacing
542inline double isce3::io::Raster::dy() const
543{
544 double trans[6];
545 getGeoTransform(trans);
546 return trans[5];
547}
548
Data structure for a 2D row-major matrix.
Definition Matrix.h:23
size_t length() const
Get matrix length.
Definition Matrix.h:77
size_t width() const
Get matrix width.
Definition Matrix.h:74
Data structure meant to handle Raster I/O operations.
Definition Raster.h:32
double y0() const
Return Northern Limit of Raster.
Definition Raster.icc:526
void getLine(T *buffer, size_t yidx, size_t iowidth, size_t band=1)
Read one line of data from given band to buffer, vector, or valarray.
Definition Raster.icc:247
void getSetValue(T &buffer, size_t xidz, size_t yidx, size_t band, GDALRWFlag)
Get/Set single value for given band.
Definition Raster.icc:177
void setValue(T &buffer, size_t xidx, size_t yidx, size_t band=1)
Definition Raster.icc:208
size_t width() const
Width getter.
Definition Raster.h:119
GDALAccess access() const
Access mode getter.
Definition Raster.h:125
void getValue(T &buffer, size_t xidx, size_t yidx, size_t band=1)
Definition Raster.icc:197
void addRasterToVRT(const isce3::io::Raster &rast)
Add a raster to VRT.
Definition Raster.icc:121
void getGeoTransform(double *) const
Copy Raster GeoTransform into a buffer, vector, or valarray.
Definition Raster.icc:489
GDALDataType dtype(const size_t band=1) const
Return GDALDatatype of specified band.
Definition Raster.h:141
GDALDataset * dataset() const
GDALDataset pointer getter.
Definition Raster.h:128
size_t numBands() const
Number of bands getter.
Definition Raster.h:122
double dx() const
Return EW pixel spacing of Raster.
Definition Raster.icc:534
void addBandToVRT(GDALRasterBand *inBand)
Add a GDALRasterBand to VRT.
Definition Raster.icc:132
void setLine(T *buffer, size_t yidx, size_t iowidth, size_t band=1)
Write one line of data from buffer, vector, or valarray to given band.
Definition Raster.icc:272
void setBlock(T *buffer, size_t xidx, size_t yidx, size_t iowidth, size_t iolength, size_t band=1)
Write block of data to given band from buffer, vector, or valarray.
Definition Raster.icc:396
void getSetLine(T *buffer, size_t yidx, size_t iowidth, size_t band, GDALRWFlag iodir)
Get/Set line in a band from raw pointer.
Definition Raster.icc:226
double x0() const
Return Western Limit of Raster.
Definition Raster.icc:518
void initFromPointer(void *ptr, GDALDataType dtype, size_t width, size_t length, size_t pixeloffset, size_t lineoffset)
Construct dataset for a 1 band dataset with raw pointer, dimensions and offsets.
Definition Raster.icc:17
Raster & operator=(const Raster &)
Assignment operator.
Definition Raster.icc:92
double dy() const
Return NS pixel spacing of Raster.
Definition Raster.icc:542
bool match(const Raster &rast) const
Check dimensions compatibility with another raster.
Definition Raster.h:146
void setGeoTransform(double *arr)
Set Raster GeoTransform from buffer, vector, or valarray.
Definition Raster.icc:457
size_t length() const
Length getter.
Definition Raster.h:116
void getSetBlock(T *buffer, size_t xidx, size_t yidx, size_t iowidth, size_t iolength, size_t band, GDALRWFlag iodir)
Get/Set block in band from raw pointer.
Definition Raster.icc:306
void open(const std::string &fname, GDALAccess access)
Open file with GDAL.
Definition Raster.icc:112
void getBlock(T *buffer, size_t xidx, size_t yidx, size_t iowidth, size_t iolength, size_t band=1)
Read block of data from given band to buffer, vector, or valarray.
Definition Raster.icc:332
void addRawBandToVRT(const std::string &fname, GDALDataType dtype)
Add a raw data band to VRT.
Definition Raster.icc:148

Generated for ISCE3.0 by doxygen 1.13.2.