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;
}
Exemple #3
0
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);
}
Exemple #7
0
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;
}
Exemple #8
0
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 );
}
Exemple #10
0
// ************************************************************
//		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);
	}
}
Exemple #11
0
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;
}
Exemple #13
0
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;
}
Exemple #14
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();
    }
}
Exemple #16
0
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 );
    }
}
Exemple #19
0
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;
}
Exemple #21
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;
}
Exemple #22
0
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;
}
Exemple #23
0
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;
}
Exemple #25
0
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;
}
Exemple #26
0
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;
}
Exemple #27
0
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);
}
Exemple #29
0
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 );
        }
    }
}
Exemple #30
0
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;
}