DimensionDescriptor operator()(const DimensionDescriptor& val) { DimensionDescriptor temp = val; temp.setActiveNumber(0); temp.setActiveNumberValid(false); return temp; }
QStringList ReplaceBandInputWizard::getBandNames(const RasterDataDescriptor* pDesc) const { const DynamicObject* pMetadata = pDesc->getMetadata(); const std::vector<DimensionDescriptor>& bands = pDesc->getBands(); std::vector<std::string> bandNames; std::string pNamesPath[] = { SPECIAL_METADATA_NAME, BAND_METADATA_NAME, NAMES_METADATA_NAME, END_METADATA_NAME }; const std::vector<std::string>* pBandNames = dv_cast<std::vector<std::string> >(&pMetadata->getAttributeByPath(pNamesPath)); if ((pBandNames != NULL) && (pBandNames->size() == bands.size())) { bandNames = *pBandNames; } else { std::string pPrefixPath[] = { SPECIAL_METADATA_NAME, BAND_NAME_PREFIX_METADATA_NAME, END_METADATA_NAME }; const std::string* pBandPrefix = dv_cast<std::string>(&pMetadata->getAttributeByPath(pPrefixPath)); if (pBandPrefix != NULL) { std::string bandNamePrefix = *pBandPrefix; for (std::vector<DimensionDescriptor>::const_iterator band = bands.begin(); band != bands.end(); ++band) { bandNames.push_back(bandNamePrefix + " " + StringUtilities::toDisplayString(band->getOriginalNumber() + 1)); } } } QStringList qBandNames; for (unsigned int i = 0; i < bands.size(); i++) { DimensionDescriptor bandDim = bands[i]; QString name; if ((i < bandNames.size()) && (bands.size() == bandNames.size())) { name = QString::fromStdString(bandNames[i]); } else { name = "Band "; if (bandDim.isOriginalNumberValid()) { unsigned int originalNumber = bandDim.getOriginalNumber() + 1; name.append(QString::number(originalNumber)); } } qBandNames.append(name); } return qBandNames; }
void PropertiesRasterLayer::setDisplayBands(QAction* pAction) { if (mpRasterLayer == NULL) { return; } RasterElement* pRasterElement = dynamic_cast<RasterElement*>(mpRasterLayer->getDataElement()); if (pRasterElement == NULL) { return; } const RasterDataDescriptor* pDescriptor = dynamic_cast<const RasterDataDescriptor*>(pRasterElement->getDataDescriptor()); if (pDescriptor == NULL) { return; } const std::string name = pAction->text().toStdString(); DimensionDescriptor redBand; DimensionDescriptor greenBand; DimensionDescriptor blueBand; if (RasterUtilities::findColorCompositeDimensionDescriptors( pDescriptor, name, redBand, greenBand, blueBand) == false) { Service<DesktopServices>()->showSuppressibleMsgDlg("Error", "Unable to display " + name + ": required wavelengths do not exist for all bands. " "Broaden the wavelength region or specify band numbers in the Raster Layers section of the Options dialog.", MESSAGE_ERROR, PropertiesRasterLayer::getDisplayAsWarningDialogId()); } // If at least one of red, green, or blue is valid set display mode to RGB and update the combo boxes appropriately if (redBand.isActiveNumberValid() || greenBand.isActiveNumberValid() || blueBand.isActiveNumberValid()) { mpDisplayModeCombo->setCurrentIndex(1); mpRedBandCombo->setCurrentIndex(redBand.isActiveNumberValid() ? redBand.getActiveNumber() : -1); mpGreenBandCombo->setCurrentIndex(greenBand.isActiveNumberValid() ? greenBand.getActiveNumber() : -1); mpBlueBandCombo->setCurrentIndex(blueBand.isActiveNumberValid() ? blueBand.getActiveNumber() : -1); } }
CachedPage::UnitPtr Jpeg2000Pager::populateImageData(const DimensionDescriptor& startRow, const DimensionDescriptor& startColumn, unsigned int concurrentRows, unsigned int concurrentColumns) const { VERIFYRV(startRow.isOnDiskNumberValid() == true, CachedPage::UnitPtr()); VERIFYRV(startColumn.isOnDiskNumberValid() == true, CachedPage::UnitPtr()); VERIFYRV(concurrentRows > 0, CachedPage::UnitPtr()); VERIFYRV(concurrentColumns > 0, CachedPage::UnitPtr()); // Get the rows, colums, and bands to load unsigned int onDiskStartRow = startRow.getOnDiskNumber(); unsigned int onDiskStopRow = onDiskStartRow + concurrentRows; unsigned int onDiskStartColumn = startColumn.getOnDiskNumber(); unsigned int onDiskStopColumn = onDiskStartColumn + concurrentColumns; const RasterElement* pRaster = getRasterElement(); VERIFYRV(pRaster != NULL, CachedPage::UnitPtr()); const RasterDataDescriptor* pDescriptor = dynamic_cast<const RasterDataDescriptor*>(pRaster->getDataDescriptor()); VERIFYRV(pDescriptor != NULL, CachedPage::UnitPtr()); const RasterFileDescriptor* pFileDescriptor = dynamic_cast<const RasterFileDescriptor*>(pDescriptor->getFileDescriptor()); VERIFYRV(pFileDescriptor != NULL, CachedPage::UnitPtr()); const std::vector<DimensionDescriptor>& allBands = pFileDescriptor->getBands(); if (allBands.empty() == true) { return CachedPage::UnitPtr(); } // Create the output data unsigned int numPixels = concurrentRows * concurrentColumns * allBands.size(); unsigned int numBytes = numPixels * getBytesPerBand(); if (numPixels > static_cast<unsigned int>(std::numeric_limits<int>::max())) // ArrayResource only allocates up // to INT_MAX number of values { return CachedPage::UnitPtr(); } ArrayResource<Out> pDestination(numPixels, true); char* pDest = reinterpret_cast<char*>(pDestination.get()); if (pDest == NULL) { return CachedPage::UnitPtr(); } memset(pDest, 0, numPixels); // Decode the image from the file, first trying the codestream format then the file format opj_image_t* pImage = decodeImage(onDiskStartRow, onDiskStartColumn, onDiskStopRow, onDiskStopColumn, Jpeg2000Utilities::J2K_CFMT); if (pImage == NULL) { pImage = decodeImage(onDiskStartRow, onDiskStartColumn, onDiskStopRow, onDiskStopColumn, Jpeg2000Utilities::JP2_CFMT); } if (pImage == NULL) { return CachedPage::UnitPtr(); } // Populate the output image data int bandFactor = 1; std::string filename = pRaster->getFilename(); if (filename.empty() == false) { QStringList parts = QString::fromStdString(filename).split('.'); foreach (QString part, parts) { bool error; EncodingType dataType = StringUtilities::fromXmlString<EncodingType>(part.toStdString(), &error); if (dataType.isValid() == true && error == false) { int currentBandFactor = Jpeg2000Utilities::get_num_bands(dataType); if (currentBandFactor > 0) { bandFactor = currentBandFactor; break; } } }
CachedPage::UnitPtr Jpeg2000Pager::fetchUnit(DataRequest* pOriginalRequest) { if (pOriginalRequest == NULL) { return CachedPage::UnitPtr(); } // Check for interleave conversions, which are not supported by this pager const RasterElement* pRaster = getRasterElement(); VERIFYRV(pRaster != NULL, CachedPage::UnitPtr()); const RasterDataDescriptor* pDescriptor = dynamic_cast<const RasterDataDescriptor*>(pRaster->getDataDescriptor()); VERIFYRV(pDescriptor != NULL, CachedPage::UnitPtr()); const RasterFileDescriptor* pFileDescriptor = dynamic_cast<const RasterFileDescriptor*>(pDescriptor->getFileDescriptor()); VERIFYRV(pFileDescriptor != NULL, CachedPage::UnitPtr()); if (pFileDescriptor->getBandCount() > 1) { InterleaveFormatType requestedInterleave = pOriginalRequest->getInterleaveFormat(); InterleaveFormatType fileInterleave = pFileDescriptor->getInterleaveFormat(); if (requestedInterleave != fileInterleave) { return CachedPage::UnitPtr(); } VERIFYRV(requestedInterleave == BIP, CachedPage::UnitPtr()); // The JPEG2000 data is stored BIP } // Get and validate the extents of the data to be loaded DimensionDescriptor startRow = pOriginalRequest->getStartRow(); DimensionDescriptor stopRow = pOriginalRequest->getStopRow(); unsigned int concurrentRows = pOriginalRequest->getConcurrentRows(); DimensionDescriptor startColumn = pOriginalRequest->getStartColumn(); DimensionDescriptor stopColumn = pOriginalRequest->getStopColumn(); unsigned int concurrentColumns = pOriginalRequest->getConcurrentColumns(); DimensionDescriptor startBand = pOriginalRequest->getStartBand(); DimensionDescriptor stopBand = pOriginalRequest->getStopBand(); if ((startRow.isOnDiskNumberValid() == false) || (stopRow.isOnDiskNumberValid() == false) || (startColumn.isOnDiskNumberValid() == false) || (stopColumn.isOnDiskNumberValid() == false) || (startBand.isOnDiskNumberValid() == false) || (stopBand.isOnDiskNumberValid() == false)) { return CachedPage::UnitPtr(); } if ((startRow.getOnDiskNumber() > stopRow.getOnDiskNumber()) || (startColumn.getOnDiskNumber() > stopColumn.getOnDiskNumber()) || (startBand.getOnDiskNumber() > stopBand.getOnDiskNumber())) { return CachedPage::UnitPtr(); } if ((startRow.getActiveNumber() + concurrentRows - 1) > stopRow.getActiveNumber()) { concurrentRows = stopRow.getActiveNumber() - startRow.getActiveNumber() + 1; } if ((startColumn.getActiveNumber() + concurrentColumns - 1) > stopColumn.getActiveNumber()) { concurrentColumns = stopColumn.getActiveNumber() - startColumn.getActiveNumber() + 1; } // Populate the image data based on the output data type EncodingType outputDataType = pDescriptor->getDataType(); switch (outputDataType) { case INT1UBYTE: return populateImageData<unsigned char>(startRow, startColumn, concurrentRows, concurrentColumns); case INT1SBYTE: return populateImageData<signed char>(startRow, startColumn, concurrentRows, concurrentColumns); case INT2UBYTES: return populateImageData<unsigned short>(startRow, startColumn, concurrentRows, concurrentColumns); case INT2SBYTES: return populateImageData<signed short>(startRow, startColumn, concurrentRows, concurrentColumns); case INT4UBYTES: return populateImageData<unsigned int>(startRow, startColumn, concurrentRows, concurrentColumns); case INT4SBYTES: return populateImageData<signed int>(startRow, startColumn, concurrentRows, concurrentColumns); case FLT4BYTES: return populateImageData<float>(startRow, startColumn, concurrentRows, concurrentColumns); case FLT8BYTES: return populateImageData<double>(startRow, startColumn, concurrentRows, concurrentColumns); default: break; } return CachedPage::UnitPtr(); }
bool EditDataDescriptor::execute(PlugInArgList* pInArgList, PlugInArgList* pOutArgList) { StepResource pStep("Execute Wizard Item", "app", "055486F4-A9DB-4FDA-9AA7-75D1917E2C87"); pStep->addProperty("Item", getName()); mpStep = pStep.get(); if (extractInputArgs(pInArgList) == false) { return false; } // Set the values in the data descriptor VERIFY(mpDescriptor != NULL); // File descriptor if (mpFileDescriptor != NULL) { mpDescriptor->setFileDescriptor(mpFileDescriptor); } // Processing location if (mpProcessingLocation != NULL) { mpDescriptor->setProcessingLocation(*mpProcessingLocation); } RasterDataDescriptor* pRasterDescriptor = dynamic_cast<RasterDataDescriptor*>(mpDescriptor); RasterFileDescriptor* pRasterFileDescriptor = dynamic_cast<RasterFileDescriptor*>(mpFileDescriptor); SignatureDataDescriptor* pSignatureDescriptor = dynamic_cast<SignatureDataDescriptor*>(mpDescriptor); SignatureFileDescriptor* pSignatureFileDescriptor = dynamic_cast<SignatureFileDescriptor*>(mpFileDescriptor); if (pRasterDescriptor != NULL) { if (pRasterFileDescriptor != NULL) { // Set the rows and columns to match the rows and columns in the file descriptor before creating the subset const vector<DimensionDescriptor>& rows = pRasterFileDescriptor->getRows(); pRasterDescriptor->setRows(rows); const vector<DimensionDescriptor>& columns = pRasterFileDescriptor->getColumns(); pRasterDescriptor->setColumns(columns); const vector<DimensionDescriptor>& bands = pRasterFileDescriptor->getBands(); pRasterDescriptor->setBands(bands); } // Data type if (mpDataType != NULL) { pRasterDescriptor->setDataType(*mpDataType); } // InterleaveFormat if (mpInterleave != NULL) { pRasterDescriptor->setInterleaveFormat(*mpInterleave); } // Bad values if (mpBadValues != NULL) { pRasterDescriptor->setBadValues(*mpBadValues); } // Rows if ((mpStartRow != NULL) || (mpEndRow != NULL) || (mpRowSkipFactor != NULL)) { // We need to obtain this origRows from the FileDescriptor if present since an importer // may generate a subset by default in which case the DataDescriptor will not contain all // the rows and subsetting will not work correctly. We // can't just set mpFileDescriptor = pRasterDescriptor->getFileDescriptor() since we only // want to replace the DataDescriptor's row list if one of the subset options is specified const RasterFileDescriptor* pFileDesc(pRasterFileDescriptor); if (pFileDesc == NULL) { pFileDesc = dynamic_cast<const RasterFileDescriptor*>(pRasterDescriptor->getFileDescriptor()); } const vector<DimensionDescriptor>& origRows = (pFileDesc != NULL) ? pFileDesc->getRows() : pRasterDescriptor->getRows(); unsigned int startRow = 0; if (mpStartRow != NULL) { startRow = *mpStartRow; } else if (origRows.empty() == false) { startRow = origRows.front().getOriginalNumber() + 1; } unsigned int endRow = 0; if (mpEndRow != NULL) { endRow = *mpEndRow; } else if (origRows.empty() == false) { endRow = origRows.back().getOriginalNumber() + 1; } unsigned int rowSkip = 0; if (mpRowSkipFactor != NULL) { rowSkip = *mpRowSkipFactor; } vector<DimensionDescriptor> rows; for (unsigned int i = 0; i < origRows.size(); ++i) { DimensionDescriptor rowDim = origRows[i]; unsigned int originalNumber = rowDim.getOriginalNumber() + 1; if ((originalNumber >= startRow) && (originalNumber <= endRow)) { rows.push_back(rowDim); i += rowSkip; } } pRasterDescriptor->setRows(rows); } // Columns if ((mpStartColumn != NULL) || (mpEndColumn != NULL) || (mpColumnSkipFactor != NULL)) { // We need to obtain this origColumns from the FileDescriptor if present since an importer // may generate a subset by default in which case the DataDescriptor will not contain all // the columns and subsetting will not work correctly. We // can't just set mpFileDescriptor = pRasterDescriptor->getFileDescriptor() since we only // want to replace the DataDescriptor's column list if one of the subset options is specified const RasterFileDescriptor* pFileDesc(pRasterFileDescriptor); if (pFileDesc == NULL) { pFileDesc = dynamic_cast<const RasterFileDescriptor*>(pRasterDescriptor->getFileDescriptor()); } const vector<DimensionDescriptor>& origColumns = (pFileDesc != NULL) ? pFileDesc->getColumns() : pRasterDescriptor->getColumns(); unsigned int startColumn = 0; if (mpStartColumn != NULL) { startColumn = *mpStartColumn; } else if (origColumns.empty() == false) { startColumn = origColumns.front().getOriginalNumber() + 1; } unsigned int endColumn = 0; if (mpEndColumn != NULL) { endColumn = *mpEndColumn; } else if (origColumns.empty() == false) { endColumn = origColumns.back().getOriginalNumber() + 1; } unsigned int columnSkip = 0; if (mpColumnSkipFactor != NULL) { columnSkip = *mpColumnSkipFactor; } vector<DimensionDescriptor> columns; for (unsigned int i = 0; i < origColumns.size(); ++i) { DimensionDescriptor columnDim = origColumns[i]; unsigned int originalNumber = columnDim.getOriginalNumber() + 1; if ((originalNumber >= startColumn) && (originalNumber <= endColumn)) { columns.push_back(columnDim); i += columnSkip; } } pRasterDescriptor->setColumns(columns); } // Bands if ((mpStartBand != NULL) || (mpEndBand != NULL) || (mpBandSkipFactor != NULL) || (mpBadBandsFile != NULL)) { // We need to obtain this origBands from the FileDescriptor if present since an importer // may generate a subset by default in which case the DataDescriptor will not contain all // the bands and subsetting (especially by bad band file) will not work correctly. We // can't just set mpFileDescriptor = pRasterDescriptor->getFileDescriptor() since we only // want to replace the DataDescriptor's band list if one of the subset options is specified const RasterFileDescriptor* pFileDesc(pRasterFileDescriptor); if (pFileDesc == NULL) { pFileDesc = dynamic_cast<const RasterFileDescriptor*>(pRasterDescriptor->getFileDescriptor()); } const vector<DimensionDescriptor>& origBands = (pFileDesc != NULL) ? pFileDesc->getBands() : pRasterDescriptor->getBands(); unsigned int startBand = 0; if (mpStartBand != NULL) { startBand = *mpStartBand; } else if (origBands.empty() == false) { startBand = origBands.front().getOriginalNumber() + 1; } unsigned int endBand = 0; if (mpEndBand != NULL) { endBand = *mpEndBand; } else if (origBands.empty() == false) { endBand = origBands.back().getOriginalNumber() + 1; } unsigned int bandSkip = 0; if (mpBandSkipFactor != NULL) { bandSkip = *mpBandSkipFactor; } // Get the bad bands from the file vector<unsigned int> badBands; if (mpBadBandsFile != NULL) { string filename = *mpBadBandsFile; if (filename.empty() == false) { FILE* pFile = fopen(filename.c_str(), "rb"); if (pFile != NULL) { char line[1024]; while (fgets(line, 1024, pFile) != NULL) { unsigned int bandNumber = 0; int iValues = sscanf(line, "%u", &bandNumber); if (iValues == 1) { badBands.push_back(bandNumber); } } fclose(pFile); } } } vector<DimensionDescriptor> bands; for (unsigned int i = 0; i < origBands.size(); ++i) { DimensionDescriptor bandDim = origBands[i]; unsigned int originalNumber = bandDim.getOriginalNumber() + 1; if ((originalNumber >= startBand) && (originalNumber <= endBand)) { bool bBad = false; for (unsigned int j = 0; j < badBands.size(); ++j) { unsigned int badBandNumber = badBands[j]; if (originalNumber == badBandNumber) { bBad = true; break; } } if (bBad == false) { bands.push_back(bandDim); i += bandSkip; } } } pRasterDescriptor->setBands(bands); } // X pixel size if (mpPixelSizeX != NULL) { pRasterDescriptor->setXPixelSize(*mpPixelSizeX); } // Y pixel size if (mpPixelSizeY != NULL) { pRasterDescriptor->setYPixelSize(*mpPixelSizeY); } // Units if ((mpUnitsName != NULL) || (mpUnitsType != NULL) || (mpUnitsScale != NULL) || (mpUnitsRangeMin != NULL) || (mpUnitsRangeMax != NULL)) { const Units* pOrigUnits = pRasterDescriptor->getUnits(); FactoryResource<Units> pUnits; VERIFY(pUnits.get() != NULL); // Name if (mpUnitsName != NULL) { pUnits->setUnitName(*mpUnitsName); } else if (pOrigUnits != NULL) { pUnits->setUnitName(pOrigUnits->getUnitName()); } // Type if (mpUnitsType != NULL) { pUnits->setUnitType(*mpUnitsType); } else if (pOrigUnits != NULL) { pUnits->setUnitType(pOrigUnits->getUnitType()); } // Scale if (mpUnitsScale != NULL) { pUnits->setScaleFromStandard(*mpUnitsScale); } else if (pOrigUnits != NULL) { pUnits->setScaleFromStandard(pOrigUnits->getScaleFromStandard()); } // Range minimum if (mpUnitsRangeMin != NULL) { pUnits->setRangeMin(*mpUnitsRangeMin); } else if (pOrigUnits != NULL) { pUnits->setRangeMin(pOrigUnits->getRangeMin()); } // Range maximum if (mpUnitsRangeMax != NULL) { pUnits->setRangeMax(*mpUnitsRangeMax); } else if (pOrigUnits != NULL) { pUnits->setRangeMax(pOrigUnits->getRangeMax()); } pRasterDescriptor->setUnits(pUnits.get()); } // Display mode if (mpDisplayMode != NULL) { pRasterDescriptor->setDisplayMode(*mpDisplayMode); } // Display bands // Gray if (mpGrayBand != NULL) { DimensionDescriptor band = pRasterDescriptor->getOriginalBand(*mpGrayBand - 1); pRasterDescriptor->setDisplayBand(GRAY, band); } // Red if (mpRedBand != NULL) { DimensionDescriptor band = pRasterDescriptor->getOriginalBand(*mpRedBand - 1); pRasterDescriptor->setDisplayBand(RED, band); } // Green if (mpGreenBand != NULL) { DimensionDescriptor band = pRasterDescriptor->getOriginalBand(*mpGreenBand - 1); pRasterDescriptor->setDisplayBand(GREEN, band); } // Blue if (mpBlueBand != NULL) { DimensionDescriptor band = pRasterDescriptor->getOriginalBand(*mpBlueBand - 1); pRasterDescriptor->setDisplayBand(BLUE, band); } } else if (pSignatureDescriptor != NULL) { if (mpComponentName != NULL) { const Units* pOrigUnits = pSignatureDescriptor->getUnits(*mpComponentName); FactoryResource<Units> pUnits; if (pOrigUnits != NULL) { *pUnits = *pOrigUnits; } if (mpUnitsName != NULL) { pUnits->setUnitName(*mpUnitsName); } if (mpUnitsType != NULL) { pUnits->setUnitType(*mpUnitsType); } if (mpUnitsScale != NULL) { pUnits->setScaleFromStandard(*mpUnitsScale); } if (mpUnitsRangeMin != NULL) { pUnits->setRangeMin(*mpUnitsRangeMin); } if (mpUnitsRangeMax != NULL) { pUnits->setRangeMax(*mpUnitsRangeMax); } pSignatureDescriptor->setUnits(*mpComponentName, pUnits.get()); } } reportComplete(); return true; }
bool GeoTIFFExporter::writeCube(TIFF* pOut) { if (pOut == NULL) { return false; } VERIFY(mpRaster != NULL); VERIFY(mpFileDescriptor != NULL); const RasterDataDescriptor* pDescriptor = dynamic_cast<const RasterDataDescriptor*>(mpRaster->getDataDescriptor()); if (pDescriptor == NULL) { return false; } int size = 0; int row = 0; unsigned char* pTempPtr = NULL; unsigned char* pBuffer = NULL; unsigned char* pDataCubePtr = NULL; unsigned short numRows = pDescriptor->getRowCount(); unsigned short numCols = pDescriptor->getColumnCount(); unsigned short numBands = pDescriptor->getBandCount(); unsigned short scols = mpFileDescriptor->getColumnCount(); unsigned short srows = mpFileDescriptor->getRowCount(); unsigned short sbands = mpFileDescriptor->getBandCount(); FactoryResource<DataRequest> pRequest; pRequest->setInterleaveFormat(BIP); DataAccessor accessor = mpRaster->getDataAccessor(pRequest.release()); if (!accessor.isValid()) { mMessage = "Could not get a valid BIP accessor for this dataset."; if (mpProgress != NULL) { mpProgress->updateProgress(mMessage, 0, ERRORS); } return false; } InterleaveFormatType eInterleave = pDescriptor->getInterleaveFormat(); if (eInterleave != BIP) { mMessage = "Data will be saved in BIP format."; if (mpProgress != NULL) { mpProgress->updateProgress(mMessage, 0, WARNING); } } unsigned int bytesPerElement(pDescriptor->getBytesPerElement()); size = scols * sbands * bytesPerElement; TIFFSetField(pOut, TIFFTAG_IMAGEWIDTH, scols); TIFFSetField(pOut, TIFFTAG_IMAGELENGTH, srows); TIFFSetField(pOut, TIFFTAG_SAMPLESPERPIXEL, sbands); //for this tag, must multiply by # of bytes per data type TIFFSetField(pOut, TIFFTAG_BITSPERSAMPLE, static_cast<unsigned short>(bytesPerElement * 8)); TIFFSetField(pOut, TIFFTAG_SAMPLEFORMAT, static_cast<unsigned short>( getTiffSampleFormat(pDescriptor->getDataType()))); bool packBits = OptionsTiffExporter::getSettingPackBitsCompression(); if (mpOptionWidget.get() != NULL) { mpOptionWidget->applyChanges(); packBits = mpOptionWidget->getPackBitsCompression(); } ttag_t compOpt = (packBits ? COMPRESSION_PACKBITS : COMPRESSION_NONE); TIFFSetField(pOut, TIFFTAG_COMPRESSION, compOpt); TIFFSetField(pOut, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB); TIFFSetField(pOut, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); TIFFSetField(pOut, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT); //???? TIFFSetField(pOut, TIFFTAG_ROWSPERSTRIP, mRowsPerStrip); //ready to test write mMessage = "Writing out GeoTIFF file..."; if (mpProgress) { mpProgress->updateProgress( mMessage, 0, NORMAL); } if ((numRows == srows) && (numCols == scols) && (numBands == sbands)) // full cube write from memory { for (row = 0; row < srows; row++) { if (mAbortFlag) { mMessage = "GeoTIFF export aborted!"; if (mpProgress != NULL) { mpProgress->updateProgress(mMessage, 0, ERRORS); } return false; } VERIFY(accessor.isValid()); pBuffer = reinterpret_cast<unsigned char*>(accessor->getRow()); if (pBuffer != NULL) { if (TIFFWriteScanline(pOut, pBuffer, row, size) < 0) { mMessage = "Unable to save GeoTIFF file, check folder permissions."; if (mpProgress) { mpProgress->updateProgress(mMessage, 0, ERRORS); } return false; } updateProgress(row, srows, mMessage, NORMAL); } accessor->nextRow(); } } else // subcube write { const vector<DimensionDescriptor>& rows = mpFileDescriptor->getRows(); const vector<DimensionDescriptor>& columns = mpFileDescriptor->getColumns(); const vector<DimensionDescriptor>& bands = mpFileDescriptor->getBands(); unsigned int activeRowNumber = 0; unsigned int rowSize(0); unsigned int outRow(0); for (unsigned int r = 0; r < srows; ++r) { if (mAbortFlag == true) { mMessage = "GeoTIFF export aborted!"; if (mpProgress != NULL) { mpProgress->updateProgress(mMessage, 0, ERRORS); } return false; } DimensionDescriptor rowDim = rows[r]; if (rowDim.isActiveNumberValid()) { // Skip to the next row for (; activeRowNumber < rowDim.getActiveNumber(); ++activeRowNumber) { accessor->nextRow(); } VERIFY(accessor.isValid()); vector<char> rowData(size); if (rowData.empty()) { mMessage = "Error GeoTIFFExporter008: Unable to allocate row buffer."; if (mpProgress) { mpProgress->updateProgress(mMessage, 0, ERRORS); } return false; } unsigned int activeColumnNumber = 0; char* pExportData = &(rowData.front()); for (unsigned int c = 0; c < scols; ++c) { DimensionDescriptor columnDim = columns[c]; if (columnDim.isActiveNumberValid()) { // Skip to the next column for (; activeColumnNumber < columnDim.getActiveNumber(); ++activeColumnNumber) { accessor->nextColumn(); } char* pCurrentPixel = reinterpret_cast<char*>(accessor->getColumn()); unsigned int activeBandNumber = 0; for (unsigned int b = 0; b < sbands; ++b) { DimensionDescriptor bandDim = bands[b]; if (bandDim.isActiveNumberValid()) { // Skip to the next band for (; activeBandNumber < bandDim.getActiveNumber(); ++activeBandNumber) { pCurrentPixel += bytesPerElement; } memcpy(pExportData, pCurrentPixel, bytesPerElement); pExportData += bytesPerElement; rowSize += bytesPerElement; } } } else // this column is not included, go to next column { accessor->nextColumn(); } } if (rowSize > 0) { // write here if (TIFFWriteScanline(pOut, &rowData[0], outRow, size) < 0) { mMessage = "Error GeoTIFFExporter006: Unable to save GeoTIFF file, check folder permissions."; if (mpProgress) { mpProgress->updateProgress(mMessage, 0, ERRORS); } return false; } updateProgress(outRow++, srows, mMessage, NORMAL); } } else // this row is not included, go to next row { accessor->nextRow(); } } } //assumed everything has been done correctly up to now //copy over Geo ref info if there are any, else //try to look for world file in same directory and apply if (!(applyWorldFile(pOut))) { if (!(CreateGeoTIFF(pOut))) { //no geo info found, where is it located? mMessage = "Geo data is unavailable and will not be written to the output file!"; updateProgress(srows, srows, mMessage, WARNING); if (mpStep != NULL) { mpStep->addMessage(mMessage, "app", "9C1E7ADE-ADC4-468c-B15E-FEB53D5FEF5B", true); } } } return true; }
bool ThresholdData::execute(PlugInArgList* pInArgList, PlugInArgList* pOutArgList) { VERIFY(pInArgList != NULL); StepResource pStep("Execute Wizard Item", "app", "{2501975d-7cd5-49b0-a3e7-49f7106793c0}"); pStep->addProperty("Item", getName()); mpStep = pStep.get(); if (!extractInputArgs(pInArgList)) { return false; } const RasterDataDescriptor* pDesc = static_cast<const RasterDataDescriptor*>(mpInputElement->getDataDescriptor()); VERIFY(pDesc); DimensionDescriptor band; if (mDisplayBandNumber > 0) { band = pDesc->getOriginalBand(mDisplayBandNumber - 1); if (band.isValid() == false) { reportError("The specified band is invalid.", "{a529538b-5b82-425d-af10-385a2581beec}"); return false; } } else { band = pDesc->getActiveBand(mDisplayBandNumber); } FactoryResource<DataRequest> pReq; pReq->setInterleaveFormat(BSQ); pReq->setBands(band, band, 1); DataAccessor acc = mpInputElement->getDataAccessor(pReq.release()); if (!acc.isValid()) { reportError("Unable to access data element.", "{b5f1b7dd-7cf7-4cd5-b5bc-7b747d3561b9}"); return false; } // If necessary, convert region units if (mRegionUnits != RAW_VALUE) { Statistics* pStatistics = mpInputElement->getStatistics(band); if (pStatistics == NULL) { reportError("Unable to calculate data statistics.", "{61a44ced-a4aa-4423-b379-5783137eb980}"); return false; } mFirstThreshold = convertToRawUnits(pStatistics, mRegionUnits, mFirstThreshold); mSecondThreshold = convertToRawUnits(pStatistics, mRegionUnits, mSecondThreshold); } FactoryResource<BitMask> pBitmask; for (unsigned int row = 0; row < pDesc->getRowCount(); ++row) { reportProgress("Thresholding data", 100 * row / pDesc->getRowCount(), "{2fc3dbea-1307-471c-bba2-bf86032be518}"); for (unsigned int col = 0; col < pDesc->getColumnCount(); ++col) { VERIFY(acc.isValid()); double val = ModelServices::getDataValue(pDesc->getDataType(), acc->getColumn(), 0); switch (mPassArea) { case UPPER: if (val >= mFirstThreshold) { pBitmask->setPixel(col, row, true); } break; case LOWER: if (val <= mFirstThreshold) { pBitmask->setPixel(col, row, true); } break; case MIDDLE: if (val >= mFirstThreshold && val <= mSecondThreshold) { pBitmask->setPixel(col, row, true); } break; case OUTSIDE: if (val <= mFirstThreshold || val >= mSecondThreshold) { pBitmask->setPixel(col, row, true); } break; default: reportError("Unknown or invalid pass area.", "{19c92b3b-52e9-442b-a01f-b545f819f200}"); return false; } acc->nextColumn(); } acc->nextRow(); } std::string aoiName = pDesc->getName() + "_aoi"; ModelResource<AoiElement> pAoi(aoiName, mpInputElement); if (pAoi.get() == NULL) { reportWarning("Overwriting existing AOI.", "{d953a030-dd63-43a1-98db-b0f491dee123}"); Service<ModelServices>()->destroyElement( Service<ModelServices>()->getElement(aoiName, TypeConverter::toString<AoiElement>(), mpInputElement)); pAoi = ModelResource<AoiElement>(aoiName, mpInputElement); } if (pAoi.get() == NULL) { reportError("Unable to create output AOI.", "{f76c2f4d-9a7f-4055-9383-022116cdcadb}"); return false; } pAoi->addPoints(pBitmask.get()); AoiLayer* pLayer = NULL; if (mpView != NULL) { if ((pLayer = static_cast<AoiLayer*>(mpView->createLayer(AOI_LAYER, pAoi.get()))) == NULL) { reportWarning("Unable to create AOI layer, continuing thresholding.", "{5eca6ea0-33c1-4b1a-b777-c8e1b86fd2fb}"); } } if (pOutArgList != NULL) { pOutArgList->setPlugInArgValue("Result", pAoi.get()); if (pLayer != NULL) { pOutArgList->setPlugInArgValue("Result Layer", pLayer); } } pAoi.release(); reportComplete(); return true; }
bool BandMath::createReturnValue(string partialResultsName) { // Set the short and long result names FactoryResource<Filename> pFilename; string shortResultsName; string longResultsName; if (pFilename.get() != NULL) { pFilename->setFullPathAndName(mpCube->getFilename()); shortResultsName = pFilename->getTitle() + " = " + partialResultsName; longResultsName = pFilename->getPath() + "/" + pFilename->getTitle() + " = " + partialResultsName; } mResultsName = longResultsName; const RasterDataDescriptor* pOrigDescriptor = dynamic_cast<RasterDataDescriptor*>(mpCube->getDataDescriptor()); const vector<DimensionDescriptor>& origRows = pOrigDescriptor->getRows(); const vector<DimensionDescriptor>& origColumns = pOrigDescriptor->getColumns(); mpResultData = NULL; unsigned int bandCount = mCubeBands; if (mbCubeMath == false) { bandCount = 1; } RasterElement* pParent = NULL; if (mbAsLayerOnExistingView) { pParent = mpCube; } RasterElement* pRaster = RasterUtilities::createRasterElement(mResultsName, origRows.size(), origColumns.size(), bandCount, FLT4BYTES, BIP, pOrigDescriptor->getProcessingLocation() == IN_MEMORY, pParent); if (pRaster == NULL) { mstrProgressString = "Error creating result raster element"; meGabbiness = ERRORS; displayErrorMessage(); mbError = true; return false; } if (!mbAsLayerOnExistingView) { // need to copy classification since parent was NULL in call to createRasterElement pRaster->copyClassification(mpCube); // make copies of existing GcpLists only if going into a new view vector<DataElement*> gcps = mpDataModel->getElements(mpCube, "GcpList"); if (!gcps.empty()) { vector<DataElement*>::iterator iter; for (iter = gcps.begin(); iter != gcps.end(); ++iter) { GcpList* theGcp = dynamic_cast<GcpList*>(*iter); theGcp->copy(theGcp->getName(), pRaster); } } } mpResultData = pRaster; RasterDataDescriptor* pDescriptor = dynamic_cast<RasterDataDescriptor*> (mpResultData->getDataDescriptor()); if (pDescriptor != NULL) { // Rows vector<DimensionDescriptor> rows = pDescriptor->getRows(); for (unsigned int i = 0; i < origRows.size(); ++i) { // Original number DimensionDescriptor origRow = origRows[i]; if (origRow.isOriginalNumberValid() == true) { rows[i].setOriginalNumber(origRow.getOriginalNumber()); } } pDescriptor->setRows(rows); // Columns vector<DimensionDescriptor> columns = pDescriptor->getColumns(); for (unsigned int i = 0; i < origColumns.size(); ++i) { // Original number DimensionDescriptor origColumn = origColumns[i]; if (origColumn.isOriginalNumberValid() == true) { columns[i].setOriginalNumber(origColumn.getOriginalNumber()); } } pDescriptor->setColumns(columns); } return true; }
vector<ImportDescriptor*> EnviImporter::getImportDescriptors(const string& filename) { string headerFile = filename; string dataFile; bool bSuccess = parseHeader(headerFile); if (bSuccess == false) { dataFile = filename; // was passed data file name instead of header file name headerFile = findHeaderFile(headerFile); if (headerFile.empty() == false) { bSuccess = parseHeader(headerFile); } } EnviField* pField = NULL; vector<ImportDescriptor*> descriptors; if (bSuccess == true) { if (dataFile.empty() == true) // was passed header file name and now need to find the data file name { dataFile = findDataFile(headerFile); } if (dataFile.empty() == false) { ImportDescriptor* pImportDescriptor = mpModel->createImportDescriptor(dataFile, "RasterElement", NULL); if (pImportDescriptor != NULL) { RasterDataDescriptor* pDescriptor = dynamic_cast<RasterDataDescriptor*>(pImportDescriptor->getDataDescriptor()); if (pDescriptor != NULL) { FactoryResource<RasterFileDescriptor> pFileDescriptor; if (pFileDescriptor.get() != NULL) { // Filename pFileDescriptor->setFilename(dataFile); // Coordinate offset int columnOffset = 0; int rowOffset = 0; pField = mFields.find("x start"); if (pField != NULL) { // ENVI numbers are 1 based vs Opticks being 0 based columnOffset = atoi(pField->mValue.c_str()) - 1; } pField = mFields.find("y start"); if (pField != NULL) { rowOffset = atoi(pField->mValue.c_str()) - 1; // ENVI numbers are 1 based vs Opticks being 0 based } // Rows vector<DimensionDescriptor> rows; pField = mFields.find("lines"); if (pField != NULL) { int numRows = atoi(pField->mValue.c_str()); for (int i = 0; i < numRows; ++i) { DimensionDescriptor rowDim; rowDim.setOriginalNumber(static_cast<unsigned int>(rowOffset + i)); rowDim.setOnDiskNumber(static_cast<unsigned int>(i)); rows.push_back(rowDim); } pDescriptor->setRows(rows); pFileDescriptor->setRows(rows); } string samplesStr = "samples"; string bandsStr = "bands"; // Special case: if the file type is an ENVI Spectral Library, then swap samples with bands // If no file type field exists, assume this is a normal ENVI header (not a Spectral Library) EnviField* pFileTypeField = mFields.find("file type"); if (pFileTypeField != NULL && (pFileTypeField->mValue == "ENVI Spectral Library" || pFileTypeField->mValue == "Spectral Library")) { samplesStr = "bands"; bandsStr = "samples"; // Since bands and samples are swapped, force the interleave to BIP pField = mFields.find("interleave"); if (pField != NULL) { pField->mValue = "bip"; } } // Columns vector<DimensionDescriptor> columns; pField = mFields.find(samplesStr); if (pField != NULL) { int numColumns = atoi(pField->mValue.c_str()); for (int i = 0; i < numColumns; ++i) { DimensionDescriptor columnDim; columnDim.setOriginalNumber(static_cast<unsigned int>(columnOffset + i)); columnDim.setOnDiskNumber(static_cast<unsigned int>(i)); columns.push_back(columnDim); } pDescriptor->setColumns(columns); pFileDescriptor->setColumns(columns); } // Bands vector<DimensionDescriptor> bands; pField = mFields.find(bandsStr); if (pField != NULL) { int numBands = atoi(pField->mValue.c_str()); bands = RasterUtilities::generateDimensionVector(numBands, true, false, true); pDescriptor->setBands(bands); pFileDescriptor->setBands(bands); } // Description list<GcpPoint> gcps; pField = mFields.find("description"); if (pField != NULL) { // Metadata if (pField->mChildren.empty() == false) { FactoryResource<DynamicObject> pMetadata; for (unsigned int i = 0; i < pField->mChildren.size(); ++i) { EnviField* pChild = pField->mChildren[i]; if (pChild != NULL) { if (pChild->mTag == "classification") { // Classification FactoryResource<Classification> pClassification; if (pClassification.get() != NULL) { string classLevel; classLevel.append(1, *(pChild->mValue.data())); pClassification->setLevel(classLevel); pDescriptor->setClassification(pClassification.get()); } } else if ((pChild->mTag == "ll") || (pChild->mTag == "lr") || (pChild->mTag == "ul") || (pChild->mTag == "ur") || (pChild->mTag == "center")) { GcpPoint gcp; bool dmsFormat = false; char ns; char ew; sscanf(pChild->mValue.c_str(), "%lg%c %lg%c", &gcp.mCoordinate.mY, &ew, &gcp.mCoordinate.mX, &ns); if (fabs(gcp.mCoordinate.mY) > 180.0 || fabs(gcp.mCoordinate.mX) > 90.0) { dmsFormat = true; } double deg; double min; double sec; if (dmsFormat == true) { deg = static_cast<int>(gcp.mCoordinate.mY / 10000.0); min = static_cast<int>((gcp.mCoordinate.mY - 10000.0 * deg) / 100.0); sec = gcp.mCoordinate.mY - 10000.0 * deg - 100.0 * min; gcp.mCoordinate.mY = deg + (min / 60.0) + (sec / 3600.0); } if (ew == 'W' || ew == 'w') { gcp.mCoordinate.mY = -gcp.mCoordinate.mY; } if (dmsFormat) { deg = static_cast<int>(gcp.mCoordinate.mX / 10000.0); min = static_cast<int>((gcp.mCoordinate.mX - 10000.0 * deg) / 100.0); sec = gcp.mCoordinate.mX - 10000.0 * deg - 100.0 * min; gcp.mCoordinate.mX = deg + (min / 60.0) + (sec / 3600.0); } if (ns == 'S' || ns == 's') { gcp.mCoordinate.mX = -gcp.mCoordinate.mX; } // ENVI uses a 1-based pixel coordinate system, with each coordinate referring // to the top-left corner of the pixel, e.g. (1,1) is the top-left // corner of the pixel in the top-left of the raster cube // The ENVI pixel coordinate format is described on p. 1126 of the ENVI 4.2 User's Guide if (pChild->mTag == "ll") { gcp.mPixel.mX = 0.0; gcp.mPixel.mY = 0.0; } else if (pChild->mTag == "lr") { gcp.mPixel.mX = columns.size() - 1.0; gcp.mPixel.mY = 0.0; } else if (pChild->mTag == "ul") { gcp.mPixel.mX = 0.0; gcp.mPixel.mY = rows.size() - 1.0; } else if (pChild->mTag == "ur") { gcp.mPixel.mX = columns.size() - 1.0; gcp.mPixel.mY = rows.size() - 1.0; } else if (pChild->mTag == "center") { gcp.mPixel.mX = floor((columns.size() - 1.0) / 2.0); gcp.mPixel.mY = floor((rows.size() - 1.0) / 2.0); } gcps.push_back(gcp); } else if (pChild->mTag.empty() == false) { pMetadata->setAttribute(pChild->mTag, pChild->mValue); } } } if (pMetadata->getNumAttributes() > 0) { pDescriptor->setMetadata(pMetadata.get()); } } } if (gcps.empty()) // not in description, check for geo points keyword { pField = mFields.find("geo points"); if (pField != NULL) { vector<double> geoValues; const int expectedNumValues = 16; // 4 values for each of the 4 corners geoValues.reserve(expectedNumValues); for (unsigned int i = 0; i < pField->mChildren.size(); i++) { vectorFromField(pField->mChildren.at(i), geoValues, "%lf"); } if (geoValues.size() == expectedNumValues) { vector<double>::iterator iter = geoValues.begin(); GcpPoint gcp; while (iter != geoValues.end()) { gcp.mPixel.mX = *iter++ - 1.0; // adjust ref point for ENVI's use of gcp.mPixel.mY = *iter++ - 1.0; // upper left corner and one-based first pixel gcp.mCoordinate.mX = *iter++; // GcpPoint has lat as mX and Lon as mY gcp.mCoordinate.mY = *iter++; // geo point field has lat then lon value gcps.push_back(gcp); } } } } // GCPs if (gcps.empty() == false) { pFileDescriptor->setGcps(gcps); } // Header bytes pField = mFields.find("header offset"); if (pField != NULL) { int headerBytes = atoi(pField->mValue.c_str()); pFileDescriptor->setHeaderBytes(static_cast<unsigned int>(headerBytes)); } // Data type pField = mFields.find("data type"); if (pField != NULL) { vector<EncodingType> validDataTypes; switch (atoi(pField->mValue.c_str())) { case 1: // char pDescriptor->setDataType(INT1UBYTE); pFileDescriptor->setBitsPerElement(8); // signed char cannot be represented in ENVI header so use the closest thing validDataTypes.push_back(INT1SBYTE); break; case 2: // short pDescriptor->setDataType(INT2SBYTES); pFileDescriptor->setBitsPerElement(16); break; case 3: // int pDescriptor->setDataType(INT4SBYTES); pFileDescriptor->setBitsPerElement(32); break; case 4: // float pDescriptor->setDataType(FLT4BYTES); pFileDescriptor->setBitsPerElement(32); break; case 5: // double pDescriptor->setDataType(FLT8BYTES); pFileDescriptor->setBitsPerElement(64); break; case 6: // float complex pDescriptor->setDataType(FLT8COMPLEX); pFileDescriptor->setBitsPerElement(64); break; case 9: // double complex // not supported break; case 12: // unsigned short pDescriptor->setDataType(INT2UBYTES); pFileDescriptor->setBitsPerElement(16); break; case 13: // unsigned int pDescriptor->setDataType(INT4UBYTES); pFileDescriptor->setBitsPerElement(32); break; case 14: // 64-bit int case 15: // unsigned 64-bit int // not supported break; case 99: // integer complex (recognized only by this application) pDescriptor->setDataType(INT4SCOMPLEX); pFileDescriptor->setBitsPerElement(32); break; default: break; } // Bad values EncodingType dataType = pDescriptor->getDataType(); if ((dataType != FLT4BYTES) && (dataType != FLT8COMPLEX) && (dataType != FLT8BYTES)) { vector<int> badValues; badValues.push_back(0); pDescriptor->setBadValues(badValues); } validDataTypes.push_back(dataType); pDescriptor->setValidDataTypes(validDataTypes); } // Interleave format pField = mFields.find("interleave"); if (pField != NULL) { string interleave = StringUtilities::toLower(pField->mValue); if (interleave == "bip") { pDescriptor->setInterleaveFormat(BIP); pFileDescriptor->setInterleaveFormat(BIP); } else if (interleave == "bil") { pDescriptor->setInterleaveFormat(BIL); pFileDescriptor->setInterleaveFormat(BIL); } else if (interleave == "bsq") { pDescriptor->setInterleaveFormat(BSQ); pFileDescriptor->setInterleaveFormat(BSQ); } } // Endian pField = mFields.find("byte order"); if (pField != NULL) { int byteOrder = atoi(pField->mValue.c_str()); if (byteOrder == 0) { pFileDescriptor->setEndian(LITTLE_ENDIAN_ORDER); } else if (byteOrder == 1) { pFileDescriptor->setEndian(BIG_ENDIAN_ORDER); } } // check for scaling factor pField = mFields.find("reflectance scale factor"); if (pField != NULL) { double scalingFactor = 0.0; stringstream scaleStream(pField->mValue); scaleStream >> scalingFactor; if (!scaleStream.fail() && scalingFactor != 0.0) { Units* pUnits = pDescriptor->getUnits(); if (pUnits != NULL) { pUnits->setScaleFromStandard(1.0 / scalingFactor); pUnits->setUnitName("Reflectance"); pUnits->setUnitType(REFLECTANCE); } } } // Pixel size pField = mFields.find("pixel size"); if (pField != NULL) { if (pField->mChildren.size() == 2) { pField = pField->mChildren[0]; if (pField != NULL) { double pixelSize = 1.0; if (sscanf(pField->mValue.c_str(), "%g", &pixelSize) == 1) { pDescriptor->setXPixelSize(pixelSize); pFileDescriptor->setXPixelSize(pixelSize); } } pField = pField->mChildren[1]; if (pField != NULL) { double pixelSize = 1.0; if (sscanf(pField->mValue.c_str(), "%g", &pixelSize) == 1) { pDescriptor->setYPixelSize(pixelSize); pFileDescriptor->setYPixelSize(pixelSize); } } } } // Default bands pField = mFields.find("default bands"); if (pField != NULL) { vector<unsigned int> displayBands; parseDefaultBands(pField, &displayBands); if (displayBands.size() == 1) { DimensionDescriptor grayBand = pFileDescriptor->getOriginalBand(displayBands[0]); pDescriptor->setDisplayBand(GRAY, grayBand); pDescriptor->setDisplayMode(GRAYSCALE_MODE); } else if (displayBands.size() == 3) { DimensionDescriptor redBand = pFileDescriptor->getOriginalBand(displayBands[0]); DimensionDescriptor greenBand = pFileDescriptor->getOriginalBand(displayBands[1]); DimensionDescriptor blueBand = pFileDescriptor->getOriginalBand(displayBands[2]); pDescriptor->setDisplayBand(RED, redBand); pDescriptor->setDisplayBand(GREEN, greenBand); pDescriptor->setDisplayBand(BLUE, blueBand); pDescriptor->setDisplayMode(RGB_MODE); } } // Bad bands pField = mFields.find("bbl"); if (pField != NULL) { vector<unsigned int> validBands; parseBbl(pField, validBands); vector<DimensionDescriptor> bandsToLoad; for (vector<unsigned int>::const_iterator iter = validBands.begin(); iter != validBands.end(); ++iter) { const unsigned int onDiskNumber = *iter; const DimensionDescriptor dim = pFileDescriptor->getOnDiskBand(onDiskNumber); if (dim.isValid()) { bandsToLoad.push_back(dim); } } pDescriptor->setBands(bandsToLoad); } DynamicObject* pMetadata = pDescriptor->getMetadata(); // Band names pField = mFields.find("band names"); if (pField != NULL) { vector<string> bandNames; bandNames.reserve(bands.size()); vector<string> strNames; for (vector<EnviField*>::size_type i = 0; i < pField->mChildren.size(); ++i) { strNames = StringUtilities::split(pField->mChildren[i]->mValue, ','); copy(strNames.begin(), strNames.end(), back_inserter(bandNames)); } vector<string>::iterator it; for (it = bandNames.begin(); it != bandNames.end(); ++it) { *it = StringUtilities::stripWhitespace(*it); } if (pMetadata != NULL) { string pNamesPath[] = { SPECIAL_METADATA_NAME, BAND_METADATA_NAME, NAMES_METADATA_NAME, END_METADATA_NAME }; pMetadata->setAttributeByPath(pNamesPath, bandNames); } } // wavelength units pField = mFields.find("wavelength units"); if (pField != NULL) { mWavelengthUnits = strToType(pField->mValue); } // Wavelengths vector<double> centerWavelengths; pField = mFields.find("wavelength"); if (pField != NULL) { if ((parseWavelengths(pField, ¢erWavelengths) == true) && (pMetadata != NULL)) { string pCenterPath[] = { SPECIAL_METADATA_NAME, BAND_METADATA_NAME, CENTER_WAVELENGTHS_METADATA_NAME, END_METADATA_NAME }; pMetadata->setAttributeByPath(pCenterPath, centerWavelengths); } } // FWHM pField = mFields.find("fwhm"); if (pField != NULL) { vector<double> startWavelengths; vector<double> endWavelengths; if ((parseFwhm(pField, &startWavelengths, ¢erWavelengths, &endWavelengths) == true) && (pMetadata != NULL)) { string pStartPath[] = { SPECIAL_METADATA_NAME, BAND_METADATA_NAME, START_WAVELENGTHS_METADATA_NAME, END_METADATA_NAME }; pMetadata->setAttributeByPath(pStartPath, startWavelengths); string pEndPath[] = { SPECIAL_METADATA_NAME, BAND_METADATA_NAME, END_WAVELENGTHS_METADATA_NAME, END_METADATA_NAME }; pMetadata->setAttributeByPath(pEndPath, endWavelengths); } } // File descriptor pDescriptor->setFileDescriptor(pFileDescriptor.get()); }
vector<ImportDescriptor*> SioImporter::getImportDescriptors(const string& filename) { vector<ImportDescriptor*> descriptors; if (filename.empty() == false) { // Read the header values FileResource pFile(filename.c_str(), "rb"); SioFile sioFile; bool bSuccess = sioFile.deserialize(pFile.get()); if (bSuccess == false) { return descriptors; } if (sioFile.mOriginalVersion == 9) { mVersion9Sio = true; } // Create the import descriptor ImportDescriptor* pImportDescriptor = mpModel->createImportDescriptor(filename, "RasterElement", NULL); if (pImportDescriptor != NULL) { RasterDataDescriptor* pDescriptor = dynamic_cast<RasterDataDescriptor*>(pImportDescriptor->getDataDescriptor()); if (pDescriptor != NULL) { FactoryResource<RasterFileDescriptor> pFileDescriptor; if (pFileDescriptor.get() != NULL) { // Filename pFileDescriptor->setFilename(filename); // Endian pFileDescriptor->setEndian(sioFile.mEndian); // Rows vector<DimensionDescriptor> rows; for (int i = 0; i < sioFile.mRows; ++i) { DimensionDescriptor rowDim; // Do not set an active number since the user has not selected the rows to load if (static_cast<unsigned int>(i) < sioFile.mOrigRowNumbers.size()) { rowDim.setOriginalNumber(sioFile.mOrigRowNumbers[i]); } else { rowDim.setOriginalNumber(i); } rowDim.setOnDiskNumber(i); rows.push_back(rowDim); } pDescriptor->setRows(rows); pFileDescriptor->setRows(rows); // Columns vector<DimensionDescriptor> columns; for (int i = 0; i < sioFile.mColumns; ++i) { DimensionDescriptor columnDim; // Do not set an active number since the user has not selected the rows to load if (static_cast<unsigned int>(i) < sioFile.mOrigColumnNumbers.size()) { columnDim.setOriginalNumber(sioFile.mOrigColumnNumbers[i]); } else { columnDim.setOriginalNumber(i); } columnDim.setOnDiskNumber(i); columns.push_back(columnDim); } pDescriptor->setColumns(columns); pFileDescriptor->setColumns(columns); // Bands vector<DimensionDescriptor> bands; for (int i = 0; i < (sioFile.mBands - sioFile.mBadBands); ++i) { DimensionDescriptor bandDim; // Do not set an active number since the user has not selected the rows to load if (static_cast<unsigned int>(i) < sioFile.mOrigBandNumbers.size()) { bandDim.setOriginalNumber(sioFile.mOrigBandNumbers[i]); } else { bandDim.setOriginalNumber(i); } bandDim.setOnDiskNumber(i); bands.push_back(bandDim); } pDescriptor->setBands(bands); pFileDescriptor->setBands(bands); // Bits per pixel pFileDescriptor->setBitsPerElement(sioFile.mBitsPerElement); // Data type pDescriptor->setDataType(sioFile.mDataType); pDescriptor->setValidDataTypes(vector<EncodingType>(1, sioFile.mDataType)); // Interleave format pDescriptor->setInterleaveFormat(BIP); pFileDescriptor->setInterleaveFormat(BIP); // Bad values if (sioFile.mBadValues.empty() == true) { if ((sioFile.mDataType != FLT4BYTES) && (sioFile.mDataType != FLT8COMPLEX) && (sioFile.mDataType != FLT8BYTES)) { vector<int> badValues; badValues.push_back(0); pDescriptor->setBadValues(badValues); } } // Header bytes pFileDescriptor->setHeaderBytes(28); // Trailer bytes struct stat statBuffer; if (stat(filename.c_str(), &statBuffer) == 0) { double dataBytes = 28 + (sioFile.mRows * sioFile.mColumns * (sioFile.mBands - sioFile.mBadBands) * (sioFile.mBitsPerElement / 8)); pFileDescriptor->setTrailerBytes(static_cast<unsigned int>(statBuffer.st_size - dataBytes)); } // Units FactoryResource<Units> pUnits; pUnits->setUnitType(sioFile.mUnitType); pUnits->setUnitName(sioFile.mUnitName); pUnits->setRangeMin(sioFile.mRangeMin); pUnits->setRangeMax(sioFile.mRangeMax); pUnits->setScaleFromStandard(sioFile.mScale); pDescriptor->setUnits(pUnits.get()); pFileDescriptor->setUnits(pUnits.get()); // GCPs GcpPoint gcpLowerLeft; gcpLowerLeft.mPixel.mX = 0.0; gcpLowerLeft.mPixel.mY = 0.0; GcpPoint gcpLowerRight; gcpLowerRight.mPixel.mX = sioFile.mColumns - 1.0; gcpLowerRight.mPixel.mY = 0.0; GcpPoint gcpUpperLeft; gcpUpperLeft.mPixel.mX = 0.0; gcpUpperLeft.mPixel.mY = sioFile.mRows - 1.0; GcpPoint gcpUpperRight; gcpUpperRight.mPixel.mX = sioFile.mColumns - 1.0; gcpUpperRight.mPixel.mY = sioFile.mRows - 1.0; GcpPoint gcpCenter; gcpCenter.mPixel.mX = sioFile.mColumns / 2.0 - 0.5; gcpCenter.mPixel.mY = sioFile.mRows / 2.0 - 0.5; bool bValidGcps = false; for (int i = ORIGINAL_SENSOR; i < INVALID_LAST_ENUM_ITEM_FLAG; ++i) { if (sioFile.mParameters[i].eParameter_Initialized == true) { switch (i) { case UPPER_LEFT_CORNER_LAT: if ((sioFile.mVersion == 5) || (sioFile.mVersion == 6)) { gcpUpperLeft.mCoordinate.mY = sioFile.mParameters[i].uParameter_Value.dData; } else if ((sioFile.mVersion == 7) || (sioFile.mVersion == 8)) { gcpUpperLeft.mCoordinate.mX = sioFile.mParameters[i].uParameter_Value.dData; } bValidGcps = true; break; case UPPER_LEFT_CORNER_LONG: if ((sioFile.mVersion == 5) || (sioFile.mVersion == 6)) { gcpUpperLeft.mCoordinate.mX = sioFile.mParameters[i].uParameter_Value.dData; } else if ((sioFile.mVersion == 7) || (sioFile.mVersion == 8)) { gcpUpperLeft.mCoordinate.mY = sioFile.mParameters[i].uParameter_Value.dData; } bValidGcps = true; break; case LOWER_LEFT_CORNER_LAT: if ((sioFile.mVersion == 5) || (sioFile.mVersion == 6)) { gcpLowerLeft.mCoordinate.mY = sioFile.mParameters[i].uParameter_Value.dData; } else if ((sioFile.mVersion == 7) || (sioFile.mVersion == 8)) { gcpLowerLeft.mCoordinate.mX = sioFile.mParameters[i].uParameter_Value.dData; } bValidGcps = true; break; case LOWER_LEFT_CORNER_LONG: if ((sioFile.mVersion == 5) || (sioFile.mVersion == 6)) { gcpLowerLeft.mCoordinate.mX = sioFile.mParameters[i].uParameter_Value.dData; } else if ((sioFile.mVersion == 7) || (sioFile.mVersion == 8)) { gcpLowerLeft.mCoordinate.mY = sioFile.mParameters[i].uParameter_Value.dData; } bValidGcps = true; break; case UPPER_RIGHT_CORNER_LAT: if ((sioFile.mVersion == 5) || (sioFile.mVersion == 6)) { gcpUpperRight.mCoordinate.mY = sioFile.mParameters[i].uParameter_Value.dData; } else if ((sioFile.mVersion == 7) || (sioFile.mVersion == 8)) { gcpUpperRight.mCoordinate.mX = sioFile.mParameters[i].uParameter_Value.dData; } bValidGcps = true; break; case UPPER_RIGHT_CORNER_LONG: if ((sioFile.mVersion == 5) || (sioFile.mVersion == 6)) { gcpUpperRight.mCoordinate.mX = sioFile.mParameters[i].uParameter_Value.dData; } else if ((sioFile.mVersion == 7) || (sioFile.mVersion == 8)) { gcpUpperRight.mCoordinate.mY = sioFile.mParameters[i].uParameter_Value.dData; } bValidGcps = true; break; case LOWER_RIGHT_CORNER_LAT: if ((sioFile.mVersion == 5) || (sioFile.mVersion == 6)) { gcpLowerRight.mCoordinate.mY = sioFile.mParameters[i].uParameter_Value.dData; } else if ((sioFile.mVersion == 7) || (sioFile.mVersion == 8)) { gcpLowerRight.mCoordinate.mX = sioFile.mParameters[i].uParameter_Value.dData; } bValidGcps = true; break; case LOWER_RIGHT_CORNER_LONG: if ((sioFile.mVersion == 5) || (sioFile.mVersion == 6)) { gcpLowerRight.mCoordinate.mX = sioFile.mParameters[i].uParameter_Value.dData; } else if ((sioFile.mVersion == 7) || (sioFile.mVersion == 8)) { gcpLowerRight.mCoordinate.mY = sioFile.mParameters[i].uParameter_Value.dData; } bValidGcps = true; break; case CENTER_LAT: if ((sioFile.mVersion == 5) || (sioFile.mVersion == 6)) { gcpCenter.mCoordinate.mY = sioFile.mParameters[i].uParameter_Value.dData; } else if ((sioFile.mVersion == 7) || (sioFile.mVersion == 8)) { gcpCenter.mCoordinate.mX = sioFile.mParameters[i].uParameter_Value.dData; } bValidGcps = true; break; case CENTER_LONG: if ((sioFile.mVersion == 5) || (sioFile.mVersion == 6)) { gcpCenter.mCoordinate.mX = sioFile.mParameters[i].uParameter_Value.dData; } else if ((sioFile.mVersion == 7) || (sioFile.mVersion == 8)) { gcpCenter.mCoordinate.mY = sioFile.mParameters[i].uParameter_Value.dData; } bValidGcps = true; break; default: break; } } } if (bValidGcps == true) { list<GcpPoint> gcps; gcps.push_back(gcpLowerLeft); gcps.push_back(gcpLowerRight); gcps.push_back(gcpUpperLeft); gcps.push_back(gcpUpperRight); gcps.push_back(gcpCenter); pFileDescriptor->setGcps(gcps); } // Classification pDescriptor->setClassification(sioFile.mpClassification.get()); // Metadata pDescriptor->setMetadata(sioFile.mpMetadata.get()); DynamicObject* pMetadata = pDescriptor->getMetadata(); if (pMetadata != NULL) { vector<double> startWavelengths(sioFile.mStartWavelengths.size()); copy(sioFile.mStartWavelengths.begin(), sioFile.mStartWavelengths.end(), startWavelengths.begin()); vector<double> endWavelengths(sioFile.mEndWavelengths.size()); copy(sioFile.mEndWavelengths.begin(), sioFile.mEndWavelengths.end(), endWavelengths.begin()); vector<double> centerWavelengths(sioFile.mCenterWavelengths.size()); copy(sioFile.mCenterWavelengths.begin(), sioFile.mCenterWavelengths.end(), centerWavelengths.begin()); string pStartPath[] = { SPECIAL_METADATA_NAME, BAND_METADATA_NAME, START_WAVELENGTHS_METADATA_NAME, END_METADATA_NAME }; pMetadata->setAttributeByPath(pStartPath, startWavelengths); string pEndPath[] = { SPECIAL_METADATA_NAME, BAND_METADATA_NAME, END_WAVELENGTHS_METADATA_NAME, END_METADATA_NAME }; pMetadata->setAttributeByPath(pEndPath, endWavelengths); string pCenterPath[] = { SPECIAL_METADATA_NAME, BAND_METADATA_NAME, CENTER_WAVELENGTHS_METADATA_NAME, END_METADATA_NAME }; pMetadata->setAttributeByPath(pCenterPath, centerWavelengths); } // File descriptor pDescriptor->setFileDescriptor(pFileDescriptor.get()); } } descriptors.push_back(pImportDescriptor); } } return descriptors; }
std::vector<ImportDescriptor*> LandsatGeotiffImporter::createImportDescriptors(const std::string& filename, const DynamicObject* pImageMetadata, Landsat::LandsatImageType type) { std::string suffix; if (type == Landsat::LANDSAT_VNIR) { suffix = "vnir"; } else if (type == Landsat::LANDSAT_PAN) { suffix = "pan"; } else if (type == Landsat::LANDSAT_TIR) { suffix = "tir"; } std::vector<ImportDescriptor*> descriptors; std::string spacecraft = dv_cast<std::string>( pImageMetadata->getAttributeByPath("LANDSAT_MTL/L1_METADATA_FILE/PRODUCT_METADATA/SPACECRAFT_ID"), ""); std::vector<std::string> bandNames = Landsat::getSensorBandNames(spacecraft, type); if (bandNames.empty()) { //this spacecraft and iamge type //isn't meant to have any bands, so terminate early //e.g. spacecraft == "Landsat5" && type == Landsat::LANDSAT_PAN return descriptors; } std::vector<unsigned int> validBands; std::vector<std::string> bandFiles = Landsat::getGeotiffBandFilenames( pImageMetadata, filename, type, validBands); if (bandFiles.empty()) { mWarnings.push_back("Unable to locate band files for " + suffix + " product."); return descriptors; } ImportDescriptorResource pImportDescriptor(filename + "-" + suffix, TypeConverter::toString<RasterElement>(), NULL, false); if (pImportDescriptor.get() == NULL) { return descriptors; } RasterDataDescriptor* pDescriptor = dynamic_cast<RasterDataDescriptor*>(pImportDescriptor->getDataDescriptor()); if (pDescriptor == NULL) { return descriptors; } pDescriptor->setProcessingLocation(ON_DISK); DynamicObject* pMetadata = pDescriptor->getMetadata(); pMetadata->merge(pImageMetadata); FactoryResource<RasterFileDescriptor> pFileDescriptorRes; pDescriptor->setFileDescriptor(pFileDescriptorRes.get()); RasterFileDescriptor* pFileDescriptor = dynamic_cast<RasterFileDescriptor*>(pDescriptor->getFileDescriptor()); pFileDescriptor->setFilename(filename); std::string tiffFile = bandFiles[0]; if (!Landsat::parseBasicsFromTiff(tiffFile, pDescriptor)) { mWarnings.push_back("Unable to parse basic information about image from tiff file for " + suffix + " product."); return descriptors; } if (pDescriptor->getBandCount() != 1 || pDescriptor->getDataType() != INT1UBYTE) { mWarnings.push_back("Improperly formatted tiff file for " + suffix + " product."); return descriptors; } pDescriptor->setInterleaveFormat(BSQ); //one tiff file per band. pFileDescriptor->setInterleaveFormat(BSQ); std::vector<DimensionDescriptor> bands = RasterUtilities::generateDimensionVector( bandFiles.size(), true, false, true); pDescriptor->setBands(bands); pFileDescriptor->setBands(bands); pDescriptor->setBadValues(std::vector<int>(1, 0)); pFileDescriptor->setDatasetLocation(suffix); //special metadata here Landsat::fixMtlMetadata(pMetadata, type, validBands); std::vector<std::string> defaultImport = OptionsLandsatImport::getSettingDefaultImport(); bool fallbackToDn = false; descriptors.push_back(pImportDescriptor.release()); if (type == Landsat::LANDSAT_VNIR) { //attempt to display true-color DimensionDescriptor redBand = RasterUtilities::findBandWavelengthMatch(0.630, 0.690, pDescriptor); DimensionDescriptor greenBand = RasterUtilities::findBandWavelengthMatch(0.510, 0.590, pDescriptor); DimensionDescriptor blueBand = RasterUtilities::findBandWavelengthMatch(0.410, 0.490, pDescriptor); if (redBand.isValid() && greenBand.isValid() && blueBand.isValid()) { pDescriptor->setDisplayMode(RGB_MODE); pDescriptor->setDisplayBand(RED, redBand); pDescriptor->setDisplayBand(GREEN, greenBand); pDescriptor->setDisplayBand(BLUE, blueBand); } } std::vector<std::pair<double, double> > radianceFactors = Landsat::determineRadianceConversionFactors( pMetadata, type, validBands); bool shouldDefaultImportRadiance = std::find(defaultImport.begin(), defaultImport.end(), suffix + "-Radiance") != defaultImport.end(); if (radianceFactors.size() == bandFiles.size()) { //we have enough to create radiance import descriptor RasterDataDescriptor* pRadianceDescriptor = dynamic_cast<RasterDataDescriptor*>( pDescriptor->copy(filename + "-" + suffix + "-radiance", NULL)); if (pRadianceDescriptor != NULL) { pRadianceDescriptor->setDataType(FLT4BYTES); pRadianceDescriptor->setValidDataTypes(std::vector<EncodingType>(1, pRadianceDescriptor->getDataType())); pRadianceDescriptor->setBadValues(std::vector<int>(1, -100)); FactoryResource<Units> pUnits; pUnits->setUnitType(RADIANCE); pUnits->setUnitName("w/(m^2*sr*um)"); pUnits->setScaleFromStandard(1.0); pRadianceDescriptor->setUnits(pUnits.get()); FileDescriptor* pRadianceFileDescriptor = pRadianceDescriptor->getFileDescriptor(); if (pRadianceFileDescriptor != NULL) { pRadianceFileDescriptor->setDatasetLocation(suffix + "-radiance"); ImportDescriptorResource pRadianceImportDescriptor(pRadianceDescriptor, shouldDefaultImportRadiance); descriptors.push_back(pRadianceImportDescriptor.release()); } } } else if (shouldDefaultImportRadiance) { fallbackToDn = true; } std::vector<double> reflectanceFactors = Landsat::determineReflectanceConversionFactors( pMetadata, type, validBands); bool shouldDefaultImportReflectance = std::find(defaultImport.begin(), defaultImport.end(), suffix + "-Reflectance") != defaultImport.end(); if (radianceFactors.size() == bandFiles.size() && reflectanceFactors.size() == bandFiles.size()) { //we have enough to create reflectance import descriptor RasterDataDescriptor* pReflectanceDescriptor = dynamic_cast<RasterDataDescriptor*>( pDescriptor->copy(filename + "-" + suffix + "-reflectance", NULL)); if (pReflectanceDescriptor != NULL) { pReflectanceDescriptor->setDataType(INT2SBYTES); pReflectanceDescriptor->setValidDataTypes( std::vector<EncodingType>(1, pReflectanceDescriptor->getDataType())); pReflectanceDescriptor->setBadValues(std::vector<int>(1, std::numeric_limits<short>::max())); FactoryResource<Units> pUnits; pUnits->setUnitType(REFLECTANCE); pUnits->setUnitName("Reflectance"); pUnits->setScaleFromStandard(1/10000.0); pReflectanceDescriptor->setUnits(pUnits.get()); FileDescriptor* pReflectanceFileDescriptor = pReflectanceDescriptor->getFileDescriptor(); if (pReflectanceFileDescriptor != NULL) { pReflectanceFileDescriptor->setDatasetLocation(suffix + "-reflectance"); ImportDescriptorResource pReflectanceImportDescriptor(pReflectanceDescriptor, shouldDefaultImportReflectance); descriptors.push_back(pReflectanceImportDescriptor.release()); } } } else if (shouldDefaultImportReflectance) { fallbackToDn = true; } double K1 = 0.0; double K2 = 0.0; bool haveTemperatureFactors = Landsat::getTemperatureConstants(pMetadata, type, K1, K2); bool shouldDefaultImportTemperature = std::find(defaultImport.begin(), defaultImport.end(), suffix + "-Temperature") != defaultImport.end(); if (radianceFactors.size() == bandFiles.size() && haveTemperatureFactors) { //we have enough to create temperature import descriptor RasterDataDescriptor* pTemperatureDescriptor = dynamic_cast<RasterDataDescriptor*>( pDescriptor->copy(filename + "-" + suffix + "-temperature", NULL)); if (pTemperatureDescriptor != NULL) { pTemperatureDescriptor->setDataType(FLT4BYTES); pTemperatureDescriptor->setValidDataTypes( std::vector<EncodingType>(1, pTemperatureDescriptor->getDataType())); pTemperatureDescriptor->setBadValues(std::vector<int>(1, -1)); FactoryResource<Units> pUnits; pUnits->setUnitType(EMISSIVITY); pUnits->setUnitName("K"); pUnits->setScaleFromStandard(1.0); pTemperatureDescriptor->setUnits(pUnits.get()); FileDescriptor* pTemperatureFileDescriptor = pTemperatureDescriptor->getFileDescriptor(); if (pTemperatureFileDescriptor != NULL) { pTemperatureFileDescriptor->setDatasetLocation(suffix + "-temperature"); ImportDescriptorResource pTemperatureImportDescriptor(pTemperatureDescriptor, shouldDefaultImportTemperature); descriptors.push_back(pTemperatureImportDescriptor.release()); } } } else if (shouldDefaultImportTemperature) { fallbackToDn = true; } if (fallbackToDn || std::find(defaultImport.begin(), defaultImport.end(), suffix + "-DN") != defaultImport.end()) { pImportDescriptor->setImported(true); } return descriptors; }
RasterPage* ConvertToBsqPager::getPage(DataRequest* pOriginalRequest, DimensionDescriptor startRow, DimensionDescriptor startColumn, DimensionDescriptor startBand) { VERIFYRV(pOriginalRequest != NULL, NULL); if (pOriginalRequest->getWritable()) { return NULL; } InterleaveFormatType requestedType = pOriginalRequest->getInterleaveFormat(); DimensionDescriptor stopRow = pOriginalRequest->getStopRow(); DimensionDescriptor stopColumn = pOriginalRequest->getStopColumn(); DimensionDescriptor stopBand = pOriginalRequest->getStopBand(); unsigned int concurrentRows = std::min(pOriginalRequest->getConcurrentRows(), stopRow.getActiveNumber() - startRow.getActiveNumber() + 1); unsigned int concurrentBands = pOriginalRequest->getConcurrentBands(); VERIFY(requestedType == BSQ); VERIFY(startBand == stopBand && concurrentBands == 1); VERIFY(mpRaster != NULL); const RasterDataDescriptor* pDd = dynamic_cast<const RasterDataDescriptor*>(mpRaster->getDataDescriptor()); VERIFY(pDd != NULL); InterleaveFormatType interleave = pDd->getInterleaveFormat(); VERIFY(interleave == BIL || interleave == BIP); unsigned int numRows = pDd->getRowCount(); unsigned int numCols = pDd->getColumnCount(); unsigned int numBands = pDd->getBandCount(); if (startRow.getActiveNumber() >= numRows || stopRow.getActiveNumber() >= numRows || startColumn.getActiveNumber() >= numCols || stopColumn.getActiveNumber() >= numCols || startBand.getActiveNumber() >= numBands || stopBand.getActiveNumber() >= numBands) { return NULL; } unsigned int cols = stopColumn.getActiveNumber() - startColumn.getActiveNumber() + 1; std::auto_ptr<ConvertToBsqPage> pPage(new ConvertToBsqPage(concurrentRows, cols, mBytesPerElement)); unsigned char* pDst = reinterpret_cast<unsigned char*>(pPage->getRawData()); if (pDst == NULL) { return NULL; } FactoryResource<DataRequest> pRequest; pRequest->setRows(startRow, stopRow); pRequest->setColumns(startColumn, stopColumn, cols); pRequest->setBands(startBand, startBand, 1); DataAccessor da = mpRaster->getDataAccessor(pRequest.release()); if (interleave == BIP) { for (unsigned int row = 0; row < concurrentRows; ++row) { for (unsigned int col = 0; col < cols; ++col) { if (da.isValid() == false) { return NULL; } memcpy(pDst, da->getColumn(), mBytesPerElement); pDst += mBytesPerElement; da->nextColumn(); } da->nextRow(); } } else if (interleave == BIL) { for (unsigned int row = 0; row < concurrentRows; ++row) { if (da.isValid() == false) { return NULL; } memcpy(pDst, da->getRow(), mBytesPerElement * cols); pDst += mBytesPerElement * cols; da->nextRow(); } } return pPage.release(); }
void PropertiesRasterLayer::updateDisplayedBandCombo(int index) { // Get the selected raster element RasterElement* pElement = NULL; if ((index > -1) && (static_cast<int>(mRasterElements.size()) > index)) { pElement = mRasterElements[index]; } // Get the band names from the element QStringList strBandNames; if (pElement != NULL) { RasterDataDescriptor* pDescriptor = dynamic_cast<RasterDataDescriptor*>(pElement->getDataDescriptor()); if (pDescriptor != NULL) { vector<string> bandNames = RasterUtilities::getBandNames(pDescriptor); for (vector<string>::iterator iter = bandNames.begin(); iter != bandNames.end(); ++iter) { strBandNames.append(QString::fromStdString(*iter)); } } } // Update the display band combo QComboBox* pCombo = dynamic_cast<QComboBox*>(sender()); if (pCombo == mpGrayElementCombo) { mpGrayBandCombo->clear(); mpGrayBandCombo->addItems(strBandNames); if (strBandNames.isEmpty() == false) { mpGrayBandCombo->setCurrentIndex(0); if ((mpRasterLayer != NULL) && (mpRasterLayer->getDataElement() == pElement)) { DimensionDescriptor displayedBand = mpRasterLayer->getDisplayedBand(GRAY); if (displayedBand.isActiveNumberValid() == true) { mpGrayBandCombo->setCurrentIndex(displayedBand.getActiveNumber()); } } } } else if (pCombo == mpRedElementCombo) { mpRedBandCombo->clear(); mpRedBandCombo->addItems(strBandNames); if (strBandNames.isEmpty() == false) { mpRedBandCombo->setCurrentIndex(0); if ((mpRasterLayer != NULL) && (mpRasterLayer->getDataElement() == pElement)) { DimensionDescriptor displayedBand = mpRasterLayer->getDisplayedBand(RED); if (displayedBand.isActiveNumberValid() == true) { mpRedBandCombo->setCurrentIndex(displayedBand.getActiveNumber()); } } } } else if (pCombo == mpGreenElementCombo) { mpGreenBandCombo->clear(); mpGreenBandCombo->addItems(strBandNames); if (strBandNames.isEmpty() == false) { mpGreenBandCombo->setCurrentIndex(0); if ((mpRasterLayer != NULL) && (mpRasterLayer->getDataElement() == pElement)) { DimensionDescriptor displayedBand = mpRasterLayer->getDisplayedBand(GREEN); if (displayedBand.isActiveNumberValid() == true) { mpGreenBandCombo->setCurrentIndex(displayedBand.getActiveNumber()); } } } } else if (pCombo == mpBlueElementCombo) { mpBlueBandCombo->clear(); mpBlueBandCombo->addItems(strBandNames); if (strBandNames.isEmpty() == false) { mpBlueBandCombo->setCurrentIndex(0); if ((mpRasterLayer != NULL) && (mpRasterLayer->getDataElement() == pElement)) { DimensionDescriptor displayedBand = mpRasterLayer->getDisplayedBand(BLUE); if (displayedBand.isActiveNumberValid() == true) { mpBlueBandCombo->setCurrentIndex(displayedBand.getActiveNumber()); } } } } }
bool RasterElementImporterShell::validate(const DataDescriptor* pDescriptor, const vector<const DataDescriptor*>& importedDescriptors, string& errorMessage) const { bool isValid = ImporterShell::validate(pDescriptor, importedDescriptors, errorMessage); if (isValid == false) { ValidationTest errorTest = getValidationError(); if (errorTest == NO_PRE_POST_BAND_BYTES) { errorMessage += " Preband and postband bytes are not supported for interleave formats other than BSQ."; } else if (errorTest == NO_BAND_FILES) { errorMessage += " Bands in multiple files are not supported for interleave formats other than BSQ."; } else if ((errorTest == NO_INTERLEAVE_CONVERSIONS) || (errorTest == NO_ROW_SKIP_FACTOR) || (errorTest == NO_COLUMN_SKIP_FACTOR) || (errorTest == NO_BAND_SUBSETS)) { errorMessage = errorMessage.substr(0, errorMessage.length() - 1); errorMessage += " with on-disk read-only processing."; } } else { // Check for display bands that are not loaded const RasterDataDescriptor* pRasterDescriptor = dynamic_cast<const RasterDataDescriptor*>(pDescriptor); VERIFY(pRasterDescriptor != NULL); DimensionDescriptor grayBand = pRasterDescriptor->getDisplayBand(GRAY); if (grayBand.isOriginalNumberValid() == true) { DimensionDescriptor band = pRasterDescriptor->getOriginalBand(grayBand.getOriginalNumber()); if (band.isValid() == false) { if (errorMessage.empty() == false) { errorMessage += "\n"; } errorMessage += "The gray display band is not available. The first loaded band will be displayed instead."; } } DimensionDescriptor redBand = pRasterDescriptor->getDisplayBand(RED); if (redBand.isOriginalNumberValid() == true) { DimensionDescriptor band = pRasterDescriptor->getOriginalBand(redBand.getOriginalNumber()); if (band.isValid() == false) { if (errorMessage.empty() == false) { errorMessage += "\n"; } errorMessage += "The red display band is not available. The first loaded band will be displayed instead."; } } DimensionDescriptor greenBand = pRasterDescriptor->getDisplayBand(GREEN); if (greenBand.isOriginalNumberValid() == true) { DimensionDescriptor band = pRasterDescriptor->getOriginalBand(greenBand.getOriginalNumber()); if (band.isValid() == false) { if (errorMessage.empty() == false) { errorMessage += "\n"; } errorMessage += "The green display band is not available. The first loaded band will be " "displayed instead."; } } DimensionDescriptor blueBand = pRasterDescriptor->getDisplayBand(BLUE); if (blueBand.isOriginalNumberValid() == true) { DimensionDescriptor band = pRasterDescriptor->getOriginalBand(blueBand.getOriginalNumber()); if (band.isValid() == false) { if (errorMessage.empty() == false) { errorMessage += "\n"; } errorMessage += "The blue display band is not available. The first loaded band will be displayed instead."; } } } return isValid; }
void ChippingWindow::createView() { if (mpChippingWidget == NULL) { return; } RasterElement* pRaster = getRasterElement(); if (pRaster == NULL) { return; } // Create the new raster element from the primary element of the source. // Note that this does not chip displayed elements if they differ from the primary element. // This causes a special case below where the stretch values are being applied to the chipped layer. RasterElement* pRasterChip = pRaster->createChip(pRaster->getParent(), "_chip", mpChippingWidget->getChipRows(), mpChippingWidget->getChipColumns(), mpChippingWidget->getChipBands()); if (pRasterChip == NULL) { QMessageBox::critical(this, windowTitle(), "Unable to create a new cube!"); return; } const RasterDataDescriptor* pDescriptor = dynamic_cast<const RasterDataDescriptor*>(pRasterChip->getDataDescriptor()); VERIFYNRV(pDescriptor != NULL); // Create a view for the new chip SpatialDataWindow* pWindow = dynamic_cast<SpatialDataWindow*>( Service<DesktopServices>()->createWindow(pRasterChip->getName(), SPATIAL_DATA_WINDOW)); if (pWindow == NULL) { return; } SpatialDataView* pView = pWindow->getSpatialDataView(); if (pView == NULL) { Service<DesktopServices>()->deleteWindow(pWindow); return; } UndoLock lock(pView); if (pView->setPrimaryRasterElement(pRasterChip) == false) { Service<DesktopServices>()->deleteWindow(pWindow); return; } // RasterLayerImp is needed for the call to setCurrentStretchAsOriginalStretch(). RasterLayerImp* pLayer = dynamic_cast<RasterLayerImp*>(pView->createLayer(RASTER, pRasterChip)); if (pLayer == NULL) { Service<DesktopServices>()->deleteWindow(pWindow); return; } string origName = pRaster->getName(); SpatialDataWindow* pOrigWindow = dynamic_cast<SpatialDataWindow*>( Service<DesktopServices>()->getWindow(origName, SPATIAL_DATA_WINDOW)); if (pOrigWindow != NULL) { SpatialDataView* pOrigView = pOrigWindow->getSpatialDataView(); if (pOrigView != NULL) { LayerList* pLayerList = pOrigView->getLayerList(); if (pLayerList != NULL) { RasterLayer* pOrigLayer = static_cast<RasterLayer*>(pLayerList->getLayer(RASTER, pRaster)); if (pOrigLayer != NULL) { // Set the stretch type first so that stretch values are interpreted correctly. pLayer->setStretchType(GRAYSCALE_MODE, pOrigLayer->getStretchType(GRAYSCALE_MODE)); pLayer->setStretchType(RGB_MODE, pOrigLayer->getStretchType(RGB_MODE)); pLayer->setDisplayMode(pOrigLayer->getDisplayMode()); // Set the properties of the cube layer in the new view. // For each channel, display the first band if the previously displayed band was chipped. vector<RasterChannelType> channels = StringUtilities::getAllEnumValues<RasterChannelType>(); for (vector<RasterChannelType>::const_iterator iter = channels.begin(); iter != channels.end(); ++iter) { bool bandCopied = true; DimensionDescriptor newBand; DimensionDescriptor oldBand = pOrigLayer->getDisplayedBand(*iter); if (oldBand.isOriginalNumberValid() == true) { newBand = pDescriptor->getOriginalBand(oldBand.getOriginalNumber()); } if (newBand.isValid() == false) { bandCopied = false; newBand = pDescriptor->getBands().front(); } // No need to explicitly set the RasterElement here since the new view only has one RasterElement. pLayer->setDisplayedBand(*iter, newBand); // Use the default stretch properties if the displayed band was removed from the view or // if the non-primary raster element was displayed. Otherwise, copy the stretch properties. if (bandCopied && pRaster == pOrigLayer->getDisplayedRasterElement(*iter)) { // Set the stretch units first so that stretch values are interpreted correctly. pLayer->setStretchUnits(*iter, pOrigLayer->getStretchUnits(*iter)); double lower; double upper; pOrigLayer->getStretchValues(*iter, lower, upper); pLayer->setStretchValues(*iter, lower, upper); } } pLayer->setCurrentStretchAsOriginalStretch(); pView->refresh(); } } } } // Create a GCP layer if (pRaster->isGeoreferenced() == true) { const vector<DimensionDescriptor>& rows = mpChippingWidget->getChipRows(); const vector<DimensionDescriptor>& columns = mpChippingWidget->getChipColumns(); if ((rows.empty() == false) && (columns.empty() == false)) { // Get the geocoordinates at the chip corners VERIFYNRV(rows.front().isActiveNumberValid() == true); VERIFYNRV(rows.back().isActiveNumberValid() == true); VERIFYNRV(columns.front().isActiveNumberValid() == true); VERIFYNRV(columns.back().isActiveNumberValid() == true); unsigned int startRow = rows.front().getActiveNumber(); unsigned int endRow = rows.back().getActiveNumber(); unsigned int startCol = columns.front().getActiveNumber(); unsigned int endCol = columns.back().getActiveNumber(); GcpPoint ulPoint; ulPoint.mPixel = LocationType(startCol, startRow); ulPoint.mCoordinate = pRaster->convertPixelToGeocoord(ulPoint.mPixel); GcpPoint urPoint; urPoint.mPixel = LocationType(endCol, startRow); urPoint.mCoordinate = pRaster->convertPixelToGeocoord(urPoint.mPixel); GcpPoint llPoint; llPoint.mPixel = LocationType(startCol, endRow); llPoint.mCoordinate = pRaster->convertPixelToGeocoord(llPoint.mPixel); GcpPoint lrPoint; lrPoint.mPixel = LocationType(endCol, endRow); lrPoint.mCoordinate = pRaster->convertPixelToGeocoord(lrPoint.mPixel); GcpPoint centerPoint; centerPoint.mPixel = LocationType((startCol + endCol) / 2, (startRow + endRow) / 2); centerPoint.mCoordinate = pRaster->convertPixelToGeocoord(centerPoint.mPixel); // Reset the coordinates to be in active numbers relative to the chip const vector<DimensionDescriptor>& chipRows = pDescriptor->getRows(); const vector<DimensionDescriptor>& chipColumns = pDescriptor->getColumns(); VERIFYNRV(chipRows.front().isActiveNumberValid() == true); VERIFYNRV(chipRows.back().isActiveNumberValid() == true); VERIFYNRV(chipColumns.front().isActiveNumberValid() == true); VERIFYNRV(chipColumns.back().isActiveNumberValid() == true); unsigned int chipStartRow = chipRows.front().getActiveNumber(); unsigned int chipEndRow = chipRows.back().getActiveNumber(); unsigned int chipStartCol = chipColumns.front().getActiveNumber(); unsigned int chipEndCol = chipColumns.back().getActiveNumber(); ulPoint.mPixel = LocationType(chipStartCol, chipStartRow); urPoint.mPixel = LocationType(chipEndCol, chipStartRow); llPoint.mPixel = LocationType(chipStartCol, chipEndRow); lrPoint.mPixel = LocationType(chipEndCol, chipEndRow); centerPoint.mPixel = LocationType((chipStartCol + chipEndCol) / 2, (chipStartRow + chipEndRow) / 2); // Create the GCP list Service<ModelServices> pModel; GcpList* pGcpList = static_cast<GcpList*>(pModel->createElement("Corner Coordinates", TypeConverter::toString<GcpList>(), pRasterChip)); if (pGcpList != NULL) { list<GcpPoint> gcps; gcps.push_back(ulPoint); gcps.push_back(urPoint); gcps.push_back(llPoint); gcps.push_back(lrPoint); gcps.push_back(centerPoint); pGcpList->addPoints(gcps); // Create the layer if (pView->createLayer(GCP_LAYER, pGcpList) == NULL) { QMessageBox::warning(this, windowTitle(), "Could not create a GCP layer."); } } else { QMessageBox::warning(this, windowTitle(), "Could not create a GCP list."); } } } }
QWidget* RasterElementImporterShell::getPreview(const DataDescriptor* pDescriptor, Progress* pProgress) { if (pDescriptor == NULL) { return NULL; } // Create a copy of the descriptor to change the loading parameters string previewName = string("Preview: ") + pDescriptor->getName(); RasterDataDescriptor* pLoadDescriptor = dynamic_cast<RasterDataDescriptor*>(pDescriptor->copy(previewName, NULL)); if (pLoadDescriptor == NULL) { return NULL; } // Set the active row and column numbers vector<DimensionDescriptor> newRows = pLoadDescriptor->getRows(); for (unsigned int i = 0; i < newRows.size(); ++i) { newRows[i].setActiveNumber(i); } pLoadDescriptor->setRows(newRows); vector<DimensionDescriptor> newColumns = pLoadDescriptor->getColumns(); for (unsigned int i = 0; i < newColumns.size(); ++i) { newColumns[i].setActiveNumber(i); } pLoadDescriptor->setColumns(newColumns); // Set the bands to load to just the first band and display it in grayscale mode const vector<DimensionDescriptor>& bands = pLoadDescriptor->getBands(); if (bands.empty() == false) { DimensionDescriptor displayBand = bands.front(); displayBand.setActiveNumber(0); vector<DimensionDescriptor> newBands; newBands.push_back(displayBand); pLoadDescriptor->setBands(newBands); pLoadDescriptor->setDisplayMode(GRAYSCALE_MODE); pLoadDescriptor->setDisplayBand(GRAY, displayBand); } // Set the processing location to load on-disk read-only pLoadDescriptor->setProcessingLocation(ON_DISK_READ_ONLY); // Do not georeference GeoreferenceDescriptor* pLoadGeorefDescriptor = pLoadDescriptor->getGeoreferenceDescriptor(); if (pLoadGeorefDescriptor != NULL) { pLoadGeorefDescriptor->setGeoreferenceOnImport(false); } // Validate the preview string errorMessage; bool bValidPreview = validate(pLoadDescriptor, vector<const DataDescriptor*>(), errorMessage); if (bValidPreview == false) { // Try an in-memory preview pLoadDescriptor->setProcessingLocation(IN_MEMORY); bValidPreview = validate(pLoadDescriptor, vector<const DataDescriptor*>(), errorMessage); } QWidget* pPreviewWidget = NULL; if (bValidPreview == true) { // Create the model element RasterElement* pRasterElement = static_cast<RasterElement*>(mpModel->createElement(pLoadDescriptor)); if (pRasterElement != NULL) { // Add the progress and raster element to an input arg list PlugInArgList* pInArgList = NULL; bool bSuccess = getInputSpecification(pInArgList); if ((bSuccess == true) && (pInArgList != NULL)) { bSuccess = pInArgList->setPlugInArgValue(Executable::ProgressArg(), pProgress); if (bSuccess) { bSuccess = pInArgList->setPlugInArgValue(Importer::ImportElementArg(), pRasterElement); } } // Load the data in batch mode bool bBatch = isBatch(); setBatch(); bSuccess = execute(pInArgList, NULL); // Restore to interactive mode if necessary if (bBatch == false) { setInteractive(); } // Create the spatial data view if (bSuccess == true) { string name = pRasterElement->getName(); SpatialDataView* pView = static_cast<SpatialDataView*>(mpDesktop->createView(name, SPATIAL_DATA_VIEW)); if (pView != NULL) { // Set the spatial data in the view pView->setPrimaryRasterElement(pRasterElement); // Add the cube layer RasterLayer* pLayer = static_cast<RasterLayer*>(pView->createLayer(RASTER, pRasterElement)); if (pLayer != NULL) { // Get the widget from the view pPreviewWidget = pView->getWidget(); } else { string message = "Could not create the cube layer!"; if (pProgress != NULL) { pProgress->updateProgress(message, 0, ERRORS); } mpModel->destroyElement(pRasterElement); } } else { string message = "Could not create the view!"; if (pProgress != NULL) { pProgress->updateProgress(message, 0, ERRORS); } mpModel->destroyElement(pRasterElement); } } else { mpModel->destroyElement(pRasterElement); } } } // Delete the data descriptor copy mpModel->destroyDataDescriptor(pLoadDescriptor); return pPreviewWidget; }
DimensionDescriptor operator()(const DimensionDescriptor& dim) { DimensionDescriptor temp = dim; temp.setOnDiskNumber(mCurrent++); return temp; }
RasterLayer* RasterElementImporterShell::createRasterLayer(SpatialDataView* pView, Step* pStep) const { if ((pView == NULL) || (mpRasterElement == NULL)) { return NULL; } RasterLayer* pLayer = static_cast<RasterLayer*>(pView->createLayer(RASTER, mpRasterElement)); if (pLayer != NULL) { // Log the initial cube layer properties const RasterDataDescriptor* pDescriptor = dynamic_cast<RasterDataDescriptor*>(mpRasterElement->getDataDescriptor()); VERIFYRV(pDescriptor != NULL, NULL); if (pStep != NULL) { DimensionDescriptor grayBand = pDescriptor->getDisplayBand(GRAY); DimensionDescriptor redBand = pDescriptor->getDisplayBand(RED); DimensionDescriptor greenBand = pDescriptor->getDisplayBand(GREEN); DimensionDescriptor blueBand = pDescriptor->getDisplayBand(BLUE); DisplayMode displayMode = pDescriptor->getDisplayMode(); if (grayBand.isOriginalNumberValid()) { pStep->addProperty("Gray Band", grayBand.getOriginalNumber()); } if (redBand.isOriginalNumberValid()) { pStep->addProperty("Red Band", redBand.getOriginalNumber()); } else { pStep->addProperty("Red Band", "No Band Displayed"); } if (greenBand.isOriginalNumberValid()) { pStep->addProperty("Green Band", greenBand.getOriginalNumber()); } else { pStep->addProperty("Green Band", "No Band Displayed"); } if (blueBand.isOriginalNumberValid()) { pStep->addProperty("Blue Band", blueBand.getOriginalNumber()); } else { pStep->addProperty("Blue Band", "No Band Displayed"); } pStep->addProperty("Display Mode", StringUtilities::toDisplayString(displayMode)); } } else { string message = "Could not create the raster layer."; if (mpProgress != NULL) { mpProgress->updateProgress(message, 0, WARNING); } if (pStep != NULL) { pStep->addMessage(message, "app", "3F06A978-3F1A-4E03-BBA7-E295A8B7CF72"); } } return pLayer; }
bool GeoTIFFExporter::CreateGeoTIFF(TIFF *pOut) { if (mpFileDescriptor == NULL) { return false; } GTIF* pGtif = GTIFNew(pOut); if (pGtif == NULL) { return false; } // Get the exported lower left corner location const vector<DimensionDescriptor>& rows = mpFileDescriptor->getRows(); const vector<DimensionDescriptor>& columns = mpFileDescriptor->getColumns(); unsigned int startRow = 0; if (rows.empty() == false) { DimensionDescriptor rowDim = rows.front(); if (rowDim.isActiveNumberValid() == true) { startRow = rowDim.getActiveNumber(); } } unsigned int startColumn = 0; if (columns.empty() == false) { DimensionDescriptor columnDim = columns.front(); if (columnDim.isActiveNumberValid() == true) { startColumn = columnDim.getActiveNumber(); } } LocationType llPixel(startColumn, startRow); LocationType urPixel = llPixel + 1.0; LocationType llGeoCoord; LocationType lrGeoCoord; LocationType ulGeoCoord; LocationType urGeoCoord; bool bGeocoords = false; if (mpRaster->isGeoreferenced()) { // Get the lat/long values from the RasterElement LocationType pixel = llPixel; LocationType latLong = mpRaster->convertPixelToGeocoord(pixel); llGeoCoord.mY = latLong.mY; llGeoCoord.mX = latLong.mX; pixel.mX = urPixel.mX; pixel.mY = llPixel.mY; latLong = mpRaster->convertPixelToGeocoord(pixel); lrGeoCoord.mY = latLong.mY; lrGeoCoord.mX = latLong.mX; pixel.mX = llPixel.mX; pixel.mY = urPixel.mY; latLong = mpRaster->convertPixelToGeocoord(pixel); ulGeoCoord.mY = latLong.mY; ulGeoCoord.mX = latLong.mX; pixel = urPixel; latLong = mpRaster->convertPixelToGeocoord(pixel); urGeoCoord.mY = latLong.mY; urGeoCoord.mX = latLong.mX; bGeocoords = true; } bool isOrthoRectified = false; DynamicObject* pMetaData = mpRaster->getMetadata(); bool hasMetaDataTag = false; if (pMetaData != NULL) { try { isOrthoRectified = dv_cast<bool>(pMetaData->getAttribute("orthorectified")); hasMetaDataTag = true; } catch (bad_cast&) { // attribute is not present or is not a bool, so calculate isOrthoRectified } } if (!hasMetaDataTag) { // calculate the value of isOrthoRectified if (mpRaster->isGeoreferenced() && !rows.empty() && !columns.empty()) { int endRow(-1); int endColumn(-1); for (vector<DimensionDescriptor>::const_reverse_iterator rowIt = rows.rbegin(); rowIt != rows.rend(); ++rowIt) { if (rowIt->isActiveNumberValid()) { endRow = rowIt->getActiveNumber(); break; } } for (vector<DimensionDescriptor>::const_reverse_iterator colIt = columns.rbegin(); colIt != columns.rend(); ++colIt) { if (colIt->isActiveNumberValid()) { endColumn = colIt->getActiveNumber(); break; } } if (endRow != -1 && endColumn != -1 && static_cast<unsigned int>(endRow) > startRow && static_cast<unsigned int>(endColumn) > startColumn) { // the chip's (0,0) LocationType startPixel = llPixel; LocationType startGeo = llGeoCoord; // the chip's (0,max) LocationType rowMax(startPixel.mX, endRow); LocationType rowMaxGeo = mpRaster->convertPixelToGeocoord(rowMax); // the chip's (max,0) LocationType colMax(endColumn, startPixel.mY); LocationType colMaxGeo = mpRaster->convertPixelToGeocoord(colMax); // LocationType rowMaxCheckGeo(rowMaxGeo.mX, startGeo.mY); LocationType rowMaxCheck = mpRaster->convertGeocoordToPixel(rowMaxCheckGeo); LocationType colMaxCheckGeo(startGeo.mX, colMaxGeo.mY); LocationType colMaxCheck = mpRaster->convertGeocoordToPixel(colMaxCheckGeo); LocationType deltaRowMax = rowMaxCheck - rowMax; LocationType deltaColMax = colMaxCheck - colMax; isOrthoRectified = (deltaRowMax.length() < 0.5) && (deltaColMax.length() < 0.5); } } } if (bGeocoords == false) { GTIFFree(pGtif); return false; } LocationType geoCoordCenter((llGeoCoord.mX + lrGeoCoord.mX + ulGeoCoord.mX + urGeoCoord.mX) / 4.0, (llGeoCoord.mY + lrGeoCoord.mY + ulGeoCoord.mY + urGeoCoord.mY) / 4.0); // if the data is orthorectified, write out the appropriate tags if (isOrthoRectified) { double pTiepoints[6] = {0.0, 0.0, 0.0, llGeoCoord.mY, llGeoCoord.mX, 0.0}; TIFFSetField(pOut, TIFFTAG_GEOTIEPOINTS, 6, pTiepoints); /* The following calculation can result in a negative scale for the latitude and/or longitude. This is correct and is explicitly called out in the GeoTIFF spec (GeoTIFF Format Specification version 1.8.1, section 2.6.1) as the proper way to handle flipping of the image. A negative latitude scale corresponds to an image with its origin in the lower left or lower right corner, while a positive latitude scale corresponds to an image with its origin in the upper left or upper right corner. Similarly for longitude scale. */ double pPixelSize[3] = {urGeoCoord.mY - llGeoCoord.mY, llGeoCoord.mX - urGeoCoord.mX, 0.0}; TIFFSetField(pOut, TIFFTAG_GEOPIXELSCALE, 3, pPixelSize); } else { //compute transformation Matrix values double a = lrGeoCoord.mY - llGeoCoord.mY; double b = ulGeoCoord.mY - llGeoCoord.mY; double d = llGeoCoord.mY; double e = lrGeoCoord.mX - llGeoCoord.mX; double f = ulGeoCoord.mX - llGeoCoord.mX; double h = llGeoCoord.mX; double k = 1.0; double p = 1.0; double tMatrix[16] = {a, b, 0.0, d, e, f, 0.0, h, 0.0, 0.0, k, 0.0, 0.0, 0.0, 0.0, p }; TIFFSetField(pOut, GTIFF_TRANSMATRIX, 16, tMatrix); } GTIFKeySet(pGtif, GTModelTypeGeoKey, TYPE_SHORT, 1, ModelGeographic); GTIFKeySet(pGtif, GTRasterTypeGeoKey, TYPE_SHORT, 1, RasterPixelIsArea); GTIFKeySet(pGtif, GeogAngularUnitsGeoKey, TYPE_SHORT, 1, Angular_Degree); GTIFKeySet(pGtif, GeogLinearUnitsGeoKey, TYPE_SHORT, 1, Linear_Meter); GTIFKeySet(pGtif, GeographicTypeGeoKey, TYPE_SHORT, 1, GCS_WGS_84); GTIFKeySet(pGtif, ProjCenterLongGeoKey, TYPE_DOUBLE, 1, geoCoordCenter.mY); GTIFKeySet(pGtif, ProjCenterLatGeoKey, TYPE_DOUBLE, 1, geoCoordCenter.mX); ///* Here we violate the GTIF abstraction to retarget on another file. // We should just have a function for copying tags from one GTIF object // to another. pGtif->gt_tif = pOut; pGtif->gt_flags |= FLAG_FILE_MODIFIED; //* Install keys and tags GTIFWriteKeys(pGtif); GTIFFree(pGtif); return true; }
GcpList* RasterElementImporterShell::createGcpList() const { if (mpRasterElement == NULL) { return NULL; } const RasterDataDescriptor* pDescriptor = dynamic_cast<const RasterDataDescriptor*>(mpRasterElement->getDataDescriptor()); if (pDescriptor == NULL) { return NULL; } const RasterFileDescriptor* pFileDescriptor = dynamic_cast<const RasterFileDescriptor*>(pDescriptor->getFileDescriptor()); if (pFileDescriptor == NULL) { return NULL; } const list<GcpPoint>& gcps = pFileDescriptor->getGcps(); if (gcps.empty() == true) { return NULL; } // Create the GCP list GcpList* pGcpList = static_cast<GcpList*>(mpModel->createElement("Corner Coordinates", "GcpList", mpRasterElement)); if (pGcpList != NULL) { unsigned int onDiskStartRow = 0; unsigned int onDiskStartColumn = 0; unsigned int numActiveRows = pDescriptor->getRowCount(); unsigned int numActiveColumns = pDescriptor->getColumnCount(); unsigned int numOnDiskRows = pFileDescriptor->getRowCount(); unsigned int numOnDiskColumns = pFileDescriptor->getColumnCount(); if ((numActiveRows != numOnDiskRows) || (numActiveColumns != numOnDiskColumns)) { const vector<DimensionDescriptor>& activeRows = pDescriptor->getRows(); if (activeRows.empty() == false) { DimensionDescriptor rowDim = activeRows.front(); if (rowDim.isOnDiskNumberValid()) { onDiskStartRow = rowDim.getOnDiskNumber(); } } const vector<DimensionDescriptor>& activeColumns = pDescriptor->getColumns(); if (activeColumns.empty() == false) { DimensionDescriptor columnDim = activeColumns.front(); if (columnDim.isOnDiskNumberValid()) { onDiskStartColumn = columnDim.getOnDiskNumber(); } } } // Add the GCPs to the GCP list list<GcpPoint> adjustedGcps; list<GcpPoint>::const_iterator iter; for (iter = gcps.begin(); iter != gcps.end(); ++iter) { GcpPoint gcp = *iter; gcp.mPixel.mX = gcp.mPixel.mX - onDiskStartColumn; gcp.mPixel.mY = gcp.mPixel.mY - onDiskStartRow; adjustedGcps.push_back(gcp); } pGcpList->addPoints(adjustedGcps); } return pGcpList; }
bool ResultsExporter::writeOutput(ostream &stream) { mMessage = "Exporting results matrix..."; if (mpProgress != NULL) { mpProgress->updateProgress(mMessage, 0, NORMAL); } StepResource pStep(mMessage, "app", "D890E37C-B960-4527-8AAC-D62F2DE7A541"); RasterDataDescriptor* pDescriptor = dynamic_cast<RasterDataDescriptor*>(mpResults->getDataDescriptor()); if (pDescriptor == NULL) { mMessage = "Could not get the results data descriptor!"; if (mpProgress != NULL) { mpProgress->updateProgress(mMessage, 0, ERRORS); } pStep->finalize(Message::Failure); return false; } VERIFY(mpResults != NULL); string name = mpResults->getName(); VERIFY(mpFileDescriptor != NULL); const vector<DimensionDescriptor>& rows = mpFileDescriptor->getRows(); const vector<DimensionDescriptor>& columns = mpFileDescriptor->getColumns(); unsigned int numRows = pDescriptor->getRowCount(); unsigned int numColumns = pDescriptor->getColumnCount(); EncodingType eDataType = pDescriptor->getDataType(); const vector<int>& badValues = pDescriptor->getBadValues(); if (mbMetadata) { stream << APP_NAME << " Results Raster\n"; stream << "Version = 4\n"; stream << "Results Name = " << name << "\n"; DataElement* pParent = mpResults->getParent(); if (pParent != NULL) { stream << "Data Set Name = " << pParent->getName() << "\n"; } stream << "Rows = " << numRows << "\n"; stream << "Columns = " << numColumns << "\n"; string dataType = StringUtilities::toDisplayString(eDataType); stream << "Data Type = " << dataType << "\n"; Statistics* pStatistics = mpResults->getStatistics(); if (pStatistics != NULL) { stream << "Min = " << pStatistics->getMin() << "\n"; stream << "Max = " << pStatistics->getMax() << "\n"; stream << "Average = " << pStatistics->getAverage() << "\n"; stream << "Standard Deviation = " << pStatistics->getStandardDeviation() << "\n\n"; } } RasterElement* pGeo = getGeoreferencedRaster(); DataAccessor da = mpResults->getDataAccessor(); if (!da.isValid()) { mMessage = "Could not access the data in the results raster!"; if (mpProgress != NULL) { mpProgress->updateProgress(mMessage, 0, ERRORS); } pStep->finalize(Message::Failure); return false; } unsigned int activeRowNumber = 0; for (unsigned int r = 0; r < rows.size(); ++r) { if (mbAbort) { mMessage = "Results exporter aborted!"; if (mpProgress != NULL) { mpProgress->updateProgress(mMessage, 0, ABORT); } pStep->finalize(Message::Abort); return false; } DimensionDescriptor rowDim = rows[r]; // Skip to the next row for (; activeRowNumber < rowDim.getActiveNumber(); ++activeRowNumber) { da->nextRow(); } unsigned int activeColumnNumber = 0; for (unsigned int c = 0; c < columns.size(); ++c) { DimensionDescriptor columnDim = columns[c]; // Skip to the next column for (; activeColumnNumber < columnDim.getActiveNumber(); ++activeColumnNumber) { da->nextColumn(); } VERIFY(da.isValid()); double dValue = ModelServices::getDataValue(eDataType, da->getColumn(), COMPLEX_MAGNITUDE, 0); if (isValueExported(dValue, badValues)) { string location = getLocationString(r, c, pGeo); char buffer[1024]; sprintf(buffer, "%lf\n", dValue); stream << name << " " << location << " " << buffer; } } // Update the progress int iProgress = (r * 100) / rows.size(); if (iProgress == 100) { iProgress = 99; } if (mpProgress != NULL) { mpProgress->updateProgress(mMessage, iProgress, NORMAL); } } stream << "\n"; return true; }
bool DataRequestImp::validate(const RasterDataDescriptor *pDescriptor) const { if (pDescriptor == NULL) { return false; } unsigned int numRows = pDescriptor->getRowCount(); unsigned int numColumns = pDescriptor->getColumnCount(); unsigned int numBands = pDescriptor->getBandCount(); unsigned int bytesPerElement = pDescriptor->getBytesPerElement(); unsigned int postLineBytes = 0; DimensionDescriptor startRow = getStartRow(); DimensionDescriptor stopRow = getStopRow(); unsigned int concurrentRows = getConcurrentRows(); DimensionDescriptor startColumn = getStartColumn(); DimensionDescriptor stopColumn = getStopColumn(); unsigned int concurrentColumns = getConcurrentColumns(); DimensionDescriptor startBand = getStartBand(); DimensionDescriptor stopBand = getStopBand(); unsigned int concurrentBands = getConcurrentBands(); if (!startRow.isActiveNumberValid() || !stopRow.isActiveNumberValid() || !startColumn.isActiveNumberValid() || !stopColumn.isActiveNumberValid() || !startBand.isActiveNumberValid() || !stopBand.isActiveNumberValid()) { return false; } //validate all the parameters before continuing if (startRow.getActiveNumber() >= numRows || startRow.getActiveNumber() > stopRow.getActiveNumber() || stopRow.getActiveNumber() >= numRows || startColumn.getActiveNumber() >= numColumns || startColumn.getActiveNumber() > stopColumn.getActiveNumber() || stopColumn.getActiveNumber() >= numColumns || startBand.getActiveNumber() >= numBands || startBand.getActiveNumber() > stopBand.getActiveNumber() || stopBand.getActiveNumber() >= numBands || concurrentRows > stopRow.getActiveNumber()-startRow.getActiveNumber()+1 || concurrentColumns > stopColumn.getActiveNumber()-startColumn.getActiveNumber()+1 || concurrentBands > stopBand.getActiveNumber()-startBand.getActiveNumber()+1) { return false; } if (getInterleaveFormat() == BSQ) { // Can only get single-band BSQ accessors if (startBand != stopBand || concurrentBands != 1) { return false; } } return true; }