DataAccessorImpl* createDataAccessor(DataElement* pElement, DataAccessorArgs* pArgs) { RasterElement* pRasterElement = dynamic_cast<RasterElement*>(pElement); if (pRasterElement == NULL) { setLastError(SIMPLE_BAD_PARAMS); return NULL; } FactoryResource<DataRequest> pRequest; RasterDataDescriptor* pDescriptor = dynamic_cast<RasterDataDescriptor*>(pRasterElement->getDataDescriptor()); if (pArgs != NULL) { pRequest->setRows(pDescriptor->getActiveRow(pArgs->rowStart), pDescriptor->getActiveRow(pArgs->rowEnd),pArgs->concurrentRows); pRequest->setColumns(pDescriptor->getActiveColumn(pArgs->columnStart), pDescriptor->getActiveColumn(pArgs->columnEnd),pArgs->concurrentColumns); pRequest->setBands(pDescriptor->getActiveBand(pArgs->bandStart), pDescriptor->getActiveBand(pArgs->bandEnd),pArgs->concurrentBands); pRequest->setInterleaveFormat(static_cast<InterleaveFormatTypeEnum>(pArgs->interleaveFormat)); pRequest->setWritable(pArgs->writable != 0); } DataAccessor dataAccessor(pRasterElement->getDataAccessor(pRequest.release())); if (!dataAccessor.isValid()) { setLastError(SIMPLE_BAD_PARAMS); return NULL; } DataAccessorImpl* pRval = dataAccessor.operator->(); pRval->incrementRefCount(); setLastError(SIMPLE_NO_ERROR); return pRval; }
DataAccessor getAccessor(int band, bool writable = false) { FactoryResource<DataRequest> pRequest = FactoryResource<DataRequest>(); pRequest->setRows(pDataDescriptor->getActiveRow(0), pDataDescriptor->getActiveRow(getRowCount() - 1)); pRequest->setColumns(pDataDescriptor->getActiveColumn(0), pDataDescriptor->getActiveColumn(getColumnCount() - 1)); pRequest->setBands(pDataDescriptor->getActiveBand(band), pDataDescriptor->getActiveBand(band)); pRequest->setWritable(writable); return pRaster->getDataAccessor(pRequest.release()); }
void ConvolutionFilterShell::ConvolutionFilterThread::convolve(const T*) { int numResultsCols = mInput.mpIterCheck->getNumSelectedColumns(); if (mInput.mpResult == NULL) { return; } const RasterDataDescriptor* pResultDescriptor = static_cast<const RasterDataDescriptor*>( mInput.mpResult->getDataDescriptor()); // account for AOIs which extend outside the dataset int maxRowNum = static_cast<int>(mInput.mpDescriptor->getRowCount()) - 1; mRowRange.mFirst = std::max(0, mRowRange.mFirst); mRowRange.mLast = std::min(mRowRange.mLast, maxRowNum); unsigned int bandCount = mInput.mBands.size(); for (unsigned int bandNum = 0; bandNum < bandCount; ++bandNum) { FactoryResource<DataRequest> pResultRequest; pResultRequest->setRows(pResultDescriptor->getActiveRow(mRowRange.mFirst), pResultDescriptor->getActiveRow(mRowRange.mLast)); pResultRequest->setColumns(pResultDescriptor->getActiveColumn(0), pResultDescriptor->getActiveColumn(numResultsCols - 1)); pResultRequest->setBands(pResultDescriptor->getActiveBand(bandNum), pResultDescriptor->getActiveBand(bandNum)); pResultRequest->setWritable(true); DataAccessor resultAccessor = mInput.mpResult->getDataAccessor(pResultRequest.release()); if (!resultAccessor.isValid()) { return; } int oldPercentDone = -1; int rowOffset = static_cast<int>(mInput.mpIterCheck->getOffset().mY); int startRow = mRowRange.mFirst + rowOffset; int stopRow = mRowRange.mLast + rowOffset; int columnOffset = static_cast<int>(mInput.mpIterCheck->getOffset().mX); int startColumn = columnOffset; int stopColumn = numResultsCols + columnOffset - 1; int yshift = (mInput.mKernel.Nrows() - 1) / 2; int xshift = (mInput.mKernel.Ncols() - 1) / 2; FactoryResource<DataRequest> pRequest; pRequest->setRows(mInput.mpDescriptor->getActiveRow(std::max(0, startRow - yshift)), mInput.mpDescriptor->getActiveRow(std::min(maxRowNum, stopRow + mInput.mKernel.Nrows() - yshift))); pRequest->setColumns(mInput.mpDescriptor->getActiveColumn(startColumn), mInput.mpDescriptor->getActiveColumn(stopColumn)); pRequest->setBands(mInput.mpDescriptor->getActiveBand(mInput.mBands[bandNum]), mInput.mpDescriptor->getActiveBand(mInput.mBands[bandNum])); DataAccessor accessor = mInput.mpRaster->getDataAccessor(pRequest.release()); if (!accessor.isValid()) { return; } Service<ModelServices> model; ModelServices* pModel = model.get(); int numRows = stopRow - startRow + 1; for (int row_index = startRow; row_index <= stopRow; ++row_index) { int percentDone = 100 * ((bandNum * numRows) + (row_index - startRow)) / (numRows * bandCount); if (percentDone > oldPercentDone) { oldPercentDone = percentDone; getReporter().reportProgress(getThreadIndex(), percentDone); } if (mInput.mpAbortFlag != NULL && *mInput.mpAbortFlag) { break; } for (int col_index = startColumn; col_index <= stopColumn; ++col_index) { double accum = 0.0; if (mInput.mpIterCheck->getPixel(col_index, row_index)) { for (int kernelrow = 0; kernelrow < mInput.mKernel.Nrows(); kernelrow++) { int neighbor_row = row_index - yshift + kernelrow; int real_row = std::min(std::max(0, neighbor_row), static_cast<int>(mInput.mpDescriptor->getRowCount()) - 1); for (int kernelcol = 0; kernelcol < mInput.mKernel.Ncols(); kernelcol++) { int neighbor_col = col_index - xshift + kernelcol; int real_col = std::min(std::max(0, neighbor_col), static_cast<int>(mInput.mpDescriptor->getColumnCount()) - 1); accessor->toPixel(real_row, real_col); if (accessor.isValid() == false) { return; } double val = 0.0; pModel->getDataValue<T>(reinterpret_cast<T*>(accessor->getColumn()), COMPLEX_MAGNITUDE, 0, val); accum += mInput.mKernel(kernelrow+1, kernelcol+1) * val / mInput.mKernel.Storage(); } } } if (resultAccessor.isValid() == false) { return; } switchOnEncoding(pResultDescriptor->getDataType(), assignResult, resultAccessor->getColumn(), accum + mInput.mOffset); resultAccessor->nextColumn(); } resultAccessor->nextRow(); } } }
void NormalizeData::NormalizeDataThread::run() { if (mInput.mpResult == NULL) { getReporter().reportError("No result data element."); return; } EncodingType encoding = mInput.mpDescriptor->getDataType(); int numCols = mInput.mpResultDescriptor->getColumnCount(); int oldPercentDone = 0; int startRow = mRowRange.mFirst; int stopRow = mRowRange.mLast; bool isBip = (mInput.mpResultDescriptor->getInterleaveFormat() == BIP); unsigned int numBandsInLoop = isBip ? 1 : mInput.mpResultDescriptor->getBandCount(); unsigned int numBandsPerElement = isBip ? mInput.mpResultDescriptor->getBandCount() : 1; std::vector<double> bandMaxValues; bandMaxValues.reserve(mInput.mpDescriptor->getBandCount()); for (unsigned int band = 0; band < mInput.mpDescriptor->getBandCount(); band++) { bandMaxValues.push_back(mInput.mpRaster->getStatistics(mInput.mpDescriptor->getActiveBand(band))->getMax()); } Service<ModelServices> pModel; for(unsigned int band = 0; band < numBandsInLoop; band++) { FactoryResource<DataRequest> pResultRequest; pResultRequest->setRows(mInput.mpResultDescriptor->getActiveRow(mRowRange.mFirst), mInput.mpResultDescriptor->getActiveRow(mRowRange.mLast)); pResultRequest->setColumns(mInput.mpResultDescriptor->getActiveColumn(0), mInput.mpResultDescriptor->getActiveColumn(numCols - 1)); if (!isBip) { pResultRequest->setBands(mInput.mpResultDescriptor->getActiveBand(band), mInput.mpResultDescriptor->getActiveBand(band)); } pResultRequest->setWritable(true); DataAccessor resultAccessor = mInput.mpResult->getDataAccessor(pResultRequest.release()); if (!resultAccessor.isValid()) { getReporter().reportError("Invalid data access."); return; } FactoryResource<DataRequest> pRequest; pRequest->setRows(mInput.mpDescriptor->getActiveRow(mRowRange.mFirst), mInput.mpDescriptor->getActiveRow(mRowRange.mLast)); pRequest->setColumns(mInput.mpDescriptor->getActiveColumn(0), mInput.mpDescriptor->getActiveColumn(numCols - 1)); if (!isBip) { pRequest->setBands(mInput.mpResultDescriptor->getActiveBand(band), mInput.mpResultDescriptor->getActiveBand(band)); } DataAccessor accessor = mInput.mpRaster->getDataAccessor(pRequest.release()); if (!accessor.isValid()) { getReporter().reportError("Invalid data access."); return; } for (int row_index = startRow; row_index <= stopRow; row_index++) { int percentDone = mRowRange.computePercent(row_index / numBandsInLoop); if (percentDone > oldPercentDone) { oldPercentDone = percentDone; getReporter().reportProgress(getThreadIndex(), percentDone); } if (mInput.mpAbortFlag != NULL && *mInput.mpAbortFlag) { getReporter().reportProgress(getThreadIndex(), 100); break; } for (int col_index = 0; col_index < numCols; col_index++) { if (!resultAccessor.isValid()) { getReporter().reportError("Invalid data access."); return; } for (unsigned int inner = 0; inner < numBandsPerElement; inner++) { double val = pModel->getDataValue(encoding, accessor->getColumn(), inner); val /= bandMaxValues[std::max(band, inner)]; reinterpret_cast<double*>(resultAccessor->getColumn())[inner] = val; } resultAccessor->nextColumn(); accessor->nextColumn(); } resultAccessor->nextRow(); accessor->nextRow(); } } getReporter().reportCompletion(getThreadIndex()); }
vector<ImportDescriptor*> SampleHdf4Importer::getImportDescriptors(const string& filename) { vector<ImportDescriptor*> descriptors; Hdf4File parsedFile(filename); bool bSuccess = getFileData(parsedFile); if (bSuccess == true) { const Hdf4Dataset* pDataset = dynamic_cast<const Hdf4Dataset*>(parsedFile.getRootGroup()->getElement("EV_500_RefSB")); if ((pDataset != NULL) && (mpModel.get() != NULL)) { Hdf4FileResource pFile(filename.c_str()); if (pFile.get() != NULL) { 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) { int32 numDims = 0; int32 dataType = 0; int32 numAttr = 0; pFileDescriptor->setFilename(filename); Hdf4DatasetResource pDataHandle(*pFile, pDataset->getName().c_str()); int32 dimSizes[MAX_VAR_DIMS] = {0}; if (pDataHandle != NULL && *pDataHandle != FAIL) { pFileDescriptor->setDatasetLocation(pDataset->getName()); int32 success = SDgetinfo(*pDataHandle, const_cast<char*>(pDataset->getName().c_str()), &numDims, dimSizes, &dataType, &numAttr); // find out what type this Dataset is string strDataType = hdf4TypeToString(dataType, 1); if (success == SUCCEED && numDims == 3 && strDataType == "unsigned short") { // Bands vector<DimensionDescriptor> bands = RasterUtilities::generateDimensionVector(dimSizes[0], true, false, true); pDescriptor->setBands(bands); pFileDescriptor->setBands(bands); // Rows vector<DimensionDescriptor> rows = RasterUtilities::generateDimensionVector(dimSizes[1], true, false, true); pDescriptor->setRows(rows); pFileDescriptor->setRows(rows); // Columns vector<DimensionDescriptor> columns = RasterUtilities::generateDimensionVector(dimSizes[2], true, false, true); pDescriptor->setColumns(columns); pFileDescriptor->setColumns(columns); } } // Data type EncodingType e; pDataset->getDataEncoding(e); pDescriptor->setDataType(e); pFileDescriptor->setBitsPerElement(pDescriptor->getBytesPerElement() * 8); // Interleave format pDescriptor->setInterleaveFormat(BSQ); pFileDescriptor->setInterleaveFormat(BSQ); // Metadata FactoryResource<DynamicObject> pMetadata; if (pMetadata.get() != NULL) { const Hdf4Dataset::AttributeContainer& attributes = pDataset->getAttributes(); for (Hdf4Dataset::AttributeContainer::const_iterator it = attributes.begin(); it != attributes.end(); ++it) { Hdf4Attribute* pAttribute = it->second; if (pAttribute != NULL) { const string& name = pAttribute->getName(); const DataVariant& var = pAttribute->getVariant(); const unsigned short* pValue = var.getPointerToValue<unsigned short>(); if (name == "_FillValue" && pValue != NULL) { // Bad values vector<int> badValues; badValues.push_back(*pValue); pDescriptor->setBadValues(badValues); } else { pMetadata->setAttribute(name, var); } } } pDescriptor->setMetadata(pMetadata.get()); } pDescriptor->setFileDescriptor(pFileDescriptor.get()); } } descriptors.push_back(pImportDescriptor); } } } } return descriptors; }
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; }
void SamThread::ComputeSam(const T* pDummyData) { int reSamBan_index = 0, row_index = 0, col_index = 0; float* pResultsData = NULL; int oldPercentDone = -1; double spectrumMag = 0.0; const T* pData=NULL; const RasterDataDescriptor* pDescriptor = static_cast<const RasterDataDescriptor*>( mInput.mpCube->getDataDescriptor()); unsigned int numCols = pDescriptor->getColumnCount(); unsigned int numBands = pDescriptor->getBandCount(); unsigned int numRows = (mRowRange.mLast - mRowRange.mFirst + 1); int numResultsCols = 0; //Sets area to apply the SAM algortihm to. Either //the entire cube, or a selected ROI. if (mInput.mIterCheck.useAllPixels()) { //Total number of Columns in cube. numResultsCols = numCols; } else { numResultsCols = mInput.mIterCheck.getNumSelectedColumns(); } if (mInput.mpResultsMatrix == NULL) { return; } const RasterDataDescriptor* pResultDescriptor = static_cast<const RasterDataDescriptor*>( mInput.mpResultsMatrix->getDataDescriptor()); // Gets results matrix that was initialized in ProcessAll() mRowRange.mFirst = std::max(0, mRowRange.mFirst); mRowRange.mLast = std::min(mRowRange.mLast, static_cast<int>(pDescriptor->getRowCount()) - 1); FactoryResource<DataRequest> pResultRequest; pResultRequest->setRows(pResultDescriptor->getActiveRow(mRowRange.mFirst), pResultDescriptor->getActiveRow(mRowRange.mLast)); pResultRequest->setColumns(pResultDescriptor->getActiveColumn(0), pResultDescriptor->getActiveColumn(numResultsCols - 1)); pResultRequest->setWritable(true); DataAccessor resultAccessor = mInput.mpResultsMatrix->getDataAccessor(pResultRequest.release()); if (!resultAccessor.isValid()) { return; } // Resamples and sets search signature for (reSamBan_index = 0; reSamBan_index < (int) mInput.mResampledBands.size(); ++reSamBan_index) { spectrumMag += mInput.mSpectrum[reSamBan_index] * mInput.mSpectrum[reSamBan_index]; } spectrumMag = sqrt(spectrumMag); int rowOffset = mInput.mIterCheck.getOffset().mY; int startRow = (mRowRange.mFirst + rowOffset); int stopRow = (mRowRange.mLast + rowOffset); int columnOffset = mInput.mIterCheck.getOffset().mX; int startColumn = columnOffset; int stopColumn = (numResultsCols + columnOffset - 1); FactoryResource<DataRequest> pRequest; pRequest->setInterleaveFormat(BIP); pRequest->setRows(pDescriptor->getActiveRow(startRow), pDescriptor->getActiveRow(stopRow)); pRequest->setColumns(pDescriptor->getActiveColumn(startColumn), pDescriptor->getActiveColumn(stopColumn)); DataAccessor accessor = mInput.mpCube->getDataAccessor(pRequest.release()); if (!accessor.isValid()) { return; } for (row_index = startRow; row_index <= stopRow; ++row_index) { int percentDone = mRowRange.computePercent(row_index-rowOffset); if (percentDone > oldPercentDone) { oldPercentDone = percentDone; getReporter().reportProgress(getThreadIndex(), percentDone); } if (mInput.mpAbortFlag != NULL && *mInput.mpAbortFlag) { break; } for (col_index = startColumn; col_index <= stopColumn; ++col_index) { VERIFYNRV(resultAccessor.isValid()); VERIFYNRV(accessor.isValid()); // Pointer to results data pResultsData = reinterpret_cast<float*>(resultAccessor->getColumn()); if (pResultsData == NULL) { return; } if (mInput.mIterCheck.getPixel(col_index, row_index)) { //Pointer to cube/sensor data pData = reinterpret_cast<T*>(accessor->getColumn()); VERIFYNRV(pData != NULL); *pResultsData = 0.0f; double pixelMag = 0.0; double angle =0.0; //Calculates Spectral Angle and Magnitude at current location for (unsigned int reSam_index = 0; reSam_index < mInput.mResampledBands.size(); ++reSam_index) { int resampledBand = mInput.mResampledBands[reSam_index]; double cubeVal = pData[resampledBand]; angle += cubeVal * mInput.mSpectrum[reSam_index]; pixelMag += cubeVal * cubeVal; } pixelMag = sqrt(pixelMag); if (pixelMag != 0.0 && spectrumMag != 0.0) { angle /= (pixelMag * spectrumMag); if (angle < -1.0) { angle = -1.0; } if (angle > 1.0) { angle = 1.0; } angle = (180.0 / 3.141592654) * acos(angle); *pResultsData = angle; } else { *pResultsData = 181.0; } } else { *pResultsData = 181.0; } //Increment Columns resultAccessor->nextColumn(); accessor->nextColumn(); } //Increment Rows resultAccessor->nextRow(); accessor->nextRow(); } }
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(); }