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 RASTERELEMENT_H 00011 #define RASTERELEMENT_H 00012 00013 #include "AppConfig.h" 00014 #include "ComplexData.h" 00015 #include "DataAccessor.h" 00016 #include "DataElement.h" 00017 #include "DimensionDescriptor.h" 00018 #include "LocationType.h" 00019 #include "TypesFile.h" 00020 00021 #include <string> 00022 #include <vector> 00023 00024 class DataRequest; 00025 class Georeference; 00026 class Progress; 00027 class RasterPager; 00028 class Statistics; 00029 00030 /** 00031 * A three-dimensional data set. 00032 * 00033 * The RasterElement class is commonly used for three dimensional data sets that 00034 * are processed by the user. 00035 * 00036 * When dealing with RasterElements that have NaN(Not a number) values, be sure to sanitize the data 00037 * before doing anything with the dataset. Failure to do so may lead to unexpected results. 00038 * 00039 * This subclass of Subject will notify upon the following conditions: 00040 * - The following method is called: updateData(). 00041 * - Everything else documented in DataElement. 00042 * 00043 * @see DataElement 00044 */ 00045 class RasterElement : public DataElement 00046 { 00047 public: 00048 /** 00049 * Emitted with any<RasterElement*> when the associated terrain object is changed. 00050 */ 00051 SIGNAL_METHOD(RasterElement, TerrainSet) 00052 00053 /** 00054 * Emitted when the RasterElement's georeferencing has been changed. 00055 */ 00056 SIGNAL_METHOD(RasterElement, GeoreferenceModified); 00057 00058 /** 00059 * Emitted when the RasterElement's data has been changed. 00060 */ 00061 SIGNAL_METHOD(RasterElement, DataModified); 00062 00063 /** 00064 * Returns an individual data value in the cube. 00065 * 00066 * @param column 00067 * The column of the pixel to check. This must be gotten from the 00068 * RasterDataDescriptor's column vector. 00069 * @param row 00070 * The row of the pixel to check. This must be gotten from the 00071 * RasterDataDescriptor's row vector. 00072 * @param band 00073 * The band of the pixel to check. A default-constructed value can be passed 00074 * in if multiple bands are not present. For a non-default value, it be gotten from the 00075 * RasterDataDescriptor's column vector. 00076 * @param component 00077 * The complex data component for which to get the data value. For non-complex 00078 * data, this value is ignored. 00079 * 00080 * @return The data value at the given column, row, and band. A value of 0.0 is 00081 * returned if the pixel value could not be obtained. 00082 */ 00083 virtual double getPixelValue(DimensionDescriptor column, DimensionDescriptor row, 00084 DimensionDescriptor band = DimensionDescriptor(), ComplexComponent component = COMPLEX_MAGNITUDE) const = 0; 00085 00086 /** 00087 * Get a DataAccessor with the parameters contained within the given request. 00088 * 00089 * @warning The returned DataAccessor must be deleted prior to the deletion of this RasterElement. 00090 * 00091 * @param pRequest 00092 * Requested access parameters. If NULL, then the default parameters will 00093 * be used. This method takes ownership of the DataRequest object. 00094 * 00095 * @return A DataAccessor for the dataset. If the request was invalid or 00096 * unable to be filled, an invalid DataAccessor will be returned. 00097 * Callers should check the returned object's DataAccessor::isValid(). 00098 */ 00099 virtual DataAccessor getDataAccessor(DataRequest *pRequest = NULL) = 0; 00100 00101 /** 00102 * Get a DataAccessor with the parameters contained within the given request. 00103 * This const overloaded method is exactly like the non-const version, except that 00104 * it cannot be used with a writable DataRequest. 00105 * 00106 * @warning The returned DataAccessor must be deleted prior to the deletion of this RasterElement. 00107 * 00108 * @param pRequest 00109 * Requested access parameters. If NULL, then the default parameters will 00110 * be used. This method takes ownership of the DataRequest object. 00111 * 00112 * @return A DataAccessor for the dataset. If the request was invalid or 00113 * unable to be filled, an invalid DataAccessor will be returned. 00114 * Callers should check the returned object's DataAccessor::isValid(). 00115 * 00116 * @see DataRequest::setWritable() 00117 */ 00118 virtual DataAccessor getDataAccessor(DataRequest *pRequest = NULL) const = 0; 00119 00120 /** 00121 * Increments the Data Accessor to the next segment of memory. 00122 * 00123 * The incrementDataAccessor() method steps to the next segment 00124 * within the Matrix. This notifies the Data Accessor that 00125 * the algorithm is complete with the current segment. 00126 * 00127 * @see DataAccessor 00128 */ 00129 virtual void incrementDataAccessor(DataAccessorImpl& accessor) = 0; 00130 00131 /** 00132 * Notifies all observers of the object that its data has changed. 00133 * 00134 * @notify This method will notify RasterElement::signalDataModified. 00135 */ 00136 virtual void updateData() = 0; 00137 00138 /** 00139 * Sanitize the data in the object. 00140 * 00141 * This method will iterate over the dataset and replace all 00142 * instances of floating point NaNs with the specified value. 00143 * 00144 * @param value 00145 * The value to use for all instances of floating point NaNs. 00146 * This value will be cast (via static_cast) to the underlying EncodingType of the dataset. 00147 * 00148 * @return The number of data values which were sanitized. 00149 * If this value is non-zero, RasterElement::updateData() will be called before returning. 00150 * 00151 * @see RasterElement::updateData() 00152 */ 00153 virtual uint64_t sanitizeData(double value = 0.0) = 0; 00154 00155 /** 00156 * Returns statistics for the given band data. 00157 * 00158 * @param band 00159 * The band for which to get its statistics. 00160 * 00161 * @return A pointer to the Statistics object from which individual 00162 * statistics values for the given band can be set or retrieved. 00163 * If invalid, this will get the first band's statistics. 00164 */ 00165 virtual Statistics* getStatistics(DimensionDescriptor band = DimensionDescriptor()) const = 0; 00166 00167 /** 00168 * This method will create a new RasterElement which is a 00169 * chip of the object it is called on. Its active row, column, and 00170 * band vectors will correctly refer to the same original and on-disk 00171 * numbers of the original cube. The new cube will match the original 00172 * RasterElement's processing location (on-disk (not read-only) or in-memory). 00173 * Except for the name and parent, a RasterElement created with this function 00174 * should be indistinguishable from one chipped on import from the same file. 00175 * 00176 * The DimensionDescriptor vectors should be created by copying the descriptors 00177 * of the desired rows, columns, or bands from the DataDescriptor of the source RasterElement. 00178 * These must be in ascending order, without duplication. 00179 * 00180 * @param pParent 00181 * The element to use for the parent of the created cube. 00182 * @param appendName 00183 * What to append to the name of the RasterElement. 00184 * ie. "_chip" would transform the name "A.sio" to "A_chip.sio". 00185 * Passing an empty string will result in using the RasterElement's 00186 * name as the chipped name. 00187 * @param selectedRows 00188 * The DimensionDescriptors (unmodified from this object) for the rows 00189 * which should be included in this chip. 00190 * Passing an empty vector will result in using the RasterElement's 00191 * rows as the chipped rows. 00192 * @param selectedColumns 00193 * The DimensionDescriptors (unmodified from this object) for the columns 00194 * which should be included in this chip. 00195 * Passing an empty vector will result in using the RasterElement's 00196 * columns as the chipped columns. 00197 * @param selectedBands 00198 * The DimensionDescriptors (unmodified from this object) for the bands 00199 * which should be included in this chip. 00200 * Passing an empty vector will result in using the RasterElement's 00201 * bands as the chipped bands. 00202 * 00203 * @return A pointer to the created RasterElement 00204 * 00205 * @see RasterElement::copy(), RasterElement::copyDataToChip() 00206 */ 00207 virtual RasterElement *createChip(DataElement *pParent, 00208 const std::string &appendName, const std::vector<DimensionDescriptor> &selectedRows, 00209 const std::vector<DimensionDescriptor> &selectedColumns, 00210 const std::vector<DimensionDescriptor> &selectedBands = std::vector<DimensionDescriptor>()) const = 0; 00211 00212 /** 00213 * This method will copy data from this RasterElement to the chip RasterElement. 00214 * 00215 * Only the cube data will be copied -- no other data from the DataDescriptor 00216 * will be copied. 00217 * 00218 * The DimensionDescriptor vectors should be created by copying the descriptors 00219 * of the desired rows, columns, or bands from the DataDescriptor of the source RasterElement. 00220 * These must be in ascending order, without duplication. 00221 * 00222 * @param pRasterChip 00223 * The chip to copy data to. 00224 * @param selectedRows 00225 * The DimensionDescriptors (unmodified from this object) for the rows 00226 * which should be included in this chip. 00227 * @param selectedColumns 00228 * The DimensionDescriptors (unmodified from this object) for the columns 00229 * which should be included in this chip. 00230 * @param selectedBands 00231 * The DimensionDescriptors (unmodified from this object) for the bands 00232 * which should be included in this chip. 00233 * @param abort 00234 * A flag which can be set externally to abort. 00235 * Set this to true when abort is desired. 00236 * @param pProgress 00237 * The progress object to report the current progress to. 00238 * 00239 * @return True if the operation succeeded, false otherwise 00240 * 00241 * @see RasterElement::copy(), RasterElement::createChip() 00242 */ 00243 virtual bool copyDataToChip(RasterElement *pRasterChip, 00244 const std::vector<DimensionDescriptor> &selectedRows, 00245 const std::vector<DimensionDescriptor> &selectedColumns, 00246 const std::vector<DimensionDescriptor> &selectedBands, 00247 bool &abort, Progress *pProgress = NULL) const = 0; 00248 00249 /** 00250 * Creates a new raster element with the same values as this element but without copying the raster data. 00251 * 00252 * The method creates a new element based on the data contained in this 00253 * element, which includes a copy of all data in the data descriptor. It is similar to 00254 * RasterElement::copy() but does not copy the raw raster data so it is faster. 00255 * This is useful if you are going to modify the raw raster data but otherwise would 00256 * like a duplicate of the raster element. 00257 * 00258 * @param name 00259 * The name for the created raster element, which can be the same 00260 * as this object's name if the parent is different than this 00261 * object's parent. 00262 * @param pParent 00263 * The parent element for the created data element, which can be 00264 * the same as this object's parent if the name is different 00265 * than this object's name. 00266 * 00267 * @return A pointer to the new raster element. \b NULL is returned if 00268 * the element cannot be copied or if the given parent is the 00269 * same as this object's parent and the given name is the same as this object's name. 00270 */ 00271 virtual RasterElement* copyShallow(const std::string& name, DataElement* pParent) const = 0; 00272 00273 /** 00274 * Sets a terrain map of the RasterElement. 00275 * 00276 * @param pTerrain 00277 * A pointer to an object containing terrain information of the data cube. 00278 * It is assumed that the passed in RasterElement is coregistered with 00279 * this RasterElement. 00280 * 00281 * @notify This method will notify signalTerrainSet() with any<RasterElement*>. 00282 */ 00283 virtual void setTerrain(RasterElement* pTerrain) = 0; 00284 00285 /** 00286 * Gets a terrain map of the RasterElement. 00287 * 00288 * NOTE: When the RasterElement is destroyed, it will destroy its associated terrain object. 00289 * DO NOT attempt to set the same terrain object in two different RasterElements. 00290 * 00291 * @return A pointer to an object containing terrain information of the data cube. Returns NULL 00292 * on RasterElements that have not had their terrain map set. 00293 */ 00294 virtual const RasterElement* getTerrain() const = 0; 00295 00296 /** 00297 * Creates an empty temporary file. 00298 * 00299 * This method creates an empty temporary file to be used for on-disk 00300 * processing. After creating the temp file, createMemoryMappedPager() 00301 * is called to create a pager plug-in that uses the data 00302 * parameters specificed in the data descriptor. Therefore, there is 00303 * no need to call createMemoryMappedPager() or setPager() 00304 * after calling this method. 00305 * 00306 * The size of the temporary file is the size of the subset specified in 00307 * the data descriptor. If no subset is specified, the size of the file 00308 * equals the size of the data. There are no header, trailer, preline, 00309 * postline, preband, or postband bytes. 00310 * 00311 * The created filename can be retrieved to copy data into the file by 00312 * calling getTemporaryFilename(). 00313 * 00314 * @return Returns \b true if the temporary file was created successfully; 00315 * otherwise returns \b false. 00316 */ 00317 virtual bool createTemporaryFile() = 0; 00318 00319 /** 00320 * Creates a default pager plug-in instance that will be used 00321 * by this object to map data from the original file on disk into memory. 00322 * 00323 * This method creates a default raster pager plug-in that is used to 00324 * access the data using the data parameters specified in the file 00325 * descriptor. It is typically used in the read-only processing case. To 00326 * set a custom pager plug-in, call the setPager() 00327 * method instead. 00328 * 00329 * @return Returns \b true if the default pager plug-in was 00330 * successfully created; otherwise returns \b false. 00331 */ 00332 virtual bool createMemoryMappedPager() = 0; 00333 00334 /** 00335 * Creates a default pager plug-in instance that will be used 00336 * by this object to store data in memory. 00337 * 00338 * This method creates a default raster pager plug-in that is used to 00339 * access the data using the data parameters specified in the data 00340 * descriptor. 00341 * 00342 * This method does not usually need to be called from a plug-in. 00343 * RasterElements with ProcessingLocation::IN_MEMORY automatically 00344 * have an in-memory pager created for them. 00345 * 00346 * @return Returns \b true if the default pager plug-in was 00347 * successfully created; otherwise returns \b false. 00348 */ 00349 virtual bool createInMemoryPager() = 0; 00350 00351 /** 00352 * If there is no pager set into the RasterElement, create a default 00353 * one. 00354 * 00355 * This method create an appropriate default pager, including blank space 00356 * to use for the data. 00357 * 00358 * @return True if there was already a pager or a default one was successfully 00359 * created, false otherwise. 00360 */ 00361 virtual bool createDefaultPager() = 0; 00362 00363 /** 00364 * Sets the raster pager plug-in instance that will be used by this 00365 * object to access the data. 00366 * 00367 * This method provides the means to set a custom pager plug-in 00368 * that is used to access the data. To create a default pager plug-in, 00369 * call createMemoryMappedPager() instead. 00370 * 00371 * @param pPager 00372 * The raster pager plug-in instance that should be used to 00373 * page data into the application. 00374 * 00375 * @return Returns \b true if the given pager plug-in can be 00376 * used by this object; otherwise returns \b false. 00377 */ 00378 virtual bool setPager(RasterPager* pPager) = 0; 00379 00380 /** 00381 * Returns the raster pager plug-in instance that will be used by this 00382 * object to access the data. 00383 * 00384 * @return Returns the raster pager plug-in instance used by this object. 00385 */ 00386 virtual RasterPager* getPager() const = 0; 00387 00388 /** 00389 * Returns the filename that contains the data used for on-disk processing. 00390 * 00391 * @return The filename from which on-disk processing will occur. An 00392 * empty string is returned if there is no temporary file. 00393 */ 00394 virtual const std::string& getTemporaryFilename() const = 0; 00395 00396 /** 00397 * Returns a read-only pointer to the data values in memory. 00398 * 00399 * This method will return non-NULL only if the entire dataset can be 00400 * accessed concurrently. This will not be true for all RasterElements. 00401 * This method should only be used to implement an optimized version of an 00402 * algorithm. The general case is to use a DataAccessor. 00403 * 00404 * The calling object must interpret the handle according to the data type 00405 * and interleave. No conversions are available. 00406 * 00407 * @return A read-only pointer to the data if it can be accessed as a whole, 00408 * NULL otherwise. 00409 * 00410 * @see RasterDataDescriptor::getDataType() 00411 */ 00412 virtual const void* getRawData() const = 0; 00413 00414 /** 00415 * Returns a pointer to the data values in memory. 00416 * 00417 * This method will return non-NULL only if the entire dataset can be 00418 * accessed concurrently. This will not be true for all RasterElements. 00419 * This method should only be used to implement an optimized version of an 00420 * algorithm. The general case is to use a DataAccessor. 00421 * 00422 * The calling object must interpret the handle according to the data type 00423 * and interleave. No conversions are available. 00424 * 00425 * @return A pointer to the data if it can be accessed as a whole, 00426 * NULL otherwise. 00427 * 00428 * @see RasterDataDescriptor::getDataType() 00429 */ 00430 virtual void* getRawData() = 0; 00431 00432 /** 00433 * Copies data from a buffer of the specified format. 00434 * 00435 * @param pData 00436 * A buffer containing the data to write. 00437 * @param interleaveType 00438 * The interleave of the given data. 00439 * @param startRow 00440 * The first row to write. 00441 * @param numRows 00442 * The number of rows to write. 00443 * @param startColumn 00444 * The first column to write. 00445 * @param numColumns 00446 * The number of columns to write. 00447 * @param startBand 00448 * The first bands to write. 00449 * @param numBands 00450 * The number of bands to write. 00451 * 00452 * @return Returns \c true on success; \c false otherwise. 00453 */ 00454 virtual bool writeRawData(void* pData, InterleaveFormatType interleaveType, 00455 unsigned int startRow, unsigned int numRows, unsigned int startColumn, unsigned int numColumns, 00456 unsigned int startBand, unsigned int numBands) = 0; 00457 00458 /** 00459 * Returns a geocoordinate corresponding to a given scene pixel location. 00460 * 00461 * @param pixel 00462 * The scene pixel location as a LocationType. 00463 * @param quick 00464 * Set this to true if less accurate results are acceptable 00465 * in exchange for speed. 00466 * @param pAccurate 00467 * Evaluation of the accuracy of the computed location as determined by the 00468 * Georeference plug-in. When \c NULL, no accuracy check is performed. 00469 * 00470 * @return The corresponding geocoordinate as a LocationType. 00471 */ 00472 virtual LocationType convertPixelToGeocoord(LocationType pixel, bool quick = false, 00473 bool* pAccurate = NULL) const = 0; 00474 00475 /** 00476 * Returns geocoordinates for multiple pixel locations. 00477 * 00478 * This method uses the convertPixelToGeocoord() method to perform the 00479 * conversion for each pixel location. 00480 * 00481 * @param pixels 00482 * The pixel locations for which to get their geocoordinates. 00483 * @param quick 00484 * Set this to true if less accurate results are acceptable 00485 * in exchange for speed. 00486 * @param pAccurate 00487 * Evaluation of the accuracy of the computed locations as determined by the 00488 * Georeference plug-in. When \c NULL, no accuracy checks are performed. 00489 * 00490 * @return A vector containing the geocoordinates that correspond to 00491 * each pixel location in the given vector. 00492 */ 00493 virtual std::vector<LocationType> convertPixelsToGeocoords(const std::vector<LocationType>& pixels, 00494 bool quick = false, 00495 bool* pAccurate = NULL) const = 0; 00496 00497 /** 00498 * Returns a scene pixel location corresponding to a given geocoordinate. 00499 * 00500 * @param geocoord 00501 * The geocoordinate as a LocationType. 00502 * @param quick 00503 * Set this to true if less accurate results are acceptable 00504 * in exchange for speed. 00505 * @param pAccurate 00506 * Evaluation of the accuracy of the computed location as determined by the 00507 * Georeference plug-in. When \c NULL, no accuracy check is performed. 00508 * 00509 * @return The corresponding pixel location as a LocationType. 00510 */ 00511 virtual LocationType convertGeocoordToPixel(LocationType geocoord, bool quick = false, 00512 bool* pAccurate = NULL) const = 0; 00513 00514 /** 00515 * Returns pixel locations for multiple geocoordinates. 00516 * 00517 * This method uses the convertGeocoordToPixel() method to perform the 00518 * conversion for each geocoordinate. 00519 * 00520 * @param geocoords 00521 * The geocoordinates for which to get the pixel locations. 00522 * @param quick 00523 * Set this to true if less accurate results are acceptable 00524 * in exchange for speed. 00525 * @param pAccurate 00526 * Evaluation of the accuracy of the computed locations as determined by the 00527 * Georeference plug-in. When \c NULL, no accuracy checks are performed. 00528 * 00529 * @return A vector containing the pixel locations that correspond to 00530 * each geocoordinate in the given vector. 00531 */ 00532 virtual std::vector<LocationType> convertGeocoordsToPixels(const std::vector<LocationType>& geocoords, 00533 bool quick = false, 00534 bool* pAccurate = NULL) const = 0; 00535 00536 /** 00537 * Determine if the RasterElement has been georeferenced. 00538 * 00539 * @return True if the RasterElement is georeferenced, false otherwise. 00540 */ 00541 virtual bool isGeoreferenced() const = 0; 00542 00543 /** 00544 * Notify the RasterElement that the georeferencing data has been updated. 00545 * 00546 * This method is typically called by a Georeference plugin. 00547 * 00548 * @notify This method will notify Raster::signalGeoreferenceModified. 00549 */ 00550 virtual void updateGeoreferenceData() = 0; 00551 00552 /** 00553 * Set a plugin to perform all georeferencing computations. 00554 * 00555 * @param pGeo 00556 * The plugin to use for georeferencing. 00557 * 00558 * @notify This method will notify Raster::signalGeoreferenceModified. 00559 */ 00560 virtual void setGeoreferencePlugin(Georeference *pGeo) = 0; 00561 00562 /** 00563 * Get the plugin currently used. 00564 * 00565 * @return The plugin used. 00566 */ 00567 virtual Georeference *getGeoreferencePlugin() const = 0; 00568 00569 protected: 00570 /** 00571 * This should be destroyed by calling ModelServices::destroyElement. 00572 */ 00573 virtual ~RasterElement() {} 00574 }; 00575 00576 #endif