CPLXMLNode *WCTSCollectRequest() { if( getenv("REQUEST_METHOD") == NULL ) WCTSEmitServiceException( "REQUEST_METHOD not set." ); if( EQUAL(getenv("REQUEST_METHOD"),"GET") ) return WCTSCollectKVPRequest(); /* -------------------------------------------------------------------- */ /* Read the body of the POST message into a buffer. */ /* -------------------------------------------------------------------- */ int nContentLength = 0; char *pszXML = NULL; if( getenv("CONTENT_LENGTH") != NULL ) { nContentLength = atoi(getenv("CONTENT_LENGTH")); pszXML = (char *) CPLMalloc(nContentLength+1); if( (int) fread(pszXML, 1, nContentLength, stdin) < nContentLength ) WCTSEmitServiceException( "POST body is short." ); pszXML[nContentLength] = '\0'; } else { int nXMLMax, nXMLLen=0; nXMLMax = 100; pszXML = (char *) CPLMalloc(nXMLMax); while( !feof(stdin) ) { pszXML[nXMLLen++] = fgetc(stdin); if( nXMLLen == nXMLMax ) { nXMLMax = nXMLMax * 2; pszXML = (char *) CPLRealloc(pszXML, nXMLMax); } } pszXML[nXMLLen] = '\0'; } /* -------------------------------------------------------------------- */ /* Convert into an XML document. */ /* -------------------------------------------------------------------- */ CPLErrorReset(); CPLXMLNode *psTree = CPLParseXMLString( pszXML ); CPLFree( pszXML ); if( CPLGetLastErrorType() == CE_Failure ) WCTSEmitServiceException( CPLGetLastErrorMsg() ); return psTree; }
OGRGeometryH OGR_G_CreateFromGML( const char *pszGML ) { if( pszGML == NULL || strlen(pszGML) == 0 ) { CPLError( CE_Failure, CPLE_AppDefined, "GML Geometry is empty in GML2OGRGeometry()." ); return NULL; } /* -------------------------------------------------------------------- */ /* Try to parse the XML snippet using the MiniXML API. If this */ /* fails, we assume the minixml api has already posted a CPL */ /* error, and just return NULL. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psGML = CPLParseXMLString( pszGML ); if( psGML == NULL ) return NULL; /* -------------------------------------------------------------------- */ /* Convert geometry recursively. */ /* -------------------------------------------------------------------- */ OGRGeometry *poGeometry; poGeometry = GML2OGRGeometry_XMLNode( psGML ); CPLDestroyXMLNode( psGML ); return (OGRGeometryH) poGeometry; }
int OGRFMECacheIndex::Load() { /* -------------------------------------------------------------------- */ /* Lock the cache index file if not already locked. */ /* -------------------------------------------------------------------- */ if( hLock == NULL && !Lock() ) return FALSE; if( psTree != NULL ) { CPLDestroyXMLNode( psTree ); psTree = NULL; } /* -------------------------------------------------------------------- */ /* Open the index file. If we don't get it, we assume it is */ /* because it doesn't exist, and we create a "stub" tree in */ /* memory. */ /* -------------------------------------------------------------------- */ FILE *fpIndex; int nLength; char *pszIndexBuffer; fpIndex = VSIFOpen( GetPath(), "rb" ); if( fpIndex == NULL ) { psTree = CPLCreateXMLNode( NULL, CXT_Element, "OGRFMECacheIndex" ); return TRUE; } /* -------------------------------------------------------------------- */ /* Load the data from the file. */ /* -------------------------------------------------------------------- */ VSIFSeek( fpIndex, 0, SEEK_END ); nLength = VSIFTell( fpIndex ); VSIFSeek( fpIndex, 0, SEEK_SET ); pszIndexBuffer = (char *) CPLMalloc(nLength+1); if( (int) VSIFRead( pszIndexBuffer, 1, nLength, fpIndex ) != nLength ) { CPLError( CE_Failure, CPLE_FileIO, "Read of %d byte index file failed.", nLength ); return FALSE; } VSIFClose( fpIndex ); /* -------------------------------------------------------------------- */ /* Parse the result into an inmemory XML tree. */ /* -------------------------------------------------------------------- */ pszIndexBuffer[nLength] = '\0'; psTree = CPLParseXMLString( pszIndexBuffer ); CPLFree( pszIndexBuffer ); return psTree != NULL; }
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; }
CPLXMLNode *OGR_G_ExportToKMLTree( OGRGeometryH hGeometry ) { // TODO - mloskot: If passed geometry is null the pszText is non-null, // so the condition below is false. char *pszText = OGR_G_ExportToKML( hGeometry, NULL ); if( pszText == NULL ) return NULL; CPLXMLNode *psTree = CPLParseXMLString( pszText ); CPLFree( pszText ); return psTree; }
CPLXMLNode* GDALGMLJP2GenerateMetadata( const CPLString& osTemplateFile, const CPLString& osSourceFile ) { GByte* pabyStr = nullptr; if( !VSIIngestFile( nullptr, osTemplateFile, &pabyStr, nullptr, -1 ) ) return nullptr; CPLString osTemplate(reinterpret_cast<char *>(pabyStr)); CPLFree(pabyStr); if( !VSIIngestFile( nullptr, osSourceFile, &pabyStr, nullptr, -1 ) ) return nullptr; CPLString osSource(reinterpret_cast<char *>(pabyStr)); CPLFree(pabyStr); xmlDocPtr pDoc = xmlParseDoc( reinterpret_cast<const xmlChar *>(osSource.c_str())); if( pDoc == nullptr ) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot parse %s", osSourceFile.c_str()); return nullptr; } xmlXPathContextPtr pXPathCtx = xmlXPathNewContext(pDoc); if( pXPathCtx == nullptr ) { xmlFreeDoc(pDoc); return nullptr; } xmlXPathRegisterFunc(pXPathCtx, reinterpret_cast<const xmlChar *>("if"), GDALGMLJP2XPathIf); xmlXPathRegisterFunc(pXPathCtx, reinterpret_cast<const xmlChar *>("uuid"), GDALGMLJP2XPathUUID); pXPathCtx->error = GDALGMLJP2XPathErrorHandler; GDALGMLJP2RegisterNamespaces(pXPathCtx, xmlDocGetRootElement(pDoc)); CPLString osXMLRes = GDALGMLJP2EvalExpr(osTemplate, pXPathCtx, pDoc); xmlXPathFreeContext(pXPathCtx); xmlFreeDoc(pDoc); return CPLParseXMLString(osXMLRes); }
CPLXMLNode *OGR_G_ExportToGMLTree( OGRGeometryH hGeometry ) { char *pszText; CPLXMLNode *psTree; pszText = OGR_G_ExportToGML( hGeometry ); if( pszText == NULL ) return NULL; psTree = CPLParseXMLString( pszText ); CPLFree( pszText ); return psTree; }
int main( int argc, char **argv ) { static char szXML[20000000]; FILE *fp; if( argc == 1 ) fp = stdin; else if( argv[1][0] == '-' ) { printf( "Usage: xmlreformat [filename]\n" ); exit( 0 ); } else { fp = fopen( argv[1], "rt" ); if( fp == NULL ) { printf( "Failed to open file %s.\n", argv[1] ); exit( 1 ); } } int nLen = fread( szXML, 1, sizeof(szXML), fp ); if( nLen >= (int) sizeof(szXML)-2 ) { fprintf( stderr, "xmlreformat fixed sized buffer (%d bytes) exceeded.\n", (int) sizeof(szXML) ); exit(1); } if( fp != stdin ) fclose( fp ); szXML[nLen] = '\0'; CPLXMLNode *poTree = CPLParseXMLString( szXML ); if( poTree != NULL ) { char *pszRawXML = CPLSerializeXMLTree( poTree ); printf( "%s", pszRawXML ); CPLFree( pszRawXML ); CPLDestroyXMLNode( poTree ); } return 0; }
CPLErr VRTSourcedRasterBand::SetMetadata( char **papszNewMD, const char *pszDomain ) { if( pszDomain != NULL && (EQUAL(pszDomain,"new_vrt_sources") || EQUAL(pszDomain,"vrt_sources")) ) { VRTDriver *poDriver = (VRTDriver *) GDALGetDriverByName( "VRT" ); CPLErr eErr; int i; if( EQUAL(pszDomain,"vrt_sources") ) { for( int i = 0; i < nSources; i++ ) delete papoSources[i]; CPLFree( papoSources ); papoSources = NULL; nSources = 0; } for( i = 0; i < CSLCount(papszNewMD); i++ ) { const char *pszXML = CPLParseNameValue( papszNewMD[i], NULL ); CPLXMLNode *psTree = CPLParseXMLString( pszXML ); VRTSource *poSource; if( psTree == NULL ) return CE_Failure; poSource = poDriver->ParseSource( psTree, NULL ); CPLDestroyXMLNode( psTree ); if( poSource != NULL ) { eErr = AddSource( poSource ); if( eErr != CE_None ) return eErr; } else return CE_Failure; } return CE_None; } else return VRTRasterBand::SetMetadata( papszNewMD, pszDomain ); }
// ************************************************************ // ParseServerException() // ************************************************************ void BaseProvider::ParseServerException(CString s) { CPLXMLNode* node = CPLParseXMLString(s); if (node) { while (node) { CPLXMLNode* nodeException = CPLGetXMLNode(node, "ServiceException"); if (nodeException) { CString msg = CPLGetXMLValue(nodeException, "", ""); CallbackHelper::ErrorMsg(Debug::Format("WMS Server exception (%s): %s", Name, msg)); } node = node->psNext; } CPLDestroyXMLNode(node); } }
static OGRGeometry* ParseKMLGeometry(const char* pszKML) { CPLXMLNode* psXML = CPLParseXMLString(pszKML); if (psXML == nullptr) return nullptr; if (psXML->eType != CXT_Element) { CPLDestroyXMLNode(psXML); return nullptr; } OGRGeometry* poGeom = ParseKMLGeometry(psXML); CPLDestroyXMLNode(psXML); return poGeom; }
/** * \brief Import coordinate system from XML format (GML only currently). * * This method is the same as the C function OSRImportFromXML() * @param pszXML XML string to import * @return OGRERR_NONE on success or OGRERR_CORRUPT_DATA on failure. */ OGRErr OGRSpatialReference::importFromXML(const char *pszXML) { CPLXMLNode *psTree; OGRErr eErr = OGRERR_UNSUPPORTED_SRS; this->Clear(); /* -------------------------------------------------------------------- */ /* Parse the XML. */ /* -------------------------------------------------------------------- */ psTree = CPLParseXMLString(pszXML); if (psTree == NULL) return OGRERR_CORRUPT_DATA; CPLStripXMLNamespace(psTree, "gml", TRUE); /* -------------------------------------------------------------------- */ /* Import according to the root node type. We walk through */ /* root elements as there is sometimes prefix stuff like */ /* <?xml>. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psNode = psTree; for (psNode = psTree; psNode != NULL; psNode = psNode->psNext) { if (EQUAL(psNode->pszValue, "GeographicCRS")) { eErr = importGeogCSFromXML(this, psNode); break; } else if (EQUAL(psNode->pszValue, "ProjectedCRS")) { eErr = importProjCSFromXML(this, psNode); break; } } CPLDestroyXMLNode(psTree); return eErr; }
int main( int argc, char **argv ) { CPLXMLNode *poTree; static char szXML[10000000]; FILE *fp; int nLen; if( argc == 1 ) fp = stdin; else if( argv[1][0] == '-' ) { printf( "Usage: xmlreformat [filename]\n" ); exit( 0 ); } else { fp = fopen( argv[1], "rt" ); if( fp == NULL ) { printf( "Failed to open file %s.\n", argv[1] ); exit( 1 ); } } nLen = fread( szXML, 1, sizeof(szXML), fp ); if( fp != stdin ) fclose( fp ); szXML[nLen] = '\0'; poTree = CPLParseXMLString( szXML ); if( poTree != NULL ) { char *pszRawXML = CPLSerializeXMLTree( poTree ); printf( "%s", pszRawXML ); CPLFree( pszRawXML ); CPLDestroyXMLNode( poTree ); } return 0; }
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); } }
void GDALJP2AbstractDataset::LoadJP2Metadata(GDALOpenInfo* poOpenInfo, const char* pszOverideFilenameIn) { const char* pszOverideFilename = pszOverideFilenameIn; if( pszOverideFilename == NULL ) pszOverideFilename = poOpenInfo->pszFilename; /* -------------------------------------------------------------------- */ /* Check for georeferencing information. */ /* -------------------------------------------------------------------- */ GDALJP2Metadata oJP2Geo; if( (poOpenInfo->fpL != NULL && pszOverideFilenameIn == NULL && oJP2Geo.ReadAndParse(poOpenInfo->fpL) ) || (!(poOpenInfo->fpL != NULL && pszOverideFilenameIn == NULL) && oJP2Geo.ReadAndParse( pszOverideFilename )) ) { CPLFree(pszProjection); pszProjection = CPLStrdup(oJP2Geo.pszProjection); bGeoTransformValid = oJP2Geo.bHaveGeoTransform; memcpy( adfGeoTransform, oJP2Geo.adfGeoTransform, sizeof(double) * 6 ); nGCPCount = oJP2Geo.nGCPCount; pasGCPList = GDALDuplicateGCPs( oJP2Geo.nGCPCount, oJP2Geo.pasGCPList ); if( oJP2Geo.bPixelIsPoint ) GDALDataset::SetMetadataItem(GDALMD_AREA_OR_POINT, GDALMD_AOP_POINT); if( oJP2Geo.papszRPCMD ) GDALDataset::SetMetadata( oJP2Geo.papszRPCMD, "RPC" ); } /* -------------------------------------------------------------------- */ /* Report XML UUID box in a dedicated metadata domain */ /* -------------------------------------------------------------------- */ if (oJP2Geo.pszXMPMetadata) { char *apszMDList[2]; apszMDList[0] = (char *) oJP2Geo.pszXMPMetadata; apszMDList[1] = NULL; GDALDataset::SetMetadata(apszMDList, "xml:XMP"); } /* -------------------------------------------------------------------- */ /* Do we have any XML boxes we would like to treat as special */ /* domain metadata? (Note: the GDAL multidomain metadata XML box */ /* has been excluded and is dealt a few lines below. */ /* -------------------------------------------------------------------- */ int iBox; for( iBox = 0; oJP2Geo.papszGMLMetadata && oJP2Geo.papszGMLMetadata[iBox] != NULL; iBox++ ) { char *pszName = NULL; const char *pszXML = CPLParseNameValue( oJP2Geo.papszGMLMetadata[iBox], &pszName ); CPLString osDomain; char *apszMDList[2]; osDomain.Printf( "xml:%s", pszName ); apszMDList[0] = (char *) pszXML; apszMDList[1] = NULL; GDALDataset::SetMetadata( apszMDList, osDomain ); CPLFree( pszName ); } /* -------------------------------------------------------------------- */ /* Do we have GDAL metadata? */ /* -------------------------------------------------------------------- */ if( oJP2Geo.pszGDALMultiDomainMetadata != NULL ) { CPLXMLNode* psXMLNode = CPLParseXMLString(oJP2Geo.pszGDALMultiDomainMetadata); if( psXMLNode ) { GDALMultiDomainMetadata oLocalMDMD; oLocalMDMD.XMLInit(psXMLNode, FALSE); char** papszDomainList = oLocalMDMD.GetDomainList(); char** papszIter = papszDomainList; GDALDataset::SetMetadata(oLocalMDMD.GetMetadata()); while( papszIter && *papszIter ) { if( !EQUAL(*papszIter, "") && !EQUAL(*papszIter, "IMAGE_STRUCTURE") ) { if( GDALDataset::GetMetadata(*papszIter) != NULL ) { CPLDebug("GDALJP2", "GDAL metadata overrides metadata in %s domain over metadata read from other boxes", *papszIter); } GDALDataset::SetMetadata(oLocalMDMD.GetMetadata(*papszIter), *papszIter); } papszIter ++; } CPLDestroyXMLNode(psXMLNode); } else CPLErrorReset(); } /* -------------------------------------------------------------------- */ /* Do we have other misc metadata (from resd box for now) ? */ /* -------------------------------------------------------------------- */ if( oJP2Geo.papszMetadata != NULL ) { char **papszMD = CSLDuplicate(GDALDataset::GetMetadata()); papszMD = CSLMerge( papszMD, oJP2Geo.papszMetadata ); GDALDataset::SetMetadata( papszMD ); CSLDestroy( papszMD ); } /* -------------------------------------------------------------------- */ /* Do we have XML IPR ? */ /* -------------------------------------------------------------------- */ if( oJP2Geo.pszXMLIPR != NULL ) { char* apszMD[2] = { NULL, NULL }; apszMD[0] = oJP2Geo.pszXMLIPR; GDALDataset::SetMetadata( apszMD, "xml:IPR" ); } /* -------------------------------------------------------------------- */ /* Check for world file. */ /* -------------------------------------------------------------------- */ if( !bGeoTransformValid ) { bGeoTransformValid |= GDALReadWorldFile2( pszOverideFilename, NULL, adfGeoTransform, poOpenInfo->GetSiblingFiles(), &pszWldFilename ) || GDALReadWorldFile2( pszOverideFilename, ".wld", adfGeoTransform, poOpenInfo->GetSiblingFiles(), &pszWldFilename ); } GDALMDReaderManager mdreadermanager; GDALMDReaderBase* mdreader = mdreadermanager.GetReader(poOpenInfo->pszFilename, poOpenInfo->GetSiblingFiles(), MDR_ANY); if(NULL != mdreader) { mdreader->FillMetadata(&(oMDMD)); papszMetadataFiles = mdreader->GetMetadataFiles(); } }
int GMLReader::LoadClasses( const char *pszFile ) { // Add logic later to determine reasonable default schema file. if( pszFile == NULL ) return FALSE; /* -------------------------------------------------------------------- */ /* Load the raw XML file. */ /* -------------------------------------------------------------------- */ FILE *fp; int nLength; char *pszWholeText; fp = VSIFOpen( pszFile, "rb" ); if( fp == NULL ) { CPLError( CE_Failure, CPLE_OpenFailed, "Failed to open file %s.", pszFile ); return FALSE; } VSIFSeek( fp, 0, SEEK_END ); nLength = VSIFTell( fp ); VSIFSeek( fp, 0, SEEK_SET ); pszWholeText = (char *) VSIMalloc(nLength+1); if( pszWholeText == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "Failed to allocate %d byte buffer for %s,\n" "is this really a GMLFeatureClassList file?", nLength, pszFile ); VSIFClose( fp ); return FALSE; } if( VSIFRead( pszWholeText, nLength, 1, fp ) != 1 ) { VSIFree( pszWholeText ); VSIFClose( fp ); CPLError( CE_Failure, CPLE_AppDefined, "Read failed on %s.", pszFile ); return FALSE; } pszWholeText[nLength] = '\0'; VSIFClose( fp ); if( strstr( pszWholeText, "<GMLFeatureClassList>" ) == NULL ) { VSIFree( pszWholeText ); CPLError( CE_Failure, CPLE_AppDefined, "File %s does not contain a GMLFeatureClassList tree.", pszFile ); return FALSE; } /* -------------------------------------------------------------------- */ /* Convert to XML parse tree. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psRoot; psRoot = CPLParseXMLString( pszWholeText ); VSIFree( pszWholeText ); // We assume parser will report errors via CPL. if( psRoot == NULL ) return FALSE; if( psRoot->eType != CXT_Element || !EQUAL(psRoot->pszValue,"GMLFeatureClassList") ) { CPLDestroyXMLNode(psRoot); CPLError( CE_Failure, CPLE_AppDefined, "File %s is not a GMLFeatureClassList document.", pszFile ); return FALSE; } /* -------------------------------------------------------------------- */ /* Extract feature classes for all definitions found. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psThis; for( psThis = psRoot->psChild; psThis != NULL; psThis = psThis->psNext ) { if( psThis->eType == CXT_Element && EQUAL(psThis->pszValue,"GMLFeatureClass") ) { GMLFeatureClass *poClass; poClass = new GMLFeatureClass(); if( !poClass->InitializeFromXML( psThis ) ) { delete poClass; CPLDestroyXMLNode( psRoot ); return FALSE; } poClass->SetSchemaLocked( TRUE ); AddClass( poClass ); } } CPLDestroyXMLNode( psRoot ); SetClassListLocked( TRUE ); return TRUE; }
CPLErr VRTSourcedRasterBand::SetMetadataItem( const char *pszName, const char *pszValue, const char *pszDomain ) { CPLDebug( "VRT", "VRTSourcedRasterBand::SetMetadataItem(%s,%s,%s)\n", pszName, pszValue, pszDomain ); if( pszDomain != NULL && EQUAL(pszDomain,"new_vrt_sources") ) { VRTDriver *poDriver = (VRTDriver *) GDALGetDriverByName( "VRT" ); CPLXMLNode *psTree = CPLParseXMLString( pszValue ); VRTSource *poSource; if( psTree == NULL ) return CE_Failure; poSource = poDriver->ParseSource( psTree, NULL ); CPLDestroyXMLNode( psTree ); if( poSource != NULL ) return AddSource( poSource ); else return CE_Failure; } else if( pszDomain != NULL && EQUAL(pszDomain,"vrt_sources") ) { int iSource; if (sscanf(pszName, "source_%d", &iSource) != 1 || iSource < 0 || iSource >= nSources) { CPLError(CE_Failure, CPLE_AppDefined, "%s metadata item name is not recognized. " "Should be between source_0 and source_%d", pszName, nSources - 1); return CE_Failure; } VRTDriver *poDriver = (VRTDriver *) GDALGetDriverByName( "VRT" ); CPLXMLNode *psTree = CPLParseXMLString( pszValue ); VRTSource *poSource; if( psTree == NULL ) return CE_Failure; poSource = poDriver->ParseSource( psTree, NULL ); CPLDestroyXMLNode( psTree ); if( poSource != NULL ) { delete papoSources[iSource]; papoSources[iSource] = poSource; ((VRTDataset *)poDS)->SetNeedsFlush(); return CE_None; } else return CE_Failure; } else return VRTRasterBand::SetMetadataItem( pszName, pszValue, pszDomain ); }
void BAGDataset::LoadMetadata() { /* -------------------------------------------------------------------- */ /* Load the metadata from the file. */ /* -------------------------------------------------------------------- */ hid_t hMDDS = H5Dopen( hHDF5, "/BAG_root/metadata" ); hid_t datatype = H5Dget_type( hMDDS ); hid_t dataspace = H5Dget_space( hMDDS ); hid_t native = H5Tget_native_type( datatype, H5T_DIR_ASCEND ); hsize_t dims[3], maxdims[3]; H5Sget_simple_extent_dims( dataspace, dims, maxdims ); pszXMLMetadata = (char *) CPLCalloc(dims[0]+1,1); H5Dread( hMDDS, native, H5S_ALL, dataspace, H5P_DEFAULT, pszXMLMetadata ); H5Sclose( dataspace ); H5Tclose( datatype ); H5Dclose( hMDDS ); if( strlen(pszXMLMetadata) == 0 ) return; /* -------------------------------------------------------------------- */ /* Try to get the geotransform. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psRoot = CPLParseXMLString( pszXMLMetadata ); if( psRoot == NULL ) return; CPLStripXMLNamespace( psRoot, NULL, TRUE ); CPLXMLNode *psGeo = CPLSearchXMLNode( psRoot, "=MD_Georectified" ); if( psGeo != NULL ) { char **papszCornerTokens = CSLTokenizeStringComplex( CPLGetXMLValue( psGeo, "cornerPoints.Point.coordinates", "" ), " ,", FALSE, FALSE ); if( CSLCount(papszCornerTokens ) == 4 ) { double dfLLX = atof( papszCornerTokens[0] ); double dfLLY = atof( papszCornerTokens[1] ); double dfURX = atof( papszCornerTokens[2] ); double dfURY = atof( papszCornerTokens[3] ); adfGeoTransform[0] = dfLLX; adfGeoTransform[1] = (dfURX - dfLLX) / (GetRasterXSize()-1); adfGeoTransform[3] = dfURY; adfGeoTransform[5] = (dfLLY - dfURY) / (GetRasterYSize()-1); adfGeoTransform[0] -= adfGeoTransform[1] * 0.5; adfGeoTransform[3] -= adfGeoTransform[5] * 0.5; } CSLDestroy( papszCornerTokens ); } CPLDestroyXMLNode( psRoot ); /* -------------------------------------------------------------------- */ /* Try to get the coordinate system. */ /* -------------------------------------------------------------------- */ OGRSpatialReference oSRS; if( OGR_SRS_ImportFromISO19115( &oSRS, pszXMLMetadata ) == OGRERR_NONE ) { oSRS.exportToWkt( &pszProjection ); } }
GDALDataset *VRTDataset::OpenXML( const char *pszXML, const char *pszVRTPath, GDALAccess eAccess) { /* -------------------------------------------------------------------- */ /* Parse the XML. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psTree; psTree = CPLParseXMLString( pszXML ); if( psTree == NULL ) return NULL; CPLXMLNode *psRoot = CPLGetXMLNode( psTree, "=VRTDataset" ); if (psRoot == NULL) { CPLError( CE_Failure, CPLE_AppDefined, "Missing VRTDataset element." ); CPLDestroyXMLNode( psTree ); return NULL; } if( CPLGetXMLNode( psRoot, "rasterXSize" ) == NULL || CPLGetXMLNode( psRoot, "rasterYSize" ) == NULL || CPLGetXMLNode( psRoot, "VRTRasterBand" ) == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "Missing one of rasterXSize, rasterYSize or bands on" " VRTDataset." ); CPLDestroyXMLNode( psTree ); return NULL; } /* -------------------------------------------------------------------- */ /* Create the new virtual dataset object. */ /* -------------------------------------------------------------------- */ VRTDataset *poDS; int nXSize = atoi(CPLGetXMLValue(psRoot,"rasterXSize","0")); int nYSize = atoi(CPLGetXMLValue(psRoot,"rasterYSize","0")); if ( !GDALCheckDatasetDimensions(nXSize, nYSize) ) { CPLDestroyXMLNode( psTree ); return NULL; } if( strstr(pszXML,"VRTWarpedDataset") != NULL ) poDS = new VRTWarpedDataset( nXSize, nYSize ); else { poDS = new VRTDataset( nXSize, nYSize ); poDS->eAccess = eAccess; } if( poDS->XMLInit( psRoot, pszVRTPath ) != CE_None ) { delete poDS; poDS = NULL; } /* -------------------------------------------------------------------- */ /* Try to return a regular handle on the file. */ /* -------------------------------------------------------------------- */ CPLDestroyXMLNode( psTree ); return poDS; }
int main( int argc, char ** argv ) { const char *pszLocX = NULL, *pszLocY = NULL; const char *pszSrcFilename = NULL; char *pszSourceSRS = NULL; std::vector<int> anBandList; bool bAsXML = false, bLIFOnly = false; bool bQuiet = false, bValOnly = false; int nOverview = -1; char **papszOpenOptions = NULL; GDALAllRegister(); argc = GDALGeneralCmdLineProcessor( argc, &argv, 0 ); if( argc < 1 ) exit( -argc ); /* -------------------------------------------------------------------- */ /* Parse arguments. */ /* -------------------------------------------------------------------- */ int i; for( i = 1; i < argc; i++ ) { if( EQUAL(argv[i], "--utility_version") ) { printf("%s was compiled against GDAL %s and is running against GDAL %s\n", argv[0], GDAL_RELEASE_NAME, GDALVersionInfo("RELEASE_NAME")); return 0; } else if( EQUAL(argv[i],"-b") && i < argc-1 ) { anBandList.push_back( atoi(argv[++i]) ); } else if( EQUAL(argv[i],"-overview") && i < argc-1 ) { nOverview = atoi(argv[++i]) - 1; } else if( EQUAL(argv[i],"-l_srs") && i < argc-1 ) { CPLFree(pszSourceSRS); pszSourceSRS = SanitizeSRS(argv[++i]); } else if( EQUAL(argv[i],"-geoloc") ) { CPLFree(pszSourceSRS); pszSourceSRS = CPLStrdup("-geoloc"); } else if( EQUAL(argv[i],"-wgs84") ) { CPLFree(pszSourceSRS); pszSourceSRS = SanitizeSRS("WGS84"); } else if( EQUAL(argv[i],"-xml") ) { bAsXML = true; } else if( EQUAL(argv[i],"-lifonly") ) { bLIFOnly = true; bQuiet = true; } else if( EQUAL(argv[i],"-valonly") ) { bValOnly = true; bQuiet = true; } else if( EQUAL(argv[i], "-oo") && i < argc-1 ) { papszOpenOptions = CSLAddString( papszOpenOptions, argv[++i] ); } else if( argv[i][0] == '-' && !isdigit(argv[i][1]) ) Usage(); else if( pszSrcFilename == NULL ) pszSrcFilename = argv[i]; else if( pszLocX == NULL ) pszLocX = argv[i]; else if( pszLocY == NULL ) pszLocY = argv[i]; else Usage(); } if( pszSrcFilename == NULL || (pszLocX != NULL && pszLocY == NULL) ) Usage(); /* -------------------------------------------------------------------- */ /* Open source file. */ /* -------------------------------------------------------------------- */ GDALDatasetH hSrcDS = NULL; hSrcDS = GDALOpenEx( pszSrcFilename, GDAL_OF_RASTER, NULL, (const char* const* )papszOpenOptions, NULL ); if( hSrcDS == NULL ) exit( 1 ); /* -------------------------------------------------------------------- */ /* Setup coordinate transformation, if required */ /* -------------------------------------------------------------------- */ OGRSpatialReferenceH hSrcSRS = NULL, hTrgSRS = NULL; OGRCoordinateTransformationH hCT = NULL; if( pszSourceSRS != NULL && !EQUAL(pszSourceSRS,"-geoloc") ) { hSrcSRS = OSRNewSpatialReference( pszSourceSRS ); hTrgSRS = OSRNewSpatialReference( GDALGetProjectionRef( hSrcDS ) ); hCT = OCTNewCoordinateTransformation( hSrcSRS, hTrgSRS ); if( hCT == NULL ) exit( 1 ); } /* -------------------------------------------------------------------- */ /* If no bands were requested, we will query them all. */ /* -------------------------------------------------------------------- */ if( anBandList.size() == 0 ) { for( i = 0; i < GDALGetRasterCount( hSrcDS ); i++ ) anBandList.push_back( i+1 ); } /* -------------------------------------------------------------------- */ /* Turn the location into a pixel and line location. */ /* -------------------------------------------------------------------- */ int inputAvailable = 1; double dfGeoX; double dfGeoY; CPLString osXML; if( pszLocX == NULL && pszLocY == NULL ) { if (fscanf(stdin, "%lf %lf", &dfGeoX, &dfGeoY) != 2) { inputAvailable = 0; } } else { dfGeoX = CPLAtof(pszLocX); dfGeoY = CPLAtof(pszLocY); } while (inputAvailable) { int iPixel, iLine; if (hCT) { if( !OCTTransform( hCT, 1, &dfGeoX, &dfGeoY, NULL ) ) exit( 1 ); } if( pszSourceSRS != NULL ) { double adfGeoTransform[6], adfInvGeoTransform[6]; if( GDALGetGeoTransform( hSrcDS, adfGeoTransform ) != CE_None ) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot get geotransform"); exit( 1 ); } if( !GDALInvGeoTransform( adfGeoTransform, adfInvGeoTransform ) ) { CPLError(CE_Failure, CPLE_AppDefined, "Cannot invert geotransform"); exit( 1 ); } iPixel = (int) floor( adfInvGeoTransform[0] + adfInvGeoTransform[1] * dfGeoX + adfInvGeoTransform[2] * dfGeoY ); iLine = (int) floor( adfInvGeoTransform[3] + adfInvGeoTransform[4] * dfGeoX + adfInvGeoTransform[5] * dfGeoY ); } else { iPixel = (int) floor(dfGeoX); iLine = (int) floor(dfGeoY); } /* -------------------------------------------------------------------- */ /* Prepare report. */ /* -------------------------------------------------------------------- */ CPLString osLine; if( bAsXML ) { osLine.Printf( "<Report pixel=\"%d\" line=\"%d\">", iPixel, iLine ); osXML += osLine; } else if( !bQuiet ) { printf( "Report:\n" ); printf( " Location: (%dP,%dL)\n", iPixel, iLine ); } int bPixelReport = TRUE; if( iPixel < 0 || iLine < 0 || iPixel >= GDALGetRasterXSize( hSrcDS ) || iLine >= GDALGetRasterYSize( hSrcDS ) ) { if( bAsXML ) osXML += "<Alert>Location is off this file! No further details to report.</Alert>"; else if( bValOnly ) printf("\n"); else if( !bQuiet ) printf( "\nLocation is off this file! No further details to report.\n"); bPixelReport = FALSE; } /* -------------------------------------------------------------------- */ /* Process each band. */ /* -------------------------------------------------------------------- */ for( i = 0; bPixelReport && i < (int) anBandList.size(); i++ ) { GDALRasterBandH hBand = GDALGetRasterBand( hSrcDS, anBandList[i] ); int iPixelToQuery = iPixel; int iLineToQuery = iLine; if (nOverview >= 0 && hBand != NULL) { GDALRasterBandH hOvrBand = GDALGetOverview(hBand, nOverview); if (hOvrBand != NULL) { int nOvrXSize = GDALGetRasterBandXSize(hOvrBand); int nOvrYSize = GDALGetRasterBandYSize(hOvrBand); iPixelToQuery = (int)(0.5 + 1.0 * iPixel / GDALGetRasterXSize( hSrcDS ) * nOvrXSize); iLineToQuery = (int)(0.5 + 1.0 * iLine / GDALGetRasterYSize( hSrcDS ) * nOvrYSize); if (iPixelToQuery >= nOvrXSize) iPixelToQuery = nOvrXSize - 1; if (iLineToQuery >= nOvrYSize) iLineToQuery = nOvrYSize - 1; } else { CPLError(CE_Failure, CPLE_AppDefined, "Cannot get overview %d of band %d", nOverview + 1, anBandList[i] ); } hBand = hOvrBand; } if (hBand == NULL) continue; if( bAsXML ) { osLine.Printf( "<BandReport band=\"%d\">", anBandList[i] ); osXML += osLine; } else if( !bQuiet ) { printf( " Band %d:\n", anBandList[i] ); } /* -------------------------------------------------------------------- */ /* Request location info for this location. It is possible */ /* only the VRT driver actually supports this. */ /* -------------------------------------------------------------------- */ CPLString osItem; osItem.Printf( "Pixel_%d_%d", iPixelToQuery, iLineToQuery ); const char *pszLI = GDALGetMetadataItem( hBand, osItem, "LocationInfo"); if( pszLI != NULL ) { if( bAsXML ) osXML += pszLI; else if( !bQuiet ) printf( " %s\n", pszLI ); else if( bLIFOnly ) { /* Extract all files, if any. */ CPLXMLNode *psRoot = CPLParseXMLString( pszLI ); if( psRoot != NULL && psRoot->psChild != NULL && psRoot->eType == CXT_Element && EQUAL(psRoot->pszValue,"LocationInfo") ) { CPLXMLNode *psNode; for( psNode = psRoot->psChild; psNode != NULL; psNode = psNode->psNext ) { if( psNode->eType == CXT_Element && EQUAL(psNode->pszValue,"File") && psNode->psChild != NULL ) { char* pszUnescaped = CPLUnescapeString( psNode->psChild->pszValue, NULL, CPLES_XML); printf( "%s\n", pszUnescaped ); CPLFree(pszUnescaped); } } } CPLDestroyXMLNode( psRoot ); } } /* -------------------------------------------------------------------- */ /* Report the pixel value of this band. */ /* -------------------------------------------------------------------- */ double adfPixel[2]; if( GDALRasterIO( hBand, GF_Read, iPixelToQuery, iLineToQuery, 1, 1, adfPixel, 1, 1, GDT_CFloat64, 0, 0) == CE_None ) { CPLString osValue; if( GDALDataTypeIsComplex( GDALGetRasterDataType( hBand ) ) ) osValue.Printf( "%.15g+%.15gi", adfPixel[0], adfPixel[1] ); else osValue.Printf( "%.15g", adfPixel[0] ); if( bAsXML ) { osXML += "<Value>"; osXML += osValue; osXML += "</Value>"; } else if( !bQuiet ) printf( " Value: %s\n", osValue.c_str() ); else if( bValOnly ) printf( "%s\n", osValue.c_str() ); // Report unscaled if we have scale/offset values. int bSuccess; double dfOffset = GDALGetRasterOffset( hBand, &bSuccess ); double dfScale = GDALGetRasterScale( hBand, &bSuccess ); if( dfOffset != 0.0 || dfScale != 1.0 ) { adfPixel[0] = adfPixel[0] * dfScale + dfOffset; adfPixel[1] = adfPixel[1] * dfScale + dfOffset; if( GDALDataTypeIsComplex( GDALGetRasterDataType( hBand ) ) ) osValue.Printf( "%.15g+%.15gi", adfPixel[0], adfPixel[1] ); else osValue.Printf( "%.15g", adfPixel[0] ); if( bAsXML ) { osXML += "<DescaledValue>"; osXML += osValue; osXML += "</DescaledValue>"; } else if( !bQuiet ) printf( " Descaled Value: %s\n", osValue.c_str() ); } } if( bAsXML ) osXML += "</BandReport>"; } osXML += "</Report>"; if( (pszLocX != NULL && pszLocY != NULL) || (fscanf(stdin, "%lf %lf", &dfGeoX, &dfGeoY) != 2) ) { inputAvailable = 0; } } /* -------------------------------------------------------------------- */ /* Finalize xml report and print. */ /* -------------------------------------------------------------------- */ if( bAsXML ) { CPLXMLNode *psRoot; char *pszFormattedXML; psRoot = CPLParseXMLString( osXML ); pszFormattedXML = CPLSerializeXMLTree( psRoot ); CPLDestroyXMLNode( psRoot ); printf( "%s", pszFormattedXML ); CPLFree( pszFormattedXML ); } /* -------------------------------------------------------------------- */ /* Cleanup */ /* -------------------------------------------------------------------- */ if (hCT) { OSRDestroySpatialReference( hSrcSRS ); OSRDestroySpatialReference( hTrgSRS ); OCTDestroyCoordinateTransformation( hCT ); } if (hSrcDS) GDALClose(hSrcDS); GDALDumpOpenDatasets( stderr ); GDALDestroyDriverManager(); CPLFree(pszSourceSRS); CSLDestroy(papszOpenOptions); CSLDestroy( argv ); return 0; }
OGRErr BAGDataset::ParseWKTFromXML( const char *pszISOXML ) { OGRSpatialReference oSRS; CPLXMLNode *psRoot = CPLParseXMLString( pszISOXML ); OGRErr eOGRErr = OGRERR_FAILURE; if( psRoot == NULL ) return eOGRErr; CPLStripXMLNamespace( psRoot, NULL, TRUE ); CPLXMLNode *psRSI = CPLSearchXMLNode( psRoot, "=referenceSystemInfo" ); if( psRSI == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "Unable to find <referenceSystemInfo> in metadata." ); CPLDestroyXMLNode( psRoot ); return eOGRErr; } oSRS.Clear(); const char *pszSRCodeString = CPLGetXMLValue( psRSI, "MD_ReferenceSystem.referenceSystemIdentifier.RS_Identifier.code.CharacterString", NULL ); if( pszSRCodeString == NULL ) { CPLDebug("BAG", "Unable to find /MI_Metadata/referenceSystemInfo[1]/MD_ReferenceSystem[1]/referenceSystemIdentifier[1]/RS_Identifier[1]/code[1]/CharacterString[1] in metadata." ); CPLDestroyXMLNode( psRoot ); return eOGRErr; } const char *pszSRCodeSpace = CPLGetXMLValue( psRSI, "MD_ReferenceSystem.referenceSystemIdentifier.RS_Identifier.codeSpace.CharacterString", "" ); if( !EQUAL( pszSRCodeSpace, "WKT" ) ) { CPLError( CE_Failure, CPLE_AppDefined, "Spatial reference string is not in WKT." ); CPLDestroyXMLNode( psRoot ); return eOGRErr; } char* pszWKT = const_cast< char* >( pszSRCodeString ); if( oSRS.importFromWkt( &pszWKT ) != OGRERR_NONE ) { CPLError( CE_Failure, CPLE_AppDefined, "Failed parsing WKT string \"%s\".", pszSRCodeString ); CPLDestroyXMLNode( psRoot ); return eOGRErr; } oSRS.exportToWkt( &pszProjection ); eOGRErr = OGRERR_NONE; psRSI = CPLSearchXMLNode( psRSI->psNext, "=referenceSystemInfo" ); if( psRSI == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "Unable to find second instance of <referenceSystemInfo> in metadata." ); CPLDestroyXMLNode( psRoot ); return eOGRErr; } pszSRCodeString = CPLGetXMLValue( psRSI, "MD_ReferenceSystem.referenceSystemIdentifier.RS_Identifier.code.CharacterString", NULL ); if( pszSRCodeString == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "Unable to find /MI_Metadata/referenceSystemInfo[2]/MD_ReferenceSystem[1]/referenceSystemIdentifier[1]/RS_Identifier[1]/code[1]/CharacterString[1] in metadata." ); CPLDestroyXMLNode( psRoot ); return eOGRErr; } pszSRCodeSpace = CPLGetXMLValue( psRSI, "MD_ReferenceSystem.referenceSystemIdentifier.RS_Identifier.codeSpace.CharacterString", "" ); if( !EQUAL( pszSRCodeSpace, "WKT" ) ) { CPLError( CE_Failure, CPLE_AppDefined, "Spatial reference string is not in WKT." ); CPLDestroyXMLNode( psRoot ); return eOGRErr; } if( EQUALN(pszSRCodeString, "VERTCS", 6 ) ) { CPLString oString( pszProjection ); oString += ","; oString += pszSRCodeString; if ( pszProjection ) CPLFree( pszProjection ); pszProjection = CPLStrdup( oString ); } CPLDestroyXMLNode( psRoot ); return eOGRErr; }
int GDALJP2Metadata::ParseGMLCoverageDesc() { /* -------------------------------------------------------------------- */ /* Do we have an XML doc that is apparently a coverage */ /* description? */ /* -------------------------------------------------------------------- */ const char *pszCoverage = CSLFetchNameValue( papszGMLMetadata, "gml.root-instance" ); if( pszCoverage == NULL ) return FALSE; CPLDebug( "GDALJP2Metadata", "Found GML Box:\n%s", pszCoverage ); /* -------------------------------------------------------------------- */ /* Try parsing the XML. Wipe any namespace prefixes. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psXML = CPLParseXMLString( pszCoverage ); if( psXML == NULL ) return FALSE; CPLStripXMLNamespace( psXML, NULL, TRUE ); /* -------------------------------------------------------------------- */ /* Isolate RectifiedGrid. Eventually we will need to support */ /* other georeferencing objects. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psRG = CPLSearchXMLNode( psXML, "=RectifiedGrid" ); CPLXMLNode *psOriginPoint = NULL; const char *pszOffset1=NULL, *pszOffset2=NULL; if( psRG != NULL ) { psOriginPoint = CPLGetXMLNode( psRG, "origin.Point" ); CPLXMLNode *psOffset1 = CPLGetXMLNode( psRG, "offsetVector" ); if( psOffset1 != NULL ) { pszOffset1 = CPLGetXMLValue( psOffset1, "", NULL ); pszOffset2 = CPLGetXMLValue( psOffset1->psNext, "=offsetVector", NULL ); } } /* -------------------------------------------------------------------- */ /* If we are missing any of the origin or 2 offsets then give up. */ /* -------------------------------------------------------------------- */ if( psOriginPoint == NULL || pszOffset1 == NULL || pszOffset2 == NULL ) { CPLDestroyXMLNode( psXML ); return FALSE; } /* -------------------------------------------------------------------- */ /* Extract origin location. */ /* -------------------------------------------------------------------- */ OGRPoint *poOriginGeometry = NULL; const char *pszSRSName = NULL; if( psOriginPoint != NULL ) { poOriginGeometry = (OGRPoint *) OGR_G_CreateFromGMLTree( psOriginPoint ); if( poOriginGeometry != NULL && wkbFlatten(poOriginGeometry->getGeometryType()) != wkbPoint ) { delete poOriginGeometry; poOriginGeometry = NULL; } // SRS? pszSRSName = CPLGetXMLValue( psOriginPoint, "srsName", NULL ); } /* -------------------------------------------------------------------- */ /* Extract offset(s) */ /* -------------------------------------------------------------------- */ char **papszOffset1Tokens = NULL; char **papszOffset2Tokens = NULL; int bSuccess = FALSE; papszOffset1Tokens = CSLTokenizeStringComplex( pszOffset1, " ,", FALSE, FALSE ); papszOffset2Tokens = CSLTokenizeStringComplex( pszOffset2, " ,", FALSE, FALSE ); if( CSLCount(papszOffset1Tokens) >= 2 && CSLCount(papszOffset2Tokens) >= 2 && poOriginGeometry != NULL ) { adfGeoTransform[0] = poOriginGeometry->getX(); adfGeoTransform[1] = atof(papszOffset1Tokens[0]); adfGeoTransform[2] = atof(papszOffset2Tokens[0]); adfGeoTransform[3] = poOriginGeometry->getY(); adfGeoTransform[4] = atof(papszOffset1Tokens[1]); adfGeoTransform[5] = atof(papszOffset2Tokens[1]); // offset from center of pixel. adfGeoTransform[0] -= adfGeoTransform[1]*0.5; adfGeoTransform[0] -= adfGeoTransform[2]*0.5; adfGeoTransform[3] -= adfGeoTransform[4]*0.5; adfGeoTransform[3] -= adfGeoTransform[5]*0.5; bSuccess = TRUE; bHaveGeoTransform = TRUE; } CSLDestroy( papszOffset1Tokens ); CSLDestroy( papszOffset2Tokens ); if( poOriginGeometry != NULL ) delete poOriginGeometry; /* -------------------------------------------------------------------- */ /* If we still don't have an srsName, check for it on the */ /* boundedBy Envelope. Some products */ /* (ie. EuropeRasterTile23.jpx) use this as the only srsName */ /* delivery vehicle. */ /* -------------------------------------------------------------------- */ if( pszSRSName == NULL ) { pszSRSName = CPLGetXMLValue( psXML, "=FeatureCollection.boundedBy.Envelope.srsName", NULL ); } /* -------------------------------------------------------------------- */ /* If we have gotten a geotransform, then try to interprete the */ /* srsName. */ /* -------------------------------------------------------------------- */ int bNeedAxisFlip = FALSE; if( bSuccess && pszSRSName != NULL && (pszProjection == NULL || strlen(pszProjection) == 0) ) { OGRSpatialReference oSRS; if( EQUALN(pszSRSName,"epsg:",5) ) { if( oSRS.SetFromUserInput( pszSRSName ) == OGRERR_NONE ) oSRS.exportToWkt( &pszProjection ); } else if( EQUALN(pszSRSName,"urn:",4) && strstr(pszSRSName,":def:") != NULL && oSRS.importFromURN(pszSRSName) == OGRERR_NONE ) { const char *pszCode = strrchr(pszSRSName,':') + 1; oSRS.exportToWkt( &pszProjection ); // Per #2131 if( atoi(pszCode) >= 4000 && atoi(pszCode) <= 4999 ) { CPLDebug( "GMLJP2", "Request axis flip for SRS=%s", pszSRSName ); bNeedAxisFlip = TRUE; } } else if( !GMLSRSLookup( pszSRSName ) ) { CPLDebug( "GDALJP2Metadata", "Unable to evaluate SRSName=%s", pszSRSName ); } } if( pszProjection ) CPLDebug( "GDALJP2Metadata", "Got projection from GML box: %s", pszProjection ); CPLDestroyXMLNode( psXML ); psXML = NULL; /* -------------------------------------------------------------------- */ /* Do we need to flip the axes? */ /* -------------------------------------------------------------------- */ if( bNeedAxisFlip && CSLTestBoolean( CPLGetConfigOption( "GDAL_IGNORE_AXIS_ORIENTATION", "FALSE" ) ) ) { bNeedAxisFlip = FALSE; CPLDebug( "GMLJP2", "Supressed axis flipping based on GDAL_IGNORE_AXIS_ORIENTATION." ); } if( bNeedAxisFlip ) { double dfTemp; CPLDebug( "GMLJP2", "Flipping axis orientation in GMLJP2 coverage description." ); dfTemp = adfGeoTransform[0]; adfGeoTransform[0] = adfGeoTransform[3]; adfGeoTransform[3] = dfTemp; dfTemp = adfGeoTransform[1]; adfGeoTransform[1] = adfGeoTransform[4]; adfGeoTransform[4] = dfTemp; dfTemp = adfGeoTransform[2]; adfGeoTransform[2] = adfGeoTransform[5]; adfGeoTransform[5] = dfTemp; } return pszProjection != NULL && bSuccess; }
OGRErr OGR_SRS_ImportFromISO19115( OGRSpatialReference *poThis, const char *pszISOXML ) { /* -------------------------------------------------------------------- */ /* Parse the XML into tree form. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psRoot = CPLParseXMLString( pszISOXML ); if( psRoot == NULL ) return OGRERR_FAILURE; CPLStripXMLNamespace( psRoot, NULL, TRUE ); /* -------------------------------------------------------------------- */ /* For now we look for projection codes recognised in the BAG */ /* format (see ons_fsd.pdf: Metadata Dataset Character String */ /* Constants). */ /* -------------------------------------------------------------------- */ CPLXMLNode *psRSI = CPLSearchXMLNode( psRoot, "=referenceSystemInfo" ); if( psRSI == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "Unable to find <referenceSystemInfo> in metadata." ); CPLDestroyXMLNode( psRoot ); return OGRERR_FAILURE; } poThis->Clear(); /* -------------------------------------------------------------------- */ /* First, set the datum. */ /* -------------------------------------------------------------------- */ const char *pszDatum = CPLGetXMLValue( psRSI, "MD_CRS.datum.RS_Identifier.code", "" ); if( strlen(pszDatum) > 0 && poThis->SetWellKnownGeogCS( pszDatum ) != OGRERR_NONE ) { CPLDestroyXMLNode( psRoot ); return OGRERR_FAILURE; } /* -------------------------------------------------------------------- */ /* Then try to extract the projection. */ /* -------------------------------------------------------------------- */ const char *pszProjection = CPLGetXMLValue( psRSI, "MD_CRS.projection.RS_Identifier.code", "" ); if( EQUAL(pszProjection,"UTM") ) { int nZone = atoi(CPLGetXMLValue( psRSI, "MD_CRS.projectionParameters.MD_ProjectionParameters.zone", "0" )); poThis->SetUTM( ABS(nZone), nZone > 0 ); } else if( EQUAL(pszProjection,"Geodetic") ) { const char *pszEllipsoid = CPLGetXMLValue( psRSI, "MD_CRS.ellipsoid.RS_Identifier.code", "" ); if( !EQUAL(pszDatum, "WGS84") || !EQUAL(pszEllipsoid, "WGS84") ) { CPLError( CE_Failure, CPLE_AppDefined, "ISO 19115 parser does not support custom GCS." ); CPLDestroyXMLNode( psRoot ); return OGRERR_FAILURE; } } else { CPLError( CE_Failure, CPLE_AppDefined, "projection = %s not recognised by ISO 19115 parser.", pszProjection ); CPLDestroyXMLNode( psRoot ); return OGRERR_FAILURE; } CPLDestroyXMLNode( psRoot ); return OGRERR_NONE; }
CPLXMLNode *GDALMultiDomainMetadata::Serialize() { CPLXMLNode *psFirst = NULL; for( int iDomain = 0; papszDomainList != NULL && papszDomainList[iDomain] != NULL; iDomain++) { char **papszMD = papoMetadataLists[iDomain]->List(); // Do not serialize empty domains if( papszMD == NULL || papszMD[0] == NULL ) continue; CPLXMLNode *psMD; int bFormatXML = FALSE; psMD = CPLCreateXMLNode( NULL, CXT_Element, "Metadata" ); if( strlen( papszDomainList[iDomain] ) > 0 ) CPLCreateXMLNode( CPLCreateXMLNode( psMD, CXT_Attribute, "domain" ), CXT_Text, papszDomainList[iDomain] ); if( EQUALN(papszDomainList[iDomain],"xml:",4) && CSLCount(papszMD) == 1 ) { CPLXMLNode *psValueAsXML = CPLParseXMLString( papszMD[0] ); if( psValueAsXML != NULL ) { bFormatXML = TRUE; CPLCreateXMLNode( CPLCreateXMLNode( psMD, CXT_Attribute, "format" ), CXT_Text, "xml" ); CPLAddXMLChild( psMD, psValueAsXML ); } } if( !bFormatXML ) { CPLXMLNode* psLastChild = NULL; // To go after domain attribute if( psMD->psChild != NULL ) { psLastChild = psMD->psChild; while( psLastChild->psNext != NULL ) psLastChild = psLastChild->psNext; } for( int i = 0; papszMD != NULL && papszMD[i] != NULL; i++ ) { const char *pszRawValue; char *pszKey = NULL; CPLXMLNode *psMDI; pszRawValue = CPLParseNameValue( papszMD[i], &pszKey ); psMDI = CPLCreateXMLNode( NULL, CXT_Element, "MDI" ); if( psLastChild == NULL ) psMD->psChild = psMDI; else psLastChild->psNext = psMDI; psLastChild = psMDI; CPLSetXMLValue( psMDI, "#key", pszKey ); CPLCreateXMLNode( psMDI, CXT_Text, pszRawValue ); CPLFree( pszKey ); } } if( psFirst == NULL ) psFirst = psMD; else CPLAddXMLSibling( psFirst, psMD ); } return psFirst; }
static CPLXMLNode * GetDictionaryItem( char **papszGMLMetadata, const char *pszURN ) { char *pszLabel; const char *pszFragmentId = NULL; int i; if( EQUALN(pszURN,"urn:jp2k:xml:", 13) ) pszLabel = CPLStrdup( pszURN + 13 ); else if( EQUALN(pszURN,"urn:ogc:tc:gmljp2:xml:", 22) ) pszLabel = CPLStrdup( pszURN + 22 ); else if( EQUALN(pszURN,"gmljp2://xml/",13) ) pszLabel = CPLStrdup( pszURN + 13 ); else pszLabel = CPLStrdup( pszURN ); /* -------------------------------------------------------------------- */ /* Split out label and fragment id. */ /* -------------------------------------------------------------------- */ for( i = 0; pszLabel[i] != '#'; i++ ) { if( pszLabel[i] == '\0' ) return NULL; } pszFragmentId = pszLabel + i + 1; pszLabel[i] = '\0'; /* -------------------------------------------------------------------- */ /* Can we find an XML box with the desired label? */ /* -------------------------------------------------------------------- */ const char *pszDictionary = CSLFetchNameValue( papszGMLMetadata, pszLabel ); if( pszDictionary == NULL ) return NULL; /* -------------------------------------------------------------------- */ /* Try and parse the dictionary. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psDictTree = CPLParseXMLString( pszDictionary ); if( psDictTree == NULL ) { CPLDestroyXMLNode( psDictTree ); return NULL; } CPLStripXMLNamespace( psDictTree, NULL, TRUE ); CPLXMLNode *psDictRoot = CPLSearchXMLNode( psDictTree, "=Dictionary" ); if( psDictRoot == NULL ) { CPLDestroyXMLNode( psDictTree ); return NULL; } /* -------------------------------------------------------------------- */ /* Search for matching id. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psEntry, *psHit = NULL; for( psEntry = psDictRoot->psChild; psEntry != NULL && psHit == NULL; psEntry = psEntry->psNext ) { const char *pszId; if( psEntry->eType != CXT_Element ) continue; if( !EQUAL(psEntry->pszValue,"dictionaryEntry") ) continue; if( psEntry->psChild == NULL ) continue; pszId = CPLGetXMLValue( psEntry->psChild, "id", "" ); if( EQUAL(pszId, pszFragmentId) ) psHit = CPLCloneXMLTree( psEntry->psChild ); } /* -------------------------------------------------------------------- */ /* Cleanup */ /* -------------------------------------------------------------------- */ CPLFree( pszLabel ); CPLDestroyXMLNode( psDictTree ); return psHit; }
OGRErr OGRMILayerAttrIndex::LoadConfigFromXML(const char* pszRawXML) { /* -------------------------------------------------------------------- */ /* Parse the XML. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psRoot = CPLParseXMLString( pszRawXML ); if( psRoot == nullptr ) return OGRERR_FAILURE; /* -------------------------------------------------------------------- */ /* Open the index file. */ /* -------------------------------------------------------------------- */ poINDFile = new TABINDFile(); if (pszMIINDFilename == nullptr) pszMIINDFilename = CPLStrdup(CPLGetXMLValue(psRoot,"MIIDFilename","")); if( pszMIINDFilename == nullptr ) return OGRERR_FAILURE; /* NOTE: Replaced r+ with r according to explanation in Ticket #1620. * This change has to be observed if it doesn't cause any * problems in future. (mloskot) */ if( poINDFile->Open( pszMIINDFilename, "r" ) != 0 ) { CPLDestroyXMLNode( psRoot ); CPLError( CE_Failure, CPLE_OpenFailed, "Failed to open index file %s.", pszMIINDFilename ); return OGRERR_FAILURE; } /* -------------------------------------------------------------------- */ /* Process each attrindex. */ /* -------------------------------------------------------------------- */ for( CPLXMLNode *psAttrIndex = psRoot->psChild; psAttrIndex != nullptr; psAttrIndex = psAttrIndex->psNext ) { if( psAttrIndex->eType != CXT_Element || !EQUAL(psAttrIndex->pszValue,"OGRMIAttrIndex") ) continue; int iField = atoi(CPLGetXMLValue(psAttrIndex,"FieldIndex","-1")); int iIndexIndex = atoi(CPLGetXMLValue(psAttrIndex,"IndexIndex","-1")); if( iField == -1 || iIndexIndex == -1 ) { CPLError( CE_Warning, CPLE_AppDefined, "Skipping corrupt OGRMIAttrIndex entry." ); continue; } AddAttrInd( iField, iIndexIndex ); } CPLDestroyXMLNode( psRoot ); CPLDebug( "OGR", "Restored %d field indexes for layer %s from %s on %s.", nIndexCount, poLayer->GetLayerDefn()->GetName(), pszMetadataFilename ? pszMetadataFilename : "--unknown--", pszMIINDFilename ); return OGRERR_NONE; }
bool VSIDIRAz::AnalyseAzureFileList( const CPLString& osBaseURL, const char* pszXML) { #if DEBUG_VERBOSE CPLDebug("AZURE", "%s", pszXML); #endif CPLXMLNode* psTree = CPLParseXMLString(pszXML); if( psTree == nullptr ) return false; CPLXMLNode* psEnumerationResults = CPLGetXMLNode(psTree, "=EnumerationResults"); bool bNonEmpty = false; if( psEnumerationResults ) { CPLString osPrefix = CPLGetXMLValue(psEnumerationResults, "Prefix", ""); CPLXMLNode* psBlobs = CPLGetXMLNode(psEnumerationResults, "Blobs"); if( psBlobs == nullptr ) { psBlobs = CPLGetXMLNode(psEnumerationResults, "Containers"); if( psBlobs != nullptr ) bNonEmpty = true; } // Count the number of occurrences of a path. Can be 1 or 2. 2 in the case // that both a filename and directory exist std::map<CPLString, int> aoNameCount; for(CPLXMLNode* psIter = psBlobs ? psBlobs->psChild : nullptr; psIter != nullptr; psIter = psIter->psNext ) { if( psIter->eType != CXT_Element ) continue; if( strcmp(psIter->pszValue, "Blob") == 0 ) { const char* pszKey = CPLGetXMLValue(psIter, "Name", nullptr); if( pszKey && strstr(pszKey, GDAL_MARKER_FOR_DIR) != nullptr ) { bNonEmpty = true; } else if( pszKey && strlen(pszKey) > osPrefix.size() ) { bNonEmpty = true; aoNameCount[pszKey + osPrefix.size()] ++; } } else if( strcmp(psIter->pszValue, "BlobPrefix") == 0 || strcmp(psIter->pszValue, "Container") == 0 ) { bNonEmpty = true; const char* pszKey = CPLGetXMLValue(psIter, "Name", nullptr); if( pszKey && strncmp(pszKey, osPrefix, osPrefix.size()) == 0 ) { CPLString osKey = pszKey; if( !osKey.empty() && osKey.back() == '/' ) osKey.resize(osKey.size()-1); if( osKey.size() > osPrefix.size() ) { aoNameCount[osKey.c_str() + osPrefix.size()] ++; } } } } for(CPLXMLNode* psIter = psBlobs ? psBlobs->psChild : nullptr; psIter != nullptr; psIter = psIter->psNext ) { if( psIter->eType != CXT_Element ) continue; if( strcmp(psIter->pszValue, "Blob") == 0 ) { const char* pszKey = CPLGetXMLValue(psIter, "Name", nullptr); if( pszKey && strstr(pszKey, GDAL_MARKER_FOR_DIR) != nullptr ) { if( nRecurseDepth < 0 ) { aoEntries.push_back( std::unique_ptr<VSIDIREntry>(new VSIDIREntry())); auto& entry = aoEntries.back(); entry->pszName = CPLStrdup(pszKey + osPrefix.size()); char* pszMarker = strstr(entry->pszName, GDAL_MARKER_FOR_DIR); if( pszMarker ) *pszMarker = '\0'; entry->nMode = S_IFDIR; entry->bModeKnown = true; } } else if( pszKey && strlen(pszKey) > osPrefix.size() ) { aoEntries.push_back( std::unique_ptr<VSIDIREntry>(new VSIDIREntry())); auto& entry = aoEntries.back(); entry->pszName = CPLStrdup(pszKey + osPrefix.size()); entry->nSize = static_cast<GUIntBig>( CPLAtoGIntBig(CPLGetXMLValue(psIter, "Properties.Content-Length", "0"))); entry->bSizeKnown = true; entry->nMode = S_IFDIR; entry->bModeKnown = true; CPLString ETag = CPLGetXMLValue(psIter, "Etag", ""); if( !ETag.empty() ) { entry->papszExtra = CSLSetNameValue( entry->papszExtra, "ETag", ETag.c_str()); } int nYear, nMonth, nDay, nHour, nMinute, nSecond; if( CPLParseRFC822DateTime( CPLGetXMLValue(psIter, "Properties.Last-Modified", ""), &nYear, &nMonth, &nDay, &nHour, &nMinute, &nSecond, nullptr, nullptr ) ) { struct tm brokendowntime; brokendowntime.tm_year = nYear - 1900; brokendowntime.tm_mon = nMonth - 1; brokendowntime.tm_mday = nDay; brokendowntime.tm_hour = nHour; brokendowntime.tm_min = nMinute; brokendowntime.tm_sec = nSecond < 0 ? 0 : nSecond; entry->nMTime = CPLYMDHMSToUnixTime(&brokendowntime); entry->bMTimeKnown = true; } if( bCacheResults ) { FileProp prop; prop.eExists = EXIST_YES; prop.bHasComputedFileSize = true; prop.fileSize = entry->nSize; prop.bIsDirectory = false; prop.mTime = static_cast<time_t>(entry->nMTime); prop.ETag = ETag; CPLString osCachedFilename = osBaseURL + "/" + osPrefix + entry->pszName; #if DEBUG_VERBOSE CPLDebug("AZURE", "Cache %s", osCachedFilename.c_str()); #endif poFS->SetCachedFileProp(osCachedFilename, prop); } } } else if( strcmp(psIter->pszValue, "BlobPrefix") == 0 || strcmp(psIter->pszValue, "Container") == 0 ) { const char* pszKey = CPLGetXMLValue(psIter, "Name", nullptr); if( pszKey && strncmp(pszKey, osPrefix, osPrefix.size()) == 0 ) { CPLString osKey = pszKey; if( !osKey.empty() && osKey.back() == '/' ) osKey.resize(osKey.size()-1); if( osKey.size() > osPrefix.size() ) { aoEntries.push_back( std::unique_ptr<VSIDIREntry>(new VSIDIREntry())); auto& entry = aoEntries.back(); entry->pszName = CPLStrdup(osKey.c_str() + osPrefix.size()); if( aoNameCount[entry->pszName] == 2 ) { // Add a / suffix to disambiguish the situation // Normally we don't suffix directories with /, but // we have no alternative here CPLString osTemp(entry->pszName); osTemp += '/'; CPLFree(entry->pszName); entry->pszName = CPLStrdup(osTemp); } entry->nMode = S_IFDIR; entry->bModeKnown = true; if( bCacheResults ) { FileProp prop; prop.eExists = EXIST_YES; prop.bIsDirectory = true; prop.bHasComputedFileSize = true; prop.fileSize = 0; prop.mTime = 0; CPLString osCachedFilename = osBaseURL + "/" + osPrefix + entry->pszName; #if DEBUG_VERBOSE CPLDebug("AZURE", "Cache %s", osCachedFilename.c_str()); #endif poFS->SetCachedFileProp(osCachedFilename, prop); } } } } if( nMaxFiles > 0 && aoEntries.size() > static_cast<unsigned>(nMaxFiles) ) break; } osNextMarker = CPLGetXMLValue(psEnumerationResults, "NextMarker", ""); } CPLDestroyXMLNode(psTree); return bNonEmpty; }
void GDALJP2AbstractDataset::LoadVectorLayers(int bOpenRemoteResources) { char** papszGMLJP2 = GetMetadata("xml:gml.root-instance"); if( papszGMLJP2 == NULL ) return; GDALDriver* poMemDriver = (GDALDriver*)GDALGetDriverByName("Memory"); if( poMemDriver == NULL ) return; CPLXMLNode* psRoot = CPLParseXMLString(papszGMLJP2[0]); if( psRoot == NULL ) return; CPLXMLNode* psCC = CPLGetXMLNode(psRoot, "=gmljp2:GMLJP2CoverageCollection"); if( psCC == NULL ) { CPLDestroyXMLNode(psRoot); return; } // Find feature collections CPLXMLNode* psCCChildIter = psCC->psChild; int nLayersAtCC = 0; int nLayersAtGC = 0; for( ; psCCChildIter != NULL; psCCChildIter = psCCChildIter->psNext ) { if( psCCChildIter->eType != CXT_Element || strcmp(psCCChildIter->pszValue, "gmljp2:featureMember") != 0 || psCCChildIter->psChild == NULL || psCCChildIter->psChild->eType != CXT_Element ) continue; CPLXMLNode* psGCorGMLJP2Features = psCCChildIter->psChild; int bIsGC = ( strstr(psGCorGMLJP2Features->pszValue, "GridCoverage") != NULL ); CPLXMLNode* psGCorGMLJP2FeaturesChildIter = psGCorGMLJP2Features->psChild; for( ; psGCorGMLJP2FeaturesChildIter != NULL; psGCorGMLJP2FeaturesChildIter = psGCorGMLJP2FeaturesChildIter->psNext ) { if( psGCorGMLJP2FeaturesChildIter->eType != CXT_Element || strcmp(psGCorGMLJP2FeaturesChildIter->pszValue, "gmljp2:feature") != 0 || psGCorGMLJP2FeaturesChildIter->psChild == NULL ) continue; CPLXMLNode* psFC = NULL; int bFreeFC = FALSE; CPLString osGMLTmpFile; CPLXMLNode* psChild = psGCorGMLJP2FeaturesChildIter->psChild; if( psChild->eType == CXT_Attribute && strcmp(psChild->pszValue, "xlink:href") == 0 && strncmp(psChild->psChild->pszValue, "gmljp2://xml/", strlen("gmljp2://xml/")) == 0 ) { const char* pszBoxName = psChild->psChild->pszValue + strlen("gmljp2://xml/"); char** papszBoxData = GetMetadata(CPLSPrintf("xml:%s", pszBoxName)); if( papszBoxData != NULL ) { psFC = CPLParseXMLString(papszBoxData[0]); bFreeFC = TRUE; } else { CPLDebug("GMLJP2", "gmljp2:feature references %s, but no corresponding box found", psChild->psChild->pszValue); } } if( psChild->eType == CXT_Attribute && strcmp(psChild->pszValue, "xlink:href") == 0 && (strncmp(psChild->psChild->pszValue, "http://", strlen("http://")) == 0 || strncmp(psChild->psChild->pszValue, "https://", strlen("https://")) == 0) ) { if( !bOpenRemoteResources ) CPLDebug("GMLJP2", "Remote feature collection %s mentionned in GMLJP2 box", psChild->psChild->pszValue); else osGMLTmpFile = "/vsicurl/" + CPLString(psChild->psChild->pszValue); } else if( psChild->eType == CXT_Element && strstr(psChild->pszValue, "FeatureCollection") != NULL ) { psFC = psChild; } if( psFC == NULL && osGMLTmpFile.size() == 0 ) continue; if( psFC != NULL ) { osGMLTmpFile = CPLSPrintf("/vsimem/gmljp2/%p/my.gml", this); // Create temporary .gml file CPLSerializeXMLTreeToFile(psFC, osGMLTmpFile); } CPLDebug("GMLJP2", "Found a FeatureCollection at %s level", (bIsGC) ? "GridCoverage" : "CoverageCollection"); CPLString osXSDTmpFile; if( psFC ) { // Try to localize its .xsd schema in a GMLJP2 auxiliary box const char* pszSchemaLocation = CPLGetXMLValue(psFC, "xsi:schemaLocation", NULL); if( pszSchemaLocation ) { char **papszTokens = CSLTokenizeString2( pszSchemaLocation, " \t\n", CSLT_HONOURSTRINGS | CSLT_STRIPLEADSPACES | CSLT_STRIPENDSPACES); if( (CSLCount(papszTokens) % 2) == 0 ) { for(char** papszIter = papszTokens; *papszIter; papszIter += 2 ) { if( strncmp(papszIter[1], "gmljp2://xml/", strlen("gmljp2://xml/")) == 0 ) { const char* pszBoxName = papszIter[1] + strlen("gmljp2://xml/"); char** papszBoxData = GetMetadata(CPLSPrintf("xml:%s", pszBoxName)); if( papszBoxData != NULL ) { osXSDTmpFile = CPLSPrintf("/vsimem/gmljp2/%p/my.xsd", this); VSIFCloseL(VSIFileFromMemBuffer(osXSDTmpFile, (GByte*)papszBoxData[0], strlen(papszBoxData[0]), FALSE)); } else { CPLDebug("GMLJP2", "Feature collection references %s, but no corresponding box found", papszIter[1]); } break; } } } CSLDestroy(papszTokens); } if( bFreeFC ) { CPLDestroyXMLNode(psFC); psFC = NULL; } } GDALDriverH hDrv = GDALIdentifyDriver(osGMLTmpFile, NULL); GDALDriverH hGMLDrv = GDALGetDriverByName("GML"); if( hDrv != NULL && hDrv == hGMLDrv ) { char* apszOpenOptions[2]; apszOpenOptions[0] = (char*) "FORCE_SRS_DETECTION=YES"; apszOpenOptions[1] = NULL; GDALDataset* poTmpDS = (GDALDataset*)GDALOpenEx( osGMLTmpFile, GDAL_OF_VECTOR, NULL, apszOpenOptions, NULL ); if( poTmpDS ) { int nLayers = poTmpDS->GetLayerCount(); for(int i=0;i<nLayers;i++) { if( poMemDS == NULL ) poMemDS = poMemDriver->Create("", 0, 0, 0, GDT_Unknown, NULL); OGRLayer* poSrcLyr = poTmpDS->GetLayer(i); const char* pszLayerName; if( bIsGC ) pszLayerName = CPLSPrintf("FC_GridCoverage_%d_%s", ++nLayersAtGC, poSrcLyr->GetName()); else pszLayerName = CPLSPrintf("FC_CoverageCollection_%d_%s", ++nLayersAtCC, poSrcLyr->GetName()); poMemDS->CopyLayer(poSrcLyr, pszLayerName, NULL); } GDALClose(poTmpDS); // In case we don't have a schema, a .gfs might have been generated VSIUnlink(CPLSPrintf("/vsimem/gmljp2/%p/my.gfs", this)); } } else { CPLDebug("GMLJP2", "No GML driver found to read feature collection"); } if( strncmp(osGMLTmpFile, "/vsicurl/", strlen("/vsicurl/")) != 0 ) VSIUnlink(osGMLTmpFile); if( osXSDTmpFile.size() ) VSIUnlink(osXSDTmpFile); } } // Find annotations psCCChildIter = psCC->psChild; int nAnnotations = 0; for( ; psCCChildIter != NULL; psCCChildIter = psCCChildIter->psNext ) { if( psCCChildIter->eType != CXT_Element || strcmp(psCCChildIter->pszValue, "gmljp2:featureMember") != 0 || psCCChildIter->psChild == NULL || psCCChildIter->psChild->eType != CXT_Element ) continue; CPLXMLNode* psGCorGMLJP2Features = psCCChildIter->psChild; int bIsGC = ( strstr(psGCorGMLJP2Features->pszValue, "GridCoverage") != NULL ); if( !bIsGC ) continue; CPLXMLNode* psGCorGMLJP2FeaturesChildIter = psGCorGMLJP2Features->psChild; for( ; psGCorGMLJP2FeaturesChildIter != NULL; psGCorGMLJP2FeaturesChildIter = psGCorGMLJP2FeaturesChildIter->psNext ) { if( psGCorGMLJP2FeaturesChildIter->eType != CXT_Element || strcmp(psGCorGMLJP2FeaturesChildIter->pszValue, "gmljp2:annotation") != 0 || psGCorGMLJP2FeaturesChildIter->psChild == NULL || psGCorGMLJP2FeaturesChildIter->psChild->eType != CXT_Element || strstr(psGCorGMLJP2FeaturesChildIter->psChild->pszValue, "kml") == NULL ) continue; CPLDebug("GMLJP2", "Found a KML annotation"); // Create temporary .kml file CPLXMLNode* psKML = psGCorGMLJP2FeaturesChildIter->psChild; CPLString osKMLTmpFile(CPLSPrintf("/vsimem/gmljp2/%p/my.kml", this)); CPLSerializeXMLTreeToFile(psKML, osKMLTmpFile); GDALDataset* poTmpDS = (GDALDataset*)GDALOpenEx( osKMLTmpFile, GDAL_OF_VECTOR, NULL, NULL, NULL ); if( poTmpDS ) { int nLayers = poTmpDS->GetLayerCount(); for(int i=0;i<nLayers;i++) { if( poMemDS == NULL ) poMemDS = poMemDriver->Create("", 0, 0, 0, GDT_Unknown, NULL); OGRLayer* poSrcLyr = poTmpDS->GetLayer(i); const char* pszLayerName; pszLayerName = CPLSPrintf("Annotation_%d_%s", ++nAnnotations, poSrcLyr->GetName()); poMemDS->CopyLayer(poSrcLyr, pszLayerName, NULL); } GDALClose(poTmpDS); } else { CPLDebug("GMLJP2", "No KML/LIBKML driver found to read annotation"); } VSIUnlink(osKMLTmpFile); } } CPLDestroyXMLNode(psRoot); }
void NASHandler::endElement( const XMLCh* const /* uri */ , const XMLCh* const localname, const XMLCh* const /* qname */) { char szElementName[MAX_TOKEN_SIZE]; GMLReadState *poState = m_poReader->GetState(); tr_strcpy( szElementName, localname ); m_nDepth --; if (m_bIgnoreFeature && m_nDepth >= m_nDepthFeature) { if (m_nDepth == m_nDepthFeature) { m_bIgnoreFeature = false; m_nDepthFeature = 0; } return; } if ( m_osIgnoredElement != "" && m_nDepth >= m_nDepthElement ) { if ( m_nDepth == m_nDepthElement ) { m_osIgnoredElement = ""; m_nDepthElement = 0; } return; } #ifdef DEBUG_VERBOSE CPLDebug("NAS", "%*sendElement %s m_bIgnoreFeature:%d depth:%d depthFeature:%d featureClass:%s", m_nDepth, "", szElementName, m_bIgnoreFeature, m_nDepth, m_nDepthFeature, poState->m_poFeature ? poState->m_poFeature->GetClass()->GetElementName() : "(no feature)" ); #endif if( m_bInUpdateProperty ) { if( EQUAL( szElementName, "Name" ) ) { CPLAssert( m_osLastPropertyName == "" ); m_osLastPropertyName = m_pszCurField; m_pszCurField = NULL; } else if( EQUAL( szElementName, "Value" ) ) { CPLAssert( m_osLastPropertyValue == "" ); m_osLastPropertyValue = m_pszCurField; m_pszCurField = NULL; } else if( EQUAL( szElementName, "Property" ) ) { if( EQUAL( m_osLastPropertyName, "adv:lebenszeitintervall/adv:AA_Lebenszeitintervall/adv:endet" ) ) { CPLAssert( m_osLastPropertyValue != "" ); m_osLastEnded = m_osLastPropertyValue; } else if( EQUAL( m_osLastPropertyName, "adv:anlass" ) ) { CPLAssert( m_osLastPropertyValue != "" ); m_osLastOccasion = m_osLastPropertyValue; } else { CPLError( CE_Warning, CPLE_AppDefined, "NAS: Expected property name or value instead of %s", m_osLastPropertyName.c_str() ); } m_osLastPropertyName = ""; m_osLastPropertyValue = ""; m_bInUpdateProperty = false; } poState->PopPath(); return; } if ( m_bInUpdate && EQUAL( szElementName, "Update" ) ) { m_bInUpdate = false; } /* -------------------------------------------------------------------- */ /* Is this closing off an attribute value? We assume so if */ /* we are collecting an attribute value and got to this point. */ /* We don't bother validating that the closing tag matches the */ /* opening tag. */ /* -------------------------------------------------------------------- */ if( m_pszCurField != NULL ) { CPLAssert( poState->m_poFeature != NULL ); m_poReader->SetFeaturePropertyDirectly( poState->osPath.c_str(), m_pszCurField ); m_pszCurField = NULL; } /* -------------------------------------------------------------------- */ /* If we are collecting Geometry than store it, and consider if */ /* this is the end of the geometry. */ /* -------------------------------------------------------------------- */ if( m_pszGeometry != NULL ) { int nLNLen = tr_strlen( localname ); /* should save attributes too! */ if( m_nGeomLen + nLNLen + 4 > m_nGeomAlloc ) { m_nGeomAlloc = (int) (m_nGeomAlloc * 1.3 + nLNLen + 1000); m_pszGeometry = (char *) CPLRealloc( m_pszGeometry, m_nGeomAlloc); } strcat( m_pszGeometry+m_nGeomLen, "</" ); tr_strcpy( m_pszGeometry+m_nGeomLen+2, localname ); strcat( m_pszGeometry+m_nGeomLen+nLNLen+2, ">" ); m_nGeomLen += static_cast<int>(strlen(m_pszGeometry+m_nGeomLen)); if( poState->m_nPathLength == m_nGeometryDepth+1 ) { if( poState->m_poFeature != NULL ) { CPLXMLNode* psNode = CPLParseXMLString(m_pszGeometry); if (psNode) { /* workaround for common malformed gml:pos with just a * elevation value instead of a full 3D coordinate: * * <gml:Point gml:id="BII2H"> * <gml:pos srsName="urn:adv:crs:ETRS89_h">41.394</gml:pos> * </gml:Point> * */ const char *pszPos; if( (pszPos = CPLGetXMLValue( psNode, "=Point.pos", NULL ) ) != NULL && strstr(pszPos, " ") == NULL ) { CPLSetXMLValue( psNode, "pos", CPLSPrintf("0 0 %s", pszPos) ); } if ( poState->m_poFeature->GetGeometryList() && poState->m_poFeature->GetGeometryList()[0] ) { int iId = poState->m_poFeature->GetClass()->GetPropertyIndex( "gml_id" ); const GMLProperty *poIdProp = poState->m_poFeature->GetProperty(iId); #ifdef DEBUG_VERBOSE char *pszOldGeom = CPLSerializeXMLTree( poState->m_poFeature->GetGeometryList()[0] ); CPLDebug("NAS", "Overwriting other geometry (%s; replace:%s; with:%s)", poIdProp && poIdProp->nSubProperties>0 && poIdProp->papszSubProperties[0] ? poIdProp->papszSubProperties[0] : "(null)", m_pszGeometry, pszOldGeom ); CPLFree( pszOldGeom ); #else CPLError( CE_Warning, CPLE_AppDefined, "NAS: Overwriting other geometry (%s)", poIdProp && poIdProp->nSubProperties>0 && poIdProp->papszSubProperties[0] ? poIdProp->papszSubProperties[0] : "(null)" ); #endif } poState->m_poFeature->SetGeometryDirectly( psNode ); } else CPLError( CE_Warning, CPLE_AppDefined, "NAS: Invalid geometry skipped" ); } else CPLError( CE_Warning, CPLE_AppDefined, "NAS: Skipping geometry without feature" ); CPLFree( m_pszGeometry ); m_pszGeometry = NULL; m_nGeomAlloc = m_nGeomLen = 0; } } /* -------------------------------------------------------------------- */ /* If we are collecting a feature, and this element tag matches */ /* element name for the class, then we have finished the */ /* feature, and we pop the feature read state. */ /* -------------------------------------------------------------------- */ const char *pszLast = NULL; if( m_nDepth == m_nDepthFeature && poState->m_poFeature != NULL && EQUAL(szElementName, poState->m_poFeature->GetClass()->GetElementName()) ) { m_nDepthFeature = 0; m_poReader->PopState(); } /* -------------------------------------------------------------------- */ /* Ends of a wfs:Delete or wfs:Update should be triggered on the */ /* close of the <Filter> element. */ /* -------------------------------------------------------------------- */ else if( m_nDepth == m_nDepthFeature && poState->m_poFeature != NULL && EQUAL(szElementName,"Filter") && (pszLast=poState->m_poFeature->GetClass()->GetElementName()) != NULL && ( EQUAL(pszLast, "Delete") || EQUAL(pszLast, "Update") ) ) { m_nDepthFeature = 0; m_poReader->PopState(); } /* -------------------------------------------------------------------- */ /* Otherwise, we just pop the element off the local read states */ /* element stack. */ /* -------------------------------------------------------------------- */ else { if( EQUAL(szElementName,poState->GetLastComponent()) ) poState->PopPath(); else { CPLAssert( false ); } } }
OGRErr OGRMILayerAttrIndex::LoadConfigFromXML() { FILE *fp; int nXMLSize; char *pszRawXML; CPLAssert( poINDFile == NULL ); /* -------------------------------------------------------------------- */ /* Read the XML file. */ /* -------------------------------------------------------------------- */ fp = VSIFOpen( pszMetadataFilename, "rb" ); if( fp == NULL ) return OGRERR_NONE; VSIFSeek( fp, 0, SEEK_END ); nXMLSize = VSIFTell( fp ); VSIFSeek( fp, 0, SEEK_SET ); pszRawXML = (char *) CPLMalloc(nXMLSize+1); pszRawXML[nXMLSize] = '\0'; VSIFRead( pszRawXML, nXMLSize, 1, fp ); VSIFClose( fp ); /* -------------------------------------------------------------------- */ /* Parse the XML. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psRoot = CPLParseXMLString( pszRawXML ); CPLFree( pszRawXML ); if( psRoot == NULL ) return OGRERR_FAILURE; /* -------------------------------------------------------------------- */ /* Open the index file. */ /* -------------------------------------------------------------------- */ poINDFile = new TABINDFile(); if( poINDFile->Open( pszMetadataFilename, "r+" ) != 0 ) { CPLDestroyXMLNode( psRoot ); CPLError( CE_Failure, CPLE_OpenFailed, "Failed to open index file %s.", pszMIINDFilename ); return OGRERR_FAILURE; } /* -------------------------------------------------------------------- */ /* Process each attrindex. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psAttrIndex; for( psAttrIndex = psRoot->psChild; psAttrIndex != NULL; psAttrIndex = psAttrIndex->psNext ) { int iField, iIndexIndex; if( psAttrIndex->eType != CXT_Element || !EQUAL(psAttrIndex->pszValue,"OGRMIAttrIndex") ) continue; iField = atoi(CPLGetXMLValue(psAttrIndex,"FieldIndex","-1")); iIndexIndex = atoi(CPLGetXMLValue(psAttrIndex,"IndexIndex","-1")); if( iField == -1 || iIndexIndex == -1 ) { CPLError( CE_Warning, CPLE_AppDefined, "Skipping corrupt OGRMIAttrIndex entry." ); continue; } AddAttrInd( iField, iIndexIndex ); } CPLDestroyXMLNode( psRoot ); CPLDebug( "OGR", "Restored %d field indexes for layer %s from %s on %s.", nIndexCount, poLayer->GetLayerDefn()->GetName(), pszMetadataFilename, pszMIINDFilename ); return OGRERR_NONE; }