/** * LoadMetadata() */ void GDALMDReaderResursDK1::LoadMetadata() { if(m_bIsMetadataLoad) return; if (!m_osXMLSourceFilename.empty()) { CPLXMLNode* psNode = CPLParseXMLFile(m_osXMLSourceFilename); if(psNode != NULL) { CPLXMLNode* pMSPRootNode = CPLSearchXMLNode(psNode, "=MSP_ROOT"); if(pMSPRootNode != NULL) { m_papszIMDMD = ReadXMLToList(pMSPRootNode, m_papszIMDMD, "MSP_ROOT"); } CPLDestroyXMLNode(psNode); } } m_papszDEFAULTMD = CSLAddNameValue(m_papszDEFAULTMD, MD_NAME_MDTYPE, "MSP"); m_bIsMetadataLoad = true; if(NULL == m_papszIMDMD) { return; } //extract imagery metadata const char* pszSatId = CSLFetchNameValue(m_papszIMDMD, "MSP_ROOT.cCodeKA"); if(NULL != pszSatId) { m_papszIMAGERYMD = CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_SATELLITE, CPLStripQuotes(pszSatId)); } const char* pszDate = CSLFetchNameValue(m_papszIMDMD, "MSP_ROOT.Normal.dSceneDate"); if(NULL != pszDate) { const char* pszTime = CSLFetchNameValue(m_papszIMDMD, "MSP_ROOT.Normal.tSceneTime"); if(NULL == pszTime) pszTime = "00:00:00.000000"; char buffer[80]; time_t timeMid = GetAcquisitionTimeFromString(CPLSPrintf( "%s %s", pszDate, pszTime)); strftime (buffer, 80, MD_DATETIMEFORMAT, localtime(&timeMid)); m_papszIMAGERYMD = CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_ACQDATETIME, buffer); } m_papszIMAGERYMD = CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_CLOUDCOVER, MD_CLOUDCOVER_NA); }
/** * LoadMetadata() */ void GDALMDReaderRapidEye::LoadMetadata() { if(m_bIsMetadataLoad) return; CPLXMLNode* psNode = CPLParseXMLFile(m_osXMLSourceFilename); if(psNode != NULL) { CPLXMLNode* pRootNode = CPLSearchXMLNode(psNode, "=re:EarthObservation"); if(pRootNode != NULL) { m_papszIMDMD = ReadXMLToList(pRootNode->psChild, m_papszIMDMD); } CPLDestroyXMLNode(psNode); } m_papszDEFAULTMD = CSLAddNameValue(m_papszDEFAULTMD, MD_NAME_MDTYPE, "RE"); m_bIsMetadataLoad = true; if(NULL == m_papszIMDMD) { return; } //extract imagery metadata const char* pszSatId = CSLFetchNameValue(m_papszIMDMD, "gml:using.eop:EarthObservationEquipment.eop:platform.eop:Platform.eop:serialIdentifier"); if(NULL != pszSatId) { m_papszIMAGERYMD = CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_SATELLITE, CPLStripQuotes(pszSatId)); } const char* pszDateTime = CSLFetchNameValue(m_papszIMDMD, "gml:using.eop:EarthObservationEquipment.eop:acquisitionParameters.re:Acquisition.re:acquisitionDateTime"); if(NULL != pszDateTime) { char buffer[80]; time_t timeMid = GetAcquisitionTimeFromString(pszDateTime); strftime (buffer, 80, MD_DATETIMEFORMAT, localtime(&timeMid)); m_papszIMAGERYMD = CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_ACQDATETIME, buffer); } const char* pszCC = CSLFetchNameValue(m_papszIMDMD, "gml:resultOf.re:EarthObservationResult.opt:cloudCoverPercentage"); if(NULL != pszSatId) { m_papszIMAGERYMD = CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_CLOUDCOVER, pszCC); } }
bool netCDFWriterConfiguration::Parse(const char *pszFilename) { CPLXMLNode *psRoot = STARTS_WITH(pszFilename, "<Configuration") ? CPLParseXMLString(pszFilename) : CPLParseXMLFile(pszFilename); if( psRoot == NULL ) return false; CPLXMLTreeCloser oCloser(psRoot); for( CPLXMLNode *psIter = psRoot->psChild; psIter != NULL; psIter = psIter->psNext ) { if( psIter->eType != CXT_Element ) continue; if( EQUAL(psIter->pszValue, "DatasetCreationOption") ) { SetNameValue(psIter, m_oDatasetCreationOptions); } else if( EQUAL(psIter->pszValue, "LayerCreationOption") ) { SetNameValue(psIter, m_oLayerCreationOptions); } else if( EQUAL(psIter->pszValue, "Attribute") ) { netCDFWriterConfigAttribute oAtt; if( oAtt.Parse(psIter) ) m_aoAttributes.push_back(oAtt); } else if( EQUAL(psIter->pszValue, "Field") ) { netCDFWriterConfigField oField; if( oField.Parse(psIter) ) m_oFields[!oField.m_osName.empty() ? oField.m_osName : CPLString("__") + oField.m_osNetCDFName] = oField; } else if( EQUAL(psIter->pszValue, "Layer") ) { netCDFWriterConfigLayer oLayer; if( oLayer.Parse(psIter) ) m_oLayers[oLayer.m_osName] = oLayer; } else { CPLDebug("GDAL_netCDF", "Ignoring %s", psIter->pszValue); } } m_bIsValid = true; return true; }
GDALDataset *ECRGTOCDataset::Open( GDALOpenInfo * poOpenInfo ) { const char *pszFilename = poOpenInfo->pszFilename; CPLString osProduct, osDiscId; if( !Identify( poOpenInfo ) ) return NULL; if( EQUALN(pszFilename, "ECRG_TOC_ENTRY:",strlen("ECRG_TOC_ENTRY:"))) { pszFilename += strlen("ECRG_TOC_ENTRY:"); osProduct = pszFilename; size_t iPos = osProduct.find(":"); if (iPos == std::string::npos) return NULL; osProduct.resize(iPos); pszFilename += iPos + 1; osDiscId = pszFilename; iPos = osDiscId.find(":"); if (iPos == std::string::npos) return NULL; osDiscId.resize(iPos); pszFilename += iPos + 1; } /* -------------------------------------------------------------------- */ /* Parse the XML file */ /* -------------------------------------------------------------------- */ CPLXMLNode* psXML = CPLParseXMLFile(pszFilename); if (psXML == NULL) { return NULL; } GDALDataset* poDS = Build( pszFilename, psXML, osProduct, osDiscId, poOpenInfo->pszFilename); CPLDestroyXMLNode(psXML); if (poDS && poOpenInfo->eAccess == GA_Update) { CPLError(CE_Failure, CPLE_NotSupported, "ECRGTOC driver does not support update mode"); delete poDS; return NULL; } return poDS; }
CPLErr GDALWMSRasterBand::ReportWMSException(const char *file_name) { CPLErr ret = CE_None; int reported_errors_count = 0; CPLXMLNode *orig_root = CPLParseXMLFile(file_name); CPLXMLNode *root = orig_root; if (root != NULL) { root = CPLGetXMLNode(root, "=ServiceExceptionReport"); } if (root != NULL) { CPLXMLNode *n = CPLGetXMLNode(root, "ServiceException"); while (n != NULL) { const char *exception = CPLGetXMLValue(n, "=ServiceException", ""); const char *exception_code = CPLGetXMLValue(n, "=ServiceException.code", ""); if (exception[0] != '\0') { if (exception_code[0] != '\0') { CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: The server returned exception code '%s': %s", exception_code, exception); ++reported_errors_count; } else { CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: The server returned exception: %s", exception); ++reported_errors_count; } } else if (exception_code[0] != '\0') { CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS: The server returned exception code '%s'.", exception_code); ++reported_errors_count; } n = n->psNext; if (n != NULL) { n = CPLGetXMLNode(n, "=ServiceException"); } } } else { ret = CE_Failure; } if (orig_root != NULL) { CPLDestroyXMLNode(orig_root); } if (reported_errors_count == 0) { ret = CE_Failure; } return ret; }
static CPLXMLNode* GMLParseXMLFile(const char* pszFilename) { if( STARTS_WITH(pszFilename, "http://") || STARTS_WITH(pszFilename, "https://") ) { CPLXMLNode* psRet = NULL; CPLHTTPResult* psResult = CPLHTTPFetch( pszFilename, NULL ); if( psResult != NULL ) { if( psResult->pabyData != NULL ) { psRet = CPLParseXMLString( (const char*) psResult->pabyData ); } CPLHTTPDestroyResult(psResult); } return psRet; } else { return CPLParseXMLFile(pszFilename); } }
bool GMLRegistry::Parse() { if( osRegistryPath.empty() ) { const char *pszFilename = CPLFindFile("gdal", "gml_registry.xml"); if( pszFilename ) osRegistryPath = pszFilename; } if( osRegistryPath.empty() ) return false; CPLXMLNode *psRootNode = CPLParseXMLFile(osRegistryPath); if( psRootNode == NULL ) return false; CPLXMLNode *psRegistryNode = CPLGetXMLNode(psRootNode, "=gml_registry"); if( psRegistryNode == NULL ) { CPLDestroyXMLNode(psRootNode); return false; } CPLXMLNode *psIter = psRegistryNode->psChild; while( psIter != NULL ) { if( psIter->eType == CXT_Element && strcmp(psIter->pszValue, "namespace") == 0 ) { GMLRegistryNamespace oNameSpace; if( oNameSpace.Parse(osRegistryPath, psIter) ) { aoNamespaces.push_back(oNameSpace); } } psIter = psIter->psNext; } CPLDestroyXMLNode(psRootNode); return true; }
VSIVirtualHandle * VSISparseFileFilesystemHandler::Open( const char *pszFilename, const char *pszAccess ) { CPLAssert( EQUALN(pszFilename,"/vsisparse/", 11) ); if( !EQUAL(pszAccess,"r") && !EQUAL(pszAccess,"rb") ) { errno = EACCES; return NULL; } /* Arbitrary number */ if( GetRecCounter() == 32 ) return NULL; CPLString osSparseFilePath = pszFilename + 11; /* -------------------------------------------------------------------- */ /* Does this file even exist? */ /* -------------------------------------------------------------------- */ VSILFILE *fp = VSIFOpenL( osSparseFilePath, "r" ); if( fp == NULL ) return NULL; VSIFCloseL( fp ); /* -------------------------------------------------------------------- */ /* Read the XML file. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psXMLRoot = CPLParseXMLFile( osSparseFilePath ); if( psXMLRoot == NULL ) return NULL; /* -------------------------------------------------------------------- */ /* Setup the file handle on this file. */ /* -------------------------------------------------------------------- */ VSISparseFileHandle *poHandle = new VSISparseFileHandle(this); /* -------------------------------------------------------------------- */ /* Translate the desired fields out of the XML tree. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psRegion; for( psRegion = psXMLRoot->psChild; psRegion != NULL; psRegion = psRegion->psNext ) { if( psRegion->eType != CXT_Element ) continue; if( !EQUAL(psRegion->pszValue,"SubfileRegion") && !EQUAL(psRegion->pszValue,"ConstantRegion") ) continue; SFRegion oRegion; oRegion.osFilename = CPLGetXMLValue( psRegion, "Filename", "" ); if( atoi(CPLGetXMLValue( psRegion, "Filename.relative", "0" )) != 0 ) { CPLString osSFPath = CPLGetPath(osSparseFilePath); oRegion.osFilename = CPLFormFilename( osSFPath, oRegion.osFilename, NULL ); } oRegion.nDstOffset = CPLScanUIntBig( CPLGetXMLValue(psRegion,"DestinationOffset","0" ), 32 ); oRegion.nSrcOffset = CPLScanUIntBig( CPLGetXMLValue(psRegion,"SourceOffset","0" ), 32); oRegion.nLength = CPLScanUIntBig( CPLGetXMLValue(psRegion,"RegionLength","0" ), 32); oRegion.byValue = (GByte) atoi(CPLGetXMLValue(psRegion,"Value","0" )); poHandle->aoRegions.push_back( oRegion ); } /* -------------------------------------------------------------------- */ /* Get sparse file length, use maximum bound of regions if not */ /* explicit in file. */ /* -------------------------------------------------------------------- */ poHandle->nOverallLength = CPLScanUIntBig( CPLGetXMLValue(psXMLRoot,"Length","0" ), 32); if( poHandle->nOverallLength == 0 ) { for( unsigned int i = 0; i < poHandle->aoRegions.size(); i++ ) { poHandle->nOverallLength = MAX(poHandle->nOverallLength, poHandle->aoRegions[i].nDstOffset + poHandle->aoRegions[i].nLength); } } CPLDestroyXMLNode( psXMLRoot ); return poHandle; }
static CPLXMLNode* CPLLoadSchemaStrInternal(CPLHashSet* hSetSchemas, const char* pszFile) { if (CPLHashSetLookup(hSetSchemas, pszFile)) return NULL; CPLHashSetInsert(hSetSchemas, CPLStrdup(pszFile)); CPLDebug("CPL", "Parsing %s", pszFile); CPLXMLNode* psXML = CPLParseXMLFile(pszFile); if (psXML == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot open %s", pszFile); return NULL; } CPLXMLNode* psSchema = CPLGetXMLNode(psXML, "=schema"); if (psSchema == NULL) psSchema = CPLGetXMLNode(psXML, "=xs:schema"); if (psSchema == NULL) psSchema = CPLGetXMLNode(psXML, "=xsd:schema"); if (psSchema == NULL) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot find schema node in %s", pszFile); CPLDestroyXMLNode(psXML); return NULL; } CPLXMLNode* psPrev = NULL; CPLXMLNode* psIter = psSchema->psChild; while(psIter) { bool bDestroyCurrentNode = false; #ifdef HAS_VALIDATION_BUG if (bHasLibXMLBug) bDestroyCurrentNode = CPLWorkaroundLibXMLBug(psIter); #endif /* Load the referenced schemas, and integrate them in the main schema */ if (psIter->eType == CXT_Element && (strcmp(psIter->pszValue, "include") == 0 || strcmp(psIter->pszValue, "xs:include") == 0|| strcmp(psIter->pszValue, "xsd:include") == 0) && psIter->psChild != NULL && psIter->psChild->eType == CXT_Attribute && strcmp(psIter->psChild->pszValue, "schemaLocation") == 0) { const char* pszIncludeSchema = psIter->psChild->psChild->pszValue; char* pszFullFilename = CPLStrdup( CPLFormFilename(CPLGetPath(pszFile), pszIncludeSchema, NULL)); CPLFixPath(pszFullFilename); CPLXMLNode* psSubXML = NULL; /* If we haven't yet loaded that schema, do it now */ if (!CPLHashSetLookup(hSetSchemas, pszFullFilename)) { psSubXML = CPLLoadSchemaStrInternal(hSetSchemas, pszFullFilename); if (psSubXML == NULL) { CPLFree(pszFullFilename); CPLDestroyXMLNode(psXML); return NULL; } } CPLFree(pszFullFilename); pszFullFilename = NULL; if (psSubXML) { CPLXMLNode* psNext = psIter->psNext; psSubXML = CPLExtractSubSchema(psSubXML, psSchema); if (psSubXML == NULL) { CPLDestroyXMLNode(psXML); return NULL; } /* Replace <include/> node by the subXML */ CPLXMLNode* psIter2 = psSubXML; while(psIter2->psNext) psIter2 = psIter2->psNext; psIter2->psNext = psNext; if (psPrev == NULL) psSchema->psChild = psSubXML; else psPrev->psNext = psSubXML; psIter->psNext = NULL; CPLDestroyXMLNode(psIter); psPrev = psIter2; psIter = psNext; continue; } else { /* We have already included that file, */ /* so just remove the <include/> node */ bDestroyCurrentNode = true; } } /* Patch the schemaLocation of <import/> */ else if (psIter->eType == CXT_Element && (strcmp(psIter->pszValue, "import") == 0 || strcmp(psIter->pszValue, "xs:import") == 0|| strcmp(psIter->pszValue, "xsd:import") == 0)) { CPLXMLNode* psIter2 = psIter->psChild; while(psIter2) { if (psIter2->eType == CXT_Attribute && strcmp(psIter2->pszValue, "schemaLocation") == 0 && psIter2->psChild != NULL && !STARTS_WITH(psIter2->psChild->pszValue, "http://") && !STARTS_WITH(psIter2->psChild->pszValue, "ftp://") && /* If the top file is our warping file, don't alter the path of the import */ strstr(pszFile, "/vsimem/CPLValidateXML_") == NULL ) { char* pszFullFilename = CPLStrdup(CPLFormFilename( CPLGetPath(pszFile), psIter2->psChild->pszValue, NULL)); CPLFixPath(pszFullFilename); CPLFree(psIter2->psChild->pszValue); psIter2->psChild->pszValue = pszFullFilename; } psIter2 = psIter2->psNext; } } if (bDestroyCurrentNode) { CPLXMLNode* psNext = psIter->psNext; if (psPrev == NULL) psSchema->psChild = psNext; else psPrev->psNext = psNext; psIter->psNext = NULL; CPLDestroyXMLNode(psIter); psIter = psNext; continue; } psPrev = psIter; psIter = psIter->psNext; } return psXML; }
GDALDataset *DIMAPDataset::Open( GDALOpenInfo * poOpenInfo ) { if( !Identify( poOpenInfo ) ) return NULL; /* -------------------------------------------------------------------- */ /* Confirm the requested access is supported. */ /* -------------------------------------------------------------------- */ if( poOpenInfo->eAccess == GA_Update ) { CPLError( CE_Failure, CPLE_NotSupported, "The DIMAP driver does not support update access to existing" " datasets.\n" ); return NULL; } /* -------------------------------------------------------------------- */ /* Get the metadata filename. */ /* -------------------------------------------------------------------- */ CPLString osMDFilename; if( poOpenInfo->bIsDirectory ) { osMDFilename = CPLFormCIFilename( poOpenInfo->pszFilename, "METADATA.DIM", NULL ); } else osMDFilename = poOpenInfo->pszFilename; /* -------------------------------------------------------------------- */ /* Ingest the xml file. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psProduct, *psImageAttributes; psProduct = CPLParseXMLFile( osMDFilename ); if( psProduct == NULL ) return NULL; CPLXMLNode *psDoc = CPLGetXMLNode( psProduct, "=Dimap_Document" ); psImageAttributes = CPLGetXMLNode( psDoc, "Raster_Dimensions" ); if( psImageAttributes == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Failed to find <Raster_Dimensions> in document." ); return NULL; } /* -------------------------------------------------------------------- */ /* Create the dataset. */ /* -------------------------------------------------------------------- */ DIMAPDataset *poDS = new DIMAPDataset(); poDS->psProduct = psProduct; /* -------------------------------------------------------------------- */ /* Get overall image information. */ /* -------------------------------------------------------------------- */ #ifdef DEBUG int nBands = atoi(CPLGetXMLValue( psImageAttributes, "NBANDS", "-1" )); #endif poDS->nRasterXSize = atoi(CPLGetXMLValue( psImageAttributes, "NCOLS", "-1" )); poDS->nRasterYSize = atoi(CPLGetXMLValue( psImageAttributes, "NROWS", "-1" )); /* -------------------------------------------------------------------- */ /* Get the name of the underlying file. */ /* -------------------------------------------------------------------- */ const char *pszHref = CPLGetXMLValue( psDoc, "Data_Access.Data_File.DATA_FILE_PATH.href", "" ); CPLString osPath = CPLGetPath(osMDFilename); CPLString osImageFilename = CPLFormFilename( osPath, pszHref, NULL ); /* -------------------------------------------------------------------- */ /* Try and open the file. */ /* -------------------------------------------------------------------- */ poDS->poImageDS = (GDALDataset *) GDALOpen( osImageFilename, GA_ReadOnly ); if( poDS->poImageDS == NULL ) { delete poDS; return NULL; } /* -------------------------------------------------------------------- */ /* Attach the bands. */ /* -------------------------------------------------------------------- */ int iBand; CPLAssert( nBands == poDS->poImageDS->GetRasterCount() ); for( iBand = 1; iBand <= poDS->poImageDS->GetRasterCount(); iBand++ ) poDS->SetBand( iBand, poDS->poImageDS->GetRasterBand( iBand ) ); /* -------------------------------------------------------------------- */ /* Try to collect simple insertion point. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psGeoLoc = CPLGetXMLNode( psDoc, "Geoposition.Geoposition_Insert" ); if( psGeoLoc != NULL ) { poDS->bHaveGeoTransform = TRUE; poDS->adfGeoTransform[0] = atof(CPLGetXMLValue(psGeoLoc,"ULXMAP","0")); poDS->adfGeoTransform[1] = atof(CPLGetXMLValue(psGeoLoc,"XDIM","0")); poDS->adfGeoTransform[2] = 0.0; poDS->adfGeoTransform[3] = atof(CPLGetXMLValue(psGeoLoc,"ULYMAP","0")); poDS->adfGeoTransform[4] = 0.0; poDS->adfGeoTransform[5] = -atof(CPLGetXMLValue(psGeoLoc,"YDIM","0")); } /* -------------------------------------------------------------------- */ /* Collect GCPs. */ /* -------------------------------------------------------------------- */ psGeoLoc = CPLGetXMLNode( psDoc, "Geoposition.Geoposition_Points" ); if( psGeoLoc != NULL ) { CPLXMLNode *psNode; // count gcps. poDS->nGCPCount = 0; for( psNode = psGeoLoc->psChild; psNode != NULL; psNode = psNode->psNext ) { if( EQUAL(psNode->pszValue,"Tie_Point") ) poDS->nGCPCount++ ; } poDS->pasGCPList = (GDAL_GCP *) CPLCalloc(sizeof(GDAL_GCP),poDS->nGCPCount); poDS->nGCPCount = 0; for( psNode = psGeoLoc->psChild; psNode != NULL; psNode = psNode->psNext ) { char szID[32]; GDAL_GCP *psGCP = poDS->pasGCPList + poDS->nGCPCount; if( !EQUAL(psNode->pszValue,"Tie_Point") ) continue; poDS->nGCPCount++ ; sprintf( szID, "%d", poDS->nGCPCount ); psGCP->pszId = CPLStrdup( szID ); psGCP->pszInfo = CPLStrdup(""); psGCP->dfGCPPixel = atof(CPLGetXMLValue(psNode,"TIE_POINT_DATA_X","0"))-0.5; psGCP->dfGCPLine = atof(CPLGetXMLValue(psNode,"TIE_POINT_DATA_Y","0"))-0.5; psGCP->dfGCPX = atof(CPLGetXMLValue(psNode,"TIE_POINT_CRS_X","")); psGCP->dfGCPY = atof(CPLGetXMLValue(psNode,"TIE_POINT_CRS_Y","")); psGCP->dfGCPZ = atof(CPLGetXMLValue(psNode,"TIE_POINT_CRS_Z","")); } } /* -------------------------------------------------------------------- */ /* Collect the CRS. For now we look only for EPSG codes. */ /* -------------------------------------------------------------------- */ const char *pszSRS = CPLGetXMLValue( psDoc, "Coordinate_Reference_System.Horizontal_CS.HORIZONTAL_CS_CODE", NULL ); if( pszSRS != NULL ) { OGRSpatialReference oSRS; if( oSRS.SetFromUserInput( pszSRS ) == OGRERR_NONE ) { if( poDS->nGCPCount > 0 ) { CPLFree(poDS->pszGCPProjection); oSRS.exportToWkt( &(poDS->pszGCPProjection) ); } else { char *pszProjection = NULL; oSRS.exportToWkt( &pszProjection ); poDS->osProjection = pszProjection; CPLFree( pszProjection ); } } } /* -------------------------------------------------------------------- */ /* Translate other metadata of interest. */ /* -------------------------------------------------------------------- */ static const char *apszMetadataTranslation[] = { "Production", "", "Production.Facility", "FACILITY_", "Dataset_Sources.Source_Information.Scene_Source", "", "Data_Processing", "", "Image_Interpretation.Spectral_Band_Info", "SPECTRAL_", NULL, NULL }; int iTrItem; for( iTrItem = 0; apszMetadataTranslation[iTrItem] != NULL; iTrItem += 2 ) { CPLXMLNode *psParent = CPLGetXMLNode( psDoc, apszMetadataTranslation[iTrItem] ); if( psParent == NULL ) continue; // hackey logic to support directly access a name/value entry // or a parent element with many name/values. CPLXMLNode *psTarget; if( psParent->psChild != NULL && psParent->psChild->eType == CXT_Text ) psTarget = psParent; else psTarget = psParent->psChild; for( ; psTarget != NULL && psTarget != psParent; psTarget = psTarget->psNext ) { if( psTarget->eType == CXT_Element && psTarget->psChild != NULL && psTarget->psChild->eType == CXT_Text ) { CPLString osName = apszMetadataTranslation[iTrItem+1]; osName += psTarget->pszValue; poDS->SetMetadataItem( osName, psTarget->psChild->pszValue ); } } } /* -------------------------------------------------------------------- */ /* Set Band metadata from the <Spectral_Band_Info> content */ /* -------------------------------------------------------------------- */ CPLXMLNode *psImageInterpretationNode = CPLGetXMLNode( psDoc, "Image_Interpretation" ); if (psImageInterpretationNode != NULL) { CPLXMLNode *psSpectralBandInfoNode = psImageInterpretationNode->psChild; while (psSpectralBandInfoNode != NULL) { if (psSpectralBandInfoNode->eType == CXT_Element && EQUAL(psSpectralBandInfoNode->pszValue, "Spectral_Band_Info")) { CPLXMLNode *psTag = psSpectralBandInfoNode->psChild; int nBandIndex = 0; while(psTag != NULL) { if (psTag->eType == CXT_Element && psTag->psChild != NULL && psTag->psChild->eType == CXT_Text && psTag->pszValue != NULL) { if (EQUAL(psTag->pszValue, "BAND_INDEX")) { nBandIndex = atoi(psTag->psChild->pszValue); if (nBandIndex <= 0 || nBandIndex > poDS->poImageDS->GetRasterCount()) { CPLError(CE_Warning, CPLE_AppDefined, "Bad BAND_INDEX value : %s", psTag->psChild->pszValue); nBandIndex = 0; } } else if (nBandIndex >= 1) { poDS->GetRasterBand(nBandIndex)->SetMetadataItem( psTag->pszValue, psTag->psChild->pszValue); } } psTag = psTag->psNext; } } psSpectralBandInfoNode = psSpectralBandInfoNode->psNext; } } /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->SetDescription( osMDFilename ); poDS->TryLoadXML(); /* -------------------------------------------------------------------- */ /* Check for overviews. */ /* -------------------------------------------------------------------- */ poDS->oOvManager.Initialize( poDS, osMDFilename ); return( poDS ); }
int main(int nArgc, char* papszArgv[]) { const char *pszFilename = NULL, *pszOutFilename = NULL; DDFModule oModule; /* -------------------------------------------------------------------- */ /* Check arguments. */ /* -------------------------------------------------------------------- */ for( int iArg = 1; iArg < nArgc; iArg++ ) { if( pszFilename == NULL ) pszFilename = papszArgv[iArg]; else if( pszOutFilename == NULL ) pszOutFilename = papszArgv[iArg]; else { pszFilename = NULL; break; } } if( pszFilename == NULL ) { printf( "Usage: 8211createfromxml filename.xml outfilename\n" ); exit( 1 ); } CPLXMLNode* poRoot = CPLParseXMLFile( pszFilename ); if( poRoot == NULL ) { fprintf(stderr, "Cannot parse XML file '%s'\n", pszFilename); exit( 1 ); } CPLXMLNode* poXMLDDFModule = CPLSearchXMLNode(poRoot, "=DDFModule"); if( poXMLDDFModule == NULL ) { fprintf(stderr, "Cannot find DDFModule node in XML file '%s'\n", pszFilename); exit( 1 ); } /* Compute the size of the DDFField tag */ CPLXMLNode* psIter = poXMLDDFModule->psChild; int nSizeFieldTag = 0; while( psIter != NULL ) { if( psIter->eType == CXT_Element && strcmp(psIter->pszValue, "DDFFieldDefn") == 0 ) { const char* pszTag = CPLGetXMLValue(psIter, "tag", ""); if( nSizeFieldTag == 0 ) nSizeFieldTag = (int)strlen(pszTag); else if( nSizeFieldTag != (int)strlen(pszTag) ) { fprintf(stderr, "All fields have not the same tag size\n"); exit( 1 ); } } psIter = psIter->psNext; } char chInterchangeLevel = '3'; char chLeaderIden = 'L'; char chCodeExtensionIndicator = 'E'; char chVersionNumber = '1'; char chAppIndicator = ' '; const char *pszExtendedCharSet = " ! "; int nSizeFieldLength = 3; int nSizeFieldPos = 4; chInterchangeLevel = CPLGetXMLValue(poXMLDDFModule, "_interchangeLevel", CPLSPrintf("%c", chInterchangeLevel))[0]; chLeaderIden = CPLGetXMLValue(poXMLDDFModule, "_leaderIden", CPLSPrintf("%c", chLeaderIden))[0]; chCodeExtensionIndicator = CPLGetXMLValue(poXMLDDFModule, "_inlineCodeExtensionIndicator", CPLSPrintf("%c", chCodeExtensionIndicator))[0]; chVersionNumber = CPLGetXMLValue(poXMLDDFModule, "_versionNumber", CPLSPrintf("%c", chVersionNumber))[0]; chAppIndicator = CPLGetXMLValue(poXMLDDFModule, "_appIndicator", CPLSPrintf("%c", chAppIndicator))[0]; char szExtendedCharSet[4]; snprintf(szExtendedCharSet, sizeof(szExtendedCharSet), "%s", CPLGetXMLValue(poXMLDDFModule, "_extendedCharSet", pszExtendedCharSet)); pszExtendedCharSet = szExtendedCharSet; nSizeFieldLength = atoi(CPLGetXMLValue(poXMLDDFModule, "_sizeFieldLength", CPLSPrintf("%d", nSizeFieldLength))); nSizeFieldPos = atoi(CPLGetXMLValue(poXMLDDFModule, "_sizeFieldPos", CPLSPrintf("%d", nSizeFieldPos))); nSizeFieldTag = atoi(CPLGetXMLValue(poXMLDDFModule, "_sizeFieldTag", CPLSPrintf("%d", nSizeFieldTag))); oModule.Initialize(chInterchangeLevel, chLeaderIden, chCodeExtensionIndicator, chVersionNumber, chAppIndicator, pszExtendedCharSet, nSizeFieldLength, nSizeFieldPos, nSizeFieldTag); oModule.SetFieldControlLength(atoi(CPLGetXMLValue(poXMLDDFModule, "_fieldControlLength", CPLSPrintf("%d", oModule.GetFieldControlLength())))); int bCreated = FALSE; /* Create DDFFieldDefn and DDFRecord elements */ psIter = poXMLDDFModule->psChild; while( psIter != NULL ) { if( psIter->eType == CXT_Element && strcmp(psIter->pszValue, "DDFFieldDefn") == 0 ) { DDFFieldDefn* poFDefn = new DDFFieldDefn(); DDF_data_struct_code eStructCode = dsc_elementary; const char* pszStructCode = CPLGetXMLValue(psIter, "dataStructCode", ""); if( strcmp(pszStructCode, "elementary") == 0 ) eStructCode = dsc_elementary; else if( strcmp(pszStructCode, "vector") == 0 ) eStructCode = dsc_vector; else if( strcmp(pszStructCode, "array") == 0 ) eStructCode = dsc_array; else if( strcmp(pszStructCode, "concatenated") == 0 ) eStructCode = dsc_concatenated; DDF_data_type_code eTypeCode = dtc_char_string; const char* pszTypeCode = CPLGetXMLValue(psIter, "dataTypeCode", ""); if( strcmp(pszTypeCode, "char_string") == 0 ) eTypeCode = dtc_char_string; else if( strcmp(pszTypeCode, "implicit_point") == 0 ) eTypeCode = dtc_implicit_point; else if( strcmp(pszTypeCode, "explicit_point") == 0 ) eTypeCode = dtc_explicit_point; else if( strcmp(pszTypeCode, "explicit_point_scaled") == 0 ) eTypeCode = dtc_explicit_point_scaled; else if( strcmp(pszTypeCode, "char_bit_string") == 0 ) eTypeCode = dtc_char_bit_string; else if( strcmp(pszTypeCode, "bit_string") == 0 ) eTypeCode = dtc_bit_string; else if( strcmp(pszTypeCode, "mixed_data_type") == 0 ) eTypeCode = dtc_mixed_data_type; const char* pszFormatControls = CPLGetXMLValue(psIter, "formatControls", NULL); if( eStructCode != dsc_elementary ) pszFormatControls = NULL; const char* pszArrayDescr = CPLGetXMLValue(psIter, "arrayDescr", ""); if( eStructCode == dsc_vector ) pszArrayDescr = ""; else if( eStructCode == dsc_array ) pszArrayDescr = "*"; poFDefn->Create( CPLGetXMLValue(psIter, "tag", ""), CPLGetXMLValue(psIter, "fieldName", ""), pszArrayDescr, eStructCode, eTypeCode, pszFormatControls ); CPLXMLNode* psSubIter = psIter->psChild; while( psSubIter != NULL ) { if( psSubIter->eType == CXT_Element && strcmp(psSubIter->pszValue, "DDFSubfieldDefn") == 0 ) { poFDefn->AddSubfield( CPLGetXMLValue(psSubIter, "name", ""), CPLGetXMLValue(psSubIter, "format", "") ); } psSubIter = psSubIter->psNext; } pszFormatControls = CPLGetXMLValue(psIter, "formatControls", NULL); if( pszFormatControls ) poFDefn->SetFormatControls(pszFormatControls); oModule.AddField( poFDefn ); } else if( psIter->eType == CXT_Element && strcmp(psIter->pszValue, "DDFRecord") == 0 ) { //const bool bFirstRecord = !bCreated; if( !bCreated ) { oModule.Create( pszOutFilename ); bCreated = TRUE; } DDFRecord *poRec = new DDFRecord( &oModule ); std::map<std::string, int> oMapField; //if( !bFirstRecord ) // poRec->SetReuseHeader(atoi(CPLGetXMLValue(psIter, "reuseHeader", CPLSPrintf("%d", poRec->GetReuseHeader())))); poRec->SetSizeFieldLength(atoi(CPLGetXMLValue(psIter, "_sizeFieldLength", CPLSPrintf("%d", poRec->GetSizeFieldLength())))); poRec->SetSizeFieldPos(atoi(CPLGetXMLValue(psIter, "_sizeFieldPos", CPLSPrintf("%d", poRec->GetSizeFieldPos())))); poRec->SetSizeFieldTag(atoi(CPLGetXMLValue(psIter, "_sizeFieldTag", CPLSPrintf("%d", poRec->GetSizeFieldTag())))); CPLXMLNode* psSubIter = psIter->psChild; while( psSubIter != NULL ) { if( psSubIter->eType == CXT_Element && strcmp(psSubIter->pszValue, "DDFField") == 0 ) { const char* pszFieldName = CPLGetXMLValue(psSubIter, "name", ""); DDFFieldDefn* poFieldDefn = oModule.FindFieldDefn( pszFieldName ); if( poFieldDefn == NULL ) { fprintf(stderr, "Can't find field '%s'\n", pszFieldName ); exit(1); } int nFieldOcc = oMapField[pszFieldName]; oMapField[pszFieldName] ++ ; DDFField *poField = poRec->AddField( poFieldDefn ); const char* pszValue = CPLGetXMLValue(psSubIter, "value", NULL); if( pszValue != NULL && STARTS_WITH(pszValue, "0x") ) { pszValue += 2; int nDataLen = (int)strlen(pszValue) / 2; char* pabyData = (char*) malloc(nDataLen); for(int i=0;i<nDataLen;i++) { char c; int nHigh, nLow; c = pszValue[2*i]; if( c >= 'A' && c <= 'F' ) nHigh = 10 + c - 'A'; else nHigh = c - '0'; c = pszValue[2*i + 1]; if( c >= 'A' && c <= 'F' ) nLow = 10 + c - 'A'; else nLow = c - '0'; pabyData[i] = (nHigh << 4) + nLow; } poRec->SetFieldRaw( poField, nFieldOcc, (const char *) pabyData, nDataLen ); free(pabyData); } else { CPLXMLNode* psSubfieldIter = psSubIter->psChild; std::map<std::string, int> oMapSubfield; while( psSubfieldIter != NULL ) { if( psSubfieldIter->eType == CXT_Element && strcmp(psSubfieldIter->pszValue, "DDFSubfield") == 0 ) { const char* pszSubfieldName = CPLGetXMLValue(psSubfieldIter, "name", ""); const char* pszSubfieldType = CPLGetXMLValue(psSubfieldIter, "type", ""); const char* pszSubfieldValue = CPLGetXMLValue(psSubfieldIter, NULL, ""); int nOcc = oMapSubfield[pszSubfieldName]; oMapSubfield[pszSubfieldName] ++ ; if( strcmp(pszSubfieldType, "float") == 0 ) { poRec->SetFloatSubfield( pszFieldName, nFieldOcc, pszSubfieldName, nOcc, CPLAtof(pszSubfieldValue) ); } else if( strcmp(pszSubfieldType, "integer") == 0 ) { poRec->SetIntSubfield( pszFieldName, nFieldOcc, pszSubfieldName, nOcc, atoi(pszSubfieldValue) ); } else if( strcmp(pszSubfieldType, "string") == 0 ) { poRec->SetStringSubfield( pszFieldName, nFieldOcc, pszSubfieldName, nOcc, pszSubfieldValue ); } else if( strcmp(pszSubfieldType, "binary") == 0 && STARTS_WITH(pszSubfieldValue, "0x") ) { pszSubfieldValue += 2; int nDataLen = (int)strlen(pszSubfieldValue) / 2; char* pabyData = (char*) malloc(nDataLen); for(int i=0;i<nDataLen;i++) { char c; int nHigh, nLow; c = pszSubfieldValue[2*i]; if( c >= 'A' && c <= 'F' ) nHigh = 10 + c - 'A'; else nHigh = c - '0'; c = pszSubfieldValue[2*i + 1]; if( c >= 'A' && c <= 'F' ) nLow = 10 + c - 'A'; else nLow = c - '0'; pabyData[i] = (nHigh << 4) + nLow; } poRec->SetStringSubfield( pszFieldName, nFieldOcc, pszSubfieldName, nOcc, pabyData, nDataLen ); free(pabyData); } } psSubfieldIter = psSubfieldIter->psNext; } } } psSubIter = psSubIter->psNext; } poRec->Write(); delete poRec; } psIter = psIter->psNext; } CPLDestroyXMLNode(poRoot); oModule.Close(); return 0; }
GDALDataset *TSXDataset::Open( GDALOpenInfo *poOpenInfo ) { /* -------------------------------------------------------------------- */ /* Is this a TerraSAR-X product file? */ /* -------------------------------------------------------------------- */ if (!TSXDataset::Identify( poOpenInfo )) { return NULL; /* nope */ } /* -------------------------------------------------------------------- */ /* Confirm the requested access is supported. */ /* -------------------------------------------------------------------- */ if( poOpenInfo->eAccess == GA_Update ) { CPLError( CE_Failure, CPLE_NotSupported, "The TSX driver does not support update access to existing" " datasets.\n" ); return NULL; } CPLString osFilename; if( poOpenInfo->bIsDirectory ) { osFilename = CPLFormCIFilename( poOpenInfo->pszFilename, CPLGetFilename( poOpenInfo->pszFilename ), "xml" ); } else osFilename = poOpenInfo->pszFilename; /* Ingest the XML */ CPLXMLNode *psData = CPLParseXMLFile( osFilename ); if (psData == NULL) return NULL; /* find the product components */ CPLXMLNode *psComponents = CPLGetXMLNode( psData, "=level1Product.productComponents" ); if (psComponents == NULL) { CPLError( CE_Failure, CPLE_OpenFailed, "Unable to find <productComponents> tag in file.\n" ); CPLDestroyXMLNode(psData); return NULL; } /* find the product info tag */ CPLXMLNode *psProductInfo = CPLGetXMLNode( psData, "=level1Product.productInfo" ); if (psProductInfo == NULL) { CPLError( CE_Failure, CPLE_OpenFailed, "Unable to find <productInfo> tag in file.\n" ); CPLDestroyXMLNode(psData); return NULL; } /* -------------------------------------------------------------------- */ /* Create the dataset. */ /* -------------------------------------------------------------------- */ TSXDataset *poDS = new TSXDataset(); /* -------------------------------------------------------------------- */ /* Read in product info. */ /* -------------------------------------------------------------------- */ poDS->SetMetadataItem( "SCENE_CENTRE_TIME", CPLGetXMLValue( psProductInfo, "sceneInfo.sceneCenterCoord.azimuthTimeUTC", "unknown" ) ); poDS->SetMetadataItem( "OPERATIONAL_MODE", CPLGetXMLValue( psProductInfo, "generationInfo.groundOperationsType", "unknown" ) ); poDS->SetMetadataItem( "ORBIT_CYCLE", CPLGetXMLValue( psProductInfo, "missionInfo.orbitCycle", "unknown" ) ); poDS->SetMetadataItem( "ABSOLUTE_ORBIT", CPLGetXMLValue( psProductInfo, "missionInfo.absOrbit", "unknown" ) ); poDS->SetMetadataItem( "ORBIT_DIRECTION", CPLGetXMLValue( psProductInfo, "missionInfo.orbitDirection", "unknown" ) ); poDS->SetMetadataItem( "IMAGING_MODE", CPLGetXMLValue( psProductInfo, "acquisitionInfo.imagingMode", "unknown" ) ); poDS->SetMetadataItem( "PRODUCT_VARIANT", CPLGetXMLValue( psProductInfo, "productVariantInfo.productVariant", "unknown" ) ); char *pszDataType = CPLStrdup( CPLGetXMLValue( psProductInfo, "imageDataInfo.imageDataType", "unknown" ) ); poDS->SetMetadataItem( "IMAGE_TYPE", pszDataType ); /* Get raster information */ int nRows = atoi( CPLGetXMLValue( psProductInfo, "imageDataInfo.imageRaster.numberOfRows", "" ) ); int nCols = atoi( CPLGetXMLValue( psProductInfo, "imageDataInfo.imageRaster.numberOfColumns", "" ) ); poDS->nRasterXSize = nCols; poDS->nRasterYSize = nRows; poDS->SetMetadataItem( "ROW_SPACING", CPLGetXMLValue( psProductInfo, "imageDataInfo.imageRaster.rowSpacing", "unknown" ) ); poDS->SetMetadataItem( "COL_SPACING", CPLGetXMLValue( psProductInfo, "imageDataInfo.imageRaster.columnSpacing", "unknown" ) ); poDS->SetMetadataItem( "COL_SPACING_UNITS", CPLGetXMLValue( psProductInfo, "imageDataInfo.imageRaster.columnSpacing.units", "unknown" ) ); /* Get equivalent number of looks */ poDS->SetMetadataItem( "AZIMUTH_LOOKS", CPLGetXMLValue( psProductInfo, "imageDataInfo.imageRaster.azimuthLooks", "unknown" ) ); poDS->SetMetadataItem( "RANGE_LOOKS", CPLGetXMLValue( psProductInfo, "imageDataInfo.imageRaster.rangeLooks", "unknown" ) ); const char *pszProductVariant = CPLGetXMLValue( psProductInfo, "productVariantInfo.productVariant", "unknown" ); poDS->SetMetadataItem( "PRODUCT_VARIANT", pszProductVariant ); /* Determine what product variant this is */ if (STARTS_WITH_CI(pszProductVariant, "SSC")) poDS->nProduct = eSSC; else if (STARTS_WITH_CI(pszProductVariant, "MGD")) poDS->nProduct = eMGD; else if (STARTS_WITH_CI(pszProductVariant, "EEC")) poDS->nProduct = eEEC; else if (STARTS_WITH_CI(pszProductVariant, "GEC")) poDS->nProduct = eGEC; else poDS->nProduct = eUnknown; /* Start reading in the product components */ char *pszGeorefFile = NULL; CPLErr geoTransformErr=CE_Failure; for ( CPLXMLNode *psComponent = psComponents->psChild; psComponent != NULL; psComponent = psComponent->psNext) { const char *pszType = NULL; const char *pszPath = CPLFormFilename( CPLGetDirname( osFilename ), GetFilePath(psComponent, &pszType), "" ); const char *pszPolLayer = CPLGetXMLValue(psComponent, "polLayer", " "); if ( !STARTS_WITH_CI(pszType, " ") ) { if (STARTS_WITH_CI(pszType, "MAPPING_GRID") ) { /* the mapping grid... save as a metadata item this path */ poDS->SetMetadataItem( "MAPPING_GRID", pszPath ); } else if (STARTS_WITH_CI(pszType, "GEOREF")) { /* save the path to the georef data for later use */ CPLFree( pszGeorefFile ); pszGeorefFile = CPLStrdup( pszPath ); } } else if( !STARTS_WITH_CI(pszPolLayer, " ") && STARTS_WITH_CI(psComponent->pszValue, "imageData") ) { /* determine the polarization of this band */ ePolarization ePol; if ( STARTS_WITH_CI(pszPolLayer, "HH") ) { ePol = HH; } else if ( STARTS_WITH_CI(pszPolLayer, "HV") ) { ePol = HV; } else if ( STARTS_WITH_CI(pszPolLayer, "VH") ) { ePol = VH; } else { ePol = VV; } GDALDataType eDataType = STARTS_WITH_CI(pszDataType, "COMPLEX") ? GDT_CInt16 : GDT_UInt16; /* try opening the file that represents that band */ GDALDataset *poBandData = reinterpret_cast<GDALDataset *>( GDALOpen( pszPath, GA_ReadOnly ) ); if ( poBandData != NULL ) { TSXRasterBand *poBand = new TSXRasterBand( poDS, eDataType, ePol, poBandData ); poDS->SetBand( poDS->GetRasterCount() + 1, poBand ); //copy georeferencing info from the band //need error checking?? //it will just save the info from the last band CPLFree( poDS->pszProjection ); poDS->pszProjection = CPLStrdup(poBandData->GetProjectionRef()); geoTransformErr = poBandData->GetGeoTransform(poDS->adfGeoTransform); } } } //now check if there is a geotransform if ( strcmp(poDS->pszProjection, "") && geoTransformErr==CE_None) { poDS->bHaveGeoTransform = TRUE; } else { poDS->bHaveGeoTransform = FALSE; CPLFree( poDS->pszProjection ); poDS->pszProjection = CPLStrdup(""); poDS->adfGeoTransform[0] = 0.0; poDS->adfGeoTransform[1] = 1.0; poDS->adfGeoTransform[2] = 0.0; poDS->adfGeoTransform[3] = 0.0; poDS->adfGeoTransform[4] = 0.0; poDS->adfGeoTransform[5] = 1.0; } CPLFree(pszDataType); /* -------------------------------------------------------------------- */ /* Check and set matrix representation. */ /* -------------------------------------------------------------------- */ if (poDS->GetRasterCount() == 4) { poDS->SetMetadataItem( "MATRIX_REPRESENTATION", "SCATTERING" ); } /* -------------------------------------------------------------------- */ /* Read the four corners and centre GCPs in */ /* -------------------------------------------------------------------- */ CPLXMLNode *psSceneInfo = CPLGetXMLNode( psData, "=level1Product.productInfo.sceneInfo" ); if (psSceneInfo != NULL) { /* extract the GCPs from the provided file */ bool success = false; if (pszGeorefFile != NULL) success = poDS->getGCPsFromGEOREF_XML(pszGeorefFile); //if the gcp's cannot be extracted from the georef file, try to get the corner coordinates //for now just SSC because the others don't have refColumn and refRow if (!success && poDS->nProduct == eSSC) { int nGCP = 0; double dfAvgHeight = CPLAtof(CPLGetXMLValue(psSceneInfo, "sceneAverageHeight", "0.0")); //count and allocate gcps - there should be five - 4 corners and a centre poDS->nGCPCount = 0; CPLXMLNode *psNode = psSceneInfo->psChild; for ( ; psNode != NULL; psNode = psNode->psNext ) { if (!EQUAL(psNode->pszValue, "sceneCenterCoord") && !EQUAL(psNode->pszValue, "sceneCornerCoord")) continue; poDS->nGCPCount++; } if (poDS->nGCPCount > 0) { poDS->pasGCPList = (GDAL_GCP *)CPLCalloc(sizeof(GDAL_GCP), poDS->nGCPCount); /* iterate over GCPs */ for (psNode = psSceneInfo->psChild; psNode != NULL; psNode = psNode->psNext ) { GDAL_GCP *psGCP = poDS->pasGCPList + nGCP; if (!EQUAL(psNode->pszValue, "sceneCenterCoord") && !EQUAL(psNode->pszValue, "sceneCornerCoord")) continue; psGCP->dfGCPPixel = CPLAtof(CPLGetXMLValue(psNode, "refColumn", "0.0")); psGCP->dfGCPLine = CPLAtof(CPLGetXMLValue(psNode, "refRow", "0.0")); psGCP->dfGCPX = CPLAtof(CPLGetXMLValue(psNode, "lon", "0.0")); psGCP->dfGCPY = CPLAtof(CPLGetXMLValue(psNode, "lat", "0.0")); psGCP->dfGCPZ = dfAvgHeight; psGCP->pszId = CPLStrdup( CPLSPrintf( "%d", nGCP ) ); psGCP->pszInfo = CPLStrdup(""); nGCP++; } //set the projection string - the fields are lat/long - seems to be WGS84 datum OGRSpatialReference osr; osr.SetWellKnownGeogCS( "WGS84" ); CPLFree(poDS->pszGCPProjection); osr.exportToWkt( &(poDS->pszGCPProjection) ); } } //gcps override geotransform - does it make sense to have both?? if (poDS->nGCPCount>0) { poDS->bHaveGeoTransform = FALSE; CPLFree( poDS->pszProjection ); poDS->pszProjection = CPLStrdup(""); poDS->adfGeoTransform[0] = 0.0; poDS->adfGeoTransform[1] = 1.0; poDS->adfGeoTransform[2] = 0.0; poDS->adfGeoTransform[3] = 0.0; poDS->adfGeoTransform[4] = 0.0; poDS->adfGeoTransform[5] = 1.0; } } else { CPLError(CE_Warning, CPLE_AppDefined, "Unable to find sceneInfo tag in XML document. " "Proceeding with caution."); } CPLFree(pszGeorefFile); /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->SetDescription( poOpenInfo->pszFilename ); poDS->TryLoadXML(); /* -------------------------------------------------------------------- */ /* Check for overviews. */ /* -------------------------------------------------------------------- */ poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename ); CPLDestroyXMLNode(psData); return poDS; }
GDALDataset *GDALWMSDataset::Open(GDALOpenInfo *poOpenInfo) { CPLXMLNode *config = NULL; CPLErr ret = CE_None; const char* pszFilename = poOpenInfo->pszFilename; const char* pabyHeader = (const char *) poOpenInfo->pabyHeader; if (poOpenInfo->nHeaderBytes == 0 && EQUALN(pszFilename, "<GDAL_WMS>", 10)) { config = CPLParseXMLString(pszFilename); } else if (poOpenInfo->nHeaderBytes >= 10 && EQUALN(pabyHeader, "<GDAL_WMS>", 10)) { config = CPLParseXMLFile(pszFilename); } else if (poOpenInfo->nHeaderBytes == 0 && (EQUALN(pszFilename, "WMS:http", 8) || EQUALN(pszFilename, "http", 4)) && strstr(pszFilename, "/MapServer?f=json") != NULL) { if (EQUALN(pszFilename, "WMS:http", 8)) pszFilename += 4; CPLString osURL(pszFilename); if (strstr(pszFilename, "&pretty=true") == NULL) osURL += "&pretty=true"; CPLHTTPResult *psResult = CPLHTTPFetch(osURL.c_str(), NULL); if (psResult == NULL) return NULL; if (psResult->pabyData == NULL) { CPLHTTPDestroyResult(psResult); return NULL; } config = GDALWMSDatasetGetConfigFromArcGISJSON(osURL, (const char*)psResult->pabyData); CPLHTTPDestroyResult(psResult); } else if (poOpenInfo->nHeaderBytes == 0 && (EQUALN(pszFilename, "WMS:", 4) || CPLString(pszFilename).ifind("SERVICE=WMS") != std::string::npos)) { CPLString osLayers = CPLURLGetValue(pszFilename, "LAYERS"); CPLString osRequest = CPLURLGetValue(pszFilename, "REQUEST"); if (osLayers.size() != 0) config = GDALWMSDatasetGetConfigFromURL(poOpenInfo); else if (EQUAL(osRequest, "GetTileService")) return GDALWMSMetaDataset::DownloadGetTileService(poOpenInfo); else return GDALWMSMetaDataset::DownloadGetCapabilities(poOpenInfo); } else if (poOpenInfo->nHeaderBytes != 0 && (strstr(pabyHeader, "<WMT_MS_Capabilities") != NULL || strstr(pabyHeader, "<WMS_Capabilities") != NULL || strstr(pabyHeader, "<!DOCTYPE WMT_MS_Capabilities") != NULL)) { CPLXMLNode* psXML = CPLParseXMLFile(pszFilename); if (psXML == NULL) return NULL; GDALDataset* poRet = GDALWMSMetaDataset::AnalyzeGetCapabilities(psXML); CPLDestroyXMLNode( psXML ); return poRet; } else if (poOpenInfo->nHeaderBytes != 0 && strstr(pabyHeader, "<WMS_Tile_Service") != NULL) { CPLXMLNode* psXML = CPLParseXMLFile(pszFilename); if (psXML == NULL) return NULL; GDALDataset* poRet = GDALWMSMetaDataset::AnalyzeGetTileService(psXML); CPLDestroyXMLNode( psXML ); return poRet; } else if (poOpenInfo->nHeaderBytes != 0 && strstr(pabyHeader, "<TileMap version=\"1.0.0\"") != NULL) { CPLXMLNode* psXML = CPLParseXMLFile(pszFilename); if (psXML == NULL) return NULL; config = GDALWMSDatasetGetConfigFromTileMap(psXML); CPLDestroyXMLNode( psXML ); } else if (poOpenInfo->nHeaderBytes != 0 && strstr(pabyHeader, "<Services") != NULL && strstr(pabyHeader, "<TileMapService version=\"1.0") != NULL) { CPLXMLNode* psXML = CPLParseXMLFile(pszFilename); if (psXML == NULL) return NULL; CPLXMLNode* psRoot = CPLGetXMLNode( psXML, "=Services" ); GDALDataset* poRet = NULL; if (psRoot) { CPLXMLNode* psTileMapService = CPLGetXMLNode(psRoot, "TileMapService"); if (psTileMapService) { const char* pszHref = CPLGetXMLValue(psTileMapService, "href", NULL); if (pszHref) { poRet = (GDALDataset*) GDALOpen(pszHref, GA_ReadOnly); } } } CPLDestroyXMLNode( psXML ); return poRet; } else if (poOpenInfo->nHeaderBytes != 0 && strstr(pabyHeader, "<TileMapService version=\"1.0.0\"") != NULL) { CPLXMLNode* psXML = CPLParseXMLFile(pszFilename); if (psXML == NULL) return NULL; GDALDataset* poRet = GDALWMSMetaDataset::AnalyzeTileMapService(psXML); CPLDestroyXMLNode( psXML ); return poRet; } else if (poOpenInfo->nHeaderBytes == 0 && EQUALN(pszFilename, "AGS:", 4)) { return NULL; } else if (poOpenInfo->nHeaderBytes == 0 && EQUALN(pszFilename, "IIP:", 4)) { CPLString osURL(pszFilename + 4); osURL += "&obj=Basic-Info"; CPLHTTPResult *psResult = CPLHTTPFetch(osURL.c_str(), NULL); if (psResult == NULL) return NULL; if (psResult->pabyData == NULL) { CPLHTTPDestroyResult(psResult); return NULL; } int nXSize, nYSize; const char* pszMaxSize = strstr((const char*)psResult->pabyData, "Max-size:"); const char* pszResolutionNumber = strstr((const char*)psResult->pabyData, "Resolution-number:"); if( pszMaxSize && sscanf(pszMaxSize + strlen("Max-size:"), "%d %d", &nXSize, &nYSize) == 2 && pszResolutionNumber ) { int nResolutions = atoi(pszResolutionNumber + strlen("Resolution-number:")); char* pszEscapedURL = CPLEscapeString(pszFilename + 4, -1, CPLES_XML); CPLString osXML = CPLSPrintf( "<GDAL_WMS>" " <Service name=\"IIP\">" " <ServerUrl>%s</ServerUrl>" " </Service>" " <DataWindow>" " <SizeX>%d</SizeX>" " <SizeY>%d</SizeY>" " <TileLevel>%d</TileLevel>" " </DataWindow>" " <BlockSizeX>256</BlockSizeX>" " <BlockSizeY>256</BlockSizeY>" " <BandsCount>3</BandsCount>" " <Cache />" "</GDAL_WMS>", pszEscapedURL, nXSize, nYSize, nResolutions - 1); config = CPLParseXMLString(osXML); CPLFree(pszEscapedURL); } CPLHTTPDestroyResult(psResult); } else return NULL; if (config == NULL) return NULL; /* -------------------------------------------------------------------- */ /* Confirm the requested access is supported. */ /* -------------------------------------------------------------------- */ if( poOpenInfo->eAccess == GA_Update ) { CPLDestroyXMLNode(config); CPLError( CE_Failure, CPLE_NotSupported, "The WMS poDriver does not support update access to existing" " datasets.\n" ); return NULL; } GDALWMSDataset *ds = new GDALWMSDataset(); ret = ds->Initialize(config); if (ret != CE_None) { delete ds; ds = NULL; } CPLDestroyXMLNode(config); /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ if (ds != NULL) { ds->SetMetadataItem( "INTERLEAVE", "PIXEL", "IMAGE_STRUCTURE" ); ds->SetDescription( poOpenInfo->pszFilename ); ds->TryLoadXML(); } return ds; }
CPLErr GDALPamDataset::TryLoadXML() { CPLXMLNode *psTree = NULL; PamInitialize(); /* -------------------------------------------------------------------- */ /* Clear dirty flag. Generally when we get to this point is */ /* from a call at the end of the Open() method, and some calls */ /* may have already marked the PAM info as dirty (for instance */ /* setting metadata), but really everything to this point is */ /* reproducable, and so the PAM info shouldn't really be */ /* thought of as dirty. */ /* -------------------------------------------------------------------- */ nPamFlags &= ~GPF_DIRTY; /* -------------------------------------------------------------------- */ /* Try reading the file. */ /* -------------------------------------------------------------------- */ if( !BuildPamFilename() ) return CE_None; VSIStatBufL sStatBuf; if( VSIStatL( psPam->pszPamFilename, &sStatBuf ) == 0 && VSI_ISREG( sStatBuf.st_mode ) ) { CPLErrorReset(); CPLPushErrorHandler( CPLQuietErrorHandler ); psTree = CPLParseXMLFile( psPam->pszPamFilename ); CPLPopErrorHandler(); } /* -------------------------------------------------------------------- */ /* If we are looking for a subdataset, search for it's subtree */ /* now. */ /* -------------------------------------------------------------------- */ if( psTree && psPam->osSubdatasetName.size() ) { CPLXMLNode *psSubTree; for( psSubTree = psTree->psChild; psSubTree != NULL; psSubTree = psSubTree->psNext ) { if( psSubTree->eType != CXT_Element || !EQUAL(psSubTree->pszValue,"Subdataset") ) continue; if( !EQUAL(CPLGetXMLValue( psSubTree, "name", "" ), psPam->osSubdatasetName) ) continue; psSubTree = CPLGetXMLNode( psSubTree, "PAMDataset" ); break; } if( psSubTree != NULL ) psSubTree = CPLCloneXMLTree( psSubTree ); CPLDestroyXMLNode( psTree ); psTree = psSubTree; } /* -------------------------------------------------------------------- */ /* If we fail, try .aux. */ /* -------------------------------------------------------------------- */ if( psTree == NULL ) return TryLoadAux(); /* -------------------------------------------------------------------- */ /* Initialize ourselves from this XML tree. */ /* -------------------------------------------------------------------- */ CPLErr eErr; CPLString osVRTPath(CPLGetPath(psPam->pszPamFilename)); eErr = XMLInit( psTree, osVRTPath ); CPLDestroyXMLNode( psTree ); if( eErr != CE_None ) PamClear(); return eErr; }
GDALDataset *TSXDataset::Open( GDALOpenInfo *poOpenInfo ) { /* -------------------------------------------------------------------- */ /* Is this a TerraSAR-X product file? */ /* -------------------------------------------------------------------- */ if (!TSXDataset::Identify( poOpenInfo )) { return NULL; /* nope */ } /* -------------------------------------------------------------------- */ /* Confirm the requested access is supported. */ /* -------------------------------------------------------------------- */ if( poOpenInfo->eAccess == GA_Update ) { CPLError( CE_Failure, CPLE_NotSupported, "The TSX driver does not support update access to existing" " datasets.\n" ); return NULL; } /* Ingest the XML */ CPLXMLNode *psData, *psComponents, *psProductInfo; psData = CPLParseXMLFile( poOpenInfo->pszFilename ); /* find the product components */ psComponents = CPLGetXMLNode( psData, "=level1Product.productComponents" ); if (psComponents == NULL) { CPLError( CE_Failure, CPLE_OpenFailed, "Unable to find <productComponents> tag in file.\n" ); return NULL; } /* find the product info tag */ psProductInfo = CPLGetXMLNode( psData, "=level1Product.productInfo" ); if (psComponents == NULL) { CPLError( CE_Failure, CPLE_OpenFailed, "Unable to find <productInfo> tag in file.\n" ); return NULL; } /* -------------------------------------------------------------------- */ /* Create the dataset. */ /* -------------------------------------------------------------------- */ TSXDataset *poDS = new TSXDataset(); poDS->fp = poOpenInfo->fp; poOpenInfo->fp = NULL; /* -------------------------------------------------------------------- */ /* Read in product info. */ /* -------------------------------------------------------------------- */ poDS->SetMetadataItem( "SCENE_CENTRE_TIME", CPLGetXMLValue( psProductInfo, "sceneInfo.sceneCenterCoord.azimuthTimeUTC", "unknown" ) ); poDS->SetMetadataItem( "OPERATIONAL_MODE", CPLGetXMLValue( psProductInfo, "generationInfo.groundOperationsType", "unknown" ) ); poDS->SetMetadataItem( "ORBIT_CYCLE", CPLGetXMLValue( psProductInfo, "missionInfo.orbitCycle", "unknown" ) ); poDS->SetMetadataItem( "ABSOLUTE_ORBIT", CPLGetXMLValue( psProductInfo, "missionInfo.absOrbit", "unknown" ) ); poDS->SetMetadataItem( "ORBIT_DIRECTION", CPLGetXMLValue( psProductInfo, "missionInfo.orbitDirection", "unknown" ) ); poDS->SetMetadataItem( "IMAGING_MODE", CPLGetXMLValue( psProductInfo, "acquisitionInfo.imagingMode", "unknown" ) ); poDS->SetMetadataItem( "PRODUCT_VARIANT", CPLGetXMLValue( psProductInfo, "productVariantInfo.productVariant", "unknown" ) ); char *pszDataType = strdup( CPLGetXMLValue( psProductInfo, "imageDataInfo.imageDataType", "unknown" ) ); poDS->SetMetadataItem( "IMAGE_TYPE", pszDataType ); /* Get raster information */ int nRows = atoi( CPLGetXMLValue( psProductInfo, "imageDataInfo.imageRaster.numberOfRows", "" ) ); int nCols = atoi( CPLGetXMLValue( psProductInfo, "imageDataInfo.imageRaster.numberOfColumns", "" ) ); poDS->nRasterXSize = nCols; poDS->nRasterYSize = nRows; poDS->SetMetadataItem( "ROW_SPACING", CPLGetXMLValue( psProductInfo, "imageDataInfo.imageRaster.rowSpacing", "unknown" ) ); poDS->SetMetadataItem( "COL_SPACING", CPLGetXMLValue( psProductInfo, "imageDataInfo.imageRaster.columnSpacing", "unknown" ) ); poDS->SetMetadataItem( "COL_SPACING_UNITS", CPLGetXMLValue( psProductInfo, "imageDataInfo.imageRaster.columnSpacing.units", "unknown" ) ); /* Get equivalent number of looks */ poDS->SetMetadataItem( "AZIMUTH_LOOKS", CPLGetXMLValue( psProductInfo, "imageDataInfo.imageRaster.azimuthLooks", "unknown" ) ); poDS->SetMetadataItem( "RANGE_LOOKS", CPLGetXMLValue( psProductInfo, "imageDataInfo.imageRaster.rangeLooks", "unknown" ) ); const char *pszProductVariant; pszProductVariant = CPLGetXMLValue( psProductInfo, "productVariantInfo.productVariant", "unknown" ); poDS->SetMetadataItem( "PRODUCT_VARIANT", pszProductVariant ); /* Determine what product variant this is */ if (EQUALN(pszProductVariant,"SSC",3)) poDS->nProduct = eSSC; else if (EQUALN(pszProductVariant,"MGD",3)) poDS->nProduct = eMGD; else if (EQUALN(pszProductVariant,"EEC",3)) poDS->nProduct = eEEC; else if (EQUALN(pszProductVariant,"GEC",3)) poDS->nProduct = eGEC; else poDS->nProduct = eUnknown; /* Start reading in the product components */ const char *pszPath; char *pszGeorefFile = NULL; CPLXMLNode *psComponent; for (psComponent = psComponents->psChild; psComponent != NULL; psComponent = psComponent->psNext) { char *pszType; pszPath = CPLFormFilename( CPLGetDirname( poOpenInfo->pszFilename ), GetFilePath(psComponent, &pszType), "" ); const char *pszPolLayer = CPLGetXMLValue(psComponent, "polLayer", " "); if ( !EQUALN(pszType," ",1) ) { if (EQUALN(pszType, "MAPPING_GRID", 12) ) { /* the mapping grid... save as a metadata item this path */ poDS->SetMetadataItem( "MAPPING_GRID", pszPath ); } else if (EQUALN(pszType, "GEOREF", 6)) { /* save the path to the georef data for later use */ pszGeorefFile = strdup( pszPath ); } CPLFree(pszType); } else if( !EQUALN(pszPolLayer, " ", 1) && EQUALN(psComponent->pszValue, "imageData", 9) ) { /* determine the polarization of this band */ ePolarization ePol; if ( EQUALN(pszPolLayer, "HH", 2) ) { ePol = HH; } else if ( EQUALN(pszPolLayer, "HV" , 2) ) { ePol = HV; } else if ( EQUALN(pszPolLayer, "VH", 2) ) { ePol = VH; } else { ePol = VV; } GDALDataType eDataType = EQUALN(pszDataType, "COMPLEX", 7) ? GDT_CInt16 : GDT_UInt16; /* try opening the file that represents that band */ TSXRasterBand *poBand; GDALDataset *poBandData; poBandData = (GDALDataset *) GDALOpen( pszPath, GA_ReadOnly ); if ( poBandData != NULL ) { poBand = new TSXRasterBand( poDS, eDataType, ePol, poBandData ); poDS->SetBand( poDS->GetRasterCount() + 1, poBand ); } } } CPLFree(pszDataType); /* -------------------------------------------------------------------- */ /* Check and set matrix representation. */ /* -------------------------------------------------------------------- */ if (poDS->GetRasterCount() == 4) { poDS->SetMetadataItem( "MATRIX_REPRESENTATION", "SCATTERING" ); } /* -------------------------------------------------------------------- */ /* Read the four corners and centre GCPs in */ /* -------------------------------------------------------------------- */ CPLXMLNode *psSceneInfo = CPLGetXMLNode( psData, "=level1Product.productInfo.sceneInfo" ); /* for SSC products */ if (poDS->nProduct == eSSC && psSceneInfo != NULL) { CPLXMLNode *psNode; int nGCP = 0; double dfAvgHeight = atof(CPLGetXMLValue(psSceneInfo, "sceneAverageHeight", "0.0")); char szID[3]; poDS->nGCPCount = 5; /* 5 GCPs provided */ poDS->pasGCPList = (GDAL_GCP *)CPLCalloc(sizeof(GDAL_GCP), poDS->nGCPCount); /* iterate over GCPs */ for (psNode = psSceneInfo->psChild; psNode != NULL; psNode = psNode->psNext ) { GDAL_GCP *psGCP = poDS->pasGCPList + nGCP; if (!EQUAL(psNode->pszValue, "sceneCenterCoord") && !EQUAL(psNode->pszValue, "sceneCornerCoord")) continue; CPLSPrintf( szID, "%d", nGCP ); psGCP->dfGCPPixel = atof(CPLGetXMLValue(psNode, "refColumn", "0.0")); psGCP->dfGCPLine = atof(CPLGetXMLValue(psNode, "refRow", "0.0")); psGCP->dfGCPX = atof(CPLGetXMLValue(psNode, "lon", "0.0")); psGCP->dfGCPY = atof(CPLGetXMLValue(psNode, "lat", "0.0")); psGCP->dfGCPZ = dfAvgHeight; psGCP->pszId = CPLStrdup( szID ); psGCP->pszInfo = CPLStrdup(""); nGCP++; } } else if (psSceneInfo != NULL) { /* extract the GCPs from the provided file */ /* TODO */ } else { CPLError(CE_Warning, CPLE_AppDefined, "Unable to find sceneInfo tag in XML document. " "Proceeding with caution."); } /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->SetDescription( poOpenInfo->pszFilename ); poDS->TryLoadXML(); /* -------------------------------------------------------------------- */ /* Check for overviews. */ /* -------------------------------------------------------------------- */ poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename ); CPLDestroyXMLNode(psData); return poDS; }
void ImdReader::ReadModel(const char *pszFilename) { CPLDebug( "OGR_ILI", "Reading model '%s'", pszFilename); CPLXMLNode* psRootNode = CPLParseXMLFile(pszFilename); if( psRootNode == NULL ) return; CPLXMLNode *psSectionNode = CPLGetXMLNode( psRootNode, "=TRANSFER.DATASECTION" ); if( psSectionNode == NULL ) return; StrNodeMap oTidLookup; /* for fast lookup of REF relations */ ClassesMap oClasses; NodeCountMap oAxisCount; NodeVector oArcLineTypes; const char *modelName; /* Fill TID lookup map and IliClasses lookup map */ CPLXMLNode* psModel = psSectionNode->psChild; while( psModel != NULL ) { modelName = CPLGetXMLValue( psModel, "BID", NULL ); //CPLDebug( "OGR_ILI", "Model: '%s'", modelName); CPLXMLNode* psEntry = psModel->psChild; while( psEntry != NULL ) { if (psEntry->eType != CXT_Attribute) //ignore BID { //CPLDebug( "OGR_ILI", "Node tag: '%s'", psEntry->pszValue); const char* psTID = CPLGetXMLValue( psEntry, "TID", NULL ); if( psTID != NULL ) oTidLookup[psTID] = psEntry; if( EQUAL(psEntry->pszValue, "IlisMeta07.ModelData.Model") && !EQUAL(modelName, "MODEL.INTERLIS")) { IliModelInfo modelInfo; modelInfo.name = CPLGetXMLValue( psEntry, "Name", "OGR" ); modelInfo.version = CPLGetXMLValue( psEntry, "Version", "" ); modelInfo.uri = CPLGetXMLValue( psEntry, "At", "" ); modelInfos.push_back(modelInfo); mainModelName = modelInfo.name; //FIXME: check model inheritance //version = CPLGetXMLValue(psEntry, "iliVersion", "0"); //1 or 2.3 CPLXMLNode *psFormatNode = CPLGetXMLNode( psEntry, "ili1Format" ); if (psFormatNode != NULL) { psFormatNode = psFormatNode->psChild; codeBlank = atoi(CPLGetXMLValue(psFormatNode, "blankCode", "95")); codeUndefined = atoi(CPLGetXMLValue(psFormatNode, "undefinedCode", "64")); codeContinue = atoi(CPLGetXMLValue(psFormatNode, "continueCode", "92")); } } else if( EQUAL(psEntry->pszValue, "IlisMeta07.ModelData.SubModel")) { mainBasketName = CPLGetXMLValue(psEntry, "TID", "OGR"); mainTopicName = CPLGetXMLValue(psEntry, "Name", "OGR"); } else if( EQUAL(psEntry->pszValue, "IlisMeta07.ModelData.Class") ) { CPLDebug( "OGR_ILI", "Class name: '%s'", psTID); oClasses[psEntry] = new IliClass(psEntry, iliVersion, oTidLookup, oClasses, oAxisCount); } } psEntry = psEntry->psNext; } // 2nd pass: add fields via TransferElement entries & role associations psEntry = psModel->psChild; while( psEntry != NULL ) { if (psEntry->eType != CXT_Attribute) //ignore BID { //CPLDebug( "OGR_ILI", "Node tag: '%s'", psEntry->pszValue); if( iliVersion == 1 && EQUAL(psEntry->pszValue, "IlisMeta07.ModelData.Ili1TransferElement")) { const char* psClassRef = CPLGetXMLValue( psEntry, "Ili1TransferClass.REF", NULL ); const char* psElementRef = CPLGetXMLValue( psEntry, "Ili1RefAttr.REF", NULL ); int iOrderPos = atoi(CPLGetXMLValue( psEntry, "Ili1RefAttr.ORDER_POS", "0" ))-1; IliClass* psParentClass = oClasses[oTidLookup[psClassRef]]; CPLXMLNode* psElementNode = oTidLookup[psElementRef]; psParentClass->AddFieldNode(psElementNode, iOrderPos); } else if( EQUAL(psEntry->pszValue, "IlisMeta07.ModelData.TransferElement")) { const char* psClassRef = CPLGetXMLValue( psEntry, "TransferClass.REF", NULL ); const char* psElementRef = CPLGetXMLValue( psEntry, "TransferElement.REF", NULL ); int iOrderPos = atoi(CPLGetXMLValue( psEntry, "TransferElement.ORDER_POS", "0" ))-1; IliClass* psParentClass = oClasses[oTidLookup[psClassRef]]; CPLXMLNode* psElementNode = oTidLookup[psElementRef]; psParentClass->AddFieldNode(psElementNode, iOrderPos); } else if( EQUAL(psEntry->pszValue, "IlisMeta07.ModelData.Role")) { const char* psRefParent = CPLGetXMLValue( psEntry, "Association.REF", NULL ); int iOrderPos = atoi(CPLGetXMLValue( psEntry, "Association.ORDER_POS", "0" ))-1; IliClass* psParentClass = oClasses[oTidLookup[psRefParent]]; if (psParentClass) psParentClass->AddRoleNode(psEntry, iOrderPos); } else if( EQUAL(psEntry->pszValue, "IlisMeta07.ModelData.AxisSpec")) { const char* psClassRef = CPLGetXMLValue( psEntry, "CoordType.REF", NULL ); //int iOrderPos = atoi(CPLGetXMLValue( psEntry, "Axis.ORDER_POS", "0" ))-1; CPLXMLNode* psCoordTypeNode = oTidLookup[psClassRef]; oAxisCount[psCoordTypeNode] += 1; } else if( EQUAL(psEntry->pszValue, "IlisMeta07.ModelData.LinesForm")) { const char* psLineForm = CPLGetXMLValue( psEntry, "LineForm.REF", NULL ); if (EQUAL(psLineForm, "INTERLIS.ARCS")) { const char* psElementRef = CPLGetXMLValue( psEntry, "LineType.REF", NULL ); CPLXMLNode* psElementNode = oTidLookup[psElementRef]; oArcLineTypes.push_back(psElementNode); } } } psEntry = psEntry->psNext; } psModel = psModel->psNext; } /* Analyze class inheritance & add fields to class table defn */ for (ClassesMap::const_iterator it = oClasses.begin(); it != oClasses.end(); ++it) { //CPLDebug( "OGR_ILI", "Class: '%s'", it->second->GetName()); const char* psRefSuper = CPLGetXMLValue( it->first, "Super.REF", NULL ); if (psRefSuper) { if (oTidLookup.find(psRefSuper) != oTidLookup.end() && oClasses.find(oTidLookup[psRefSuper]) != oClasses.end()) { oClasses[oTidLookup[psRefSuper]]->hasDerivedClasses = true; } else { CPLError(CE_Warning, CPLE_AppDefined, "Couldn't reference super class '%s'", psRefSuper); } } it->second->InitFieldDefinitions(); it->second->AddFieldDefinitions(oArcLineTypes); } /* Filter relevant classes */ for (ClassesMap::const_iterator it = oClasses.begin(); it != oClasses.end(); ++it) { const char* className = it->second->GetIliName(); FeatureDefnInfo oClassInfo = it->second->tableDefs(); if (!EQUALN(className, "INTERLIS.", 9) && oClassInfo.poTableDefn) featureDefnInfos.push_back(oClassInfo); } CPLDestroyXMLNode(psRootNode); }
GDALDataset *ECRGTOCDataset::Open( GDALOpenInfo * poOpenInfo ) { if( !Identify( poOpenInfo ) ) return nullptr; const char *pszFilename = poOpenInfo->pszFilename; CPLString osFilename; CPLString osProduct, osDiscId, osScale; if( STARTS_WITH_CI(pszFilename, "ECRG_TOC_ENTRY:") ) { pszFilename += strlen("ECRG_TOC_ENTRY:"); /* PRODUCT:DISK:SCALE:FILENAME (or PRODUCT:DISK:FILENAME historically) */ /* with FILENAME potentially C:\BLA... */ char** papszTokens = CSLTokenizeString2(pszFilename, ":", 0); int nTokens = CSLCount(papszTokens); if( nTokens != 3 && nTokens != 4 && nTokens != 5 ) { CSLDestroy(papszTokens); return nullptr; } osProduct = papszTokens[0]; osDiscId = papszTokens[1]; if( nTokens == 3 ) osFilename = papszTokens[2]; else if( nTokens == 4 ) { if( strlen(papszTokens[2]) == 1 && (papszTokens[3][0] == '\\' || papszTokens[3][0] == '/') ) { osFilename = papszTokens[2]; osFilename += ":"; osFilename += papszTokens[3]; } else { osScale = papszTokens[2]; osFilename = papszTokens[3]; } } else if( nTokens == 5 && strlen(papszTokens[3]) == 1 && (papszTokens[4][0] == '\\' || papszTokens[4][0] == '/') ) { osScale = papszTokens[2]; osFilename = papszTokens[3]; osFilename += ":"; osFilename += papszTokens[4]; } else { CSLDestroy(papszTokens); return nullptr; } CSLDestroy(papszTokens); pszFilename = osFilename.c_str(); } /* -------------------------------------------------------------------- */ /* Parse the XML file */ /* -------------------------------------------------------------------- */ CPLXMLNode* psXML = CPLParseXMLFile(pszFilename); if (psXML == nullptr) { return nullptr; } GDALDataset* poDS = Build( pszFilename, psXML, osProduct, osDiscId, osScale, poOpenInfo->pszFilename); CPLDestroyXMLNode(psXML); if (poDS && poOpenInfo->eAccess == GA_Update) { CPLError(CE_Failure, CPLE_NotSupported, "ECRGTOC driver does not support update mode"); delete poDS; return nullptr; } return poDS; }
int GMLReader::ParseXSD( const char *pszFile ) { if( pszFile == NULL ) return FALSE; /* -------------------------------------------------------------------- */ /* Load the raw XML file. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psXSDTree = CPLParseXMLFile( pszFile ); if( psXSDTree == NULL ) return FALSE; /* -------------------------------------------------------------------- */ /* Strip off any namespace qualifiers. */ /* -------------------------------------------------------------------- */ CPLStripXMLNamespace( psXSDTree, NULL, TRUE ); /* -------------------------------------------------------------------- */ /* Find <schema> root element. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psSchemaNode = CPLGetXMLNode( psXSDTree, "=schema" ); if( psSchemaNode == NULL ) { CPLDestroyXMLNode( psXSDTree ); return FALSE; } /* ==================================================================== */ /* Process each feature class definition. */ /* ==================================================================== */ CPLXMLNode *psThis; int bIsLevel0 = TRUE; for( psThis = psSchemaNode->psChild; psThis != NULL; psThis = psThis->psNext ) { /* -------------------------------------------------------------------- */ /* Check for <xs:element> node. */ /* -------------------------------------------------------------------- */ if( psThis->eType != CXT_Element || !EQUAL(psThis->pszValue,"element") ) continue; /* -------------------------------------------------------------------- */ /* Check the substitution group. */ /* -------------------------------------------------------------------- */ const char *pszSubGroup = StripNS(CPLGetXMLValue(psThis,"substitutionGroup","")); // Old OGR produced elements for the feature collection. if( EQUAL(pszSubGroup, "_FeatureCollection") ) continue; if( !EQUAL(pszSubGroup, "_Feature") ) { bIsLevel0 = FALSE; break; } /* -------------------------------------------------------------------- */ /* Get name */ /* -------------------------------------------------------------------- */ const char *pszName; pszName = CPLGetXMLValue( psThis, "name", NULL ); if( pszName == NULL ) { bIsLevel0 = FALSE; break; } /* -------------------------------------------------------------------- */ /* Get type and verify relationship with name. */ /* -------------------------------------------------------------------- */ const char *pszType; pszType = CPLGetXMLValue( psThis, "type", NULL ); if( strstr( pszType, ":" ) != NULL ) pszType = strstr( pszType, ":" ) + 1; if( pszType == NULL || !EQUALN(pszType,pszName,strlen(pszName)) || !(EQUAL(pszType+strlen(pszName),"_Type") || EQUAL(pszType+strlen(pszName),"Type")) ) { bIsLevel0 = FALSE; break; } /* -------------------------------------------------------------------- */ /* The very next element should be the corresponding */ /* complexType declaration for the element. */ /* -------------------------------------------------------------------- */ psThis = psThis->psNext; while( psThis != NULL && psThis->eType == CXT_Comment ) psThis = psThis->psNext; if( psThis == NULL || psThis->eType != CXT_Element || !EQUAL(psThis->pszValue,"complexType") || !EQUAL(CPLGetXMLValue(psThis,"name",""),pszType) ) { bIsLevel0 = FALSE; break; } /* -------------------------------------------------------------------- */ /* Grab the sequence of extensions greatgrandchild. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psAttrSeq = CPLGetXMLNode( psThis, "complexContent.extension.sequence" ); if( psAttrSeq == NULL ) { bIsLevel0 = FALSE; break; } /* -------------------------------------------------------------------- */ /* We are pretty sure this going to be a valid Feature class */ /* now, so create it. */ /* -------------------------------------------------------------------- */ GMLFeatureClass *poClass = new GMLFeatureClass( pszName ); /* -------------------------------------------------------------------- */ /* Loop over each of the attribute elements being defined for */ /* this feature class. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psAttrDef; for( psAttrDef = psAttrSeq->psChild; psAttrDef != NULL; psAttrDef = psAttrDef->psNext ) { if( !EQUAL(psAttrDef->pszValue,"element") ) continue; // For now we skip geometries .. fixup later. if( CPLGetXMLNode( psAttrDef, "simpleType" ) == NULL ) continue; GMLPropertyDefn *poProp = new GMLPropertyDefn( CPLGetXMLValue( psAttrDef, "name", "unnamed" ), CPLGetXMLValue( psAttrDef, "name", "unnamed" ) ); const char *pszBase = StripNS( CPLGetXMLValue( psAttrDef, "simpleType.restriction.base", "" )); if( EQUAL(pszBase,"decimal") ) { poProp->SetType( GMLPT_Real ); const char *pszWidth = CPLGetXMLValue( psAttrDef, "simpleType.restriction.totalDigits.value", "0" ); const char *pszPrecision = CPLGetXMLValue( psAttrDef, "simpleType.restriction.fractionDigits.value", "0" ); poProp->SetWidth( atoi(pszWidth) ); poProp->SetPrecision( atoi(pszPrecision) ); } else if( EQUAL(pszBase,"float") || EQUAL(pszBase,"double") ) poProp->SetType( GMLPT_Real ); else if( EQUAL(pszBase,"integer") ) { poProp->SetType( GMLPT_Integer ); const char *pszWidth = CPLGetXMLValue( psAttrDef, "simpleType.restriction.totalDigits.value", "0" ); poProp->SetWidth( atoi(pszWidth) ); } else if( EQUAL(pszBase,"string") ) { poProp->SetType( GMLPT_String ); const char *pszWidth = CPLGetXMLValue( psAttrDef, "simpleType.restriction.maxLength.value", "0" ); poProp->SetWidth( atoi(pszWidth) ); } else poProp->SetType( GMLPT_Untyped ); poClass->AddProperty( poProp ); } /* -------------------------------------------------------------------- */ /* Class complete, add to reader class list. */ /* -------------------------------------------------------------------- */ poClass->SetSchemaLocked( TRUE ); AddClass( poClass ); } CPLDestroyXMLNode( psXSDTree ); if( m_nClassCount > 0 ) { SetClassListLocked( TRUE ); return TRUE; } else return FALSE; }
GDALDataset *GDALWMSDataset::Open(GDALOpenInfo *poOpenInfo) { CPLXMLNode *config = NULL; CPLErr ret = CE_None; const char* pszFilename = poOpenInfo->pszFilename; const char* pabyHeader = (const char *) poOpenInfo->pabyHeader; if (poOpenInfo->nHeaderBytes == 0 && EQUALN(pszFilename, "<GDAL_WMS>", 10)) { config = CPLParseXMLString(pszFilename); } else if (poOpenInfo->nHeaderBytes >= 10 && EQUALN(pabyHeader, "<GDAL_WMS>", 10)) { config = CPLParseXMLFile(pszFilename); } else if (poOpenInfo->nHeaderBytes == 0 && (EQUALN(pszFilename, "WMS:http", 8) || EQUALN(pszFilename, "http", 4)) && strstr(pszFilename, "/MapServer?f=json") != NULL) { if (EQUALN(pszFilename, "WMS:http", 8)) pszFilename += 4; CPLString osURL(pszFilename); if (strstr(pszFilename, "&pretty=true") == NULL) osURL += "&pretty=true"; CPLHTTPResult *psResult = CPLHTTPFetch(osURL.c_str(), NULL); if (psResult == NULL) return NULL; if (psResult->pabyData == NULL) { CPLHTTPDestroyResult(psResult); return NULL; } config = GDALWMSDatasetGetConfigFromArcGISJSON(osURL, (const char*)psResult->pabyData); CPLHTTPDestroyResult(psResult); } else if (poOpenInfo->nHeaderBytes == 0 && (EQUALN(pszFilename, "WMS:", 4) || CPLString(pszFilename).ifind("SERVICE=WMS") != std::string::npos)) { CPLString osLayers = CPLURLGetValue(pszFilename, "LAYERS"); CPLString osRequest = CPLURLGetValue(pszFilename, "REQUEST"); if (osLayers.size() != 0) config = GDALWMSDatasetGetConfigFromURL(poOpenInfo); else if (EQUAL(osRequest, "GetTileService")) return GDALWMSMetaDataset::DownloadGetTileService(poOpenInfo); else return GDALWMSMetaDataset::DownloadGetCapabilities(poOpenInfo); } else if (poOpenInfo->nHeaderBytes != 0 && (strstr(pabyHeader, "<WMT_MS_Capabilities") != NULL || strstr(pabyHeader, "<WMS_Capabilities") != NULL || strstr(pabyHeader, "<!DOCTYPE WMT_MS_Capabilities") != NULL)) { CPLXMLNode* psXML = CPLParseXMLFile(pszFilename); if (psXML == NULL) return NULL; GDALDataset* poRet = GDALWMSMetaDataset::AnalyzeGetCapabilities(psXML); CPLDestroyXMLNode( psXML ); return poRet; } else if (poOpenInfo->nHeaderBytes != 0 && strstr(pabyHeader, "<WMS_Tile_Service") != NULL) { CPLXMLNode* psXML = CPLParseXMLFile(pszFilename); if (psXML == NULL) return NULL; GDALDataset* poRet = GDALWMSMetaDataset::AnalyzeGetTileService(psXML); CPLDestroyXMLNode( psXML ); return poRet; } else if (poOpenInfo->nHeaderBytes != 0 && strstr(pabyHeader, "<TileMap version=\"1.0.0\"") != NULL) { CPLXMLNode* psXML = CPLParseXMLFile(pszFilename); if (psXML == NULL) return NULL; config = GDALWMSDatasetGetConfigFromTileMap(psXML); CPLDestroyXMLNode( psXML ); } else if (poOpenInfo->nHeaderBytes != 0 && strstr(pabyHeader, "<Services") != NULL && strstr(pabyHeader, "<TileMapService version=\"1.0") != NULL) { CPLXMLNode* psXML = CPLParseXMLFile(pszFilename); if (psXML == NULL) return NULL; CPLXMLNode* psRoot = CPLGetXMLNode( psXML, "=Services" ); GDALDataset* poRet = NULL; if (psRoot) { CPLXMLNode* psTileMapService = CPLGetXMLNode(psRoot, "TileMapService"); if (psTileMapService) { const char* pszHref = CPLGetXMLValue(psTileMapService, "href", NULL); if (pszHref) { poRet = (GDALDataset*) GDALOpen(pszHref, GA_ReadOnly); } } } CPLDestroyXMLNode( psXML ); return poRet; } else if (poOpenInfo->nHeaderBytes != 0 && strstr(pabyHeader, "<TileMapService version=\"1.0.0\"") != NULL) { CPLXMLNode* psXML = CPLParseXMLFile(pszFilename); if (psXML == NULL) return NULL; GDALDataset* poRet = GDALWMSMetaDataset::AnalyzeTileMapService(psXML); CPLDestroyXMLNode( psXML ); return poRet; } else return NULL; if (config == NULL) return NULL; /* -------------------------------------------------------------------- */ /* Confirm the requested access is supported. */ /* -------------------------------------------------------------------- */ if( poOpenInfo->eAccess == GA_Update ) { CPLDestroyXMLNode(config); CPLError( CE_Failure, CPLE_NotSupported, "The WMS driver does not support update access to existing" " datasets.\n" ); return NULL; } GDALWMSDataset *ds = new GDALWMSDataset(); ret = ds->Initialize(config); if (ret != CE_None) { delete ds; ds = NULL; } CPLDestroyXMLNode(config); /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ if (ds != NULL) { ds->SetMetadataItem( "INTERLEAVE", "PIXEL", "IMAGE_STRUCTURE" ); ds->SetDescription( poOpenInfo->pszFilename ); ds->TryLoadXML(); } return ds; }
bool GMLASConfiguration::Load(const char* pszFilename) { // Allow configuration to be inlined CPLXMLNode* psRoot = STARTS_WITH(pszFilename, "<Configuration>") ? CPLParseXMLString(pszFilename) : CPLParseXMLFile(pszFilename); if( psRoot == NULL ) { Finalize(); return false; } CPLXMLTreeCloser oCloser(psRoot); // Validate the configuration file if( CPLTestBool(CPLGetConfigOption("GDAL_XML_VALIDATION", "YES")) ) { const char* pszXSD = CPLFindFile( "gdal", "gmlasconf.xsd" ); if( pszXSD != NULL ) { std::vector<CPLString> aosErrors; const CPLErr eErrClass = CPLGetLastErrorType(); const CPLErrorNum nErrNum = CPLGetLastErrorNo(); const CPLString osErrMsg = CPLGetLastErrorMsg(); CPLPushErrorHandlerEx(GMLASConfigurationErrorHandler, &aosErrors); int bRet = CPLValidateXML(pszFilename, pszXSD, NULL); CPLPopErrorHandler(); if( !bRet && aosErrors.size() > 0 && strstr(aosErrors[0].c_str(), "missing libxml2 support") == NULL ) { for(size_t i = 0; i < aosErrors.size(); i++) { CPLError(CE_Warning, CPLE_AppDefined, "%s", aosErrors[i].c_str()); } } else { CPLErrorSetState(eErrClass, nErrNum, osErrMsg); } } } m_bAllowRemoteSchemaDownload = CPLGetXMLBoolValue(psRoot, "=Configuration.AllowRemoteSchemaDownload", ALLOW_REMOTE_SCHEMA_DOWNLOAD_DEFAULT ); m_bAllowXSDCache = CPLGetXMLBoolValue( psRoot, "=Configuration.SchemaCache.enabled", ALLOW_XSD_CACHE_DEFAULT ); if( m_bAllowXSDCache ) { m_osXSDCacheDirectory = CPLGetXMLValue(psRoot, "=Configuration.SchemaCache.Directory", ""); } m_bValidate = CPLGetXMLBoolValue( psRoot, "=Configuration.Validation.enabled", VALIDATE_DEFAULT ); if( m_bValidate ) { m_bFailIfValidationError = CPLGetXMLBoolValue(psRoot, "=Configuration.Validation.FailIfError", FAIL_IF_VALIDATION_ERROR_DEFAULT ); } m_bExposeMetadataLayers = CPLGetXMLBoolValue( psRoot, "=Configuration.ExposeMetadataLayers", EXPOSE_METADATA_LAYERS_DEFAULT ); m_bAlwaysGenerateOGRId = CPLGetXMLBoolValue( psRoot, "=Configuration.LayerBuildingRules.AlwaysGenerateOGRId", ALWAYS_GENERATE_OGR_ID_DEFAULT ); m_bRemoveUnusedLayers = CPLGetXMLBoolValue( psRoot, "=Configuration.LayerBuildingRules.RemoveUnusedLayers", REMOVE_UNUSED_LAYERS_DEFAULT ); m_bRemoveUnusedFields = CPLGetXMLBoolValue( psRoot, "=Configuration.LayerBuildingRules.RemoveUnusedFields", REMOVE_UNUSED_FIELDS_DEFAULT ); m_bUseArrays = CPLGetXMLBoolValue( psRoot, "=Configuration.LayerBuildingRules.UseArrays", USE_ARRAYS_DEFAULT ); m_bIncludeGeometryXML = CPLGetXMLBoolValue( psRoot, "=Configuration.LayerBuildingRules.GML.IncludeGeometryXML", INCLUDE_GEOMETRY_XML_DEFAULT ); m_bInstantiateGMLFeaturesOnly = CPLGetXMLBoolValue( psRoot, "=Configuration.LayerBuildingRules.GML.InstantiateGMLFeaturesOnly", INSTANTIATE_GML_FEATURES_ONLY_DEFAULT ); m_nIdentifierMaxLength = atoi( CPLGetXMLValue( psRoot, "=Configuration.LayerBuildingRules.IdentifierMaxLength", "0" ) ); m_bCaseInsensitiveIdentifier = CPLGetXMLBoolValue( psRoot, "=Configuration.LayerBuildingRules.CaseInsensitiveIdentifier", CASE_INSENSITIVE_IDENTIFIER_DEFAULT ); CPLXMLNode* psIgnoredXPaths = CPLGetXMLNode(psRoot, "=Configuration.IgnoredXPaths"); if( psIgnoredXPaths ) { const bool bGlobalWarnIfIgnoredXPathFound = CPLGetXMLBoolValue( psIgnoredXPaths, "WarnIfIgnoredXPathFoundInDocInstance", WARN_IF_EXCLUDED_XPATH_FOUND_DEFAULT ); CPLXMLNode* psNamespaces = CPLGetXMLNode(psIgnoredXPaths, "Namespaces"); if( psNamespaces != NULL ) { for( CPLXMLNode* psIter = psNamespaces->psChild; psIter != NULL; psIter = psIter->psNext ) { if( psIter->eType == CXT_Element && EQUAL(psIter->pszValue, "Namespace") ) { CPLString osPrefix = CPLGetXMLValue(psIter, "prefix", ""); CPLString osURI = CPLGetXMLValue(psIter, "uri", ""); if( !osPrefix.empty() && !osURI.empty() ) { if( m_oMapPrefixToURIIgnoredXPaths.find(osPrefix) == m_oMapPrefixToURIIgnoredXPaths.end() ) { m_oMapPrefixToURIIgnoredXPaths[osPrefix] = osURI; } else { CPLError(CE_Warning, CPLE_AppDefined, "Prefix %s was already mapped to %s. " "Attempt to map it to %s ignored", osPrefix.c_str(), m_oMapPrefixToURIIgnoredXPaths[osPrefix]. c_str(), osURI.c_str()); } } } } } for( CPLXMLNode* psIter = psIgnoredXPaths->psChild; psIter != NULL; psIter = psIter->psNext ) { if( psIter->eType == CXT_Element && EQUAL(psIter->pszValue, "XPath") ) { const CPLString& osXPath( CPLGetXMLValue(psIter, "", "") ); if( IsValidXPath(osXPath) ) { m_aosIgnoredXPaths.push_back( osXPath ); const bool bWarnIfIgnoredXPathFound = CPLGetXMLBoolValue( psIter, "warnIfIgnoredXPathFoundInDocInstance", bGlobalWarnIfIgnoredXPathFound ); m_oMapIgnoredXPathToWarn[ osXPath ] = bWarnIfIgnoredXPathFound; } else { CPLError(CE_Warning, CPLE_AppDefined, "XPath syntax %s not supported", osXPath.c_str()); } } } } CPLXMLNode* psXLinkResolutionNode = CPLGetXMLNode( psRoot, "=Configuration.XLinkResolution"); if( psXLinkResolutionNode != NULL ) m_oXLinkResolution.LoadFromXML( psXLinkResolutionNode ); Finalize(); return true; }
GDALDataset *ISCEDataset::Open( GDALOpenInfo *poOpenInfo ) { /* -------------------------------------------------------------------- */ /* Confirm that the header is compatible with a ISCE dataset. */ /* -------------------------------------------------------------------- */ if ( !Identify(poOpenInfo) ) { return NULL; } /* -------------------------------------------------------------------- */ /* Open and parse the .xml file */ /* -------------------------------------------------------------------- */ const CPLString osXMLFilename = getXMLFilename( poOpenInfo ); CPLXMLNode *psNode = CPLParseXMLFile( osXMLFilename ); if ( psNode == NULL || CPLGetXMLNode( psNode, "=imageFile" ) == NULL ) { CPLDestroyXMLNode( psNode ); return NULL; } CPLXMLNode *psCur = CPLGetXMLNode( psNode, "=imageFile" )->psChild; char **papszXmlProps = NULL; while ( psCur != NULL ) { const char *name, *value; if ( strcmp(psCur->pszValue, "property") != 0) { psCur = psCur->psNext; continue; } name = CPLGetXMLValue( psCur, "name", NULL ); value = CPLGetXMLValue( psCur, "value.", NULL ); papszXmlProps = CSLSetNameValue( papszXmlProps, name, value ); psCur = psCur->psNext; } /* TODO: extract <component name=Coordinate[12]> for georeferencing */ CPLDestroyXMLNode( psNode ); /* -------------------------------------------------------------------- */ /* Fetch required fields. */ /* -------------------------------------------------------------------- */ if ( CSLFetchNameValue( papszXmlProps, "WIDTH" ) == NULL || CSLFetchNameValue( papszXmlProps, "LENGTH" ) == NULL || CSLFetchNameValue( papszXmlProps, "NUMBER_BANDS" ) == NULL || CSLFetchNameValue( papszXmlProps, "DATA_TYPE" ) == NULL || CSLFetchNameValue( papszXmlProps, "SCHEME" ) == NULL ) { CSLDestroy( papszXmlProps ); return NULL; } const int nWidth = atoi( CSLFetchNameValue( papszXmlProps, "WIDTH" ) ); const int nFileLength = atoi( CSLFetchNameValue( papszXmlProps, "LENGTH" ) ); /* -------------------------------------------------------------------- */ /* Update byte order info if image specify something. */ /* -------------------------------------------------------------------- */ bool bNativeOrder = true; if ( CSLFetchNameValue( papszXmlProps, "BYTE_ORDER" ) != NULL ) { const char *sByteOrder = CSLFetchNameValue( papszXmlProps, "BYTE_ORDER" ); #ifdef CPL_LSB if ( EQUAL( sByteOrder, "b" ) ) #else if ( EQUAL( sByteOrder, "l" ) ) #endif bNativeOrder = false; } /* -------------------------------------------------------------------- */ /* Create a corresponding GDALDataset. */ /* -------------------------------------------------------------------- */ ISCEDataset *poDS = new ISCEDataset(); poDS->nRasterXSize = nWidth; poDS->nRasterYSize = nFileLength; poDS->eAccess = poOpenInfo->eAccess; poDS->pszXMLFilename = CPLStrdup( osXMLFilename.c_str() ); /* -------------------------------------------------------------------- */ /* Reopen file in update mode if necessary. */ /* -------------------------------------------------------------------- */ if( poOpenInfo->eAccess == GA_Update ) { poDS->fpImage = VSIFOpenL( poOpenInfo->pszFilename, "rb+" ); } else { poDS->fpImage = VSIFOpenL( poOpenInfo->pszFilename, "rb" ); } if( poDS->fpImage == NULL ) { CSLDestroy( papszXmlProps ); delete poDS; CPLError( CE_Failure, CPLE_OpenFailed, "Failed to re-open %s within ISCE driver.\n", poOpenInfo->pszFilename ); return NULL; } /* -------------------------------------------------------------------- */ /* Create band information objects. */ /* -------------------------------------------------------------------- */ const char *sDataType = CSLFetchNameValue( (char **)apszISCE2GDALDatatypes, CSLFetchNameValue( papszXmlProps, "DATA_TYPE" ) ); const GDALDataType eDataType = GDALGetDataTypeByName( sDataType ); const int nBands = atoi( CSLFetchNameValue( papszXmlProps, "NUMBER_BANDS" ) ); const char *sScheme = CSLFetchNameValue( papszXmlProps, "SCHEME" ); int nPixelOffset, nLineOffset, nBandOffset; if ( EQUAL( sScheme, "BIL" ) ) { poDS->eScheme = BIL; nPixelOffset = GDALGetDataTypeSize(eDataType)/8; nLineOffset = nPixelOffset * nWidth * nBands; nBandOffset = GDALGetDataTypeSize(eDataType)/8 * nWidth; } else if ( EQUAL( sScheme, "BIP" ) ) { poDS->eScheme = BIP; nPixelOffset = GDALGetDataTypeSize(eDataType)/8 * nBands; nLineOffset = nPixelOffset * nWidth; if( nBands > 1 ) { // GDAL 2.1.0 had a value of nLineOffset that was equal to the theoretical // nLineOffset multiplied by nBands... VSIFSeekL( poDS->fpImage, 0, SEEK_END ); const GUIntBig nWrongFileSize = GDALGetDataTypeSizeBytes(eDataType) * nWidth * (static_cast<GUIntBig>(nFileLength - 1) * nBands * nBands + nBands); if( VSIFTellL( poDS->fpImage ) == nWrongFileSize ) { CPLError(CE_Warning, CPLE_AppDefined, "This file has been incorrectly generated by an older " "GDAL version whose line offset computation was erroneous. " "Taking that into account, but the file should be re-encoded ideally"); nLineOffset = nLineOffset * nBands; } } nBandOffset = GDALGetDataTypeSize(eDataType)/8; } else if ( EQUAL( sScheme, "BSQ" ) ) { poDS->eScheme = BSQ; nPixelOffset = GDALGetDataTypeSize(eDataType)/8; nLineOffset = nPixelOffset * nWidth; nBandOffset = nLineOffset * nFileLength; } else { CSLDestroy( papszXmlProps ); delete poDS; CPLError( CE_Failure, CPLE_OpenFailed, "Unknown scheme \"%s\" within ISCE raster.\n", CSLFetchNameValue( papszXmlProps, "SCHEME" ) ); return NULL; } poDS->nBands = nBands; for (int b = 0; b < nBands; b++) { poDS->SetBand( b + 1, new ISCERasterBand( poDS, b + 1, poDS->fpImage, nBandOffset * b, nPixelOffset, nLineOffset, eDataType, TRUE, bNativeOrder, FALSE ) ); } /* -------------------------------------------------------------------- */ /* Interpret georeferencing, if present. */ /* -------------------------------------------------------------------- */ /* TODO */ /* -------------------------------------------------------------------- */ /* Set all the other header metadata into the ISCE domain */ /* -------------------------------------------------------------------- */ for (int i = 0; papszXmlProps != NULL && papszXmlProps[i] != NULL; i++) { char **papszTokens; papszTokens = CSLTokenizeString2( papszXmlProps[i], "=", CSLT_STRIPLEADSPACES | CSLT_STRIPENDSPACES); if ( strcmp( papszTokens[0], "WIDTH" ) == 0 || strcmp( papszTokens[0], "LENGTH" ) == 0 || strcmp( papszTokens[0], "NUMBER_BANDS" ) == 0 || strcmp( papszTokens[0], "DATA_TYPE" ) == 0 || strcmp( papszTokens[0], "SCHEME" ) == 0 ) { CSLDestroy( papszTokens ); continue; } poDS->SetMetadataItem(papszTokens[0], papszTokens[1], "ISCE"); CSLDestroy( papszTokens ); } /* -------------------------------------------------------------------- */ /* Free papszXmlProps */ /* -------------------------------------------------------------------- */ CSLDestroy( papszXmlProps ); /* -------------------------------------------------------------------- */ /* Initialize any PAM information. */ /* -------------------------------------------------------------------- */ poDS->SetDescription( poOpenInfo->pszFilename ); poDS->TryLoadXML(); /* -------------------------------------------------------------------- */ /* Check for overviews. */ /* -------------------------------------------------------------------- */ poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename ); return( poDS ); }
/** * LoadMetadata() */ void GDALMDReaderDigitalGlobe::LoadMetadata() { if(m_bIsMetadataLoad) return; if (!m_osIMDSourceFilename.empty()) { m_papszIMDMD = GDALLoadIMDFile( m_osIMDSourceFilename ); } if(!m_osRPBSourceFilename.empty()) { m_papszRPCMD = GDALLoadRPBFile( m_osRPBSourceFilename ); } if((NULL == m_papszIMDMD || NULL == m_papszRPCMD) && !m_osXMLSourceFilename.empty()) { CPLXMLNode* psNode = CPLParseXMLFile(m_osXMLSourceFilename); if(psNode != NULL) { CPLXMLNode* psisdNode = psNode->psNext; if(psisdNode != NULL) { if( m_papszIMDMD == NULL ) m_papszIMDMD = LoadIMDXmlNode( CPLSearchXMLNode(psisdNode, "IMD") ); if( m_papszRPCMD == NULL ) m_papszRPCMD = LoadRPBXmlNode( CPLSearchXMLNode(psisdNode, "RPB") ); } CPLDestroyXMLNode(psNode); } } m_papszDEFAULTMD = CSLAddNameValue(m_papszDEFAULTMD, MD_NAME_MDTYPE, "DG"); m_bIsMetadataLoad = true; if(NULL == m_papszIMDMD) { return; } //extract imagery metadata const char* pszSatId = CSLFetchNameValue(m_papszIMDMD, "IMAGE.SATID"); if(NULL != pszSatId) { m_papszIMAGERYMD = CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_SATELLITE, CPLStripQuotes(pszSatId)); } else { pszSatId = CSLFetchNameValue(m_papszIMDMD, "IMAGE_1.SATID"); if(NULL != pszSatId) { m_papszIMAGERYMD = CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_SATELLITE, CPLStripQuotes(pszSatId)); } } const char* pszCloudCover = CSLFetchNameValue(m_papszIMDMD, "IMAGE.CLOUDCOVER"); if(NULL != pszCloudCover) { double fCC = CPLAtofM(pszCloudCover); if(fCC < 0) { m_papszIMAGERYMD = CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_CLOUDCOVER, MD_CLOUDCOVER_NA); } else { m_papszIMAGERYMD = CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_CLOUDCOVER, CPLSPrintf("%d", int(fCC * 100))); } } else { pszCloudCover = CSLFetchNameValue(m_papszIMDMD, "IMAGE_1.cloudCover"); if(NULL != pszCloudCover) { double fCC = CPLAtofM(pszCloudCover); if(fCC < 0) { m_papszIMAGERYMD = CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_CLOUDCOVER, MD_CLOUDCOVER_NA); } else { m_papszIMAGERYMD = CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_CLOUDCOVER, CPLSPrintf("%d", int(fCC * 100))); } } } const char* pszDateTime = CSLFetchNameValue(m_papszIMDMD, "IMAGE.FIRSTLINETIME"); if(NULL != pszDateTime) { time_t timeStart = GetAcquisitionTimeFromString(pszDateTime); char szMidDateTime[80]; strftime (szMidDateTime, 80, MD_DATETIMEFORMAT, localtime(&timeStart)); m_papszIMAGERYMD = CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_ACQDATETIME, szMidDateTime); } else { pszDateTime = CSLFetchNameValue(m_papszIMDMD, "IMAGE_1.firstLineTime"); if(NULL != pszDateTime) { time_t timeStart = GetAcquisitionTimeFromString(pszDateTime); char szMidDateTime[80]; strftime (szMidDateTime, 80, MD_DATETIMEFORMAT, localtime(&timeStart)); m_papszIMAGERYMD = CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_ACQDATETIME, szMidDateTime); } } }
/** * LoadMetadata() */ void GDALMDReaderSpot::LoadMetadata() { if(m_bIsMetadataLoad) return; if (!m_osIMDSourceFilename.empty()) { CPLXMLNode* psNode = CPLParseXMLFile(m_osIMDSourceFilename); if(psNode != NULL) { CPLXMLNode* psisdNode = CPLSearchXMLNode(psNode, "=Dimap_Document"); if(psisdNode != NULL) { m_papszIMDMD = ReadXMLToList(psisdNode->psChild, m_papszIMDMD); } CPLDestroyXMLNode(psNode); } } m_papszDEFAULTMD = CSLAddNameValue(m_papszDEFAULTMD, MD_NAME_MDTYPE, "DIMAP"); m_bIsMetadataLoad = true; if(NULL == m_papszIMDMD) { return; } //extract imagery metadata int nCounter = -1; const char* pszSatId1 = CSLFetchNameValue(m_papszIMDMD, "Dataset_Sources.Source_Information.Scene_Source.MISSION"); if(NULL == pszSatId1) { nCounter = 1; for(int i = 0; i < 5; i++) { pszSatId1 = CSLFetchNameValue(m_papszIMDMD, CPLSPrintf("Dataset_Sources.Source_Information_%d.Scene_Source.MISSION", nCounter)); if(NULL != pszSatId1) break; nCounter++; } } const char* pszSatId2; if(nCounter == -1) pszSatId2 = CSLFetchNameValue(m_papszIMDMD, "Dataset_Sources.Source_Information.Scene_Source.MISSION_INDEX"); else pszSatId2 = CSLFetchNameValue(m_papszIMDMD, CPLSPrintf( "Dataset_Sources.Source_Information_%d.Scene_Source.MISSION_INDEX", nCounter)); if(NULL != pszSatId1 && NULL != pszSatId2) { m_papszIMAGERYMD = CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_SATELLITE, CPLSPrintf( "%s %s", CPLStripQuotes(pszSatId1).c_str(), CPLStripQuotes(pszSatId2).c_str())); } else if(NULL != pszSatId1 && NULL == pszSatId2) { m_papszIMAGERYMD = CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_SATELLITE, CPLStripQuotes(pszSatId1)); } else if(NULL == pszSatId1 && NULL != pszSatId2) { m_papszIMAGERYMD = CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_SATELLITE, CPLStripQuotes(pszSatId2)); } const char* pszDate; if(nCounter == -1) pszDate = CSLFetchNameValue(m_papszIMDMD, "Dataset_Sources.Source_Information.Scene_Source.IMAGING_DATE"); else pszDate = CSLFetchNameValue(m_papszIMDMD, CPLSPrintf( "Dataset_Sources.Source_Information_%d.Scene_Source.IMAGING_DATE", nCounter)); if(NULL != pszDate) { const char* pszTime; if(nCounter == -1) pszTime = CSLFetchNameValue(m_papszIMDMD, "Dataset_Sources.Source_Information.Scene_Source.IMAGING_TIME"); else pszTime = CSLFetchNameValue(m_papszIMDMD, CPLSPrintf( "Dataset_Sources.Source_Information_%d.Scene_Source.IMAGING_TIME", nCounter)); if(NULL == pszTime) pszTime = "00:00:00.0Z"; char buffer[80]; time_t timeMid = GetAcquisitionTimeFromString(CPLSPrintf( "%sT%s", pszDate, pszTime)); strftime (buffer, 80, MD_DATETIMEFORMAT, localtime(&timeMid)); m_papszIMAGERYMD = CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_ACQDATETIME, buffer); } m_papszIMAGERYMD = CSLAddNameValue(m_papszIMAGERYMD, MD_NAME_CLOUDCOVER, MD_CLOUDCOVER_NA); }
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; }
bool TSXDataset::getGCPsFromGEOREF_XML(char *pszGeorefFilename) { //open GEOREF.xml CPLXMLNode *psGeorefData = CPLParseXMLFile( pszGeorefFilename ); if (psGeorefData==NULL) return false; //get the ellipsoid and semi-major, semi-minor axes OGRSpatialReference osr; CPLXMLNode *psSphere = CPLGetXMLNode( psGeorefData, "=geoReference.referenceFrames.sphere" ); if (psSphere!=NULL) { const char *pszEllipsoidName = CPLGetXMLValue( psSphere, "ellipsoidID", "" ); const double minor_axis = CPLAtof(CPLGetXMLValue( psSphere, "semiMinorAxis", "0.0" )); const double major_axis = CPLAtof(CPLGetXMLValue( psSphere, "semiMajorAxis", "0.0" )); //save datum parameters to the spatial reference 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"); osr.SetWellKnownGeogCS( "WGS84" ); } else if ( EQUAL( pszEllipsoidName, "WGS84" ) ) { osr.SetWellKnownGeogCS( "WGS84" ); } else { const double inv_flattening = major_axis/(major_axis - minor_axis); osr.SetGeogCS( "","",pszEllipsoidName, major_axis, inv_flattening); } } //get gcps CPLXMLNode *psGeolocationGrid = CPLGetXMLNode( psGeorefData, "=geoReference.geolocationGrid" ); if (psGeolocationGrid==NULL) { CPLDestroyXMLNode( psGeorefData ); return false; } nGCPCount = atoi(CPLGetXMLValue( psGeolocationGrid, "numberOfGridPoints.total", "0" )); //count the gcps if the given count value is invalid CPLXMLNode *psNode; if (nGCPCount<=0) { for( psNode = psGeolocationGrid->psChild; psNode != NULL; psNode = psNode->psNext ) if( EQUAL(psNode->pszValue,"gridPoint") ) nGCPCount++ ; } //if there are no gcps, fail if(nGCPCount<=0) { CPLDestroyXMLNode( psGeorefData ); return false; } //put some reasonable limits of the number of gcps if (nGCPCount>MAX_GCPS ) nGCPCount=MAX_GCPS; //allocate memory for the gcps pasGCPList = reinterpret_cast<GDAL_GCP *>( CPLCalloc(sizeof(GDAL_GCP), nGCPCount) ); //loop through all gcps and set info //save the number allocated to ensure it does not run off the end of the array const int gcps_allocated = nGCPCount; nGCPCount=0; //reset to zero and count //do a check on the grid point to make sure it has lat,long row, and column //it seems that only SSC products contain row, col - how to map lat long otherwise?? //for now fail if row and col are not present - just check the first and assume the rest are the same for( psNode = psGeolocationGrid->psChild; psNode != NULL; psNode = psNode->psNext ) { if( !EQUAL(psNode->pszValue,"gridPoint") ) continue; if ( !strcmp(CPLGetXMLValue(psNode,"col","error"), "error") || !strcmp(CPLGetXMLValue(psNode,"row","error"), "error") || !strcmp(CPLGetXMLValue(psNode,"lon","error"), "error") || !strcmp(CPLGetXMLValue(psNode,"lat","error"), "error")) { CPLDestroyXMLNode( psGeorefData ); return false; } } for( psNode = psGeolocationGrid->psChild; psNode != NULL; psNode = psNode->psNext ) { //break out if the end of the array has been reached if (nGCPCount >= gcps_allocated) { CPLError(CE_Warning, CPLE_AppDefined, "GDAL TSX driver: Truncating the number of GCPs."); break; } GDAL_GCP *psGCP = pasGCPList + nGCPCount; if( !EQUAL(psNode->pszValue,"gridPoint") ) continue; nGCPCount++ ; char szID[32]; snprintf( szID, sizeof(szID), "%d", nGCPCount ); psGCP->pszId = CPLStrdup( szID ); psGCP->pszInfo = CPLStrdup(""); psGCP->dfGCPPixel = CPLAtof(CPLGetXMLValue(psNode,"col","0")); psGCP->dfGCPLine = CPLAtof(CPLGetXMLValue(psNode,"row","0")); psGCP->dfGCPX = CPLAtof(CPLGetXMLValue(psNode,"lon","")); psGCP->dfGCPY = CPLAtof(CPLGetXMLValue(psNode,"lat","")); //looks like height is in meters - should it be converted so xyz are all on the same scale?? psGCP->dfGCPZ = 0; //CPLAtof(CPLGetXMLValue(psNode,"height","")); } CPLFree(pszGCPProjection); osr.exportToWkt( &(pszGCPProjection) ); CPLDestroyXMLNode( psGeorefData ); return true; }
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; }
int GMLParseXSD( const char *pszFile, std::vector<GMLFeatureClass*> & aosClasses) { if( pszFile == NULL ) return FALSE; /* -------------------------------------------------------------------- */ /* Load the raw XML file. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psXSDTree = CPLParseXMLFile( pszFile ); if( psXSDTree == NULL ) return FALSE; /* -------------------------------------------------------------------- */ /* Strip off any namespace qualifiers. */ /* -------------------------------------------------------------------- */ CPLStripXMLNamespace( psXSDTree, NULL, TRUE ); /* -------------------------------------------------------------------- */ /* Find <schema> root element. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psSchemaNode = CPLGetXMLNode( psXSDTree, "=schema" ); if( psSchemaNode == NULL ) { CPLDestroyXMLNode( psXSDTree ); return FALSE; } /* ==================================================================== */ /* Process each feature class definition. */ /* ==================================================================== */ CPLXMLNode *psThis; for( psThis = psSchemaNode->psChild; psThis != NULL; psThis = psThis->psNext ) { /* -------------------------------------------------------------------- */ /* Check for <xs:element> node. */ /* -------------------------------------------------------------------- */ if( psThis->eType != CXT_Element || !EQUAL(psThis->pszValue,"element") ) continue; /* -------------------------------------------------------------------- */ /* Check the substitution group. */ /* -------------------------------------------------------------------- */ const char *pszSubGroup = StripNS(CPLGetXMLValue(psThis,"substitutionGroup","")); // Old OGR produced elements for the feature collection. if( EQUAL(pszSubGroup, "_FeatureCollection") ) continue; if( !EQUAL(pszSubGroup, "_Feature") && !EQUAL(pszSubGroup, "AbstractFeature") /* AbstractFeature used by GML 3.2 */ ) { continue; } /* -------------------------------------------------------------------- */ /* Get name */ /* -------------------------------------------------------------------- */ const char *pszName; pszName = CPLGetXMLValue( psThis, "name", NULL ); if( pszName == NULL ) { continue; } /* -------------------------------------------------------------------- */ /* Get type and verify relationship with name. */ /* -------------------------------------------------------------------- */ const char *pszType; pszType = CPLGetXMLValue( psThis, "type", NULL ); if (pszType == NULL) { CPLXMLNode *psComplexType = CPLGetXMLNode( psThis, "complexType" ); if (psComplexType) { GMLFeatureClass* poClass = GMLParseFeatureType(psSchemaNode, pszName, psComplexType); if (poClass) aosClasses.push_back(poClass); } continue; } if( strstr( pszType, ":" ) != NULL ) pszType = strstr( pszType, ":" ) + 1; if( EQUAL(pszType, pszName) ) { /* A few WFS servers return a type name which is the element name */ /* without any _Type or Type suffix */ /* e.g. : http://apollo.erdas.com/erdas-apollo/vector/Cherokee?SERVICE=WFS&VERSION=1.0.0&REQUEST=DescribeFeatureType&TYPENAME=iwfs:Air */ } else if( !EQUALN(pszType,pszName,strlen(pszName)) || !(EQUAL(pszType+strlen(pszName),"_Type") || EQUAL(pszType+strlen(pszName),"Type")) ) { continue; } /* CanVec .xsd contains weird types that are not used in the related GML */ if (strncmp(pszName, "XyZz", 4) == 0 || strncmp(pszName, "XyZ1", 4) == 0 || strncmp(pszName, "XyZ2", 4) == 0) continue; GMLFeatureClass* poClass = GMLParseFeatureType(psSchemaNode, pszName, pszType); if (poClass) aosClasses.push_back(poClass); } CPLDestroyXMLNode( psXSDTree ); if( aosClasses.size() > 0 ) { return TRUE; } else return FALSE; }
CPLErr GDALPamDataset::TrySaveXML() { CPLXMLNode *psTree; CPLErr eErr = CE_None; nPamFlags &= ~GPF_DIRTY; if( psPam == NULL || (nPamFlags & GPF_NOSAVE) ) return CE_None; /* -------------------------------------------------------------------- */ /* Make sure we know the filename we want to store in. */ /* -------------------------------------------------------------------- */ if( !BuildPamFilename() ) return CE_None; /* -------------------------------------------------------------------- */ /* Build the XML representation of the auxilary metadata. */ /* -------------------------------------------------------------------- */ CPLString osVRTPath = CPLGetPath(psPam->pszPamFilename); psTree = SerializeToXML( osVRTPath ); if( psTree == NULL ) return CE_None; /* -------------------------------------------------------------------- */ /* If we are working with a subdataset, we need to integrate */ /* the subdataset tree within the whole existing pam tree, */ /* after removing any old version of the same subdataset. */ /* -------------------------------------------------------------------- */ if( psPam->osSubdatasetName.size() != 0 ) { CPLXMLNode *psOldTree, *psSubTree; CPLErrorReset(); CPLPushErrorHandler( CPLQuietErrorHandler ); psOldTree = CPLParseXMLFile( psPam->pszPamFilename ); CPLPopErrorHandler(); if( psOldTree == NULL ) psOldTree = CPLCreateXMLNode( NULL, CXT_Element, "PAMDataset" ); for( psSubTree = psTree->psChild; psSubTree != NULL; psSubTree = psSubTree->psNext ) { if( psSubTree->eType != CXT_Element || !EQUAL(psSubTree->pszValue,"Subdataset") ) continue; if( !EQUAL(CPLGetXMLValue( psSubTree, "name", "" ), psPam->osSubdatasetName) ) continue; break; } if( psSubTree == NULL ) { psSubTree = CPLCreateXMLNode( psOldTree, CXT_Element, "Subdataset" ); CPLCreateXMLNode( CPLCreateXMLNode( psSubTree, CXT_Attribute, "name" ), CXT_Text, psPam->osSubdatasetName ); } CPLXMLNode *psOldPamDataset = CPLGetXMLNode( psSubTree, "PAMDataset"); if( psOldPamDataset != NULL ) { CPLRemoveXMLChild( psSubTree, psOldPamDataset ); CPLDestroyXMLNode( psOldPamDataset ); } CPLAddXMLChild( psSubTree, psTree ); psTree = psOldTree; } /* -------------------------------------------------------------------- */ /* Try saving the auxilary metadata. */ /* -------------------------------------------------------------------- */ const char *pszNewPam; int bSaved; CPLPushErrorHandler( CPLQuietErrorHandler ); bSaved = CPLSerializeXMLTreeToFile( psTree, psPam->pszPamFilename ); CPLPopErrorHandler(); /* -------------------------------------------------------------------- */ /* If it fails, check if we have a proxy directory for auxilary */ /* metadata to be stored in, and try to save there. */ /* -------------------------------------------------------------------- */ if( bSaved ) eErr = CE_None; else if( PamGetProxy(GetDescription()) == NULL && ((pszNewPam = PamAllocateProxy(GetDescription())) != NULL)) { CPLErrorReset(); CPLFree( psPam->pszPamFilename ); psPam->pszPamFilename = CPLStrdup(pszNewPam); eErr = TrySaveXML(); } else { CPLError( CE_Warning, CPLE_AppDefined, "Unable to save auxilary information in %s.", psPam->pszPamFilename ); eErr = CE_Warning; } /* -------------------------------------------------------------------- */ /* Cleanup */ /* -------------------------------------------------------------------- */ CPLDestroyXMLNode( psTree ); return eErr; }
GvSymbolObj * gv_symbol_manager_get_symbol(GvSymbolManager *manager, const char *symbol_name) { gchar *pszOpenEVHome = NULL; gchar *pszSymbolsDir = NULL; gchar *pszAbsolutePath = NULL; gchar *pszPathSeparator = NULL; GDALDatasetH hDataset; GvSymbolObj *poSymbol; CPLXMLNode *xml_shape = NULL; GByte *rgba_buffer; /* -------------------------------------------------------------------- */ /* Lookup the symbol in the hash table, and return it if found. */ /* -------------------------------------------------------------------- */ poSymbol = g_hash_table_lookup( manager->symbol_cache, symbol_name ); if( poSymbol != NULL ) return poSymbol; /* -------------------------------------------------------------------- */ /* We didn't already have it, so try to find a file to load it */ /* from. */ /* -------------------------------------------------------------------- */ #ifndef WIN32 pszPathSeparator = "/"; #else pszPathSeparator = "\\"; #endif /* WIN32 */ /* validate inputs */ g_return_val_if_fail( manager != NULL, 0 ); g_return_val_if_fail( symbol_name != NULL, 0 ); /* get an absolute path */ if ( !g_path_is_absolute( symbol_name ) ) { /* check configuration option first */ pszSymbolsDir = g_strdup( gv_manager_get_preference( gv_get_manager(), "symbols_dir" ) ); /* if not configured check $OPENEV_HOME */ if ( !pszSymbolsDir ) { pszOpenEVHome = g_getenv( "OPENEV_HOME" ); if( pszOpenEVHome == NULL ) pszOpenEVHome = g_getenv( "OPENEVHOME" ); if ( pszOpenEVHome ) pszSymbolsDir = g_strjoin( pszPathSeparator, pszOpenEVHome, "symbols", NULL ); } /* get current directory as last resort */ if ( !pszSymbolsDir ) pszSymbolsDir = g_get_current_dir(); pszAbsolutePath = g_strjoin( pszPathSeparator, pszSymbolsDir, symbol_name, NULL ); g_free( pszSymbolsDir ); } else pszAbsolutePath = g_strdup( symbol_name ); /* -------------------------------------------------------------------- */ /* pszAbsolutePath contains a newly allocated string that is */ /* suitable for using as a key in the hash table. If a texture */ /* is found in the hash table then this string needs to be */ /* freed. If one isn't found then the string is used in the */ /* hash table and should be freed when the associated hash */ /* table entry is released */ /* -------------------------------------------------------------------- */ CPLDebug( "OpenEV", "gv_symbol_manager_get_symbol(%s) ... need to load.", pszAbsolutePath ); /* * validate path by opening with GDAL and looking for an error * Disable CPL error handler to supress error reporting */ CPLErrorReset(); CPLPushErrorHandler( CPLQuietErrorHandler ); hDataset = GDALOpen( pszAbsolutePath, GA_ReadOnly ); CPLPopErrorHandler(); if ( hDataset ) { rgba_buffer = gdal_to_rgba( hDataset ); if ( rgba_buffer ) { gv_symbol_manager_inject_raster_symbol( manager, symbol_name, GDALGetRasterXSize( hDataset ), GDALGetRasterYSize( hDataset ), rgba_buffer ); CPLFree( rgba_buffer ); } GDALClose( hDataset ); } /* probably we have vector symbol? */ else if ( ( xml_shape = CPLParseXMLFile( pszAbsolutePath ) ) ) { GvShape *shape; shape = gv_shape_from_xml_tree( xml_shape ); CPLDestroyXMLNode( xml_shape ); if( shape != NULL ) gv_symbol_manager_inject_vector_symbol( manager, symbol_name, shape ); else { CPLDebug( "OpenEV", "Failed to instantiate GvSahpe from file %s, using simple point.", pszAbsolutePath ); shape = gv_shape_new( GVSHAPE_POINT ); gv_symbol_manager_inject_vector_symbol( manager, symbol_name, shape ); } } else { GvShape *shape; CPLDebug( "OpenEV", "Failed to open file %s, using simple point.", pszAbsolutePath ); shape = gv_shape_new( GVSHAPE_POINT ); gv_symbol_manager_inject_vector_symbol( manager, symbol_name, shape ); } /* look up in the hash table again */ poSymbol = g_hash_table_lookup(manager->symbol_cache, symbol_name ); g_free( pszAbsolutePath ); return poSymbol; }
static CPLXMLNode *FindTreeByURL( CPLXMLNode *** ppapsRoot, char *** ppapszResourceHREF, const char *pszURL ) { if( *ppapsRoot == NULL || ppapszResourceHREF == NULL ) return NULL; //if found in ppapszResourceHREF int i, nItems; char *pszLocation; if( ( i = CSLFindString( *ppapszResourceHREF, pszURL )) >= 0 ) { //return corresponding psRoot return (*ppapsRoot)[i]; } else { CPLXMLNode *psSrcTree = NULL, *psSibling; pszLocation = CPLStrdup( pszURL ); //if it is part of filesystem if( CPLCheckForFile( pszLocation, NULL) ) {//filesystem psSrcTree = CPLParseXMLFile( pszURL ); } else if( CPLHTTPEnabled() ) {//web resource CPLErrorReset(); CPLHTTPResult *psResult = CPLHTTPFetch( pszURL, NULL ); if( psResult != NULL ) { if( psResult->nDataLen > 0 && CPLGetLastErrorNo() == 0) psSrcTree = CPLParseXMLString( (const char*)psResult->pabyData ); CPLHTTPDestroyResult( psResult ); } } //report error in case the resource cannot be retrieved. if( psSrcTree == NULL ) CPLError( CE_Failure, CPLE_NotSupported, "Could not access %s", pszLocation ); CPLFree( pszLocation ); /************************************************************************/ /* In the external GML resource we will only need elements */ /* identified by a "gml:id". So trim them. */ /************************************************************************/ psSibling = psSrcTree; while( psSibling != NULL ) { TrimTree( psSibling ); psSibling = psSibling->psNext; } //update to lists nItems = CSLCount(*ppapszResourceHREF); *ppapszResourceHREF = CSLAddString( *ppapszResourceHREF, pszURL ); *ppapsRoot = (CPLXMLNode**)CPLRealloc(*ppapsRoot, (nItems+2)*sizeof(CPLXMLNode*)); (*ppapsRoot)[nItems] = psSrcTree; (*ppapsRoot)[nItems+1] = NULL; //return the tree return (*ppapsRoot)[nItems]; } }