GDALAsyncReader* ECWDataset::BeginAsyncReader( int nXOff, int nYOff, int nXSize, int nYSize, void *pBuf, int nBufXSize, int nBufYSize, GDALDataType eBufType, int nBandCount, int* panBandMap, int nPixelSpace, int nLineSpace, int nBandSpace, char **papszOptions) { /* -------------------------------------------------------------------- */ /* Provide default packing if needed. */ /* -------------------------------------------------------------------- */ if( nPixelSpace == 0 ) nPixelSpace = GDALGetDataTypeSize(eBufType) / 8; if( nLineSpace == 0 ) nLineSpace = nPixelSpace * nBufXSize; if( nBandSpace == 0 ) nBandSpace = nLineSpace * nBufYSize; /* -------------------------------------------------------------------- */ /* We should do a bit of validation first - perhaps add later. */ /* -------------------------------------------------------------------- */ /* -------------------------------------------------------------------- */ /* Create the corresponding async reader. */ /* -------------------------------------------------------------------- */ ECWAsyncReader *poReader = new ECWAsyncReader(); poReader->poDS = this; poReader->nXOff = nXOff; poReader->nYOff = nYOff; poReader->nXSize = nXSize; poReader->nYSize = nYSize; poReader->pBuf = pBuf; poReader->nBufXSize = nBufXSize; poReader->nBufYSize = nBufYSize; poReader->eBufType = eBufType; poReader->nBandCount = nBandCount; poReader->panBandMap = (int *) CPLCalloc(sizeof(int),nBandCount); memcpy( poReader->panBandMap, panBandMap, sizeof(int) * nBandCount ); poReader->nPixelSpace = nPixelSpace; poReader->nLineSpace = nLineSpace; poReader->nBandSpace = nBandSpace; /* -------------------------------------------------------------------- */ /* Create a new view for this request. */ /* -------------------------------------------------------------------- */ poReader->poFileView = OpenFileView( GetDescription(), true, poReader->bUsingCustomStream ); if( poReader->poFileView == NULL ) { delete poReader; return NULL; } poReader->poFileView->SetClientData( poReader ); poReader->poFileView->SetRefreshCallback( ECWAsyncReader::RefreshCB ); /* -------------------------------------------------------------------- */ /* Issue a corresponding SetView command. */ /* -------------------------------------------------------------------- */ std::vector<UINT32> anBandIndices; int i; NCSError eNCSErr; CNCSError oErr; for( i = 0; i < nBandCount; i++ ) anBandIndices.push_back( panBandMap[i] - 1 ); oErr = poReader->poFileView->SetView( nBandCount, &(anBandIndices[0]), nXOff, nYOff, nXOff + nXSize - 1, nYOff + nYSize - 1, nBufXSize, nBufYSize ); eNCSErr = oErr.GetErrorNumber(); if( eNCSErr != NCS_SUCCESS ) { delete poReader; CPLError( CE_Failure, CPLE_AppDefined, "%s", NCSGetErrorText(eNCSErr) ); return NULL; } return poReader; }
void GDALPamProxyDB::LoadDB() { /* -------------------------------------------------------------------- */ /* Open the database relating original names to proxy .aux.xml */ /* file names. */ /* -------------------------------------------------------------------- */ CPLString osDBName = CPLFormFilename( osProxyDBDir, "gdal_pam_proxy", "dat" ); VSILFILE *fpDB = VSIFOpenL( osDBName, "r" ); nUpdateCounter = 0; if( fpDB == NULL ) return; /* -------------------------------------------------------------------- */ /* Read header, verify and extract update counter. */ /* -------------------------------------------------------------------- */ const size_t nHeaderSize = 100; GByte abyHeader[nHeaderSize] = { '\0' }; if( VSIFReadL( abyHeader, 1, nHeaderSize, fpDB ) != nHeaderSize || !STARTS_WITH(reinterpret_cast<char *>(abyHeader), "GDAL_PROXY") ) { CPLError( CE_Failure, CPLE_AppDefined, "Problem reading %s header - short or corrupt?", osDBName.c_str() ); CPL_IGNORE_RET_VAL(VSIFCloseL(fpDB)); return; } nUpdateCounter = atoi(reinterpret_cast<char *>(abyHeader) + 10); /* -------------------------------------------------------------------- */ /* Read the file in one gulp. */ /* -------------------------------------------------------------------- */ if( VSIFSeekL( fpDB, 0, SEEK_END ) != 0 ) { CPL_IGNORE_RET_VAL(VSIFCloseL(fpDB)); return; } const int nBufLength = static_cast<int>(VSIFTellL(fpDB) - nHeaderSize); if( VSIFSeekL( fpDB, nHeaderSize, SEEK_SET ) != 0 ) { CPL_IGNORE_RET_VAL(VSIFCloseL(fpDB)); return; } char *pszDBData = static_cast<char *>( CPLCalloc(1,nBufLength+1) ); if( VSIFReadL( pszDBData, 1, nBufLength, fpDB ) != static_cast<size_t>(nBufLength) ) { CPLFree(pszDBData); CPL_IGNORE_RET_VAL(VSIFCloseL(fpDB)); return; } CPL_IGNORE_RET_VAL(VSIFCloseL( fpDB )); /* -------------------------------------------------------------------- */ /* Parse the list of in/out names. */ /* -------------------------------------------------------------------- */ int iNext = 0; while( iNext < nBufLength ) { CPLString osOriginal; osOriginal.assign( pszDBData + iNext ); for( ; iNext < nBufLength && pszDBData[iNext] != '\0'; iNext++ ) {} if( iNext == nBufLength ) break; iNext++; CPLString osProxy = osProxyDBDir; osProxy += "/"; osProxy += pszDBData + iNext; for( ; iNext < nBufLength && pszDBData[iNext] != '\0'; iNext++ ) {} iNext++; aosOriginalFiles.push_back( osOriginal ); aosProxyFiles.push_back( osProxy ); } CPLFree( pszDBData ); }
void PALSARJaxaDataset::ReadMetadata( PALSARJaxaDataset *poDS, FILE *fp ) { /* seek to the end fo the leader file descriptor */ VSIFSeekL( fp, LEADER_FILE_DESCRIPTOR_LENGTH, SEEK_SET ); if (poDS->nFileType == level_11) { poDS->SetMetadataItem( "PRODUCT_LEVEL", "1.1" ); poDS->SetMetadataItem( "AZIMUTH_LOOKS", "1.0" ); } else { poDS->SetMetadataItem( "PRODUCT_LEVEL", "1.5" ); /* extract equivalent number of looks */ VSIFSeekL( fp, LEADER_FILE_DESCRIPTOR_LENGTH + EFFECTIVE_LOOKS_AZIMUTH_OFFSET, SEEK_SET ); char pszENL[17]; double dfENL; READ_CHAR_FLOAT(dfENL, 16, fp); sprintf( pszENL, "%-16.1f", dfENL ); poDS->SetMetadataItem( "AZIMUTH_LOOKS", pszENL ); /* extract pixel spacings */ VSIFSeekL( fp, LEADER_FILE_DESCRIPTOR_LENGTH + DATA_SET_SUMMARY_LENGTH + PIXEL_SPACING_OFFSET, SEEK_SET ); double dfPixelSpacing; double dfLineSpacing; char pszPixelSpacing[33]; char pszLineSpacing[33]; READ_CHAR_FLOAT(dfPixelSpacing, 16, fp); READ_CHAR_FLOAT(dfLineSpacing, 16, fp); sprintf( pszPixelSpacing, "%-32.1f",dfPixelSpacing ); sprintf( pszLineSpacing, "%-32.1f", dfLineSpacing ); poDS->SetMetadataItem( "PIXEL_SPACING", pszPixelSpacing ); poDS->SetMetadataItem( "LINE_SPACING", pszPixelSpacing ); /* Alphanumeric projection name */ VSIFSeekL( fp, LEADER_FILE_DESCRIPTOR_LENGTH + DATA_SET_SUMMARY_LENGTH + ALPHANUMERIC_PROJECTION_NAME_OFFSET, SEEK_SET ); char pszProjName[33]; READ_STRING(pszProjName, 32, fp); poDS->SetMetadataItem( "PROJECTION_NAME", pszProjName ); /* Extract corner GCPs */ poDS->nGCPCount = 4; poDS->pasGCPList = (GDAL_GCP *)CPLCalloc( sizeof(GDAL_GCP), poDS->nGCPCount ); GDALInitGCPs( poDS->nGCPCount, poDS->pasGCPList ); /* setup the GCPs */ int i; for (i = 0; i < poDS->nGCPCount; i++) { char pszID[2]; sprintf( pszID, "%d", i + 1); CPLFree(poDS->pasGCPList[i].pszId); poDS->pasGCPList[i].pszId = CPLStrdup( pszID ); poDS->pasGCPList[i].dfGCPZ = 0.0; } double dfTemp = 0.0; /* seek to start of GCPs */ VSIFSeekL( fp, LEADER_FILE_DESCRIPTOR_LENGTH + DATA_SET_SUMMARY_LENGTH + TOP_LEFT_LAT_OFFSET, SEEK_SET ); /* top-left GCP */ READ_CHAR_FLOAT(dfTemp, 16, fp); poDS->pasGCPList[0].dfGCPY = dfTemp; READ_CHAR_FLOAT(dfTemp, 16, fp); poDS->pasGCPList[0].dfGCPX = dfTemp; poDS->pasGCPList[0].dfGCPLine = 0.5; poDS->pasGCPList[0].dfGCPPixel = 0.5; /* top right GCP */ READ_CHAR_FLOAT(dfTemp, 16, fp); poDS->pasGCPList[1].dfGCPY = dfTemp; READ_CHAR_FLOAT(dfTemp, 16, fp); poDS->pasGCPList[1].dfGCPX = dfTemp; poDS->pasGCPList[1].dfGCPLine = 0.5; poDS->pasGCPList[1].dfGCPPixel = poDS->nRasterYSize - 0.5; /* bottom right GCP */ READ_CHAR_FLOAT(dfTemp, 16, fp); poDS->pasGCPList[2].dfGCPY = dfTemp; READ_CHAR_FLOAT(dfTemp, 16, fp); poDS->pasGCPList[2].dfGCPX = dfTemp; poDS->pasGCPList[2].dfGCPLine = poDS->nRasterYSize - 0.5; poDS->pasGCPList[2].dfGCPPixel = poDS->nRasterYSize - 0.5; /* bottom left GCP */ READ_CHAR_FLOAT(dfTemp, 16, fp); poDS->pasGCPList[3].dfGCPY = dfTemp; READ_CHAR_FLOAT(dfTemp, 16, fp); poDS->pasGCPList[3].dfGCPX = dfTemp; poDS->pasGCPList[3].dfGCPLine = poDS->nRasterYSize - 0.5; poDS->pasGCPList[3].dfGCPPixel = 0.5; } /* some generic metadata items */ poDS->SetMetadataItem( "SENSOR_BAND", "L" ); /* PALSAR is L-band */ poDS->SetMetadataItem( "RANGE_LOOKS", "1.0" ); /* Check if this is a PolSAR dataset */ if ( poDS->GetRasterCount() == 4 ) { /* PALSAR data is only available from JAXA in Scattering Matrix form */ poDS->SetMetadataItem( "MATRIX_REPRESENTATION", "SCATTERING" ); } }
OGRMultiPolygon* OGRILI1Layer::Polygonize( OGRGeometryCollection* poLines, bool fix_crossing_lines ) { if (poLines->getNumGeometries() == 0) { return new OGRMultiPolygon(); } #if defined(HAVE_GEOS) GEOSGeom *ahInGeoms = NULL; OGRGeometryCollection *poNoncrossingLines = poLines; GEOSGeom hResultGeom = NULL; OGRGeometry *poMP = NULL; if (fix_crossing_lines && poLines->getNumGeometries() > 0) { CPLDebug( "OGR_ILI", "Fixing crossing lines"); //A union of the geometry collection with one line fixes invalid geometries OGRGeometry* poUnion = poLines->Union(poLines->getGeometryRef(0)); if( poUnion != NULL ) { if( wkbFlatten(poUnion->getGeometryType()) == wkbGeometryCollection || wkbFlatten(poUnion->getGeometryType()) == wkbMultiLineString ) { poNoncrossingLines = dynamic_cast<OGRGeometryCollection*>(poUnion); CPLDebug( "OGR_ILI", "Fixed lines: %d", poNoncrossingLines->getNumGeometries()-poLines->getNumGeometries()); } else { delete poUnion; } } } GEOSContextHandle_t hGEOSCtxt = OGRGeometry::createGEOSContext(); ahInGeoms = (GEOSGeom *) CPLCalloc(sizeof(void*),poNoncrossingLines->getNumGeometries()); for( int i = 0; i < poNoncrossingLines->getNumGeometries(); i++ ) ahInGeoms[i] = poNoncrossingLines->getGeometryRef(i)->exportToGEOS(hGEOSCtxt); hResultGeom = GEOSPolygonize_r( hGEOSCtxt, ahInGeoms, poNoncrossingLines->getNumGeometries() ); for( int i = 0; i < poNoncrossingLines->getNumGeometries(); i++ ) GEOSGeom_destroy_r( hGEOSCtxt, ahInGeoms[i] ); CPLFree( ahInGeoms ); if (poNoncrossingLines != poLines) delete poNoncrossingLines; if( hResultGeom == NULL ) { OGRGeometry::freeGEOSContext( hGEOSCtxt ); return new OGRMultiPolygon(); } poMP = OGRGeometryFactory::createFromGEOS( hGEOSCtxt, hResultGeom ); GEOSGeom_destroy_r( hGEOSCtxt, hResultGeom ); OGRGeometry::freeGEOSContext( hGEOSCtxt ); poMP = OGRGeometryFactory::forceToMultiPolygon( poMP ); if( poMP && wkbFlatten(poMP->getGeometryType()) == wkbMultiPolygon ) return dynamic_cast<OGRMultiPolygon *>(poMP); else { delete poMP; return new OGRMultiPolygon(); } #else return new OGRMultiPolygon(); #endif }
GDALDataset *SAFEDataset::Open( GDALOpenInfo * poOpenInfo ) { /* -------------------------------------------------------------------- */ /* Is this a SENTINEL-1 manifest.safe definition? */ /* -------------------------------------------------------------------- */ if ( !SAFEDataset::Identify( poOpenInfo ) ) { return nullptr; } /* -------------------------------------------------------------------- */ /* Get subdataset information, if relevant */ /* -------------------------------------------------------------------- */ CPLString osMDFilename; //Subdataset 1st level selection (ex: for swath selection) CPLString osSelectedSubDS1; //Subdataset 2nd level selection (ex: for polarisation selection) CPLString osSelectedSubDS2; if (STARTS_WITH_CI(poOpenInfo->pszFilename, "SENTINEL1_DS:")) { osMDFilename = poOpenInfo->pszFilename + strlen("SENTINEL1_DS:"); const char* pszSelection1 = strrchr(osMDFilename.c_str(), ':'); if (pszSelection1 == nullptr || pszSelection1 == osMDFilename.c_str() ) { CPLError(CE_Failure, CPLE_AppDefined, "Invalid syntax for SENTINEL1_DS:"); return nullptr; } osMDFilename.resize( pszSelection1 - osMDFilename.c_str() ); osSelectedSubDS1 = pszSelection1 + strlen(":"); const char* pszSelection2 = strchr(osSelectedSubDS1.c_str(), '_'); if (pszSelection2 != nullptr && pszSelection2 != pszSelection1 ) { osSelectedSubDS1.resize( pszSelection2 - osSelectedSubDS1.c_str() ); osSelectedSubDS2 = pszSelection2 + strlen("_"); } //update directory check: VSIStatBufL sStat; if( VSIStatL( osMDFilename.c_str(), &sStat ) == 0 ) poOpenInfo->bIsDirectory = VSI_ISDIR( sStat.st_mode ); } else { osMDFilename = poOpenInfo->pszFilename; } if( poOpenInfo->bIsDirectory ) { osMDFilename = CPLFormCIFilename( osMDFilename.c_str(), "manifest.safe", nullptr ); } /* -------------------------------------------------------------------- */ /* Ingest the manifest.safe file. */ /* -------------------------------------------------------------------- */ //TODO REMOVE CPLXMLNode *psImageAttributes, *psImageGenerationParameters; CPLXMLNode *psManifest = CPLParseXMLFile( osMDFilename ); if( psManifest == nullptr ) return nullptr; CPLString osPath(CPLGetPath( osMDFilename )); /* -------------------------------------------------------------------- */ /* Confirm the requested access is supported. */ /* -------------------------------------------------------------------- */ if( poOpenInfo->eAccess == GA_Update ) { CPLDestroyXMLNode( psManifest ); CPLError( CE_Failure, CPLE_NotSupported, "The SAFE driver does not support update access to existing" " datasets.\n" ); return nullptr; } /* -------------------------------------------------------------------- */ /* Get contentUnit parent element. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psContentUnits = CPLGetXMLNode( psManifest, "=xfdu:XFDU.informationPackageMap.xfdu:contentUnit" ); if( psContentUnits == nullptr ) { CPLDestroyXMLNode( psManifest ); CPLError( CE_Failure, CPLE_OpenFailed, "Failed to find <xfdu:XFDU><informationPackageMap>" "<xfdu:contentUnit> in manifest file." ); return nullptr; } /* -------------------------------------------------------------------- */ /* Get Metadata Objects element. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psMetaDataObjects = CPLGetXMLNode( psManifest, "=xfdu:XFDU.metadataSection" ); if( psMetaDataObjects == nullptr ) { CPLDestroyXMLNode( psManifest ); CPLError( CE_Failure, CPLE_OpenFailed, "Failed to find <xfdu:XFDU><metadataSection>" "in manifest file." ); return nullptr; } /* -------------------------------------------------------------------- */ /* Get Data Objects element. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psDataObjects = CPLGetXMLNode( psManifest, "=xfdu:XFDU.dataObjectSection" ); if( psDataObjects == nullptr ) { CPLDestroyXMLNode( psManifest ); CPLError( CE_Failure, CPLE_OpenFailed, "Failed to find <xfdu:XFDU><dataObjectSection> in document." ); return nullptr; } /* -------------------------------------------------------------------- */ /* Create the dataset. */ /* -------------------------------------------------------------------- */ SAFEDataset *poDS = new SAFEDataset(); poDS->psManifest = psManifest; /* -------------------------------------------------------------------- */ /* Look for "Measurement Data Unit" contentUnit elements. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psAnnotation = nullptr; //Map with all measures aggregated by swath std::map<CPLString, std::set<CPLString> > oMapSwaths2Pols; for( CPLXMLNode *psContentUnit = psContentUnits->psChild; psContentUnit != nullptr; psContentUnit = psContentUnit->psNext ) { if( psContentUnit->eType != CXT_Element || !(EQUAL(psContentUnit->pszValue,"xfdu:contentUnit")) ) { continue; } const char *pszUnitType = CPLGetXMLValue( psContentUnit, "unitType", "" ); const char *pszAnnotation = nullptr; const char *pszCalibration = nullptr; const char *pszMeasurement = nullptr; if ( EQUAL(pszUnitType, "Measurement Data Unit") ) { /* Get dmdID and dataObjectID */ const char *pszDmdID = CPLGetXMLValue(psContentUnit, "dmdID", ""); const char *pszDataObjectID = CPLGetXMLValue( psContentUnit, "dataObjectPointer.dataObjectID", "" ); if( *pszDataObjectID == '\0' || *pszDmdID == '\0' ) { continue; } CPLXMLNode *psDataObject = SAFEDataset::GetDataObject( psDataObjects, pszDataObjectID); const char *pszRepId = CPLGetXMLValue( psDataObject, "repID", "" ); if ( !EQUAL(pszRepId, "s1Level1MeasurementSchema") ) { continue; } pszMeasurement = CPLGetXMLValue( psDataObject, "byteStream.fileLocation.href", ""); if( *pszMeasurement == '\0' ) { continue; } char** papszTokens = CSLTokenizeString2( pszDmdID, " ", CSLT_ALLOWEMPTYTOKENS | CSLT_STRIPLEADSPACES | CSLT_STRIPENDSPACES ); for( int j = 0; j < CSLCount( papszTokens ); j++ ) { const char* pszId = papszTokens[j]; if( *pszId == '\0' ) { continue; } //Map the metadata ID to the object element CPLXMLNode *psDO = SAFEDataset::GetDataObject( psMetaDataObjects, psDataObjects, pszId); if (psDO == nullptr) { continue; } //check object type pszRepId = CPLGetXMLValue( psDO, "repID", "" ); if( EQUAL(pszRepId, "s1Level1ProductSchema") ) { /* Get annotation filename */ pszAnnotation = CPLGetXMLValue( psDO, "byteStream.fileLocation.href", ""); if( *pszAnnotation == '\0' ) { continue; } } else if( EQUAL(pszRepId, "s1Level1CalibrationSchema") ) { pszCalibration = CPLGetXMLValue( psDO, "byteStream.fileLocation.href", ""); if( *pszCalibration == '\0' ) { continue; } } else { continue; } } CSLDestroy(papszTokens); if (pszAnnotation == nullptr || pszCalibration == nullptr ) { continue; } //open Annotation XML file CPLString osAnnotationFilePath = CPLFormFilename( osPath, pszAnnotation, nullptr ); if( psAnnotation ) CPLDestroyXMLNode(psAnnotation); psAnnotation = CPLParseXMLFile( osAnnotationFilePath ); if( psAnnotation == nullptr ) continue; /* -------------------------------------------------------------------- */ /* Get overall image information. */ /* -------------------------------------------------------------------- */ poDS->nRasterXSize = atoi(CPLGetXMLValue( psAnnotation, "=product.imageAnnotation.imageInformation.numberOfSamples", "-1" )); poDS->nRasterYSize = atoi(CPLGetXMLValue( psAnnotation, "=product.imageAnnotation.imageInformation.numberOfLines", "-1" )); if (poDS->nRasterXSize <= 1 || poDS->nRasterYSize <= 1) { CPLError( CE_Failure, CPLE_OpenFailed, "Non-sane raster dimensions provided in manifest.safe. " "If this is a valid SENTINEL-1 scene, please contact your " "data provider for a corrected dataset." ); delete poDS; CPLDestroyXMLNode(psAnnotation); return nullptr; } CPLString osProductType = CPLGetXMLValue( psAnnotation, "=product.adsHeader.productType", "UNK" ); CPLString osMissionId = CPLGetXMLValue( psAnnotation, "=product.adsHeader.missionId", "UNK" ); CPLString osPolarisation = CPLGetXMLValue( psAnnotation, "=product.adsHeader.polarisation", "UNK" ); CPLString osMode = CPLGetXMLValue( psAnnotation, "=product.adsHeader.mode", "UNK" ); CPLString osSwath = CPLGetXMLValue( psAnnotation, "=product.adsHeader.swath", "UNK" ); oMapSwaths2Pols[osSwath].insert(osPolarisation); if (osSelectedSubDS1.empty()) { // If not subdataset was selected, // open the first one we can find. osSelectedSubDS1 = osSwath; } if (!EQUAL(osSelectedSubDS1.c_str(), osSwath.c_str())) { //do not mix swath, otherwise it does not work for SLC products continue; } if (!osSelectedSubDS2.empty() && (osSelectedSubDS2.find(osPolarisation)== std::string::npos)) { // Add only selected polarisations. continue; } poDS->SetMetadataItem("PRODUCT_TYPE", osProductType.c_str()); poDS->SetMetadataItem("MISSION_ID", osMissionId.c_str()); poDS->SetMetadataItem("MODE", osMode.c_str()); poDS->SetMetadataItem("SWATH", osSwath.c_str()); /* -------------------------------------------------------------------- */ /* Get dataType (so we can recognize complex data), and the */ /* bitsPerSample. */ /* -------------------------------------------------------------------- */ const char *pszDataType = CPLGetXMLValue( psAnnotation, "=product.imageAnnotation.imageInformation.outputPixels", "" ); GDALDataType eDataType; if( EQUAL(pszDataType,"16 bit Signed Integer") ) eDataType = GDT_CInt16; else if( EQUAL(pszDataType,"16 bit Unsigned Integer") ) eDataType = GDT_UInt16; else { delete poDS; CPLError( CE_Failure, CPLE_AppDefined, "dataType=%s: not a supported configuration.", pszDataType ); CPLDestroyXMLNode(psAnnotation); return nullptr; } /* Extract pixel spacing information */ const char *pszPixelSpacing = CPLGetXMLValue( psAnnotation, "=product.imageAnnotation.imageInformation.rangePixelSpacing", "UNK" ); poDS->SetMetadataItem( "PIXEL_SPACING", pszPixelSpacing ); const char *pszLineSpacing = CPLGetXMLValue( psAnnotation, "=product.imageAnnotation.imageInformation.azimuthPixelSpacing", "UNK" ); poDS->SetMetadataItem( "LINE_SPACING", pszLineSpacing ); /* -------------------------------------------------------------------- */ /* Form full filename (path of manifest.safe + measurement file). */ /* -------------------------------------------------------------------- */ char *pszFullname = CPLStrdup(CPLFormFilename( osPath, pszMeasurement, nullptr )); /* -------------------------------------------------------------------- */ /* Try and open the file. */ /* -------------------------------------------------------------------- */ GDALDataset *poBandFile = reinterpret_cast<GDALDataset *>( GDALOpen( pszFullname, GA_ReadOnly ) ); if( poBandFile == nullptr ) { // NOP } else if (poBandFile->GetRasterCount() == 0) { GDALClose( (GDALRasterBandH) poBandFile ); } else { poDS->papszExtraFiles = CSLAddString( poDS->papszExtraFiles, osAnnotationFilePath ); poDS->papszExtraFiles = CSLAddString( poDS->papszExtraFiles, pszFullname ); /* -------------------------------------------------------------------- */ /* Create the band. */ /* -------------------------------------------------------------------- */ SAFERasterBand *poBand = new SAFERasterBand( poDS, eDataType, osSwath.c_str(), osPolarisation.c_str(), poBandFile ); poDS->SetBand( poDS->GetRasterCount() + 1, poBand ); } CPLFree( pszFullname ); } } //loop through all Swath/pols to add subdatasets int iSubDS = 1; for (std::map<CPLString, std::set<CPLString> >::iterator iterSwath=oMapSwaths2Pols.begin(); iterSwath!=oMapSwaths2Pols.end(); ++iterSwath) { CPLString osSubDS1 = iterSwath->first; CPLString osSubDS2; for (std::set<CPLString>::iterator iterPol=iterSwath->second.begin(); iterPol!=iterSwath->second.end(); ++iterPol) { if (!osSubDS2.empty()) { osSubDS2 += "+"; } osSubDS2 += *iterPol; //Create single band SubDataset SAFEDataset::AddSubDataset(poDS, iSubDS, CPLSPrintf("SENTINEL1_DS:%s:%s_%s", osPath.c_str(), osSubDS1.c_str(), (*iterPol).c_str()), CPLSPrintf("Single band with %s swath and %s polarisation", osSubDS1.c_str(), (*iterPol).c_str()) ); iSubDS++; } if (iterSwath->second.size()>1) { //Create single band SubDataset with all polarisations SAFEDataset::AddSubDataset(poDS, iSubDS, CPLSPrintf("SENTINEL1_DS:%s:%s", osPath.c_str(), osSubDS1.c_str()), CPLSPrintf("%s swath with all polarisations as bands", osSubDS1.c_str()) ); iSubDS++; } } if (poDS->GetRasterCount() == 0) { CPLError( CE_Failure, CPLE_OpenFailed, "Measurement bands not found." ); delete poDS; if( psAnnotation ) CPLDestroyXMLNode(psAnnotation); return nullptr; } /* -------------------------------------------------------------------- */ /* Collect more metadata elements */ /* -------------------------------------------------------------------- */ /* -------------------------------------------------------------------- */ /* Platform information */ /* -------------------------------------------------------------------- */ CPLXMLNode *psPlatformAttrs = SAFEDataset::GetMetaDataObject( psMetaDataObjects, "platform"); if (psPlatformAttrs != nullptr) { const char *pszItem = CPLGetXMLValue( psPlatformAttrs, "metadataWrap.xmlData.safe:platform" ".safe:familyName", "" ); poDS->SetMetadataItem( "SATELLITE_IDENTIFIER", pszItem ); pszItem = CPLGetXMLValue( psPlatformAttrs, "metadataWrap.xmlData.safe:platform" ".safe:instrument.safe:familyName.abbreviation", "" ); poDS->SetMetadataItem( "SENSOR_IDENTIFIER", pszItem ); pszItem = CPLGetXMLValue( psPlatformAttrs, "metadataWrap.xmlData.safe:platform" ".safe:instrument.safe:extension" ".s1sarl1:instrumentMode.s1sarl1:mode", "UNK" ); poDS->SetMetadataItem( "BEAM_MODE", pszItem ); pszItem = CPLGetXMLValue( psPlatformAttrs, "metadataWrap.xmlData.safe:platform" ".safe:instrument.safe:extension" ".s1sarl1:instrumentMode.s1sarl1:swath", "UNK" ); poDS->SetMetadataItem( "BEAM_SWATH", pszItem ); } /* -------------------------------------------------------------------- */ /* Acquisition Period information */ /* -------------------------------------------------------------------- */ CPLXMLNode *psAcquisitionAttrs = SAFEDataset::GetMetaDataObject( psMetaDataObjects, "acquisitionPeriod"); if (psAcquisitionAttrs != nullptr) { const char *pszItem = CPLGetXMLValue( psAcquisitionAttrs, "metadataWrap.xmlData.safe:acquisitionPeriod" ".safe:startTime", "UNK" ); poDS->SetMetadataItem( "ACQUISITION_START_TIME", pszItem ); pszItem = CPLGetXMLValue( psAcquisitionAttrs, "metadataWrap.xmlData.safe:acquisitionPeriod" ".safe:stopTime", "UNK" ); poDS->SetMetadataItem( "ACQUISITION_STOP_TIME", pszItem ); } /* -------------------------------------------------------------------- */ /* Processing information */ /* -------------------------------------------------------------------- */ CPLXMLNode *psProcessingAttrs = SAFEDataset::GetMetaDataObject( psMetaDataObjects, "processing"); if (psProcessingAttrs != nullptr) { const char *pszItem = CPLGetXMLValue( psProcessingAttrs, "metadataWrap.xmlData.safe:processing.safe:facility.name", "UNK" ); poDS->SetMetadataItem( "FACILITY_IDENTIFIER", pszItem ); } /* -------------------------------------------------------------------- */ /* Measurement Orbit Reference information */ /* -------------------------------------------------------------------- */ CPLXMLNode *psOrbitAttrs = SAFEDataset::GetMetaDataObject( psMetaDataObjects, "measurementOrbitReference"); if (psOrbitAttrs != nullptr) { const char *pszItem = CPLGetXMLValue( psOrbitAttrs, "metadataWrap.xmlData.safe:orbitReference" ".safe:orbitNumber", "UNK" ); poDS->SetMetadataItem( "ORBIT_NUMBER", pszItem ); pszItem = CPLGetXMLValue( psOrbitAttrs, "metadataWrap.xmlData.safe:orbitReference" ".safe:extension.s1:orbitProperties.s1:pass", "UNK" ); poDS->SetMetadataItem( "ORBIT_DIRECTION", pszItem ); } /* -------------------------------------------------------------------- */ /* Collect Annotation Processing Information */ /* -------------------------------------------------------------------- */ CPLXMLNode *psProcessingInfo = CPLGetXMLNode( psAnnotation, "=product.imageAnnotation.processingInformation" ); if ( psProcessingInfo != nullptr ) { OGRSpatialReference oLL, oPrj; const char *pszEllipsoidName = CPLGetXMLValue( psProcessingInfo, "ellipsoidName", "" ); const double minor_axis = CPLAtof(CPLGetXMLValue( psProcessingInfo, "ellipsoidSemiMinorAxis", "0.0" )); const double major_axis = CPLAtof(CPLGetXMLValue( psProcessingInfo, "ellipsoidSemiMajorAxis", "0.0" )); if ( EQUAL(pszEllipsoidName, "") || ( minor_axis == 0.0 ) || ( major_axis == 0.0 ) ) { CPLError(CE_Warning,CPLE_AppDefined,"Warning- incomplete" " ellipsoid information. Using wgs-84 parameters.\n"); oLL.SetWellKnownGeogCS( "WGS84" ); oPrj.SetWellKnownGeogCS( "WGS84" ); } else if ( EQUAL( pszEllipsoidName, "WGS84" ) ) { oLL.SetWellKnownGeogCS( "WGS84" ); oPrj.SetWellKnownGeogCS( "WGS84" ); } else { const double inv_flattening = major_axis/(major_axis - minor_axis); oLL.SetGeogCS( "","",pszEllipsoidName, major_axis, inv_flattening); oPrj.SetGeogCS( "","",pszEllipsoidName, major_axis, inv_flattening); } CPLFree( poDS->pszGCPProjection ); poDS->pszGCPProjection = nullptr; oLL.exportToWkt( &(poDS->pszGCPProjection) ); } /* -------------------------------------------------------------------- */ /* Collect GCPs. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psGeoGrid = CPLGetXMLNode( psAnnotation, "=product.geolocationGrid.geolocationGridPointList" ); if( psGeoGrid != nullptr ) { /* count GCPs */ poDS->nGCPCount = 0; for( CPLXMLNode *psNode = psGeoGrid->psChild; psNode != nullptr; psNode = psNode->psNext ) { if( EQUAL(psNode->pszValue,"geolocationGridPoint") ) poDS->nGCPCount++ ; } poDS->pasGCPList = reinterpret_cast<GDAL_GCP *>( CPLCalloc( sizeof(GDAL_GCP), poDS->nGCPCount ) ); poDS->nGCPCount = 0; for( CPLXMLNode *psNode = psGeoGrid->psChild; psNode != nullptr; psNode = psNode->psNext ) { GDAL_GCP *psGCP = poDS->pasGCPList + poDS->nGCPCount; if( !EQUAL(psNode->pszValue,"geolocationGridPoint") ) continue; poDS->nGCPCount++ ; char szID[32]; snprintf( szID, sizeof(szID), "%d", poDS->nGCPCount ); psGCP->pszId = CPLStrdup( szID ); psGCP->pszInfo = CPLStrdup(""); psGCP->dfGCPPixel = CPLAtof(CPLGetXMLValue(psNode,"pixel","0")); psGCP->dfGCPLine = CPLAtof(CPLGetXMLValue(psNode,"line","0")); psGCP->dfGCPX = CPLAtof(CPLGetXMLValue(psNode,"longitude","")); psGCP->dfGCPY = CPLAtof(CPLGetXMLValue(psNode,"latitude","")); psGCP->dfGCPZ = CPLAtof(CPLGetXMLValue(psNode,"height","")); } } CPLDestroyXMLNode(psAnnotation); /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ const CPLString osDescription = osMDFilename; /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->SetDescription( osDescription ); poDS->SetPhysicalFilename( osMDFilename ); poDS->SetSubdatasetName( osDescription ); poDS->TryLoadXML(); /* -------------------------------------------------------------------- */ /* Check for overviews. */ /* -------------------------------------------------------------------- */ poDS->oOvManager.Initialize( poDS, ":::VIRTUAL:::" ); return poDS; }
/** * Retrieves and stores the GCPs from a COSMO-SKYMED dataset * It only retrieves the GCPs for L0, L1A and L1B products * for L1C and L1D products, geotransform is provided. * The GCPs provided will be the Image's corners. * @param iProductType type of CSK product @see HDF5CSKProductEnum */ void HDF5ImageDataset::CaptureCSKGCPs(int iProductType) { //Only retrieve GCPs for L0,L1A and L1B products if(iProductType == PROD_CSK_L0||iProductType == PROD_CSK_L1A|| iProductType == PROD_CSK_L1B) { int i; double *pdCornerCoordinates; nGCPCount=4; pasGCPList = (GDAL_GCP *) CPLCalloc(sizeof(GDAL_GCP),4); CPLString osCornerName[4]; double pdCornerPixel[4]; double pdCornerLine[4]; const char *pszSubdatasetName = GetSubdatasetName(); //Load the subdataset name first for(i=0;i <4;i++) osCornerName[i] = pszSubdatasetName; //Load the attribute name, and raster coordinates for //all the corners osCornerName[0] += "/Top Left Geodetic Coordinates"; pdCornerPixel[0] = 0; pdCornerLine[0] = 0; osCornerName[1] += "/Top Right Geodetic Coordinates"; pdCornerPixel[1] = GetRasterXSize(); pdCornerLine[1] = 0; osCornerName[2] += "/Bottom Left Geodetic Coordinates"; pdCornerPixel[2] = 0; pdCornerLine[2] = GetRasterYSize(); osCornerName[3] += "/Bottom Right Geodetic Coordinates"; pdCornerPixel[3] = GetRasterXSize(); pdCornerLine[3] = GetRasterYSize(); //For all the image's corners for(i=0;i<4;i++) { GDALInitGCPs( 1, pasGCPList + i ); CPLFree( pasGCPList[i].pszId ); pasGCPList[i].pszId = NULL; //Retrieve the attributes if(HDF5ReadDoubleAttr(osCornerName[i].c_str(), &pdCornerCoordinates) == CE_Failure) { CPLError( CE_Failure, CPLE_OpenFailed, "Error retrieving CSK GCPs\n" ); // Free on failure, e.g. in case of QLK subdataset. for( int i = 0; i < 4; i++ ) { if( pasGCPList[i].pszId ) CPLFree( pasGCPList[i].pszId ); if( pasGCPList[i].pszInfo ) CPLFree( pasGCPList[i].pszInfo ); } CPLFree( pasGCPList ); pasGCPList = NULL; nGCPCount = 0; break; } //Fill the GCPs name pasGCPList[i].pszId = CPLStrdup( osCornerName[i].c_str() ); //Fill the coordinates pasGCPList[i].dfGCPX = pdCornerCoordinates[1]; pasGCPList[i].dfGCPY = pdCornerCoordinates[0]; pasGCPList[i].dfGCPZ = pdCornerCoordinates[2]; pasGCPList[i].dfGCPPixel = pdCornerPixel[i]; pasGCPList[i].dfGCPLine = pdCornerLine[i]; //Free the returned coordinates CPLFree(pdCornerCoordinates); } } }
CPLErr HDF5ImageDataset::CreateProjections() { switch(iSubdatasetType) { case CSK_PRODUCT: { const char *osMissionLevel = NULL; int productType = PROD_UNKNOWN; if(GetMetadataItem("Product_Type")!=NULL) { //Get the format's level osMissionLevel = HDF5Dataset::GetMetadataItem("Product_Type"); if(EQUALN(osMissionLevel,"RAW",3)) productType = PROD_CSK_L0; if(EQUALN(osMissionLevel,"SSC",3)) productType = PROD_CSK_L1A; if(EQUALN(osMissionLevel,"DGM",3)) productType = PROD_CSK_L1B; if(EQUALN(osMissionLevel,"GEC",3)) productType = PROD_CSK_L1C; if(EQUALN(osMissionLevel,"GTC",3)) productType = PROD_CSK_L1D; } CaptureCSKGeoTransform(productType); CaptureCSKGeolocation(productType); CaptureCSKGCPs(productType); break; } case UNKNOWN_PRODUCT: { #define NBGCPLAT 100 #define NBGCPLON 30 hid_t LatitudeDatasetID = -1; hid_t LongitudeDatasetID = -1; hid_t LatitudeDataspaceID; hid_t LongitudeDataspaceID; float* Latitude; float* Longitude; int i,j; int nDeltaLat; int nDeltaLon; nDeltaLat = nRasterYSize / NBGCPLAT; nDeltaLon = nRasterXSize / NBGCPLON; if( nDeltaLat == 0 || nDeltaLon == 0 ) return CE_None; /* -------------------------------------------------------------------- */ /* Create HDF5 Data Hierarchy in a link list */ /* -------------------------------------------------------------------- */ poH5Objects=HDF5FindDatasetObjects( poH5RootGroup, "Latitude" ); if( !poH5Objects ) { return CE_None; } /* -------------------------------------------------------------------- */ /* The Lattitude and Longitude arrays must have a rank of 2 to */ /* retrieve GCPs. */ /* -------------------------------------------------------------------- */ if( poH5Objects->nRank != 2 ) { return CE_None; } /* -------------------------------------------------------------------- */ /* Retrieve HDF5 data information */ /* -------------------------------------------------------------------- */ LatitudeDatasetID = H5Dopen( hHDF5,poH5Objects->pszPath ); LatitudeDataspaceID = H5Dget_space( dataset_id ); poH5Objects=HDF5FindDatasetObjects( poH5RootGroup, "Longitude" ); LongitudeDatasetID = H5Dopen( hHDF5,poH5Objects->pszPath ); LongitudeDataspaceID = H5Dget_space( dataset_id ); if( ( LatitudeDatasetID > 0 ) && ( LongitudeDatasetID > 0) ) { Latitude = ( float * ) CPLCalloc( nRasterYSize*nRasterXSize, sizeof( float ) ); Longitude = ( float * ) CPLCalloc( nRasterYSize*nRasterXSize, sizeof( float ) ); memset( Latitude, 0, nRasterXSize*nRasterYSize*sizeof( float ) ); memset( Longitude, 0, nRasterXSize*nRasterYSize*sizeof( float ) ); H5Dread ( LatitudeDatasetID, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, Latitude ); H5Dread ( LongitudeDatasetID, H5T_NATIVE_FLOAT, H5S_ALL, H5S_ALL, H5P_DEFAULT, Longitude ); oSRS.SetWellKnownGeogCS( "WGS84" ); CPLFree(pszProjection); CPLFree(pszGCPProjection); oSRS.exportToWkt( &pszProjection ); oSRS.exportToWkt( &pszGCPProjection ); /* -------------------------------------------------------------------- */ /* Fill the GCPs list. */ /* -------------------------------------------------------------------- */ nGCPCount = nRasterYSize/nDeltaLat * nRasterXSize/nDeltaLon; pasGCPList = ( GDAL_GCP * ) CPLCalloc( nGCPCount, sizeof( GDAL_GCP ) ); GDALInitGCPs( nGCPCount, pasGCPList ); int k=0; int nYLimit = ((int)nRasterYSize/nDeltaLat) * nDeltaLat; int nXLimit = ((int)nRasterXSize/nDeltaLon) * nDeltaLon; for( j = 0; j < nYLimit; j+=nDeltaLat ) { for( i = 0; i < nXLimit; i+=nDeltaLon ) { int iGCP = j * nRasterXSize + i; pasGCPList[k].dfGCPX = ( double ) Longitude[iGCP]+180.0; pasGCPList[k].dfGCPY = ( double ) Latitude[iGCP]; pasGCPList[k].dfGCPPixel = i + 0.5; pasGCPList[k++].dfGCPLine = j + 0.5; } } CPLFree( Latitude ); CPLFree( Longitude ); } if( LatitudeDatasetID > 0 ) H5Dclose(LatitudeDatasetID); if( LongitudeDatasetID > 0 ) H5Dclose(LongitudeDatasetID); break; } } return CE_None; }
void E00GRIDDataset::ReadMetadata() { if (bHasReadMetadata) return; bHasReadMetadata = TRUE; if (e00ReadPtr == nullptr) { const int nRoundedBlockXSize = DIV_ROUND_UP(nRasterXSize, VALS_PER_LINE) * VALS_PER_LINE; if( static_cast<vsi_l_offset>(nRasterYSize) > GUINTBIG_MAX / nRoundedBlockXSize ) { return; } const vsi_l_offset nValsToSkip = (vsi_l_offset)nRasterYSize * nRoundedBlockXSize; const vsi_l_offset nLinesToSkip = nValsToSkip / VALS_PER_LINE; const int nBytesPerLine = VALS_PER_LINE * E00_FLOAT_SIZE + nBytesEOL; const vsi_l_offset nPos = nDataStart + nLinesToSkip * nBytesPerLine; VSIFSeekL(fp, nPos, SEEK_SET); } else { nLastYOff = -1; const unsigned int BUFFER_SIZE = 65536; const unsigned int NEEDLE_SIZE = 3*5; const unsigned int nToRead = BUFFER_SIZE - NEEDLE_SIZE; char* pabyBuffer = (char*)CPLCalloc(1, BUFFER_SIZE+NEEDLE_SIZE); int nRead; int bEOGFound = FALSE; VSIFSeekL(fp, 0, SEEK_END); vsi_l_offset nEndPos = VSIFTellL(fp); if (nEndPos > BUFFER_SIZE) nEndPos -= BUFFER_SIZE; else nEndPos = 0; VSIFSeekL(fp, nEndPos, SEEK_SET); #define GOTO_NEXT_CHAR() \ i ++; \ if (pabyBuffer[i] == 13 || pabyBuffer[i] == 10) \ { \ i++; \ if (pabyBuffer[i] == 10) \ i++; \ } \ while ((nRead = static_cast<int>(VSIFReadL(pabyBuffer, 1, nToRead, fp))) != 0) { int i; for(i = 0; i < nRead; i++) { if (pabyBuffer[i] == 'E') { GOTO_NEXT_CHAR(); if (pabyBuffer[i] == 'O') { GOTO_NEXT_CHAR(); if (pabyBuffer[i] == 'G') { GOTO_NEXT_CHAR(); if (pabyBuffer[i] == '~') { GOTO_NEXT_CHAR(); if (pabyBuffer[i] == '}') { bEOGFound = TRUE; break; } } } } } } if (bEOGFound) { VSIFSeekL(fp, VSIFTellL(fp) - nRead + i + 1, SEEK_SET); e00ReadPtr->iInBufPtr = 0; e00ReadPtr->szInBuf[0] = '\0'; break; } if (nEndPos == 0) break; if ((unsigned int)nRead == nToRead) { memmove(pabyBuffer + nToRead, pabyBuffer, NEEDLE_SIZE); if (nEndPos >= (vsi_l_offset)nToRead) nEndPos -= nToRead; else nEndPos = 0; VSIFSeekL(fp, nEndPos, SEEK_SET); } else break; } CPLFree(pabyBuffer); if (!bEOGFound) return; } const char* pszLine = nullptr; bool bPRJFound = false; bool bStatsFound = false; while((pszLine = ReadLine()) != nullptr) { if (STARTS_WITH_CI(pszLine, "PRJ 2")) { bPRJFound = true; while((pszLine = ReadLine()) != nullptr) { if (EQUAL(pszLine, "EOP")) { break; } if (!EQUAL(pszLine, "~") ) { papszPrj = CSLAddString(papszPrj, pszLine); } } OGRSpatialReference oSRS; if( oSRS.importFromESRI( papszPrj ) != OGRERR_NONE ) { CPLError( CE_Warning, CPLE_AppDefined, "Failed to parse PRJ section, ignoring." ); } else { char* pszWKT = nullptr; if (oSRS.exportToWkt(&pszWKT) == OGRERR_NONE && pszWKT != nullptr) osProjection = pszWKT; CPLFree(pszWKT); } if (bStatsFound) break; } else if (strcmp(pszLine, "STDV 8-1 254-1 15 3 60-1 -1 -1-1 4-") == 0) { bStatsFound = true; pszLine = ReadLine(); if (pszLine) { CPLString osStats = pszLine; pszLine = ReadLine(); if (pszLine) { osStats += pszLine; char** papszTokens = CSLTokenizeString(osStats); if (CSLCount(papszTokens) == 4) { dfMin = CPLAtof(papszTokens[0]); dfMax = CPLAtof(papszTokens[1]); dfMean = CPLAtof(papszTokens[2]); dfStddev = CPLAtof(papszTokens[3]); bHasStats = TRUE; } CSLDestroy(papszTokens); } } if (bPRJFound) break; } } }
OGRErr OGR_SRSNode::exportToWkt( char ** ppszResult ) { char **papszChildrenWkt = NULL; int nLength = strlen(pszValue)+4; int i; /* -------------------------------------------------------------------- */ /* Build a list of the WKT format for the children. */ /* -------------------------------------------------------------------- */ papszChildrenWkt = (char **) CPLCalloc(sizeof(char*),(nChildren+1)); for( i = 0; i < nChildren; i++ ) { papoChildNodes[i]->exportToWkt( papszChildrenWkt + i ); nLength += strlen(papszChildrenWkt[i]) + 1; } /* -------------------------------------------------------------------- */ /* Allocate the result string. */ /* -------------------------------------------------------------------- */ *ppszResult = (char *) CPLMalloc(nLength); *ppszResult[0] = '\0'; /* -------------------------------------------------------------------- */ /* Do we need to quote this value? Determine whether or not */ /* this is a terminal string value. */ /* -------------------------------------------------------------------- */ int bNeedQuoting = FALSE; if( GetChildCount() == 0 ) { for( i = 0; pszValue[i] != '\0'; i++ ) { if( (pszValue[i] < '0' || pszValue[i] > '9') && pszValue[i] != '.' && pszValue[i] != '-' && pszValue[i] != '+' && pszValue[i] != 'e' && pszValue[i] != 'E' ) bNeedQuoting = TRUE; } } /* -------------------------------------------------------------------- */ /* Capture this nodes value. We put it in double quotes if */ /* this is a leaf node, otherwise we assume it is a well formed */ /* node name. */ /* -------------------------------------------------------------------- */ if( bNeedQuoting ) { strcat( *ppszResult, "\"" ); strcat( *ppszResult, pszValue ); /* should we do quoting? */ strcat( *ppszResult, "\"" ); } else strcat( *ppszResult, pszValue ); /* -------------------------------------------------------------------- */ /* Add the children strings with appropriate brackets and commas. */ /* -------------------------------------------------------------------- */ if( nChildren > 0 ) strcat( *ppszResult, "[" ); for( i = 0; i < nChildren; i++ ) { strcat( *ppszResult, papszChildrenWkt[i] ); if( i == nChildren-1 ) strcat( *ppszResult, "]" ); else strcat( *ppszResult, "," ); } CSLDestroy( papszChildrenWkt ); return OGRERR_NONE; }
int GMLReader::ResolveXlinks( const char *pszFile, int* pbOutIsTempFile, char **papszSkip, const int bStrict) { *pbOutIsTempFile = FALSE; // Check if the original source file is set. if( m_pszFilename == NULL ) { CPLError( CE_Failure, CPLE_NotSupported, "GML source file needs to be set first with " "GMLReader::SetSourceFile()." ); return FALSE; } /* -------------------------------------------------------------------- */ /* Load the raw XML file into a XML Node tree. */ /* -------------------------------------------------------------------- */ CPLXMLNode **papsSrcTree; papsSrcTree = (CPLXMLNode **)CPLCalloc( 2, sizeof(CPLXMLNode *)); papsSrcTree[0] = CPLParseXMLFile( m_pszFilename ); if( papsSrcTree[0] == NULL ) { CPLFree(papsSrcTree); return FALSE; } //make all the URLs absolute CPLXMLNode *psSibling = NULL; for( psSibling = papsSrcTree[0]; psSibling != NULL; psSibling = psSibling->psNext ) CorrectURLs( psSibling, m_pszFilename ); //setup resource data structure char **papszResourceHREF = NULL; // "" is the href of the original source file papszResourceHREF = CSLAddString( papszResourceHREF, m_pszFilename ); //call resolver CPLErr eReturned = CE_None; eReturned = Resolve( papsSrcTree[0], &papsSrcTree, &papszResourceHREF, papszSkip, bStrict ); int bReturn = TRUE; if( eReturned != CE_Failure ) { char *pszTmpName = NULL; int bTryWithTempFile = FALSE; if( EQUALN(pszFile, "/vsitar/", strlen("/vsitar/")) || EQUALN(pszFile, "/vsigzip/", strlen("/vsigzip/")) || EQUALN(pszFile, "/vsizip/", strlen("/vsizip/")) ) { bTryWithTempFile = TRUE; } else if( !CPLSerializeXMLTreeToFile( papsSrcTree[0], pszFile ) ) { CPLError( CE_Failure, CPLE_FileIO, "Cannot serialize resolved file %s to %s.", m_pszFilename, pszFile ); bTryWithTempFile = TRUE; } if (bTryWithTempFile) { pszTmpName = CPLStrdup( CPLGenerateTempFilename( "ResolvedGML" ) ); if( !CPLSerializeXMLTreeToFile( papsSrcTree[0], pszTmpName ) ) { CPLError( CE_Failure, CPLE_FileIO, "Cannot serialize resolved file %s to %s either.", m_pszFilename, pszTmpName ); CPLFree( pszTmpName ); bReturn = FALSE; } else { //set the source file to the resolved file CPLFree( m_pszFilename ); m_pszFilename = pszTmpName; *pbOutIsTempFile = TRUE; } } else { //set the source file to the resolved file CPLFree( m_pszFilename ); m_pszFilename = CPLStrdup( pszFile ); } } else { bReturn = FALSE; } int nItems = CSLCount( papszResourceHREF ); CSLDestroy( papszResourceHREF ); while( nItems > 0 ) CPLDestroyXMLNode( papsSrcTree[--nItems] ); CPLFree( papsSrcTree ); return bReturn; }
GDALDataset *CTable2Dataset::Create( const char * pszFilename, int nXSize, int nYSize, int nBands, GDALDataType eType, char ** papszOptions ) { if( eType != GDT_Float32 ) { CPLError(CE_Failure, CPLE_AppDefined, "Attempt to create CTable2 file with unsupported data type '%s'.", GDALGetDataTypeName( eType ) ); return NULL; } /* -------------------------------------------------------------------- */ /* Try to open or create file. */ /* -------------------------------------------------------------------- */ VSILFILE *fp; fp = VSIFOpenL( pszFilename, "wb" ); if( fp == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Attempt to create file `%s' failed.\n", pszFilename ); return NULL; } /* -------------------------------------------------------------------- */ /* Create a file header, with a defaulted georeferencing. */ /* -------------------------------------------------------------------- */ char achHeader[160]; int nValue32; double dfValue; memset( achHeader, 0, sizeof(achHeader)); memcpy( achHeader+0, "CTABLE V2.0 ", 16 ); if( CSLFetchNameValue( papszOptions, "DESCRIPTION" ) != NULL ) strncpy( achHeader + 16, CSLFetchNameValue( papszOptions, "DESCRIPTION" ), 80 ); // lower left origin (longitude, center of pixel, radians) dfValue = 0; CPL_LSBPTR64( &dfValue ); memcpy( achHeader + 96, &dfValue, 8 ); // lower left origin (latitude, center of pixel, radians) dfValue = 0; CPL_LSBPTR64( &dfValue ); memcpy( achHeader + 104, &dfValue, 8 ); // pixel width (radians) dfValue = 0.01 * M_PI / 180.0; CPL_LSBPTR64( &dfValue ); memcpy( achHeader + 112, &dfValue, 8 ); // pixel height (radians) dfValue = 0.01 * M_PI / 180.0; CPL_LSBPTR64( &dfValue ); memcpy( achHeader + 120, &dfValue, 8 ); // raster width in pixels nValue32 = nXSize; CPL_LSBPTR32( &nValue32 ); memcpy( achHeader + 128, &nValue32, 4 ); // raster width in pixels nValue32 = nYSize; CPL_LSBPTR32( &nValue32 ); memcpy( achHeader + 132, &nValue32, 4 ); VSIFWriteL( achHeader, 1, sizeof(achHeader), fp ); /* -------------------------------------------------------------------- */ /* Write zeroed grid data. */ /* -------------------------------------------------------------------- */ float *pafLine = (float *) CPLCalloc(sizeof(float)*2,nXSize); int i; for( i = 0; i < nYSize; i++ ) { if( (int)VSIFWriteL( pafLine, sizeof(float)*2, nXSize, fp ) != nXSize ) { CPLError( CE_Failure, CPLE_FileIO, "Write failed at line %d, perhaps the disk is full?", i ); return NULL; } } /* -------------------------------------------------------------------- */ /* Cleanup and return. */ /* -------------------------------------------------------------------- */ CPLFree( pafLine ); VSIFCloseL( fp ); return (GDALDataset *) GDALOpen( pszFilename, GA_Update ); }
void * OGRCalloc( size_t count, size_t size ) { return CPLCalloc( count, size ); }
const char * OGRWktReadPoints( const char * pszInput, OGRRawPoint ** ppaoPoints, double **ppadfZ, int * pnMaxPoints, int * pnPointsRead ) { const char *pszOrigInput = pszInput; *pnPointsRead = 0; if( pszInput == NULL ) return NULL; /* -------------------------------------------------------------------- */ /* Eat any leading white space. */ /* -------------------------------------------------------------------- */ while( *pszInput == ' ' || *pszInput == '\t' ) pszInput++; /* -------------------------------------------------------------------- */ /* If this isn't an opening bracket then we have a problem! */ /* -------------------------------------------------------------------- */ if( *pszInput != '(' ) { CPLDebug( "OGR", "Expected '(', but got %s in OGRWktReadPoints().\n", pszInput ); return pszInput; } pszInput++; /* ==================================================================== */ /* This loop reads a single point. It will continue till we */ /* run out of well formed points, or a closing bracket is */ /* encountered. */ /* ==================================================================== */ char szDelim[OGR_WKT_TOKEN_MAX]; do { /* -------------------------------------------------------------------- */ /* Read the X and Y values, verify they are numeric. */ /* -------------------------------------------------------------------- */ char szTokenX[OGR_WKT_TOKEN_MAX]; char szTokenY[OGR_WKT_TOKEN_MAX]; pszInput = OGRWktReadToken( pszInput, szTokenX ); pszInput = OGRWktReadToken( pszInput, szTokenY ); if( (!isdigit(szTokenX[0]) && szTokenX[0] != '-' && szTokenX[0] != '.' ) || (!isdigit(szTokenY[0]) && szTokenY[0] != '-' && szTokenY[0] != '.') ) return NULL; /* -------------------------------------------------------------------- */ /* Do we need to grow the point list to hold this point? */ /* -------------------------------------------------------------------- */ if( *pnPointsRead == *pnMaxPoints ) { *pnMaxPoints = *pnMaxPoints * 2 + 10; *ppaoPoints = (OGRRawPoint *) CPLRealloc(*ppaoPoints, sizeof(OGRRawPoint) * *pnMaxPoints); if( *ppadfZ != NULL ) { *ppadfZ = (double *) CPLRealloc(*ppadfZ, sizeof(double) * *pnMaxPoints); } } /* -------------------------------------------------------------------- */ /* Add point to list. */ /* -------------------------------------------------------------------- */ (*ppaoPoints)[*pnPointsRead].x = atof(szTokenX); (*ppaoPoints)[*pnPointsRead].y = atof(szTokenY); /* -------------------------------------------------------------------- */ /* Do we have a Z coordinate? */ /* -------------------------------------------------------------------- */ pszInput = OGRWktReadToken( pszInput, szDelim ); if( isdigit(szDelim[0]) || szDelim[0] == '-' || szDelim[0] == '.' ) { if( *ppadfZ == NULL ) { *ppadfZ = (double *) CPLCalloc(sizeof(double),*pnMaxPoints); } (*ppadfZ)[*pnPointsRead] = atof(szDelim); pszInput = OGRWktReadToken( pszInput, szDelim ); } (*pnPointsRead)++; /* -------------------------------------------------------------------- */ /* Do we have a M coordinate? */ /* If we do, just skip it. */ /* -------------------------------------------------------------------- */ if( isdigit(szDelim[0]) || szDelim[0] == '-' || szDelim[0] == '.' ) { pszInput = OGRWktReadToken( pszInput, szDelim ); } /* -------------------------------------------------------------------- */ /* Read next delimeter ... it should be a comma if there are */ /* more points. */ /* -------------------------------------------------------------------- */ if( szDelim[0] != ')' && szDelim[0] != ',' ) { CPLDebug( "OGR", "Corrupt input in OGRWktReadPoints()\n" "Got `%s' when expecting `,' or `)', near `%s' in %s.\n", szDelim, pszInput, pszOrigInput ); return NULL; } } while( szDelim[0] == ',' ); return pszInput; }
int OGRAVCBinDataSource::Open( const char * pszNewName, int bTestOpen ) { /* -------------------------------------------------------------------- */ /* Open the source file. Suppress error reporting if we are in */ /* TestOpen mode. */ /* -------------------------------------------------------------------- */ if( bTestOpen ) CPLPushErrorHandler( CPLQuietErrorHandler ); psAVC = AVCE00ReadOpen( pszNewName ); if( bTestOpen ) { CPLPopErrorHandler(); CPLErrorReset(); } if( psAVC == NULL ) return FALSE; pszName = CPLStrdup( pszNewName ); pszCoverageName = CPLStrdup( psAVC->pszCoverName ); /* -------------------------------------------------------------------- */ /* Create layers for the "interesting" sections of the coverage. */ /* -------------------------------------------------------------------- */ int iSection; papoLayers = (OGRLayer **) CPLCalloc( sizeof(OGRLayer *), psAVC->numSections ); nLayers = 0; for( iSection = 0; iSection < psAVC->numSections; iSection++ ) { AVCE00Section *psSec = psAVC->pasSections + iSection; switch( psSec->eType ) { case AVCFileARC: case AVCFilePAL: case AVCFileCNT: case AVCFileLAB: case AVCFileRPL: case AVCFileTXT: case AVCFileTX6: papoLayers[nLayers++] = new OGRAVCBinLayer( this, psSec ); break; case AVCFilePRJ: { char **papszPRJ; AVCBinFile *hFile; hFile = AVCBinReadOpen(psAVC->pszCoverPath, psSec->pszFilename, psAVC->eCoverType, psSec->eType, psAVC->psDBCSInfo); if( hFile && poSRS == NULL ) { papszPRJ = AVCBinReadNextPrj( hFile ); poSRS = new OGRSpatialReference(); if( poSRS->importFromESRI( papszPRJ ) != OGRERR_NONE ) { CPLError( CE_Warning, CPLE_AppDefined, "Failed to parse PRJ section, ignoring." ); delete poSRS; poSRS = NULL; } AVCBinReadClose( hFile ); } } break; default: ; } } return nLayers > 0; }
/** * \brief Fetch a document from an url and return in a string. * * @param pszURL valid URL recognized by underlying download library (libcurl) * @param papszOptions option list as a NULL-terminated array of strings. May be NULL. * The following options are handled : * <ul> * <li>TIMEOUT=val, where val is in seconds</li> * <li>HEADERS=val, where val is an extra header to use when getting a web page. * For example "Accept: application/x-ogcwkt" * <li>HTTPAUTH=[BASIC/NTLM/GSSNEGOTIATE/ANY] to specify an authentication scheme to use. * <li>USERPWD=userid:password to specify a user and password for authentication * <li>POSTFIELDS=val, where val is a nul-terminated string to be passed to the server * with a POST request. * <li>PROXY=val, to make requests go through a proxy server, where val is of the * form proxy.server.com:port_number * <li>PROXYUSERPWD=val, where val is of the form username:password * <li>CUSTOMREQUEST=val, where val is GET, PUT, POST, DELETE, etc.. (GDAL >= 1.9.0) * </ul> * * Alternatively, if not defined in the papszOptions arguments, the PROXY and * PROXYUSERPWD values are searched in the configuration options named * GDAL_HTTP_PROXY and GDAL_HTTP_PROXYUSERPWD, as proxy configuration belongs * to networking setup and makes more sense at the configuration option level * than at the connection level. * * @return a CPLHTTPResult* structure that must be freed by * CPLHTTPDestroyResult(), or NULL if libcurl support is disabled */ CPLHTTPResult *CPLHTTPFetch( const char *pszURL, char **papszOptions ) { #ifndef HAVE_CURL (void) papszOptions; (void) pszURL; CPLError( CE_Failure, CPLE_NotSupported, "GDAL/OGR not compiled with libcurl support, remote requests not supported." ); return NULL; #else /* -------------------------------------------------------------------- */ /* Are we using a persistent named session? If so, search for */ /* or create it. */ /* */ /* Currently this code does not attempt to protect against */ /* multiple threads asking for the same named session. If that */ /* occurs it will be in use in multiple threads at once which */ /* might have bad consequences depending on what guarantees */ /* libcurl gives - which I have not investigated. */ /* -------------------------------------------------------------------- */ CURL *http_handle = NULL; const char *pszPersistent = CSLFetchNameValue( papszOptions, "PERSISTENT" ); const char *pszClosePersistent = CSLFetchNameValue( papszOptions, "CLOSE_PERSISTENT" ); if (pszPersistent) { CPLString osSessionName = pszPersistent; CPLMutexHolder oHolder( &hSessionMapMutex ); if( oSessionMap.count( osSessionName ) == 0 ) { oSessionMap[osSessionName] = curl_easy_init(); CPLDebug( "HTTP", "Establish persistent session named '%s'.", osSessionName.c_str() ); } http_handle = oSessionMap[osSessionName]; } /* -------------------------------------------------------------------- */ /* Are we requested to close a persistent named session? */ /* -------------------------------------------------------------------- */ else if (pszClosePersistent) { CPLString osSessionName = pszClosePersistent; CPLMutexHolder oHolder( &hSessionMapMutex ); std::map<CPLString,CURL*>::iterator oIter = oSessionMap.find( osSessionName ); if( oIter != oSessionMap.end() ) { curl_easy_cleanup(oIter->second); oSessionMap.erase(oIter); CPLDebug( "HTTP", "Ended persistent session named '%s'.", osSessionName.c_str() ); } else { CPLDebug( "HTTP", "Could not find persistent session named '%s'.", osSessionName.c_str() ); } return NULL; } else http_handle = curl_easy_init(); /* -------------------------------------------------------------------- */ /* Setup the request. */ /* -------------------------------------------------------------------- */ char szCurlErrBuf[CURL_ERROR_SIZE+1]; CPLHTTPResult *psResult; struct curl_slist *headers=NULL; const char* pszArobase = strchr(pszURL, '@'); const char* pszSlash = strchr(pszURL, '/'); const char* pszColon = (pszSlash) ? strchr(pszSlash, ':') : NULL; if (pszArobase != NULL && pszColon != NULL && pszArobase - pszColon > 0) { /* http://user:[email protected] */ char* pszSanitizedURL = CPLStrdup(pszURL); pszSanitizedURL[pszColon-pszURL] = 0; CPLDebug( "HTTP", "Fetch(%s:#password#%s)", pszSanitizedURL, pszArobase ); CPLFree(pszSanitizedURL); } else { CPLDebug( "HTTP", "Fetch(%s)", pszURL ); } psResult = (CPLHTTPResult *) CPLCalloc(1,sizeof(CPLHTTPResult)); curl_easy_setopt(http_handle, CURLOPT_URL, pszURL ); if (CSLTestBoolean(CPLGetConfigOption("CPL_CURL_VERBOSE", "NO"))) curl_easy_setopt(http_handle, CURLOPT_VERBOSE, 1); const char *pszHttpVersion = CSLFetchNameValue( papszOptions, "HTTP_VERSION"); if( pszHttpVersion && strcmp(pszHttpVersion, "1.0") == 0 ) curl_easy_setopt(http_handle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0 ); /* Support control over HTTPAUTH */ const char *pszHttpAuth = CSLFetchNameValue( papszOptions, "HTTPAUTH" ); if( pszHttpAuth == NULL ) /* do nothing */; /* CURLOPT_HTTPAUTH is defined in curl 7.11.0 or newer */ #if LIBCURL_VERSION_NUM >= 0x70B00 else if( EQUAL(pszHttpAuth,"BASIC") ) curl_easy_setopt(http_handle, CURLOPT_HTTPAUTH, CURLAUTH_BASIC ); else if( EQUAL(pszHttpAuth,"NTLM") ) curl_easy_setopt(http_handle, CURLOPT_HTTPAUTH, CURLAUTH_NTLM ); else if( EQUAL(pszHttpAuth,"ANY") ) curl_easy_setopt(http_handle, CURLOPT_HTTPAUTH, CURLAUTH_ANY ); #ifdef CURLAUTH_GSSNEGOTIATE else if( EQUAL(pszHttpAuth,"NEGOTIATE") ) curl_easy_setopt(http_handle, CURLOPT_HTTPAUTH, CURLAUTH_GSSNEGOTIATE ); #endif else { CPLError( CE_Warning, CPLE_AppDefined, "Unsupported HTTPAUTH value '%s', ignored.", pszHttpAuth ); } #else else {
OGRErr OGR_SRSNode::exportToPrettyWkt( char ** ppszResult, int bSimplify, int nDepth ) { char **papszChildrenWkt = NULL; int nLength = strlen(pszValue)+4; int i; /* -------------------------------------------------------------------- */ /* Skip uninteresting nodes if simplify flag is set. */ /* -------------------------------------------------------------------- */ if( bSimplify && (EQUAL(GetValue(),"AUTHORITY") || EQUAL(GetValue(),"AXIS")) ) { *ppszResult = CPLStrdup(""); return OGRERR_NONE; } /* -------------------------------------------------------------------- */ /* Build a list of the WKT format for the children. */ /* -------------------------------------------------------------------- */ papszChildrenWkt = (char **) CPLCalloc(sizeof(char*),(nChildren+1)); for( i = 0; i < nChildren; i++ ) { papoChildNodes[i]->exportToPrettyWkt( papszChildrenWkt + i, bSimplify, nDepth + 1); nLength += strlen(papszChildrenWkt[i]) + 2 + nDepth*4; } /* -------------------------------------------------------------------- */ /* Allocate the result string. */ /* -------------------------------------------------------------------- */ *ppszResult = (char *) CPLMalloc(nLength); *ppszResult[0] = '\0'; /* -------------------------------------------------------------------- */ /* Do we need to quote this value? Determine whether or not */ /* this is a terminal string value. */ /* -------------------------------------------------------------------- */ int bNeedQuoting = FALSE; if( GetChildCount() == 0 ) { for( i = 0; pszValue[i] != '\0'; i++ ) { if( (pszValue[i] < '0' || pszValue[i] > '9') && pszValue[i] != '.' && pszValue[i] != '-' && pszValue[i] != '+' && pszValue[i] != 'e' && pszValue[i] != 'E' ) bNeedQuoting = TRUE; } } /* -------------------------------------------------------------------- */ /* Capture this nodes value. We put it in double quotes if */ /* this is a leaf node, otherwise we assume it is a well formed */ /* node name. */ /* -------------------------------------------------------------------- */ if( bNeedQuoting ) { strcat( *ppszResult, "\"" ); strcat( *ppszResult, pszValue ); /* should we do quoting? */ strcat( *ppszResult, "\"" ); } else strcat( *ppszResult, pszValue ); /* -------------------------------------------------------------------- */ /* Add the children strings with appropriate brackets and commas. */ /* -------------------------------------------------------------------- */ if( nChildren > 0 ) strcat( *ppszResult, "[" ); for( i = 0; i < nChildren; i++ ) { if( strlen(papszChildrenWkt[i]) == 0 ) continue; if( papoChildNodes[i]->GetChildCount() > 0 ) { int j; strcat( *ppszResult, "\n" ); for( j = 0; j < 4*nDepth; j++ ) strcat( *ppszResult, " " ); } strcat( *ppszResult, papszChildrenWkt[i] ); if( i < nChildren-1 ) strcat( *ppszResult, "," ); } if( nChildren > 0 ) { if( (*ppszResult)[strlen(*ppszResult)-1] == ',' ) (*ppszResult)[strlen(*ppszResult)-1] = '\0'; strcat( *ppszResult, "]" ); } CSLDestroy( papszChildrenWkt ); return OGRERR_NONE; }
int OGRPGeoDataSource::Open( const char * pszNewName, int bUpdate, int bTestOpen ) { CPLAssert( nLayers == 0 ); /* -------------------------------------------------------------------- */ /* If this is the name of an MDB file, then construct the */ /* appropriate connection string. Otherwise clip of PGEO: to */ /* get the DSN. */ /* */ /* -------------------------------------------------------------------- */ char *pszDSN; if( EQUALN(pszNewName,"PGEO:",5) ) pszDSN = CPLStrdup( pszNewName + 5 ); else { pszDSN = (char *) CPLMalloc(strlen(pszNewName)+50); sprintf( pszDSN, "DRIVER=Microsoft Access Driver (*.mdb);DBQ=%s", pszNewName ); } /* -------------------------------------------------------------------- */ /* Initialize based on the DSN. */ /* -------------------------------------------------------------------- */ CPLDebug( "PGeo", "EstablishSession(%s)", pszDSN ); if( !oSession.EstablishSession( pszDSN, NULL, NULL ) ) { CPLError( CE_Failure, CPLE_AppDefined, "Unable to initialize ODBC connection to DSN for %s,\n" "%s", pszDSN, oSession.GetLastError() ); CPLFree( pszDSN ); return FALSE; } CPLFree( pszDSN ); pszName = CPLStrdup( pszNewName ); bDSUpdate = bUpdate; /* -------------------------------------------------------------------- */ /* Collect list of tables and their supporting info from */ /* GDB_GeomColumns. */ /* -------------------------------------------------------------------- */ std::vector<char **> apapszGeomColumns; CPLODBCStatement oStmt( &oSession ); oStmt.Append( "SELECT TableName, FieldName, ShapeType, ExtentLeft, ExtentRight, ExtentBottom, ExtentTop, SRID, HasZ FROM GDB_GeomColumns" ); if( !oStmt.ExecuteSQL() ) { CPLDebug( "PGEO", "SELECT on GDB_GeomColumns fails, perhaps not a personal geodatabase?\n%s", oSession.GetLastError() ); return FALSE; } while( oStmt.Fetch() ) { int i, iNew = apapszGeomColumns.size(); char **papszRecord = NULL; for( i = 0; i < 9; i++ ) papszRecord = CSLAddString( papszRecord, oStmt.GetColData(i) ); apapszGeomColumns.resize(iNew+1); apapszGeomColumns[iNew] = papszRecord; } /* -------------------------------------------------------------------- */ /* Create a layer for each spatial table. */ /* -------------------------------------------------------------------- */ unsigned int iTable; papoLayers = (OGRPGeoLayer **) CPLCalloc(apapszGeomColumns.size(), sizeof(void*)); for( iTable = 0; iTable < apapszGeomColumns.size(); iTable++ ) { char **papszRecord = apapszGeomColumns[iTable]; OGRPGeoTableLayer *poLayer; poLayer = new OGRPGeoTableLayer( this ); if( poLayer->Initialize( papszRecord[0], // TableName papszRecord[1], // FieldName atoi(papszRecord[2]), // ShapeType atof(papszRecord[3]), // ExtentLeft atof(papszRecord[4]), // ExtentRight atof(papszRecord[5]), // ExtentBottom atof(papszRecord[6]), // ExtentTop atoi(papszRecord[7]), // SRID atoi(papszRecord[8])) // HasZ != CE_None ) { delete poLayer; } else papoLayers[nLayers++] = poLayer; CSLDestroy( papszRecord ); } return TRUE; }
herr_t HDF5CreateGroupObjs( hid_t hHDF5, const char *pszObjName, void *poHObjParent) { HDF5GroupObjects *const poHparent = static_cast<HDF5GroupObjects *>(poHObjParent); HDF5GroupObjects *poHchild = poHparent->poHchild; H5G_stat_t oStatbuf; if( H5Gget_objinfo(hHDF5, pszObjName, FALSE, &oStatbuf) < 0 ) return -1; // Look for next child. unsigned idx = 0; // idx is used after the for loop. for( ; idx < poHparent->nbObjs; idx++ ) { if( poHchild->pszName == nullptr ) break; poHchild++; } if( idx == poHparent->nbObjs ) return -1; // All children parsed. // Save child information. poHchild->pszName = CPLStrdup(pszObjName); poHchild->nType = oStatbuf.type; poHchild->nIndex = idx; poHchild->poHparent = poHparent; poHchild->nRank = 0; poHchild->paDims = nullptr; poHchild->HDatatype = 0; poHchild->objno[0] = oStatbuf.objno[0]; poHchild->objno[1] = oStatbuf.objno[1]; if( poHchild->pszPath == nullptr ) { CreatePath(poHchild); } if( poHparent->pszPath == nullptr ) { CreatePath(poHparent); } switch( oStatbuf.type ) { case H5G_LINK: { poHchild->nbAttrs = 0; poHchild->nbObjs = 0; poHchild->poHchild = nullptr; poHchild->nRank = 0; poHchild->paDims = nullptr; poHchild->HDatatype = 0; break; } case H5G_GROUP: { hid_t hGroupID = H5I_INVALID_HID; // Identifier of group. if( (hGroupID = H5Gopen(hHDF5, pszObjName)) == -1) { CPLError(CE_Failure, CPLE_AppDefined, "unable to access \"%s\" group.", pszObjName); return -1; } // Number of attributes in object. const int nbAttrs = H5Aget_num_attrs(hGroupID); hsize_t nbObjs = 0; // Number of objects in a group. H5Gget_num_objs(hGroupID, &nbObjs); poHchild->nbAttrs = nbAttrs; poHchild->nbObjs = static_cast<int>(nbObjs); poHchild->nRank = 0; poHchild->paDims = nullptr; poHchild->HDatatype = 0; if( nbObjs > 0 ) { poHchild->poHchild = static_cast<HDF5GroupObjects *>( CPLCalloc(static_cast<int>(nbObjs), sizeof(HDF5GroupObjects))); memset(poHchild->poHchild, 0, static_cast<size_t>(sizeof(HDF5GroupObjects) * nbObjs)); } else { poHchild->poHchild = nullptr; } if( !HDF5GroupCheckDuplicate(poHparent, oStatbuf.objno) ) H5Giterate(hHDF5, pszObjName, nullptr, HDF5CreateGroupObjs, poHchild); else CPLDebug("HDF5", "avoiding link looping on node '%s'.", pszObjName); H5Gclose(hGroupID); break; } case H5G_DATASET: { hid_t hDatasetID = H5I_INVALID_HID; // Identifier of dataset. if( (hDatasetID = H5Dopen(hHDF5, pszObjName)) == -1) { CPLError(CE_Failure, CPLE_AppDefined, "unable to access \"%s\" dataset.", pszObjName); return -1; } const int nbAttrs = H5Aget_num_attrs(hDatasetID); const hid_t datatype = H5Dget_type(hDatasetID); const hid_t dataspace = H5Dget_space(hDatasetID); const int n_dims = H5Sget_simple_extent_ndims(dataspace); const hid_t native = H5Tget_native_type(datatype, H5T_DIR_ASCEND); hsize_t *maxdims = nullptr; hsize_t *dims = nullptr; if( n_dims > 0 ) { dims = static_cast<hsize_t *>(CPLCalloc(n_dims, sizeof(hsize_t))); maxdims = static_cast<hsize_t *>(CPLCalloc(n_dims, sizeof(hsize_t))); } H5Sget_simple_extent_dims(dataspace, dims, maxdims); if( maxdims != nullptr ) CPLFree(maxdims); if( n_dims > 0 ) { poHchild->nRank = n_dims; // rank of the array poHchild->paDims = dims; // dimension of the array. poHchild->HDatatype = datatype; // HDF5 datatype } else { poHchild->nRank = -1; poHchild->paDims = nullptr; poHchild->HDatatype = 0; } poHchild->nbAttrs = nbAttrs; poHchild->nbObjs = 0; poHchild->poHchild = nullptr; poHchild->native = native; H5Tclose(datatype); H5Sclose(dataspace); H5Dclose(hDatasetID); break; } case H5G_TYPE: { poHchild->nbAttrs = 0; poHchild->nbObjs = 0; poHchild->poHchild = nullptr; poHchild->nRank = 0; poHchild->paDims = nullptr; poHchild->HDatatype = 0; break; } default: break; } return 0; }
GDALDataset *HDF5ImageDataset::Open( GDALOpenInfo * poOpenInfo ) { int i; HDF5ImageDataset *poDS; char szFilename[2048]; if(!EQUALN( poOpenInfo->pszFilename, "HDF5:", 5 ) || strlen(poOpenInfo->pszFilename) > sizeof(szFilename) - 3 ) return NULL; /* -------------------------------------------------------------------- */ /* Confirm the requested access is supported. */ /* -------------------------------------------------------------------- */ if( poOpenInfo->eAccess == GA_Update ) { CPLError( CE_Failure, CPLE_NotSupported, "The HDF5ImageDataset driver does not support update access to existing" " datasets.\n" ); return NULL; } poDS = new HDF5ImageDataset(); /* -------------------------------------------------------------------- */ /* Create a corresponding GDALDataset. */ /* -------------------------------------------------------------------- */ /* printf("poOpenInfo->pszFilename %s\n",poOpenInfo->pszFilename); */ char **papszName = CSLTokenizeString2( poOpenInfo->pszFilename, ":", CSLT_HONOURSTRINGS|CSLT_PRESERVEESCAPES ); if( !((CSLCount(papszName) == 3) || (CSLCount(papszName) == 4)) ) { CSLDestroy(papszName); delete poDS; return NULL; } poDS->SetDescription( poOpenInfo->pszFilename ); /* -------------------------------------------------------------------- */ /* Check for drive name in windows HDF5:"D:\... */ /* -------------------------------------------------------------------- */ CPLString osSubdatasetName; strcpy(szFilename, papszName[1]); if( strlen(papszName[1]) == 1 && papszName[3] != NULL ) { strcat(szFilename, ":"); strcat(szFilename, papszName[2]); osSubdatasetName = papszName[3]; } else osSubdatasetName = papszName[2]; poDS->SetSubdatasetName( osSubdatasetName ); CSLDestroy(papszName); papszName = NULL; if( !H5Fis_hdf5(szFilename) ) { delete poDS; return NULL; } poDS->SetPhysicalFilename( szFilename ); /* -------------------------------------------------------------------- */ /* Try opening the dataset. */ /* -------------------------------------------------------------------- */ poDS->hHDF5 = H5Fopen(szFilename, H5F_ACC_RDONLY, H5P_DEFAULT ); if( poDS->hHDF5 < 0 ) { delete poDS; return NULL; } poDS->hGroupID = H5Gopen( poDS->hHDF5, "/" ); if( poDS->hGroupID < 0 ) { poDS->bIsHDFEOS=false; delete poDS; return NULL; } /* -------------------------------------------------------------------- */ /* THIS IS AN HDF5 FILE */ /* -------------------------------------------------------------------- */ poDS->bIsHDFEOS=TRUE; poDS->ReadGlobalAttributes( FALSE ); /* -------------------------------------------------------------------- */ /* Create HDF5 Data Hierarchy in a link list */ /* -------------------------------------------------------------------- */ poDS->poH5Objects = poDS->HDF5FindDatasetObjectsbyPath( poDS->poH5RootGroup, osSubdatasetName ); if( poDS->poH5Objects == NULL ) { delete poDS; return NULL; } /* -------------------------------------------------------------------- */ /* Retrieve HDF5 data information */ /* -------------------------------------------------------------------- */ poDS->dataset_id = H5Dopen( poDS->hHDF5,poDS->poH5Objects->pszPath ); poDS->dataspace_id = H5Dget_space( poDS->dataset_id ); poDS->ndims = H5Sget_simple_extent_ndims( poDS->dataspace_id ); poDS->dims = (hsize_t*)CPLCalloc( poDS->ndims, sizeof(hsize_t) ); poDS->maxdims = (hsize_t*)CPLCalloc( poDS->ndims, sizeof(hsize_t) ); poDS->dimensions = H5Sget_simple_extent_dims( poDS->dataspace_id, poDS->dims, poDS->maxdims ); poDS->datatype = H5Dget_type( poDS->dataset_id ); poDS->clas = H5Tget_class( poDS->datatype ); poDS->size = H5Tget_size( poDS->datatype ); poDS->address = H5Dget_offset( poDS->dataset_id ); poDS->native = H5Tget_native_type( poDS->datatype, H5T_DIR_ASCEND ); poDS->nRasterYSize=(int)poDS->dims[poDS->ndims-2]; // Y poDS->nRasterXSize=(int)poDS->dims[poDS->ndims-1]; // X alway last poDS->nBands=1; if( poDS->ndims == 3 ) poDS->nBands=(int) poDS->dims[0]; for( i = 1; i <= poDS->nBands; i++ ) { HDF5ImageRasterBand *poBand = new HDF5ImageRasterBand( poDS, i, poDS->GetDataType( poDS->native ) ); poDS->SetBand( i, poBand ); if( poBand->bNoDataSet ) poBand->SetNoDataValue( 255 ); } // CSK code in IdentifyProductType() and CreateProjections() // uses dataset metadata. poDS->SetMetadata( poDS->papszMetadata ); // Check if the hdf5 is a well known product type poDS->IdentifyProductType(); poDS->CreateProjections( ); /* -------------------------------------------------------------------- */ /* Setup/check for pam .aux.xml. */ /* -------------------------------------------------------------------- */ poDS->TryLoadXML(); /* -------------------------------------------------------------------- */ /* Setup overviews. */ /* -------------------------------------------------------------------- */ poDS->oOvManager.Initialize( poDS, ":::VIRTUAL:::" ); return( poDS ); }
int main( int argc, char ** argv ) { /* Check that we are running against at least GDAL 1.4 (probably older in fact !) */ /* Note to developers : if we use newer API, please change the requirement */ if (atoi(GDALVersionInfo("VERSION_NUM")) < 1400) { fprintf(stderr, "At least, GDAL >= 1.4.0 is required for this version of %s, " "which was compiled against GDAL %s\n", argv[0], GDAL_RELEASE_NAME); exit(1); } /* -------------------------------------------------------------------- */ /* Generic arg processing. */ /* -------------------------------------------------------------------- */ GDALAllRegister(); GDALSetCacheMax( 100000000 ); argc = GDALGeneralCmdLineProcessor( argc, &argv, 0 ); if( argc < 1 ) exit( -argc ); /* -------------------------------------------------------------------- */ /* Parse arguments. */ /* -------------------------------------------------------------------- */ int i; const char *pszOutFile = NULL; const char *pszInFile = NULL; int nMaxNonBlack = 2; int nNearDist = 15; int bNearWhite = FALSE; 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], "-o") && i < argc-1 ) pszOutFile = argv[++i]; else if( EQUAL(argv[i], "-white") ) bNearWhite = TRUE; else if( EQUAL(argv[i], "-nb") && i < argc-1 ) nMaxNonBlack = atoi(argv[++i]); else if( EQUAL(argv[i], "-near") && i < argc-1 ) nNearDist = atoi(argv[++i]); else if( argv[i][0] == '-' ) Usage(); else if( pszInFile == NULL ) pszInFile = argv[i]; else Usage(); } if( pszInFile == NULL ) Usage(); if( pszOutFile == NULL ) pszOutFile = pszInFile; /* -------------------------------------------------------------------- */ /* Open input file. */ /* -------------------------------------------------------------------- */ GDALDatasetH hInDS, hOutDS = NULL; int nXSize, nYSize, nBands; if( pszOutFile == pszInFile ) hInDS = hOutDS = GDALOpen( pszInFile, GA_Update ); else hInDS = GDALOpen( pszInFile, GA_ReadOnly ); if( hInDS == NULL ) exit( 1 ); nXSize = GDALGetRasterXSize( hInDS ); nYSize = GDALGetRasterYSize( hInDS ); nBands = GDALGetRasterCount( hInDS ); /* -------------------------------------------------------------------- */ /* Do we need to create output file? */ /* -------------------------------------------------------------------- */ if( hOutDS == NULL ) { GDALDriverH hDriver = GDALGetDriverByName( "HFA" ); hOutDS = GDALCreate( hDriver, pszOutFile, nXSize, nYSize, nBands, GDT_Byte, NULL ); if( hOutDS == NULL ) exit( 1 ); double adfGeoTransform[6]; if( GDALGetGeoTransform( hInDS, adfGeoTransform ) == CE_None ) { GDALSetGeoTransform( hOutDS, adfGeoTransform ); GDALSetProjection( hOutDS, GDALGetProjectionRef( hInDS ) ); } } int iBand; for( iBand = 0; iBand < nBands; iBand++ ) { GDALRasterBandH hBand = GDALGetRasterBand(hInDS, iBand+1); if (GDALGetRasterDataType(hBand) != GDT_Byte) { CPLError(CE_Warning, CPLE_AppDefined, "Band %d is not of type GDT_Byte. It can lead to unexpected results.", iBand+1); } if (GDALGetRasterColorTable(hBand) != NULL) { CPLError(CE_Warning, CPLE_AppDefined, "Band %d has a color table, which is ignored by nearblack. " "It can lead to unexpected results.", iBand+1); } } /* -------------------------------------------------------------------- */ /* Allocate a line buffer. */ /* -------------------------------------------------------------------- */ GByte *pabyLine; int *panLastLineCounts; pabyLine = (GByte *) CPLMalloc(nXSize * nBands); panLastLineCounts = (int *) CPLCalloc(sizeof(int),nXSize); /* -------------------------------------------------------------------- */ /* Processing data one line at a time. */ /* -------------------------------------------------------------------- */ int iLine; for( iLine = 0; iLine < nYSize; iLine++ ) { CPLErr eErr; eErr = GDALDatasetRasterIO( hInDS, GF_Read, 0, iLine, nXSize, 1, pabyLine, nXSize, 1, GDT_Byte, nBands, NULL, nBands, nXSize * nBands, 1 ); if( eErr != CE_None ) break; ProcessLine( pabyLine, 0, nXSize-1, nBands, nNearDist, nMaxNonBlack, bNearWhite, panLastLineCounts, TRUE, TRUE ); ProcessLine( pabyLine, nXSize-1, 0, nBands, nNearDist, nMaxNonBlack, bNearWhite, NULL, TRUE, FALSE ); eErr = GDALDatasetRasterIO( hOutDS, GF_Write, 0, iLine, nXSize, 1, pabyLine, nXSize, 1, GDT_Byte, nBands, NULL, nBands, nXSize * nBands, 1 ); if( eErr != CE_None ) break; GDALTermProgress( 0.5 * ((iLine+1) / (double) nYSize), NULL, NULL ); } /* -------------------------------------------------------------------- */ /* Now process from the bottom back up, doing only the vertical pass.*/ /* -------------------------------------------------------------------- */ memset( panLastLineCounts, 0, sizeof(int) * nXSize); for( iLine = nYSize-1; iLine >= 0; iLine-- ) { CPLErr eErr; eErr = GDALDatasetRasterIO( hOutDS, GF_Read, 0, iLine, nXSize, 1, pabyLine, nXSize, 1, GDT_Byte, nBands, NULL, nBands, nXSize * nBands, 1 ); if( eErr != CE_None ) break; ProcessLine( pabyLine, 0, nXSize-1, nBands, nNearDist, nMaxNonBlack, bNearWhite, panLastLineCounts, FALSE, TRUE ); eErr = GDALDatasetRasterIO( hOutDS, GF_Write, 0, iLine, nXSize, 1, pabyLine, nXSize, 1, GDT_Byte, nBands, NULL, nBands, nXSize * nBands, 1 ); if( eErr != CE_None ) break; GDALTermProgress( 0.5 + 0.5 * (nYSize-iLine) / (double) nYSize, NULL, NULL ); } CPLFree(pabyLine); CPLFree( panLastLineCounts ); GDALClose( hOutDS ); if( hInDS != hOutDS ) GDALClose( hInDS ); GDALDumpOpenDatasets( stderr ); GDALDestroyDriverManager(); return 0; }
OGRErr OGRMultiPolygon::exportToWkt( char ** ppszDstText ) const { char **papszPolygons; int iPoly, nCumulativeLength = 0, nValidPolys=0; OGRErr eErr; int bMustWriteComma = FALSE; /* -------------------------------------------------------------------- */ /* Build a list of strings containing the stuff for each ring. */ /* -------------------------------------------------------------------- */ papszPolygons = (char **) CPLCalloc(sizeof(char *),getNumGeometries()); for( iPoly = 0; iPoly < getNumGeometries(); iPoly++ ) { eErr = getGeometryRef(iPoly)->exportToWkt( &(papszPolygons[iPoly]) ); if( eErr != OGRERR_NONE ) goto error; if( !EQUALN(papszPolygons[iPoly],"POLYGON (", 9) ) { CPLDebug( "OGR", "OGRMultiPolygon::exportToWkt() - skipping %s.", papszPolygons[iPoly] ); CPLFree( papszPolygons[iPoly] ); papszPolygons[iPoly] = NULL; continue; } nCumulativeLength += strlen(papszPolygons[iPoly] + 8); nValidPolys++; } /* -------------------------------------------------------------------- */ /* Return MULTIPOLYGON EMPTY if we get no valid polygons. */ /* -------------------------------------------------------------------- */ if( nValidPolys == 0 ) { CPLFree( papszPolygons ); *ppszDstText = CPLStrdup("MULTIPOLYGON EMPTY"); return OGRERR_NONE; } /* -------------------------------------------------------------------- */ /* Allocate exactly the right amount of space for the */ /* aggregated string. */ /* -------------------------------------------------------------------- */ *ppszDstText = (char *) VSIMalloc(nCumulativeLength+getNumGeometries()+20); if( *ppszDstText == NULL ) { eErr = OGRERR_NOT_ENOUGH_MEMORY; goto error; } /* -------------------------------------------------------------------- */ /* Build up the string, freeing temporary strings as we go. */ /* -------------------------------------------------------------------- */ strcpy( *ppszDstText, "MULTIPOLYGON (" ); nCumulativeLength = strlen(*ppszDstText); for( iPoly = 0; iPoly < getNumGeometries(); iPoly++ ) { if( papszPolygons[iPoly] == NULL ) continue; if( bMustWriteComma ) (*ppszDstText)[nCumulativeLength++] = ','; bMustWriteComma = TRUE; int nPolyLength = strlen(papszPolygons[iPoly] + 8); memcpy( *ppszDstText + nCumulativeLength, papszPolygons[iPoly] + 8, nPolyLength ); nCumulativeLength += nPolyLength; VSIFree( papszPolygons[iPoly] ); } (*ppszDstText)[nCumulativeLength++] = ')'; (*ppszDstText)[nCumulativeLength] = '\0'; CPLFree( papszPolygons ); return OGRERR_NONE; error: for( iPoly = 0; iPoly < getNumGeometries(); iPoly++ ) CPLFree( papszPolygons[iPoly] ); CPLFree( papszPolygons ); return eErr; }
OGRLayer *OGRDataSource::CopyLayer( OGRLayer *poSrcLayer, const char *pszNewName, char **papszOptions ) { OGRFeatureDefn *poSrcDefn = poSrcLayer->GetLayerDefn(); OGRLayer *poDstLayer = NULL; /* -------------------------------------------------------------------- */ /* Create the layer. */ /* -------------------------------------------------------------------- */ if( !TestCapability( ODsCCreateLayer ) ) { CPLError( CE_Failure, CPLE_NotSupported, "This datasource does not support creation of layers." ); return NULL; } CPLErrorReset(); poDstLayer = CreateLayer( pszNewName, poSrcLayer->GetSpatialRef(), poSrcDefn->GetGeomType(), papszOptions ); if( poDstLayer == NULL ) return NULL; /* -------------------------------------------------------------------- */ /* Add fields. Default to copy all field. */ /* If only a subset of all fields requested, then output only */ /* the selected fields, and in the order that they were */ /* selected. */ /* -------------------------------------------------------------------- */ int iField; for( iField = 0; iField < poSrcDefn->GetFieldCount(); iField++ ) poDstLayer->CreateField( poSrcDefn->GetFieldDefn(iField) ); /* -------------------------------------------------------------------- */ /* Check if the destination layer supports transactions and set a */ /* default number of features in a single transaction. */ /* -------------------------------------------------------------------- */ int nGroupTransactions = 0; if( poDstLayer->TestCapability( OLCTransactions ) ) nGroupTransactions = 128; /* -------------------------------------------------------------------- */ /* Transfer features. */ /* -------------------------------------------------------------------- */ OGRFeature *poFeature; poSrcLayer->ResetReading(); if( nGroupTransactions <= 0 ) { while( TRUE ) { OGRFeature *poDstFeature = NULL; poFeature = poSrcLayer->GetNextFeature(); if( poFeature == NULL ) break; CPLErrorReset(); poDstFeature = OGRFeature::CreateFeature( poDstLayer->GetLayerDefn() ); if( poDstFeature->SetFrom( poFeature, TRUE ) != OGRERR_NONE ) { delete poFeature; CPLError( CE_Failure, CPLE_AppDefined, "Unable to translate feature %ld from layer %s.\n", poFeature->GetFID(), poSrcDefn->GetName() ); return poDstLayer; } poDstFeature->SetFID( poFeature->GetFID() ); OGRFeature::DestroyFeature( poFeature ); CPLErrorReset(); if( poDstLayer->CreateFeature( poDstFeature ) != OGRERR_NONE ) { OGRFeature::DestroyFeature( poDstFeature ); return poDstLayer; } OGRFeature::DestroyFeature( poDstFeature ); } } else { int i, bStopTransfer = FALSE, bStopTransaction = FALSE; int nFeatCount = 0; // Number of features in the temporary array int nFeaturesToAdd = 0; while( !bStopTransfer ) { OGRFeature **papoDstFeature = (OGRFeature **)CPLCalloc(sizeof(OGRFeature *), nGroupTransactions); /* -------------------------------------------------------------------- */ /* Fill the array with features */ /* -------------------------------------------------------------------- */ for( nFeatCount = 0; nFeatCount < nGroupTransactions; nFeatCount++ ) { poFeature = poSrcLayer->GetNextFeature(); if( poFeature == NULL ) { bStopTransfer = 1; break; } CPLErrorReset(); papoDstFeature[nFeatCount] = OGRFeature::CreateFeature( poDstLayer->GetLayerDefn() ); if( papoDstFeature[nFeatCount]->SetFrom( poFeature, TRUE ) != OGRERR_NONE ) { OGRFeature::DestroyFeature( poFeature ); CPLError( CE_Failure, CPLE_AppDefined, "Unable to translate feature %ld from layer %s.\n", poFeature->GetFID(), poSrcDefn->GetName() ); bStopTransfer = TRUE; break; } papoDstFeature[nFeatCount]->SetFID( poFeature->GetFID() ); OGRFeature::DestroyFeature( poFeature ); } nFeaturesToAdd = nFeatCount; CPLErrorReset(); bStopTransaction = FALSE; while( !bStopTransaction ) { bStopTransaction = TRUE; poDstLayer->StartTransaction(); for( i = 0; i < nFeaturesToAdd; i++ ) { if( poDstLayer->CreateFeature( papoDstFeature[i] ) != OGRERR_NONE ) { nFeaturesToAdd = i; bStopTransfer = TRUE; bStopTransaction = FALSE; } } if( bStopTransaction ) poDstLayer->CommitTransaction(); else poDstLayer->RollbackTransaction(); } for( i = 0; i < nFeatCount; i++ ) OGRFeature::DestroyFeature( papoDstFeature[i] ); } } return poDstLayer; }
void OGRILI1Layer::PolygonizeAreaLayer( OGRILI1Layer* poAreaLineLayer, int nAreaFieldIndex, int nPointFieldIndex ) { //add all lines from poAreaLineLayer to collection OGRGeometryCollection *gc = new OGRGeometryCollection(); poAreaLineLayer->ResetReading(); while (OGRFeature *feature = poAreaLineLayer->GetNextFeatureRef()) gc->addGeometry(feature->GetGeometryRef()); //polygonize lines CPLDebug( "OGR_ILI", "Polygonizing layer %s with %d multilines", poAreaLineLayer->GetLayerDefn()->GetName(), gc->getNumGeometries()); poAreaLineLayer = 0; OGRMultiPolygon* polys = Polygonize( gc , false); CPLDebug( "OGR_ILI", "Resulting polygons: %d", polys->getNumGeometries()); if (polys->getNumGeometries() != GetFeatureCount()) { CPLDebug( "OGR_ILI", "Feature count of layer %s: " CPL_FRMT_GIB, GetLayerDefn()->GetName(), GetFeatureCount()); CPLDebug( "OGR_ILI", "Polygonizing again with crossing line fix"); delete polys; polys = Polygonize( gc, true ); //try again with crossing line fix CPLDebug( "OGR_ILI", "Resulting polygons: %d", polys->getNumGeometries()); } delete gc; //associate polygon feature with data row according to centroid #if defined(HAVE_GEOS) int i; OGRPolygon emptyPoly; GEOSGeom *ahInGeoms = NULL; CPLDebug( "OGR_ILI", "Associating layer %s with area polygons", GetLayerDefn()->GetName()); ahInGeoms = (GEOSGeom *) CPLCalloc(sizeof(void*), polys->getNumGeometries()); GEOSContextHandle_t hGEOSCtxt = OGRGeometry::createGEOSContext(); for( i = 0; i < polys->getNumGeometries(); i++ ) { ahInGeoms[i] = polys->getGeometryRef(i)->exportToGEOS(hGEOSCtxt); if (!GEOSisValid_r(hGEOSCtxt, ahInGeoms[i])) ahInGeoms[i] = NULL; } for ( int nFidx = 0; nFidx < nFeatures; nFidx++) { OGRFeature *feature = papoFeatures[nFidx]; OGRGeometry* geomRef = feature->GetGeomFieldRef(nPointFieldIndex); if( !geomRef ) { continue; } GEOSGeom point = (GEOSGeom)(geomRef->exportToGEOS(hGEOSCtxt)); for (i = 0; i < polys->getNumGeometries(); i++ ) { if (ahInGeoms[i] && GEOSWithin_r(hGEOSCtxt, point, ahInGeoms[i])) { feature->SetGeomField(nAreaFieldIndex, polys->getGeometryRef(i)); break; } } if (i == polys->getNumGeometries()) { CPLDebug( "OGR_ILI", "Association between area and point failed."); feature->SetGeometry( &emptyPoly ); } GEOSGeom_destroy_r( hGEOSCtxt, point ); } for( i = 0; i < polys->getNumGeometries(); i++ ) GEOSGeom_destroy_r( hGEOSCtxt, ahInGeoms[i] ); CPLFree( ahInGeoms ); OGRGeometry::freeGEOSContext( hGEOSCtxt ); #endif poAreaLineLayer = 0; delete polys; }
void OGRILI1Layer::PolygonizeAreaLayer() { if (poAreaLineLayer == 0) return; //add all lines from poAreaLineLayer to collection OGRGeometryCollection *gc = new OGRGeometryCollection(); poAreaLineLayer->ResetReading(); while (OGRFeature *feature = poAreaLineLayer->GetNextFeatureRef()) gc->addGeometry(feature->GetGeometryRef()); //polygonize lines CPLDebug( "OGR_ILI", "Polygonizing layer %s with %d multilines", poAreaLineLayer->GetLayerDefn()->GetName(), gc->getNumGeometries()); poAreaLineLayer = 0; OGRMultiPolygon* polys = Polygonize( gc , false); CPLDebug( "OGR_ILI", "Resulting polygons: %d", polys->getNumGeometries()); if (polys->getNumGeometries() != poAreaReferenceLayer->GetFeatureCount()) { CPLDebug( "OGR_ILI", "Feature count of layer %s: %d", poAreaReferenceLayer->GetLayerDefn()->GetName(), GetFeatureCount()); CPLDebug( "OGR_ILI", "Polygonizing again with crossing line fix"); delete polys; polys = Polygonize( gc, true ); //try again with crossing line fix } delete gc; //associate polygon feature with data row according to centroid #if defined(HAVE_GEOS) int i; OGRPolygon emptyPoly; GEOSGeom *ahInGeoms = NULL; CPLDebug( "OGR_ILI", "Associating layer %s with area polygons", GetLayerDefn()->GetName()); ahInGeoms = (GEOSGeom *) CPLCalloc(sizeof(void*),polys->getNumGeometries()); for( i = 0; i < polys->getNumGeometries(); i++ ) { ahInGeoms[i] = polys->getGeometryRef(i)->exportToGEOS(); if (!GEOSisValid(ahInGeoms[i])) ahInGeoms[i] = NULL; } poAreaReferenceLayer->ResetReading(); while (OGRFeature *feature = poAreaReferenceLayer->GetNextFeatureRef()) { OGRGeometry* geomRef = feature->GetGeometryRef(); if( !geomRef ) { continue; } GEOSGeom point = (GEOSGeom)(geomRef->exportToGEOS()); for (i = 0; i < polys->getNumGeometries(); i++ ) { if (ahInGeoms[i] && GEOSWithin(point, ahInGeoms[i])) { OGRFeature* areaFeature = new OGRFeature(poFeatureDefn); areaFeature->SetFrom(feature); areaFeature->SetGeometry( polys->getGeometryRef(i) ); AddFeature(areaFeature); break; } } if (i == polys->getNumGeometries()) { CPLDebug( "OGR_ILI", "Association between area and point failed."); feature->SetGeometry( &emptyPoly ); } GEOSGeom_destroy( point ); } for( i = 0; i < polys->getNumGeometries(); i++ ) GEOSGeom_destroy( ahInGeoms[i] ); CPLFree( ahInGeoms ); #endif poAreaLineLayer = 0; delete polys; }
/********************************************************************** * AVCE00WriteOpen() * * Open (create) an Arc/Info coverage, ready to be receive a stream * of ASCII E00 lines and convert that to the binary coverage format. * * For now, writing to or overwriting existing coverages is not supported * (and may quite well never be!)... you can only create new coverages. * * Important Note: The E00 source lines are assumed to be valid... the * library performs no validation on the consistency of what it is * given as input (i.e. topology, polygons consistency, etc.). * So the coverage that will be created will be only as good as the * E00 input that is used to generate it. * * pszCoverPath MUST be the name of the coverage directory, including * the path to it. * (contrary to AVCE00ReadOpen(), you cannot pass the name of one of * the files in the coverage directory). * The name of the coverage MUST be included in pszCoverPath... this * means that passing "." is invalid. * * nPrecision should always be AVC_DEFAULT_PREC to automagically detect the * source coverage's precision and use that same precision * for the new coverage. * * This parameter has been included to allow adding the * possibility to eventually create coverages with a precision * different from the source E00. * Given the way the lib is built, it could be possible to * also pass AVC_SINGLE_PREC or AVC_DOUBLE_PREC to explicitly * request the creation of a coverage with that precision, * but the library does not (not yet!) properly convert the * TABLE attributes' precision, and the resulting coverage may * be invalid in some cases. * This improvement is on the ToDo list! * * Returns a new AVCE00WritePtr handle or NULL if the coverage could * not be created or if a coverage with that name already exists. * * The handle will eventually have to be released with AVCE00ReadClose(). **********************************************************************/ AVCE00WritePtr AVCE00WriteOpen(const char *pszCoverPath, int nPrecision) { AVCE00WritePtr psInfo; int i, nLen; VSIStatBuf sStatBuf; CPLErrorReset(); /*----------------------------------------------------------------- * Create pszCoverPath directory. * This should fail if the directory already exists. *----------------------------------------------------------------*/ if (pszCoverPath == NULL || strlen(pszCoverPath) == 0 || #ifdef WIN32 mkdir(pszCoverPath) != 0 #else mkdir (pszCoverPath, 0777) != 0 #endif ) { CPLError(CE_Failure, CPLE_OpenFailed, "Unable to create coverage directory: %s.", pszCoverPath?pszCoverPath:"(NULL)"); return NULL; } /*----------------------------------------------------------------- * Alloc the AVCE00WritePtr handle *----------------------------------------------------------------*/ psInfo = (AVCE00WritePtr)CPLCalloc(1, sizeof(struct AVCE00WriteInfo_t)); /*----------------------------------------------------------------- * Requested precision for the new coverage... for now only * AVC_DEFAULT_PREC is supported. When the first section is * read, then this section's precision will be used for the whole * coverage. (This is done inside AVCE00WriteNextLine()) *----------------------------------------------------------------*/ if (nPrecision == AVC_DEFAULT_PREC) psInfo->nPrecision = nPrecision; else { CPLError(CE_Failure, CPLE_IllegalArg, "Coverages can only be created using AVC_DEFAULT_PREC. " "Please see the documentation for AVCE00WriteOpen()."); CPLFree(psInfo); return NULL; } /*----------------------------------------------------------------- * Make sure coverage directory name is terminated with a '/' (or '\\') *----------------------------------------------------------------*/ nLen = strlen(pszCoverPath); if (pszCoverPath[nLen-1] == '/' || pszCoverPath[nLen-1] == '\\') psInfo->pszCoverPath = CPLStrdup(pszCoverPath); else { #ifdef WIN32 psInfo->pszCoverPath = CPLStrdup(CPLSPrintf("%s\\",pszCoverPath)); #else psInfo->pszCoverPath = CPLStrdup(CPLSPrintf("%s/",pszCoverPath)); #endif } /*----------------------------------------------------------------- * Extract the coverage name from the coverage path. Note that * for this the coverage path must be in the form: * "dir1/dir2/dir3/covername/" ... if it is not the case, then * we would have to use getcwd() to find the current directory name... * but for now we'll just produce an error if this happens. *----------------------------------------------------------------*/ nLen = 0; for( i = strlen(psInfo->pszCoverPath)-1; i > 0 && psInfo->pszCoverPath[i-1] != '/' && psInfo->pszCoverPath[i-1] != '\\'&& psInfo->pszCoverPath[i-1] != ':'; i-- ) { nLen++; } if (nLen > 0) { psInfo->pszCoverName = CPLStrdup(psInfo->pszCoverPath+i); psInfo->pszCoverName[nLen] = '\0'; } else { CPLError(CE_Failure, CPLE_OpenFailed, "Invalid coverage path (%s): " "coverage name must be included in path.", pszCoverPath); CPLFree(psInfo->pszCoverPath); CPLFree(psInfo); return NULL; } if (strlen(psInfo->pszCoverName) > 13 || !_IsStringAlnum(psInfo->pszCoverName) ) { CPLError(CE_Failure, CPLE_OpenFailed, "Invalid coverage name (%s): " "coverage name must be 13 chars or less and contain only " "alphanumerical characters or '_'.", psInfo->pszCoverName); CPLFree(psInfo->pszCoverPath); CPLFree(psInfo->pszCoverName); CPLFree(psInfo); return NULL; } /*----------------------------------------------------------------- * Lazy way to build the INFO path: simply add "../info/"... * this could probably be improved! *----------------------------------------------------------------*/ psInfo->pszInfoPath = (char*)CPLMalloc((strlen(psInfo->pszCoverPath)+9)* sizeof(char)); #ifdef WIN32 # define AVC_INFOPATH "..\\info\\" #else # define AVC_INFOPATH "../info/" #endif sprintf(psInfo->pszInfoPath, "%s%s", psInfo->pszCoverPath, AVC_INFOPATH); /*----------------------------------------------------------------- * Check if the info directory exists and contains the "arc.dir" * if the info dir does not exist, then make sure we can create * the arc.dir file (i.e. try to create an empty one) * * Note: On Windows, this VSIStat() call seems to sometimes fail even * when the directory exists (buffering issue?), and the * following if() block is sometimes executed even if it * should not, but this should not cause problems since the * arc.dir is opened with "a+b" access. *----------------------------------------------------------------*/ if ( VSIStat(psInfo->pszInfoPath, &sStatBuf) == -1) { FILE *fp; char *pszArcDir; #ifdef WIN32 mkdir(psInfo->pszInfoPath); #else mkdir (psInfo->pszInfoPath, 0777); #endif pszArcDir = CPLStrdup(CPLSPrintf("%s%s", psInfo->pszInfoPath, "arc.dir")); fp = VSIFOpen(pszArcDir, "a+b"); CPLFree(pszArcDir); if (fp) { VSIFClose(fp); } else { CPLError(CE_Failure, CPLE_OpenFailed, "Unable to create (or write to) 'info' directory %s", psInfo->pszInfoPath); CPLFree(psInfo->pszCoverPath); CPLFree(psInfo->pszInfoPath); CPLFree(psInfo); return NULL; } } /*----------------------------------------------------------------- * Init the E00 parser. *----------------------------------------------------------------*/ psInfo->hParseInfo = AVCE00ParseInfoAlloc(); psInfo->eCurFileType = AVCFileUnknown; /*----------------------------------------------------------------- * If an error happened during the open call, cleanup and return NULL. *----------------------------------------------------------------*/ if (CPLGetLastErrorNo() != 0) { AVCE00WriteClose(psInfo); psInfo = NULL; } return psInfo; }
OGRErr OGRGeometryCollection::exportToWkt( char ** ppszDstText ) const { char **papszGeoms; int iGeom, nCumulativeLength = 0; OGRErr eErr; if( getNumGeometries() == 0 ) { *ppszDstText = CPLStrdup("GEOMETRYCOLLECTION EMPTY"); return OGRERR_NONE; } /* -------------------------------------------------------------------- */ /* Build a list of strings containing the stuff for each Geom. */ /* -------------------------------------------------------------------- */ papszGeoms = (char **) CPLCalloc(sizeof(char *),nGeomCount); for( iGeom = 0; iGeom < nGeomCount; iGeom++ ) { eErr = papoGeoms[iGeom]->exportToWkt( &(papszGeoms[iGeom]) ); if( eErr != OGRERR_NONE ) goto error; nCumulativeLength += strlen(papszGeoms[iGeom]); } /* -------------------------------------------------------------------- */ /* Allocate the right amount of space for the aggregated string */ /* -------------------------------------------------------------------- */ *ppszDstText = (char *) VSIMalloc(nCumulativeLength + nGeomCount + 23); if( *ppszDstText == NULL ) { eErr = OGRERR_NOT_ENOUGH_MEMORY; goto error; } /* -------------------------------------------------------------------- */ /* Build up the string, freeing temporary strings as we go. */ /* -------------------------------------------------------------------- */ strcpy( *ppszDstText, getGeometryName() ); strcat( *ppszDstText, " (" ); nCumulativeLength = strlen(*ppszDstText); for( iGeom = 0; iGeom < nGeomCount; iGeom++ ) { if( iGeom > 0 ) (*ppszDstText)[nCumulativeLength++] = ','; int nGeomLength = strlen(papszGeoms[iGeom]); memcpy( *ppszDstText + nCumulativeLength, papszGeoms[iGeom], nGeomLength ); nCumulativeLength += nGeomLength; VSIFree( papszGeoms[iGeom] ); } (*ppszDstText)[nCumulativeLength++] = ')'; (*ppszDstText)[nCumulativeLength] = '\0'; CPLFree( papszGeoms ); return OGRERR_NONE; error: for( iGeom = 0; iGeom < nGeomCount; iGeom++ ) CPLFree( papszGeoms[iGeom] ); CPLFree( papszGeoms ); return eErr; }
GIFAbstractRasterBand::GIFAbstractRasterBand( GIFAbstractDataset *poDSIn, int nBandIn, SavedImage *psSavedImage, int nBackground, int bAdvertizeInterlacedMDI ) : panInterlaceMap(NULL), poColorTable(NULL), nTransparentColor(0) { this->poDS = poDSIn; this->nBand = nBandIn; eDataType = GDT_Byte; nBlockXSize = poDS->GetRasterXSize(); nBlockYSize = 1; psImage = psSavedImage; if (psImage == NULL) return; /* -------------------------------------------------------------------- */ /* Setup interlacing map if required. */ /* -------------------------------------------------------------------- */ panInterlaceMap = NULL; if( psImage->ImageDesc.Interlace ) { int iLine = 0; if( bAdvertizeInterlacedMDI ) poDS->SetMetadataItem( "INTERLACED", "YES", "IMAGE_STRUCTURE" ); panInterlaceMap = (int *) CPLCalloc(poDSIn->nRasterYSize,sizeof(int)); for (int i = 0; i < 4; i++) { for (int j = InterlacedOffset[i]; j < poDSIn->nRasterYSize; j += InterlacedJumps[i]) panInterlaceMap[j] = iLine++; } } else if( bAdvertizeInterlacedMDI ) poDS->SetMetadataItem( "INTERLACED", "NO", "IMAGE_STRUCTURE" ); /* -------------------------------------------------------------------- */ /* Check for transparency. We just take the first graphic */ /* control extension block we find, if any. */ /* -------------------------------------------------------------------- */ nTransparentColor = -1; for( int iExtBlock = 0; iExtBlock < psImage->ExtensionBlockCount; iExtBlock++ ) { unsigned char *pExtData; if( psImage->ExtensionBlocks[iExtBlock].Function != 0xf9 || psImage->ExtensionBlocks[iExtBlock].ByteCount < 4 ) continue; pExtData = (unsigned char *) psImage->ExtensionBlocks[iExtBlock].Bytes; /* check if transparent color flag is set */ if( !(pExtData[0] & 0x1) ) continue; nTransparentColor = pExtData[3]; } /* -------------------------------------------------------------------- */ /* Setup colormap. */ /* -------------------------------------------------------------------- */ ColorMapObject *psGifCT = psImage->ImageDesc.ColorMap; if( psGifCT == NULL ) psGifCT = poDSIn->hGifFile->SColorMap; poColorTable = new GDALColorTable(); for( int iColor = 0; iColor < psGifCT->ColorCount; iColor++ ) { GDALColorEntry oEntry; oEntry.c1 = psGifCT->Colors[iColor].Red; oEntry.c2 = psGifCT->Colors[iColor].Green; oEntry.c3 = psGifCT->Colors[iColor].Blue; if( iColor == nTransparentColor ) oEntry.c4 = 0; else oEntry.c4 = 255; poColorTable->SetColorEntry( iColor, &oEntry ); } /* -------------------------------------------------------------------- */ /* If we have a background value, return it here. Some */ /* applications might want to treat this as transparent, but in */ /* many uses this is inappropriate so we don't return it as */ /* nodata or transparent. */ /* -------------------------------------------------------------------- */ if( nBackground != 255 ) { char szBackground[10]; snprintf( szBackground, sizeof(szBackground), "%d", nBackground ); SetMetadataItem( "GIF_BACKGROUND", szBackground ); } }
int SDTSTransfer::Open( const char * pszFilename ) { /* -------------------------------------------------------------------- */ /* Open the catalog. */ /* -------------------------------------------------------------------- */ if( !oCATD.Read( pszFilename ) ) return FALSE; /* -------------------------------------------------------------------- */ /* Read the IREF file. */ /* -------------------------------------------------------------------- */ if( oCATD.GetModuleFilePath( "IREF" ) == nullptr ) { CPLError( CE_Failure, CPLE_AppDefined, "Can't find IREF module in transfer `%s'.\n", pszFilename ); return FALSE; } if( !oIREF.Read( oCATD.GetModuleFilePath( "IREF" ) ) ) return FALSE; /* -------------------------------------------------------------------- */ /* Read the XREF file. */ /* -------------------------------------------------------------------- */ if( oCATD.GetModuleFilePath( "XREF" ) == nullptr ) { CPLError( CE_Warning, CPLE_AppDefined, "Can't find XREF module in transfer `%s'.\n", pszFilename ); } else if( !oXREF.Read( oCATD.GetModuleFilePath( "XREF" ) ) ) { CPLError( CE_Warning, CPLE_AppDefined, "Can't read XREF module, even though found in transfer `%s'.\n", pszFilename ); } /* -------------------------------------------------------------------- */ /* Build an index of layer types we recognise and care about. */ /* -------------------------------------------------------------------- */ panLayerCATDEntry = reinterpret_cast<int *>( CPLMalloc( sizeof(int) * oCATD.GetEntryCount() ) ); for( int iCATDLayer = 0; iCATDLayer < oCATD.GetEntryCount(); iCATDLayer++ ) { switch( oCATD.GetEntryType(iCATDLayer) ) { case SLTPoint: case SLTLine: case SLTAttr: case SLTPoly: case SLTRaster: panLayerCATDEntry[nLayers++] = iCATDLayer; break; default: /* ignore */ break; } } /* -------------------------------------------------------------------- */ /* Initialized the related indexed readers list. */ /* -------------------------------------------------------------------- */ papoLayerReader = reinterpret_cast<SDTSIndexedReader **>( CPLCalloc( sizeof(SDTSIndexedReader*), oCATD.GetEntryCount() ) ); return TRUE; }
/********************************************************************** * AVCRawBinOpen() * * Open a binary file for reading with buffering, or writing. * * Returns a valid AVCRawBinFile structure, or NULL if the file could * not be opened or created. * * AVCRawBinClose() will eventually have to be called to release the * resources used by the AVCRawBinFile structure. **********************************************************************/ AVCRawBinFile *AVCRawBinOpen(const char *pszFname, const char *pszAccess, AVCByteOrder eFileByteOrder, AVCDBCSInfo *psDBCSInfo) { AVCRawBinFile *psFile; psFile = (AVCRawBinFile*)CPLCalloc(1, sizeof(AVCRawBinFile)); /*----------------------------------------------------------------- * Validate access mode and open/create file. * For now we support only: "r" for read-only or "w" for write-only * or "a" for append. * * A case for "r+" is included here, but random access is not * properly supported yet... so this option should be used with care. *----------------------------------------------------------------*/ if (EQUALN(pszAccess, "r+", 2)) { psFile->eAccess = AVCReadWrite; psFile->fp = VSIFOpen(pszFname, "r+b"); } else if (EQUALN(pszAccess, "r", 1)) { psFile->eAccess = AVCRead; psFile->fp = VSIFOpen(pszFname, "rb"); } else if (EQUALN(pszAccess, "w", 1)) { psFile->eAccess = AVCWrite; psFile->fp = VSIFOpen(pszFname, "wb"); } else if (EQUALN(pszAccess, "a", 1)) { psFile->eAccess = AVCWrite; psFile->fp = VSIFOpen(pszFname, "ab"); } else { CPLError(CE_Failure, CPLE_IllegalArg, "Acces mode \"%s\" not supported.", pszAccess); CPLFree(psFile); return NULL; } /*----------------------------------------------------------------- * Check that file was opened succesfully, and init struct. *----------------------------------------------------------------*/ if (psFile->fp == NULL) { CPLError(CE_Failure, CPLE_OpenFailed, "Failed to open file %s", pszFname); CPLFree(psFile); return NULL; } /*----------------------------------------------------------------- * OK... Init psFile struct *----------------------------------------------------------------*/ psFile->pszFname = CPLStrdup(pszFname); psFile->eByteOrder = eFileByteOrder; psFile->psDBCSInfo = psDBCSInfo; /* Handle on dataset DBCS info */ /*----------------------------------------------------------------- * One can set nFileDataSize based on some header fields to force * EOF beyond a given point in the file. Useful for cases like * PC Arc/Info where the physical file size is always a multiple of * 256 bytes padded with some junk at the end. *----------------------------------------------------------------*/ psFile->nFileDataSize = -1; return psFile; }
void BAGDataset::LoadMetadata() { // Load the metadata from the file. const hid_t hMDDS = H5Dopen(hHDF5, "/BAG_root/metadata"); const hid_t datatype = H5Dget_type(hMDDS); const hid_t dataspace = H5Dget_space(hMDDS); const hid_t native = H5Tget_native_type(datatype, H5T_DIR_ASCEND); hsize_t dims[3] = { static_cast<hsize_t>(0), static_cast<hsize_t>(0), static_cast<hsize_t>(0) }; hsize_t maxdims[3] = { static_cast<hsize_t>(0), static_cast<hsize_t>(0), static_cast<hsize_t>(0) }; H5Sget_simple_extent_dims(dataspace, dims, maxdims); pszXMLMetadata = static_cast<char *>(CPLCalloc(static_cast<int>(dims[0] + 1), 1)); H5Dread(hMDDS, native, H5S_ALL, dataspace, H5P_DEFAULT, pszXMLMetadata); H5Tclose(native); H5Sclose(dataspace); H5Tclose(datatype); H5Dclose(hMDDS); if( strlen(pszXMLMetadata) == 0 ) return; // Try to get the geotransform. CPLXMLNode *psRoot = CPLParseXMLString(pszXMLMetadata); if( psRoot == nullptr ) return; CPLStripXMLNamespace(psRoot, nullptr, TRUE); CPLXMLNode *const psGeo = CPLSearchXMLNode(psRoot, "=MD_Georectified"); if( psGeo != nullptr ) { char **papszCornerTokens = CSLTokenizeStringComplex( CPLGetXMLValue(psGeo, "cornerPoints.Point.coordinates", ""), " ,", FALSE, FALSE); if( CSLCount(papszCornerTokens) == 4 ) { const double dfLLX = CPLAtof(papszCornerTokens[0]); const double dfLLY = CPLAtof(papszCornerTokens[1]); const double dfURX = CPLAtof(papszCornerTokens[2]); const double dfURY = CPLAtof(papszCornerTokens[3]); adfGeoTransform[0] = dfLLX; adfGeoTransform[1] = (dfURX - dfLLX) / (GetRasterXSize() - 1); adfGeoTransform[3] = dfURY; adfGeoTransform[5] = (dfLLY - dfURY) / (GetRasterYSize() - 1); adfGeoTransform[0] -= adfGeoTransform[1] * 0.5; adfGeoTransform[3] -= adfGeoTransform[5] * 0.5; } CSLDestroy(papszCornerTokens); } // Try to get the coordinate system. OGRSpatialReference oSRS; if( OGR_SRS_ImportFromISO19115(&oSRS, pszXMLMetadata) == OGRERR_NONE ) { oSRS.exportToWkt(&pszProjection); } else { ParseWKTFromXML(pszXMLMetadata); } // Fetch acquisition date. CPLXMLNode *const psDateTime = CPLSearchXMLNode(psRoot, "=dateTime"); if( psDateTime != nullptr ) { const char *pszDateTimeValue = CPLGetXMLValue(psDateTime, nullptr, ""); if( pszDateTimeValue ) SetMetadataItem("BAG_DATETIME", pszDateTimeValue); } CPLDestroyXMLNode(psRoot); }