00001 /* 00002 * The information in this file is 00003 * Copyright(c) 2007 Ball Aerospace & Technologies Corporation 00004 * and is subject to the terms and conditions of the 00005 * GNU Lesser General Public License Version 2.1 00006 * The license text is available from 00007 * http://www.gnu.org/licenses/lgpl.html 00008 */ 00009 00010 #ifndef RASTERUTILITIES_H 00011 #define RASTERUTILITIES_H 00012 00013 #include "AppConfig.h" 00014 #include "DimensionDescriptor.h" 00015 #include "EnumWrapper.h" 00016 #include "TypesFile.h" 00017 00018 #if defined(WIN_API) 00019 #include <windows.h> 00020 #include <float.h> 00021 #define FINITE _finite 00022 #define isnanf(x) (_finite(x) == 0) 00023 #elif defined(SOLARIS) 00024 #include <ieeefp.h> 00025 #define FINITE finite 00026 #elif defined(LINUX) 00027 #include <ieee754.h> 00028 #include <math.h> 00029 #define FINITE finite 00030 #endif 00031 00032 #include <string> 00033 #include <vector> 00034 00035 class DataDescriptor; 00036 class DataElement; 00037 class DynamicObject; 00038 class FileDescriptor; 00039 class Progress; 00040 class RasterDataDescriptor; 00041 class RasterDataDescriptor; 00042 class RasterElement; 00043 class RasterFileDescriptor; 00044 00045 /** 00046 * This namespace contains a number of convenience functions 00047 * for dealing with raster datasets. This includes creation of 00048 * DataDescriptors, FileDescriptors, and DataElements. 00049 */ 00050 namespace RasterUtilities 00051 { 00052 /** 00053 * Returns a vector of DimensionDescriptors, suitable for use in 00054 * a RasterDataDescriptor or RasterFileDescriptor. 00055 * 00056 * @param count 00057 * The number of DimensionDescriptors to generate. 00058 * @param setOriginalNumbers 00059 * if \c true, the original numbers will be set from 0 to count-1 00060 * matching their index location within the vector. 00061 * @param setActiveNumbers 00062 * if \c true, the active numbers will be set from 0 to count-1 00063 * matching their index location within the vector. 00064 * @param setOnDiskNumbers 00065 * if \c true, the on-disk numbers will be set from 0 to count-1 00066 * matching their index location within the vector. 00067 * 00068 * @return A vector of size count, containing the requested 00069 * DimensionDescriptors. 00070 */ 00071 std::vector<DimensionDescriptor> generateDimensionVector(unsigned int count, 00072 bool setOriginalNumbers = true, bool setActiveNumbers = false, bool setOnDiskNumbers = false); 00073 00074 /** 00075 * Determines a uniform skip factor, if any, between multiple 00076 * DimensionDescriptor objects. 00077 * 00078 * This method determines the uniform skip factor between each given 00079 * DimensionDescriptor based on its on-disk number, which represents the 00080 * skip factor used when the data was imported. 00081 * 00082 * @param values 00083 * The DimensionDescriptor objects for which to determine the skip 00084 * factor. 00085 * @param skipFactor 00086 * This parameter will be populated with the calculated skip factor. 00087 * A value of 0 indicates the on-disk numbers are as follows: 00088 * 0, 1, 2, 3, 4, 5, 6, etc. A skip factor of 1 indicates the 00089 * on-disk numbers are as follows: 0, 2, 4, 6, etc. If the 00090 * DimensionDescriptor objects do not have a uniform skip factor 00091 * (i.e. the method returns \c false), \em skipFactor is not 00092 * modified. 00093 * 00094 * @return Returns \c true if a uniform skip factor could be determined; 00095 * otherwise returns \c false. 00096 * 00097 * @see determineExportSkipFactor(), 00098 * DimensionDescriptor::getOnDiskNumber() 00099 */ 00100 bool determineSkipFactor(const std::vector<DimensionDescriptor>& values, unsigned int& skipFactor); 00101 00102 /** 00103 * Determines a uniform skip factor, if any, between multiple 00104 * DimensionDescriptor objects. 00105 * 00106 * This method determines the uniform skip factor between each given 00107 * DimensionDescriptor based on its active number, which represents the 00108 * skip factor that should be used when exporting the data. 00109 * 00110 * @param values 00111 * The DimensionDescriptor objects for which to determine the skip 00112 * factor. 00113 * @param skipFactor 00114 * This parameter will be populated with the calculated skip factor. 00115 * A value of 0 indicates the active numbers are as follows: 00116 * 0, 1, 2, 3, 4, 5, 6, etc. A skip factor of 1 indicates the 00117 * active numbers are as follows: 0, 2, 4, 6, etc. If the 00118 * DimensionDescriptor objects do not have a uniform skip factor 00119 * (i.e. the method returns \c false), \em skipFactor is not 00120 * modified. 00121 * 00122 * @return Returns \c true if a uniform skip factor could be determined; 00123 * otherwise returns \c false. 00124 * 00125 * @see determineSkipFactor(), DimensionDescriptor::getActiveNumber() 00126 */ 00127 bool determineExportSkipFactor(const std::vector<DimensionDescriptor>&values, unsigned int& skipFactor); 00128 00129 /** 00130 * Returns a subset DimensionDescriptor vector. 00131 * 00132 * @param origValues 00133 * The DimensionDescriptor vector that should be subset. 00134 * @param start 00135 * The DimensionDescriptor that specifies the start of the subset. 00136 * The DimensionDescriptor::getOriginalNumber() will be used to determine 00137 * the start of the subset in the vector. 00138 * A default constructed DimensionDescriptor can be provided, in which 00139 * case the beginning of the origVector will be used. 00140 * @param stop 00141 * The DimensionDescriptor that specifies the end of the subset. 00142 * The DimensionDescriptor::getOriginalNumber() will be used to determine 00143 * the end of the subset in the vector. 00144 * A default constructed DimensionDescriptor can be provided, in which 00145 * case the end of the origVector will be used. 00146 * @param skipFactor 00147 * Specifies the number of DimensionDescriptors that should be skipped 00148 * while creating the subset. For example, a skipFactor of 0 would include 00149 * the following entries of the vector: 0, 1, 2, 3, 4, 5, 6. For example, a 00150 * skipFactor of 1 would include the following entries of the vector: 0, 2, 4, 6. 00151 * 00152 * @return A new DimensionDescriptor vector that has been subset as specified. 00153 */ 00154 std::vector<DimensionDescriptor> subsetDimensionVector(const std::vector<DimensionDescriptor>& origValues, 00155 const DimensionDescriptor& start, const DimensionDescriptor& stop, unsigned int skipFactor = 0); 00156 00157 /** 00158 * Returns a FileDescriptor to go with a passed in DataDescriptor. 00159 * 00160 * @param pDd 00161 * The DataDescriptor to generate a FileDescriptor for. 00162 * If a RasterDataDescriptor, the DimensionDescriptors 00163 * will be modified to set on-disk numbers. 00164 * @param filename 00165 * The filename for the FileDescriptor 00166 * @param datasetLocation 00167 * The location within the file which contains the dataset. 00168 * @param endian 00169 * The endianness of the file. 00170 * 00171 * @return A newly created FileDescriptor, of an appropriate subclass 00172 * to match pDd. It has the appropriate fields copied from 00173 * the source DataDescriptor. Any special fields (like GCPs, 00174 * preline bytes, etc) must be set manually. The returned 00175 * FileDescriptor is not set into the DataDescriptor. 00176 */ 00177 FileDescriptor *generateFileDescriptor(DataDescriptor *pDd, 00178 const std::string &filename, const std::string &datasetLocation, 00179 EndianType endian); 00180 00181 /** 00182 * Returns a FileDescriptor to go with a passed in DataDescriptor and sets 00183 * the FileDescriptor onto the provided DataDescriptor. 00184 * 00185 * @param pDd 00186 * The DataDescriptor to generate a FileDescriptor for. 00187 * If a RasterDataDescriptor, the DimensionDescriptors 00188 * will be modified to set on-disk numbers. 00189 * @param filename 00190 * The filename for the FileDescriptor 00191 * @param datasetLocation 00192 * The location within the file which contains the dataset. 00193 * @param endian 00194 * The endianness of the file. 00195 * 00196 * @return A newly created FileDescriptor, of an appropriate subclass 00197 * to match pDd. It has the appropriate fields copied from 00198 * the source DataDescriptor. Any special fields (like GCPs, 00199 * preline bytes, etc) must be set manually. The returned 00200 * FileDescriptor is set into the DataDescriptor. 00201 */ 00202 FileDescriptor *generateAndSetFileDescriptor(DataDescriptor *pDd, 00203 const std::string &filename, const std::string &datasetLocation, 00204 EndianType endian); 00205 00206 /** 00207 * Returns a FileDescriptor that can be provided to an exporter 00208 * to export the data represented by the given DataDescriptor. 00209 * 00210 * @param pDd 00211 * The DataDescriptor to generate a suitable FileDescriptor 00212 * necessary for export of. 00213 * @param filename 00214 * The name of the file that the data should be exported to. 00215 * 00216 * @return A newly created FileDescriptor, of an appropriate subclass 00217 * to match pDd. The returned FileDescriptor is not set into the 00218 * DataDescriptor and is only suitable for an exporter to use. 00219 */ 00220 FileDescriptor* generateFileDescriptorForExport(const DataDescriptor* pDd, 00221 const std::string &filename); 00222 00223 /** 00224 * Returns a FileDescriptor that can be provided to an exporter 00225 * to export the raster data that is some subset of the given RasterDataDescriptor. 00226 * 00227 * @param pRasterDd 00228 * The RasterDataDescriptor to generate a suitable RasterFileDescriptor 00229 * necessary for export of. 00230 * @param filename 00231 * The name of the file that the data should be exported to. 00232 * @param startRow 00233 * The DimensionDescriptor that specifies the starting row of the subset. 00234 * The DimensionDescriptor::getOriginalNumber() will be used to determine 00235 * the start of the row subset in the vector. 00236 * A default constructed DimensionDescriptor can be provided, in which 00237 * case the first row will be used. 00238 * @param stopRow 00239 * The DimensionDescriptor that specifies the ending row of the subset. 00240 * The DimensionDescriptor::getOriginalNumber() will be used to determine 00241 * the end of the row subset in the vector. 00242 * A default constructed DimensionDescriptor can be provided, in which 00243 * case the last row will be used. 00244 * @param rowSkipFactor 00245 * Specifies the number of rows that should be skipped 00246 * while creating the subset. For example, a skipFactor of 0 would include 00247 * the following row positions: 0, 1, 2, 3, 4, 5, 6. For example, a 00248 * skipFactor of 1 would include the following row positions: 0, 2, 4, 6. 00249 * @param startCol 00250 * The DimensionDescriptor that specifies the starting column of the subset. 00251 * The DimensionDescriptor::getOriginalNumber() will be used to determine 00252 * the start of the column subset in the vector. 00253 * A default constructed DimensionDescriptor can be provided, in which 00254 * case the first column will be used. 00255 * @param stopCol 00256 * The DimensionDescriptor that specifies the ending column of the subset. 00257 * The DimensionDescriptor::getOriginalNumber() will be used to determine 00258 * the end of the column subset in the vector. 00259 * A default constructed DimensionDescriptor can be provided, in which 00260 * case the last column will be used. 00261 * @param colSkipFactor 00262 * Specifies the number of columns that should be skipped 00263 * while creating the subset. For example, a skipFactor of 0 would include 00264 * the following column positions: 0, 1, 2, 3, 4, 5, 6. For example, a 00265 * skipFactor of 1 would include the following column positions: 0, 2, 4, 6. 00266 * @param subsetBands 00267 * Specifies the list of bands that should be included in the subset. 00268 * The vector must be a subset of the DataDescriptor::getBands() value. An 00269 * empty vector can be provided, in which case no bands will be removed 00270 * during the subset. 00271 * @return A newly created RasterFileDescriptor. The returned RasterFileDescriptor 00272 * only includes the specified subset and is not set into the 00273 * RasterDataDescriptor and is only suitable for an exporter to use. 00274 */ 00275 RasterFileDescriptor* generateRasterFileDescriptorForExport(const RasterDataDescriptor* pRasterDd, 00276 const std::string &filename, const DimensionDescriptor& startRow, 00277 const DimensionDescriptor& stopRow, 00278 unsigned int rowSkipFactor, 00279 const DimensionDescriptor& startCol, 00280 const DimensionDescriptor& stopCol, 00281 unsigned int colSkipFactor, 00282 const std::vector<DimensionDescriptor>& subsetBands = std::vector<DimensionDescriptor>()); 00283 00284 /** 00285 * Returns a RasterFileDescriptor that can be provided to an exporter 00286 * to export the data that is some subset of the given RasterDataDescriptor. 00287 * 00288 * @param pRasterDd 00289 * The RasterDataDescriptor to generate a suitable RasterFileDescriptor 00290 * necessary for export of. 00291 * @param filename 00292 * The name of the file that the data should be exported to. 00293 * @param startRow 00294 * The DimensionDescriptor that specifies the starting row of the subset. 00295 * The DimensionDescriptor::getOriginalNumber() will be used to determine 00296 * the start of the row subset in the vector. 00297 * A default constructed DimensionDescriptor can be provided, in which 00298 * case the first row will be used. 00299 * @param stopRow 00300 * The DimensionDescriptor that specifies the ending row of the subset. 00301 * The DimensionDescriptor::getOriginalNumber() will be used to determine 00302 * the end of the row subset in the vector. 00303 * A default constructed DimensionDescriptor can be provided, in which 00304 * case the last row will be used. 00305 * @param rowSkipFactor 00306 * Specifies the number of rows that should be skipped 00307 * while creating the subset. For example, a skipFactor of 0 would include 00308 * the following row positions: 0, 1, 2, 3, 4, 5, 6. For example, a 00309 * skipFactor of 1 would include the following row positions: 0, 2, 4, 6. 00310 * @param startCol 00311 * The DimensionDescriptor that specifies the starting column of the subset. 00312 * The DimensionDescriptor::getOriginalNumber() will be used to determine 00313 * the start of the column subset in the vector. 00314 * A default constructed DimensionDescriptor can be provided, in which 00315 * case the first column will be used. 00316 * @param stopCol 00317 * The DimensionDescriptor that specifies the ending column of the subset. 00318 * The DimensionDescriptor::getOriginalNumber() will be used to determine 00319 * the end of the column subset in the vector. 00320 * A default constructed DimensionDescriptor can be provided, in which 00321 * case the last column will be used. 00322 * @param colSkipFactor 00323 * Specifies the number of columns that should be skipped 00324 * while creating the subset. For example, a skipFactor of 0 would include 00325 * the following column positions: 0, 1, 2, 3, 4, 5, 6. For example, a 00326 * skipFactor of 1 would include the following column positions: 0, 2, 4, 6. 00327 * @param startBand 00328 * The DimensionDescriptor that specifies the starting band of the subset. 00329 * The DimensionDescriptor::getOriginalNumber() will be used to determine 00330 * the start of the band subset in the vector. 00331 * A default constructed DimensionDescriptor can be provided, in which 00332 * case the first band will be used. 00333 * @param stopBand 00334 * The DimensionDescriptor that specifies the ending band of the subset. 00335 * The DimensionDescriptor::getOriginalNumber() will be used to determine 00336 * the end of the band subset in the vector. 00337 * A default constructed DimensionDescriptor can be provided, in which 00338 * case the last band will be used. 00339 * @param bandSkipFactor 00340 * Specifies the number of band that should be skipped 00341 * while creating the subset. For example, a skipFactor of 0 would include 00342 * the following band positions: 0, 1, 2, 3, 4, 5, 6. For example, a 00343 * skipFactor of 1 would include the following band positions: 0, 2, 4, 6. 00344 * @return A newly created RasterFileDescriptor. The returned FileDescriptor only includes 00345 * the specified subset and is not set into the 00346 * RasterDataDescriptor and is only suitable for an exporter to use. 00347 */ 00348 RasterFileDescriptor* generateRasterFileDescriptorForExport(const RasterDataDescriptor* pRasterDd, 00349 const std::string &filename, const DimensionDescriptor& startRow, 00350 const DimensionDescriptor& stopRow, 00351 unsigned int rowSkipFactor, 00352 const DimensionDescriptor& startCol, 00353 const DimensionDescriptor& stopCol, 00354 unsigned int colSkipFactor, 00355 const DimensionDescriptor& startBand, 00356 const DimensionDescriptor& stopBand, 00357 unsigned int bandSkipFactor); 00358 00359 /** 00360 * Generate a populated RasterDataDescriptor to match the given 00361 * parameters. The new RasterDataDescriptor will inherit the 00362 * classification settings of the parent DataElement unless the 00363 * parent element is \c NULL, in which case the classification will 00364 * be set to the system's highest level. 00365 * 00366 * @param name 00367 * The name for the new RasterDataDescriptor. 00368 * @param pParent 00369 * The parent element for the new RasterDataDescriptor. 00370 * @param rows 00371 * The number of rows for the new RasterDataDescriptor. 00372 * @param columns 00373 * The number of columns for the new RasterDataDescriptor. 00374 * @param bands 00375 * The number of bands for the new RasterDataDescriptor. 00376 * @param interleave 00377 * The interleave for the new RasterDataDescriptor. 00378 * @param encoding 00379 * The encoding for the new RasterDataDescriptor. 00380 * @param location 00381 * The processing location for the new RasterDataDescriptor. 00382 * 00383 * @return A fully populated RasterDataDescriptor, without a 00384 * FileDescriptor. Note that original numbers for 00385 * rows, columns, and bands will go from 0 to n. 00386 */ 00387 RasterDataDescriptor* generateRasterDataDescriptor(const std::string& name, DataElement* pParent, 00388 unsigned int rows, unsigned int columns, unsigned int bands, InterleaveFormatType interleave, 00389 EncodingType encoding, ProcessingLocation location); 00390 00391 /** 00392 * Generate a populated RasterDataDescriptor to match the given 00393 * parameters assuming the data only has one band. The new 00394 * RasterDataDescriptor will inherit the classification settings 00395 * of the parent DataElement unless the parent element is \c NULL, in 00396 * which case the classification will be set to the system's highest level. 00397 * 00398 * @param name 00399 * The name for the new RasterDataDescriptor. 00400 * @param pParent 00401 * The parent element for the new RasterDataDescriptor. 00402 * @param rows 00403 * The number of rows for the new RasterDataDescriptor. 00404 * @param columns 00405 * The number of columns for the new RasterDataDescriptor. 00406 * @param encoding 00407 * The encoding for the new RasterDataDescriptor. 00408 * @param location 00409 * The processing location for the new RasterDataDescriptor. 00410 * 00411 * @return A fully populated RasterDataDescriptor, without a 00412 * FileDescriptor. Note that original numbers for 00413 * rows, and columns will go from 0 to n. 00414 */ 00415 RasterDataDescriptor* generateRasterDataDescriptor(const std::string& name, DataElement* pParent, 00416 unsigned int rows, unsigned int columns, EncodingType encoding, ProcessingLocation location); 00417 00418 /** 00419 * Generate a populated RasterDataDescriptor with RasterFileDescriptor 00420 * to match the given RasterElement without any chipping. 00421 * 00422 * This method will retain any interesting original DimensionDescriptor 00423 * numbers, inherit the classification from the original element but not copy any metadata. 00424 * 00425 * @param pOrigElement 00426 * The RasterElement to copy. There must be a valid RasterFileDescriptor 00427 * attached to this element. 00428 * 00429 * @return A fully populated RasterDataDescriptor with RasterFileDescriptor. 00430 * The original numbers for rows and columns will match those for 00431 * pOrigElement, but without any chipping. The parent of 00432 * this descriptor is pOrigElement. 00433 */ 00434 RasterDataDescriptor *generateUnchippedRasterDataDescriptor( 00435 const RasterElement *pOrigElement); 00436 00437 /** 00438 * Modifies the provided DataDescriptor to include only the subset specified. 00439 * 00440 * @param pDd 00441 * The DataDescriptor that should be modified to only include the 00442 * specified subset. 00443 * @param startRow 00444 * The DimensionDescriptor that specifies the starting row of the subset. 00445 * The DimensionDescriptor::getOriginalNumber() will be used to determine 00446 * the start of the row subset in the vector. 00447 * A default constructed DimensionDescriptor can be provided, in which 00448 * case the first row will be used. 00449 * @param stopRow 00450 * The DimensionDescriptor that specifies the ending row of the subset. 00451 * The DimensionDescriptor::getOriginalNumber() will be used to determine 00452 * the end of the row subset in the vector. 00453 * A default constructed DimensionDescriptor can be provided, in which 00454 * case the last row will be used. 00455 * @param rowSkipFactor 00456 * Specifies the number of rows that should be skipped 00457 * while creating the subset. For example, a skipFactor of 0 would include 00458 * the following row positions: 0, 1, 2, 3, 4, 5, 6. For example, a 00459 * skipFactor of 1 would include the following row positions: 0, 2, 4, 6. 00460 * @param startCol 00461 * The DimensionDescriptor that specifies the starting column of the subset. 00462 * The DimensionDescriptor::getOriginalNumber() will be used to determine 00463 * the start of the column subset in the vector. 00464 * A default constructed DimensionDescriptor can be provided, in which 00465 * case the first column will be used. 00466 * @param stopCol 00467 * The DimensionDescriptor that specifies the ending column of the subset. 00468 * The DimensionDescriptor::getOriginalNumber() will be used to determine 00469 * the end of the column subset in the vector. 00470 * A default constructed DimensionDescriptor can be provided, in which 00471 * case the last column will be used. 00472 * @param colSkipFactor 00473 * Specifies the number of columns that should be skipped 00474 * while creating the subset. For example, a skipFactor of 0 would include 00475 * the following column positions: 0, 1, 2, 3, 4, 5, 6. For example, a 00476 * skipFactor of 1 would include the following column positions: 0, 2, 4, 6. 00477 * @param subsetBands 00478 * Specifies the list of bands that should be included in the subset. 00479 * The vector must be a subset of the DataDescriptor::getBands() value. An 00480 * empty vector can be provided, in which case no bands will be removed 00481 * during the subset. 00482 */ 00483 void subsetDataDescriptor(DataDescriptor* pDd, 00484 const DimensionDescriptor& startRow, 00485 const DimensionDescriptor& stopRow, 00486 unsigned int rowSkipFactor, 00487 const DimensionDescriptor& startCol, 00488 const DimensionDescriptor& stopCol, 00489 unsigned int colSkipFactor, 00490 const std::vector<DimensionDescriptor>& subsetBands = std::vector<DimensionDescriptor>()); 00491 00492 /** 00493 * Modifies the provided DataDescriptor to include only the subset specified. 00494 * 00495 * @param pDd 00496 * The DataDescriptor that should be modified to only include the 00497 * specified subset. 00498 * @param startRow 00499 * The DimensionDescriptor that specifies the starting row of the subset. 00500 * The DimensionDescriptor::getOriginalNumber() will be used to determine 00501 * the start of the row subset in the vector. 00502 * A default constructed DimensionDescriptor can be provided, in which 00503 * case the first row will be used. 00504 * @param stopRow 00505 * The DimensionDescriptor that specifies the ending row of the subset. 00506 * The DimensionDescriptor::getOriginalNumber() will be used to determine 00507 * the end of the row subset in the vector. 00508 * A default constructed DimensionDescriptor can be provided, in which 00509 * case the last row will be used. 00510 * @param rowSkipFactor 00511 * Specifies the number of rows that should be skipped 00512 * while creating the subset. For example, a skipFactor of 0 would include 00513 * the following row positions: 0, 1, 2, 3, 4, 5, 6. For example, a 00514 * skipFactor of 1 would include the following row positions: 0, 2, 4, 6. 00515 * @param startCol 00516 * The DimensionDescriptor that specifies the starting column of the subset. 00517 * The DimensionDescriptor::getOriginalNumber() will be used to determine 00518 * the start of the column subset in the vector. 00519 * A default constructed DimensionDescriptor can be provided, in which 00520 * case the first column will be used. 00521 * @param stopCol 00522 * The DimensionDescriptor that specifies the ending column of the subset. 00523 * The DimensionDescriptor::getOriginalNumber() will be used to determine 00524 * the end of the column subset in the vector. 00525 * A default constructed DimensionDescriptor can be provided, in which 00526 * case the last column will be used. 00527 * @param colSkipFactor 00528 * Specifies the number of columns that should be skipped 00529 * while creating the subset. For example, a skipFactor of 0 would include 00530 * the following column positions: 0, 1, 2, 3, 4, 5, 6. For example, a 00531 * skipFactor of 1 would include the following column positions: 0, 2, 4, 6. 00532 * @param startBand 00533 * The DimensionDescriptor that specifies the starting band of the subset. 00534 * The DimensionDescriptor::getOriginalNumber() will be used to determine 00535 * the start of the band subset in the vector. 00536 * A default constructed DimensionDescriptor can be provided, in which 00537 * case the first band will be used. 00538 * @param stopBand 00539 * The DimensionDescriptor that specifies the ending band of the subset. 00540 * The DimensionDescriptor::getOriginalNumber() will be used to determine 00541 * the end of the band subset in the vector. 00542 * A default constructed DimensionDescriptor can be provided, in which 00543 * case the last band will be used. 00544 * @param bandSkipFactor 00545 * Specifies the number of band that should be skipped 00546 * while creating the subset. For example, a skipFactor of 0 would include 00547 * the following band positions: 0, 1, 2, 3, 4, 5, 6. For example, a 00548 * skipFactor of 1 would include the following band positions: 0, 2, 4, 6. 00549 */ 00550 void subsetDataDescriptor(DataDescriptor* pDd, 00551 const DimensionDescriptor& startRow, 00552 const DimensionDescriptor& stopRow, 00553 unsigned int rowSkipFactor, 00554 const DimensionDescriptor& startCol, 00555 const DimensionDescriptor& stopCol, 00556 unsigned int colSkipFactor, 00557 const DimensionDescriptor& startBand, 00558 const DimensionDescriptor& stopBand, 00559 unsigned int bandSkipFactor); 00560 00561 /** 00562 * Creates a RasterElement with the given parameters and that 00563 * assumes a single band that can be immediately used. This method 00564 * should only be used by plug-ins that need to programmatically create a RasterElement to store 00565 * results of an algorithm. It should NOT be used by importers or exporters to create a RasterElement. 00566 * It should also NOT be used to create a RasterElement that corresponds to a data file on the filesystem. 00567 * The created element will inherit the parent's classification unless the parent is \c NULL, in which case 00568 * the classification will be set to the system's highest level of classification. Use the DataElement convenience 00569 * method copyClassification or setClassification if the parent is \c NULL or if you require different 00570 * classification settings. 00571 * 00572 * @param name 00573 * The name for the new RasterDataDescriptor. 00574 * @param rows 00575 * The number of rows for the new RasterDataDescriptor. 00576 * @param columns 00577 * The number of columns for the new RasterDataDescriptor. 00578 * @param encoding 00579 * The encoding for the new RasterDataDescriptor. 00580 * @param inMemory 00581 * If true, the data for the RasterElement will be fully contained in RAM. If false, 00582 * the data for the RasterElement will be fully contained on the filesystem and will 00583 * be paged into memory as required. 00584 * @param pParent 00585 * The parent element for the new RasterDataDescriptor. 00586 * 00587 * @return A RasterElement created with the given parameters 00588 * and that assumes a single band that requires no additional initialization. 00589 * 00590 * @see DataElement::copyClassification, DataElement::setClassification 00591 */ 00592 RasterElement* createRasterElement(const std::string& name, unsigned int rows, unsigned int columns, 00593 EncodingType encoding, bool inMemory = true, DataElement* pParent = 0 ); 00594 00595 /** 00596 * Creates a RasterElement with the given parameters that can be immediately used. This method 00597 * should only be used by plug-ins that need to programmatically create a RasterElement to store 00598 * results of an algorithm. It should NOT be used by importers or exporters to create a RasterElement. 00599 * It should also NOT be used to create a RasterElement that corresponds to a data file on the filesystem. 00600 * The created element will inherit the parent's classification unless the parent is \c NULL, in which case 00601 * the classification will be set to the system's highest level of classification. Use the DataElement convenience 00602 * method copyClassification or setClassification if the parent is \c NULL or if you require different 00603 * classification settings. 00604 * 00605 * @param name 00606 * The name for the new RasterDataDescriptor. 00607 * @param rows 00608 * The number of rows for the new RasterDataDescriptor. 00609 * @param columns 00610 * The number of columns for the new RasterDataDescriptor. 00611 * @param bands 00612 * The number of bands for the new RasterDataDescriptor. 00613 * @param encoding 00614 * The encoding for the new RasterDataDescriptor. 00615 * @param interleave 00616 * The interleave for the new RasterDataDescriptor. 00617 * @param inMemory 00618 * If true, the data for the RasterElement will be fully contained in RAM. If false, 00619 * the data for the RasterElement will be fully contained on the filesystem and will 00620 * be paged into memory as required. 00621 * @param pParent 00622 * The parent element for the new RasterDataDescriptor. 00623 * 00624 * @return A RasterElement created with the given parameters that requires no additional initialization. 00625 * 00626 * @see DataElement::copyClassification, DataElement::setClassification 00627 */ 00628 RasterElement* createRasterElement(const std::string& name, unsigned int rows, unsigned int columns, 00629 unsigned int bands, EncodingType encoding, InterleaveFormatType interleave = BIP, bool inMemory = true, 00630 DataElement* pParent = 0); 00631 00632 /** 00633 * Determine the number of bytes in a single element of a 00634 * given EncodingType. 00635 * 00636 * @param encoding 00637 * EncodingType to find the size of. 00638 * 00639 * @return The size in bytes of encoding. 00640 */ 00641 size_t bytesInEncoding(EncodingType encoding); 00642 00643 /** 00644 * Returns the band names for the given descriptor. This 00645 * method will query the #SPECIAL_METADATA_NAME / #BAND_METADATA_NAME / #NAMES_METADATA_NAME 00646 * and #SPECIAL_METADATA_NAME / #BAND_NAME_PREFIX_METADATA_NAME 00647 * keys of the metadata to determine the correct band names. 00648 * 00649 * @param pDescriptor 00650 * the descriptor to return the band names for. 00651 * 00652 * @return the band names for the given descriptor or empty vector if not found. 00653 */ 00654 std::vector<std::string> getBandNames(const RasterDataDescriptor* pDescriptor); 00655 00656 /** 00657 * Returns the band name for the given descriptor and band. This 00658 * method will query the #SPECIAL_METADATA_NAME / #BAND_METADATA_NAME / #NAMES_METADATA_NAME 00659 * and #SPECIAL_METADATA_NAME / #BAND_NAME_PREFIX_METADATA_NAME 00660 * keys of the metadata to determine the correct band name. This 00661 * method should not be called for every band in a RasterDataDescriptor, 00662 * for that please call getBandNames(). 00663 * 00664 * @param pDescriptor 00665 * the descriptor to return the band name for. 00666 * @param band 00667 * the individual band to return the band name for. 00668 * 00669 * @return the band name for the given descriptor and band or empty string if not found. 00670 */ 00671 std::string getBandName(const RasterDataDescriptor* pDescriptor, DimensionDescriptor band); 00672 00673 /** 00674 * Returns whether or not raster image is a subcube. 00675 * 00676 * @param pDescriptor 00677 * the descriptor of the raster image to be checked. 00678 * @param checkBands 00679 * If \c true, include the bands in the comparison. If \c false, don't include the bands 00680 * 00681 * @return True if the raster image DimensionDescriptors for Rows, Columns and Bands are equal 00682 * to the DimensionDescriptors for the Rows, Columns and Bands of the RasterFileDescriptor 00683 * and the checkBands parameter is true or if the raster image DimensionDescriptors for Rows and 00684 * Columns are equal to the DimensionDescriptors for the Rows and Columns of the RasterFileDescriptor 00685 * and the checkBands parameter is false. 00686 */ 00687 bool isSubcube(const RasterDataDescriptor* pDescriptor, bool checkBands); 00688 00689 /** 00690 * Find the appropriate red, green, and blue bands for a color composite. 00691 * 00692 * @param pDescriptor 00693 * RasterDataDescriptor containing the band and wavelength information. 00694 * @param name 00695 * The name of the user-defined color composite to set. 00696 * This is typically chosen from a menu. 00697 * @param redBand 00698 * The band to be displayed in the red channel. 00699 * @param greenBand 00700 * The band to be displayed in the green channel. 00701 * @param blueBand 00702 * The band to be displayed in the blue channel. 00703 * 00704 * @return \c True if red, green, and blue bands are successfully set and are valid, \c false otherwise. 00705 * 00706 * @see RasterLayer::getSettingColorComposites(), DimensionDescriptor::isValid() 00707 */ 00708 bool findColorCompositeDimensionDescriptors(const RasterDataDescriptor* pDescriptor, const std::string& name, 00709 DimensionDescriptor& redBand, DimensionDescriptor& greenBand, DimensionDescriptor& blueBand); 00710 00711 /** 00712 * Find the band which matches a wavelength region. 00713 * 00714 * This searches the wavelengths vectors for all bands which fall within the 00715 * (\em lowTarget, \em highTarget) region. The \em allowPartialMatch variable determines if 00716 * the entire band must fall in the region or if a partial overlap is allowed. 00717 * Once all the bands have been found, they are sorted by lower wavelength and the 00718 * index of the median value is returned. The parameters \em lowTarget, \em highTarget, \em lowWavelengths, and 00719 * \em highWavelengths must all have the same units. If \em highWavelengths is empty, \em lowWavelengths 00720 * should contain wave centers which will be matched instead of a continuous region. 00721 * 00722 * @param lowTarget 00723 * The lower bound of the wavelength region. 00724 * @param highTarget 00725 * The upper bound of the wavelength region. 00726 * @param lowWavelengths 00727 * The lower bound of the wavelengths for each band. 00728 * @param highWavelengths 00729 * The upper bound of the wavelengths for each band. Must be either empty 00730 * of the same length as \em lowWavelengths. 00731 * @param allowPartialMatch 00732 * Set to \c false to require entire band range to fall within requested wavelength region. 00733 * Set to \c true to allow partial inclusion. 00734 * @return The band number found or -1 if no bands were found. This corresponds to an 00735 * index into the \em lowWavelengths and \em highWavelengths vectors. 00736 */ 00737 int findBandWavelengthMatch(double lowTarget, double highTarget, 00738 const std::vector<double>& lowWavelengths, const std::vector<double>& highWavelengths = std::vector<double>(), 00739 bool allowPartialMatch = true); 00740 00741 /** 00742 * Find the bands which match a wavelength region. 00743 * 00744 * This searches the wavelengths vectors for all bands which fall within the 00745 * (\em lowTarget, \em highTarget) region. The \em allowPartialMatch variable determines if 00746 * the entire band must fall in the region or if a partial overlap is allowed. 00747 * Once all the bands have been found, they are sorted by lower wavelength. 00748 * The parameters \em lowTarget, \em highTarget, \em lowWavelengths, and 00749 * \em highWavelengths must all have the same units. If \em highWavelengths is empty, \em lowWavelengths 00750 * should contain wave centers which will be matched instead of a continuous region. 00751 * 00752 * @param lowTarget 00753 * The lower bound of the wavelength region. 00754 * @param highTarget 00755 * The upper bound of the wavelength region. 00756 * @param lowWavelengths 00757 * The lower bound of the wavelengths for each band. 00758 * @param highWavelengths 00759 * The upper bound of the wavelengths for each band. Must be either empty 00760 * of the same length as \em lowWavelengths. 00761 * @param allowPartialMatch 00762 * Set to \c false to require entire band range to fall within requested wavelength region. 00763 * Set to \c true to allow partial inclusion. 00764 * @return The band numbers found or an empty vector if no bands were found. These correspond to 00765 * indices into the \em lowWavelengths and \em highWavelengths vectors. 00766 */ 00767 std::vector<unsigned int> findBandWavelengthMatches(double lowTarget, double highTarget, 00768 const std::vector<double>& lowWavelengths, const std::vector<double>& highWavelengths = std::vector<double>(), 00769 bool allowPartialMatch = true); 00770 00771 /** 00772 * Find the band which matches a wavelength region. 00773 * 00774 * This searches the wavelengths stored in the metadata for all bands which fall within the 00775 * (\em lowTarget, \em highTarget) region. The preferred order of the wavelengths to use is: 00776 * - Start and End (if both are available) 00777 * - Center only 00778 * - Start only 00779 * - End only 00780 * 00781 * The \em allowPartialMatch variable determines if 00782 * the entire band must fall in the region or if a partial overlap is allowed. 00783 * Both \em lowTarget and \em highTarget must be in microns. 00784 * 00785 * @param lowTarget 00786 * The lower bound of the wavelength region. 00787 * @param highTarget 00788 * The upper bound of the wavelength region. 00789 * @param pDescriptor 00790 * The RasterDataDescriptor to search for wavelength regions. 00791 * @param allowPartialMatch 00792 * Set to \c false to require entire band range to fall within requested wavelength region. 00793 * Set to \c true to allow partial inclusion. 00794 * @return The band found or an invalid DimensionDescriptor if no bands were found. 00795 */ 00796 DimensionDescriptor findBandWavelengthMatch(double lowTarget, double highTarget, 00797 const RasterDataDescriptor* pDescriptor, bool allowPartialMatch = true); 00798 00799 /** 00800 * Finds the closest match in vector of values to a value within the tolerance specified. 00801 * This method will return the index in vector of the closest match. If there is no 00802 * match within the tolerance, the method will return -1. 00803 * 00804 * @param values 00805 * the list of values to search for the closest match. 00806 * @param value 00807 * the value for which to find the closest match. 00808 * @param tolerance 00809 * the maximum difference allowed to consider as a valid match. 00810 * @param startAt 00811 * the index at which to start search. Defaults to first element. 00812 * @return the index of best match or -1 if no match found. 00813 */ 00814 int findBestMatch(const std::vector<double> &values, double value, 00815 double tolerance, int startAt = 0); 00816 00817 /** 00818 * Returns a vector of RasterChannelType enum values. 00819 * 00820 * @return a vector of RasterChannelType enum values. 00821 */ 00822 std::vector<RasterChannelType> getVisibleRasterChannels(); 00823 00824 /** 00825 * Chip the metadata in-place. 00826 * 00827 * The vector metadata with the #SPECIAL_METADATA_NAME / #BAND_METADATA_NAME, 00828 * #ROW_METADATA_NAME, and #COLUMN_METADATA_NAME 00829 * DynamicObjects will be chipped such that they can still be 00830 * indexed with active numbers. 00831 * 00832 * This method will automatically be called when using one 00833 * of the standard ways to chip (RasterElement::createChip, chipping 00834 * on import using the default behavior in RasterElementImporterShell). 00835 * Plug-ins should only call it when implementing their own chipping behavior. 00836 * 00837 * Metadata chipping is supported for vectors of the signed and unsigned variants 00838 * of char, int, long, int64_t, as well as float, double, bool, and std::string. 00839 * 00840 * @param pMetadata 00841 * The DynamicObject that contains 00842 * #SPECIAL_METADATA_NAME / #BAND_METADATA_NAME, 00843 * #ROW_METADATA_NAME, and #COLUMN_METADATA_NAME that will 00844 * be chipped by this method. This DynamicObject will 00845 * be modified in-place. This DynamicObject will most likely 00846 * come from DataDescriptor::getMetadata(). 00847 * @param selectedRows 00848 * The DimensionDescriptors (unmodified from the RasterElement) for the rows 00849 * which should be included in this chip. 00850 * @param selectedColumns 00851 * The DimensionDescriptors (unmodified from the RasterElement) for the columns 00852 * which should be included in this chip. 00853 * @param selectedBands 00854 * The DimensionDescriptors (unmodified from the RasterElement) for the bands 00855 * which should be included in this chip. 00856 * 00857 * @return True if the operation succeeded, false otherwise. 00858 */ 00859 bool chipMetadata(DynamicObject* pMetadata, 00860 const std::vector<DimensionDescriptor> &selectedRows, 00861 const std::vector<DimensionDescriptor> &selectedColumns, 00862 const std::vector<DimensionDescriptor> &selectedBands); 00863 00864 /** 00865 * Checks whether a floating-point value is a NaN. 00866 * 00867 * @param value 00868 * The value to test. 00869 * 00870 * @return True if value is NaN, false otherwise. 00871 */ 00872 template<typename T> 00873 inline bool isBad(T value) 00874 { 00875 return false; 00876 } 00877 00878 /** 00879 * Checks whether a floating-point value is a NaN. 00880 * 00881 * @param value 00882 * The value to test. 00883 * 00884 * @return True if value is NaN, false otherwise. 00885 */ 00886 template<> 00887 inline bool isBad<double>(double value) 00888 { 00889 return isnanf(value); 00890 } 00891 00892 /** 00893 * Checks whether a floating-point value is a NaN. 00894 * 00895 * @param value 00896 * The value to test. 00897 * 00898 * @return True if value is NaN, false otherwise. 00899 */ 00900 template<> 00901 inline bool isBad<float>(float value) 00902 { 00903 return (FINITE(value) == 0); 00904 } 00905 00906 /** 00907 * Sanitize the given data. 00908 * 00909 * This method will iterate over the given data and replace all 00910 * instances of floating point NaNs with the specified value. 00911 * 00912 * @param pData 00913 * Pointer to the data to be sanitized. 00914 * 00915 * @param count 00916 * The number of data values to be sanitized. 00917 * 00918 * @param value 00919 * The value to use for all instances of floating point NaNs. 00920 * This value will be cast (via static_cast) to T. 00921 * 00922 * @return The number of data values which were sanitized. 00923 */ 00924 template <typename T> 00925 inline uint64_t sanitizeData(T* pData, uint64_t count, double value = 0.0) 00926 { 00927 uint64_t badValueCount = 0; 00928 00929 if (pData != NULL) 00930 { 00931 for (uint64_t index = 0; index < count; ++index) 00932 { 00933 if (isBad(pData[index])) 00934 { 00935 pData[index] = static_cast<T>(value); 00936 ++badValueCount; 00937 } 00938 } 00939 } 00940 00941 return badValueCount; 00942 } 00943 00944 /** 00945 * Sanitize the given data. 00946 * 00947 * This method will iterate over the given data and replace all 00948 * instances of floating point NaNs with the specified value. 00949 * 00950 * @param pData 00951 * Pointer to the data to be sanitized. 00952 * 00953 * @param count 00954 * The number of data values to be sanitized. 00955 * 00956 * @param type 00957 * The EncodingType of pData. 00958 * 00959 * @param value 00960 * The value to use for all instances of floating point NaNs. 00961 * This value will be cast (via static_cast) to the given EncodingType. 00962 * 00963 * @return The number of data values which were sanitized. 00964 */ 00965 inline uint64_t sanitizeData(void* pData, uint64_t count, EncodingType type, double value = 0.0) 00966 { 00967 switch (type) 00968 { 00969 case FLT8COMPLEX: 00970 count *= 2; // fall through 00971 case FLT4BYTES: 00972 return sanitizeData(reinterpret_cast<float*>(pData), count, value); 00973 case FLT8BYTES: 00974 return sanitizeData(reinterpret_cast<double*>(pData), count, value); 00975 default: 00976 return 0; 00977 } 00978 } 00979 00980 /** 00981 * Calculate size of data file. 00982 * 00983 * This function will calculate the size of the file described in 00984 * the given RasterFileDescriptor. For a BSQ multiple file data set, it will 00985 * calculate the required size for an individual file, not the total 00986 * of all the files. 00987 * 00988 * @param pDescriptor 00989 * The RasterFileDescriptor to use in calculation of file size. 00990 * 00991 * @return The calculated file size. For BSQ multiple files, it will return 00992 * calculated size that each of the files should require. 00993 * Will return -1 if errors occurred during calculation, e.g. 00994 * if pDescriptor is NULL. 00995 */ 00996 int64_t calculateFileSize(const RasterFileDescriptor* pDescriptor); 00997 00998 /** 00999 * Types of interpolation. 01000 */ 01001 enum InterpolationTypeEnum 01002 { 01003 NEAREST_NEIGHBOR, /**< Duplicate the nearest neighbor */ 01004 BILINEAR, /**< Bilinear interpolation */ 01005 BICUBIC /**< Bicubic interpolation */ 01006 }; 01007 01008 /** 01009 * @EnumWrapper RasterUtilities::InterpolationTypeEnum. 01010 */ 01011 typedef EnumWrapper<InterpolationTypeEnum> InterpolationType; 01012 01013 /** 01014 * Rotate a data set. 01015 * 01016 * The original dimensions of the data set are maintained. This means that data clipping and padding may occur. 01017 * 01018 * @param pDst 01019 * Destination RasterElement. Must be initialized to the same params as pSrc. 01020 * @param pSrc 01021 * RasterElement to rotate. 01022 * @param angle 01023 * Rotate by this angle. In radians. 01024 * @param defaultValue 01025 * Pixels which do not map to anything in the original data set will be set to this value. 01026 * This value will be added to the bad values list if it is not already there. 01027 * @param interp 01028 * Interpolation type. Only NEAREST_NEIGHBOR is currently supported. 01029 * @param pProgress 01030 * Report progress. 01031 * @param pAbort 01032 * If not \c NULL, check this value during the rotation. If the value becomes \c true, abort. 01033 * @return \c True if successful, \c false on error. 01034 */ 01035 bool rotate(RasterElement* pDst, const RasterElement* pSrc, double angle, int defaultValue, 01036 InterpolationType interp = NEAREST_NEIGHBOR, Progress* pProgress = NULL, bool* pAbort = NULL); 01037 } 01038 01039 #endif