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 RASTERELEMENTIMPORTERSHELL_H 00011 #define RASTERELEMENTIMPORTERSHELL_H 00012 00013 #include "DesktopServices.h" 00014 #include "ImporterShell.h" 00015 #include "ModelServices.h" 00016 #include "PlugInManagerServices.h" 00017 #include "TypesFile.h" 00018 #include "UtilityServices.h" 00019 00020 #include <string> 00021 #include <vector> 00022 00023 class DataDescriptor; 00024 class GcpLayer; 00025 class GcpList; 00026 class LatLonLayer; 00027 class PlugIn; 00028 class Progress; 00029 class RasterElement; 00030 class RasterLayer; 00031 class SpatialDataView; 00032 class Step; 00033 00034 /** 00035 * \ingroup ShellModule 00036 * Provides a shell class for importers loading RasterElement objects. 00037 * 00038 * This class provides capabilities for importers to load data from a file 00039 * which is stored in a RasterElement object. The default input arg list contains 00040 * two objects: Progress and RasterElement. The default output arg list contains a 00041 * single View object in interactive mode. 00042 * 00043 * On a typical import from interactive mode, derived importers must override the 00044 * getImportDescriptors() method to parse a file for the valid data set parameters. 00045 * The user may then modify the fields in the DataDescriptor, and a RasterElement object 00046 * is created from the modified DataDescriptor. This RasterElement object is then set 00047 * into the input arg list before execute() is called. 00048 * 00049 * The default implementation of the execute() method calls createRasterPager() 00050 * and copies the selected data into the import RasterElement. A view is 00051 * automatically created if the plug-in is in interactive mode. If the 00052 * DataDescriptor input arg is \c NULL, one is created and the getImportDescriptors() 00053 * method is called to set the values. The plug-in contains aborting capabilities 00054 * which aborts the copy in progress. 00055 * 00056 * Importers that have a special format to load data from the file only need to override 00057 * createRasterPager() to create the format-specific RasterPager. Importers that 00058 * desire more control can do so by overriding execute(). The parseInputArgList() method 00059 * can be called to extract the Progress and RasterElement values from the arg list, and the 00060 * createView() method can be called to create a view for the RasterElement in interactive 00061 * mode. A derived importer can also override abort() to properly allow the user to 00062 * abort the import. 00063 * 00064 * @see ImporterShell 00065 */ 00066 class RasterElementImporterShell : public ImporterShell 00067 { 00068 public: 00069 /** 00070 * Creates a raster element importer plug-in. 00071 * 00072 * The constructor sets the plug-in subtype to "Raster Element" and sets 00073 * the plug-in to allow multiple instances. 00074 * 00075 * @see getSubtype(), areMultipleInstancesAllowed() 00076 */ 00077 RasterElementImporterShell(); 00078 00079 /** 00080 * Destroys the raster element importer plug-in. 00081 */ 00082 virtual ~RasterElementImporterShell(); 00083 00084 /** 00085 * @copydoc ImporterShell::getInputSpecification() 00086 * 00087 * @default The default implementation adds a Progress arg and a 00088 * RasterElement arg to the arg list. 00089 */ 00090 virtual bool getInputSpecification(PlugInArgList*& pArgList); 00091 00092 /** 00093 * @copydoc ImporterShell::getOutputSpecification() 00094 * 00095 * @default The default implementation adds a SpatialDataView arg to the 00096 * arg list if the plug-in is in interactive mode and does nothing 00097 * if the plug-in is in batch mode. 00098 */ 00099 virtual bool getOutputSpecification(PlugInArgList*& pArgList); 00100 00101 /** 00102 * @copydoc ImporterShell::execute() 00103 * 00104 * @default The default implementation imports the RasterElement in the 00105 * input arg list by creating a RasterPager if the processing 00106 * location is ProcessingLocation::ON_DISK_READ_ONLY or by 00107 * creating a separate RasterElement and RasterPager and copying 00108 * the data into the original RasterElement in the input arg list. 00109 * A RasterElement arg needs to be present in the input arg list 00110 * for the method to complete successfully. 00111 */ 00112 virtual bool execute(PlugInArgList* pInArgList, PlugInArgList* pOutArgList); 00113 00114 /** 00115 * @copydoc Importer::validate() 00116 * 00117 * @default The default implementation calls the base class implementation 00118 * and provides better error messages where appropriate based on 00119 * the test conditions in getValidationTest(). If the base class 00120 * implementation validates successfully, the gray, red, green, and 00121 * blue display bands in the RasterDataDescriptor are checked 00122 * against the loaded bands. If the display band will not be 00123 * loaded, a warning is added to \em errorMessage and the method 00124 * returns \c true. 00125 */ 00126 virtual bool validate(const DataDescriptor* pDescriptor, std::string& errorMessage) const; 00127 00128 /** 00129 * @copydoc Importer::isProcessingLocationSupported() 00130 * 00131 * @default All processing locations are supported, so the default 00132 * implementation returns \b true for any valid ProcessingLocation 00133 * value. 00134 */ 00135 virtual bool isProcessingLocationSupported(ProcessingLocation location) const; 00136 00137 /** 00138 * @copydoc Importer::getPreview() 00139 * 00140 * @default The default implementation creates and returns a preview of the 00141 * given data set. A SpatialDataView is created in grayscale mode 00142 * using only the data in the first band of the data descriptor. 00143 * The data is loaded on-disk read-only to avoid unnecessary 00144 * memory allocation. However, if the data cannot be loaded 00145 * on-disk as determined with a call to validate(), it will be 00146 * loaded into memory to create the preview. 00147 */ 00148 virtual QWidget* getPreview(const DataDescriptor* pDescriptor, Progress* pProgress); 00149 00150 protected: 00151 /** 00152 * Extracts the progress and sensor data from the given input arg list. 00153 * 00154 * This method extracts the progress and sensor data values from the input 00155 * args in the given arg list. The values are stored and can be retrieved by 00156 * calling the getProgress() and getRasterElement() methods. 00157 * 00158 * @param pInArgList 00159 * The input arg list for which to extract the progress and raster 00160 * element values. 00161 * 00162 * @return Returns <b>true</b> if the sensor data value was successfully 00163 * extracted from the arg list. <b>false</b> is returned if the raster 00164 * element value could not be extracted from the arg list. The return value 00165 * does not depend on successfully extracting the progress value since 00166 * the Progress object is not required to successfully load the element. 00167 * 00168 * @see getProgress(), getRasterElement() 00169 */ 00170 virtual bool parseInputArgList(PlugInArgList* pInArgList); 00171 00172 /** 00173 * Returns the Progress object extracted from the input arg list. 00174 * 00175 * @return A pointer to the Progress object extracted from the input arg list. 00176 * <b>NULL</b> is returned if the parseInputArgList() method has not 00177 * been called or if the parsed input arg list does not contain a valid 00178 * Progress arg value. 00179 * 00180 * @see parseInputArgList() 00181 */ 00182 Progress* getProgress() const; 00183 00184 /** 00185 * Returns the RasterElement object extracted from the input arg list. 00186 * 00187 * @return A pointer to the RasterElement object extracted from the input arg list. 00188 * <b>NULL</b> is returned if the parseInputArgList() method has not 00189 * been called or if the parsed input arg list does not contain a valid 00190 * RasterElement arg value. 00191 * 00192 * @see parseInputArgList() 00193 */ 00194 RasterElement* getRasterElement() const; 00195 00196 /** 00197 * @copydoc ImporterShell::getValidationTest() 00198 * 00199 * \par 00200 * The following raster-specific tests are added to the base class defaults 00201 * listed above: 00202 * - \link ImporterShell::VALID_CLASSIFICATION VALID_CLASSIFICATION \endlink 00203 * - \link ImporterShell::RASTER_SIZE RASTER_SIZE \endlink 00204 * - \link ImporterShell::VALID_DATA_TYPE VALID_DATA_TYPE \endlink 00205 * . 00206 * \par 00207 * Additionally, the following test is added if the ::ProcessingLocation is 00208 * ::IN_MEMORY: 00209 * - \link ImporterShell::AVAILABLE_MEMORY AVAILABLE_MEMORY \endlink 00210 * . 00211 * \par 00212 * The following tests are added if the ::ProcessingLocation is 00213 * ::ON_DISK_READ_ONLY: 00214 * - \link ImporterShell::NO_INTERLEAVE_CONVERSIONS NO_INTERLEAVE_CONVERSIONS \endlink 00215 * - \link ImporterShell::NO_BAND_SUBSETS NO_BAND_SUBSETS \endlink 00216 * - \link ImporterShell::NO_SKIP_FACTORS NO_SKIP_FACTORS \endlink 00217 * . 00218 * \par 00219 * The following tests are added if the ::InterleaveFormatType is not ::BSQ: 00220 * - \link ImporterShell::NO_PRE_POST_BAND_BYTES NO_PRE_POST_BAND_BYTES \endlink 00221 * - \link ImporterShell::NO_BAND_FILES NO_BAND_FILES \endlink 00222 * . 00223 * \par 00224 * The following test is added if multiple band files are present: 00225 * - \link ImporterShell::EXISTING_BAND_FILES EXISTING_BAND_FILES \endlink 00226 * . 00227 */ 00228 virtual int getValidationTest(const DataDescriptor* pDescriptor) const; 00229 00230 /** 00231 * Perform the a default import. 00232 * 00233 * This method performs a default import by creating a RasterPager if the processing 00234 * location is ProcessingLocation::ON_DISK_READ_ONLY or by creating a separate 00235 * RasterElement and RasterPager and copying the data into the original RasterElement. 00236 * 00237 * parseInputArgList() must be called before calling this method. This method is 00238 * called from the default implementation of execute(). 00239 * 00240 * @return \c true if the operation succeeded, or \c false otherwise. Failure 00241 * may be due to an abort. In case of failure, the Progress will have an 00242 * appropriate message. 00243 */ 00244 virtual bool performImport() const; 00245 00246 /** 00247 * Creates a view for the imported data set. 00248 * 00249 * This method creates a view for the imported data set in interactive mode only. 00250 * Prior to calling this method, the parseInputArgList() method must be called to 00251 * extract the RasterElement. This method is called from the default implementation 00252 * of execute() after the createGcpList() method. 00253 * 00254 * A new message log step is created and the initially displayed bands and display 00255 * mode are added as properties to the step. 00256 * 00257 * @return A pointer to the created view. <b>NULL</b> is returned if the plug-in 00258 * is in batch mode or the raster element has not been extracted from the 00259 * input arg list. 00260 */ 00261 virtual SpatialDataView* createView() const; 00262 00263 /** 00264 * Creates a raster layer in the given view. 00265 * 00266 * This method is called from the default implementation of createView() 00267 * after the view is created. 00268 * 00269 * @param pView 00270 * The view in which to create the raster layer. 00271 * @param pStep 00272 * The message log step for creating the view. 00273 * 00274 * @return A pointer to the created raster layer. 00275 * 00276 * @default The default implementation of this method calls 00277 * SpatialDataView::createLayer() with the raster element 00278 * extracted from the input arg list as the element to display in 00279 * the layer. 00280 * 00281 * @see getRasterElement() 00282 */ 00283 virtual RasterLayer* createRasterLayer(SpatialDataView* pView, Step* pStep) const; 00284 00285 /** 00286 * Creates a GCP layer in the given view. 00287 * 00288 * This method is called from the default implementation of createView() 00289 * after the raster layer is created. 00290 * 00291 * @param pView 00292 * The view in which to create the GCP layer. 00293 * @param pStep 00294 * The message log step for creating the view. 00295 * 00296 * @return A pointer to the created GCP layer. 00297 * 00298 * @default The default implementation of this method calls 00299 * SpatialDataView::createLayer() with the GCP list returned from 00300 * createGcpList() as the element to display in the layer. If 00301 * createGcpList() returns \c NULL, the default implementation 00302 * does nothing. 00303 * 00304 * @see createRasterLayer() 00305 */ 00306 virtual GcpLayer* createGcpLayer(SpatialDataView* pView, Step* pStep) const; 00307 00308 /** 00309 * Creates a latitude/longitude layer in the given view. 00310 * 00311 * This method is called from the default implementation of createView() 00312 * after the GCP layer is created. This method is not called if the 00313 * \link Georeference::getSettingCreateLatLonLayer() 00314 * Georeference::CreateLatLonLayer\endlink setting is \c false. 00315 * 00316 * @param pView 00317 * The view in which to create the latitude/longitude layer. 00318 * @param pStep 00319 * The message log step for creating the view. 00320 * 00321 * @return A pointer to the created latitude/longitude layer. 00322 * 00323 * @default The default implementation of this method executes the 00324 * "Georeference" plug-in to create the latitude/longitude layer 00325 * based on the previously georeferenced raster element. If the 00326 * layer is successfully created, the layer is shown or hidden 00327 * based on the value of the 00328 * \link Georeference::getSettingDisplayLatLonLayer() 00329 * Georeference::DisplayLatLonLayer\endlink setting. If the raster 00330 * element was not successfully georeferenced, the default 00331 * implementation does nothing. 00332 * 00333 * @see createGcpLayer() 00334 */ 00335 virtual LatLonLayer* createLatLonLayer(SpatialDataView* pView, Step* pStep) const; 00336 00337 /** 00338 * Creates a GcpList element for the GCPs contained in the raster element 00339 * file descriptor. 00340 * 00341 * Prior to calling this method, the parseInputArgList() method must be 00342 * called to extract the raster element. This method is called from the 00343 * default implementation of execute() after the performImport() method. 00344 * 00345 * @return A pointer to the created GCP list. \c NULL is returned if the 00346 * raster element has not been extracted from the input arg list. 00347 * 00348 * @see getRasterElement() 00349 */ 00350 virtual GcpList* createGcpList() const; 00351 00352 /** 00353 * Returns the GcpList object returned from createGcpList(). 00354 * 00355 * @return A pointer to the GcpList object created as a result of the call 00356 * to createGcpList(). \c NULL is returned if the createGcpList() 00357 * method has not yet been called. 00358 */ 00359 GcpList* getGcpList() const; 00360 00361 /** 00362 * Creates a Georeference plug-in that can be used to georeference the 00363 * raster data. 00364 * 00365 * This method is called from within execute() if the configuration settings 00366 * to auto-georeference and to get the georeference plug-in from the 00367 * importer are enabled. The method is called after calling createGcpList(), 00368 * regardless of whether a valid GCP list is returned. 00369 * 00370 * The default implementation of this method creates an instance of the 00371 * GCP %Georeference plug-in and calls Georeference::canHandleRasterElement() 00372 * to see if it can georeference the raster data. If the plug-in supports 00373 * the raster data, it is returned. Otherwise the plug-in is destroyed and 00374 * \c NULL is returned. 00375 * 00376 * Derived importers should override this method if a better Georeference 00377 * plug-in is available for the raster data. 00378 * 00379 * @return A pointer to the Georeference plug-in that will be used to 00380 * georeference the raster data. The plug-in should support the 00381 * raster element returned by getRasterElement() such that 00382 * Georeference::canHandleRasterElement() returns \c true. 00383 * Ownership of the plug-in is transferred to the shell and will 00384 * be destroyed automatically. \c NULL is returned if no plug-in 00385 * is available to georeference the raster data, or if the raster 00386 * data does not contain georeference information. 00387 * 00388 * @see getRasterElement(), Georeference::getSettingAutoGeoreference(), 00389 * Georeference::getSettingImporterGeoreferencePlugIn() 00390 */ 00391 virtual PlugIn* getGeoreferencePlugIn() const; 00392 00393 /** 00394 * Create and set a RasterPager for a given RasterElement. 00395 * 00396 * Most importers should override this method instead of execute(). 00397 * Overriding this method will allow the importer to get all 00398 * of the copy and conversion capabilities provided by the default execute(). 00399 * 00400 * @param pRaster 00401 * The RasterElement to create the RasterPager for. 00402 * 00403 * @return True if the pager was successfully created, false otherwise. 00404 */ 00405 virtual bool createRasterPager(RasterElement* pRaster) const; 00406 00407 /** 00408 * Copy data from the source element to the imported one. 00409 * 00410 * @param pSrcElement 00411 * The source element to copy from. The active rows, columns, 00412 * and bands should be a superset of those being imported. 00413 * 00414 * @return True if the copy was successful, false otherwise. 00415 */ 00416 bool copyData(const RasterElement* pSrcElement) const; 00417 00418 Service<DesktopServices> mpDesktop; 00419 Service<ModelServices> mpModel; 00420 Service<PlugInManagerServices> mpPlugInManager; 00421 Service<UtilityServices> mpUtilities; 00422 00423 private: 00424 bool checkAbortOrError(std::string message, Step* pStep, bool checkForError = true) const; 00425 00426 mutable bool mUsingMemoryMappedPager; 00427 Progress* mpProgress; 00428 RasterElement* mpRasterElement; 00429 GcpList* mpGcpList; 00430 }; 00431 00432 #endif