//! @cond Doxygen_Suppress int PamParseHistogram( CPLXMLNode *psHistItem, double *pdfMin, double *pdfMax, int *pnBuckets, GUIntBig **ppanHistogram, int * /* pbIncludeOutOfRange */, int * /* pbApproxOK */ ) { if( psHistItem == nullptr ) return FALSE; *pdfMin = CPLAtofM(CPLGetXMLValue( psHistItem, "HistMin", "0")); *pdfMax = CPLAtofM(CPLGetXMLValue( psHistItem, "HistMax", "1")); *pnBuckets = atoi(CPLGetXMLValue( psHistItem, "BucketCount","2")); if( *pnBuckets <= 0 || *pnBuckets > INT_MAX / 2 ) return FALSE; if( ppanHistogram == nullptr ) return TRUE; // Fetch the histogram and use it. const char *pszHistCounts = CPLGetXMLValue( psHistItem, "HistCounts", "" ); // Sanity check to test consistency of BucketCount and HistCounts. if( strlen(pszHistCounts) < 2 * static_cast<size_t>(*pnBuckets) - 1 ) { CPLError( CE_Failure, CPLE_AppDefined, "HistCounts content isn't consistent with BucketCount value" ); return FALSE; } *ppanHistogram = static_cast<GUIntBig *>( VSICalloc(sizeof(GUIntBig),*pnBuckets) ); if( *ppanHistogram == nullptr ) { CPLError( CE_Failure, CPLE_OutOfMemory, "Cannot allocate memory for %d buckets", *pnBuckets ); return FALSE; } for( int iBucket = 0; iBucket < *pnBuckets; iBucket++ ) { (*ppanHistogram)[iBucket] = CPLAtoGIntBig(pszHistCounts); // Skip to next number. while( *pszHistCounts != '\0' && *pszHistCounts != '|' ) pszHistCounts++; if( *pszHistCounts == '|' ) pszHistCounts++; } return TRUE; }
static void GDALGeoLocRescale(char**& papszMD, const char* pszItem, double dfRatio, double dfDefaultVal) { double dfVal = CPLAtofM(CSLFetchNameValueDef(papszMD, pszItem, CPLSPrintf("%.18g", dfDefaultVal))); dfVal *= dfRatio; papszMD = CSLSetNameValue(papszMD, pszItem, CPLSPrintf("%.18g", dfVal)); }
CPLErr ZMapRasterBand::IReadBlock( int nBlockXOff, int nBlockYOff, void * pImage ) { int i; ZMapDataset *poGDS = (ZMapDataset *) poDS; if (poGDS->fp == NULL) return CE_Failure; if (nBlockXOff < poGDS->nColNum + 1) { VSIFSeekL(poGDS->fp, poGDS->nDataStartOff, SEEK_SET); poGDS->nColNum = -1; } if (nBlockXOff > poGDS->nColNum + 1) { for(i=poGDS->nColNum + 1;i<nBlockXOff;i++) { if (IReadBlock(i,0,pImage) != CE_None) return CE_Failure; } } char* pszLine; i = 0; double dfExp = pow(10.0, poGDS->nDecimalCount); while(i<nRasterYSize) { pszLine = (char*)CPLReadLineL(poGDS->fp); if (pszLine == NULL) return CE_Failure; int nExpected = nRasterYSize - i; if (nExpected > poGDS->nValuesPerLine) nExpected = poGDS->nValuesPerLine; if ((int)strlen(pszLine) != nExpected * poGDS->nFieldSize) return CE_Failure; for(int j=0;j<nExpected;j++) { char* pszValue = pszLine + j * poGDS->nFieldSize; char chSaved = pszValue[poGDS->nFieldSize]; pszValue[poGDS->nFieldSize] = 0; if (strchr(pszValue, '.') != NULL) ((double*)pImage)[i+j] = CPLAtofM(pszValue); else ((double*)pImage)[i+j] = atoi(pszValue) * dfExp; pszValue[poGDS->nFieldSize] = chSaved; } i += nExpected; } poGDS->nColNum ++; return CE_None; }
CPLErr ZMapRasterBand::IReadBlock( int nBlockXOff, CPL_UNUSED int nBlockYOff, void * pImage ) { ZMapDataset *poGDS = reinterpret_cast<ZMapDataset *>( poDS ); if (poGDS->fp == NULL) return CE_Failure; if (nBlockXOff < poGDS->nColNum + 1) { VSIFSeekL(poGDS->fp, poGDS->nDataStartOff, SEEK_SET); poGDS->nColNum = -1; } if (nBlockXOff > poGDS->nColNum + 1) { for( int i = poGDS->nColNum + 1; i < nBlockXOff; i++ ) { if (IReadBlock(i,0,pImage) != CE_None) return CE_Failure; } } int i = 0; const double dfExp = std::pow(10.0, poGDS->nDecimalCount); while(i<nRasterYSize) { char* pszLine = const_cast<char *>( CPLReadLineL(poGDS->fp) ); if (pszLine == NULL) return CE_Failure; int nExpected = nRasterYSize - i; if (nExpected > poGDS->nValuesPerLine) nExpected = poGDS->nValuesPerLine; if( static_cast<int>( strlen(pszLine) ) != nExpected * poGDS->nFieldSize ) return CE_Failure; for( int j = 0; j < nExpected; j++ ) { char* pszValue = pszLine + j * poGDS->nFieldSize; const char chSaved = pszValue[poGDS->nFieldSize]; pszValue[poGDS->nFieldSize] = 0; if (strchr(pszValue, '.') != NULL) reinterpret_cast<double *>( pImage )[i+j] = CPLAtofM(pszValue); else reinterpret_cast<double *>( pImage )[i+j] = atoi(pszValue) * dfExp; pszValue[poGDS->nFieldSize] = chSaved; } i += nExpected; } poGDS->nColNum ++; return CE_None; }
CPLXMLNode * PamFindMatchingHistogram( CPLXMLNode *psSavedHistograms, double dfMin, double dfMax, int nBuckets, int bIncludeOutOfRange, int bApproxOK ) { if( psSavedHistograms == nullptr ) return nullptr; for( CPLXMLNode *psXMLHist = psSavedHistograms->psChild; psXMLHist != nullptr; psXMLHist = psXMLHist->psNext ) { if( psXMLHist->eType != CXT_Element || !EQUAL(psXMLHist->pszValue,"HistItem") ) continue; const double dfHistMin = CPLAtofM(CPLGetXMLValue( psXMLHist, "HistMin", "0")); const double dfHistMax = CPLAtofM(CPLGetXMLValue( psXMLHist, "HistMax", "0")); if( !(ARE_REAL_EQUAL(dfHistMin, dfMin) ) || !(ARE_REAL_EQUAL(dfHistMax, dfMax) ) || atoi(CPLGetXMLValue( psXMLHist, "BucketCount","0")) != nBuckets || !atoi(CPLGetXMLValue( psXMLHist, "IncludeOutOfRange","0")) != !bIncludeOutOfRange || (!bApproxOK && atoi(CPLGetXMLValue( psXMLHist, "Approximate","0"))) ) continue; return psXMLHist; } return nullptr; }
double VRTSourcedRasterBand::GetMaximum(int *pbSuccess ) { const char *pszValue = NULL; if( (pszValue = GetMetadataItem("STATISTICS_MAXIMUM")) != NULL ) { if( pbSuccess != NULL ) *pbSuccess = TRUE; return CPLAtofM(pszValue); } if ( bAntiRecursionFlag ) { CPLError( CE_Failure, CPLE_AppDefined, "VRTSourcedRasterBand::GetMaximum() called recursively on the same band. " "It looks like the VRT is referencing itself." ); if( pbSuccess != NULL ) *pbSuccess = FALSE; return 0.0; } bAntiRecursionFlag = TRUE; double dfMax = 0; for( int iSource = 0; iSource < nSources; iSource++ ) { int bSuccess = FALSE; double dfSourceMax = papoSources[iSource]->GetMaximum(GetXSize(), GetYSize(), &bSuccess); if (!bSuccess) { dfMax = GDALRasterBand::GetMaximum(pbSuccess); bAntiRecursionFlag = FALSE; return dfMax; } if (iSource == 0 || dfSourceMax > dfMax) dfMax = dfSourceMax; } bAntiRecursionFlag = FALSE; if( pbSuccess != NULL ) *pbSuccess = TRUE; return dfMax; }
GDALDataset *SAGADataset::Open( GDALOpenInfo * poOpenInfo ) { /* -------------------------------------------------------------------- */ /* We assume the user is pointing to the binary (ie. .sdat) file. */ /* -------------------------------------------------------------------- */ if( !EQUAL(CPLGetExtension( poOpenInfo->pszFilename ), "sdat")) { return NULL; } CPLString osPath = CPLGetPath( poOpenInfo->pszFilename ); CPLString osName = CPLGetBasename( poOpenInfo->pszFilename ); CPLString osHDRFilename; osHDRFilename = CPLFormCIFilename( osPath, osName, ".sgrd" ); VSILFILE *fp; fp = VSIFOpenL( osHDRFilename, "r" ); if( fp == NULL ) { return NULL; } /* -------------------------------------------------------------------- */ /* Is this file a SAGA header file? Read a few lines of text */ /* searching for something starting with nrows or ncols. */ /* -------------------------------------------------------------------- */ const char *pszLine; int nRows = -1, nCols = -1; double dXmin = 0.0, dYmin = 0.0, dCellsize = 0.0, dNoData = 0.0, dZFactor = 0.0; int nLineCount = 0; char szDataFormat[20] = "DOUBLE"; char szByteOrderBig[10] = "FALSE"; char szTopToBottom[10] = "FALSE"; char **papszHDR = NULL; while( (pszLine = CPLReadLineL( fp )) != NULL ) { char **papszTokens; nLineCount++; if( nLineCount > 50 || strlen(pszLine) > 1000 ) break; papszHDR = CSLAddString( papszHDR, pszLine ); papszTokens = CSLTokenizeStringComplex( pszLine, " =", TRUE, FALSE ); if( CSLCount( papszTokens ) < 2 ) { CSLDestroy( papszTokens ); continue; } if( EQUALN(papszTokens[0],"CELLCOUNT_X",strlen("CELLCOUNT_X")) ) nCols = atoi(papszTokens[1]); else if( EQUALN(papszTokens[0],"CELLCOUNT_Y",strlen("CELLCOUNT_Y")) ) nRows = atoi(papszTokens[1]); else if( EQUALN(papszTokens[0],"POSITION_XMIN",strlen("POSITION_XMIN")) ) dXmin = CPLAtofM(papszTokens[1]); else if( EQUALN(papszTokens[0],"POSITION_YMIN",strlen("POSITION_YMIN")) ) dYmin = CPLAtofM(papszTokens[1]); else if( EQUALN(papszTokens[0],"CELLSIZE",strlen("CELLSIZE")) ) dCellsize = CPLAtofM(papszTokens[1]); else if( EQUALN(papszTokens[0],"NODATA_VALUE",strlen("NODATA_VALUE")) ) dNoData = CPLAtofM(papszTokens[1]); else if( EQUALN(papszTokens[0],"DATAFORMAT",strlen("DATAFORMAT")) ) strncpy( szDataFormat, papszTokens[1], sizeof(szDataFormat)-1 ); else if( EQUALN(papszTokens[0],"BYTEORDER_BIG",strlen("BYTEORDER_BIG")) ) strncpy( szByteOrderBig, papszTokens[1], sizeof(szByteOrderBig)-1 ); else if( EQUALN(papszTokens[0],"TOPTOBOTTOM",strlen("TOPTOBOTTOM")) ) strncpy( szTopToBottom, papszTokens[1], sizeof(szTopToBottom)-1 ); else if( EQUALN(papszTokens[0],"Z_FACTOR",strlen("Z_FACTOR")) ) dZFactor = CPLAtofM(papszTokens[1]); CSLDestroy( papszTokens ); } VSIFCloseL( fp ); CSLDestroy( papszHDR ); /* -------------------------------------------------------------------- */ /* Did we get the required keywords? If not we return with */ /* this never having been considered to be a match. This isn't */ /* an error! */ /* -------------------------------------------------------------------- */ if( nRows == -1 || nCols == -1 ) { return NULL; } if (!GDALCheckDatasetDimensions(nCols, nRows)) { return NULL; } if( EQUALN(szTopToBottom,"TRUE",strlen("TRUE")) ) { CPLError( CE_Failure, CPLE_AppDefined, "Currently the SAGA Binary Grid driver does not support\n" "SAGA grids written TOPTOBOTTOM.\n"); return NULL; } if( dZFactor != 1.0) { CPLError( CE_Warning, CPLE_AppDefined, "Currently the SAGA Binary Grid driver does not support\n" "ZFACTORs other than 1.\n"); } /* -------------------------------------------------------------------- */ /* Create a corresponding GDALDataset. */ /* -------------------------------------------------------------------- */ SAGADataset *poDS = new SAGADataset(); poDS->eAccess = poOpenInfo->eAccess; if( poOpenInfo->eAccess == GA_ReadOnly ) poDS->fp = VSIFOpenL( poOpenInfo->pszFilename, "rb" ); else poDS->fp = VSIFOpenL( poOpenInfo->pszFilename, "r+b" ); if( poDS->fp == NULL ) { delete poDS; CPLError( CE_Failure, CPLE_OpenFailed, "VSIFOpenL(%s) failed unexpectedly.", poOpenInfo->pszFilename ); return NULL; } poDS->nRasterXSize = nCols; poDS->nRasterYSize = nRows; SAGARasterBand *poBand = new SAGARasterBand( poDS, 1 ); /* -------------------------------------------------------------------- */ /* Figure out the byte order. */ /* -------------------------------------------------------------------- */ if( EQUALN(szByteOrderBig,"TRUE",strlen("TRUE")) ) poBand->m_ByteOrder = 1; else if( EQUALN(szByteOrderBig,"FALSE",strlen("FALSE")) ) poBand->m_ByteOrder = 0; /* -------------------------------------------------------------------- */ /* Figure out the data type. */ /* -------------------------------------------------------------------- */ if( EQUAL(szDataFormat,"BIT") ) { poBand->SetDataType(GDT_Byte); poBand->m_nBits = 8; } else if( EQUAL(szDataFormat,"BYTE_UNSIGNED") ) { poBand->SetDataType(GDT_Byte); poBand->m_nBits = 8; } else if( EQUAL(szDataFormat,"BYTE") ) { poBand->SetDataType(GDT_Byte); poBand->m_nBits = 8; } else if( EQUAL(szDataFormat,"SHORTINT_UNSIGNED") ) { poBand->SetDataType(GDT_UInt16); poBand->m_nBits = 16; } else if( EQUAL(szDataFormat,"SHORTINT") ) { poBand->SetDataType(GDT_Int16); poBand->m_nBits = 16; } else if( EQUAL(szDataFormat,"INTEGER_UNSIGNED") ) { poBand->SetDataType(GDT_UInt32); poBand->m_nBits = 32; } else if( EQUAL(szDataFormat,"INTEGER") ) { poBand->SetDataType(GDT_Int32); poBand->m_nBits = 32; } else if( EQUAL(szDataFormat,"FLOAT") ) { poBand->SetDataType(GDT_Float32); poBand->m_nBits = 32; } else if( EQUAL(szDataFormat,"DOUBLE") ) { poBand->SetDataType(GDT_Float64); poBand->m_nBits = 64; } else { CPLError( CE_Failure, CPLE_NotSupported, "SAGA driver does not support the dataformat %s.", szDataFormat ); delete poBand; delete poDS; return NULL; } /* -------------------------------------------------------------------- */ /* Save band information */ /* -------------------------------------------------------------------- */ poBand->m_Xmin = dXmin; poBand->m_Ymin = dYmin; poBand->m_NoData = dNoData; poBand->m_Cellsize = dCellsize; poBand->m_Rows = nRows; poBand->m_Cols = nCols; poDS->SetBand( 1, poBand ); /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->SetDescription( poOpenInfo->pszFilename ); poDS->TryLoadXML(); /* -------------------------------------------------------------------- */ /* Check for a .prj file. */ /* -------------------------------------------------------------------- */ const char *pszPrjFilename = CPLFormCIFilename( osPath, osName, "prj" ); fp = VSIFOpenL( pszPrjFilename, "r" ); if( fp != NULL ) { char **papszLines; OGRSpatialReference oSRS; VSIFCloseL( fp ); papszLines = CSLLoad( pszPrjFilename ); if( oSRS.importFromESRI( papszLines ) == OGRERR_NONE ) { CPLFree( poDS->pszProjection ); oSRS.exportToWkt( &(poDS->pszProjection) ); } CSLDestroy( papszLines ); } /* -------------------------------------------------------------------- */ /* Check for external overviews. */ /* -------------------------------------------------------------------- */ poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename, poOpenInfo->papszSiblingFiles ); return poDS; }
OGRErr OGRSpatialReference::importFromOzi( const char * const* papszLines ) { int iLine; const char *pszDatum, *pszProj = NULL, *pszProjParms = NULL; Clear(); int nLines = CSLCount((char**)papszLines); if( nLines < 5 ) return OGRERR_NOT_ENOUGH_DATA; pszDatum = papszLines[4]; for ( iLine = 5; iLine < nLines; iLine++ ) { if ( EQUALN(papszLines[iLine], "Map Projection", 14) ) { pszProj = papszLines[iLine]; } else if ( EQUALN(papszLines[iLine], "Projection Setup", 16) ) { pszProjParms = papszLines[iLine]; } } if ( ! ( pszDatum && pszProj && pszProjParms ) ) return OGRERR_NOT_ENOUGH_DATA; /* -------------------------------------------------------------------- */ /* Operate on the basis of the projection name. */ /* -------------------------------------------------------------------- */ char **papszProj = CSLTokenizeStringComplex( pszProj, ",", TRUE, TRUE ); char **papszProjParms = CSLTokenizeStringComplex( pszProjParms, ",", TRUE, TRUE ); char **papszDatum = NULL; if (CSLCount(papszProj) < 2) { goto not_enough_data; } if ( EQUALN(papszProj[1], "Latitude/Longitude", 18) ) { } else if ( EQUALN(papszProj[1], "Mercator", 8) ) { if (CSLCount(papszProjParms) < 6) goto not_enough_data; double dfScale = CPLAtof(papszProjParms[3]); if (papszProjParms[3][0] == 0) dfScale = 1; /* if unset, default to scale = 1 */ SetMercator( CPLAtof(papszProjParms[1]), CPLAtof(papszProjParms[2]), dfScale, CPLAtof(papszProjParms[4]), CPLAtof(papszProjParms[5]) ); } else if ( EQUALN(papszProj[1], "Transverse Mercator", 19) ) { if (CSLCount(papszProjParms) < 6) goto not_enough_data; SetTM( CPLAtof(papszProjParms[1]), CPLAtof(papszProjParms[2]), CPLAtof(papszProjParms[3]), CPLAtof(papszProjParms[4]), CPLAtof(papszProjParms[5]) ); } else if ( EQUALN(papszProj[1], "Lambert Conformal Conic", 23) ) { if (CSLCount(papszProjParms) < 8) goto not_enough_data; SetLCC( CPLAtof(papszProjParms[6]), CPLAtof(papszProjParms[7]), CPLAtof(papszProjParms[1]), CPLAtof(papszProjParms[2]), CPLAtof(papszProjParms[4]), CPLAtof(papszProjParms[5]) ); } else if ( EQUALN(papszProj[1], "Sinusoidal", 10) ) { if (CSLCount(papszProjParms) < 6) goto not_enough_data; SetSinusoidal( CPLAtof(papszProjParms[2]), CPLAtof(papszProjParms[4]), CPLAtof(papszProjParms[5]) ); } else if ( EQUALN(papszProj[1], "Albers Equal Area", 17) ) { if (CSLCount(papszProjParms) < 8) goto not_enough_data; SetACEA( CPLAtof(papszProjParms[6]), CPLAtof(papszProjParms[7]), CPLAtof(papszProjParms[1]), CPLAtof(papszProjParms[2]), CPLAtof(papszProjParms[4]), CPLAtof(papszProjParms[5]) ); } else if ( EQUALN(papszProj[1], "(UTM) Universal Transverse Mercator", 35) && nLines > 5 ) { /* Look for the UTM zone in the calibration point data */ for ( iLine = 5; iLine < nLines; iLine++ ) { if ( EQUALN(papszLines[iLine], "Point", 5) ) { char **papszTok = NULL; papszTok = CSLTokenizeString2( papszLines[iLine], ",", CSLT_ALLOWEMPTYTOKENS | CSLT_STRIPLEADSPACES | CSLT_STRIPENDSPACES ); if ( CSLCount(papszTok) < 17 || EQUAL(papszTok[2], "") || EQUAL(papszTok[13], "") || EQUAL(papszTok[14], "") || EQUAL(papszTok[15], "") || EQUAL(papszTok[16], "") ) { CSLDestroy(papszTok); continue; } SetUTM( CPLAtofM(papszTok[13]), EQUAL(papszTok[16], "N") ); CSLDestroy(papszTok); break; } } if ( iLine == nLines ) /* Try to guess the UTM zone */ { float fMinLongitude = INT_MAX; float fMaxLongitude = INT_MIN; float fMinLatitude = INT_MAX; float fMaxLatitude = INT_MIN; int bFoundMMPLL = FALSE; for ( iLine = 5; iLine < nLines; iLine++ ) { if ( EQUALN(papszLines[iLine], "MMPLL", 5) ) { char **papszTok = NULL; papszTok = CSLTokenizeString2( papszLines[iLine], ",", CSLT_ALLOWEMPTYTOKENS | CSLT_STRIPLEADSPACES | CSLT_STRIPENDSPACES ); if ( CSLCount(papszTok) < 4 ) { CSLDestroy(papszTok); continue; } float fLongitude = CPLAtofM(papszTok[2]); float fLatitude = CPLAtofM(papszTok[3]); CSLDestroy(papszTok); bFoundMMPLL = TRUE; if ( fMinLongitude > fLongitude ) fMinLongitude = fLongitude; if ( fMaxLongitude < fLongitude ) fMaxLongitude = fLongitude; if ( fMinLatitude > fLatitude ) fMinLatitude = fLatitude; if ( fMaxLatitude < fLatitude ) fMaxLatitude = fLatitude; } } float fMedianLatitude = ( fMinLatitude + fMaxLatitude ) / 2; float fMedianLongitude = ( fMinLongitude + fMaxLongitude ) / 2; if ( bFoundMMPLL && fMaxLatitude <= 90 ) { int nUtmZone; if ( fMedianLatitude >= 56 && fMedianLatitude <= 64 && fMedianLongitude >= 3 && fMedianLongitude <= 12 ) nUtmZone = 32; /* Norway exception */ else if ( fMedianLatitude >= 72 && fMedianLatitude <= 84 && fMedianLongitude >= 0 && fMedianLongitude <= 42 ) nUtmZone = (int) ((fMedianLongitude + 3 ) / 12) * 2 + 31; /* Svalbard exception */ else nUtmZone = (int) ((fMedianLongitude + 180 ) / 6) + 1; SetUTM( nUtmZone, fMedianLatitude >= 0 ); } else CPLDebug( "OSR_Ozi", "UTM Zone not found"); } } else if ( EQUALN(papszProj[1], "(I) France Zone I", 17) ) { SetLCC1SP( 49.5, 2.337229167, 0.99987734, 600000, 1200000 ); } else if ( EQUALN(papszProj[1], "(II) France Zone II", 19) ) { SetLCC1SP( 46.8, 2.337229167, 0.99987742, 600000, 2200000 ); } else if ( EQUALN(papszProj[1], "(III) France Zone III", 21) ) { SetLCC1SP( 44.1, 2.337229167, 0.99987750, 600000, 3200000 ); } else if ( EQUALN(papszProj[1], "(IV) France Zone IV", 19) ) { SetLCC1SP( 42.165, 2.337229167, 0.99994471, 234.358, 4185861.369 ); } /* * Note : The following projections have not been implemented yet * */ /* else if ( EQUALN(papszProj[1], "(BNG) British National Grid", 27) ) { } else if ( EQUALN(papszProj[1], "(IG) Irish Grid", 15) ) { } else if ( EQUALN(papszProj[1], "(NZG) New Zealand Grid", 22) ) { } else if ( EQUALN(papszProj[1], "(NZTM2) New Zealand TM 2000", 27) ) { } else if ( EQUALN(papszProj[1], "(SG) Swedish Grid", 27) ) { } else if ( EQUALN(papszProj[1], "(SUI) Swiss Grid", 26) ) { } else if ( EQUALN(papszProj[1], "(A)Lambert Azimuthual Equal Area", 32) ) { } else if ( EQUALN(papszProj[1], "(EQC) Equidistant Conic", 23) ) { } else if ( EQUALN(papszProj[1], "Polyconic (American)", 20) ) { } else if ( EQUALN(papszProj[1], "Van Der Grinten", 15) ) { } else if ( EQUALN(papszProj[1], "Vertical Near-Sided Perspective", 31) ) { } else if ( EQUALN(papszProj[1], "(WIV) Wagner IV", 15) ) { } else if ( EQUALN(papszProj[1], "Bonne", 5) ) { } else if ( EQUALN(papszProj[1], "(MT0) Montana State Plane Zone 2500", 35) ) { } else if ( EQUALN(papszProj[1], "ITA1) Italy Grid Zone 1", 23) ) { } else if ( EQUALN(papszProj[1], "ITA2) Italy Grid Zone 2", 23) ) { } else if ( EQUALN(papszProj[1], "(VICMAP-TM) Victoria Aust.(pseudo AMG)", 38) ) { } else if ( EQUALN(papszProj[1], "VICGRID) Victoria Australia", 27) ) { } else if ( EQUALN(papszProj[1], "(VG94) VICGRID94 Victoria Australia", 35) ) { } else if ( EQUALN(papszProj[1], "Gnomonic", 8) ) { } */ else { CPLDebug( "OSR_Ozi", "Unsupported projection: \"%s\"", papszProj[1] ); SetLocalCS( CPLString().Printf("\"Ozi\" projection \"%s\"", papszProj[1]) ); } /* -------------------------------------------------------------------- */ /* Try to translate the datum/spheroid. */ /* -------------------------------------------------------------------- */ papszDatum = CSLTokenizeString2( pszDatum, ",", CSLT_ALLOWEMPTYTOKENS | CSLT_STRIPLEADSPACES | CSLT_STRIPENDSPACES ); if ( papszDatum == NULL) goto not_enough_data; if ( !IsLocal() ) { /* -------------------------------------------------------------------- */ /* Verify that we can find the CSV file containing the datums */ /* -------------------------------------------------------------------- */ if( CSVScanFileByName( CSVFilename( "ozi_datum.csv" ), "EPSG_DATUM_CODE", "4326", CC_Integer ) == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Unable to open OZI support file %s.\n" "Try setting the GDAL_DATA environment variable to point\n" "to the directory containing OZI csv files.", CSVFilename( "ozi_datum.csv" ) ); goto other_error; } /* -------------------------------------------------------------------- */ /* Search for matching datum */ /* -------------------------------------------------------------------- */ const char *pszOziDatum = CSVFilename( "ozi_datum.csv" ); CPLString osDName = CSVGetField( pszOziDatum, "NAME", papszDatum[0], CC_ApproxString, "NAME" ); if( strlen(osDName) == 0 ) { CPLError( CE_Failure, CPLE_AppDefined, "Failed to find datum %s in ozi_datum.csv.", papszDatum[0] ); goto other_error; } int nDatumCode = atoi( CSVGetField( pszOziDatum, "NAME", papszDatum[0], CC_ApproxString, "EPSG_DATUM_CODE" ) ); if ( nDatumCode > 0 ) // There is a matching EPSG code { OGRSpatialReference oGCS; oGCS.importFromEPSG( nDatumCode ); CopyGeogCSFrom( &oGCS ); } else // We use the parameters from the CSV files { CPLString osEllipseCode = CSVGetField( pszOziDatum, "NAME", papszDatum[0], CC_ApproxString, "ELLIPSOID_CODE" ); double dfDeltaX = CPLAtof(CSVGetField( pszOziDatum, "NAME", papszDatum[0], CC_ApproxString, "DELTAX" ) ); double dfDeltaY = CPLAtof(CSVGetField( pszOziDatum, "NAME", papszDatum[0], CC_ApproxString, "DELTAY" ) ); double dfDeltaZ = CPLAtof(CSVGetField( pszOziDatum, "NAME", papszDatum[0], CC_ApproxString, "DELTAZ" ) ); /* -------------------------------------------------------------------- */ /* Verify that we can find the CSV file containing the ellipsoids */ /* -------------------------------------------------------------------- */ if( CSVScanFileByName( CSVFilename( "ozi_ellips.csv" ), "ELLIPSOID_CODE", "20", CC_Integer ) == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Unable to open OZI support file %s.\n" "Try setting the GDAL_DATA environment variable to point\n" "to the directory containing OZI csv files.", CSVFilename( "ozi_ellips.csv" ) ); goto other_error; } /* -------------------------------------------------------------------- */ /* Lookup the ellipse code. */ /* -------------------------------------------------------------------- */ const char *pszOziEllipse = CSVFilename( "ozi_ellips.csv" ); CPLString osEName = CSVGetField( pszOziEllipse, "ELLIPSOID_CODE", osEllipseCode, CC_ApproxString, "NAME" ); if( strlen(osEName) == 0 ) { CPLError( CE_Failure, CPLE_AppDefined, "Failed to find ellipsoid %s in ozi_ellips.csv.", osEllipseCode.c_str() ); goto other_error; } double dfA = CPLAtof(CSVGetField( pszOziEllipse, "ELLIPSOID_CODE", osEllipseCode, CC_ApproxString, "A" )); double dfInvF = CPLAtof(CSVGetField( pszOziEllipse, "ELLIPSOID_CODE", osEllipseCode, CC_ApproxString, "INVF" )); /* -------------------------------------------------------------------- */ /* Create geographic coordinate system. */ /* -------------------------------------------------------------------- */ SetGeogCS( osDName, osDName, osEName, dfA, dfInvF ); SetTOWGS84( dfDeltaX, dfDeltaY, dfDeltaZ ); } } /* -------------------------------------------------------------------- */ /* Grid units translation */ /* -------------------------------------------------------------------- */ if( IsLocal() || IsProjected() ) SetLinearUnits( SRS_UL_METER, 1.0 ); FixupOrdering(); CSLDestroy(papszProj); CSLDestroy(papszProjParms); CSLDestroy(papszDatum); return OGRERR_NONE; not_enough_data: CSLDestroy(papszProj); CSLDestroy(papszProjParms); CSLDestroy(papszDatum); return OGRERR_NOT_ENOUGH_DATA; other_error: CSLDestroy(papszProj); CSLDestroy(papszProjParms); CSLDestroy(papszDatum); return OGRERR_FAILURE; }
CPLErr VRTRasterBand::XMLInit( CPLXMLNode * psTree, const char *pszVRTPath ) { /* -------------------------------------------------------------------- */ /* Validate a bit. */ /* -------------------------------------------------------------------- */ if( psTree == NULL || psTree->eType != CXT_Element || !EQUAL(psTree->pszValue,"VRTRasterBand") ) { CPLError( CE_Failure, CPLE_AppDefined, "Invalid node passed to VRTRasterBand::XMLInit()." ); return CE_Failure; } /* -------------------------------------------------------------------- */ /* Set the band if provided as an attribute. */ /* -------------------------------------------------------------------- */ const char* pszBand = CPLGetXMLValue( psTree, "band", NULL); if( pszBand != NULL ) { nBand = atoi(pszBand); } /* -------------------------------------------------------------------- */ /* Set the band if provided as an attribute. */ /* -------------------------------------------------------------------- */ const char *pszDataType = CPLGetXMLValue( psTree, "dataType", NULL); if( pszDataType != NULL ) { eDataType = GDALGetDataTypeByName(pszDataType); } /* -------------------------------------------------------------------- */ /* Apply any band level metadata. */ /* -------------------------------------------------------------------- */ oMDMD.XMLInit( psTree, TRUE ); /* -------------------------------------------------------------------- */ /* Collect various other items of metadata. */ /* -------------------------------------------------------------------- */ SetDescription( CPLGetXMLValue( psTree, "Description", "" ) ); if( CPLGetXMLValue( psTree, "NoDataValue", NULL ) != NULL ) SetNoDataValue( CPLAtofM(CPLGetXMLValue( psTree, "NoDataValue", "0" )) ); if( CPLGetXMLValue( psTree, "HideNoDataValue", NULL ) != NULL ) bHideNoDataValue = CSLTestBoolean( CPLGetXMLValue( psTree, "HideNoDataValue", "0" ) ); SetUnitType( CPLGetXMLValue( psTree, "UnitType", NULL ) ); SetOffset( atof(CPLGetXMLValue( psTree, "Offset", "0.0" )) ); SetScale( atof(CPLGetXMLValue( psTree, "Scale", "1.0" )) ); if( CPLGetXMLValue( psTree, "ColorInterp", NULL ) != NULL ) { const char *pszInterp = CPLGetXMLValue( psTree, "ColorInterp", NULL ); SetColorInterpretation(GDALGetColorInterpretationByName(pszInterp)); } /* -------------------------------------------------------------------- */ /* Category names. */ /* -------------------------------------------------------------------- */ if( CPLGetXMLNode( psTree, "CategoryNames" ) != NULL ) { CPLXMLNode *psEntry; CSLDestroy( papszCategoryNames ); papszCategoryNames = NULL; CPLStringList oCategoryNames; for( psEntry = CPLGetXMLNode( psTree, "CategoryNames" )->psChild; psEntry != NULL; psEntry = psEntry->psNext ) { if( psEntry->eType != CXT_Element || !EQUAL(psEntry->pszValue,"Category") || (psEntry->psChild != NULL && psEntry->psChild->eType != CXT_Text) ) continue; oCategoryNames.AddString( (psEntry->psChild) ? psEntry->psChild->pszValue : ""); } papszCategoryNames = oCategoryNames.StealList(); } /* -------------------------------------------------------------------- */ /* Collect a color table. */ /* -------------------------------------------------------------------- */ if( CPLGetXMLNode( psTree, "ColorTable" ) != NULL ) { CPLXMLNode *psEntry; GDALColorTable oTable; int iEntry = 0; for( psEntry = CPLGetXMLNode( psTree, "ColorTable" )->psChild; psEntry != NULL; psEntry = psEntry->psNext ) { GDALColorEntry sCEntry; sCEntry.c1 = (short) atoi(CPLGetXMLValue( psEntry, "c1", "0" )); sCEntry.c2 = (short) atoi(CPLGetXMLValue( psEntry, "c2", "0" )); sCEntry.c3 = (short) atoi(CPLGetXMLValue( psEntry, "c3", "0" )); sCEntry.c4 = (short) atoi(CPLGetXMLValue( psEntry, "c4", "255" )); oTable.SetColorEntry( iEntry++, &sCEntry ); } SetColorTable( &oTable ); } /* -------------------------------------------------------------------- */ /* Histograms */ /* -------------------------------------------------------------------- */ CPLXMLNode *psHist = CPLGetXMLNode( psTree, "Histograms" ); if( psHist != NULL ) { CPLXMLNode *psNext = psHist->psNext; psHist->psNext = NULL; psSavedHistograms = CPLCloneXMLTree( psHist ); psHist->psNext = psNext; } /* ==================================================================== */ /* Overviews */ /* ==================================================================== */ CPLXMLNode *psNode; for( psNode = psTree->psChild; psNode != NULL; psNode = psNode->psNext ) { if( psNode->eType != CXT_Element || !EQUAL(psNode->pszValue,"Overview") ) continue; /* -------------------------------------------------------------------- */ /* Prepare filename. */ /* -------------------------------------------------------------------- */ char *pszSrcDSName = NULL; CPLXMLNode* psFileNameNode=CPLGetXMLNode(psNode,"SourceFilename"); const char *pszFilename = psFileNameNode ? CPLGetXMLValue(psFileNameNode,NULL, NULL) : NULL; if( pszFilename == NULL ) { CPLError( CE_Warning, CPLE_AppDefined, "Missing <SourceFilename> element in Overview." ); return CE_Failure; } if (EQUALN(pszFilename, "MEM:::", 6) && pszVRTPath != NULL && !CSLTestBoolean(CPLGetConfigOption("VRT_ALLOW_MEM_DRIVER", "NO"))) { CPLError( CE_Failure, CPLE_AppDefined, "<SourceFilename> points to a MEM dataset, which is rather suspect! " "If you know what you are doing, define the VRT_ALLOW_MEM_DRIVER configuration option to YES" ); return CE_Failure; } if( pszVRTPath != NULL && atoi(CPLGetXMLValue( psFileNameNode, "relativetoVRT", "0")) ) { pszSrcDSName = CPLStrdup( CPLProjectRelativeFilename( pszVRTPath, pszFilename ) ); } else pszSrcDSName = CPLStrdup( pszFilename ); /* -------------------------------------------------------------------- */ /* Get the raster band. */ /* -------------------------------------------------------------------- */ int nSrcBand = atoi(CPLGetXMLValue(psNode,"SourceBand","1")); apoOverviews.resize( apoOverviews.size() + 1 ); apoOverviews[apoOverviews.size()-1].osFilename = pszSrcDSName; apoOverviews[apoOverviews.size()-1].nBand = nSrcBand; CPLFree( pszSrcDSName ); } /* ==================================================================== */ /* Mask band (specific to that raster band) */ /* ==================================================================== */ CPLXMLNode* psMaskBandNode = CPLGetXMLNode(psTree, "MaskBand"); if (psMaskBandNode) psNode = psMaskBandNode->psChild; else psNode = NULL; for( ; psNode != NULL; psNode = psNode->psNext ) { if( psNode->eType != CXT_Element || !EQUAL(psNode->pszValue,"VRTRasterBand") ) continue; if( ((VRTDataset*)poDS)->poMaskBand != NULL) { CPLError( CE_Warning, CPLE_AppDefined, "Illegal mask band at raster band level when a dataset mask band already exists." ); break; } const char *pszSubclass = CPLGetXMLValue( psNode, "subclass", "VRTSourcedRasterBand" ); VRTRasterBand *poBand = NULL; if( EQUAL(pszSubclass,"VRTSourcedRasterBand") ) poBand = new VRTSourcedRasterBand( GetDataset(), 0 ); else if( EQUAL(pszSubclass, "VRTDerivedRasterBand") ) poBand = new VRTDerivedRasterBand( GetDataset(), 0 ); else if( EQUAL(pszSubclass, "VRTRawRasterBand") ) poBand = new VRTRawRasterBand( GetDataset(), 0 ); else if( EQUAL(pszSubclass, "VRTWarpedRasterBand") ) poBand = new VRTWarpedRasterBand( GetDataset(), 0 ); else { CPLError( CE_Failure, CPLE_AppDefined, "VRTRasterBand of unrecognised subclass '%s'.", pszSubclass ); break; } if( poBand->XMLInit( psNode, pszVRTPath ) == CE_None ) { SetMaskBand(poBand); } break; } return CE_None; }
int AAIGDataset::ParseHeader(const char *pszHeader, const char *pszDataType) { char **papszTokens = CSLTokenizeString2(pszHeader, " \n\r\t", 0); const int nTokens = CSLCount(papszTokens); int i = 0; if ( (i = CSLFindString(papszTokens, "ncols")) < 0 || i + 1 >= nTokens) { CSLDestroy(papszTokens); return FALSE; } nRasterXSize = atoi(papszTokens[i + 1]); if ( (i = CSLFindString(papszTokens, "nrows")) < 0 || i + 1 >= nTokens) { CSLDestroy(papszTokens); return FALSE; } nRasterYSize = atoi(papszTokens[i + 1]); if (!GDALCheckDatasetDimensions(nRasterXSize, nRasterYSize)) { CSLDestroy(papszTokens); return FALSE; } // TODO(schwehr): Would be good to also factor the file size into the max. // TODO(schwehr): Allow the user to disable this check. // The driver allocates a panLineOffset array based on nRasterYSize constexpr int kMaxDimSize = 10000000; // 1e7 cells. if (nRasterXSize > kMaxDimSize || nRasterYSize > kMaxDimSize) { CSLDestroy(papszTokens); return FALSE; } double dfCellDX = 0.0; double dfCellDY = 0.0; if ( (i = CSLFindString(papszTokens, "cellsize")) < 0 ) { int iDX, iDY; if( (iDX = CSLFindString(papszTokens, "dx")) < 0 || (iDY = CSLFindString(papszTokens, "dy")) < 0 || iDX + 1 >= nTokens || iDY + 1 >= nTokens ) { CSLDestroy(papszTokens); return FALSE; } dfCellDX = CPLAtofM(papszTokens[iDX + 1]); dfCellDY = CPLAtofM(papszTokens[iDY + 1]); } else { if (i + 1 >= nTokens) { CSLDestroy(papszTokens); return FALSE; } dfCellDY = CPLAtofM(papszTokens[i + 1]); dfCellDX = dfCellDY; } int j = 0; if ((i = CSLFindString(papszTokens, "xllcorner")) >= 0 && (j = CSLFindString(papszTokens, "yllcorner")) >= 0 && i + 1 < nTokens && j + 1 < nTokens) { adfGeoTransform[0] = CPLAtofM(papszTokens[i + 1]); // Small hack to compensate from insufficient precision in cellsize // parameter in datasets of // http://ccafs-climate.org/data/A2a_2020s/hccpr_hadcm3 if ((nRasterXSize % 360) == 0 && fabs(adfGeoTransform[0] - (-180.0)) < 1e-12 && dfCellDX == dfCellDY && fabs(dfCellDX - (360.0 / nRasterXSize)) < 1e-9) { dfCellDY = 360.0 / nRasterXSize; dfCellDX = dfCellDY; } adfGeoTransform[1] = dfCellDX; adfGeoTransform[2] = 0.0; adfGeoTransform[3] = CPLAtofM(papszTokens[j + 1]) + nRasterYSize * dfCellDY; adfGeoTransform[4] = 0.0; adfGeoTransform[5] = -dfCellDY; } else if ((i = CSLFindString(papszTokens, "xllcenter")) >= 0 && (j = CSLFindString(papszTokens, "yllcenter")) >= 0 && i + 1 < nTokens && j + 1 < nTokens) { SetMetadataItem(GDALMD_AREA_OR_POINT, GDALMD_AOP_POINT); adfGeoTransform[0] = CPLAtofM(papszTokens[i + 1]) - 0.5 * dfCellDX; adfGeoTransform[1] = dfCellDX; adfGeoTransform[2] = 0.0; adfGeoTransform[3] = CPLAtofM(papszTokens[j + 1]) - 0.5 * dfCellDY + nRasterYSize * dfCellDY; adfGeoTransform[4] = 0.0; adfGeoTransform[5] = -dfCellDY; } else { adfGeoTransform[0] = 0.0; adfGeoTransform[1] = dfCellDX; adfGeoTransform[2] = 0.0; adfGeoTransform[3] = 0.0; adfGeoTransform[4] = 0.0; adfGeoTransform[5] = -dfCellDY; } if( (i = CSLFindString( papszTokens, "NODATA_value" )) >= 0 && i + 1 < nTokens) { const char *pszNoData = papszTokens[i + 1]; bNoDataSet = true; dfNoDataValue = CPLAtofM(pszNoData); if( pszDataType == nullptr && (strchr(pszNoData, '.') != nullptr || strchr(pszNoData, ',') != nullptr || std::numeric_limits<int>::min() > dfNoDataValue || dfNoDataValue > std::numeric_limits<int>::max()) ) { eDataType = GDT_Float32; if( !CPLIsInf(dfNoDataValue) && (fabs(dfNoDataValue) < std::numeric_limits<float>::min() || fabs(dfNoDataValue) > std::numeric_limits<float>::max()) ) { eDataType = GDT_Float64; } } if( eDataType == GDT_Float32 ) { dfNoDataValue = MapNoDataToFloat(dfNoDataValue); } } CSLDestroy(papszTokens); return TRUE; }
GDALDataset *ISIS3Dataset::Open( GDALOpenInfo * poOpenInfo ) { /* -------------------------------------------------------------------- */ /* Does this look like a CUBE dataset? */ /* -------------------------------------------------------------------- */ if( !Identify( poOpenInfo ) ) return NULL; /* -------------------------------------------------------------------- */ /* Open the file using the large file API. */ /* -------------------------------------------------------------------- */ VSILFILE *fpQube = VSIFOpenL( poOpenInfo->pszFilename, "rb" ); if( fpQube == NULL ) return NULL; ISIS3Dataset *poDS; poDS = new ISIS3Dataset(); if( ! poDS->oKeywords.Ingest( fpQube, 0 ) ) { VSIFCloseL( fpQube ); delete poDS; return NULL; } VSIFCloseL( fpQube ); /* -------------------------------------------------------------------- */ /* Assume user is pointing to label (ie .lbl) file for detached option */ /* -------------------------------------------------------------------- */ // Image can be inline or detached and point to an image name // the Format can be Tiled or Raw // Object = Core // StartByte = 65537 // Format = Tile // TileSamples = 128 // TileLines = 128 //OR----- // Object = Core // StartByte = 1 // ^Core = r0200357_detatched.cub // Format = BandSequential //OR----- // Object = Core // StartByte = 1 // ^Core = r0200357_detached_tiled.cub // Format = Tile // TileSamples = 128 // TileLines = 128 /* -------------------------------------------------------------------- */ /* What file contains the actual data? */ /* -------------------------------------------------------------------- */ const char *pszCore = poDS->GetKeyword( "IsisCube.Core.^Core" ); CPLString osQubeFile; if( EQUAL(pszCore,"") ) osQubeFile = poOpenInfo->pszFilename; else { CPLString osPath = CPLGetPath( poOpenInfo->pszFilename ); osQubeFile = CPLFormFilename( osPath, pszCore, NULL ); poDS->osExternalCube = osQubeFile; } /* -------------------------------------------------------------------- */ /* Check if file an ISIS3 header file? Read a few lines of text */ /* searching for something starting with nrows or ncols. */ /* -------------------------------------------------------------------- */ GDALDataType eDataType = GDT_Byte; OGRSpatialReference oSRS; int nRows = -1; int nCols = -1; int nBands = 1; int nSkipBytes = 0; int tileSizeX = 0; int tileSizeY = 0; double dfULXMap=0.5; double dfULYMap = 0.5; double dfXDim = 1.0; double dfYDim = 1.0; double scaleFactor = 1.0; double dfNoData = 0.0; int bNoDataSet = FALSE; char chByteOrder = 'M'; //default to MSB char szLayout[32] = "BandSequential"; //default to band seq. const char *target_name; //planet name //projection parameters const char *map_proj_name; int bProjectionSet = TRUE; char proj_target_name[200]; char geog_name[60]; char datum_name[60]; char sphere_name[60]; char bIsGeographic = TRUE; double semi_major = 0.0; double semi_minor = 0.0; double iflattening = 0.0; float center_lat = 0.0; float center_lon = 0.0; float first_std_parallel = 0.0; float second_std_parallel = 0.0; double radLat, localRadius; VSILFILE *fp; /************* Skipbytes *****************************/ nSkipBytes = atoi(poDS->GetKeyword("IsisCube.Core.StartByte","")) - 1; /******* Grab format type (BandSequential, Tiled) *******/ const char *value; value = poDS->GetKeyword( "IsisCube.Core.Format", "" ); if (EQUAL(value,"Tile") ) { //Todo strcpy(szLayout,"Tiled"); /******* Get Tile Sizes *********/ tileSizeX = atoi(poDS->GetKeyword("IsisCube.Core.TileSamples","")); tileSizeY = atoi(poDS->GetKeyword("IsisCube.Core.TileLines","")); if (tileSizeX <= 0 || tileSizeY <= 0) { CPLError( CE_Failure, CPLE_OpenFailed, "Wrong tile dimensions : %d x %d", tileSizeX, tileSizeY); delete poDS; return NULL; } } else if (EQUAL(value,"BandSequential") ) strcpy(szLayout,"BSQ"); else { CPLError( CE_Failure, CPLE_OpenFailed, "%s layout not supported. Abort\n\n", value); delete poDS; return NULL; } /*********** Grab samples lines band ************/ nCols = atoi(poDS->GetKeyword("IsisCube.Core.Dimensions.Samples","")); nRows = atoi(poDS->GetKeyword("IsisCube.Core.Dimensions.Lines","")); nBands = atoi(poDS->GetKeyword("IsisCube.Core.Dimensions.Bands","")); /****** Grab format type - ISIS3 only supports 8,U16,S16,32 *****/ const char *itype; itype = poDS->GetKeyword( "IsisCube.Core.Pixels.Type" ); if (EQUAL(itype,"UnsignedByte") ) { eDataType = GDT_Byte; dfNoData = NULL1; bNoDataSet = TRUE; } else if (EQUAL(itype,"UnsignedWord") ) { eDataType = GDT_UInt16; dfNoData = NULL1; bNoDataSet = TRUE; } else if (EQUAL(itype,"SignedWord") ) { eDataType = GDT_Int16; dfNoData = NULL2; bNoDataSet = TRUE; } else if (EQUAL(itype,"Real") || EQUAL(value,"") ) { eDataType = GDT_Float32; dfNoData = NULL3; bNoDataSet = TRUE; } else { CPLError( CE_Failure, CPLE_OpenFailed, "%s layout type not supported. Abort\n\n", itype); delete poDS; return NULL; } /*********** Grab samples lines band ************/ value = poDS->GetKeyword( "IsisCube.Core.Pixels.ByteOrder"); if (EQUAL(value,"Lsb")) chByteOrder = 'I'; /*********** Grab Cellsize ************/ value = poDS->GetKeyword("IsisCube.Mapping.PixelResolution"); if (strlen(value) > 0 ) { dfXDim = atof(value); /* values are in meters */ dfYDim = -atof(value); } /*********** Grab UpperLeftCornerY ************/ value = poDS->GetKeyword("IsisCube.Mapping.UpperLeftCornerY"); if (strlen(value) > 0) { dfULYMap = atof(value); } /*********** Grab UpperLeftCornerX ************/ value = poDS->GetKeyword("IsisCube.Mapping.UpperLeftCornerX"); if( strlen(value) > 0 ) { dfULXMap = atof(value); } /*********** Grab TARGET_NAME ************/ /**** This is the planets name i.e. Mars ***/ target_name = poDS->GetKeyword("IsisCube.Mapping.TargetName"); /*********** Grab MAP_PROJECTION_TYPE ************/ map_proj_name = poDS->GetKeyword( "IsisCube.Mapping.ProjectionName"); /*********** Grab SEMI-MAJOR ************/ semi_major = atof(poDS->GetKeyword( "IsisCube.Mapping.EquatorialRadius")); /*********** Grab semi-minor ************/ semi_minor = atof(poDS->GetKeyword( "IsisCube.Mapping.PolarRadius")); /*********** Grab CENTER_LAT ************/ center_lat = atof(poDS->GetKeyword( "IsisCube.Mapping.CenterLatitude")); /*********** Grab CENTER_LON ************/ center_lon = atof(poDS->GetKeyword( "IsisCube.Mapping.CenterLongitude")); /*********** Grab 1st std parallel ************/ first_std_parallel = atof(poDS->GetKeyword( "IsisCube.Mapping.FirstStandardParallel")); /*********** Grab 2nd std parallel ************/ second_std_parallel = atof(poDS->GetKeyword( "IsisCube.Mapping.SecondStandardParallel")); /*********** Grab scaleFactor ************/ scaleFactor = atof(poDS->GetKeyword( "IsisCube.Mapping.scaleFactor")); /*** grab LatitudeType = Planetographic ****/ // Need to further study how ocentric/ographic will effect the gdal library // So far we will use this fact to define a sphere or ellipse for some // projections // Frank - may need to talk this over value = poDS->GetKeyword("IsisCube.Mapping.LatitudeType"); if (EQUAL( value, "\"Planetocentric\"" )) bIsGeographic = FALSE; //Set oSRS projection and parameters //############################################################ //ISIS3 Projection types // Equirectangular // LambertConformal // Mercator // ObliqueCylindrical //Todo // Orthographic // PolarStereographic // SimpleCylindrical // Sinusoidal // TransverseMercator #ifdef DEBUG CPLDebug( "ISIS3", "using projection %s", map_proj_name); #endif if ((EQUAL( map_proj_name, "Equirectangular" )) || (EQUAL( map_proj_name, "SimpleCylindrical" )) ) { oSRS.OGRSpatialReference::SetEquirectangular2 ( 0.0, center_lon, center_lat, 0, 0 ); } else if (EQUAL( map_proj_name, "Orthographic" )) { oSRS.OGRSpatialReference::SetOrthographic ( center_lat, center_lon, 0, 0 ); } else if (EQUAL( map_proj_name, "Sinusoidal" )) { oSRS.OGRSpatialReference::SetSinusoidal ( center_lon, 0, 0 ); } else if (EQUAL( map_proj_name, "Mercator" )) { oSRS.OGRSpatialReference::SetMercator ( center_lat, center_lon, scaleFactor, 0, 0 ); } else if (EQUAL( map_proj_name, "PolarStereographic" )) { oSRS.OGRSpatialReference::SetPS ( center_lat, center_lon, scaleFactor, 0, 0 ); } else if (EQUAL( map_proj_name, "TransverseMercator" )) { oSRS.OGRSpatialReference::SetTM ( center_lat, center_lon, scaleFactor, 0, 0 ); } else if (EQUAL( map_proj_name, "LambertConformal" )) { oSRS.OGRSpatialReference::SetLCC ( first_std_parallel, second_std_parallel, center_lat, center_lon, 0, 0 ); } else { CPLDebug( "ISIS3", "Dataset projection %s is not supported. Continuing...", map_proj_name ); bProjectionSet = FALSE; } if (bProjectionSet) { //Create projection name, i.e. MERCATOR MARS and set as ProjCS keyword strcpy(proj_target_name, map_proj_name); strcat(proj_target_name, " "); strcat(proj_target_name, target_name); oSRS.SetProjCS(proj_target_name); //set ProjCS keyword //The geographic/geocentric name will be the same basic name as the body name //'GCS' = Geographic/Geocentric Coordinate System strcpy(geog_name, "GCS_"); strcat(geog_name, target_name); //The datum name will be the same basic name as the planet strcpy(datum_name, "D_"); strcat(datum_name, target_name); strcpy(sphere_name, target_name); //strcat(sphere_name, "_IAU_IAG"); //Might not be IAU defined so don't add //calculate inverse flattening from major and minor axis: 1/f = a/(a-b) if ((semi_major - semi_minor) < 0.0000001) iflattening = 0; else iflattening = semi_major / (semi_major - semi_minor); //Set the body size but take into consideration which proj is being used to help w/ proj4 compatibility //The use of a Sphere, polar radius or ellipse here is based on how ISIS does it internally if ( ( (EQUAL( map_proj_name, "Stereographic" ) && (fabs(center_lat) == 90)) ) || (EQUAL( map_proj_name, "PolarStereographic" )) ) { if (bIsGeographic) { //Geograpraphic, so set an ellipse oSRS.SetGeogCS( geog_name, datum_name, sphere_name, semi_major, iflattening, "Reference_Meridian", 0.0 ); } else { //Geocentric, so force a sphere using the semi-minor axis. I hope... strcat(sphere_name, "_polarRadius"); oSRS.SetGeogCS( geog_name, datum_name, sphere_name, semi_minor, 0.0, "Reference_Meridian", 0.0 ); } } else if ( (EQUAL( map_proj_name, "SimpleCylindrical" )) || (EQUAL( map_proj_name, "Orthographic" )) || (EQUAL( map_proj_name, "Stereographic" )) || (EQUAL( map_proj_name, "Sinusoidal" )) ) { //isis uses the sphereical equation for these projections so force a sphere oSRS.SetGeogCS( geog_name, datum_name, sphere_name, semi_major, 0.0, "Reference_Meridian", 0.0 ); } else if (EQUAL( map_proj_name, "Equirectangular" )) { //Calculate localRadius using ISIS3 simple elliptical method // not the more standard Radius of Curvature method //PI = 4 * atan(1); radLat = center_lat * PI / 180; // in radians localRadius = semi_major * semi_minor / sqrt(pow(semi_minor*cos(radLat),2) + pow(semi_major*sin(radLat),2) ); strcat(sphere_name, "_localRadius"); oSRS.SetGeogCS( geog_name, datum_name, sphere_name, localRadius, 0.0, "Reference_Meridian", 0.0 ); } else { //All other projections: Mercator, Transverse Mercator, Lambert Conformal, etc. //Geographic, so set an ellipse if (bIsGeographic) { oSRS.SetGeogCS( geog_name, datum_name, sphere_name, semi_major, iflattening, "Reference_Meridian", 0.0 ); } else { //Geocentric, so force a sphere. I hope... oSRS.SetGeogCS( geog_name, datum_name, sphere_name, semi_major, 0.0, "Reference_Meridian", 0.0 ); } } // translate back into a projection string. char *pszResult = NULL; oSRS.exportToWkt( &pszResult ); poDS->osProjection = pszResult; CPLFree( pszResult ); } /* END ISIS3 Label Read */ /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ /* -------------------------------------------------------------------- */ /* Is the CUB detached - if so, reset name to binary file? */ /* -------------------------------------------------------------------- */ #ifdef notdef // Frank - is this correct? //The extension already added on so don't add another. But is this needed? char *pszPath = CPLStrdup( CPLGetPath( poOpenInfo->pszFilename ) ); char *pszName = CPLStrdup( CPLGetBasename( poOpenInfo->pszFilename ) ); if (bIsDetached) pszCUBFilename = CPLFormCIFilename( pszPath, detachedCub, "" ); #endif /* -------------------------------------------------------------------- */ /* Did we get the required keywords? If not we return with */ /* this never having been considered to be a match. This isn't */ /* an error! */ /* -------------------------------------------------------------------- */ if( nRows < 1 || nCols < 1 || nBands < 1 ) { delete poDS; return NULL; } /* -------------------------------------------------------------------- */ /* Capture some information from the file that is of interest. */ /* -------------------------------------------------------------------- */ poDS->nRasterXSize = nCols; poDS->nRasterYSize = nRows; /* -------------------------------------------------------------------- */ /* Open target binary file. */ /* -------------------------------------------------------------------- */ if( poOpenInfo->eAccess == GA_ReadOnly ) poDS->fpImage = VSIFOpenL( osQubeFile, "r" ); else poDS->fpImage = VSIFOpenL( osQubeFile, "r+" ); if( poDS->fpImage == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Failed to open %s with write permission.\n%s", osQubeFile.c_str(), VSIStrerror( errno ) ); delete poDS; return NULL; } poDS->eAccess = poOpenInfo->eAccess; /* -------------------------------------------------------------------- */ /* Compute the line offset. */ /* -------------------------------------------------------------------- */ int nItemSize = GDALGetDataTypeSize(eDataType)/8; int nLineOffset=0, nPixelOffset=0, nBandOffset=0; if( EQUAL(szLayout,"BSQ") ) { nPixelOffset = nItemSize; nLineOffset = nPixelOffset * nCols; nBandOffset = nLineOffset * nRows; } else /* Tiled */ { } /* -------------------------------------------------------------------- */ /* Create band information objects. */ /* -------------------------------------------------------------------- */ int i; #ifdef CPL_LSB int bNativeOrder = !(chByteOrder == 'M'); #else int bNativeOrder = (chByteOrder == 'M'); #endif for( i = 0; i < nBands; i++ ) { GDALRasterBand *poBand; if( EQUAL(szLayout,"Tiled") ) { poBand = new ISISTiledBand( poDS, poDS->fpImage, i+1, eDataType, tileSizeX, tileSizeY, nSkipBytes, 0, 0, bNativeOrder ); } else { poBand = new RawRasterBand( poDS, i+1, poDS->fpImage, nSkipBytes + nBandOffset * i, nPixelOffset, nLineOffset, eDataType, #ifdef CPL_LSB chByteOrder == 'I' || chByteOrder == 'L', #else chByteOrder == 'M', #endif TRUE ); } poDS->SetBand( i+1, poBand ); if( bNoDataSet ) ((GDALPamRasterBand *) poBand)->SetNoDataValue( dfNoData ); // Set offset/scale values at the PAM level. poBand->SetOffset( CPLAtofM(poDS->GetKeyword("IsisCube.Core.Pixels.Base","0.0"))); poBand->SetScale( CPLAtofM(poDS->GetKeyword("IsisCube.Core.Pixels.Multiplier","1.0"))); } /* -------------------------------------------------------------------- */ /* Check for a .prj file. For ISIS3 I would like to keep this in */ /* -------------------------------------------------------------------- */ CPLString osPath, osName; osPath = CPLGetPath( poOpenInfo->pszFilename ); osName = CPLGetBasename(poOpenInfo->pszFilename); const char *pszPrjFile = CPLFormCIFilename( osPath, osName, "prj" ); fp = VSIFOpenL( pszPrjFile, "r" ); if( fp != NULL ) { char **papszLines; OGRSpatialReference oSRS; VSIFCloseL( fp ); papszLines = CSLLoad( pszPrjFile ); if( oSRS.importFromESRI( papszLines ) == OGRERR_NONE ) { char *pszResult = NULL; oSRS.exportToWkt( &pszResult ); poDS->osProjection = pszResult; CPLFree( pszResult ); } CSLDestroy( papszLines ); } if( dfULYMap != 0.5 || dfULYMap != 0.5 || dfXDim != 1.0 || dfYDim != 1.0 ) { poDS->bGotTransform = TRUE; poDS->adfGeoTransform[0] = dfULXMap; poDS->adfGeoTransform[1] = dfXDim; poDS->adfGeoTransform[2] = 0.0; poDS->adfGeoTransform[3] = dfULYMap; poDS->adfGeoTransform[4] = 0.0; poDS->adfGeoTransform[5] = dfYDim; } if( !poDS->bGotTransform ) poDS->bGotTransform = GDALReadWorldFile( poOpenInfo->pszFilename, "cbw", poDS->adfGeoTransform ); if( !poDS->bGotTransform ) poDS->bGotTransform = GDALReadWorldFile( poOpenInfo->pszFilename, "wld", poDS->adfGeoTransform ); /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->SetDescription( poOpenInfo->pszFilename ); poDS->TryLoadXML(); /* -------------------------------------------------------------------- */ /* Check for overviews. */ /* -------------------------------------------------------------------- */ poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename ); return( poDS ); }
/** * LoadMetadata() */ void GDALMDReaderLandsat::LoadMetadata() { if(m_bIsMetadataLoad) return; if (!m_osIMDSourceFilename.empty()) { m_papszIMDMD = GDALLoadIMDFile( m_osIMDSourceFilename ); } m_papszDEFAULTMD = CSLAddNameValue(m_papszDEFAULTMD, MD_NAME_MDTYPE, "ODL"); m_bIsMetadataLoad = true; // date/time // DATE_ACQUIRED = 2013-04-07 // SCENE_CENTER_TIME = 15:47:03.0882620Z // L1_METADATA_FILE.PRODUCT_METADATA.SPACECRAFT_ID const char* pszSatId = CSLFetchNameValue(m_papszIMDMD, "L1_METADATA_FILE.PRODUCT_METADATA.SPACECRAFT_ID"); if(NULL != pszSatId) { m_papszIMAGERYMD = CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_SATELLITE, CPLStripQuotes(pszSatId)); } // L1_METADATA_FILE.IMAGE_ATTRIBUTES.CLOUD_COVER const char* pszCloudCover = CSLFetchNameValue(m_papszIMDMD, "L1_METADATA_FILE.IMAGE_ATTRIBUTES.CLOUD_COVER"); if(NULL != pszCloudCover) { double fCC = CPLAtofM(pszCloudCover); if(fCC < 0) { m_papszIMAGERYMD = CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_CLOUDCOVER, MD_CLOUDCOVER_NA); } else { m_papszIMAGERYMD = CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_CLOUDCOVER, CPLSPrintf("%d", int(fCC))); } } // L1_METADATA_FILE.PRODUCT_METADATA.ACQUISITION_DATE // L1_METADATA_FILE.PRODUCT_METADATA.SCENE_CENTER_SCAN_TIME // L1_METADATA_FILE.PRODUCT_METADATA.DATE_ACQUIRED // L1_METADATA_FILE.PRODUCT_METADATA.SCENE_CENTER_TIME const char* pszDate = CSLFetchNameValue(m_papszIMDMD, "L1_METADATA_FILE.PRODUCT_METADATA.ACQUISITION_DATE"); if(NULL == pszDate) { pszDate = CSLFetchNameValue(m_papszIMDMD, "L1_METADATA_FILE.PRODUCT_METADATA.DATE_ACQUIRED"); } if(NULL != pszDate) { const char* pszTime = CSLFetchNameValue(m_papszIMDMD, "L1_METADATA_FILE.PRODUCT_METADATA.SCENE_CENTER_SCAN_TIME"); if(NULL == pszTime) { pszTime = CSLFetchNameValue(m_papszIMDMD, "L1_METADATA_FILE.PRODUCT_METADATA.SCENE_CENTER_TIME"); } if(NULL == pszTime) pszTime = "00:00:00.000000Z"; char buffer[80]; time_t timeMid = GetAcquisitionTimeFromString(CPLSPrintf( "%sT%s", pszDate, pszTime)); strftime (buffer, 80, MD_DATETIMEFORMAT, localtime(&timeMid)); m_papszIMAGERYMD = CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_ACQDATETIME, buffer); } }
CPLErr XYZRasterBand::IReadBlock( int nBlockXOff, int nBlockYOff, void * pImage ) { XYZDataset *poGDS = (XYZDataset *) poDS; if (poGDS->fp == NULL) return CE_Failure; int nLineInFile = nBlockYOff * nBlockXSize; if (poGDS->nDataLineNum > nLineInFile) { poGDS->nDataLineNum = 0; VSIFSeekL(poGDS->fp, 0, SEEK_SET); for(int i=0;i<poGDS->nCommentLineCount;i++) CPLReadLine2L(poGDS->fp, 100, NULL); if (poGDS->bHasHeaderLine) { const char* pszLine = CPLReadLine2L(poGDS->fp, 100, 0); if (pszLine == NULL) { memset(pImage, 0, nBlockXSize * (GDALGetDataTypeSize(eDataType) / 8)); return CE_Failure; } poGDS->nLineNum ++; } } while(poGDS->nDataLineNum < nLineInFile) { const char* pszLine = CPLReadLine2L(poGDS->fp, 100, 0); if (pszLine == NULL) { memset(pImage, 0, nBlockXSize * (GDALGetDataTypeSize(eDataType) / 8)); return CE_Failure; } poGDS->nLineNum ++; const char* pszPtr = pszLine; char ch; int nCol = 0; int bLastWasSep = TRUE; while((ch = *pszPtr) != '\0') { if (ch == ' ' || ch == ',' || ch == '\t' || ch == ';') { if (!bLastWasSep) nCol ++; bLastWasSep = TRUE; } else { bLastWasSep = FALSE; } pszPtr ++; } /* Skip empty line */ if (nCol == 0 && bLastWasSep) continue; poGDS->nDataLineNum ++; } int i; for(i=0;i<nBlockXSize;i++) { int nCol; int bLastWasSep; do { const char* pszLine = CPLReadLine2L(poGDS->fp, 100, 0); if (pszLine == NULL) { memset(pImage, 0, nBlockXSize * (GDALGetDataTypeSize(eDataType) / 8)); return CE_Failure; } poGDS->nLineNum ++; const char* pszPtr = pszLine; char ch; nCol = 0; bLastWasSep = TRUE; while((ch = *pszPtr) != '\0') { if (ch == ' ' || ch == ',' || ch == '\t' || ch == ';') { if (!bLastWasSep) nCol ++; bLastWasSep = TRUE; } else { if (bLastWasSep && nCol == poGDS->nZIndex) { double dfZ = CPLAtofM(pszPtr); if (eDataType == GDT_Float32) { ((float*)pImage)[i] = (float)dfZ; } else if (eDataType == GDT_Int32) { ((GInt32*)pImage)[i] = (GInt32)dfZ; } else if (eDataType == GDT_Int16) { ((GInt16*)pImage)[i] = (GInt16)dfZ; } else { ((GByte*)pImage)[i] = (GByte)dfZ; } } bLastWasSep = FALSE; } pszPtr ++; } /* Skip empty line */ } while (nCol == 0 && bLastWasSep); poGDS->nDataLineNum ++; nCol ++; if (nCol < poGDS->nMinTokens) { memset(pImage, 0, nBlockXSize * (GDALGetDataTypeSize(eDataType) / 8)); return CE_Failure; } } CPLAssert(poGDS->nDataLineNum == (nBlockYOff + 1) * nBlockXSize); return CE_None; }
cgrd::CGRDDataset * cgrd::CGRDDataset::Open ( GDALOpenInfo * poOpenInfo ) { char ** papszTokens = NULL; /************************************************************************/ /* Does this look like a grid file? */ /************************************************************************/ if ( poOpenInfo->nHeaderBytes < 100 || ! ( EQUALN ( ( const char * ) poOpenInfo->pabyHeader, "DataMark", 8 ) || EQUALN ( ( const char * ) poOpenInfo->pabyHeader, "Version", 7 ) || EQUALN ( ( const char * ) poOpenInfo->pabyHeader, "Alpha", 5 ) || EQUALN ( ( const char * ) poOpenInfo->pabyHeader, "Compress", 8 ) || EQUALN ( ( const char * ) poOpenInfo->pabyHeader, "X0", 2 ) || EQUALN ( ( const char * ) poOpenInfo->pabyHeader, "Y0", 2 ) || EQUALN ( ( const char * ) poOpenInfo->pabyHeader, "DX", 2 ) || EQUALN ( ( const char * ) poOpenInfo->pabyHeader, "DY", 2 ) || EQUALN ( ( const char * ) poOpenInfo->pabyHeader, "Row", 3 ) || EQUALN ( ( const char * ) poOpenInfo->pabyHeader, "Col", 3 ) || EQUALN ( ( const char * ) poOpenInfo->pabyHeader, "ValueType", 9 ) || EQUALN ( ( const char * ) poOpenInfo->pabyHeader, "Hzoom", 5 ) || EQUALN ( ( const char * ) poOpenInfo->pabyHeader, "XYUnit", 6 ) || EQUALN ( ( const char * ) poOpenInfo->pabyHeader, "ZUnit", 5 ) ) ) { return NULL; } papszTokens = CSLTokenizeString2 ( ( const char * ) poOpenInfo->pabyHeader, ":\n\r\t", 0 ); int nTokens = CSLCount ( papszTokens ); /************************************************************************/ /* Create a corresponding GDALDataset. */ /************************************************************************/ CGRDDataset * poDS = new CGRDDataset(); /************************************************************************/ /* Parse the header. */ /************************************************************************/ double dfCellDX = 0; double dfCellDY = 0; double dfWinULX = 0; double dfWinULY = 0; int bcompress = 0; int nDataType = -1; //char =0 ,integer=1 int XYUnit; //d=0,m=1,other=2 int ZUnit; //d=0,m=1,other=2 int i; if ( ( i = CSLFindString ( papszTokens, "DataMark" ) ) < 0 || i + 1 >= nTokens ) { CSLDestroy ( papszTokens ); delete poDS; return NULL; } if ( ( i = CSLFindString ( papszTokens, "Version" ) ) < 0 || i + 1 >= nTokens ) { CSLDestroy ( papszTokens ); delete poDS; return NULL; } if ( ( i = CSLFindString ( papszTokens, "Alpha" ) ) < 0 || i + 1 >= nTokens ) { CSLDestroy ( papszTokens ); delete poDS; return NULL; } if ( ( i = CSLFindString ( papszTokens, "Compress" ) ) < 0 || i + 1 >= nTokens ) { CSLDestroy ( papszTokens ); delete poDS; return NULL; } bcompress = atoi ( papszTokens[i + 1] ); if ( ( i = CSLFindString ( papszTokens, "X0" ) ) < 0 || i + 1 >= nTokens ) { CSLDestroy ( papszTokens ); delete poDS; return NULL; } dfWinULX = CPLAtofM ( papszTokens[i + 1] ); if ( ( i = CSLFindString ( papszTokens, "Y0" ) ) < 0 || i + 1 >= nTokens ) { CSLDestroy ( papszTokens ); delete poDS; return NULL; } dfWinULY = CPLAtofM ( papszTokens[i + 1] ); if ( ( i = CSLFindString ( papszTokens, "DX" ) ) < 0 || i + 1 >= nTokens ) { CSLDestroy ( papszTokens ); delete poDS; return NULL; } dfCellDX = CPLAtofM ( papszTokens[i + 1] ); if ( ( i = CSLFindString ( papszTokens, "DY" ) ) < 0 || i + 1 >= nTokens ) { CSLDestroy ( papszTokens ); delete poDS; return NULL; } dfCellDY = CPLAtofM ( papszTokens[i + 1] ); if ( ( i = CSLFindString ( papszTokens, "Row" ) ) < 0 || i + 1 >= nTokens ) { CSLDestroy ( papszTokens ); delete poDS; return NULL; } poDS->SetnRasterYSize ( atoi ( papszTokens[i + 1] ) ); if ( ( i = CSLFindString ( papszTokens, "Col" ) ) < 0 || i + 1 >= nTokens ) { CSLDestroy ( papszTokens ); delete poDS; return NULL; } poDS->SetnRasterXSize ( atoi ( papszTokens[i + 1] ) ); poDS->BlockXSize(poDS->GetRasterXSize()); poDS->BlockYSize(1); if ( ( i = CSLFindString ( papszTokens, "ValueType" ) ) < 0 || i + 1 >= nTokens ) { CSLDestroy ( papszTokens ); delete poDS; return NULL; } if ( EQUAL ( papszTokens[i + 1], "Char" ) ) { nDataType = 0; } else if ( EQUAL ( papszTokens[i + 1], "Integer" ) ) { nDataType = 1; } if ( ( i = CSLFindString ( papszTokens, "Hzoom" ) ) < 0 || i + 1 >= nTokens ) { CSLDestroy ( papszTokens ); delete poDS; return NULL; } poDS->SetnHZoom ( atoi ( papszTokens[i + 1] ) ); if ( ( i = CSLFindString ( papszTokens, "XYUnit" ) ) < 0 || i + 1 >= nTokens ) { CSLDestroy ( papszTokens ); delete poDS; return NULL; } if ( EQUAL ( papszTokens[i + 1], "M" ) ) { XYUnit = 1; } else if ( EQUAL ( papszTokens[i + 1], "D" ) ) { XYUnit = 0; } else { XYUnit = 2; } if ( ( i = CSLFindString ( papszTokens, "ZUnit" ) ) < 0 || i + 1 >= nTokens ) { CSLDestroy ( papszTokens ); delete poDS; return NULL; } if ( EQUAL ( papszTokens[i + 1], "M" ) ) { ZUnit = 1; } else if ( EQUAL ( papszTokens[i + 1], "D" ) ) { ZUnit = 0; } else { ZUnit = 2; } poDS->adfGeoTransform[0] = dfWinULX; poDS->adfGeoTransform[1] = dfCellDX; poDS->adfGeoTransform[2] = 0.0; poDS->adfGeoTransform[3] = dfWinULY; poDS->adfGeoTransform[4] = 0.0; poDS->adfGeoTransform[5] = dfCellDY; poDS->bNoDataSet = TRUE; GDALDataType eDataType; if ( poDS->GetnHZoom() >= 100 ) { eDataType = GDT_Float64; } else { eDataType = GDT_Int32; } /************************************************************************/ /* Default nodata value in grd is -9999. You can set by yourself. */ /************************************************************************/ int nodata = -9999; poDS->dfNoDataValue = ( double ) ( nodata / poDS->GetnHZoom() ); /************************************************************************/ /* Open file with large file API. */ /************************************************************************/ poDS->fp = VSIFOpenL ( poOpenInfo->pszFilename, "r" ); if ( poDS->fp == NULL ) { CPLError ( CE_Failure, CPLE_OpenFailed, "VSIFOpenL(%s) failed unexpectedly.", poOpenInfo->pszFilename ); delete poDS; return NULL; } /************************************************************************/ /* Find the start of real data. */ /************************************************************************/ int nStartOfData = 0; for ( int i = 1; TRUE ; i++ ) { if ( poOpenInfo->pabyHeader[i] == '\0' ) { CPLError ( CE_Failure, CPLE_AppDefined, "Couldn't find data values in dem file.\n" ); delete poDS; return NULL; } if ( poOpenInfo->pabyHeader[i - 1] == '\n' || poOpenInfo->pabyHeader[i - 1] == '\r' ) { if ( !isalpha ( poOpenInfo->pabyHeader[i] ) && poOpenInfo->pabyHeader[i] != '\n' && poOpenInfo->pabyHeader[i] != '\r' ) { nStartOfData = i; /* Beginning of real data found. */ break; } } } /************************************************************************/ /* Open file with large file API. */ /************************************************************************/ poDS->fp = VSIFOpenL ( poOpenInfo->pszFilename, "r" ); if ( poDS->fp == NULL ) { CPLError ( CE_Failure, CPLE_OpenFailed, "VSIFOpenL(%s) failed unexpectedly.", poOpenInfo->pszFilename ); delete poDS; return NULL; } /************************************************************************/ /* Create band information objects. */ /************************************************************************/ CGRDRasterBand * poNewBand = new CGRDRasterBand ( poDS, nStartOfData, eDataType ); poDS->SetBand ( poNewBand ); if ( poNewBand->panLineOffset == NULL ) { delete poDS; return NULL; } CSLDestroy ( papszTokens ); return poDS; }
static int ProxyMain( int argc, char ** argv ) { // GDALDatasetH hDataset, hOutDS; // int i; // int nRasterXSize, nRasterYSize; // const char *pszSource=NULL, *pszDest=NULL, *pszFormat = "GTiff"; // GDALDriverH hDriver; // int *panBandList = NULL; /* negative value of panBandList[i] means mask band of ABS(panBandList[i]) */ // int nBandCount = 0, bDefBands = TRUE; // double adfGeoTransform[6]; // GDALDataType eOutputType = GDT_Unknown; // int nOXSize = 0, nOYSize = 0; // char *pszOXSize=NULL, *pszOYSize=NULL; // char **papszCreateOptions = NULL; // int anSrcWin[4], bStrict = FALSE; // const char *pszProjection; // int bScale = FALSE, bHaveScaleSrc = FALSE, bUnscale=FALSE; // double dfScaleSrcMin=0.0, dfScaleSrcMax=255.0; // double dfScaleDstMin=0.0, dfScaleDstMax=255.0; // double dfULX, dfULY, dfLRX, dfLRY; // char **papszMetadataOptions = NULL; // char *pszOutputSRS = NULL; // int bQuiet = FALSE, bGotBounds = FALSE; // GDALProgressFunc pfnProgress = GDALTermProgress; // int nGCPCount = 0; // GDAL_GCP *pasGCPs = NULL; // int iSrcFileArg = -1, iDstFileArg = -1; // int bCopySubDatasets = FALSE; // double adfULLR[4] = { 0,0,0,0 }; // int bSetNoData = FALSE; // int bUnsetNoData = FALSE; // double dfNoDataReal = 0.0; // int nRGBExpand = 0; // int bParsedMaskArgument = FALSE; // int eMaskMode = MASK_AUTO; // int nMaskBand = 0; /* negative value means mask band of ABS(nMaskBand) */ // int bStats = FALSE, bApproxStats = FALSE; // GDALDatasetH hDataset, hOutDS; GDALDataset *hDataset = NULL; GDALDataset *hOutDS = NULL; int i; int nRasterXSize, nRasterYSize; const char *pszSource=NULL, *pszDest=NULL, *pszFormat = "GTiff"; // GDALDriverH hDriver; GDALDriver *hDriver; GDALDataType eOutputType = GDT_Unknown; char **papszCreateOptions = NULL; int bStrict = FALSE; int bQuiet = FALSE; GDALProgressFunc pfnProgress = GDALTermProgress; int iSrcFileArg = -1, iDstFileArg = -1; int bSetNoData = FALSE; int bUnsetNoData = FALSE; double dfNoDataReal = 0.0; GDALRasterBand *inBand = NULL; GDALRasterBand *outBand = NULL; GByte *srcBuffer; double adfGeoTransform[6]; int nRasterCount; int bReplaceIds = FALSE; const char *pszReplaceFilename = NULL; const char *pszReplaceFieldFrom = NULL; const char *pszReplaceFieldTo = NULL; std::map<GByte,GByte> mReplaceTable; /* Check strict compilation and runtime library version as we use C++ API */ if (! GDAL_CHECK_VERSION(argv[0])) exit(1); /* Must process GDAL_SKIP before GDALAllRegister(), but we can't call */ /* GDALGeneralCmdLineProcessor before it needs the drivers to be registered */ /* for the --format or --formats options */ for( i = 1; i < argc; i++ ) { if( EQUAL(argv[i],"--config") && i + 2 < argc && EQUAL(argv[i + 1], "GDAL_SKIP") ) { CPLSetConfigOption( argv[i+1], argv[i+2] ); i += 2; } } /* -------------------------------------------------------------------- */ /* Register standard GDAL drivers, and process generic GDAL */ /* command options. */ /* -------------------------------------------------------------------- */ GDALAllRegister(); argc = GDALGeneralCmdLineProcessor( argc, &argv, 0 ); if( argc < 1 ) exit( -argc ); /* -------------------------------------------------------------------- */ /* Handle command line arguments. */ /* -------------------------------------------------------------------- */ for( i = 1; i < argc; i++ ) { if( EQUAL(argv[i],"-of") && i < argc-1 ) pszFormat = argv[++i]; else if( EQUAL(argv[i],"-q") || EQUAL(argv[i],"-quiet") ) { bQuiet = TRUE; pfnProgress = GDALDummyProgress; } else if( EQUAL(argv[i],"-ot") && i < argc-1 ) { int iType; for( iType = 1; iType < GDT_TypeCount; iType++ ) { if( GDALGetDataTypeName((GDALDataType)iType) != NULL && EQUAL(GDALGetDataTypeName((GDALDataType)iType), argv[i+1]) ) { eOutputType = (GDALDataType) iType; } } if( eOutputType == GDT_Unknown ) { printf( "Unknown output pixel type: %s\n", argv[i+1] ); Usage(); GDALDestroyDriverManager(); exit( 2 ); } i++; } else if( EQUAL(argv[i],"-not_strict") ) bStrict = FALSE; else if( EQUAL(argv[i],"-strict") ) bStrict = TRUE; else if( EQUAL(argv[i],"-a_nodata") && i < argc - 1 ) { if (EQUAL(argv[i+1], "none")) { bUnsetNoData = TRUE; } else { bSetNoData = TRUE; dfNoDataReal = CPLAtofM(argv[i+1]); } i += 1; } else if( EQUAL(argv[i],"-co") && i < argc-1 ) { papszCreateOptions = CSLAddString( papszCreateOptions, argv[++i] ); } else if( EQUAL(argv[i],"-replace_ids") && i < argc-3 ) { bReplaceIds = TRUE; pszReplaceFilename = (argv[++i]); pszReplaceFieldFrom = (argv[++i]); pszReplaceFieldTo = (argv[++i]); } else if( argv[i][0] == '-' ) { printf( "Option %s incomplete, or not recognised.\n\n", argv[i] ); Usage(); GDALDestroyDriverManager(); exit( 2 ); } else if( pszSource == NULL ) { iSrcFileArg = i; pszSource = argv[i]; } else if( pszDest == NULL ) { pszDest = argv[i]; iDstFileArg = i; } else { printf( "Too many command options.\n\n" ); Usage(); GDALDestroyDriverManager(); exit( 2 ); } } if( pszDest == NULL ) { Usage(); GDALDestroyDriverManager(); exit( 10 ); } if ( strcmp(pszSource, pszDest) == 0) { fprintf(stderr, "Source and destination datasets must be different.\n"); GDALDestroyDriverManager(); exit( 1 ); } if( bReplaceIds ) { if ( ! pszReplaceFilename | ! pszReplaceFieldFrom | ! pszReplaceFieldTo ) Usage(); // FILE * ifile; // if ( (ifile = fopen(pszReplaceFilename, "r")) == NULL ) // { // fprintf( stderr, "Replace file %s cannot be read!\n\n", pszReplaceFilename ); // Usage(); // } // else // fclose( ifile ); mReplaceTable = InitReplaceTable(pszReplaceFilename, pszReplaceFieldFrom, pszReplaceFieldTo); printf("TMP ET size: %d\n",(int)mReplaceTable.size()); } /* -------------------------------------------------------------------- */ /* Attempt to open source file. */ /* -------------------------------------------------------------------- */ // hDataset = GDALOpenShared( pszSource, GA_ReadOnly ); hDataset = (GDALDataset *) GDALOpen(pszSource, GA_ReadOnly ); if( hDataset == NULL ) { fprintf( stderr, "GDALOpen failed - %d\n%s\n", CPLGetLastErrorNo(), CPLGetLastErrorMsg() ); GDALDestroyDriverManager(); exit( 1 ); } /* -------------------------------------------------------------------- */ /* Collect some information from the source file. */ /* -------------------------------------------------------------------- */ // nRasterXSize = GDALGetRasterXSize( hDataset ); // nRasterYSize = GDALGetRasterYSize( hDataset ); nRasterXSize = hDataset->GetRasterXSize(); nRasterYSize = hDataset->GetRasterYSize(); if( !bQuiet ) printf( "Input file size is %d, %d\n", nRasterXSize, nRasterYSize ); /* -------------------------------------------------------------------- */ /* Find the output driver. */ /* -------------------------------------------------------------------- */ hDriver = GetGDALDriverManager()->GetDriverByName( pszFormat ); if( hDriver == NULL ) { int iDr; printf( "Output driver `%s' not recognised.\n", pszFormat ); printf( "The following format drivers are configured and support output:\n" ); for( iDr = 0; iDr < GDALGetDriverCount(); iDr++ ) { GDALDriverH hDriver = GDALGetDriver(iDr); if( GDALGetMetadataItem( hDriver, GDAL_DCAP_CREATE, NULL ) != NULL || GDALGetMetadataItem( hDriver, GDAL_DCAP_CREATECOPY, NULL ) != NULL ) { printf( " %s: %s\n", GDALGetDriverShortName( hDriver ), GDALGetDriverLongName( hDriver ) ); } } printf( "\n" ); Usage(); GDALClose( (GDALDatasetH) hDataset ); GDALDestroyDriverManager(); CSLDestroy( argv ); CSLDestroy( papszCreateOptions ); exit( 1 ); } /* -------------------------------------------------------------------- */ /* Create Dataset and copy info */ /* -------------------------------------------------------------------- */ nRasterCount = hDataset->GetRasterCount(); printf("creating\n"); hOutDS = hDriver->Create( pszDest, nRasterXSize, nRasterYSize, nRasterCount, GDT_Byte, papszCreateOptions); printf("created\n"); if( hOutDS != NULL ) { hDataset->GetGeoTransform( adfGeoTransform); hOutDS->SetGeoTransform( adfGeoTransform ); hOutDS->SetProjection( hDataset->GetProjectionRef() ); /* ==================================================================== */ /* Process all bands. */ /* ==================================================================== */ // if (0) for( i = 1; i < nRasterCount+1; i++ ) { inBand = hDataset->GetRasterBand( i ); // hOutDS->AddBand(GDT_Byte); outBand = hOutDS->GetRasterBand( i ); CopyBandInfo( inBand, outBand, 0, 1, 1 ); nRasterXSize = inBand->GetXSize( ); nRasterYSize = inBand->GetYSize( ); GByte old_value, new_value; // char tmp_value[255]; // const char *tmp_value2; std::map<GByte,GByte>::iterator it; //tmp int nXBlocks, nYBlocks, nXBlockSize, nYBlockSize; int iXBlock, iYBlock; inBand->GetBlockSize( &nXBlockSize, &nYBlockSize ); // nXBlockSize = nXBlockSize / 4; // nYBlockSize = nYBlockSize / 4; nXBlocks = (inBand->GetXSize() + nXBlockSize - 1) / nXBlockSize; nYBlocks = (inBand->GetYSize() + nYBlockSize - 1) / nYBlockSize; printf("blocks: %d %d %d %d\n",nXBlockSize,nYBlockSize,nXBlocks,nYBlocks); printf("TMP ET creating raster %d x %d\n",nRasterXSize, nRasterYSize); // srcBuffer = new GByte[nRasterXSize * nRasterYSize]; // printf("reading\n"); // inBand->RasterIO( GF_Read, 0, 0, nRasterXSize, nRasterYSize, // srcBuffer, nRasterXSize, nRasterYSize, GDT_Byte, // 0, 0 ); // srcBuffer = (GByte *) CPLMalloc(sizeof(GByte)*nRasterXSize * nRasterYSize); srcBuffer = (GByte *) CPLMalloc(nXBlockSize * nYBlockSize); for( iYBlock = 0; iYBlock < nYBlocks; iYBlock++ ) { // if(iYBlock%1000 == 0) // printf("iXBlock: %d iYBlock: %d\n",iXBlock,iYBlock); if(iYBlock%1000 == 0) printf("iYBlock: %d / %d\n",iYBlock,nYBlocks); for( iXBlock = 0; iXBlock < nXBlocks; iXBlock++ ) { int nXValid, nYValid; // inBand->ReadBlock( iXBlock, iYBlock, srcBuffer ); inBand->RasterIO( GF_Read, iXBlock, iYBlock, nXBlockSize, nYBlockSize, srcBuffer, nXBlockSize, nYBlockSize, GDT_Byte, 0, 0 ); // Compute the portion of the block that is valid // for partial edge blocks. if( (iXBlock+1) * nXBlockSize > inBand->GetXSize() ) nXValid = inBand->GetXSize() - iXBlock * nXBlockSize; else nXValid = nXBlockSize; if( (iYBlock+1) * nYBlockSize > inBand->GetYSize() ) nYValid = inBand->GetYSize() - iYBlock * nYBlockSize; else nYValid = nYBlockSize; // printf("iXBlock: %d iYBlock: %d read, nXValid: %d nYValid: %d\n",iXBlock,iYBlock,nXValid, nYValid); // if(0) if ( pszReplaceFilename ) { for( int iY = 0; iY < nYValid; iY++ ) { for( int iX = 0; iX < nXValid; iX++ ) { // panHistogram[pabyData[iX + iY * nXBlockSize]] += 1; old_value = new_value = srcBuffer[iX + iY * nXBlockSize]; // sprintf(tmp_value,"%d",old_value); it = mReplaceTable.find(old_value); if ( it != mReplaceTable.end() ) new_value = it->second; if ( old_value != new_value ) { srcBuffer[iX + iY * nXBlockSize] = new_value; // printf("old_value %d new_value %d final %d\n",old_value,new_value, srcBuffer[iX + iY * nXBlockSize]); } // tmp_value2 = CSVGetField( pszReplaceFilename,pszReplaceFieldFrom, // tmp_value, CC_Integer, pszReplaceFieldTo); // if( tmp_value2 != NULL ) // { // new_value = atoi(tmp_value2); // } // new_value = old_value +1; // } } } // printf("writing\n"); // outBand->WriteBlock( iXBlock, iYBlock, srcBuffer ); outBand->RasterIO( GF_Write, iXBlock, iYBlock, nXBlockSize, nYBlockSize, srcBuffer, nXBlockSize, nYBlockSize, GDT_Byte, 0, 0 ); // printf("wrote\n"); } } CPLFree(srcBuffer); printf("read\n"); printf("mod\n"); // if ( pszReplaceFilename ) // { // GByte old_value, new_value; // // char tmp_value[255]; // // const char *tmp_value2; // std::map<GByte,GByte>::iterator it; // for ( int j=0; j<nRasterXSize*nRasterYSize; j++ ) // { // old_value = new_value = srcBuffer[j]; // // sprintf(tmp_value,"%d",old_value); // it = mReplaceTable.find(old_value); // if ( it != mReplaceTable.end() ) new_value = it->second; // // tmp_value2 = CSVGetField( pszReplaceFilename,pszReplaceFieldFrom, // // tmp_value, CC_Integer, pszReplaceFieldTo); // // if( tmp_value2 != NULL ) // // { // // new_value = atoi(tmp_value2); // // } // // new_value = old_value +1; // if ( old_value != new_value ) srcBuffer[j] = new_value; // // printf("old_value %d new_value %d final %d\n",old_value,new_value, srcBuffer[j]); // } // printf("writing\n"); // outBand->RasterIO( GF_Write, 0, 0, nRasterXSize, nRasterYSize, // srcBuffer, nRasterXSize, nRasterYSize, GDT_Byte, // 0, 0 ); // printf("wrote\n"); // delete [] srcBuffer; // } } } if( hOutDS != NULL ) GDALClose( (GDALDatasetH) hOutDS ); if( hDataset != NULL ) GDALClose( (GDALDatasetH) hDataset ); GDALDumpOpenDatasets( stderr ); // GDALDestroyDriverManager(); CSLDestroy( argv ); CSLDestroy( papszCreateOptions ); return hOutDS == NULL; }
int main( int argc, char ** argv ) { GDALDriverH hDriver; const char *pszSource=NULL, *pszDest=NULL, *pszFormat = "GTiff"; int bFormatExplicitlySet = FALSE; char **papszLayers = NULL; const char *pszBurnAttribute = NULL; double dfIncreaseBurnValue = 0.0; double dfMultiplyBurnValue = 1.0; const char *pszWHERE = NULL, *pszSQL = NULL; GDALDataType eOutputType = GDT_Float64; char **papszCreateOptions = NULL; GUInt32 nXSize = 0, nYSize = 0; double dfXMin = 0.0, dfXMax = 0.0, dfYMin = 0.0, dfYMax = 0.0; int bIsXExtentSet = FALSE, bIsYExtentSet = FALSE; GDALGridAlgorithm eAlgorithm = GGA_InverseDistanceToAPower; void *pOptions = NULL; char *pszOutputSRS = NULL; int bQuiet = FALSE; GDALProgressFunc pfnProgress = GDALTermProgress; int i; OGRGeometry *poSpatialFilter = NULL; int bClipSrc = FALSE; OGRGeometry *poClipSrc = NULL; const char *pszClipSrcDS = NULL; const char *pszClipSrcSQL = NULL; const char *pszClipSrcLayer = NULL; const char *pszClipSrcWhere = NULL; int bNoDataSet = FALSE; double dfNoDataValue = 0; /* Check strict compilation and runtime library version as we use C++ API */ if (! GDAL_CHECK_VERSION(argv[0])) exit(1); GDALAllRegister(); OGRRegisterAll(); argc = GDALGeneralCmdLineProcessor( argc, &argv, 0 ); if( argc < 1 ) exit( -argc ); /* -------------------------------------------------------------------- */ /* Parse arguments. */ /* -------------------------------------------------------------------- */ for( i = 1; i < argc; i++ ) { if( EQUAL(argv[i], "--utility_version") ) { printf("%s was compiled against GDAL %s and is running against GDAL %s\n", argv[0], GDAL_RELEASE_NAME, GDALVersionInfo("RELEASE_NAME")); return 0; } else if( EQUAL(argv[i],"--help") ) Usage(); else if( EQUAL(argv[i],"-of") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); pszFormat = argv[++i]; bFormatExplicitlySet = TRUE; } else if( EQUAL(argv[i],"-q") || EQUAL(argv[i],"-quiet") ) { bQuiet = TRUE; pfnProgress = GDALDummyProgress; } else if( EQUAL(argv[i],"-ot") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); int iType; for( iType = 1; iType < GDT_TypeCount; iType++ ) { if( GDALGetDataTypeName((GDALDataType)iType) != NULL && EQUAL(GDALGetDataTypeName((GDALDataType)iType), argv[i+1]) ) { eOutputType = (GDALDataType) iType; } } if( eOutputType == GDT_Unknown ) { Usage(CPLSPrintf("Unknown output pixel type: %s.", argv[i + 1] )); } i++; } else if( EQUAL(argv[i],"-txe") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(2); dfXMin = CPLAtof(argv[++i]); dfXMax = CPLAtof(argv[++i]); bIsXExtentSet = TRUE; } else if( EQUAL(argv[i],"-tye") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(2); dfYMin = CPLAtof(argv[++i]); dfYMax = CPLAtof(argv[++i]); bIsYExtentSet = TRUE; } else if( EQUAL(argv[i],"-outsize") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(2); nXSize = atoi(argv[++i]); nYSize = atoi(argv[++i]); } else if( EQUAL(argv[i],"-co") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); papszCreateOptions = CSLAddString( papszCreateOptions, argv[++i] ); } else if( EQUAL(argv[i],"-zfield") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); pszBurnAttribute = argv[++i]; } else if( EQUAL(argv[i],"-z_increase") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); dfIncreaseBurnValue = CPLAtof(argv[++i]); } else if( EQUAL(argv[i],"-z_multiply") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); dfMultiplyBurnValue = CPLAtof(argv[++i]); } else if( EQUAL(argv[i],"-where") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); pszWHERE = argv[++i]; } else if( EQUAL(argv[i],"-l") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); papszLayers = CSLAddString( papszLayers, argv[++i] ); } else if( EQUAL(argv[i],"-sql") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); pszSQL = argv[++i]; } else if( EQUAL(argv[i],"-spat") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(4); OGRLinearRing oRing; oRing.addPoint( CPLAtof(argv[i+1]), CPLAtof(argv[i+2]) ); oRing.addPoint( CPLAtof(argv[i+1]), CPLAtof(argv[i+4]) ); oRing.addPoint( CPLAtof(argv[i+3]), CPLAtof(argv[i+4]) ); oRing.addPoint( CPLAtof(argv[i+3]), CPLAtof(argv[i+2]) ); oRing.addPoint( CPLAtof(argv[i+1]), CPLAtof(argv[i+2]) ); poSpatialFilter = new OGRPolygon(); ((OGRPolygon *) poSpatialFilter)->addRing( &oRing ); i += 4; } else if ( EQUAL(argv[i],"-clipsrc") ) { if (i + 1 >= argc) Usage(CPLSPrintf("%s option requires 1 or 4 arguments", argv[i])); bClipSrc = TRUE; errno = 0; const double unused = strtod( argv[i + 1], NULL ); // XXX: is it a number or not? if ( errno != 0 && argv[i + 2] != NULL && argv[i + 3] != NULL && argv[i + 4] != NULL) { OGRLinearRing oRing; oRing.addPoint( CPLAtof(argv[i + 1]), CPLAtof(argv[i + 2]) ); oRing.addPoint( CPLAtof(argv[i + 1]), CPLAtof(argv[i + 4]) ); oRing.addPoint( CPLAtof(argv[i + 3]), CPLAtof(argv[i + 4]) ); oRing.addPoint( CPLAtof(argv[i + 3]), CPLAtof(argv[i + 2]) ); oRing.addPoint( CPLAtof(argv[i + 1]), CPLAtof(argv[i + 2]) ); poClipSrc = new OGRPolygon(); ((OGRPolygon *) poClipSrc)->addRing( &oRing ); i += 4; (void)unused; } else if (EQUALN(argv[i + 1], "POLYGON", 7) || EQUALN(argv[i + 1], "MULTIPOLYGON", 12)) { OGRGeometryFactory::createFromWkt(&argv[i + 1], NULL, &poClipSrc); if ( poClipSrc == NULL ) { Usage("Invalid geometry. " "Must be a valid POLYGON or MULTIPOLYGON WKT."); } i++; } else if (EQUAL(argv[i + 1], "spat_extent") ) { i++; } else { pszClipSrcDS = argv[i + 1]; i++; } } else if ( EQUAL(argv[i], "-clipsrcsql") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); pszClipSrcSQL = argv[i + 1]; i++; } else if ( EQUAL(argv[i], "-clipsrclayer") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); pszClipSrcLayer = argv[i + 1]; i++; } else if ( EQUAL(argv[i], "-clipsrcwhere") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); pszClipSrcWhere = argv[i + 1]; i++; } else if( EQUAL(argv[i],"-a_srs") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); OGRSpatialReference oOutputSRS; if( oOutputSRS.SetFromUserInput( argv[i+1] ) != OGRERR_NONE ) { fprintf( stderr, "Failed to process SRS definition: %s\n", argv[i+1] ); GDALDestroyDriverManager(); exit( 1 ); } oOutputSRS.exportToWkt( &pszOutputSRS ); i++; } else if( EQUAL(argv[i],"-a") ) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(1); const char* pszAlgorithm = argv[++i]; if ( ParseAlgorithmAndOptions( pszAlgorithm, &eAlgorithm, &pOptions ) != CE_None ) { fprintf( stderr, "Failed to process algorithm name and parameters.\n" ); exit( 1 ); } char **papszParms = CSLTokenizeString2( pszAlgorithm, ":", FALSE ); const char* pszNoDataValue = CSLFetchNameValue( papszParms, "nodata" ); if( pszNoDataValue != NULL ) { bNoDataSet = TRUE; dfNoDataValue = CPLAtofM(pszNoDataValue); } CSLDestroy(papszParms); } else if( argv[i][0] == '-' ) { Usage(CPLSPrintf("Unknown option name '%s'", argv[i])); } else if( pszSource == NULL ) { pszSource = argv[i]; } else if( pszDest == NULL ) { pszDest = argv[i]; } else { Usage("Too many command options."); } } if( pszSource == NULL ) { Usage("Source datasource is not specified."); } if( pszDest == NULL ) { Usage("Target dataset is not specified."); } if( pszSQL == NULL && papszLayers == NULL ) { Usage("Neither -sql nor -l are specified."); } if ( bClipSrc && pszClipSrcDS != NULL ) { poClipSrc = LoadGeometry( pszClipSrcDS, pszClipSrcSQL, pszClipSrcLayer, pszClipSrcWhere ); if ( poClipSrc == NULL ) { Usage("Cannot load source clip geometry."); } } else if ( bClipSrc && poClipSrc == NULL && !poSpatialFilter ) { Usage("-clipsrc must be used with -spat option or \n" "a bounding box, WKT string or datasource must be " "specified."); } if ( poSpatialFilter ) { if ( poClipSrc ) { OGRGeometry *poTemp = poSpatialFilter->Intersection( poClipSrc ); if ( poTemp ) { OGRGeometryFactory::destroyGeometry( poSpatialFilter ); poSpatialFilter = poTemp; } OGRGeometryFactory::destroyGeometry( poClipSrc ); poClipSrc = NULL; } } else { if ( poClipSrc ) { poSpatialFilter = poClipSrc; poClipSrc = NULL; } } /* -------------------------------------------------------------------- */ /* Find the output driver. */ /* -------------------------------------------------------------------- */ hDriver = GDALGetDriverByName( pszFormat ); if( hDriver == NULL ) { int iDr; fprintf( stderr, "FAILURE: Output driver `%s' not recognised.\n", pszFormat ); fprintf( stderr, "The following format drivers are configured and support output:\n" ); for( iDr = 0; iDr < GDALGetDriverCount(); iDr++ ) { GDALDriverH hDriver = GDALGetDriver(iDr); if( GDALGetMetadataItem( hDriver, GDAL_DCAP_RASTER, NULL) != NULL && ( GDALGetMetadataItem( hDriver, GDAL_DCAP_CREATE, NULL ) != NULL || GDALGetMetadataItem( hDriver, GDAL_DCAP_CREATECOPY, NULL ) != NULL) ) { fprintf( stderr, " %s: %s\n", GDALGetDriverShortName( hDriver ), GDALGetDriverLongName( hDriver ) ); } } printf( "\n" ); Usage(); } /* -------------------------------------------------------------------- */ /* Open input datasource. */ /* -------------------------------------------------------------------- */ OGRDataSourceH hSrcDS; hSrcDS = OGROpen( pszSource, FALSE, NULL ); if( hSrcDS == NULL ) { fprintf( stderr, "Unable to open input datasource \"%s\".\n", pszSource ); fprintf( stderr, "%s\n", CPLGetLastErrorMsg() ); exit( 3 ); } /* -------------------------------------------------------------------- */ /* Create target raster file. */ /* -------------------------------------------------------------------- */ GDALDatasetH hDstDS; int nLayerCount = CSLCount(papszLayers); int nBands = nLayerCount; if ( pszSQL ) nBands++; // FIXME if ( nXSize == 0 ) nXSize = 256; if ( nYSize == 0 ) nYSize = 256; if (!bQuiet && !bFormatExplicitlySet) CheckExtensionConsistency(pszDest, pszFormat); hDstDS = GDALCreate( hDriver, pszDest, nXSize, nYSize, nBands, eOutputType, papszCreateOptions ); if ( hDstDS == NULL ) { fprintf( stderr, "Unable to create target dataset \"%s\".\n", pszDest ); fprintf( stderr, "%s\n", CPLGetLastErrorMsg() ); exit( 3 ); } if( bNoDataSet ) { for( i = 1; i <= nBands; i++ ) { GDALRasterBandH hBand = GDALGetRasterBand( hDstDS, i ); GDALSetRasterNoDataValue( hBand, dfNoDataValue ); } } /* -------------------------------------------------------------------- */ /* If algorithm was not specified assigh default one. */ /* -------------------------------------------------------------------- */ if ( !pOptions ) ParseAlgorithmAndOptions( szAlgNameInvDist, &eAlgorithm, &pOptions ); /* -------------------------------------------------------------------- */ /* Process SQL request. */ /* -------------------------------------------------------------------- */ if( pszSQL != NULL ) { OGRLayerH hLayer; hLayer = OGR_DS_ExecuteSQL( hSrcDS, pszSQL, (OGRGeometryH)poSpatialFilter, NULL ); if( hLayer != NULL ) { // Custom layer will be rasterized in the first band. ProcessLayer( hLayer, hDstDS, poSpatialFilter, nXSize, nYSize, 1, bIsXExtentSet, bIsYExtentSet, dfXMin, dfXMax, dfYMin, dfYMax, pszBurnAttribute, dfIncreaseBurnValue, dfMultiplyBurnValue, eOutputType, eAlgorithm, pOptions, bQuiet, pfnProgress ); } } /* -------------------------------------------------------------------- */ /* Process each layer. */ /* -------------------------------------------------------------------- */ for( i = 0; i < nLayerCount; i++ ) { OGRLayerH hLayer = OGR_DS_GetLayerByName( hSrcDS, papszLayers[i]); if( hLayer == NULL ) { fprintf( stderr, "Unable to find layer \"%s\", skipping.\n", papszLayers[i] ); continue; } if( pszWHERE ) { if( OGR_L_SetAttributeFilter( hLayer, pszWHERE ) != OGRERR_NONE ) break; } if ( poSpatialFilter != NULL ) OGR_L_SetSpatialFilter( hLayer, (OGRGeometryH)poSpatialFilter ); // Fetch the first meaningful SRS definition if ( !pszOutputSRS ) { OGRSpatialReferenceH hSRS = OGR_L_GetSpatialRef( hLayer ); if ( hSRS ) OSRExportToWkt( hSRS, &pszOutputSRS ); } ProcessLayer( hLayer, hDstDS, poSpatialFilter, nXSize, nYSize, i + 1 + nBands - nLayerCount, bIsXExtentSet, bIsYExtentSet, dfXMin, dfXMax, dfYMin, dfYMax, pszBurnAttribute, dfIncreaseBurnValue, dfMultiplyBurnValue, eOutputType, eAlgorithm, pOptions, bQuiet, pfnProgress ); } /* -------------------------------------------------------------------- */ /* Apply geotransformation matrix. */ /* -------------------------------------------------------------------- */ double adfGeoTransform[6]; adfGeoTransform[0] = dfXMin; adfGeoTransform[1] = (dfXMax - dfXMin) / nXSize; adfGeoTransform[2] = 0.0; adfGeoTransform[3] = dfYMin; adfGeoTransform[4] = 0.0; adfGeoTransform[5] = (dfYMax - dfYMin) / nYSize; GDALSetGeoTransform( hDstDS, adfGeoTransform ); /* -------------------------------------------------------------------- */ /* Apply SRS definition if set. */ /* -------------------------------------------------------------------- */ if ( pszOutputSRS ) { GDALSetProjection( hDstDS, pszOutputSRS ); CPLFree( pszOutputSRS ); } /* -------------------------------------------------------------------- */ /* Cleanup */ /* -------------------------------------------------------------------- */ OGR_DS_Destroy( hSrcDS ); GDALClose( hDstDS ); OGRGeometryFactory::destroyGeometry( poSpatialFilter ); CPLFree( pOptions ); CSLDestroy( papszCreateOptions ); CSLDestroy( argv ); CSLDestroy( papszLayers ); OGRCleanupAll(); GDALDestroyDriverManager(); return 0; }
GDALDataset *VICARDataset::Open( GDALOpenInfo * poOpenInfo ) { /* -------------------------------------------------------------------- */ /* Does this look like a VICAR dataset? */ /* -------------------------------------------------------------------- */ if( !Identify( poOpenInfo ) ) return NULL; /* -------------------------------------------------------------------- */ /* Open the file using the large file API. */ /* -------------------------------------------------------------------- */ VSILFILE *fpQube = VSIFOpenL( poOpenInfo->pszFilename, "rb" ); if( fpQube == NULL ) return NULL; VICARDataset *poDS = new VICARDataset(); if( ! poDS->oKeywords.Ingest( fpQube, poOpenInfo->pabyHeader ) ) { VSIFCloseL( fpQube ); delete poDS; return NULL; } VSIFCloseL( fpQube ); /***** CHECK ENDIANNESS **************/ const char *value = poDS->GetKeyword( "INTFMT" ); if (!EQUAL(value,"LOW") ) { CPLError( CE_Failure, CPLE_OpenFailed, "%s layout not supported. Abort\n\n", value); delete poDS; return FALSE; } value = poDS->GetKeyword( "REALFMT" ); if (!EQUAL(value,"RIEEE") ) { CPLError( CE_Failure, CPLE_OpenFailed, "%s layout not supported. Abort\n\n", value); delete poDS; return FALSE; } char chByteOrder = 'M'; value = poDS->GetKeyword( "BREALFMT" ); if (EQUAL(value,"VAX") ) { chByteOrder = 'I'; } /************ CHECK INSTRUMENT *****************/ /************ ONLY HRSC TESTED *****************/ bool bIsDTM = false; value = poDS->GetKeyword( "DTM.DTM_OFFSET" ); if (!EQUAL(value,"") ) { bIsDTM = true; } value = poDS->GetKeyword( "BLTYPE" ); if (!EQUAL(value,"M94_HRSC") && !bIsDTM ) { CPLError( CE_Failure, CPLE_OpenFailed, "%s instrument not tested. Continue with caution!\n\n", value); } /*********** Grab layout type (BSQ, BIP, BIL) ************/ char szLayout[10] = "BSQ"; //default to band seq. value = poDS->GetKeyword( "ORG" ); if (!EQUAL(value,"BSQ") ) { CPLError( CE_Failure, CPLE_OpenFailed, "%s layout not supported. Abort\n\n", value); delete poDS; return FALSE; } strcpy(szLayout,"BSQ"); const int nCols = atoi(poDS->GetKeyword("NS")); const int nRows = atoi(poDS->GetKeyword("NL")); const int nBands = atoi(poDS->GetKeyword("NB")); /*********** Grab record bytes **********/ int nSkipBytes = atoi(poDS->GetKeyword("NBB")); GDALDataType eDataType = GDT_Byte; double dfNoData = 0.0; if (EQUAL( poDS->GetKeyword( "FORMAT" ), "BYTE" )) { eDataType = GDT_Byte; dfNoData = NULL1; } else if (EQUAL( poDS->GetKeyword( "FORMAT" ), "HALF" )) { eDataType = GDT_Int16; dfNoData = NULL2; chByteOrder = 'I'; } else if (EQUAL( poDS->GetKeyword( "FORMAT" ), "FULL" )) { eDataType = GDT_UInt32; dfNoData = 0; } else if (EQUAL( poDS->GetKeyword( "FORMAT" ), "REAL" )) { eDataType = GDT_Float32; dfNoData = NULL3; chByteOrder = 'I'; } else { CPLError( CE_Failure, CPLE_AppDefined, "Could not find known VICAR label entries!\n"); delete poDS; return NULL; } if( nRows < 1 || nCols < 1 || nBands < 1 ) { CPLError( CE_Failure, CPLE_AppDefined, "File %s appears to be a VICAR file, but failed to find some " "required keywords.", poDS->GetDescription() ); return FALSE; } /* -------------------------------------------------------------------- */ /* Capture some information from the file that is of interest. */ /* -------------------------------------------------------------------- */ poDS->nRasterXSize = nCols; poDS->nRasterYSize = nRows; double dfULXMap=0.5; double dfULYMap = 0.5; double dfXDim = 1.0; double dfYDim = 1.0; double xulcenter = 0.0; double yulcenter = 0.0; value = poDS->GetKeyword("MAP.MAP_SCALE"); if (strlen(value) > 0 ) { dfXDim = CPLAtof(value); dfYDim = CPLAtof(value) * -1; dfXDim = dfXDim * 1000.0; dfYDim = dfYDim * 1000.0; } double dfSampleOffset_Shift = CPLAtof(CPLGetConfigOption( "PDS_SampleProjOffset_Shift", "-0.5" )); double dfLineOffset_Shift = CPLAtof(CPLGetConfigOption( "PDS_LineProjOffset_Shift", "-0.5" )); double dfSampleOffset_Mult = CPLAtof(CPLGetConfigOption( "PDS_SampleProjOffset_Mult", "-1.0") ); double dfLineOffset_Mult = CPLAtof( CPLGetConfigOption( "PDS_LineProjOffset_Mult", "1.0") ); /*********** Grab LINE_PROJECTION_OFFSET ************/ value = poDS->GetKeyword("MAP.LINE_PROJECTION_OFFSET"); if (strlen(value) > 0) { yulcenter = CPLAtof(value); dfULYMap = ((yulcenter + dfLineOffset_Shift) * -dfYDim * dfLineOffset_Mult); } /*********** Grab SAMPLE_PROJECTION_OFFSET ************/ value = poDS->GetKeyword("MAP.SAMPLE_PROJECTION_OFFSET"); if( strlen(value) > 0 ) { xulcenter = CPLAtof(value); dfULXMap = ((xulcenter + dfSampleOffset_Shift) * dfXDim * dfSampleOffset_Mult); } /* ==================================================================== */ /* Get the coordinate system. */ /* ==================================================================== */ bool bProjectionSet = true; /*********** Grab TARGET_NAME ************/ /**** This is the planets name i.e. MARS ***/ const CPLString target_name = poDS->GetKeyword("MAP.TARGET_NAME"); /********** Grab MAP_PROJECTION_TYPE *****/ const CPLString map_proj_name = poDS->GetKeyword( "MAP.MAP_PROJECTION_TYPE"); /****** Grab semi_major & convert to KM ******/ const double semi_major = CPLAtof(poDS->GetKeyword( "MAP.A_AXIS_RADIUS")) * 1000.0; /****** Grab semi-minor & convert to KM ******/ const double semi_minor = CPLAtof(poDS->GetKeyword( "MAP.C_AXIS_RADIUS")) * 1000.0; /*********** Grab CENTER_LAT ************/ const double center_lat = CPLAtof(poDS->GetKeyword( "MAP.CENTER_LATITUDE")); /*********** Grab CENTER_LON ************/ const double center_lon = CPLAtof(poDS->GetKeyword( "MAP.CENTER_LONGITUDE")); /********** Grab 1st std parallel *******/ const double first_std_parallel = CPLAtof(poDS->GetKeyword( "MAP.FIRST_STANDARD_PARALLEL")); /********** Grab 2nd std parallel *******/ const double second_std_parallel = CPLAtof(poDS->GetKeyword( "MAP.SECOND_STANDARD_PARALLEL")); /*** grab PROJECTION_LATITUDE_TYPE = "PLANETOCENTRIC" ****/ // Need to further study how ocentric/ographic will effect the gdal library. // So far we will use this fact to define a sphere or ellipse for some projections // Frank - may need to talk this over bool bIsGeographic = true; value = poDS->GetKeyword("MAP.COORDINATE_SYSTEM_NAME"); if (EQUAL( value, "PLANETOCENTRIC" )) bIsGeographic = false; /** Set oSRS projection and parameters --- all PDS supported types added if apparently supported in oSRS "AITOFF", ** Not supported in GDAL?? "ALBERS", "BONNE", "BRIESEMEISTER", ** Not supported in GDAL?? "CYLINDRICAL EQUAL AREA", "EQUIDISTANT", "EQUIRECTANGULAR", "GNOMONIC", "HAMMER", ** Not supported in GDAL?? "HENDU", ** Not supported in GDAL?? "LAMBERT AZIMUTHAL EQUAL AREA", "LAMBERT CONFORMAL", "MERCATOR", "MOLLWEIDE", "OBLIQUE CYLINDRICAL", "ORTHOGRAPHIC", "SIMPLE CYLINDRICAL", "SINUSOIDAL", "STEREOGRAPHIC", "TRANSVERSE MERCATOR", "VAN DER GRINTEN", ** Not supported in GDAL?? "WERNER" ** Not supported in GDAL?? **/ CPLDebug( "PDS", "using projection %s\n\n", map_proj_name.c_str()); OGRSpatialReference oSRS; if ((EQUAL( map_proj_name, "EQUIRECTANGULAR" )) || (EQUAL( map_proj_name, "SIMPLE_CYLINDRICAL" )) || (EQUAL( map_proj_name, "EQUIDISTANT" )) ) { oSRS.SetEquirectangular2 ( 0.0, center_lon, center_lat, 0, 0 ); } else if (EQUAL( map_proj_name, "ORTHOGRAPHIC" )) { oSRS.SetOrthographic ( center_lat, center_lon, 0, 0 ); } else if (EQUAL( map_proj_name, "SINUSOIDAL" )) { oSRS.SetSinusoidal ( center_lon, 0, 0 ); } else if (EQUAL( map_proj_name, "MERCATOR" )) { oSRS.SetMercator ( center_lat, center_lon, 1, 0, 0 ); } else if (EQUAL( map_proj_name, "STEREOGRAPHIC" )) { oSRS.SetStereographic ( center_lat, center_lon, 1, 0, 0 ); } else if (EQUAL( map_proj_name, "POLAR_STEREOGRAPHIC")) { oSRS.SetPS ( center_lat, center_lon, 1, 0, 0 ); } else if (EQUAL( map_proj_name, "TRANSVERSE_MERCATOR" )) { oSRS.SetTM ( center_lat, center_lon, 1, 0, 0 ); } else if (EQUAL( map_proj_name, "LAMBERT_CONFORMAL_CONIC" )) { oSRS.SetLCC ( first_std_parallel, second_std_parallel, center_lat, center_lon, 0, 0 ); } else if (EQUAL( map_proj_name, "LAMBERT_AZIMUTHAL_EQUAL_AREA" )) { oSRS.SetLAEA( center_lat, center_lon, 0, 0 ); } else if (EQUAL( map_proj_name, "CYLINDRICAL_EQUAL_AREA" )) { oSRS.SetCEA ( first_std_parallel, center_lon, 0, 0 ); } else if (EQUAL( map_proj_name, "MOLLWEIDE" )) { oSRS.SetMollweide ( center_lon, 0, 0 ); } else if (EQUAL( map_proj_name, "ALBERS" )) { oSRS.SetACEA ( first_std_parallel, second_std_parallel, center_lat, center_lon, 0, 0 ); } else if (EQUAL( map_proj_name, "BONNE" )) { oSRS.SetBonne ( first_std_parallel, center_lon, 0, 0 ); } else if (EQUAL( map_proj_name, "GNOMONIC" )) { oSRS.SetGnomonic ( center_lat, center_lon, 0, 0 ); } else if (EQUAL( map_proj_name, "OBLIQUE_CYLINDRICAL" )) { // hope Swiss Oblique Cylindrical is the same oSRS.SetSOC ( center_lat, center_lon, 0, 0 ); } else { CPLDebug( "VICAR", "Dataset projection %s is not supported. Continuing...", map_proj_name.c_str() ); bProjectionSet = false; } if (bProjectionSet) { //Create projection name, i.e. MERCATOR MARS and set as ProjCS keyword CPLString proj_target_name = map_proj_name + " " + target_name; oSRS.SetProjCS(proj_target_name); //set ProjCS keyword //The geographic/geocentric name will be the same basic name as the body name //'GCS' = Geographic/Geocentric Coordinate System CPLString geog_name = "GCS_" + target_name; //The datum and sphere names will be the same basic name aas the planet CPLString datum_name = "D_" + target_name; CPLString sphere_name = target_name; // + "_IAU_IAG"); //Might not be IAU defined so don't add //calculate inverse flattening from major and minor axis: 1/f = a/(a-b) double iflattening = 0.0; if ((semi_major - semi_minor) < 0.0000001) iflattening = 0; else iflattening = semi_major / (semi_major - semi_minor); //Set the body size but take into consideration which proj is being used to help w/ compatibility //Notice that most PDS projections are spherical based on the fact that ISIS/PICS are spherical //Set the body size but take into consideration which proj is being used to help w/ proj4 compatibility //The use of a Sphere, polar radius or ellipse here is based on how ISIS does it internally if ( ( (EQUAL( map_proj_name, "STEREOGRAPHIC" ) && (fabs(center_lat) == 90)) ) || (EQUAL( map_proj_name, "POLAR_STEREOGRAPHIC" ))) { if (bIsGeographic) { //Geograpraphic, so set an ellipse oSRS.SetGeogCS( geog_name, datum_name, sphere_name, semi_major, iflattening, "Reference_Meridian", 0.0 ); } else { //Geocentric, so force a sphere using the semi-minor axis. I hope... sphere_name += "_polarRadius"; oSRS.SetGeogCS( geog_name, datum_name, sphere_name, semi_minor, 0.0, "Reference_Meridian", 0.0 ); } } else if ( (EQUAL( map_proj_name, "SIMPLE_CYLINDRICAL" )) || (EQUAL( map_proj_name, "EQUIDISTANT" )) || (EQUAL( map_proj_name, "ORTHOGRAPHIC" )) || (EQUAL( map_proj_name, "STEREOGRAPHIC" )) || (EQUAL( map_proj_name, "SINUSOIDAL" )) ) { //isis uses the spherical equation for these projections so force a sphere oSRS.SetGeogCS( geog_name, datum_name, sphere_name, semi_major, 0.0, "Reference_Meridian", 0.0 ); } else if (EQUAL( map_proj_name, "EQUIRECTANGULAR" )) { //isis uses local radius as a sphere, which is pre-calculated in the PDS label as the semi-major sphere_name += "_localRadius"; oSRS.SetGeogCS( geog_name, datum_name, sphere_name, semi_major, 0.0, "Reference_Meridian", 0.0 ); } else { //All other projections: Mercator, Transverse Mercator, Lambert Conformal, etc. //Geographic, so set an ellipse if (bIsGeographic) { oSRS.SetGeogCS( geog_name, datum_name, sphere_name, semi_major, iflattening, "Reference_Meridian", 0.0 ); } else { //Geocentric, so force a sphere. I hope... oSRS.SetGeogCS( geog_name, datum_name, sphere_name, semi_major, 0.0, "Reference_Meridian", 0.0 ); } } // translate back into a projection string. char *pszResult = NULL; oSRS.exportToWkt( &pszResult ); poDS->osProjection = pszResult; CPLFree( pszResult ); } { poDS->bGotTransform = TRUE; poDS->adfGeoTransform[0] = dfULXMap; poDS->adfGeoTransform[1] = dfXDim; poDS->adfGeoTransform[2] = 0.0; poDS->adfGeoTransform[3] = dfULYMap; poDS->adfGeoTransform[4] = 0.0; poDS->adfGeoTransform[5] = dfYDim; } CPLString osQubeFile = poOpenInfo->pszFilename; if( !poDS->bGotTransform ) poDS->bGotTransform = GDALReadWorldFile( osQubeFile, "psw", poDS->adfGeoTransform ); if( !poDS->bGotTransform ) poDS->bGotTransform = GDALReadWorldFile( osQubeFile, "wld", poDS->adfGeoTransform ); /* -------------------------------------------------------------------- */ /* Open target binary file. */ /* -------------------------------------------------------------------- */ if( poOpenInfo->eAccess == GA_ReadOnly ) poDS->fpImage = VSIFOpenL( osQubeFile, "r" ); else poDS->fpImage = VSIFOpenL( osQubeFile, "r+" ); if( poDS->fpImage == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Failed to open %s with write permission.\n%s", osQubeFile.c_str(), VSIStrerror( errno ) ); delete poDS; return NULL; } poDS->eAccess = poOpenInfo->eAccess; /* -------------------------------------------------------------------- */ /* Compute the line offsets. */ /* -------------------------------------------------------------------- */ const long int nItemSize = GDALGetDataTypeSize(eDataType)/8; const long int nPixelOffset = nItemSize; const long int nLineOffset = nPixelOffset * nCols + atoi(poDS->GetKeyword("NBB")) ; const long int nBandOffset = nLineOffset * nRows; nSkipBytes = atoi(poDS->GetKeyword("LBLSIZE")); /* -------------------------------------------------------------------- */ /* Create band information objects. */ /* -------------------------------------------------------------------- */ for( int i = 0; i < nBands; i++ ) { GDALRasterBand *poBand = new RawRasterBand( poDS, i+1, poDS->fpImage, nSkipBytes + nBandOffset * i, nPixelOffset, nLineOffset, eDataType, #ifdef CPL_LSB chByteOrder == 'I' || chByteOrder == 'L', #else chByteOrder == 'M', #endif TRUE ); poDS->SetBand( i+1, poBand ); poBand->SetNoDataValue( dfNoData ); if (bIsDTM) { poBand->SetScale( (double) CPLAtof(poDS->GetKeyword( "DTM.DTM_SCALING_FACTOR") ) ); poBand->SetOffset( (double) CPLAtof(poDS->GetKeyword( "DTM.DTM_OFFSET") ) ); const char* pszMin = poDS->GetKeyword( "DTM.DTM_MINIMUM_DN", NULL ); const char* pszMax = poDS->GetKeyword( "DTM.DTM_MAXIMUM_DN", NULL ); if (pszMin != NULL && pszMax != NULL ) poBand->SetStatistics(CPLAtofM(pszMin),CPLAtofM(pszMax),0,0); const char* pszNoData = poDS->GetKeyword( "DTM.DTM_MISSING_DN", NULL ); if (pszNoData != NULL ) poBand->SetNoDataValue( CPLAtofM(pszNoData) ); } else if (EQUAL( poDS->GetKeyword( "BLTYPE"), "M94_HRSC" )) { float scale=CPLAtof(poDS->GetKeyword("DLRTO8.REFLECTANCE_SCALING_FACTOR","-1.")); if (scale < 0.) { scale = CPLAtof(poDS->GetKeyword( "HRCAL.REFLECTANCE_SCALING_FACTOR","1.")); } poBand->SetScale( scale ); float offset=CPLAtof(poDS->GetKeyword("DLRTO8.REFLECTANCE_OFFSET","-1.")); if (offset < 0.) { offset = CPLAtof(poDS->GetKeyword( "HRCAL.REFLECTANCE_OFFSET","0.")); } poBand->SetOffset( offset ); } const char* pszMin = poDS->GetKeyword( "STATISTICS.MINIMUM", NULL ); const char* pszMax = poDS->GetKeyword( "STATISTICS.MAXIMUM", NULL ); const char* pszMean = poDS->GetKeyword( "STATISTICS.MEAN", NULL ); const char* pszStdDev = poDS->GetKeyword( "STATISTICS.STANDARD_DEVIATION", NULL ); if (pszMin != NULL && pszMax != NULL && pszMean != NULL && pszStdDev != NULL ) poBand->SetStatistics(CPLAtofM(pszMin),CPLAtofM(pszMax),CPLAtofM(pszMean),CPLAtofM(pszStdDev)); } /* -------------------------------------------------------------------- */ /* Instrument-specific keywords as metadata. */ /* -------------------------------------------------------------------- */ /****************** HRSC ******************************/ if (EQUAL( poDS->GetKeyword( "BLTYPE"), "M94_HRSC" ) ) { poDS->SetMetadataItem( "SPACECRAFT_NAME", poDS->GetKeyword( "M94_INSTRUMENT.INSTRUMENT_HOST_NAME") ); poDS->SetMetadataItem( "PRODUCT_TYPE", poDS->GetKeyword( "TYPE")); if (EQUAL( poDS->GetKeyword( "M94_INSTRUMENT.DETECTOR_ID"), "MEX_HRSC_SRC" )) { static const char *apszKeywords[] = { "M94_ORBIT.IMAGE_TIME", "FILE.EVENT_TYPE", "FILE.PROCESSING_LEVEL_ID", "M94_INSTRUMENT.DETECTOR_ID", "M94_CAMERAS.EXPOSURE_DURATION", "HRCONVER.INSTRUMENT_TEMPERATURE", NULL }; for( int i = 0; apszKeywords[i] != NULL; i++ ) { const char *pszKeywordValue = poDS->GetKeyword( apszKeywords[i] ); if( pszKeywordValue != NULL ) poDS->SetMetadataItem( apszKeywords[i], pszKeywordValue ); } } else { static const char *apszKeywords[] = { "M94_ORBIT.START_TIME", "M94_ORBIT.STOP_TIME", "M94_INSTRUMENT.DETECTOR_ID", "M94_CAMERAS.MACROPIXEL_SIZE", "FILE.EVENT_TYPE", "M94_INSTRUMENT.MISSION_PHASE_NAME", "HRORTHO.SPICE_FILE_NAME", "HRCONVER.MISSING_FRAMES", "HRCONVER.OVERFLOW_FRAMES", "HRCONVER.ERROR_FRAMES", "HRFOOT.BEST_GROUND_SAMPLING_DISTANCE", "DLRTO8.RADIANCE_SCALING_FACTOR", "DLRTO8.RADIANCE_OFFSET", "DLRTO8.REFLECTANCE_SCALING_FACTOR", "DLRTO8.REFLECTANCE_OFFSET", "HRCAL.RADIANCE_SCALING_FACTOR", "HRCAL.RADIANCE_OFFSET", "HRCAL.REFLECTANCE_SCALING_FACTOR", "HRCAL.REFLECTANCE_OFFSET", "HRORTHO.DTM_NAME", "HRORTHO.EXTORI_FILE_NAME", "HRORTHO.GEOMETRIC_CALIB_FILE_NAME", NULL }; for( int i = 0; apszKeywords[i] != NULL; i++ ) { const char *pszKeywordValue = poDS->GetKeyword( apszKeywords[i], NULL ); if( pszKeywordValue != NULL ) poDS->SetMetadataItem( apszKeywords[i], pszKeywordValue ); } } } if (bIsDTM && EQUAL( poDS->GetKeyword( "MAP.TARGET_NAME"), "MARS" )) { poDS->SetMetadataItem( "SPACECRAFT_NAME", "MARS_EXPRESS" ); poDS->SetMetadataItem( "PRODUCT_TYPE", "DTM"); static const char *apszKeywords[] = { "DTM.DTM_MISSING_DN", "DTM.DTM_OFFSET", "DTM.DTM_SCALING_FACTOR", "DTM.DTM_A_AXIS_RADIUS", "DTM.DTM_B_AXIS_RADIUS", "DTM.DTM_C_AXIS_RADIUS", "DTM.DTM_DESC", "DTM.DTM_MINIMUM_DN", "DTM.DTM_MAXIMUM_DN", NULL }; for( int i = 0; apszKeywords[i] != NULL; i++ ) { const char *pszKeywordValue = poDS->GetKeyword( apszKeywords[i] ); if( pszKeywordValue != NULL ) poDS->SetMetadataItem( apszKeywords[i], pszKeywordValue ); } } /****************** DAWN ******************************/ else if (EQUAL( poDS->GetKeyword( "INSTRUMENT_ID"), "FC2" )) { poDS->SetMetadataItem( "SPACECRAFT_NAME", "DAWN" ); static const char *apszKeywords[] = {"ORBIT_NUMBER","FILTER_NUMBER", "FRONT_DOOR_STATUS", "FIRST_LINE", "FIRST_LINE_SAMPLE", "PRODUCER_INSTITUTION_NAME", "SOURCE_FILE_NAME", "PROCESSING_LEVEL_ID", "TARGET_NAME", "LIMB_IN_IMAGE", "POLE_IN_IMAGE", "REFLECTANCE_SCALING_FACTOR", "SPICE_FILE_NAME", "SPACECRAFT_CENTRIC_LATITUDE", "SPACECRAFT_EASTERN_LONGITUDE", "FOOTPRINT_POSITIVE_LONGITUDE", NULL }; for( int i = 0; apszKeywords[i] != NULL; i++ ) { const char *pszKeywordValue = poDS->GetKeyword( apszKeywords[i] ); if( pszKeywordValue != NULL ) poDS->SetMetadataItem( apszKeywords[i], pszKeywordValue ); } } else if (bIsDTM && EQUAL( poDS->GetKeyword( "TARGET_NAME"), "VESTA" )) { poDS->SetMetadataItem( "SPACECRAFT_NAME", "DAWN" ); poDS->SetMetadataItem( "PRODUCT_TYPE", "DTM"); static const char *apszKeywords[] = { "DTM_MISSING_DN", "DTM_OFFSET", "DTM_SCALING_FACTOR", "DTM_A_AXIS_RADIUS", "DTM_B_AXIS_RADIUS", "DTM_C_AXIS_RADIUS", "DTM_MINIMUM_DN", "DTM_MAXIMUM_DN", "MAP_PROJECTION_TYPE", "COORDINATE_SYSTEM_NAME", "POSITIVE_LONGITUDE_DIRECTION", "MAP_SCALE", "CENTER_LONGITUDE", "LINE_PROJECTION_OFFSET", "SAMPLE_PROJECTION_OFFSET", NULL }; for( int i = 0; apszKeywords[i] != NULL; i++ ) { const char *pszKeywordValue = poDS->GetKeyword( apszKeywords[i] ); if( pszKeywordValue != NULL ) poDS->SetMetadataItem( apszKeywords[i], pszKeywordValue ); } } /* -------------------------------------------------------------------- */ /* END Instrument-specific keywords as metadata. */ /* -------------------------------------------------------------------- */ if (EQUAL(poDS->GetKeyword( "EOL"), "1" )) poDS->SetMetadataItem( "END-OF-DATASET_LABEL", "PRESENT" ); poDS->SetMetadataItem( "CONVERSION_DETAILS", "http://www.lpi.usra.edu/meetings/lpsc2014/pdf/1088.pdf" ); /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->TryLoadXML(); /* -------------------------------------------------------------------- */ /* Check for overviews. */ /* -------------------------------------------------------------------- */ poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename ); return( poDS ); }
GDALDataset *XYZDataset::Open( GDALOpenInfo * poOpenInfo ) { int i; int bHasHeaderLine; int nCommentLineCount = 0; if (!IdentifyEx(poOpenInfo, bHasHeaderLine, nCommentLineCount)) return NULL; CPLString osFilename(poOpenInfo->pszFilename); /* GZipped .xyz files are common, so automagically open them */ /* if the /vsigzip/ has not been explicitely passed */ if (strlen(poOpenInfo->pszFilename) > 6 && EQUAL(poOpenInfo->pszFilename + strlen(poOpenInfo->pszFilename) - 6, "xyz.gz") && !EQUALN(poOpenInfo->pszFilename, "/vsigzip/", 9)) { osFilename = "/vsigzip/"; osFilename += poOpenInfo->pszFilename; } /* -------------------------------------------------------------------- */ /* Find dataset characteristics */ /* -------------------------------------------------------------------- */ VSILFILE* fp = VSIFOpenL(osFilename.c_str(), "rb"); if (fp == NULL) return NULL; /* For better performance of CPLReadLine2L() we create a buffered reader */ /* (except for /vsigzip/ since it has one internally) */ if (!EQUALN(poOpenInfo->pszFilename, "/vsigzip/", 9)) fp = (VSILFILE*) VSICreateBufferedReaderHandle((VSIVirtualHandle*)fp); const char* pszLine; int nXIndex = -1, nYIndex = -1, nZIndex = -1; int nMinTokens = 0; for(i=0;i<nCommentLineCount;i++) CPLReadLine2L(fp, 100, NULL); /* -------------------------------------------------------------------- */ /* Parse header line */ /* -------------------------------------------------------------------- */ if (bHasHeaderLine) { pszLine = CPLReadLine2L(fp, 100, NULL); if (pszLine == NULL) { VSIFCloseL(fp); return NULL; } char** papszTokens = CSLTokenizeString2( pszLine, " ,\t;", CSLT_HONOURSTRINGS ); int nTokens = CSLCount(papszTokens); if (nTokens < 3) { CPLError(CE_Failure, CPLE_AppDefined, "At line %d, found %d tokens. Expected 3 at least", 1, nTokens); CSLDestroy(papszTokens); VSIFCloseL(fp); return NULL; } int i; for(i=0;i<nTokens;i++) { if (EQUAL(papszTokens[i], "x") || EQUALN(papszTokens[i], "lon", 3) || EQUALN(papszTokens[i], "east", 4)) nXIndex = i; else if (EQUAL(papszTokens[i], "y") || EQUALN(papszTokens[i], "lat", 3) || EQUALN(papszTokens[i], "north", 5)) nYIndex = i; else if (EQUAL(papszTokens[i], "z") || EQUALN(papszTokens[i], "alt", 3) || EQUAL(papszTokens[i], "height")) nZIndex = i; } CSLDestroy(papszTokens); papszTokens = NULL; if (nXIndex < 0 || nYIndex < 0 || nZIndex < 0) { CPLError(CE_Warning, CPLE_AppDefined, "Could not find one of the X, Y or Z column names in header line. Defaulting to the first 3 columns"); nXIndex = 0; nYIndex = 1; nZIndex = 2; } nMinTokens = 1 + MAX(MAX(nXIndex, nYIndex), nZIndex); } else { nXIndex = 0; nYIndex = 1; nZIndex = 2; nMinTokens = 3; } /* -------------------------------------------------------------------- */ /* Parse data lines */ /* -------------------------------------------------------------------- */ int nXSize = 0, nYSize = 0; int nLineNum = 0; int nDataLineNum = 0; double dfFirstX = 0; double dfX = 0, dfY = 0, dfZ = 0; double dfMinX = 0, dfMinY = 0, dfMaxX = 0, dfMaxY = 0; double dfLastX = 0, dfLastY = 0; double dfStepX = 0, dfStepY = 0; GDALDataType eDT = GDT_Byte; while((pszLine = CPLReadLine2L(fp, 100, NULL)) != NULL) { nLineNum ++; const char* pszPtr = pszLine; char ch; int nCol = 0; int bLastWasSep = TRUE; while((ch = *pszPtr) != '\0') { if (ch == ' ' || ch == ',' || ch == '\t' || ch == ';') { if (!bLastWasSep) nCol ++; bLastWasSep = TRUE; } else { if (bLastWasSep) { if (nCol == nXIndex) dfX = CPLAtofM(pszPtr); else if (nCol == nYIndex) dfY = CPLAtofM(pszPtr); else if (nCol == nZIndex && eDT != GDT_Float32) { dfZ = CPLAtofM(pszPtr); int nZ = (int)dfZ; if ((double)nZ != dfZ) { eDT = GDT_Float32; } else if ((eDT == GDT_Byte || eDT == GDT_Int16) && (nZ < 0 || nZ > 255)) { if (nZ < -32768 || nZ > 32767) eDT = GDT_Int32; else eDT = GDT_Int16; } } } bLastWasSep = FALSE; } pszPtr ++; } /* skip empty lines */ if (bLastWasSep && nCol == 0) { continue; } nDataLineNum ++; nCol ++; if (nCol < nMinTokens) { CPLError(CE_Failure, CPLE_AppDefined, "At line %d, found %d tokens. Expected %d at least", nLineNum, nCol, nMinTokens); VSIFCloseL(fp); return NULL; } if (nDataLineNum == 1) { dfFirstX = dfMinX = dfMaxX = dfX; dfMinY = dfMaxY = dfY; } else { if (dfX < dfMinX) dfMinX = dfX; if (dfX > dfMaxX) dfMaxX = dfX; if (dfY < dfMinY) dfMinY = dfY; if (dfY > dfMaxY) dfMaxY = dfY; } if (nDataLineNum == 2) { dfStepX = dfX - dfLastX; if (dfStepX <= 0) { CPLError(CE_Failure, CPLE_AppDefined, "Ungridded dataset: At line %d, X spacing was %f. Expected >0 value", nLineNum, dfStepX); VSIFCloseL(fp); return NULL; } } else if (nDataLineNum > 2) { double dfNewStepX = dfX - dfLastX; double dfNewStepY = dfY - dfLastY; if (dfNewStepY != 0) { nYSize ++; if (dfStepY == 0) { nXSize = nDataLineNum - 1; double dfAdjustedStepX = (dfMaxX - dfMinX) / (nXSize - 1); if (fabs(dfStepX - dfAdjustedStepX) > 1e-8) { CPLDebug("XYZ", "Adjusting stepx from %f to %f", dfStepX, dfAdjustedStepX); } dfStepX = dfAdjustedStepX; } if (dfStepY != 0 && fabs(dfX - dfFirstX) > 1e-8) { CPLError(CE_Failure, CPLE_AppDefined, "Ungridded dataset: At line %d, X is %f, where as %f was expected", nLineNum, dfX, dfFirstX); VSIFCloseL(fp); return NULL; } if (dfStepY != 0 && fabs(dfLastX - dfMaxX) > 1e-8) { CPLError(CE_Failure, CPLE_AppDefined, "Ungridded dataset: At line %d, X is %f, where as %f was expected", nLineNum - 1, dfLastX, dfMaxX); VSIFCloseL(fp); return NULL; } /*if (dfStepY != 0 && fabs(dfNewStepY - dfStepY) > 1e-8) { CPLError(CE_Failure, CPLE_AppDefined, "Ungridded dataset: At line %d, Y spacing was %f, whereas it was %f before", nLineNum, dfNewStepY, dfStepY); VSIFCloseL(fp); return NULL; }*/ dfStepY = dfNewStepY; } else if (dfNewStepX != 0) { /*if (dfStepX != 0 && fabs(dfNewStepX - dfStepX) > 1e-8) { CPLError(CE_Failure, CPLE_AppDefined, "At line %d, X spacing was %f, whereas it was %f before", nLineNum, dfNewStepX, dfStepX); VSIFCloseL(fp); return NULL; }*/ } } dfLastX = dfX; dfLastY = dfY; } nYSize ++; if (dfStepX == 0) { CPLError(CE_Failure, CPLE_AppDefined, "Couldn't determine X spacing"); VSIFCloseL(fp); return NULL; } if (dfStepY == 0) { CPLError(CE_Failure, CPLE_AppDefined, "Couldn't determine Y spacing"); VSIFCloseL(fp); return NULL; } double dfAdjustedStepY = ((dfStepY < 0) ? -1 : 1) * (dfMaxY - dfMinY) / (nYSize - 1); if (fabs(dfStepY - dfAdjustedStepY) > 1e-8) { CPLDebug("XYZ", "Adjusting stepy from %f to %f", dfStepY, dfAdjustedStepY); } dfStepY = dfAdjustedStepY; //CPLDebug("XYZ", "minx=%f maxx=%f stepx=%f", dfMinX, dfMaxX, dfStepX); //CPLDebug("XYZ", "miny=%f maxy=%f stepy=%f", dfMinY, dfMaxY, dfStepY); if (nDataLineNum != nXSize * nYSize) { CPLError(CE_Failure, CPLE_AppDefined, "Found %d lines. Expected %d", nDataLineNum,nXSize * nYSize); VSIFCloseL(fp); return NULL; } if (poOpenInfo->eAccess == GA_Update) { CPLError( CE_Failure, CPLE_NotSupported, "The XYZ driver does not support update access to existing" " datasets.\n" ); VSIFCloseL(fp); return NULL; } /* -------------------------------------------------------------------- */ /* Create a corresponding GDALDataset. */ /* -------------------------------------------------------------------- */ XYZDataset *poDS; poDS = new XYZDataset(); poDS->fp = fp; poDS->bHasHeaderLine = bHasHeaderLine; poDS->nCommentLineCount = nCommentLineCount; poDS->nXIndex = nXIndex; poDS->nYIndex = nYIndex; poDS->nZIndex = nZIndex; poDS->nMinTokens = nMinTokens; poDS->nRasterXSize = nXSize; poDS->nRasterYSize = nYSize; poDS->adfGeoTransform[0] = dfMinX - dfStepX / 2; poDS->adfGeoTransform[1] = dfStepX; poDS->adfGeoTransform[3] = (dfStepY < 0) ? dfMaxY - dfStepY / 2 : dfMinY - dfStepY / 2; poDS->adfGeoTransform[5] = dfStepY; if (!GDALCheckDatasetDimensions(poDS->nRasterXSize, poDS->nRasterYSize)) { delete poDS; return NULL; } /* -------------------------------------------------------------------- */ /* Create band information objects. */ /* -------------------------------------------------------------------- */ poDS->nBands = 1; for( i = 0; i < poDS->nBands; i++ ) poDS->SetBand( i+1, new XYZRasterBand( poDS, i+1, eDT ) ); /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->SetDescription( poOpenInfo->pszFilename ); poDS->TryLoadXML(); /* -------------------------------------------------------------------- */ /* Support overviews. */ /* -------------------------------------------------------------------- */ poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename ); return( poDS ); }
GDALDataset *SAGADataset::Create( const char * pszFilename, int nXSize, int nYSize, int nBands, GDALDataType eType, char **papszParmList ) { if( nXSize <= 0 || nYSize <= 0 ) { CPLError( CE_Failure, CPLE_IllegalArg, "Unable to create grid, both X and Y size must be " "non-negative.\n" ); return NULL; } if( nBands != 1 ) { CPLError( CE_Failure, CPLE_IllegalArg, "SAGA Binary Grid only supports 1 band" ); return NULL; } if( eType != GDT_Byte && eType != GDT_UInt16 && eType != GDT_Int16 && eType != GDT_UInt32 && eType != GDT_Int32 && eType != GDT_Float32 && eType != GDT_Float64 ) { CPLError( CE_Failure, CPLE_AppDefined, "SAGA Binary Grid only supports Byte, UInt16, Int16, " "UInt32, Int32, Float32 and Float64 datatypes. Unable to " "create with type %s.\n", GDALGetDataTypeName( eType ) ); return NULL; } VSILFILE *fp = VSIFOpenL( pszFilename, "w+b" ); if( fp == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Attempt to create file '%s' failed.\n", pszFilename ); return NULL; } char abyNoData[8]; double dfNoDataVal = 0.0; const char* pszNoDataValue = CSLFetchNameValue(papszParmList, "NODATA_VALUE"); if (pszNoDataValue) { dfNoDataVal = CPLAtofM(pszNoDataValue); } else { switch (eType) /* GDT_Byte, GDT_UInt16, GDT_Int16, GDT_UInt32 */ { /* GDT_Int32, GDT_Float32, GDT_Float64 */ case (GDT_Byte): { dfNoDataVal = SG_NODATA_GDT_Byte; break; } case (GDT_UInt16): { dfNoDataVal = SG_NODATA_GDT_UInt16; break; } case (GDT_Int16): { dfNoDataVal = SG_NODATA_GDT_Int16; break; } case (GDT_UInt32): { dfNoDataVal = SG_NODATA_GDT_UInt32; break; } case (GDT_Int32): { dfNoDataVal = SG_NODATA_GDT_Int32; break; } default: case (GDT_Float32): { dfNoDataVal = SG_NODATA_GDT_Float32; break; } case (GDT_Float64): { dfNoDataVal = SG_NODATA_GDT_Float64; break; } } } GDALCopyWords(&dfNoDataVal, GDT_Float64, 0, abyNoData, eType, 0, 1); CPLString osHdrFilename = CPLResetExtension( pszFilename, "sgrd" ); CPLErr eErr = WriteHeader( osHdrFilename, eType, nXSize, nYSize, 0.0, 0.0, 1.0, dfNoDataVal, 1.0, false ); if( eErr != CE_None ) { VSIFCloseL( fp ); return NULL; } if (CSLFetchBoolean( papszParmList , "FILL_NODATA", TRUE )) { int nDataTypeSize = GDALGetDataTypeSize(eType) / 8; GByte* pabyNoDataBuf = (GByte*) VSIMalloc2(nDataTypeSize, nXSize); if (pabyNoDataBuf == NULL) { VSIFCloseL( fp ); return NULL; } for( int iCol = 0; iCol < nXSize; iCol++) { memcpy(pabyNoDataBuf + iCol * nDataTypeSize, abyNoData, nDataTypeSize); } for( int iRow = 0; iRow < nYSize; iRow++ ) { if( VSIFWriteL( pabyNoDataBuf, nDataTypeSize, nXSize, fp ) != (unsigned)nXSize ) { VSIFCloseL( fp ); VSIFree(pabyNoDataBuf); CPLError( CE_Failure, CPLE_FileIO, "Unable to write grid cell. Disk full?\n" ); return NULL; } } VSIFree(pabyNoDataBuf); } VSIFCloseL( fp ); return (GDALDataset *)GDALOpen( pszFilename, GA_Update ); }
GDALDataset* HF2Dataset::CreateCopy( const char * pszFilename, GDALDataset *poSrcDS, int bStrict, char ** papszOptions, GDALProgressFunc pfnProgress, void * pProgressData ) { /* -------------------------------------------------------------------- */ /* Some some rudimentary checks */ /* -------------------------------------------------------------------- */ int nBands = poSrcDS->GetRasterCount(); if (nBands == 0) { CPLError( CE_Failure, CPLE_NotSupported, "HF2 driver does not support source dataset with zero band.\n"); return NULL; } if (nBands != 1) { CPLError( (bStrict) ? CE_Failure : CE_Warning, CPLE_NotSupported, "HF2 driver only uses the first band of the dataset.\n"); if (bStrict) return NULL; } if( pfnProgress && !pfnProgress( 0.0, NULL, pProgressData ) ) return NULL; /* -------------------------------------------------------------------- */ /* Get source dataset info */ /* -------------------------------------------------------------------- */ int nXSize = poSrcDS->GetRasterXSize(); int nYSize = poSrcDS->GetRasterYSize(); double adfGeoTransform[6]; poSrcDS->GetGeoTransform(adfGeoTransform); int bHasGeoTransform = !(adfGeoTransform[0] == 0 && adfGeoTransform[1] == 1 && adfGeoTransform[2] == 0 && adfGeoTransform[3] == 0 && adfGeoTransform[4] == 0 && adfGeoTransform[5] == 1); if (adfGeoTransform[2] != 0 || adfGeoTransform[4] != 0) { CPLError( CE_Failure, CPLE_NotSupported, "HF2 driver does not support CreateCopy() from skewed or rotated dataset.\n"); return NULL; } GDALDataType eSrcDT = poSrcDS->GetRasterBand(1)->GetRasterDataType(); GDALDataType eReqDT; float fVertPres = (float) 0.01; if (eSrcDT == GDT_Byte || eSrcDT == GDT_Int16) { fVertPres = 1; eReqDT = GDT_Int16; } else eReqDT = GDT_Float32; /* -------------------------------------------------------------------- */ /* Read creation options */ /* -------------------------------------------------------------------- */ const char* pszCompressed = CSLFetchNameValue(papszOptions, "COMPRESS"); int bCompress = FALSE; if (pszCompressed) bCompress = CSLTestBoolean(pszCompressed); const char* pszVerticalPrecision = CSLFetchNameValue(papszOptions, "VERTICAL_PRECISION"); if (pszVerticalPrecision) { fVertPres = (float) CPLAtofM(pszVerticalPrecision); if (fVertPres <= 0) { CPLError(CE_Warning, CPLE_AppDefined, "Unsupported value for VERTICAL_PRECISION. Defaulting to 0.01"); fVertPres = (float) 0.01; } if (eReqDT == GDT_Int16 && fVertPres > 1) eReqDT = GDT_Float32; } const char* pszBlockSize = CSLFetchNameValue(papszOptions, "BLOCKSIZE"); int nTileSize = 256; if (pszBlockSize) { nTileSize = atoi(pszBlockSize); if (nTileSize < 8 || nTileSize > 4096) { CPLError(CE_Warning, CPLE_AppDefined, "Unsupported value for BLOCKSIZE. Defaulting to 256"); nTileSize = 256; } } /* -------------------------------------------------------------------- */ /* Parse source dataset georeferencing info */ /* -------------------------------------------------------------------- */ int nExtendedHeaderLen = 0; if (bHasGeoTransform) nExtendedHeaderLen += 58; const char* pszProjectionRef = poSrcDS->GetProjectionRef(); int nDatumCode = -2; int nUTMZone = 0; int bNorth = FALSE; int nEPSGCode = 0; int nExtentUnits = 1; if (pszProjectionRef != NULL && pszProjectionRef[0] != '\0') { OGRSpatialReference oSRS; char* pszTemp = (char*) pszProjectionRef; if (oSRS.importFromWkt(&pszTemp) == OGRERR_NONE) { const char* pszValue = NULL; if( oSRS.GetAuthorityName( "GEOGCS|DATUM" ) != NULL && EQUAL(oSRS.GetAuthorityName( "GEOGCS|DATUM" ),"EPSG") ) nDatumCode = atoi(oSRS.GetAuthorityCode( "GEOGCS|DATUM" )); else if ((pszValue = oSRS.GetAttrValue("GEOGCS|DATUM")) != NULL) { if (strstr(pszValue, "WGS") && strstr(pszValue, "84")) nDatumCode = 6326; } nUTMZone = oSRS.GetUTMZone(&bNorth); } if( oSRS.GetAuthorityName( "PROJCS" ) != NULL && EQUAL(oSRS.GetAuthorityName( "PROJCS" ),"EPSG") ) nEPSGCode = atoi(oSRS.GetAuthorityCode( "PROJCS" )); if( oSRS.IsGeographic() ) { nExtentUnits = 0; } else { double dfLinear = oSRS.GetLinearUnits(); if( ABS(dfLinear - 0.3048) < 0.0000001 ) nExtentUnits = 2; else if( ABS(dfLinear - CPLAtof(SRS_UL_US_FOOT_CONV)) < 0.00000001 ) nExtentUnits = 3; else nExtentUnits = 1; } } if (nDatumCode != -2) nExtendedHeaderLen += 26; if (nUTMZone != 0) nExtendedHeaderLen += 26; if (nEPSGCode) nExtendedHeaderLen += 26; /* -------------------------------------------------------------------- */ /* Create target file */ /* -------------------------------------------------------------------- */ CPLString osFilename; if (bCompress) { osFilename = "/vsigzip/"; osFilename += pszFilename; } else osFilename = pszFilename; VSILFILE* fp = VSIFOpenL(osFilename.c_str(), "wb"); if (fp == NULL) { CPLError( CE_Failure, CPLE_AppDefined, "Cannot create %s", pszFilename ); return NULL; } /* -------------------------------------------------------------------- */ /* Write header */ /* -------------------------------------------------------------------- */ VSIFWriteL("HF2\0", 4, 1, fp); WriteShort(fp, 0); WriteInt(fp, nXSize); WriteInt(fp, nYSize); WriteShort(fp, (GInt16) nTileSize); WriteFloat(fp, fVertPres); float fHorizScale = (float) ((fabs(adfGeoTransform[1]) + fabs(adfGeoTransform[5])) / 2); WriteFloat(fp, fHorizScale); WriteInt(fp, nExtendedHeaderLen); /* -------------------------------------------------------------------- */ /* Write extended header */ /* -------------------------------------------------------------------- */ char szBlockName[16 + 1]; if (bHasGeoTransform) { VSIFWriteL("bin\0", 4, 1, fp); memset(szBlockName, 0, 16 + 1); strcpy(szBlockName, "georef-extents"); VSIFWriteL(szBlockName, 16, 1, fp); WriteInt(fp, 34); WriteShort(fp, (GInt16) nExtentUnits); WriteDouble(fp, adfGeoTransform[0]); WriteDouble(fp, adfGeoTransform[0] + nXSize * adfGeoTransform[1]); WriteDouble(fp, adfGeoTransform[3] + nYSize * adfGeoTransform[5]); WriteDouble(fp, adfGeoTransform[3]); } if (nUTMZone != 0) { VSIFWriteL("bin\0", 4, 1, fp); memset(szBlockName, 0, 16 + 1); strcpy(szBlockName, "georef-utm"); VSIFWriteL(szBlockName, 16, 1, fp); WriteInt(fp, 2); WriteShort(fp, (GInt16) ((bNorth) ? nUTMZone : -nUTMZone)); } if (nDatumCode != -2) { VSIFWriteL("bin\0", 4, 1, fp); memset(szBlockName, 0, 16 + 1); strcpy(szBlockName, "georef-datum"); VSIFWriteL(szBlockName, 16, 1, fp); WriteInt(fp, 2); WriteShort(fp, (GInt16) nDatumCode); } if (nEPSGCode != 0) { VSIFWriteL("bin\0", 4, 1, fp); memset(szBlockName, 0, 16 + 1); strcpy(szBlockName, "georef-epsg-prj"); VSIFWriteL(szBlockName, 16, 1, fp); WriteInt(fp, 2); WriteShort(fp, (GInt16) nEPSGCode); } /* -------------------------------------------------------------------- */ /* Copy imagery */ /* -------------------------------------------------------------------- */ int nXBlocks = (nXSize + nTileSize - 1) / nTileSize; int nYBlocks = (nYSize + nTileSize - 1) / nTileSize; void* pTileBuffer = (void*) VSIMalloc(nTileSize * nTileSize * (GDALGetDataTypeSize(eReqDT) / 8)); if (pTileBuffer == NULL) { CPLError( CE_Failure, CPLE_OutOfMemory, "Out of memory"); VSIFCloseL(fp); return NULL; } int i, j, k, l; CPLErr eErr = CE_None; for(j=0;j<nYBlocks && eErr == CE_None;j++) { for(i=0;i<nXBlocks && eErr == CE_None;i++) { int nReqXSize = MIN(nTileSize, nXSize - i * nTileSize); int nReqYSize = MIN(nTileSize, nYSize - j * nTileSize); eErr = poSrcDS->GetRasterBand(1)->RasterIO(GF_Read, i * nTileSize, MAX(0, nYSize - (j + 1) * nTileSize), nReqXSize, nReqYSize, pTileBuffer, nReqXSize, nReqYSize, eReqDT, 0, 0, NULL); if (eErr != CE_None) break; if (eReqDT == GDT_Int16) { WriteFloat(fp, 1); /* scale */ WriteFloat(fp, 0); /* offset */ for(k=0;k<nReqYSize;k++) { int nLastVal = ((short*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + 0]; GByte nWordSize = 1; for(l=1;l<nReqXSize;l++) { int nVal = ((short*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + l]; int nDiff = nVal - nLastVal; if (nDiff < -32768 || nDiff > 32767) { nWordSize = 4; break; } if (nDiff < -128 || nDiff > 127) nWordSize = 2; nLastVal = nVal; } VSIFWriteL(&nWordSize, 1, 1, fp); nLastVal = ((short*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + 0]; WriteInt(fp, nLastVal); for(l=1;l<nReqXSize;l++) { int nVal = ((short*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + l]; int nDiff = nVal - nLastVal; if (nWordSize == 1) { CPLAssert(nDiff >= -128 && nDiff <= 127); signed char chDiff = (signed char)nDiff; VSIFWriteL(&chDiff, 1, 1, fp); } else if (nWordSize == 2) { CPLAssert(nDiff >= -32768 && nDiff <= 32767); WriteShort(fp, (short)nDiff); } else { WriteInt(fp, nDiff); } nLastVal = nVal; } } } else { float fMinVal = ((float*)pTileBuffer)[0]; float fMaxVal = fMinVal; for(k=1;k<nReqYSize*nReqXSize;k++) { float fVal = ((float*)pTileBuffer)[k]; if (fVal < fMinVal) fMinVal = fVal; if (fVal > fMaxVal) fMaxVal = fVal; } float fIntRange = (fMaxVal - fMinVal) / fVertPres; float fScale = (fMinVal == fMaxVal) ? 1 : (fMaxVal - fMinVal) / fIntRange; float fOffset = fMinVal; WriteFloat(fp, fScale); /* scale */ WriteFloat(fp, fOffset); /* offset */ for(k=0;k<nReqYSize;k++) { float fLastVal = ((float*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + 0]; float fIntLastVal = (fLastVal - fOffset) / fScale; CPLAssert(fIntLastVal >= -2147483648.0f && fIntLastVal <= 2147483647.0f); int nLastVal = (int)fIntLastVal; GByte nWordSize = 1; for(l=1;l<nReqXSize;l++) { float fVal = ((float*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + l]; float fIntVal = (fVal - fOffset) / fScale; CPLAssert(fIntVal >= -2147483648.0f && fIntVal <= 2147483647.0f); int nVal = (int)fIntVal; int nDiff = nVal - nLastVal; CPLAssert((int)((GIntBig)nVal - nLastVal) == nDiff); if (nDiff < -32768 || nDiff > 32767) { nWordSize = 4; break; } if (nDiff < -128 || nDiff > 127) nWordSize = 2; nLastVal = nVal; } VSIFWriteL(&nWordSize, 1, 1, fp); fLastVal = ((float*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + 0]; fIntLastVal = (fLastVal - fOffset) / fScale; nLastVal = (int)fIntLastVal; WriteInt(fp, nLastVal); for(l=1;l<nReqXSize;l++) { float fVal = ((float*)pTileBuffer)[(nReqYSize - k - 1) * nReqXSize + l]; float fIntVal = (fVal - fOffset) / fScale; int nVal = (int)fIntVal; int nDiff = nVal - nLastVal; CPLAssert((int)((GIntBig)nVal - nLastVal) == nDiff); if (nWordSize == 1) { CPLAssert(nDiff >= -128 && nDiff <= 127); signed char chDiff = (signed char)nDiff; VSIFWriteL(&chDiff, 1, 1, fp); } else if (nWordSize == 2) { CPLAssert(nDiff >= -32768 && nDiff <= 32767); WriteShort(fp, (short)nDiff); } else { WriteInt(fp, nDiff); } nLastVal = nVal; } } } if( pfnProgress && !pfnProgress( (j * nXBlocks + i + 1) * 1.0 / (nXBlocks * nYBlocks), NULL, pProgressData ) ) { eErr = CE_Failure; break; } } } CPLFree(pTileBuffer); VSIFCloseL(fp); if (eErr != CE_None) return NULL; return (GDALDataset*) GDALOpen(osFilename.c_str(), GA_ReadOnly); }
GDALDataset *SNODASDataset::Open( GDALOpenInfo * poOpenInfo ) { if( !Identify(poOpenInfo) ) return NULL; VSILFILE *fp; fp = VSIFOpenL( poOpenInfo->pszFilename, "r" ); if( fp == NULL ) { return NULL; } const char * pszLine; int nRows = -1, nCols = -1; CPLString osDataFilename; int bIsInteger = FALSE, bIs2Bytes = FALSE; double dfNoData = 0; int bHasNoData = FALSE; double dfMin = 0; int bHasMin = FALSE; double dfMax = 0; int bHasMax = FALSE; double dfMinX = 0.0, dfMinY = 0.0, dfMaxX = 0.0, dfMaxY = 0.0; int bHasMinX = FALSE, bHasMinY = FALSE, bHasMaxX = FALSE, bHasMaxY = FALSE; int bNotProjected = FALSE, bIsWGS84 = FALSE; CPLString osDescription, osDataUnits; int nStartYear = -1, nStartMonth = -1, nStartDay = -1, nStartHour = -1, nStartMinute = -1, nStartSecond = -1; int nStopYear = -1, nStopMonth = -1, nStopDay = -1, nStopHour = -1, nStopMinute = -1, nStopSecond = -1; while( (pszLine = CPLReadLine2L( fp, 256, NULL )) != NULL ) { char** papszTokens = CSLTokenizeStringComplex( pszLine, ":", TRUE, FALSE ); if( CSLCount( papszTokens ) != 2 ) { CSLDestroy( papszTokens ); continue; } if( papszTokens[1][0] == ' ' ) memmove(papszTokens[1], papszTokens[1] + 1, strlen(papszTokens[1] + 1) + 1); if( EQUAL(papszTokens[0],"Data file pathname") ) { osDataFilename = papszTokens[1]; } else if( EQUAL(papszTokens[0],"Description") ) { osDescription = papszTokens[1]; } else if( EQUAL(papszTokens[0],"Data units") ) { osDataUnits= papszTokens[1]; } else if( EQUAL(papszTokens[0],"Start year") ) nStartYear = atoi(papszTokens[1]); else if( EQUAL(papszTokens[0],"Start month") ) nStartMonth = atoi(papszTokens[1]); else if( EQUAL(papszTokens[0],"Start day") ) nStartDay = atoi(papszTokens[1]); else if( EQUAL(papszTokens[0],"Start hour") ) nStartHour = atoi(papszTokens[1]); else if( EQUAL(papszTokens[0],"Start minute") ) nStartMinute = atoi(papszTokens[1]); else if( EQUAL(papszTokens[0],"Start second") ) nStartSecond = atoi(papszTokens[1]); else if( EQUAL(papszTokens[0],"Stop year") ) nStopYear = atoi(papszTokens[1]); else if( EQUAL(papszTokens[0],"Stop month") ) nStopMonth = atoi(papszTokens[1]); else if( EQUAL(papszTokens[0],"Stop day") ) nStopDay = atoi(papszTokens[1]); else if( EQUAL(papszTokens[0],"Stop hour") ) nStopHour = atoi(papszTokens[1]); else if( EQUAL(papszTokens[0],"Stop minute") ) nStopMinute = atoi(papszTokens[1]); else if( EQUAL(papszTokens[0],"Stop second") ) nStopSecond = atoi(papszTokens[1]); else if( EQUAL(papszTokens[0],"Number of columns") ) { nCols = atoi(papszTokens[1]); } else if( EQUAL(papszTokens[0],"Number of rows") ) { nRows = atoi(papszTokens[1]); } else if( EQUAL(papszTokens[0],"Data type")) { bIsInteger = EQUAL(papszTokens[1],"integer"); } else if( EQUAL(papszTokens[0],"Data bytes per pixel")) { bIs2Bytes = EQUAL(papszTokens[1],"2"); } else if( EQUAL(papszTokens[0],"Projected")) { bNotProjected = EQUAL(papszTokens[1],"no"); } else if( EQUAL(papszTokens[0],"Horizontal datum")) { bIsWGS84 = EQUAL(papszTokens[1],"WGS84"); } else if( EQUAL(papszTokens[0],"No data value")) { bHasNoData = TRUE; dfNoData = CPLAtofM(papszTokens[1]); } else if( EQUAL(papszTokens[0],"Minimum data value")) { bHasMin = TRUE; dfMin = CPLAtofM(papszTokens[1]); } else if( EQUAL(papszTokens[0],"Maximum data value")) { bHasMax = TRUE; dfMax = CPLAtofM(papszTokens[1]); } else if( EQUAL(papszTokens[0],"Minimum x-axis coordinate") ) { bHasMinX = TRUE; dfMinX = CPLAtofM(papszTokens[1]); } else if( EQUAL(papszTokens[0],"Minimum y-axis coordinate") ) { bHasMinY = TRUE; dfMinY = CPLAtofM(papszTokens[1]); } else if( EQUAL(papszTokens[0],"Maximum x-axis coordinate") ) { bHasMaxX = TRUE; dfMaxX = CPLAtofM(papszTokens[1]); } else if( EQUAL(papszTokens[0],"Maximum y-axis coordinate") ) { bHasMaxY = TRUE; dfMaxY = CPLAtofM(papszTokens[1]); } CSLDestroy( papszTokens ); } VSIFCloseL( fp ); /* -------------------------------------------------------------------- */ /* Did we get the required keywords? If not we return with */ /* this never having been considered to be a match. This isn't */ /* an error! */ /* -------------------------------------------------------------------- */ if( nRows == -1 || nCols == -1 || !bIsInteger || !bIs2Bytes ) return NULL; if( !bNotProjected || !bIsWGS84 ) return NULL; if( osDataFilename.size() == 0 ) return NULL; if (!GDALCheckDatasetDimensions(nCols, nRows)) return NULL; /* -------------------------------------------------------------------- */ /* Open target binary file. */ /* -------------------------------------------------------------------- */ const char* pszPath = CPLGetPath(poOpenInfo->pszFilename); osDataFilename = CPLFormFilename(pszPath, osDataFilename, NULL); VSILFILE* fpRaw = VSIFOpenL( osDataFilename, "rb" ); if( fpRaw == NULL ) return NULL; /* -------------------------------------------------------------------- */ /* Create a corresponding GDALDataset. */ /* -------------------------------------------------------------------- */ SNODASDataset *poDS; poDS = new SNODASDataset(); poDS->nRasterXSize = nCols; poDS->nRasterYSize = nRows; poDS->osDataFilename = osDataFilename; poDS->bHasNoData = bHasNoData; poDS->dfNoData = dfNoData; poDS->bHasMin = bHasMin; poDS->dfMin = dfMin; poDS->bHasMax = bHasMax; poDS->dfMax = dfMax; if (bHasMinX && bHasMinY && bHasMaxX && bHasMaxY) { poDS->bGotTransform = TRUE; poDS->adfGeoTransform[0] = dfMinX; poDS->adfGeoTransform[1] = (dfMaxX - dfMinX) / nCols; poDS->adfGeoTransform[2] = 0.0; poDS->adfGeoTransform[3] = dfMaxY; poDS->adfGeoTransform[4] = 0.0; poDS->adfGeoTransform[5] = - (dfMaxY - dfMinY) / nRows; } if (osDescription.size()) poDS->SetMetadataItem("Description", osDescription); if (osDataUnits.size()) poDS->SetMetadataItem("Data_Units", osDataUnits); if (nStartYear != -1 && nStartMonth != -1 && nStartDay != -1 && nStartHour != -1 && nStartMinute != -1 && nStartSecond != -1) poDS->SetMetadataItem("Start_Date", CPLSPrintf("%04d/%02d/%02d %02d:%02d:%02d", nStartYear, nStartMonth, nStartDay, nStartHour, nStartMinute, nStartSecond)); if (nStopYear != -1 && nStopMonth != -1 && nStopDay != -1 && nStopHour != -1 && nStopMinute != -1 && nStopSecond != -1) poDS->SetMetadataItem("Stop_Date", CPLSPrintf("%04d/%02d/%02d %02d:%02d:%02d", nStopYear, nStopMonth, nStopDay, nStopHour, nStopMinute, nStopSecond)); /* -------------------------------------------------------------------- */ /* Create band information objects. */ /* -------------------------------------------------------------------- */ poDS->SetBand( 1, new SNODASRasterBand( fpRaw, nCols, nRows) ); /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->SetDescription( poOpenInfo->pszFilename ); poDS->TryLoadXML(); /* -------------------------------------------------------------------- */ /* Check for overviews. */ /* -------------------------------------------------------------------- */ poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename ); return( poDS ); }
GDALDataset *ZMapDataset::Open( GDALOpenInfo * poOpenInfo ) { if (!Identify(poOpenInfo)) return NULL; /* -------------------------------------------------------------------- */ /* Find dataset characteristics */ /* -------------------------------------------------------------------- */ VSILFILE* fp = VSIFOpenL(poOpenInfo->pszFilename, "rb"); if (fp == NULL) return NULL; const char* pszLine; while((pszLine = CPLReadLine2L(fp, 100, NULL)) != NULL) { if (*pszLine == '!') { continue; } else break; } if (pszLine == NULL) { VSIFCloseL(fp); return NULL; } /* Parse first header line */ char** papszTokens = CSLTokenizeString2( pszLine, ",", 0 ); if (CSLCount(papszTokens) != 3) { CSLDestroy(papszTokens); VSIFCloseL(fp); return NULL; } int nValuesPerLine = atoi(papszTokens[2]); if (nValuesPerLine <= 0) { CSLDestroy(papszTokens); VSIFCloseL(fp); return NULL; } CSLDestroy(papszTokens); papszTokens = NULL; /* Parse second header line */ pszLine = CPLReadLine2L(fp, 100, NULL); if (pszLine == NULL) { VSIFCloseL(fp); return NULL; } papszTokens = CSLTokenizeString2( pszLine, ",", 0 ); if (CSLCount(papszTokens) != 5) { CSLDestroy(papszTokens); VSIFCloseL(fp); return NULL; } int nFieldSize = atoi(papszTokens[0]); double dfNoDataValue = CPLAtofM(papszTokens[1]); int nDecimalCount = atoi(papszTokens[3]); int nColumnNumber = atoi(papszTokens[4]); CSLDestroy(papszTokens); papszTokens = NULL; if (nFieldSize <= 0 || nFieldSize >= 40 || nDecimalCount <= 0 || nDecimalCount >= nFieldSize || nColumnNumber != 1) { CPLDebug("ZMap", "nFieldSize=%d, nDecimalCount=%d, nColumnNumber=%d", nFieldSize, nDecimalCount, nColumnNumber); VSIFCloseL(fp); return NULL; } /* Parse third header line */ pszLine = CPLReadLine2L(fp, 100, NULL); if (pszLine == NULL) { VSIFCloseL(fp); return NULL; } papszTokens = CSLTokenizeString2( pszLine, ",", 0 ); if (CSLCount(papszTokens) != 6) { CSLDestroy(papszTokens); VSIFCloseL(fp); return NULL; } int nRows = atoi(papszTokens[0]); int nCols = atoi(papszTokens[1]); double dfMinX = CPLAtofM(papszTokens[2]); double dfMaxX = CPLAtofM(papszTokens[3]); double dfMinY = CPLAtofM(papszTokens[4]); double dfMaxY = CPLAtofM(papszTokens[5]); CSLDestroy(papszTokens); papszTokens = NULL; if (!GDALCheckDatasetDimensions(nCols, nRows) || nCols == 1 || nRows == 1) { VSIFCloseL(fp); return NULL; } /* Ignore fourth header line */ pszLine = CPLReadLine2L(fp, 100, NULL); if (pszLine == NULL) { VSIFCloseL(fp); return NULL; } /* Check fifth header line */ pszLine = CPLReadLine2L(fp, 100, NULL); if (pszLine == NULL || pszLine[0] != '@') { VSIFCloseL(fp); return NULL; } /* -------------------------------------------------------------------- */ /* Create a corresponding GDALDataset. */ /* -------------------------------------------------------------------- */ ZMapDataset *poDS; poDS = new ZMapDataset(); poDS->fp = fp; poDS->nDataStartOff = VSIFTellL(fp); poDS->nValuesPerLine = nValuesPerLine; poDS->nFieldSize = nFieldSize; poDS->nDecimalCount = nDecimalCount; poDS->nRasterXSize = nCols; poDS->nRasterYSize = nRows; poDS->dfNoDataValue = dfNoDataValue; if (CSLTestBoolean(CPLGetConfigOption("ZMAP_PIXEL_IS_POINT", "FALSE"))) { double dfStepX = (dfMaxX - dfMinX) / (nCols - 1); double dfStepY = (dfMaxY - dfMinY) / (nRows - 1); poDS->adfGeoTransform[0] = dfMinX - dfStepX / 2; poDS->adfGeoTransform[1] = dfStepX; poDS->adfGeoTransform[3] = dfMaxY + dfStepY / 2; poDS->adfGeoTransform[5] = -dfStepY; } else { double dfStepX = (dfMaxX - dfMinX) / nCols ; double dfStepY = (dfMaxY - dfMinY) / nRows; poDS->adfGeoTransform[0] = dfMinX; poDS->adfGeoTransform[1] = dfStepX; poDS->adfGeoTransform[3] = dfMaxY; poDS->adfGeoTransform[5] = -dfStepY; } /* -------------------------------------------------------------------- */ /* Create band information objects. */ /* -------------------------------------------------------------------- */ poDS->nBands = 1; poDS->SetBand( 1, new ZMapRasterBand( poDS ) ); /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->SetDescription( poOpenInfo->pszFilename ); poDS->TryLoadXML(); /* -------------------------------------------------------------------- */ /* Support overviews. */ /* -------------------------------------------------------------------- */ poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename ); return( poDS ); }
CPLErr ParseAlgorithmAndOptions(const char *pszAlgoritm, GDALGridAlgorithm *peAlgorithm, void **ppOptions) { char **papszParms = CSLTokenizeString2(pszAlgoritm, ":", FALSE); if (CSLCount(papszParms) < 1) return CE_Failure; if (EQUAL(papszParms[0], szAlgNameInvDist)) *peAlgorithm = GGA_InverseDistanceToAPower; else if (EQUAL(papszParms[0], szAlgNameAverage)) *peAlgorithm = GGA_MovingAverage; else if (EQUAL(papszParms[0], szAlgNameNearest)) *peAlgorithm = GGA_NearestNeighbor; else if (EQUAL(papszParms[0], szAlgNameMinimum)) *peAlgorithm = GGA_MetricMinimum; else if (EQUAL(papszParms[0], szAlgNameMaximum)) *peAlgorithm = GGA_MetricMaximum; else if (EQUAL(papszParms[0], szAlgNameRange)) *peAlgorithm = GGA_MetricRange; else if (EQUAL(papszParms[0], szAlgNameCount)) *peAlgorithm = GGA_MetricCount; else if (EQUAL(papszParms[0], szAlgNameAverageDistance)) *peAlgorithm = GGA_MetricAverageDistance; else if (EQUAL(papszParms[0], szAlgNameAverageDistancePts)) *peAlgorithm = GGA_MetricAverageDistancePts; else { fprintf(stderr, "Unsupported gridding method \"%s\".\n", papszParms[0]); CSLDestroy(papszParms); return CE_Failure; } /* -------------------------------------------------------------------- */ /* Parse algorithm parameters and assign defaults. */ /* -------------------------------------------------------------------- */ const char *pszValue; switch (*peAlgorithm) { case GGA_InverseDistanceToAPower: default: *ppOptions = CPLMalloc(sizeof(GDALGridInverseDistanceToAPowerOptions)); pszValue = CSLFetchNameValue(papszParms, "power"); ((GDALGridInverseDistanceToAPowerOptions*)*ppOptions)-> dfPower = (pszValue) ? CPLAtofM(pszValue) : 2.0; pszValue = CSLFetchNameValue(papszParms, "smoothing"); ((GDALGridInverseDistanceToAPowerOptions*)*ppOptions)-> dfSmoothing = (pszValue) ? CPLAtofM(pszValue) : 0.0; pszValue = CSLFetchNameValue(papszParms, "radius1"); ((GDALGridInverseDistanceToAPowerOptions*)*ppOptions)-> dfRadius1 = (pszValue) ? CPLAtofM(pszValue) : 0.0; pszValue = CSLFetchNameValue(papszParms, "radius2"); ((GDALGridInverseDistanceToAPowerOptions*)*ppOptions)-> dfRadius2 = (pszValue) ? CPLAtofM(pszValue) : 0.0; pszValue = CSLFetchNameValue(papszParms, "angle"); ((GDALGridInverseDistanceToAPowerOptions*)*ppOptions)-> dfAngle = (pszValue) ? CPLAtofM(pszValue) : 0.0; pszValue = CSLFetchNameValue(papszParms, "max_points"); ((GDALGridInverseDistanceToAPowerOptions*)*ppOptions)-> nMaxPoints = (GUInt32) ((pszValue) ? CPLAtofM(pszValue) : 0); pszValue = CSLFetchNameValue(papszParms, "min_points"); ((GDALGridInverseDistanceToAPowerOptions*)*ppOptions)-> nMinPoints = (GUInt32) ((pszValue) ? CPLAtofM(pszValue) : 0); pszValue = CSLFetchNameValue(papszParms, "nodata"); ((GDALGridInverseDistanceToAPowerOptions*)*ppOptions)-> dfNoDataValue = (pszValue) ? CPLAtofM(pszValue) : 0.0; break; case GGA_MovingAverage: *ppOptions = CPLMalloc(sizeof(GDALGridMovingAverageOptions)); pszValue = CSLFetchNameValue(papszParms, "radius1"); ((GDALGridMovingAverageOptions*)*ppOptions)-> dfRadius1 = (pszValue) ? CPLAtofM(pszValue) : 0.0; pszValue = CSLFetchNameValue(papszParms, "radius2"); ((GDALGridMovingAverageOptions*)*ppOptions)-> dfRadius2 = (pszValue) ? CPLAtofM(pszValue) : 0.0; pszValue = CSLFetchNameValue(papszParms, "angle"); ((GDALGridMovingAverageOptions*)*ppOptions)-> dfAngle = (pszValue) ? CPLAtofM(pszValue) : 0.0; pszValue = CSLFetchNameValue(papszParms, "min_points"); ((GDALGridMovingAverageOptions*)*ppOptions)-> nMinPoints = (GUInt32) ((pszValue) ? CPLAtofM(pszValue) : 0); pszValue = CSLFetchNameValue(papszParms, "nodata"); ((GDALGridMovingAverageOptions*)*ppOptions)-> dfNoDataValue = (pszValue) ? CPLAtofM(pszValue) : 0.0; break; case GGA_NearestNeighbor: *ppOptions = CPLMalloc(sizeof(GDALGridNearestNeighborOptions)); pszValue = CSLFetchNameValue(papszParms, "radius1"); ((GDALGridNearestNeighborOptions*)*ppOptions)-> dfRadius1 = (pszValue) ? CPLAtofM(pszValue) : 0.0; pszValue = CSLFetchNameValue(papszParms, "radius2"); ((GDALGridNearestNeighborOptions*)*ppOptions)-> dfRadius2 = (pszValue) ? CPLAtofM(pszValue) : 0.0; pszValue = CSLFetchNameValue(papszParms, "angle"); ((GDALGridNearestNeighborOptions*)*ppOptions)-> dfAngle = (pszValue) ? CPLAtofM(pszValue) : 0.0; pszValue = CSLFetchNameValue(papszParms, "nodata"); ((GDALGridNearestNeighborOptions*)*ppOptions)-> dfNoDataValue = (pszValue) ? CPLAtofM(pszValue) : 0.0; break; case GGA_MetricMinimum: case GGA_MetricMaximum: case GGA_MetricRange: case GGA_MetricCount: case GGA_MetricAverageDistance: case GGA_MetricAverageDistancePts: *ppOptions = CPLMalloc(sizeof(GDALGridDataMetricsOptions)); pszValue = CSLFetchNameValue(papszParms, "radius1"); ((GDALGridDataMetricsOptions*)*ppOptions)-> dfRadius1 = (pszValue) ? CPLAtofM(pszValue) : 0.0; pszValue = CSLFetchNameValue(papszParms, "radius2"); ((GDALGridDataMetricsOptions*)*ppOptions)-> dfRadius2 = (pszValue) ? CPLAtofM(pszValue) : 0.0; pszValue = CSLFetchNameValue(papszParms, "angle"); ((GDALGridDataMetricsOptions*)*ppOptions)-> dfAngle = (pszValue) ? CPLAtofM(pszValue) : 0.0; pszValue = CSLFetchNameValue(papszParms, "min_points"); ((GDALGridDataMetricsOptions*)*ppOptions)-> nMinPoints = (pszValue) ? atol(pszValue) : 0; pszValue = CSLFetchNameValue(papszParms, "nodata"); ((GDALGridDataMetricsOptions*)*ppOptions)-> dfNoDataValue = (pszValue) ? CPLAtofM(pszValue) : 0.0; break; } CSLDestroy(papszParms); return CE_None; }
CPLErr GDALPamRasterBand::XMLInit( CPLXMLNode *psTree, const char * /* pszUnused */ ) { PamInitialize(); /* -------------------------------------------------------------------- */ /* Apply any dataset level metadata. */ /* -------------------------------------------------------------------- */ oMDMD.XMLInit( psTree, TRUE ); /* -------------------------------------------------------------------- */ /* Collect various other items of metadata. */ /* -------------------------------------------------------------------- */ GDALMajorObject::SetDescription( CPLGetXMLValue( psTree, "Description", "" ) ); if( CPLGetXMLValue( psTree, "NoDataValue", nullptr ) != nullptr ) { const char *pszLEHex = CPLGetXMLValue( psTree, "NoDataValue.le_hex_equiv", nullptr ); if( pszLEHex != nullptr ) { int nBytes; GByte *pabyBin = CPLHexToBinary( pszLEHex, &nBytes ); if( nBytes == 8 ) { CPL_LSBPTR64( pabyBin ); GDALPamRasterBand::SetNoDataValue( *reinterpret_cast<const double*>(pabyBin) ); } else { GDALPamRasterBand::SetNoDataValue( CPLAtof(CPLGetXMLValue( psTree, "NoDataValue", "0" )) ); } CPLFree( pabyBin ); } else { GDALPamRasterBand::SetNoDataValue( CPLAtof(CPLGetXMLValue( psTree, "NoDataValue", "0" )) ); } } GDALPamRasterBand::SetOffset( CPLAtof(CPLGetXMLValue( psTree, "Offset", "0.0" )) ); GDALPamRasterBand::SetScale( CPLAtof(CPLGetXMLValue( psTree, "Scale", "1.0" )) ); GDALPamRasterBand::SetUnitType( CPLGetXMLValue( psTree, "UnitType", nullptr)); if( CPLGetXMLValue( psTree, "ColorInterp", nullptr ) != nullptr ) { const char *pszInterp = CPLGetXMLValue( psTree, "ColorInterp", nullptr ); GDALPamRasterBand::SetColorInterpretation( GDALGetColorInterpretationByName(pszInterp)); } /* -------------------------------------------------------------------- */ /* Category names. */ /* -------------------------------------------------------------------- */ if( CPLGetXMLNode( psTree, "CategoryNames" ) != nullptr ) { CPLStringList oCategoryNames; for( CPLXMLNode *psEntry = CPLGetXMLNode( psTree, "CategoryNames" )->psChild; psEntry != nullptr; psEntry = psEntry->psNext ) { /* Don't skeep <Category> tag with empty content */ if( psEntry->eType != CXT_Element || !EQUAL(psEntry->pszValue,"Category") || (psEntry->psChild != nullptr && psEntry->psChild->eType != CXT_Text) ) continue; oCategoryNames.AddString( psEntry->psChild ? psEntry->psChild->pszValue : "" ); } GDALPamRasterBand::SetCategoryNames( oCategoryNames.List() ); } /* -------------------------------------------------------------------- */ /* Collect a color table. */ /* -------------------------------------------------------------------- */ if( CPLGetXMLNode( psTree, "ColorTable" ) != nullptr ) { GDALColorTable oTable; int iEntry = 0; for( CPLXMLNode *psEntry = CPLGetXMLNode( psTree, "ColorTable" )->psChild; psEntry != nullptr; psEntry = psEntry->psNext ) { if( !(psEntry->eType == CXT_Element && EQUAL(psEntry->pszValue, "Entry")) ) { continue; } GDALColorEntry sCEntry = { static_cast<short>(atoi(CPLGetXMLValue( psEntry, "c1", "0" ))), static_cast<short>(atoi(CPLGetXMLValue( psEntry, "c2", "0" ))), static_cast<short>(atoi(CPLGetXMLValue( psEntry, "c3", "0" ))), static_cast<short>(atoi(CPLGetXMLValue( psEntry, "c4", "255" ))) }; oTable.SetColorEntry( iEntry++, &sCEntry ); } GDALPamRasterBand::SetColorTable( &oTable ); } /* -------------------------------------------------------------------- */ /* Do we have a complete set of stats? */ /* -------------------------------------------------------------------- */ if( CPLGetXMLNode( psTree, "Minimum" ) != nullptr && CPLGetXMLNode( psTree, "Maximum" ) != nullptr ) { psPam->bHaveMinMax = TRUE; psPam->dfMin = CPLAtofM(CPLGetXMLValue(psTree, "Minimum","0")); psPam->dfMax = CPLAtofM(CPLGetXMLValue(psTree, "Maximum","0")); } if( CPLGetXMLNode( psTree, "Mean" ) != nullptr && CPLGetXMLNode( psTree, "StandardDeviation" ) != nullptr ) { psPam->bHaveStats = TRUE; psPam->dfMean = CPLAtofM(CPLGetXMLValue(psTree, "Mean","0")); psPam->dfStdDev = CPLAtofM(CPLGetXMLValue(psTree, "StandardDeviation", "0")); } /* -------------------------------------------------------------------- */ /* Histograms */ /* -------------------------------------------------------------------- */ CPLXMLNode *psHist = CPLGetXMLNode( psTree, "Histograms" ); if( psHist != nullptr ) { CPLXMLNode *psNext = psHist->psNext; psHist->psNext = nullptr; if( psPam->psSavedHistograms != nullptr ) { CPLDestroyXMLNode (psPam->psSavedHistograms ); psPam->psSavedHistograms = nullptr; } psPam->psSavedHistograms = CPLCloneXMLTree( psHist ); psHist->psNext = psNext; } /* -------------------------------------------------------------------- */ /* Raster Attribute Table */ /* -------------------------------------------------------------------- */ CPLXMLNode *psRAT = CPLGetXMLNode( psTree, "GDALRasterAttributeTable" ); if( psRAT != nullptr ) { if( psPam->poDefaultRAT != nullptr ) { delete psPam->poDefaultRAT; psPam->poDefaultRAT = nullptr; } psPam->poDefaultRAT = new GDALDefaultRasterAttributeTable(); psPam->poDefaultRAT->XMLInit( psRAT, "" ); } return CE_None; }
int main( int nArgc, char ** papszArgv ) { // register drivers GDALAllRegister(); if( nArgc < 2 ) return EXIT_FAILURE; double dfaCornersX[5] = {0}; double dfaCornersY[5] = {0}; CPLString sFileName; // parse input values for( int iArg = 1; iArg < nArgc; iArg++ ) { if( EQUAL(papszArgv[iArg],"-nw")) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(2); const char* pszCoord = papszArgv[++iArg]; dfaCornersY[1] = CPLAtofM(pszCoord); pszCoord = papszArgv[++iArg]; dfaCornersX[1] = CPLAtofM(pszCoord); } else if( EQUAL(papszArgv[iArg],"-ne")) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(2); const char* pszCoord = papszArgv[++iArg]; dfaCornersY[2] = CPLAtofM(pszCoord); pszCoord = papszArgv[++iArg]; dfaCornersX[2] = CPLAtofM(pszCoord); } else if( EQUAL(papszArgv[iArg],"-se")) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(2); const char* pszCoord = papszArgv[++iArg]; dfaCornersY[3] = CPLAtofM(pszCoord); pszCoord = papszArgv[++iArg]; dfaCornersX[3] = CPLAtofM(pszCoord); } else if( EQUAL(papszArgv[iArg],"-sw")) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(2); const char* pszCoord = papszArgv[++iArg]; dfaCornersY[4] = CPLAtofM(pszCoord); pszCoord = papszArgv[++iArg]; dfaCornersX[4] = CPLAtofM(pszCoord); } else if( EQUAL(papszArgv[iArg],"-c")) { CHECK_HAS_ENOUGH_ADDITIONAL_ARGS(2); const char* pszCoord = papszArgv[++iArg]; dfaCornersY[0] = CPLAtofM(pszCoord); pszCoord = papszArgv[++iArg]; dfaCornersX[0] = CPLAtofM(pszCoord); } else if(sFileName.empty()) sFileName = papszArgv[iArg]; } OGRSpatialReference oOGRSpatialReference(SRS_WKT_WGS84); int nZoneNo = ceil( (180.0 + dfaCornersX[0]) / 6.0 ); OGRSpatialReference oDstSpatialReference(SRS_WKT_WGS84); oDstSpatialReference.SetUTM(nZoneNo, dfaCornersY[0] > 0); // transform coordinates from WGS84 to UTM OGRCoordinateTransformation *poCT = OGRCreateCoordinateTransformation( &oOGRSpatialReference, &oDstSpatialReference); if(!poCT) { Usage("get coordinate transformation failed"); return EXIT_FAILURE; } int nResult = poCT->Transform(5, dfaCornersX, dfaCornersY, NULL); if(!nResult) { Usage("transformation failed"); return EXIT_FAILURE; } // open input dataset GDALDataset *poSrcDataset = (GDALDataset *) GDALOpen( sFileName, GA_ReadOnly ); // GA_Update char* pszSpaRefDef = NULL; if( oDstSpatialReference.exportToWkt(&pszSpaRefDef) != OGRERR_NONE) { CPLFree( pszSpaRefDef ); GDALClose( (GDALDatasetH) poSrcDataset ); return EXIT_FAILURE; } // search point along image // add GCP to opened raster OGRPoint ptCenter(dfaCornersX[0], dfaCornersY[0]); OGRPoint pt1(dfaCornersX[1], dfaCornersY[1]); // NW Cormer OGRPoint pt2(dfaCornersX[2], dfaCornersY[2]); // NE Corner OGRPoint pt3(dfaCornersX[3], dfaCornersY[3]); // SE Corner OGRPoint pt4(dfaCornersX[4], dfaCornersY[4]); // SW Corner int nGCPCount = 0; OGREnvelope DstEnv; GDAL_GCP *paGSPs = PrepareGCP(sFileName, &pt1, &pt2, &pt3, &pt4, &ptCenter, oDstSpatialReference, poSrcDataset->GetRasterXSize(), poSrcDataset->GetRasterYSize(), nGCPCount, DstEnv); if(poSrcDataset->SetGCPs(nGCPCount, paGSPs, pszSpaRefDef) != CE_None) { Usage( "Set GCPs failed" ); return EXIT_FAILURE; } // create warper char **papszTO = NULL; papszTO = CSLSetNameValue( papszTO, "METHOD", "GCP_TPS" ); papszTO = CSLSetNameValue( papszTO, "NUM_THREADS", "4" ); papszTO = CSLSetNameValue( papszTO, "DST_SRS", pszSpaRefDef ); papszTO = CSLSetNameValue( papszTO, "SRC_SRS", pszSpaRefDef ); papszTO = CSLSetNameValue( papszTO, "INSERT_CENTER_LONG", "FALSE" ); GDALDriver *poOutputDriver = (GDALDriver *) GDALGetDriverByName( "GTiff" ); CPLSetConfigOption( "CHECK_WITH_INVERT_PROJ", "TRUE" ); void* hTransformArg = GDALCreateGenImgProjTransformer2( poSrcDataset, NULL, papszTO ); GDALTransformerInfo* psInfo = (GDALTransformerInfo*)hTransformArg; double adfThisGeoTransform[6]; double adfExtent[4]; int nThisPixels, nThisLines; // suggest the raster output size if( GDALSuggestedWarpOutput2( poSrcDataset, psInfo->pfnTransform, hTransformArg, adfThisGeoTransform, &nThisPixels, &nThisLines, adfExtent, 0 ) != CE_None ) { Usage( "Suggest Output failed" ); return EXIT_FAILURE; } adfThisGeoTransform[0] = DstEnv.MinX; adfThisGeoTransform[3] = DstEnv.MaxY; int nPixels = (int) ((DstEnv.MaxX - DstEnv.MinX) / adfThisGeoTransform[1] + 0.5); int nLines = (int) ((DstEnv.MaxY - DstEnv.MinY) / -adfThisGeoTransform[5] + 0.5); GDALSetGenImgProjTransformerDstGeoTransform( hTransformArg, adfThisGeoTransform); // create new raster CPLString sOutputRasterPath = CPLResetExtension(sFileName, "tif"); GDALDataset *poDstDataset = poOutputDriver->Create(sOutputRasterPath, nPixels, nLines, poSrcDataset->GetRasterCount(), GDT_Byte, NULL ); if( NULL == poDstDataset ) { Usage( "Create Output failed" ); return EXIT_FAILURE; } poDstDataset->SetProjection( pszSpaRefDef ); poDstDataset->SetGeoTransform( adfThisGeoTransform ); #ifdef APRROX_MAXERROR hTransformArg = GDALCreateApproxTransformer( GDALGenImgProjTransform, hTransformArg, APRROX_MAXERROR); GDALTransformerFunc pfnTransformer = GDALApproxTransform; GDALApproxTransformerOwnsSubtransformer(hTransformArg, TRUE); #else GDALTransformerFunc pfnTransformer = GDALGenImgProjTransform; #endif // APRROX_MAXERROR // warp GDALWarpOptions *psWO = GDALCreateWarpOptions(); psWO->eWorkingDataType = GDT_Byte; psWO->eResampleAlg = GRA_NearestNeighbour; psWO->hSrcDS = poSrcDataset; psWO->hDstDS = poDstDataset; psWO->pfnTransformer = pfnTransformer; psWO->pTransformerArg = hTransformArg; psWO->pfnProgress = GDALTermProgress; psWO->nBandCount = poSrcDataset->GetRasterCount(); psWO->panSrcBands = (int *) CPLMalloc(psWO->nBandCount*sizeof(int)); psWO->panDstBands = (int *) CPLMalloc(psWO->nBandCount*sizeof(int)); for(int i = 0; i < psWO->nBandCount; ++i ) { psWO->panSrcBands[i] = i+1; psWO->panDstBands[i] = i+1; } GDALWarpOperation oWO; if( oWO.Initialize( psWO ) == CE_None ) { #ifdef MULTI if( oWO.ChunkAndWarpMulti( 0, 0, poDstDataset->GetRasterXSize(), poDstDataset->GetRasterYSize() ) != CE_None) #else //MULTI if( oWO.ChunkAndWarpImage( 0, 0, poDstDataset->GetRasterXSize(), poDstDataset->GetRasterYSize() ) != CE_None) #endif //MULTI { const char* err = CPLGetLastErrorMsg(); Usage( CPLSPrintf("Warp failed.%s", err) ); return EXIT_FAILURE; } } // cleanup GDALDestroyWarpOptions( psWO ); CSLDestroy( papszTO ); CPLFree( pszSpaRefDef ); GDALClose( (GDALDatasetH) poSrcDataset ); GDALClose( (GDALDatasetH) poDstDataset ); GDALDestroyDriverManager(); return EXIT_SUCCESS; }
GDALDataset *ERSDataset::Open( GDALOpenInfo * poOpenInfo ) { /* -------------------------------------------------------------------- */ /* We assume the user selects the .ers file. */ /* -------------------------------------------------------------------- */ if( poOpenInfo->nHeaderBytes > 15 && EQUALN((const char *) poOpenInfo->pabyHeader,"Algorithm Begin",15) ) { CPLError( CE_Failure, CPLE_OpenFailed, "%s appears to be an algorithm ERS file, which is not currently supported.", poOpenInfo->pszFilename ); return NULL; } /* -------------------------------------------------------------------- */ /* We assume the user selects the .ers file. */ /* -------------------------------------------------------------------- */ if( poOpenInfo->nHeaderBytes < 15 || !EQUALN((const char *) poOpenInfo->pabyHeader,"DatasetHeader ",14) ) return NULL; /* -------------------------------------------------------------------- */ /* Open the .ers file, and read the first line. */ /* -------------------------------------------------------------------- */ VSILFILE *fpERS = VSIFOpenL( poOpenInfo->pszFilename, "rb" ); if( fpERS == NULL ) return NULL; CPLReadLineL( fpERS ); /* -------------------------------------------------------------------- */ /* Now ingest the rest of the file as a tree of header nodes. */ /* -------------------------------------------------------------------- */ ERSHdrNode *poHeader = new ERSHdrNode(); if( !poHeader->ParseChildren( fpERS ) ) { delete poHeader; VSIFCloseL( fpERS ); return NULL; } VSIFCloseL( fpERS ); /* -------------------------------------------------------------------- */ /* Do we have the minimum required information from this header? */ /* -------------------------------------------------------------------- */ if( poHeader->Find( "RasterInfo.NrOfLines" ) == NULL || poHeader->Find( "RasterInfo.NrOfCellsPerLine" ) == NULL || poHeader->Find( "RasterInfo.NrOfBands" ) == NULL ) { if( poHeader->FindNode( "Algorithm" ) != NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "%s appears to be an algorithm ERS file, which is not currently supported.", poOpenInfo->pszFilename ); } delete poHeader; return NULL; } /* -------------------------------------------------------------------- */ /* Create a corresponding GDALDataset. */ /* -------------------------------------------------------------------- */ ERSDataset *poDS; poDS = new ERSDataset(); poDS->poHeader = poHeader; poDS->eAccess = poOpenInfo->eAccess; /* -------------------------------------------------------------------- */ /* Capture some information from the file that is of interest. */ /* -------------------------------------------------------------------- */ int nBands = atoi(poHeader->Find( "RasterInfo.NrOfBands" )); poDS->nRasterXSize = atoi(poHeader->Find( "RasterInfo.NrOfCellsPerLine" )); poDS->nRasterYSize = atoi(poHeader->Find( "RasterInfo.NrOfLines" )); if (!GDALCheckDatasetDimensions(poDS->nRasterXSize, poDS->nRasterYSize) || !GDALCheckBandCount(nBands, FALSE)) { delete poDS; return NULL; } /* -------------------------------------------------------------------- */ /* Get the HeaderOffset if it exists in the header */ /* -------------------------------------------------------------------- */ GIntBig nHeaderOffset = 0; if( poHeader->Find( "HeaderOffset" ) != NULL ) { nHeaderOffset = atoi(poHeader->Find( "HeaderOffset" )); } /* -------------------------------------------------------------------- */ /* Establish the data type. */ /* -------------------------------------------------------------------- */ GDALDataType eType; CPLString osCellType = poHeader->Find( "RasterInfo.CellType", "Unsigned8BitInteger" ); if( EQUAL(osCellType,"Unsigned8BitInteger") ) eType = GDT_Byte; else if( EQUAL(osCellType,"Signed8BitInteger") ) eType = GDT_Byte; else if( EQUAL(osCellType,"Unsigned16BitInteger") ) eType = GDT_UInt16; else if( EQUAL(osCellType,"Signed16BitInteger") ) eType = GDT_Int16; else if( EQUAL(osCellType,"Unsigned32BitInteger") ) eType = GDT_UInt32; else if( EQUAL(osCellType,"Signed32BitInteger") ) eType = GDT_Int32; else if( EQUAL(osCellType,"IEEE4ByteReal") ) eType = GDT_Float32; else if( EQUAL(osCellType,"IEEE8ByteReal") ) eType = GDT_Float64; else { CPLDebug( "ERS", "Unknown CellType '%s'", osCellType.c_str() ); eType = GDT_Byte; } /* -------------------------------------------------------------------- */ /* Pick up the word order. */ /* -------------------------------------------------------------------- */ int bNative; #ifdef CPL_LSB bNative = EQUAL(poHeader->Find( "ByteOrder", "LSBFirst" ), "LSBFirst"); #else bNative = EQUAL(poHeader->Find( "ByteOrder", "MSBFirst" ), "MSBFirst"); #endif /* -------------------------------------------------------------------- */ /* Figure out the name of the target file. */ /* -------------------------------------------------------------------- */ CPLString osPath = CPLGetPath( poOpenInfo->pszFilename ); CPLString osDataFile = poHeader->Find( "DataFile", "" ); CPLString osDataFilePath; if( osDataFile.length() == 0 ) // just strip off extension. { osDataFile = CPLGetFilename( poOpenInfo->pszFilename ); osDataFile = osDataFile.substr( 0, osDataFile.find_last_of('.') ); } osDataFilePath = CPLFormFilename( osPath, osDataFile, NULL ); /* -------------------------------------------------------------------- */ /* DataSetType = Translated files are links to things like ecw */ /* files. */ /* -------------------------------------------------------------------- */ if( EQUAL(poHeader->Find("DataSetType",""),"Translated") ) { poDS->poDepFile = (GDALDataset *) GDALOpenShared( osDataFilePath, poOpenInfo->eAccess ); if( poDS->poDepFile != NULL && poDS->poDepFile->GetRasterCount() >= nBands ) { int iBand; for( iBand = 0; iBand < nBands; iBand++ ) { // Assume pixel interleaved. poDS->SetBand( iBand+1, poDS->poDepFile->GetRasterBand( iBand+1 ) ); } } } /* ==================================================================== */ /* While ERStorage indicates a raw file. */ /* ==================================================================== */ else if( EQUAL(poHeader->Find("DataSetType",""),"ERStorage") ) { // Open data file. if( poOpenInfo->eAccess == GA_Update ) poDS->fpImage = VSIFOpenL( osDataFilePath, "r+" ); else poDS->fpImage = VSIFOpenL( osDataFilePath, "r" ); poDS->osRawFilename = osDataFilePath; if( poDS->fpImage != NULL ) { int iWordSize = GDALGetDataTypeSize(eType) / 8; int iBand; for( iBand = 0; iBand < nBands; iBand++ ) { // Assume pixel interleaved. poDS->SetBand( iBand+1, new RawRasterBand( poDS, iBand+1, poDS->fpImage, nHeaderOffset + iWordSize * iBand * poDS->nRasterXSize, iWordSize, iWordSize * nBands * poDS->nRasterXSize, eType, bNative, TRUE )); if( EQUAL(osCellType,"Signed8BitInteger") ) poDS->GetRasterBand(iBand+1)-> SetMetadataItem( "PIXELTYPE", "SIGNEDBYTE", "IMAGE_STRUCTURE" ); } } } /* -------------------------------------------------------------------- */ /* Otherwise we have an error! */ /* -------------------------------------------------------------------- */ if( poDS->nBands == 0 ) { delete poDS; return NULL; } /* -------------------------------------------------------------------- */ /* Look for band descriptions. */ /* -------------------------------------------------------------------- */ int iChild, iBand = 0; ERSHdrNode *poRI = poHeader->FindNode( "RasterInfo" ); for( iChild = 0; poRI != NULL && iChild < poRI->nItemCount && iBand < poDS->nBands; iChild++ ) { if( poRI->papoItemChild[iChild] != NULL && EQUAL(poRI->papszItemName[iChild],"BandId") ) { const char *pszValue = poRI->papoItemChild[iChild]->Find( "Value", NULL ); iBand++; if( pszValue ) { CPLPushErrorHandler( CPLQuietErrorHandler ); poDS->GetRasterBand( iBand )->SetDescription( pszValue ); CPLPopErrorHandler(); } pszValue = poRI->papoItemChild[iChild]->Find( "Units", NULL ); if ( pszValue ) { CPLPushErrorHandler( CPLQuietErrorHandler ); poDS->GetRasterBand( iBand )->SetUnitType( pszValue ); CPLPopErrorHandler(); } } } /* -------------------------------------------------------------------- */ /* Look for projection. */ /* -------------------------------------------------------------------- */ OGRSpatialReference oSRS; CPLString osProjection = poHeader->Find( "CoordinateSpace.Projection", "RAW" ); CPLString osDatum = poHeader->Find( "CoordinateSpace.Datum", "WGS84" ); CPLString osUnits = poHeader->Find( "CoordinateSpace.Units", "METERS" ); oSRS.importFromERM( osProjection, osDatum, osUnits ); CPLFree( poDS->pszProjection ); oSRS.exportToWkt( &(poDS->pszProjection) ); /* -------------------------------------------------------------------- */ /* Look for the geotransform. */ /* -------------------------------------------------------------------- */ if( poHeader->Find( "RasterInfo.RegistrationCoord.Eastings", NULL ) && poHeader->Find( "RasterInfo.CellInfo.Xdimension", NULL ) ) { poDS->bGotTransform = TRUE; poDS->adfGeoTransform[0] = CPLAtof( poHeader->Find( "RasterInfo.RegistrationCoord.Eastings", "" )); poDS->adfGeoTransform[1] = CPLAtof( poHeader->Find( "RasterInfo.CellInfo.Xdimension", "" )); poDS->adfGeoTransform[2] = 0.0; poDS->adfGeoTransform[3] = CPLAtof( poHeader->Find( "RasterInfo.RegistrationCoord.Northings", "" )); poDS->adfGeoTransform[4] = 0.0; poDS->adfGeoTransform[5] = -CPLAtof( poHeader->Find( "RasterInfo.CellInfo.Ydimension", "" )); } else if( poHeader->Find( "RasterInfo.RegistrationCoord.Latitude", NULL ) && poHeader->Find( "RasterInfo.CellInfo.Xdimension", NULL ) ) { poDS->bGotTransform = TRUE; poDS->adfGeoTransform[0] = ERSDMS2Dec( poHeader->Find( "RasterInfo.RegistrationCoord.Longitude", "" )); poDS->adfGeoTransform[1] = CPLAtof( poHeader->Find( "RasterInfo.CellInfo.Xdimension", "" )); poDS->adfGeoTransform[2] = 0.0; poDS->adfGeoTransform[3] = ERSDMS2Dec( poHeader->Find( "RasterInfo.RegistrationCoord.Latitude", "" )); poDS->adfGeoTransform[4] = 0.0; poDS->adfGeoTransform[5] = -CPLAtof( poHeader->Find( "RasterInfo.CellInfo.Ydimension", "" )); } /* -------------------------------------------------------------------- */ /* Adjust if we have a registration cell. */ /* -------------------------------------------------------------------- */ int iCellX = atoi(poHeader->Find("RasterInfo.RegistrationCellX", "1")); int iCellY = atoi(poHeader->Find("RasterInfo.RegistrationCellY", "1")); if( poDS->bGotTransform ) { poDS->adfGeoTransform[0] -= (iCellX-1) * poDS->adfGeoTransform[1] + (iCellY-1) * poDS->adfGeoTransform[2]; poDS->adfGeoTransform[3] -= (iCellX-1) * poDS->adfGeoTransform[4] + (iCellY-1) * poDS->adfGeoTransform[5]; } /* -------------------------------------------------------------------- */ /* Check for null values. */ /* -------------------------------------------------------------------- */ if( poHeader->Find( "RasterInfo.NullCellValue", NULL ) ) { CPLPushErrorHandler( CPLQuietErrorHandler ); for( iBand = 1; iBand <= poDS->nBands; iBand++ ) poDS->GetRasterBand(iBand)->SetNoDataValue( CPLAtofM(poHeader->Find( "RasterInfo.NullCellValue" )) ); CPLPopErrorHandler(); } /* -------------------------------------------------------------------- */ /* Do we have an "All" region? */ /* -------------------------------------------------------------------- */ ERSHdrNode *poAll = NULL; for( iChild = 0; poRI != NULL && iChild < poRI->nItemCount; iChild++ ) { if( poRI->papoItemChild[iChild] != NULL && EQUAL(poRI->papszItemName[iChild],"RegionInfo") ) { if( EQUAL(poRI->papoItemChild[iChild]->Find("RegionName",""), "All") ) poAll = poRI->papoItemChild[iChild]; } } /* -------------------------------------------------------------------- */ /* Do we have statistics? */ /* -------------------------------------------------------------------- */ if( poAll && poAll->FindNode( "Stats" ) ) { CPLPushErrorHandler( CPLQuietErrorHandler ); for( iBand = 1; iBand <= poDS->nBands; iBand++ ) { const char *pszValue = poAll->FindElem( "Stats.MinimumValue", iBand-1 ); if( pszValue ) poDS->GetRasterBand(iBand)->SetMetadataItem( "STATISTICS_MINIMUM", pszValue ); pszValue = poAll->FindElem( "Stats.MaximumValue", iBand-1 ); if( pszValue ) poDS->GetRasterBand(iBand)->SetMetadataItem( "STATISTICS_MAXIMUM", pszValue ); pszValue = poAll->FindElem( "Stats.MeanValue", iBand-1 ); if( pszValue ) poDS->GetRasterBand(iBand)->SetMetadataItem( "STATISTICS_MEAN", pszValue ); pszValue = poAll->FindElem( "Stats.MedianValue", iBand-1 ); if( pszValue ) poDS->GetRasterBand(iBand)->SetMetadataItem( "STATISTICS_MEDIAN", pszValue ); } CPLPopErrorHandler(); } /* -------------------------------------------------------------------- */ /* Do we have GCPs. */ /* -------------------------------------------------------------------- */ if( poHeader->FindNode( "RasterInfo.WarpControl" ) ) poDS->ReadGCPs(); /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->SetDescription( poOpenInfo->pszFilename ); poDS->TryLoadXML(); // if no SR in xml, try aux const char* pszPrj = poDS->GDALPamDataset::GetProjectionRef(); if( !pszPrj || strlen(pszPrj) == 0 ) { // try aux GDALDataset* poAuxDS = GDALFindAssociatedAuxFile( poOpenInfo->pszFilename, GA_ReadOnly, poDS ); if( poAuxDS ) { pszPrj = poAuxDS->GetProjectionRef(); if( pszPrj && strlen(pszPrj) > 0 ) { CPLFree( poDS->pszProjection ); poDS->pszProjection = CPLStrdup(pszPrj); } GDALClose( poAuxDS ); } } /* -------------------------------------------------------------------- */ /* Check for overviews. */ /* -------------------------------------------------------------------- */ poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename ); return( poDS ); }
CPLErr AAIGRasterBand::IReadBlock( int nBlockXOff, int nBlockYOff, void *pImage ) { AAIGDataset *poODS = static_cast<AAIGDataset *>(poDS); if( nBlockYOff < 0 || nBlockYOff > poODS->nRasterYSize - 1 || nBlockXOff != 0 || panLineOffset == nullptr || poODS->fp == nullptr ) return CE_Failure; if( panLineOffset[nBlockYOff] == 0 ) { for( int iPrevLine = 1; iPrevLine <= nBlockYOff; iPrevLine++ ) if( panLineOffset[iPrevLine] == 0 ) IReadBlock(nBlockXOff, iPrevLine - 1, nullptr); } if( panLineOffset[nBlockYOff] == 0 ) return CE_Failure; if( poODS->Seek(panLineOffset[nBlockYOff]) != 0 ) { CPLError(CE_Failure, CPLE_FileIO, "Can't seek to offset %lu in input file to read data.", static_cast<long unsigned int>(panLineOffset[nBlockYOff])); return CE_Failure; } for( int iPixel = 0; iPixel < poODS->nRasterXSize; ) { // Suck up any pre-white space. char chNext = '\0'; do { chNext = poODS->Getc(); } while( isspace(static_cast<unsigned char>(chNext)) ); char szToken[500] = { '\0' }; int iTokenChar = 0; while( chNext != '\0' && !isspace((unsigned char)chNext) ) { if( iTokenChar == sizeof(szToken) - 2 ) { CPLError(CE_Failure, CPLE_FileIO, "Token too long at scanline %d.", nBlockYOff); return CE_Failure; } szToken[iTokenChar++] = chNext; chNext = poODS->Getc(); } if( chNext == '\0' && (iPixel != poODS->nRasterXSize - 1 || nBlockYOff != poODS->nRasterYSize - 1) ) { CPLError(CE_Failure, CPLE_FileIO, "File short, can't read line %d.", nBlockYOff); return CE_Failure; } szToken[iTokenChar] = '\0'; if( pImage != nullptr ) { if( eDataType == GDT_Float64 ) reinterpret_cast<double *>(pImage)[iPixel] = CPLAtofM(szToken); else if( eDataType == GDT_Float32 ) reinterpret_cast<float *>(pImage)[iPixel] = DoubleToFloatClamp(CPLAtofM(szToken)); else reinterpret_cast<GInt32 *>(pImage)[iPixel] = static_cast<GInt32>(atoi(szToken)); } iPixel++; } if( nBlockYOff < poODS->nRasterYSize - 1 ) panLineOffset[nBlockYOff + 1] = poODS->Tell(); return CE_None; }
GDALDataset *ISIS2Dataset::Open( GDALOpenInfo * poOpenInfo ) { /* -------------------------------------------------------------------- */ /* Does this look like a CUBE or an IMAGE Primary Data Object? */ /* -------------------------------------------------------------------- */ if( !Identify( poOpenInfo ) ) return NULL; /* -------------------------------------------------------------------- */ /* Open the file using the large file API. */ /* -------------------------------------------------------------------- */ VSILFILE *fpQube = VSIFOpenL( poOpenInfo->pszFilename, "rb" ); if( fpQube == NULL ) return NULL; ISIS2Dataset *poDS; poDS = new ISIS2Dataset(); if( ! poDS->oKeywords.Ingest( fpQube, 0 ) ) { VSIFCloseL( fpQube ); delete poDS; return NULL; } VSIFCloseL( fpQube ); /* -------------------------------------------------------------------- */ /* We assume the user is pointing to the label (ie. .lab) file. */ /* -------------------------------------------------------------------- */ // QUBE can be inline or detached and point to an image name // ^QUBE = 76 // ^QUBE = ("ui31s015.img",6441<BYTES>) - has another label on the image // ^QUBE = "ui31s015.img" - which implies no label or skip value const char *pszQube = poDS->GetKeyword( "^QUBE" ); GUIntBig nQube = 0; int bByteLocation = FALSE; CPLString osTargetFile = poOpenInfo->pszFilename; if( pszQube[0] == '"' ) { CPLString osTPath = CPLGetPath(poOpenInfo->pszFilename); CPLString osFilename = pszQube; poDS->CleanString( osFilename ); osTargetFile = CPLFormCIFilename( osTPath, osFilename, NULL ); poDS->osExternalCube = osTargetFile; } else if( pszQube[0] == '(' ) { CPLString osTPath = CPLGetPath(poOpenInfo->pszFilename); CPLString osFilename = poDS->GetKeywordSub("^QUBE",1,""); poDS->CleanString( osFilename ); osTargetFile = CPLFormCIFilename( osTPath, osFilename, NULL ); poDS->osExternalCube = osTargetFile; nQube = atoi(poDS->GetKeywordSub("^QUBE",2,"1")); if( strstr(poDS->GetKeywordSub("^QUBE",2,"1"),"<BYTES>") != NULL ) bByteLocation = true; } else { nQube = atoi(pszQube); if( strstr(pszQube,"<BYTES>") != NULL ) bByteLocation = true; } /* -------------------------------------------------------------------- */ /* Check if file an ISIS2 header file? Read a few lines of text */ /* searching for something starting with nrows or ncols. */ /* -------------------------------------------------------------------- */ GDALDataType eDataType = GDT_Byte; OGRSpatialReference oSRS; //image parameters int nRows, nCols, nBands = 1; GUIntBig nSkipBytes = 0; int itype; int s_ix, s_iy, s_iz; // check SUFFIX_ITEMS params. int record_bytes; int bNoDataSet = FALSE; char chByteOrder = 'M'; //default to MSB //Georef parameters double dfULXMap=0.5; double dfULYMap = 0.5; double dfXDim = 1.0; double dfYDim = 1.0; double dfNoData = 0.0; double xulcenter = 0.0; double yulcenter = 0.0; //projection parameters int bProjectionSet = TRUE; double semi_major = 0.0; double semi_minor = 0.0; double iflattening = 0.0; double center_lat = 0.0; double center_lon = 0.0; double first_std_parallel = 0.0; double second_std_parallel = 0.0; VSILFILE *fp; /* -------------------------------------------------------------------- */ /* Checks to see if this is valid ISIS2 cube */ /* SUFFIX_ITEM tag in .cub file should be (0,0,0); no side-planes */ /* -------------------------------------------------------------------- */ s_ix = atoi(poDS->GetKeywordSub( "QUBE.SUFFIX_ITEMS", 1 )); s_iy = atoi(poDS->GetKeywordSub( "QUBE.SUFFIX_ITEMS", 2 )); s_iz = atoi(poDS->GetKeywordSub( "QUBE.SUFFIX_ITEMS", 3 )); if( s_ix != 0 || s_iy != 0 || s_iz != 0 ) { CPLError( CE_Failure, CPLE_OpenFailed, "*** ISIS 2 cube file has invalid SUFFIX_ITEMS parameters:\n" "*** gdal isis2 driver requires (0, 0, 0), thus no sideplanes or backplanes\n" "found: (%i, %i, %i)\n\n", s_ix, s_iy, s_iz ); delete poDS; return NULL; } /**************** end SUFFIX_ITEM check ***********************/ /*********** Grab layout type (BSQ, BIP, BIL) ************/ // AXIS_NAME = (SAMPLE,LINE,BAND) /***********************************************************/ const char *value; char szLayout[10] = "BSQ"; //default to band seq. value = poDS->GetKeyword( "QUBE.AXIS_NAME", "" ); if (EQUAL(value,"(SAMPLE,LINE,BAND)") ) strcpy(szLayout,"BSQ"); else if (EQUAL(value,"(BAND,LINE,SAMPLE)") ) strcpy(szLayout,"BIP"); else if (EQUAL(value,"(SAMPLE,BAND,LINE)") || EQUAL(value,"") ) strcpy(szLayout,"BSQ"); else { CPLError( CE_Failure, CPLE_OpenFailed, "%s layout not supported. Abort\n\n", value); delete poDS; return NULL; } /*********** Grab samples lines band ************/ nCols = atoi(poDS->GetKeywordSub("QUBE.CORE_ITEMS",1)); nRows = atoi(poDS->GetKeywordSub("QUBE.CORE_ITEMS",2)); nBands = atoi(poDS->GetKeywordSub("QUBE.CORE_ITEMS",3)); /*********** Grab Qube record bytes **********/ record_bytes = atoi(poDS->GetKeyword("RECORD_BYTES")); if (nQube > 0 && bByteLocation ) nSkipBytes = (nQube - 1); else if( nQube > 0 ) nSkipBytes = (nQube - 1) * record_bytes; else nSkipBytes = 0; /*********** Grab samples lines band ************/ CPLString osCoreItemType = poDS->GetKeyword( "QUBE.CORE_ITEM_TYPE" ); if( (EQUAL(osCoreItemType,"PC_INTEGER")) || (EQUAL(osCoreItemType,"PC_UNSIGNED_INTEGER")) || (EQUAL(osCoreItemType,"PC_REAL")) ) { chByteOrder = 'I'; } /******** Grab format type - isis2 only supports 8,16,32 *******/ itype = atoi(poDS->GetKeyword("QUBE.CORE_ITEM_BYTES","")); switch(itype) { case 1 : eDataType = GDT_Byte; dfNoData = NULL1; bNoDataSet = TRUE; break; case 2 : if( strstr(osCoreItemType,"UNSIGNED") != NULL ) { dfNoData = 0; eDataType = GDT_UInt16; } else { dfNoData = NULL2; eDataType = GDT_Int16; } bNoDataSet = TRUE; break; case 4 : eDataType = GDT_Float32; dfNoData = NULL3; bNoDataSet = TRUE; break; case 8 : eDataType = GDT_Float64; dfNoData = NULL3; bNoDataSet = TRUE; break; default : CPLError( CE_Failure, CPLE_AppDefined, "Itype of %d is not supported in ISIS 2.", itype); delete poDS; return NULL; } /*********** Grab Cellsize ************/ value = poDS->GetKeyword("QUBE.IMAGE_MAP_PROJECTION.MAP_SCALE"); if (strlen(value) > 0 ) { dfXDim = (float) atof(value) * 1000.0; /* convert from km to m */ dfYDim = (float) atof(value) * 1000.0 * -1; } /*********** Grab LINE_PROJECTION_OFFSET ************/ value = poDS->GetKeyword("QUBE.IMAGE_MAP_PROJECTION.LINE_PROJECTION_OFFSET"); if (strlen(value) > 0) { yulcenter = (float) atof(value); yulcenter = ((yulcenter) * dfYDim); dfULYMap = yulcenter - (dfYDim/2); } /*********** Grab SAMPLE_PROJECTION_OFFSET ************/ value = poDS->GetKeyword("QUBE.IMAGE_MAP_PROJECTION.SAMPLE_PROJECTION_OFFSET"); if( strlen(value) > 0 ) { xulcenter = (float) atof(value); xulcenter = ((xulcenter) * dfXDim); dfULXMap = xulcenter - (dfXDim/2); } /*********** Grab TARGET_NAME ************/ /**** This is the planets name i.e. MARS ***/ CPLString target_name = poDS->GetKeyword("QUBE.TARGET_NAME"); /*********** Grab MAP_PROJECTION_TYPE ************/ CPLString map_proj_name = poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.MAP_PROJECTION_TYPE"); poDS->CleanString( map_proj_name ); /*********** Grab SEMI-MAJOR ************/ semi_major = atof(poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.A_AXIS_RADIUS")) * 1000.0; /*********** Grab semi-minor ************/ semi_minor = atof(poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.C_AXIS_RADIUS")) * 1000.0; /*********** Grab CENTER_LAT ************/ center_lat = atof(poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.CENTER_LATITUDE")); /*********** Grab CENTER_LON ************/ center_lon = atof(poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.CENTER_LONGITUDE")); /*********** Grab 1st std parallel ************/ first_std_parallel = atof(poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.FIRST_STANDARD_PARALLEL")); /*********** Grab 2nd std parallel ************/ second_std_parallel = atof(poDS->GetKeyword( "QUBE.IMAGE_MAP_PROJECTION.SECOND_STANDARD_PARALLEL")); /*** grab PROJECTION_LATITUDE_TYPE = "PLANETOCENTRIC" ****/ // Need to further study how ocentric/ographic will effect the gdal library. // So far we will use this fact to define a sphere or ellipse for some projections // Frank - may need to talk this over char bIsGeographic = TRUE; value = poDS->GetKeyword("CUBE.IMAGE_MAP_PROJECTION.PROJECTION_LATITUDE_TYPE"); if (EQUAL( value, "\"PLANETOCENTRIC\"" )) bIsGeographic = FALSE; CPLDebug("ISIS2","using projection %s", map_proj_name.c_str() ); //Set oSRS projection and parameters if ((EQUAL( map_proj_name, "EQUIRECTANGULAR_CYLINDRICAL" )) || (EQUAL( map_proj_name, "EQUIRECTANGULAR" )) || (EQUAL( map_proj_name, "SIMPLE_CYLINDRICAL" )) ) { oSRS.OGRSpatialReference::SetEquirectangular2 ( 0.0, center_lon, center_lat, 0, 0 ); } else if (EQUAL( map_proj_name, "ORTHOGRAPHIC" )) { oSRS.OGRSpatialReference::SetOrthographic ( center_lat, center_lon, 0, 0 ); } else if ((EQUAL( map_proj_name, "SINUSOIDAL" )) || (EQUAL( map_proj_name, "SINUSOIDAL_EQUAL-AREA" ))) { oSRS.OGRSpatialReference::SetSinusoidal ( center_lon, 0, 0 ); } else if (EQUAL( map_proj_name, "MERCATOR" )) { oSRS.OGRSpatialReference::SetMercator ( center_lat, center_lon, 1, 0, 0 ); } else if (EQUAL( map_proj_name, "POLAR_STEREOGRAPHIC" )) { oSRS.OGRSpatialReference::SetPS ( center_lat, center_lon, 1, 0, 0 ); } else if (EQUAL( map_proj_name, "TRANSVERSE_MERCATOR" )) { oSRS.OGRSpatialReference::SetTM ( center_lat, center_lon, 1, 0, 0 ); } else if (EQUAL( map_proj_name, "LAMBERT_CONFORMAL_CONIC" )) { oSRS.OGRSpatialReference::SetLCC ( first_std_parallel, second_std_parallel, center_lat, center_lon, 0, 0 ); } else if (EQUAL( map_proj_name, "") ) { /* no projection */ bProjectionSet = FALSE; } else { CPLDebug( "ISIS2", "Dataset projection %s is not supported. Continuing...", map_proj_name.c_str() ); bProjectionSet = FALSE; } if (bProjectionSet) { //Create projection name, i.e. MERCATOR MARS and set as ProjCS keyword CPLString proj_target_name = map_proj_name + " " + target_name; oSRS.SetProjCS(proj_target_name); //set ProjCS keyword //The geographic/geocentric name will be the same basic name as the body name //'GCS' = Geographic/Geocentric Coordinate System CPLString geog_name = "GCS_" + target_name; //The datum and sphere names will be the same basic name aas the planet CPLString datum_name = "D_" + target_name; CPLString sphere_name = target_name; // + "_IAU_IAG"); //Might not be IAU defined so don't add //calculate inverse flattening from major and minor axis: 1/f = a/(a-b) if ((semi_major - semi_minor) < 0.0000001) iflattening = 0; else iflattening = semi_major / (semi_major - semi_minor); //Set the body size but take into consideration which proj is being used to help w/ proj4 compatibility //The use of a Sphere, polar radius or ellipse here is based on how ISIS does it internally if ( ( (EQUAL( map_proj_name, "STEREOGRAPHIC" ) && (fabs(center_lat) == 90)) ) || (EQUAL( map_proj_name, "POLAR_STEREOGRAPHIC" ))) { if (bIsGeographic) { //Geograpraphic, so set an ellipse oSRS.SetGeogCS( geog_name, datum_name, sphere_name, semi_major, iflattening, "Reference_Meridian", 0.0 ); } else { //Geocentric, so force a sphere using the semi-minor axis. I hope... sphere_name += "_polarRadius"; oSRS.SetGeogCS( geog_name, datum_name, sphere_name, semi_minor, 0.0, "Reference_Meridian", 0.0 ); } } else if ( (EQUAL( map_proj_name, "SIMPLE_CYLINDRICAL" )) || (EQUAL( map_proj_name, "ORTHOGRAPHIC" )) || (EQUAL( map_proj_name, "STEREOGRAPHIC" )) || (EQUAL( map_proj_name, "SINUSOIDAL_EQUAL-AREA" )) || (EQUAL( map_proj_name, "SINUSOIDAL" )) ) { //isis uses the sphereical equation for these projections so force a sphere oSRS.SetGeogCS( geog_name, datum_name, sphere_name, semi_major, 0.0, "Reference_Meridian", 0.0 ); } else if ((EQUAL( map_proj_name, "EQUIRECTANGULAR_CYLINDRICAL" )) || (EQUAL( map_proj_name, "EQUIRECTANGULAR" )) ) { //Calculate localRadius using ISIS3 simple elliptical method // not the more standard Radius of Curvature method //PI = 4 * atan(1); double radLat, localRadius; if (center_lon == 0) { //No need to calculate local radius oSRS.SetGeogCS( geog_name, datum_name, sphere_name, semi_major, 0.0, "Reference_Meridian", 0.0 ); } else { radLat = center_lat * PI / 180; // in radians localRadius = semi_major * semi_minor / sqrt(pow(semi_minor*cos(radLat),2) + pow(semi_major*sin(radLat),2) ); sphere_name += "_localRadius"; oSRS.SetGeogCS( geog_name, datum_name, sphere_name, localRadius, 0.0, "Reference_Meridian", 0.0 ); CPLDebug( "ISIS2", "local radius: %f", localRadius); } } else { //All other projections: Mercator, Transverse Mercator, Lambert Conformal, etc. //Geographic, so set an ellipse if (bIsGeographic) { oSRS.SetGeogCS( geog_name, datum_name, sphere_name, semi_major, iflattening, "Reference_Meridian", 0.0 ); } else { //Geocentric, so force a sphere. I hope... oSRS.SetGeogCS( geog_name, datum_name, sphere_name, semi_major, 0.0, "Reference_Meridian", 0.0 ); } } // translate back into a projection string. char *pszResult = NULL; oSRS.exportToWkt( &pszResult ); poDS->osProjection = pszResult; CPLFree( pszResult ); } /* END ISIS2 Label Read */ /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ /* -------------------------------------------------------------------- */ /* Did we get the required keywords? If not we return with */ /* this never having been considered to be a match. This isn't */ /* an error! */ /* -------------------------------------------------------------------- */ if( nRows < 1 || nCols < 1 || nBands < 1 ) { delete poDS; return NULL; } /* -------------------------------------------------------------------- */ /* Capture some information from the file that is of interest. */ /* -------------------------------------------------------------------- */ poDS->nRasterXSize = nCols; poDS->nRasterYSize = nRows; /* -------------------------------------------------------------------- */ /* Open target binary file. */ /* -------------------------------------------------------------------- */ if( poOpenInfo->eAccess == GA_ReadOnly ) poDS->fpImage = VSIFOpenL( osTargetFile, "rb" ); else poDS->fpImage = VSIFOpenL( osTargetFile, "r+b" ); if( poDS->fpImage == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Failed to open %s with write permission.\n%s", osTargetFile.c_str(), VSIStrerror( errno ) ); delete poDS; return NULL; } poDS->eAccess = poOpenInfo->eAccess; /* -------------------------------------------------------------------- */ /* Compute the line offset. */ /* -------------------------------------------------------------------- */ int nItemSize = GDALGetDataTypeSize(eDataType)/8; int nLineOffset, nPixelOffset, nBandOffset; if( EQUAL(szLayout,"BIP") ) { nPixelOffset = nItemSize * nBands; nLineOffset = nPixelOffset * nCols; nBandOffset = nItemSize; } else if( EQUAL(szLayout,"BSQ") ) { nPixelOffset = nItemSize; nLineOffset = nPixelOffset * nCols; nBandOffset = nLineOffset * nRows; } else /* assume BIL */ { nPixelOffset = nItemSize; nLineOffset = nItemSize * nBands * nCols; nBandOffset = nItemSize * nCols; } /* -------------------------------------------------------------------- */ /* Create band information objects. */ /* -------------------------------------------------------------------- */ int i; poDS->nBands = nBands;; for( i = 0; i < poDS->nBands; i++ ) { RawRasterBand *poBand; poBand = new RawRasterBand( poDS, i+1, poDS->fpImage, nSkipBytes + nBandOffset * i, nPixelOffset, nLineOffset, eDataType, #ifdef CPL_LSB chByteOrder == 'I' || chByteOrder == 'L', #else chByteOrder == 'M', #endif TRUE ); if( bNoDataSet ) poBand->SetNoDataValue( dfNoData ); poDS->SetBand( i+1, poBand ); // Set offset/scale values at the PAM level. poBand->SetOffset( CPLAtofM(poDS->GetKeyword("QUBE.CORE_BASE","0.0"))); poBand->SetScale( CPLAtofM(poDS->GetKeyword("QUBE.CORE_MULTIPLIER","1.0"))); } /* -------------------------------------------------------------------- */ /* Check for a .prj file. For isis2 I would like to keep this in */ /* -------------------------------------------------------------------- */ CPLString osPath, osName; osPath = CPLGetPath( poOpenInfo->pszFilename ); osName = CPLGetBasename(poOpenInfo->pszFilename); const char *pszPrjFile = CPLFormCIFilename( osPath, osName, "prj" ); fp = VSIFOpenL( pszPrjFile, "r" ); if( fp != NULL ) { char **papszLines; OGRSpatialReference oSRS; VSIFCloseL( fp ); papszLines = CSLLoad( pszPrjFile ); if( oSRS.importFromESRI( papszLines ) == OGRERR_NONE ) { char *pszResult = NULL; oSRS.exportToWkt( &pszResult ); poDS->osProjection = pszResult; CPLFree( pszResult ); } CSLDestroy( papszLines ); } if( dfULYMap != 0.5 || dfULYMap != 0.5 || dfXDim != 1.0 || dfYDim != 1.0 ) { poDS->bGotTransform = TRUE; poDS->adfGeoTransform[0] = dfULXMap; poDS->adfGeoTransform[1] = dfXDim; poDS->adfGeoTransform[2] = 0.0; poDS->adfGeoTransform[3] = dfULYMap; poDS->adfGeoTransform[4] = 0.0; poDS->adfGeoTransform[5] = dfYDim; } if( !poDS->bGotTransform ) poDS->bGotTransform = GDALReadWorldFile( poOpenInfo->pszFilename, "cbw", poDS->adfGeoTransform ); if( !poDS->bGotTransform ) poDS->bGotTransform = GDALReadWorldFile( poOpenInfo->pszFilename, "wld", poDS->adfGeoTransform ); /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->SetDescription( poOpenInfo->pszFilename ); poDS->TryLoadXML(); /* -------------------------------------------------------------------- */ /* Check for overviews. */ /* -------------------------------------------------------------------- */ poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename ); return( poDS ); }
int GRASSASCIIDataset::ParseHeader(const char *pszHeader, const char *pszDataType) { char **papszTokens = CSLTokenizeString2(pszHeader, " \n\r\t:", 0); const int nTokens = CSLCount(papszTokens); int i = 0; if ( (i = CSLFindString(papszTokens, "cols")) < 0 || i + 1 >= nTokens) { CSLDestroy(papszTokens); return FALSE; } nRasterXSize = atoi(papszTokens[i + 1]); if ( (i = CSLFindString( papszTokens, "rows" )) < 0 || i + 1 >= nTokens) { CSLDestroy(papszTokens); return FALSE; } nRasterYSize = atoi(papszTokens[i + 1]); if (!GDALCheckDatasetDimensions(nRasterXSize, nRasterYSize)) { CSLDestroy(papszTokens); return FALSE; } // TODO(schwehr): Would be good to also factor the file size into the max. // TODO(schwehr): Allow the user to disable this check. // The driver allocates a panLineOffset array based on nRasterYSize constexpr int kMaxDimSize = 10000000; // 1e7 cells. if (nRasterXSize > kMaxDimSize || nRasterYSize > kMaxDimSize) { CSLDestroy(papszTokens); return FALSE; } const int iNorth = CSLFindString(papszTokens, "north"); const int iSouth = CSLFindString(papszTokens, "south"); const int iEast = CSLFindString(papszTokens, "east"); const int iWest = CSLFindString(papszTokens, "west"); if (iNorth == -1 || iSouth == -1 || iEast == -1 || iWest == -1 || std::max(std::max(iNorth, iSouth), std::max(iEast, iWest)) + 1 >= nTokens) { CSLDestroy(papszTokens); return FALSE; } const double dfNorth = CPLAtofM(papszTokens[iNorth + 1]); const double dfSouth = CPLAtofM(papszTokens[iSouth + 1]); const double dfEast = CPLAtofM(papszTokens[iEast + 1]); const double dfWest = CPLAtofM(papszTokens[iWest + 1]); const double dfPixelXSize = (dfEast - dfWest) / nRasterXSize; const double dfPixelYSize = (dfNorth - dfSouth) / nRasterYSize; adfGeoTransform[0] = dfWest; adfGeoTransform[1] = dfPixelXSize; adfGeoTransform[2] = 0.0; adfGeoTransform[3] = dfNorth; adfGeoTransform[4] = 0.0; adfGeoTransform[5] = -dfPixelYSize; if( (i = CSLFindString(papszTokens, "null")) >= 0 && i + 1 < nTokens) { const char *pszNoData = papszTokens[i + 1]; bNoDataSet = true; dfNoDataValue = CPLAtofM(pszNoData); if( pszDataType == nullptr && (strchr(pszNoData, '.') != nullptr || strchr(pszNoData, ',') != nullptr || std::numeric_limits<int>::min() > dfNoDataValue || dfNoDataValue > std::numeric_limits<int>::max()) ) { eDataType = GDT_Float32; } if( eDataType == GDT_Float32 ) { dfNoDataValue = MapNoDataToFloat(dfNoDataValue); } } if( (i = CSLFindString(papszTokens, "type")) >= 0 && i + 1 < nTokens) { const char *pszType = papszTokens[i + 1]; if (EQUAL(pszType, "int")) eDataType = GDT_Int32; else if (EQUAL(pszType, "float")) eDataType = GDT_Float32; else if (EQUAL(pszType, "double")) eDataType = GDT_Float64; else { CPLError(CE_Warning, CPLE_AppDefined, "Invalid value for type parameter : %s", pszType); } } CSLDestroy(papszTokens); return TRUE; }
int PDSDataset::ParseImage( CPLString osPrefix ) { /* ------------------------------------------------------------------- */ /* We assume the user is pointing to the label (ie. .lbl) file. */ /* ------------------------------------------------------------------- */ // IMAGE can be inline or detached and point to an image name // ^IMAGE = 3 // ^IMAGE = "GLOBAL_ALBEDO_8PPD.IMG" // ^IMAGE = "MEGT90N000CB.IMG" // ^IMAGE = ("BLAH.IMG",1) -- start at record 1 (1 based) // ^IMAGE = ("BLAH.IMG") -- still start at record 1 (equiv of "BLAH.IMG") // ^IMAGE = ("BLAH.IMG", 5 <BYTES>) -- start at byte 5 (the fifth byte in the file) // ^IMAGE = 10851 <BYTES> // ^SPECTRAL_QUBE = 5 for multi-band images CPLString osImageKeyword = osPrefix + "^IMAGE"; CPLString osQube = GetKeyword( osImageKeyword, "" ); CPLString osTargetFile = GetDescription(); if (EQUAL(osQube,"")) { osImageKeyword = "^SPECTRAL_QUBE"; osQube = GetKeyword( osImageKeyword ); } int nQube = atoi(osQube); int nDetachedOffset = 0; int bDetachedOffsetInBytes = FALSE; if( osQube.size() && osQube[0] == '(' ) { osQube = "\""; osQube += GetKeywordSub( osImageKeyword, 1 ); osQube += "\""; nDetachedOffset = atoi(GetKeywordSub( osImageKeyword, 2, "1")) - 1; // If this is not explicitly in bytes, then it is assumed to be in // records, and we need to translate to bytes. if (strstr(GetKeywordSub(osImageKeyword,2),"<BYTES>") != NULL) bDetachedOffsetInBytes = TRUE; } if( osQube.size() && osQube[0] == '"' ) { CPLString osTPath = CPLGetPath(GetDescription()); CPLString osFilename = osQube; CleanString( osFilename ); osTargetFile = CPLFormCIFilename( osTPath, osFilename, NULL ); osExternalCube = osTargetFile; } GDALDataType eDataType = GDT_Byte; //image parameters int nRows, nCols, nBands = 1; int nSkipBytes = 0; int itype; int record_bytes; char chByteOrder = 'M'; //default to MSB double dfNoData = 0.0; /* -------------------------------------------------------------------- */ /* Checks to see if this is raw PDS image not compressed image */ /* so ENCODING_TYPE either does not exist or it equals "N/A". */ /* Compressed types will not be supported in this routine */ /* -------------------------------------------------------------------- */ const char *value; CPLString osEncodingType = GetKeyword(osPrefix+"IMAGE.ENCODING_TYPE","N/A"); CleanString(osEncodingType); if ( !EQUAL(osEncodingType.c_str(),"N/A") ) { CPLError( CE_Failure, CPLE_OpenFailed, "*** PDS image file has an ENCODING_TYPE parameter:\n" "*** gdal pds driver does not support compressed image types\n" "found: (%s)\n\n", osEncodingType.c_str() ); return FALSE; } /**************** end ENCODING_TYPE check ***********************/ /*********** Grab layout type (BSQ, BIP, BIL) ************/ // AXIS_NAME = (SAMPLE,LINE,BAND) /*********** Grab samples lines band **************/ /** if AXIS_NAME = "" then Bands=1 and Sample and Lines **/ /** are there own keywords "LINES" and "LINE_SAMPLES" **/ /** if not NULL then CORE_ITEMS keyword i.e. (234,322,2) **/ /***********************************************************/ char szLayout[10] = "BSQ"; //default to band seq. value = GetKeyword( osPrefix+"IMAGE.AXIS_NAME", "" ); if (EQUAL(value,"(SAMPLE,LINE,BAND)") ) { strcpy(szLayout,"BSQ"); nCols = atoi(GetKeywordSub(osPrefix+"IMAGE.CORE_ITEMS",1)); nRows = atoi(GetKeywordSub(osPrefix+"IMAGE.CORE_ITEMS",2)); nBands = atoi(GetKeywordSub(osPrefix+"IMAGE.CORE_ITEMS",3)); } else if (EQUAL(value,"(BAND,LINE,SAMPLE)") ) { strcpy(szLayout,"BIP"); nBands = atoi(GetKeywordSub(osPrefix+"IMAGE.CORE_ITEMS",1)); nRows = atoi(GetKeywordSub(osPrefix+"IMAGE.CORE_ITEMS",2)); nCols = atoi(GetKeywordSub(osPrefix+"IMAGE.CORE_ITEMS",3)); } else if (EQUAL(value,"(SAMPLE,BAND,LINE)") ) { strcpy(szLayout,"BIL"); nCols = atoi(GetKeywordSub(osPrefix+"IMAGE.CORE_ITEMS",1)); nBands = atoi(GetKeywordSub(osPrefix+"IMAGE.CORE_ITEMS",2)); nRows = atoi(GetKeywordSub(osPrefix+"IMAGE.CORE_ITEMS",3)); } else if ( EQUAL(value,"") ) { strcpy(szLayout,"BSQ"); nCols = atoi(GetKeyword(osPrefix+"IMAGE.LINE_SAMPLES","")); nRows = atoi(GetKeyword(osPrefix+"IMAGE.LINES","")); nBands = atoi(GetKeyword(osPrefix+"IMAGE.BANDS","1")); } else { CPLError( CE_Failure, CPLE_OpenFailed, "%s layout not supported. Abort\n\n", value); return FALSE; } /*********** Grab Qube record bytes **********/ record_bytes = atoi(GetKeyword(osPrefix+"IMAGE.RECORD_BYTES")); if (record_bytes == 0) record_bytes = atoi(GetKeyword(osPrefix+"RECORD_BYTES")); // this can happen with "record_type = undefined". if( record_bytes == 0 ) record_bytes = 1; if( nQube >0 && osQube.find("<BYTES>") != CPLString::npos ) nSkipBytes = nQube - 1; else if (nQube > 0 ) nSkipBytes = (nQube - 1) * record_bytes; else if( nDetachedOffset > 0 ) { if (bDetachedOffsetInBytes) nSkipBytes = nDetachedOffset; else nSkipBytes = nDetachedOffset * record_bytes; } else nSkipBytes = 0; nSkipBytes += atoi(GetKeyword(osPrefix+"IMAGE.LINE_PREFIX_BYTES","")); /*********** Grab SAMPLE_TYPE *****************/ /** if keyword not found leave as "M" or "MSB" **/ CPLString osST = GetKeyword( osPrefix+"IMAGE.SAMPLE_TYPE" ); if( osST.size() >= 2 && osST[0] == '"' && osST[osST.size()-1] == '"' ) osST = osST.substr( 1, osST.size() - 2 ); if( (EQUAL(osST,"LSB_INTEGER")) || (EQUAL(osST,"LSB")) || // just incase (EQUAL(osST,"LSB_UNSIGNED_INTEGER")) || (EQUAL(osST,"LSB_SIGNED_INTEGER")) || (EQUAL(osST,"UNSIGNED_INTEGER")) || (EQUAL(osST,"VAX_REAL")) || (EQUAL(osST,"VAX_INTEGER")) || (EQUAL(osST,"PC_INTEGER")) || //just incase (EQUAL(osST,"PC_REAL")) ) { chByteOrder = 'I'; } /**** Grab format type - pds supports 1,2,4,8,16,32,64 (in theory) **/ /**** I have only seen 8, 16, 32 (float) in released datasets **/ itype = atoi(GetKeyword(osPrefix+"IMAGE.SAMPLE_BITS","")); switch(itype) { case 8 : eDataType = GDT_Byte; dfNoData = NULL1; break; case 16 : if( strstr(osST,"UNSIGNED") != NULL ) eDataType = GDT_UInt16; else eDataType = GDT_Int16; dfNoData = NULL2; break; case 32 : eDataType = GDT_Float32; dfNoData = NULL3; break; case 64 : eDataType = GDT_Float64; dfNoData = NULL3; break; default : CPLError( CE_Failure, CPLE_AppDefined, "Sample_bits of %d is not supported in this gdal PDS reader.", itype); return FALSE; } /* -------------------------------------------------------------------- */ /* Is there a specific nodata value in the file? Either the */ /* MISSING or MISSING_CONSTANT keywords are nodata. */ /* -------------------------------------------------------------------- */ if( GetKeyword( osPrefix+"IMAGE.MISSING", NULL ) != NULL ) dfNoData = CPLAtofM( GetKeyword( osPrefix+"IMAGE.MISSING", "" ) ); if( GetKeyword( osPrefix+"IMAGE.MISSING_CONSTANT", NULL ) != NULL ) dfNoData = CPLAtofM( GetKeyword( osPrefix+"IMAGE.MISSING_CONSTANT","")); /* -------------------------------------------------------------------- */ /* Did we get the required keywords? If not we return with */ /* this never having been considered to be a match. This isn't */ /* an error! */ /* -------------------------------------------------------------------- */ if( nRows < 1 || nCols < 1 || nBands < 1 ) { CPLError( CE_Failure, CPLE_AppDefined, "File %s appears to be a PDS file, but failed to find some required keywords.", GetDescription() ); return FALSE; } /* -------------------------------------------------------------------- */ /* Capture some information from the file that is of interest. */ /* -------------------------------------------------------------------- */ nRasterXSize = nCols; nRasterYSize = nRows; /* -------------------------------------------------------------------- */ /* Open target binary file. */ /* -------------------------------------------------------------------- */ if( eAccess == GA_ReadOnly ) { fpImage = VSIFOpenL( osTargetFile, "rb" ); if( fpImage == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Failed to open %s.\n%s", osTargetFile.c_str(), VSIStrerror( errno ) ); return FALSE; } } else { fpImage = VSIFOpenL( osTargetFile, "r+b" ); if( fpImage == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Failed to open %s with write permission.\n%s", osTargetFile.c_str(), VSIStrerror( errno ) ); return FALSE; } } /* -------------------------------------------------------------------- */ /* Compute the line offset. */ /* -------------------------------------------------------------------- */ int nItemSize = GDALGetDataTypeSize(eDataType)/8; int nLineOffset = record_bytes; int nPixelOffset, nBandOffset; if( EQUAL(szLayout,"BIP") ) { nPixelOffset = nItemSize * nBands; nBandOffset = nItemSize; nLineOffset = ((nPixelOffset * nCols + record_bytes - 1)/record_bytes) * record_bytes; } else if( EQUAL(szLayout,"BSQ") ) { nPixelOffset = nItemSize; nLineOffset = ((nPixelOffset * nCols + record_bytes - 1)/record_bytes) * record_bytes; nBandOffset = nLineOffset * nRows; } else /* assume BIL */ { nPixelOffset = nItemSize; nBandOffset = nItemSize * nCols; nLineOffset = ((nBandOffset * nCols + record_bytes - 1)/record_bytes) * record_bytes; } /* -------------------------------------------------------------------- */ /* Create band information objects. */ /* -------------------------------------------------------------------- */ int i; for( i = 0; i < nBands; i++ ) { RawRasterBand *poBand; poBand = new RawRasterBand( this, i+1, fpImage, nSkipBytes + nBandOffset * i, nPixelOffset, nLineOffset, eDataType, #ifdef CPL_LSB chByteOrder == 'I' || chByteOrder == 'L', #else chByteOrder == 'M', #endif TRUE ); if( nBands == 1 ) { const char* pszMin = GetKeyword(osPrefix+"IMAGE.MINIMUM", NULL); const char* pszMax = GetKeyword(osPrefix+"IMAGE.MAXIMUM", NULL); const char* pszMean = GetKeyword(osPrefix+"IMAGE.MEAN", NULL); const char* pszStdDev= GetKeyword(osPrefix+"IMAGE.STANDARD_DEVIATION", NULL); if (pszMin != NULL && pszMax != NULL && pszMean != NULL && pszStdDev != NULL) { poBand->SetStatistics( CPLAtofM(pszMin), CPLAtofM(pszMax), CPLAtofM(pszMean), CPLAtofM(pszStdDev)); } } poBand->SetNoDataValue( dfNoData ); SetBand( i+1, poBand ); // Set offset/scale values at the PAM level. poBand->SetOffset( CPLAtofM(GetKeyword(osPrefix+"IMAGE.OFFSET","0.0"))); poBand->SetScale( CPLAtofM(GetKeyword(osPrefix+"IMAGE.SCALING_FACTOR","1.0"))); } return TRUE; }