Example #1
0
static
int LookForSimpleType(CPLXMLNode *psSchemaNode,
                      const char* pszStrippedNSType,
                      GMLPropertyType *pGMLType,
                      int *pnWidth,
                      int *pnPrecision)
{
    CPLXMLNode *psThis;
    for( psThis = psSchemaNode->psChild;
         psThis != NULL; psThis = psThis->psNext )
    {
        if( psThis->eType == CXT_Element
           && EQUAL(psThis->pszValue,"simpleType")
           && EQUAL(CPLGetXMLValue(psThis,"name",""),pszStrippedNSType) )
        {
            break;
        }
    }
    if (psThis == NULL)
        return FALSE;

    return GetSimpleTypeProperties(psThis, pGMLType, pnWidth, pnPrecision);
}
Example #2
0
CPLXMLNode * SAFEDataset::GetDataObject(
    CPLXMLNode *psMetaDataObjects, CPLXMLNode *psDataObjects,
    const char *metadataObjectId)
{
/* -------------------------------------------------------------------- */
/*      Look for MetadataObject Element by ID.                          */
/* -------------------------------------------------------------------- */
    CPLXMLNode *psMDO = SAFEDataset::GetMetaDataObject(
            psMetaDataObjects, metadataObjectId);

    if (psMDO!=nullptr) {
        const char *dataObjectId = CPLGetXMLValue(
            psMDO, "dataObjectPointer.dataObjectID", "" );
        if( *dataObjectId != '\0' ) {
            return SAFEDataset::GetDataObject(psDataObjects, dataObjectId);
        }
    }

    CPLError( CE_Warning, CPLE_AppDefined,
              "DataObject not found with MetaID=%s",
              metadataObjectId);

    return nullptr;
}
Example #3
0
int OGRFMECacheIndex::ExpireOldCaches( IFMESession *poSession )

{
    CPLXMLNode *psDSNode, *psLastDSNode = NULL;
    unsigned long nCurTime = time(NULL);
    int  bChangeMade = FALSE;

    if( psTree == NULL )
        return FALSE;

    for( psLastDSNode = NULL; TRUE; psLastDSNode = psDSNode )
    {
        if( psLastDSNode != NULL )
            psDSNode = psLastDSNode->psNext;
        else
            psDSNode = psTree->psChild;
        if( psDSNode == NULL )
            break;

        if( !EQUAL(psDSNode->pszValue,"DataSource") )
            continue;
        
/* -------------------------------------------------------------------- */
/*      When was this datasource last accessed?                         */
/* -------------------------------------------------------------------- */
        unsigned long nLastUseTime = 0;

        sscanf( CPLGetXMLValue( psDSNode, "LastUseTime", "0" ), 
                "%lu", &nLastUseTime );
        
/* -------------------------------------------------------------------- */
/*      When was this datasource created.                               */
/* -------------------------------------------------------------------- */
        unsigned long nCreationTime = 0;

        sscanf( CPLGetXMLValue( psDSNode, "CreationTime", "0" ), 
                "%lu", &nCreationTime );

/* -------------------------------------------------------------------- */
/*      Do we want to delete this datasource according to our           */
/*      retention and ref timeout rules?                                */
/* -------------------------------------------------------------------- */
        int bCleanup = FALSE;

        // Do we want to cleanup this node? 
        if( atoi(CPLGetXMLValue( psDSNode, "RefCount", "0" )) > 0 
             && nLastUseTime + FMECACHE_REF_TIMEOUT < nCurTime )
            bCleanup = TRUE;

        if( atoi(CPLGetXMLValue( psDSNode, "RefCount", "0" )) < 1 
            && nLastUseTime + FMECACHE_RETENTION < nCurTime )
            bCleanup = TRUE;

        if( atoi(CPLGetXMLValue( psDSNode, "RefCount", "0" )) < 1 
            && nCreationTime + FMECACHE_MAX_RETENTION < nCurTime )
            bCleanup = TRUE;

        if( !bCleanup )
            continue;

        bChangeMade = TRUE;

        CPLDebug( "OGRFMECacheIndex", 
                  "ExpireOldCaches() cleaning up data source %s - %ds since last use, %ds old.",
                  CPLGetXMLValue( psDSNode, "DSName", "<missing name>" ),
                  nCurTime - nLastUseTime,
                  nCurTime - nCreationTime );

/* -------------------------------------------------------------------- */
/*      Loop over all the layers, to delete the spatial caches on       */
/*      disk.                                                           */
/* -------------------------------------------------------------------- */
        CPLXMLNode *psLayerN;

        for( psLayerN = psDSNode->psChild; 
             psLayerN != NULL;
             psLayerN = psLayerN->psNext )
        {
            IFMESpatialIndex   *poIndex;

            if( !EQUAL(psLayerN->pszValue,"OGRLayer") )
                continue;

            const char *pszBase;

            pszBase = CPLGetXMLValue( psLayerN, "SpatialCacheName", "" );
            if( EQUAL(pszBase,"") )
                continue;

            // open, and then delete the index on close.
            poIndex = poSession->createSpatialIndex( pszBase, "READ", NULL );

            if( poIndex == NULL )
                continue;

            if( poIndex->open() != 0 )
            {
                CPLDebug( "OGRFMECacheIndex", "Failed to open FME index %s.",
                          pszBase );
                          
                poSession->destroySpatialIndex( poIndex );
                continue;
            }
         
            poIndex->close( FME_TRUE );
            poSession->destroySpatialIndex( poIndex );
        }

/* -------------------------------------------------------------------- */
/*      Remove the datasource from the tree.                            */
/* -------------------------------------------------------------------- */
        if( psLastDSNode == NULL )
            psTree->psChild = psDSNode->psNext;
        else
            psLastDSNode->psNext = psDSNode->psNext;

        psDSNode->psNext = NULL;
        CPLDestroyXMLNode( psDSNode );
        psDSNode = psLastDSNode;
    }

    return bChangeMade;
}
Example #4
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;
}
Example #5
0
OGRLayer*  OGRVRTDataSource::InstanciateUnionLayer(
                                        CPLXMLNode *psLTree,
                                        const char *pszVRTDirectory,
                                        int bUpdate,
                                        int nRecLevel)
{
    CPLXMLNode *psSubNode;

    if( !EQUAL(psLTree->pszValue,"OGRVRTUnionLayer") )
        return NULL;

/* -------------------------------------------------------------------- */
/*      Get layer name.                                                 */
/* -------------------------------------------------------------------- */
    const char *pszLayerName = CPLGetXMLValue( psLTree, "name", NULL );

    if( pszLayerName == NULL )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Missing name attribute on OGRVRTUnionLayer" );
        return FALSE;
    }

/* -------------------------------------------------------------------- */
/*      Do we have a fixed geometry type?  If not derive from the       */
/*      source layer.                                                   */
/* -------------------------------------------------------------------- */
    const char* pszGType = CPLGetXMLValue( psLTree, "GeometryType", NULL );
    int bGlobalGeomTypeSet = FALSE;
    OGRwkbGeometryType eGlobalGeomType = wkbUnknown;
    if( pszGType != NULL )
    {
        int bError;
        bGlobalGeomTypeSet = TRUE;
        eGlobalGeomType = OGRVRTGetGeometryType(pszGType, &bError);
        if( bError )
        {
            CPLError( CE_Failure, CPLE_AppDefined,
                    "GeometryType %s not recognised.",
                    pszGType );
            return NULL;
        }
    }

/* -------------------------------------------------------------------- */
/*      Apply a spatial reference system if provided                    */
/* -------------------------------------------------------------------- */
     const char* pszLayerSRS = CPLGetXMLValue( psLTree, "LayerSRS", NULL );
     OGRSpatialReference* poGlobalSRS = NULL;
     int bGlobalSRSSet = FALSE;
     if( pszLayerSRS != NULL )
     {
         bGlobalSRSSet = TRUE;
         if( !EQUAL(pszLayerSRS,"NULL") )
         {
             OGRSpatialReference oSRS;

             if( oSRS.SetFromUserInput( pszLayerSRS ) != OGRERR_NONE )
             {
                 CPLError( CE_Failure, CPLE_AppDefined,
                           "Failed to import LayerSRS `%s'.", pszLayerSRS );
                 return FALSE;
             }
             poGlobalSRS = oSRS.Clone();
         }
     }

/* -------------------------------------------------------------------- */
/*      Find field declarations.                                        */
/* -------------------------------------------------------------------- */
    OGRFieldDefn** papoFields = NULL;
    int nFields = 0;
    OGRUnionLayerGeomFieldDefn** papoGeomFields = NULL;
    int nGeomFields = 0;

    for( psSubNode=psLTree->psChild;
         psSubNode != NULL;
         psSubNode=psSubNode->psNext )
    {
         if( psSubNode->eType != CXT_Element )
             continue;

         if( psSubNode->eType == CXT_Element && EQUAL(psSubNode->pszValue,"Field") )
         {
/* -------------------------------------------------------------------- */
/*      Field name.                                                     */
/* -------------------------------------------------------------------- */
             const char *pszName = CPLGetXMLValue( psSubNode, "name", NULL );
             if( pszName == NULL )
             {
                 CPLError( CE_Failure, CPLE_AppDefined,
                           "Unable to identify Field name." );
                 break;
             }

             OGRFieldDefn oFieldDefn( pszName, OFTString );

/* -------------------------------------------------------------------- */
/*      Type                                                            */
/* -------------------------------------------------------------------- */
             const char *pszArg = CPLGetXMLValue( psSubNode, "type", NULL );

             if( pszArg != NULL )
             {
                 int iType;

                 for( iType = 0; iType <= (int) OFTMaxType; iType++ )
                 {
                     if( EQUAL(pszArg,OGRFieldDefn::GetFieldTypeName(
                                   (OGRFieldType)iType)) )
                     {
                         oFieldDefn.SetType( (OGRFieldType) iType );
                         break;
                     }
                 }

                 if( iType > (int) OFTMaxType )
                 {
                     CPLError( CE_Failure, CPLE_AppDefined,
                               "Unable to identify Field type '%s'.",
                               pszArg );
                     break;
                 }
             }

/* -------------------------------------------------------------------- */
/*      Width and precision.                                            */
/* -------------------------------------------------------------------- */
             int nWidth = atoi(CPLGetXMLValue( psSubNode, "width", "0" ));
             if (nWidth < 0)
             {
                CPLError( CE_Failure, CPLE_IllegalArg,
                          "Invalid width for field %s.",
                          pszName );
                break;
             }
             oFieldDefn.SetWidth(nWidth);

             int nPrecision = atoi(CPLGetXMLValue( psSubNode, "precision", "0" ));
             if (nPrecision < 0 || nPrecision > 1024)
             {
                CPLError( CE_Failure, CPLE_IllegalArg,
                          "Invalid precision for field %s.",
                          pszName );
                break;
             }
             oFieldDefn.SetPrecision(nPrecision);

             papoFields = (OGRFieldDefn**) CPLRealloc(papoFields,
                                        sizeof(OGRFieldDefn*) * (nFields + 1));
             papoFields[nFields] = new OGRFieldDefn(&oFieldDefn);
             nFields ++;
         }

         else if( psSubNode->eType == CXT_Element &&
                  EQUAL(psSubNode->pszValue,"GeometryField") )
         {
             const char *pszName = CPLGetXMLValue( psSubNode, "name", NULL );
             if( pszName == NULL )
             {
                 CPLError( CE_Failure, CPLE_AppDefined,
                           "Unable to identify GeometryField name." );
                 break;
             }

             pszGType = CPLGetXMLValue( psSubNode, "GeometryType", NULL );
             if( pszGType == NULL && nGeomFields == 0 )
                 pszGType = CPLGetXMLValue( psLTree, "GeometryType", NULL );
             OGRwkbGeometryType eGeomType = wkbUnknown;
             int bGeomTypeSet = FALSE;
             if( pszGType != NULL )
             {
                int bError;
                eGeomType = OGRVRTGetGeometryType(pszGType, &bError);
                bGeomTypeSet = TRUE;
                if( bError || eGeomType == wkbNone )
                {
                    CPLError( CE_Failure, CPLE_AppDefined,
                            "GeometryType %s not recognised.",
                            pszGType );
                    break;
                }
             }

             const char* pszSRS = CPLGetXMLValue( psSubNode, "SRS", NULL );
             if( pszSRS == NULL && nGeomFields == 0 )
                 pszSRS = CPLGetXMLValue( psLTree, "LayerSRS", NULL );
             OGRSpatialReference* poSRS = NULL;
             int bSRSSet = FALSE;
             if( pszSRS != NULL )
             {
                 bSRSSet = TRUE;
                 if( !EQUAL(pszSRS,"NULL") )
                 {
                    OGRSpatialReference oSRS;

                    if( oSRS.SetFromUserInput( pszSRS ) != OGRERR_NONE )
                    {
                        CPLError( CE_Failure, CPLE_AppDefined,
                                "Failed to import SRS `%s'.", pszSRS );
                        break;
                    }
                    poSRS = oSRS.Clone();
                }
             }

             OGRUnionLayerGeomFieldDefn* poFieldDefn =
                    new OGRUnionLayerGeomFieldDefn(pszName, eGeomType);
             if( poSRS != NULL )
             {
                poFieldDefn->SetSpatialRef(poSRS);
                poSRS->Dereference();
             }
             poFieldDefn->bGeomTypeSet = bGeomTypeSet;
             poFieldDefn->bSRSSet = bSRSSet;

             const char* pszExtentXMin = CPLGetXMLValue( psSubNode, "ExtentXMin", NULL );
             const char* pszExtentYMin = CPLGetXMLValue( psSubNode, "ExtentYMin", NULL );
             const char* pszExtentXMax = CPLGetXMLValue( psSubNode, "ExtentXMax", NULL );
             const char* pszExtentYMax = CPLGetXMLValue( psSubNode, "ExtentYMax", NULL );
             if( pszExtentXMin != NULL && pszExtentYMin != NULL &&
                 pszExtentXMax != NULL && pszExtentYMax != NULL )
             {
                poFieldDefn->sStaticEnvelope.MinX = CPLAtof(pszExtentXMin);
                poFieldDefn->sStaticEnvelope.MinY = CPLAtof(pszExtentYMin);
                poFieldDefn->sStaticEnvelope.MaxX = CPLAtof(pszExtentXMax);
                poFieldDefn->sStaticEnvelope.MaxY = CPLAtof(pszExtentYMax);
             }

             papoGeomFields = (OGRUnionLayerGeomFieldDefn**) CPLRealloc(papoGeomFields,
                                        sizeof(OGRUnionLayerGeomFieldDefn*) * (nGeomFields + 1));
             papoGeomFields[nGeomFields] = poFieldDefn;
             nGeomFields ++;
         }
    }

/* -------------------------------------------------------------------- */
/*      Set Extent if provided                                          */
/* -------------------------------------------------------------------- */
    const char* pszExtentXMin = CPLGetXMLValue( psLTree, "ExtentXMin", NULL );
    const char* pszExtentYMin = CPLGetXMLValue( psLTree, "ExtentYMin", NULL );
    const char* pszExtentXMax = CPLGetXMLValue( psLTree, "ExtentXMax", NULL );
    const char* pszExtentYMax = CPLGetXMLValue( psLTree, "ExtentYMax", NULL );

    if( eGlobalGeomType != wkbNone && nGeomFields == 0 &&
        (bGlobalGeomTypeSet || bGlobalSRSSet ||
         (pszExtentXMin != NULL && pszExtentYMin != NULL &&
          pszExtentXMax != NULL && pszExtentYMax != NULL)) )
    {
        OGRUnionLayerGeomFieldDefn* poFieldDefn =
                new OGRUnionLayerGeomFieldDefn("", eGlobalGeomType);
        if( poGlobalSRS != NULL )
        {
            poFieldDefn->SetSpatialRef(poGlobalSRS);
            poGlobalSRS->Dereference();
            poGlobalSRS = NULL;
        }
        poFieldDefn->bGeomTypeSet = bGlobalGeomTypeSet;
        poFieldDefn->bSRSSet = bGlobalSRSSet;
        if( pszExtentXMin != NULL && pszExtentYMin != NULL &&
            pszExtentXMax != NULL && pszExtentYMax != NULL )
        {
            poFieldDefn->sStaticEnvelope.MinX = CPLAtof(pszExtentXMin);
            poFieldDefn->sStaticEnvelope.MinY = CPLAtof(pszExtentYMin);
            poFieldDefn->sStaticEnvelope.MaxX = CPLAtof(pszExtentXMax);
            poFieldDefn->sStaticEnvelope.MaxY = CPLAtof(pszExtentYMax);
        }

        papoGeomFields = (OGRUnionLayerGeomFieldDefn**) CPLRealloc(papoGeomFields,
                                sizeof(OGRUnionLayerGeomFieldDefn*) * (nGeomFields + 1));
        papoGeomFields[nGeomFields] = poFieldDefn;
        nGeomFields ++;
    }
    else
    {
        delete poGlobalSRS;
        poGlobalSRS = NULL;
    }

/* -------------------------------------------------------------------- */
/*      Find source layers                                              */
/* -------------------------------------------------------------------- */

    int nSrcLayers = 0;
    OGRLayer** papoSrcLayers = NULL;

    for( psSubNode=psLTree->psChild;
         psSubNode != NULL;
         psSubNode=psSubNode->psNext )
    {
        if( psSubNode->eType != CXT_Element )
            continue;

        OGRLayer* poSrcLayer = InstanciateLayer(psSubNode, pszVRTDirectory,
                                           bUpdate, nRecLevel + 1);
        if( poSrcLayer != NULL )
        {
            papoSrcLayers = (OGRLayer**)
                CPLRealloc(papoSrcLayers, sizeof(OGRLayer*) * (nSrcLayers + 1));
            papoSrcLayers[nSrcLayers] = poSrcLayer;
            nSrcLayers ++;
        }
    }

    if( nSrcLayers == 0 )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Cannot find source layers" );
        int iField;
        for(iField = 0; iField < nFields; iField++)
            delete papoFields[iField];
        CPLFree(papoFields);
        for(iField = 0; iField < nGeomFields; iField++)
            delete papoGeomFields[iField];
        CPLFree(papoGeomFields);
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Build the OGRUnionLayer.                                        */
/* -------------------------------------------------------------------- */
    OGRUnionLayer* poLayer = new OGRUnionLayer( pszLayerName,
                                                nSrcLayers,
                                                papoSrcLayers,
                                                TRUE );

/* -------------------------------------------------------------------- */
/*      Set the source layer field name attribute.                      */
/* -------------------------------------------------------------------- */
    const char* pszSourceLayerFieldName =
        CPLGetXMLValue( psLTree, "SourceLayerFieldName", NULL );
    poLayer->SetSourceLayerFieldName(pszSourceLayerFieldName);

/* -------------------------------------------------------------------- */
/*      Set the PreserveSrcFID attribute.                               */
/* -------------------------------------------------------------------- */
    int bPreserveSrcFID = FALSE;
    const char* pszPreserveFID = CPLGetXMLValue( psLTree, "PreserveSrcFID", NULL );
    if( pszPreserveFID != NULL )
        bPreserveSrcFID = CSLTestBoolean(pszPreserveFID);
    poLayer->SetPreserveSrcFID(bPreserveSrcFID);

/* -------------------------------------------------------------------- */
/*      Set fields                                                      */
/* -------------------------------------------------------------------- */
    FieldUnionStrategy eFieldStrategy = FIELD_UNION_ALL_LAYERS;
    const char* pszFieldStrategy = CPLGetXMLValue( psLTree, "FieldStrategy", NULL );
    if( pszFieldStrategy != NULL )
    {
        if( EQUAL(pszFieldStrategy, "FirstLayer") )
            eFieldStrategy = FIELD_FROM_FIRST_LAYER;
        else if( EQUAL(pszFieldStrategy, "Union") )
            eFieldStrategy = FIELD_UNION_ALL_LAYERS;
        else if( EQUAL(pszFieldStrategy, "Intersection") )
            eFieldStrategy = FIELD_INTERSECTION_ALL_LAYERS;
        else
        {
            CPLError( CE_Warning, CPLE_AppDefined,
                      "Unhandled value for FieldStrategy `%s'.", pszFieldStrategy );
        }
    }
    if( nFields != 0 || nGeomFields > 1 )
    {
        if( pszFieldStrategy != NULL )
            CPLError( CE_Warning, CPLE_AppDefined,
                      "Ignoring FieldStrategy value, because explicit Field or GeometryField is provided") ;
        eFieldStrategy = FIELD_SPECIFIED;
    }

    poLayer->SetFields(eFieldStrategy, nFields, papoFields,
                       (nGeomFields == 0 && eGlobalGeomType == wkbNone) ? -1 : nGeomFields,
                       papoGeomFields);
    int iField;
    for(iField = 0; iField < nFields; iField++)
        delete papoFields[iField];
    CPLFree(papoFields);
    for(iField = 0; iField < nGeomFields; iField++)
        delete papoGeomFields[iField];
    CPLFree(papoGeomFields);

/* -------------------------------------------------------------------- */
/*      Set FeatureCount if provided                                    */
/* -------------------------------------------------------------------- */
    const char* pszFeatureCount = CPLGetXMLValue( psLTree, "FeatureCount", NULL );
    if( pszFeatureCount != NULL )
    {
        poLayer->SetFeatureCount(atoi(pszFeatureCount));
    }

    return poLayer;
}
Example #6
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 );
        }
    }
}
Example #7
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;
}
Example #8
0
GDALDataset *TSXDataset::Open( GDALOpenInfo *poOpenInfo ) {
/* -------------------------------------------------------------------- */
/*      Is this a TerraSAR-X product file?                              */
/* -------------------------------------------------------------------- */
    if (!TSXDataset::Identify( poOpenInfo ))
    {
        return NULL; /* nope */
    }

/* -------------------------------------------------------------------- */
/*      Confirm the requested access is supported.                      */
/* -------------------------------------------------------------------- */
    if( poOpenInfo->eAccess == GA_Update )
    {
        CPLError( CE_Failure, CPLE_NotSupported,
                  "The TSX driver does not support update access to existing"
                  " datasets.\n" );
        return NULL;
    }

    CPLString osFilename;

    if( poOpenInfo->bIsDirectory )
    {
        osFilename =
            CPLFormCIFilename( poOpenInfo->pszFilename,
                               CPLGetFilename( poOpenInfo->pszFilename ),
                               "xml" );
    }
    else
        osFilename = poOpenInfo->pszFilename;

    /* Ingest the XML */
    CPLXMLNode *psData = CPLParseXMLFile( osFilename );
    if (psData == NULL)
        return NULL;

    /* find the product components */
    CPLXMLNode *psComponents
        = CPLGetXMLNode( psData, "=level1Product.productComponents" );
    if (psComponents == NULL) {
        CPLError( CE_Failure, CPLE_OpenFailed,
            "Unable to find <productComponents> tag in file.\n" );
        CPLDestroyXMLNode(psData);
        return NULL;
    }

    /* find the product info tag */
    CPLXMLNode *psProductInfo
        = CPLGetXMLNode( psData, "=level1Product.productInfo" );
    if (psProductInfo == NULL) {
        CPLError( CE_Failure, CPLE_OpenFailed,
            "Unable to find <productInfo> tag in file.\n" );
        CPLDestroyXMLNode(psData);
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Create the dataset.                                             */
/* -------------------------------------------------------------------- */

    TSXDataset *poDS = new TSXDataset();

/* -------------------------------------------------------------------- */
/*      Read in product info.                                           */
/* -------------------------------------------------------------------- */

    poDS->SetMetadataItem( "SCENE_CENTRE_TIME", CPLGetXMLValue( psProductInfo,
        "sceneInfo.sceneCenterCoord.azimuthTimeUTC", "unknown" ) );
    poDS->SetMetadataItem( "OPERATIONAL_MODE", CPLGetXMLValue( psProductInfo,
        "generationInfo.groundOperationsType", "unknown" ) );
    poDS->SetMetadataItem( "ORBIT_CYCLE", CPLGetXMLValue( psProductInfo,
        "missionInfo.orbitCycle", "unknown" ) );
    poDS->SetMetadataItem( "ABSOLUTE_ORBIT", CPLGetXMLValue( psProductInfo,
        "missionInfo.absOrbit", "unknown" ) );
    poDS->SetMetadataItem( "ORBIT_DIRECTION", CPLGetXMLValue( psProductInfo,
        "missionInfo.orbitDirection", "unknown" ) );
    poDS->SetMetadataItem( "IMAGING_MODE", CPLGetXMLValue( psProductInfo,
        "acquisitionInfo.imagingMode", "unknown" ) );
    poDS->SetMetadataItem( "PRODUCT_VARIANT", CPLGetXMLValue( psProductInfo,
        "productVariantInfo.productVariant", "unknown" ) );
    char *pszDataType = CPLStrdup( CPLGetXMLValue( psProductInfo,
        "imageDataInfo.imageDataType", "unknown" ) );
    poDS->SetMetadataItem( "IMAGE_TYPE", pszDataType );

    /* Get raster information */
    int nRows = atoi( CPLGetXMLValue( psProductInfo,
        "imageDataInfo.imageRaster.numberOfRows", "" ) );
    int nCols = atoi( CPLGetXMLValue( psProductInfo,
        "imageDataInfo.imageRaster.numberOfColumns", "" ) );

    poDS->nRasterXSize = nCols;
    poDS->nRasterYSize = nRows;

    poDS->SetMetadataItem( "ROW_SPACING", CPLGetXMLValue( psProductInfo,
        "imageDataInfo.imageRaster.rowSpacing", "unknown" ) );
    poDS->SetMetadataItem( "COL_SPACING", CPLGetXMLValue( psProductInfo,
        "imageDataInfo.imageRaster.columnSpacing", "unknown" ) );
    poDS->SetMetadataItem( "COL_SPACING_UNITS", CPLGetXMLValue( psProductInfo,
        "imageDataInfo.imageRaster.columnSpacing.units", "unknown" ) );

    /* Get equivalent number of looks */
    poDS->SetMetadataItem( "AZIMUTH_LOOKS", CPLGetXMLValue( psProductInfo,
        "imageDataInfo.imageRaster.azimuthLooks", "unknown" ) );
    poDS->SetMetadataItem( "RANGE_LOOKS", CPLGetXMLValue( psProductInfo,
        "imageDataInfo.imageRaster.rangeLooks", "unknown" ) );

    const char *pszProductVariant = CPLGetXMLValue( psProductInfo,
        "productVariantInfo.productVariant", "unknown" );

    poDS->SetMetadataItem( "PRODUCT_VARIANT", pszProductVariant );

    /* Determine what product variant this is */
    if (STARTS_WITH_CI(pszProductVariant, "SSC"))
        poDS->nProduct = eSSC;
    else if (STARTS_WITH_CI(pszProductVariant, "MGD"))
        poDS->nProduct = eMGD;
    else if (STARTS_WITH_CI(pszProductVariant, "EEC"))
        poDS->nProduct = eEEC;
    else if (STARTS_WITH_CI(pszProductVariant, "GEC"))
        poDS->nProduct = eGEC;
    else
        poDS->nProduct = eUnknown;

    /* Start reading in the product components */
    char *pszGeorefFile = NULL;
    CPLErr geoTransformErr=CE_Failure;
    for ( CPLXMLNode *psComponent = psComponents->psChild;
          psComponent != NULL;
          psComponent = psComponent->psNext)
    {
        const char *pszType = NULL;
        const char *pszPath = CPLFormFilename(
                CPLGetDirname( osFilename ),
                GetFilePath(psComponent, &pszType),
                "" );
        const char *pszPolLayer = CPLGetXMLValue(psComponent, "polLayer", " ");

        if ( !STARTS_WITH_CI(pszType, " ") ) {
            if (STARTS_WITH_CI(pszType, "MAPPING_GRID") ) {
                /* the mapping grid... save as a metadata item this path */
                poDS->SetMetadataItem( "MAPPING_GRID", pszPath );
            }
            else if (STARTS_WITH_CI(pszType, "GEOREF")) {
                /* save the path to the georef data for later use */
                CPLFree( pszGeorefFile );
                pszGeorefFile = CPLStrdup( pszPath );
            }
        }
        else if( !STARTS_WITH_CI(pszPolLayer, " ") &&
            STARTS_WITH_CI(psComponent->pszValue, "imageData") ) {
            /* determine the polarization of this band */
            ePolarization ePol;
            if ( STARTS_WITH_CI(pszPolLayer, "HH") ) {
                ePol = HH;
            }
            else if ( STARTS_WITH_CI(pszPolLayer, "HV") ) {
                ePol = HV;
            }
            else if ( STARTS_WITH_CI(pszPolLayer, "VH") ) {
                ePol = VH;
            }
            else {
                ePol = VV;
            }

            GDALDataType eDataType = STARTS_WITH_CI(pszDataType, "COMPLEX") ?
                GDT_CInt16 : GDT_UInt16;

            /* try opening the file that represents that band */
            GDALDataset *poBandData = reinterpret_cast<GDALDataset *>(
                GDALOpen( pszPath, GA_ReadOnly ) );
            if ( poBandData != NULL ) {
                TSXRasterBand *poBand
                    = new TSXRasterBand( poDS, eDataType, ePol, poBandData );
                poDS->SetBand( poDS->GetRasterCount() + 1, poBand );

                //copy georeferencing info from the band
                //need error checking??
                //it will just save the info from the last band
                CPLFree( poDS->pszProjection );
                poDS->pszProjection = CPLStrdup(poBandData->GetProjectionRef());
                geoTransformErr = poBandData->GetGeoTransform(poDS->adfGeoTransform);
            }
        }
    }

    //now check if there is a geotransform
    if ( strcmp(poDS->pszProjection, "") && geoTransformErr==CE_None)
    {
        poDS->bHaveGeoTransform = TRUE;
    }
    else
    {
        poDS->bHaveGeoTransform = FALSE;
        CPLFree( poDS->pszProjection );
        poDS->pszProjection = CPLStrdup("");
        poDS->adfGeoTransform[0] = 0.0;
        poDS->adfGeoTransform[1] = 1.0;
        poDS->adfGeoTransform[2] = 0.0;
        poDS->adfGeoTransform[3] = 0.0;
        poDS->adfGeoTransform[4] = 0.0;
        poDS->adfGeoTransform[5] = 1.0;
    }

    CPLFree(pszDataType);

/* -------------------------------------------------------------------- */
/*      Check and set matrix representation.                            */
/* -------------------------------------------------------------------- */

    if (poDS->GetRasterCount() == 4) {
        poDS->SetMetadataItem( "MATRIX_REPRESENTATION", "SCATTERING" );
    }

/* -------------------------------------------------------------------- */
/*      Read the four corners and centre GCPs in                        */
/* -------------------------------------------------------------------- */

    CPLXMLNode *psSceneInfo = CPLGetXMLNode( psData,
        "=level1Product.productInfo.sceneInfo" );
    if (psSceneInfo != NULL)
    {
        /* extract the GCPs from the provided file */
        bool success = false;
        if (pszGeorefFile != NULL)
            success = poDS->getGCPsFromGEOREF_XML(pszGeorefFile);

        //if the gcp's cannot be extracted from the georef file, try to get the corner coordinates
        //for now just SSC because the others don't have refColumn and refRow
        if (!success && poDS->nProduct == eSSC)
        {
            int nGCP = 0;
            double dfAvgHeight = CPLAtof(CPLGetXMLValue(psSceneInfo,
                "sceneAverageHeight", "0.0"));

            //count and allocate gcps - there should be five - 4 corners and a centre
            poDS->nGCPCount = 0;
            CPLXMLNode *psNode = psSceneInfo->psChild;
            for ( ; psNode != NULL; psNode = psNode->psNext )
            {
                if (!EQUAL(psNode->pszValue, "sceneCenterCoord") &&
                    !EQUAL(psNode->pszValue, "sceneCornerCoord"))
                    continue;

                poDS->nGCPCount++;
            }
            if (poDS->nGCPCount > 0)
            {
                poDS->pasGCPList = (GDAL_GCP *)CPLCalloc(sizeof(GDAL_GCP), poDS->nGCPCount);

                /* iterate over GCPs */
                for (psNode = psSceneInfo->psChild; psNode != NULL; psNode = psNode->psNext )
                {
                    GDAL_GCP *psGCP = poDS->pasGCPList + nGCP;

                    if (!EQUAL(psNode->pszValue, "sceneCenterCoord") &&
                        !EQUAL(psNode->pszValue, "sceneCornerCoord"))
                        continue;

                    psGCP->dfGCPPixel = CPLAtof(CPLGetXMLValue(psNode, "refColumn",
                        "0.0"));
                    psGCP->dfGCPLine = CPLAtof(CPLGetXMLValue(psNode, "refRow", "0.0"));
                    psGCP->dfGCPX = CPLAtof(CPLGetXMLValue(psNode, "lon", "0.0"));
                    psGCP->dfGCPY = CPLAtof(CPLGetXMLValue(psNode, "lat", "0.0"));
                    psGCP->dfGCPZ = dfAvgHeight;
                    psGCP->pszId = CPLStrdup( CPLSPrintf( "%d", nGCP ) );
                    psGCP->pszInfo = CPLStrdup("");

                    nGCP++;
                }

                //set the projection string - the fields are lat/long - seems to be WGS84 datum
                OGRSpatialReference osr;
                osr.SetWellKnownGeogCS( "WGS84" );
                CPLFree(poDS->pszGCPProjection);
                osr.exportToWkt( &(poDS->pszGCPProjection) );
            }
        }

        //gcps override geotransform - does it make sense to have both??
        if (poDS->nGCPCount>0)
        {
            poDS->bHaveGeoTransform = FALSE;
            CPLFree( poDS->pszProjection );
            poDS->pszProjection = CPLStrdup("");
            poDS->adfGeoTransform[0] = 0.0;
            poDS->adfGeoTransform[1] = 1.0;
            poDS->adfGeoTransform[2] = 0.0;
            poDS->adfGeoTransform[3] = 0.0;
            poDS->adfGeoTransform[4] = 0.0;
            poDS->adfGeoTransform[5] = 1.0;
        }

    }
    else {
        CPLError(CE_Warning, CPLE_AppDefined,
            "Unable to find sceneInfo tag in XML document. "
            "Proceeding with caution.");
    }

    CPLFree(pszGeorefFile);

/* -------------------------------------------------------------------- */
/*      Initialize any PAM information.                                 */
/* -------------------------------------------------------------------- */
    poDS->SetDescription( poOpenInfo->pszFilename );
    poDS->TryLoadXML();

/* -------------------------------------------------------------------- */
/*      Check for overviews.                                            */
/* -------------------------------------------------------------------- */
    poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename );

    CPLDestroyXMLNode(psData);

    return poDS;
}
Example #9
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;
}
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);
}
Example #11
0
static OGRGeometry* ParseKMLGeometry(/* const */ CPLXMLNode* psXML)
{
    OGRGeometry* poGeom = nullptr;
    const char* pszGeomType = psXML->pszValue;
    if (strcmp(pszGeomType, "Point") == 0)
    {
        const char* pszCoordinates = CPLGetXMLValue(psXML, "coordinates", nullptr);
        if (pszCoordinates)
        {
            char** papszTokens = CSLTokenizeString2(pszCoordinates, ",", 0);
            if (CSLCount(papszTokens) == 2)
                poGeom = new OGRPoint(CPLAtof(papszTokens[0]), CPLAtof(papszTokens[1]));
            else if (CSLCount(papszTokens) == 3)
                poGeom = new OGRPoint(CPLAtof(papszTokens[0]), CPLAtof(papszTokens[1]),
                                      CPLAtof(papszTokens[2]));
            CSLDestroy(papszTokens);
        }
    }
    else if (strcmp(pszGeomType, "LineString") == 0)
    {
        const char* pszCoordinates = CPLGetXMLValue(psXML, "coordinates", nullptr);
        if (pszCoordinates)
        {
            OGRLineString* poLS = new OGRLineString();
            ParseLineString(poLS, pszCoordinates);
            poGeom = poLS;
        }
    }
    else if (strcmp(pszGeomType, "Polygon") == 0)
    {
        OGRPolygon* poPoly = nullptr;
        CPLXMLNode* psOuterBoundary = CPLGetXMLNode(psXML, "outerBoundaryIs");
        if (psOuterBoundary)
        {
            CPLXMLNode* psLinearRing = CPLGetXMLNode(psOuterBoundary, "LinearRing");
            const char* pszCoordinates = CPLGetXMLValue(
                psLinearRing ? psLinearRing : psOuterBoundary, "coordinates", nullptr);
            if (pszCoordinates)
            {
                OGRLinearRing* poLS = new OGRLinearRing();
                ParseLineString(poLS, pszCoordinates);
                poPoly = new OGRPolygon();
                poPoly->addRingDirectly(poLS);
                poGeom = poPoly;
            }

            if (poPoly)
            {
                CPLXMLNode* psIter = psXML->psChild;
                while(psIter)
                {
                    if (psIter->eType == CXT_Element &&
                        strcmp(psIter->pszValue, "innerBoundaryIs") == 0)
                    {
                        psLinearRing = CPLGetXMLNode(psIter, "LinearRing");
                        pszCoordinates = CPLGetXMLValue(
                            psLinearRing ? psLinearRing : psIter, "coordinates", nullptr);
                        if (pszCoordinates)
                        {
                            OGRLinearRing* poLS = new OGRLinearRing();
                            ParseLineString(poLS, pszCoordinates);
                            poPoly->addRingDirectly(poLS);
                        }
                    }
                    psIter = psIter->psNext;
                }
            }
        }
    }
    else if (strcmp(pszGeomType, "MultiGeometry") == 0)
    {
        CPLXMLNode* psIter = nullptr;
        OGRwkbGeometryType eType = wkbUnknown;
        for(psIter = psXML->psChild; psIter; psIter = psIter->psNext)
        {
            if (psIter->eType == CXT_Element)
            {
                OGRwkbGeometryType eNewType = wkbUnknown;
                if (strcmp(psIter->pszValue, "Point") == 0)
                {
                    eNewType = wkbPoint;
                }
                else if (strcmp(psIter->pszValue, "LineString") == 0)
                {
                    eNewType = wkbLineString;
                }
                else if (strcmp(psIter->pszValue, "Polygon") == 0)
                {
                    eNewType = wkbPolygon;
                }
                else
                    break;
                if (eType == wkbUnknown)
                    eType = eNewType;
                else if (eType != eNewType)
                    break;
            }
        }
        OGRGeometryCollection* poColl = nullptr;
        if (psIter != nullptr)
            poColl = new OGRGeometryCollection();
        else if (eType == wkbPoint)
            poColl = new OGRMultiPoint();
        else if (eType == wkbLineString)
            poColl = new OGRMultiLineString();
        else if (eType == wkbPolygon)
            poColl = new OGRMultiPolygon();
        else {
            CPLAssert(false);
        }

        for(psIter = psXML->psChild; psIter; psIter = psIter->psNext)
        {
            if (psIter->eType == CXT_Element)
            {
                OGRGeometry* poSubGeom = ParseKMLGeometry(psIter);
                if (poSubGeom)
                    poColl->addGeometryDirectly(poSubGeom);
            }
        }

        poGeom = poColl;
    }

    return poGeom;
}
CPLErr GDALWMSMiniDriver_AGS::Initialize(CPLXMLNode *config)
{
	CPLErr ret = CE_None;
	int i;

    if (ret == CE_None) 
    {
        const char *base_url = CPLGetXMLValue(config, "ServerURL", "");
        if (base_url[0] != '\0') 
        {
            /* Try the old name */
            base_url = CPLGetXMLValue(config, "ServerUrl", "");
        }
        
        if (base_url[0] != '\0') 
        {
            m_base_url = base_url;
        }
        else 
        {
            CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS, ArcGIS Server mini-driver: ServerURL missing.");
            ret = CE_Failure;
        }
    }

	if (ret == CE_None) 
	{
        m_image_format = CPLGetXMLValue(config, "ImageFormat", "png");
        m_transparent = CPLGetXMLValue(config, "Transparent","");
		// the transparent flag needs to be "true" or "false" 
		// in lower case according to the ArcGIS Server REST API
        for(i = 0; i < (int)m_transparent.size(); i++)
        {
			m_transparent[i] = (char) tolower(m_transparent[i]);
        }
        
		m_layers = CPLGetXMLValue(config, "Layers", "");
    }
    
	if (ret == CE_None) 
	{
		const char* irs = CPLGetXMLValue(config, "SRS", "102100");
		
		if (irs != NULL)
		{
	        if(EQUALN(irs, "EPSG:", 5)) //if we have EPSG code just convert it to WKT
	        {
	            m_projection_wkt = ProjToWKT(irs);
	            m_irs = irs + 5;
	        }
	        else //if we have AGS code - try if it's EPSG
		    {
		        m_irs = irs;
		        m_projection_wkt = ProjToWKT("EPSG:" + m_irs);
		    }
		    // TODO: if we have AGS JSON    
		}
		m_identification_tolerance = CPLGetXMLValue(config, "IdentificationTolerance", "2");
	}

	if (ret == CE_None)
	{
        const char *bbox_order = CPLGetXMLValue(config, "BBoxOrder", "xyXY");
        if (bbox_order[0] != '\0') 
        {
            for (i = 0; i < 4; ++i) 
            {
                if ((bbox_order[i] != 'x') && (bbox_order[i] != 'y') && 
                    (bbox_order[i] != 'X') && (bbox_order[i] != 'Y')) 
                    break;
            }
            
            if (i == 4) 
            {
                m_bbox_order = bbox_order;
            } 
            else 
            {
                CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS, ArcGIS Server mini-driver: Incorrect BBoxOrder.");
                ret = CE_Failure;
            }
        } 
        else
        {
            CPLError(CE_Failure, CPLE_AppDefined, "GDALWMS, ArcGIS Server mini-driver: BBoxOrder missing.");
            ret = CE_Failure;
        }
    }
	
    return ret;
}
Example #13
0
VSIVirtualHandle *
VSISparseFileFilesystemHandler::Open( const char *pszFilename, 
                                      const char *pszAccess )

{
    CPLAssert( EQUALN(pszFilename,"/vsisparse/", 11) );

    if( !EQUAL(pszAccess,"r") && !EQUAL(pszAccess,"rb") )
    {
        errno = EACCES;
        return NULL;
    }

    /* Arbitrary number */
    if( GetRecCounter() == 32 )
        return NULL;

    CPLString osSparseFilePath = pszFilename + 11;

/* -------------------------------------------------------------------- */
/*      Does this file even exist?                                      */
/* -------------------------------------------------------------------- */
    VSILFILE *fp = VSIFOpenL( osSparseFilePath, "r" );
    if( fp == NULL )
        return NULL;
    VSIFCloseL( fp );

/* -------------------------------------------------------------------- */
/*      Read the XML file.                                              */
/* -------------------------------------------------------------------- */
    CPLXMLNode *psXMLRoot = CPLParseXMLFile( osSparseFilePath );

    if( psXMLRoot == NULL )
        return NULL;

/* -------------------------------------------------------------------- */
/*      Setup the file handle on this file.                             */
/* -------------------------------------------------------------------- */
    VSISparseFileHandle *poHandle = new VSISparseFileHandle(this);

/* -------------------------------------------------------------------- */
/*      Translate the desired fields out of the XML tree.               */
/* -------------------------------------------------------------------- */
    CPLXMLNode *psRegion;

    for( psRegion = psXMLRoot->psChild;
         psRegion != NULL;
         psRegion = psRegion->psNext )
    {
        if( psRegion->eType != CXT_Element )
            continue;

        if( !EQUAL(psRegion->pszValue,"SubfileRegion")
            && !EQUAL(psRegion->pszValue,"ConstantRegion") )
            continue;

        SFRegion oRegion;

        oRegion.osFilename = CPLGetXMLValue( psRegion, "Filename", "" );
        if( atoi(CPLGetXMLValue( psRegion, "Filename.relative", "0" )) != 0 )
        {
            CPLString osSFPath = CPLGetPath(osSparseFilePath);
            oRegion.osFilename = CPLFormFilename( osSFPath,
                                                  oRegion.osFilename, NULL );
        }

        oRegion.nDstOffset = 
            CPLScanUIntBig( CPLGetXMLValue(psRegion,"DestinationOffset","0" ),
                            32 );

        oRegion.nSrcOffset = 
            CPLScanUIntBig( CPLGetXMLValue(psRegion,"SourceOffset","0" ), 32);

        oRegion.nLength = 
            CPLScanUIntBig( CPLGetXMLValue(psRegion,"RegionLength","0" ), 32);

        oRegion.byValue = (GByte) atoi(CPLGetXMLValue(psRegion,"Value","0" ));

        poHandle->aoRegions.push_back( oRegion );
    }

/* -------------------------------------------------------------------- */
/*      Get sparse file length, use maximum bound of regions if not     */
/*      explicit in file.                                               */
/* -------------------------------------------------------------------- */
    poHandle->nOverallLength = 
        CPLScanUIntBig( CPLGetXMLValue(psXMLRoot,"Length","0" ), 32);
    if( poHandle->nOverallLength == 0 )
    {
        for( unsigned int i = 0; i < poHandle->aoRegions.size(); i++ )
        {
            poHandle->nOverallLength = MAX(poHandle->nOverallLength,
                                           poHandle->aoRegions[i].nDstOffset
                                           + poHandle->aoRegions[i].nLength);
        }
    }

    CPLDestroyXMLNode( psXMLRoot );

    return poHandle;
}
Example #14
0
GDALDataset* ECRGTOCDataset::Build(const char* pszTOCFilename,
                                   CPLXMLNode* psXML,
                                   CPLString osProduct,
                                   CPLString osDiscId,
                                   const char* pszOpenInfoFilename)
{
    CPLXMLNode* psTOC = CPLGetXMLNode(psXML, "=Table_of_Contents");
    if (psTOC == NULL)
    {
        CPLError(CE_Warning, CPLE_AppDefined,
                 "Cannot find Table_of_Contents element");
        return NULL;
    }

    double dfGlobalMinX = 0, dfGlobalMinY = 0, dfGlobalMaxX = 0, dfGlobalMaxY= 0;
    double dfGlobalPixelXSize = 0, dfGlobalPixelYSize = 0;
    int bGlobalExtentValid = FALSE;

    ECRGTOCDataset* poDS = new ECRGTOCDataset();
    int nSubDatasets = 0;

    int bLookForSubDataset = osProduct.size() != 0 && osDiscId.size() != 0;

    int nCountSubDataset = 0;

    poDS->SetDescription( pszOpenInfoFilename );
    poDS->papszFileList = poDS->GDALDataset::GetFileList();

    for(CPLXMLNode* psIter1 = psTOC->psChild;
                    psIter1 != NULL;
                    psIter1 = psIter1->psNext)
    {
        if (!(psIter1->eType == CXT_Element && psIter1->pszValue != NULL &&
              strcmp(psIter1->pszValue, "product") == 0))
            continue;

        const char* pszProductTitle =
            CPLGetXMLValue(psIter1, "product_title", NULL);
        if (pszProductTitle == NULL)
        {
            CPLError(CE_Warning, CPLE_AppDefined,
                        "Cannot find product_title attribute");
            continue;
        }

        if (bLookForSubDataset && strcmp(pszProductTitle, osProduct.c_str()) != 0)
            continue;

        for(CPLXMLNode* psIter2 = psIter1->psChild;
                        psIter2 != NULL;
                        psIter2 = psIter2->psNext)
        {
            if (!(psIter2->eType == CXT_Element && psIter2->pszValue != NULL &&
                  strcmp(psIter2->pszValue, "disc") == 0))
                continue;

            const char* pszDiscId = CPLGetXMLValue(psIter2, "id", NULL);
            if (pszDiscId == NULL)
            {
                CPLError(CE_Warning, CPLE_AppDefined,
                            "Cannot find id attribute");
                continue;
            }

            if (bLookForSubDataset && strcmp(pszDiscId, osDiscId.c_str()) != 0)
                continue;

            nCountSubDataset ++;

            CPLXMLNode* psFrameList = CPLGetXMLNode(psIter2, "frame_list");
            if (psFrameList == NULL)
            {
                CPLError(CE_Warning, CPLE_AppDefined,
                            "Cannot find frame_list element");
                continue;
            }

            int nValidFrames = 0;

            std::vector<FrameDesc> aosFrameDesc;

            int nSubDatasetScale = -1;

            for(CPLXMLNode* psIter3 = psFrameList->psChild;
                            psIter3 != NULL;
                            psIter3 = psIter3->psNext)
            {
                if (!(psIter3->eType == CXT_Element &&
                      psIter3->pszValue != NULL &&
                      strcmp(psIter3->pszValue, "scale") == 0))
                    continue;

                const char* pszSize = CPLGetXMLValue(psIter3, "size", NULL);
                if (pszSize == NULL)
                {
                    CPLError(CE_Warning, CPLE_AppDefined,
                                "Cannot find size attribute");
                    continue;
                }

                int nScale = GetScaleFromString(pszSize);
                if (nScale <= 0)
                {
                    CPLError(CE_Warning, CPLE_AppDefined,
                             "Invalid scale %s", pszSize);
                    continue;
                }

                if (nValidFrames == 0)
                    nSubDatasetScale = nScale;
                else
                    nSubDatasetScale = -1;

                for(CPLXMLNode* psIter4 = psIter3->psChild;
                                psIter4 != NULL;
                                psIter4 = psIter4->psNext)
                {
                    if (!(psIter4->eType == CXT_Element &&
                          psIter4->pszValue != NULL &&
                          strcmp(psIter4->pszValue, "frame") == 0))
                        continue;

                    const char* pszFrameName =
                        CPLGetXMLValue(psIter4, "name", NULL);
                    if (pszFrameName == NULL)
                    {
                        CPLError(CE_Warning, CPLE_AppDefined,
                                 "Cannot find name element");
                        continue;
                    }

                    if (strlen(pszFrameName) != 18)
                    {
                        CPLError(CE_Warning, CPLE_AppDefined,
                                 "Invalid value for name element : %s",
                                 pszFrameName);
                        continue;
                    }

                    const char* pszFramePath =
                        CPLGetXMLValue(psIter4, "frame_path", NULL);
                    if (pszFramePath == NULL)
                    {
                        CPLError(CE_Warning, CPLE_AppDefined,
                                 "Cannot find frame_path element");
                        continue;
                    }

                    const char* pszFrameZone =
                        CPLGetXMLValue(psIter4, "frame_zone", NULL);
                    if (pszFrameZone == NULL)
                    {
                        CPLError(CE_Warning, CPLE_AppDefined,
                                 "Cannot find frame_zone element");
                        continue;
                    }
                    if (strlen(pszFrameZone) != 1)
                    {
                        CPLError(CE_Warning, CPLE_AppDefined,
                                 "Invalid value for frame_zone element : %s",
                                 pszFrameZone);
                        continue;
                    }
                    char chZone = pszFrameZone[0];
                    int nZone = 0;
                    if (chZone >= '1' && chZone <= '9')
                        nZone = chZone - '0';
                    else if (chZone >= 'a' && chZone <= 'h')
                        nZone = -(chZone - 'a' + 1);
                    else if (chZone >= 'A' && chZone <= 'H')
                        nZone = -(chZone - 'A' + 1);
                    else if (chZone == 'j' || chZone == 'J')
                        nZone = -9;
                    else
                    {
                        CPLError(CE_Warning, CPLE_AppDefined,
                                 "Invalid value for frame_zone element : %s",
                                  pszFrameZone);
                        continue;
                    }
                    if (nZone == 9 || nZone == -9)
                    {
                        CPLError(CE_Warning, CPLE_AppDefined,
                                 "Polar zones unhandled by current implementation");
                        continue;
                    }

                    double dfMinX = 0, dfMaxX = 0,
                           dfMinY = 0, dfMaxY = 0,
                           dfPixelXSize = 0, dfPixelYSize = 0;
                    if (!GetExtent(pszFrameName, nScale, nZone,
                                   dfMinX, dfMaxX, dfMinY, dfMaxY,
                                   dfPixelXSize, dfPixelYSize))
                    {
                        continue;
                    }

                    nValidFrames ++;

                    const char* pszFullName = BuildFullName(pszTOCFilename,
                                                        pszFramePath,
                                                        pszFrameName);
                    poDS->papszFileList = CSLAddString(poDS->papszFileList, pszFullName);

                    if (!bGlobalExtentValid)
                    {
                        dfGlobalMinX = dfMinX;
                        dfGlobalMinY = dfMinY;
                        dfGlobalMaxX = dfMaxX;
                        dfGlobalMaxY = dfMaxY;
                        dfGlobalPixelXSize = dfPixelXSize;
                        dfGlobalPixelYSize = dfPixelYSize;
                        bGlobalExtentValid = TRUE;
                    }
                    else
                    {
                        if (dfMinX < dfGlobalMinX) dfGlobalMinX = dfMinX;
                        if (dfMinY < dfGlobalMinY) dfGlobalMinY = dfMinY;
                        if (dfMaxX > dfGlobalMaxX) dfGlobalMaxX = dfMaxX;
                        if (dfMaxY > dfGlobalMaxY) dfGlobalMaxY = dfMaxY;
                        if (dfPixelXSize < dfGlobalPixelXSize)
                            dfGlobalPixelXSize = dfPixelXSize;
                        if (dfPixelYSize < dfGlobalPixelYSize)
                            dfGlobalPixelYSize = dfPixelYSize;
                    }

                    if (bLookForSubDataset)
                    {
                        FrameDesc frameDesc;
                        frameDesc.pszName = pszFrameName;
                        frameDesc.pszPath = pszFramePath;
                        frameDesc.nScale = nScale;
                        frameDesc.nZone = nZone;
                        aosFrameDesc.push_back(frameDesc);
                    }
                }
            }

            if (bLookForSubDataset)
            {
                delete poDS;
                if (nValidFrames == 0)
                    return NULL;
                return ECRGTOCSubDataset::Build(pszProductTitle,
                                                pszDiscId,
                                                nSubDatasetScale,
                                                nCountSubDataset,
                                                pszTOCFilename,
                                                aosFrameDesc,
                                                dfGlobalMinX,
                                                dfGlobalMinY,
                                                dfGlobalMaxX,
                                                dfGlobalMaxY,
                                                dfGlobalPixelXSize,
                                                dfGlobalPixelYSize);
            }

            if (nValidFrames)
            {
                poDS->AddSubDataset(pszOpenInfoFilename,
                                    pszProductTitle, pszDiscId);
                nSubDatasets ++;
            }
        }
    }

    if (!bGlobalExtentValid)
    {
        delete poDS;
        return NULL;
    }

    if (nSubDatasets == 1)
    {
        const char* pszSubDatasetName = CSLFetchNameValue(
            poDS->GetMetadata("SUBDATASETS"), "SUBDATASET_1_NAME");
        GDALOpenInfo oOpenInfo(pszSubDatasetName, GA_ReadOnly);
        delete poDS;
        GDALDataset* poRetDS = Open(&oOpenInfo);
        if (poRetDS)
            poRetDS->SetDescription(pszOpenInfoFilename);
        return poRetDS;
    }

    poDS->adfGeoTransform[0] = dfGlobalMinX;
    poDS->adfGeoTransform[1] = dfGlobalPixelXSize;
    poDS->adfGeoTransform[2] = 0.0;
    poDS->adfGeoTransform[3] = dfGlobalMaxY;
    poDS->adfGeoTransform[4] = 0.0;
    poDS->adfGeoTransform[5] = - dfGlobalPixelYSize;

    poDS->nRasterXSize = (int)(0.5 + (dfGlobalMaxX - dfGlobalMinX) / dfGlobalPixelXSize);
    poDS->nRasterYSize = (int)(0.5 + (dfGlobalMaxY - dfGlobalMinY) / dfGlobalPixelYSize);

/* -------------------------------------------------------------------- */
/*      Initialize any PAM information.                                 */
/* -------------------------------------------------------------------- */
    poDS->TryLoadXML();

    return poDS;
}
GDALDataset *DIMAPDataset::Open( GDALOpenInfo * poOpenInfo )

{
    if( !Identify( poOpenInfo ) )
        return NULL;
        
/* -------------------------------------------------------------------- */
/*      Confirm the requested access is supported.                      */
/* -------------------------------------------------------------------- */
    if( poOpenInfo->eAccess == GA_Update )
    {
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "The DIMAP driver does not support update access to existing"
                  " datasets.\n" );
        return NULL;
    }
/* -------------------------------------------------------------------- */
/*      Get the metadata filename.                                      */
/* -------------------------------------------------------------------- */
    CPLString osMDFilename;

    if( poOpenInfo->bIsDirectory )
    {
        osMDFilename = 
            CPLFormCIFilename( poOpenInfo->pszFilename, "METADATA.DIM", NULL );
    }
    else
        osMDFilename = poOpenInfo->pszFilename;

/* -------------------------------------------------------------------- */
/*      Ingest the xml file.                                            */
/* -------------------------------------------------------------------- */
    CPLXMLNode *psProduct, *psImageAttributes;

    psProduct = CPLParseXMLFile( osMDFilename );
    if( psProduct == NULL )
        return NULL;

    CPLXMLNode *psDoc = CPLGetXMLNode( psProduct, "=Dimap_Document" );
    psImageAttributes = CPLGetXMLNode( psDoc, "Raster_Dimensions" );
    if( psImageAttributes == NULL )
    {
        CPLError( CE_Failure, CPLE_OpenFailed, 
                  "Failed to find <Raster_Dimensions> in document." );
        return NULL;
    }


/* -------------------------------------------------------------------- */
/*      Create the dataset.                                             */
/* -------------------------------------------------------------------- */
    DIMAPDataset *poDS = new DIMAPDataset();

    poDS->psProduct = psProduct;

/* -------------------------------------------------------------------- */
/*      Get overall image information.                                  */
/* -------------------------------------------------------------------- */
#ifdef DEBUG
    int nBands = 
        atoi(CPLGetXMLValue( psImageAttributes, "NBANDS", "-1" ));
#endif

    poDS->nRasterXSize = 
        atoi(CPLGetXMLValue( psImageAttributes, "NCOLS", "-1" ));
    poDS->nRasterYSize = 
        atoi(CPLGetXMLValue( psImageAttributes, "NROWS", "-1" ));

/* -------------------------------------------------------------------- */
/*      Get the name of the underlying file.                            */
/* -------------------------------------------------------------------- */
    const char *pszHref = CPLGetXMLValue(
        psDoc, "Data_Access.Data_File.DATA_FILE_PATH.href", "" );
    CPLString osPath = CPLGetPath(osMDFilename);
    CPLString osImageFilename = 
        CPLFormFilename( osPath, pszHref, NULL );
                                   
/* -------------------------------------------------------------------- */
/*      Try and open the file.                                          */
/* -------------------------------------------------------------------- */
    poDS->poImageDS = (GDALDataset *) GDALOpen( osImageFilename, GA_ReadOnly );
    if( poDS->poImageDS == NULL )
    {
        delete poDS;
        return NULL;
    }
        
/* -------------------------------------------------------------------- */
/*      Attach the bands.                                               */
/* -------------------------------------------------------------------- */
    int iBand;
    CPLAssert( nBands == poDS->poImageDS->GetRasterCount() );

    for( iBand = 1; iBand <= poDS->poImageDS->GetRasterCount(); iBand++ )
        poDS->SetBand( iBand, poDS->poImageDS->GetRasterBand( iBand ) );

/* -------------------------------------------------------------------- */
/*      Try to collect simple insertion point.                          */
/* -------------------------------------------------------------------- */
    CPLXMLNode *psGeoLoc =  
        CPLGetXMLNode( psDoc, "Geoposition.Geoposition_Insert" );

    if( psGeoLoc != NULL )
    {
        poDS->bHaveGeoTransform = TRUE;
        poDS->adfGeoTransform[0] = atof(CPLGetXMLValue(psGeoLoc,"ULXMAP","0"));
        poDS->adfGeoTransform[1] = atof(CPLGetXMLValue(psGeoLoc,"XDIM","0"));
        poDS->adfGeoTransform[2] = 0.0;
        poDS->adfGeoTransform[3] = atof(CPLGetXMLValue(psGeoLoc,"ULYMAP","0"));
        poDS->adfGeoTransform[4] = 0.0;
        poDS->adfGeoTransform[5] = -atof(CPLGetXMLValue(psGeoLoc,"YDIM","0"));
    }

/* -------------------------------------------------------------------- */
/*      Collect GCPs.                                                   */
/* -------------------------------------------------------------------- */
    psGeoLoc = CPLGetXMLNode( psDoc, "Geoposition.Geoposition_Points" );

    if( psGeoLoc != NULL )
    {
        CPLXMLNode *psNode;					       

        // count gcps.
        poDS->nGCPCount = 0;
        for( psNode = psGeoLoc->psChild; psNode != NULL;
             psNode = psNode->psNext )
        {
            if( EQUAL(psNode->pszValue,"Tie_Point") )
                poDS->nGCPCount++ ;
        }

        poDS->pasGCPList = (GDAL_GCP *) 
            CPLCalloc(sizeof(GDAL_GCP),poDS->nGCPCount);
        
        poDS->nGCPCount = 0;
        
        for( psNode = psGeoLoc->psChild; psNode != NULL;
             psNode = psNode->psNext )
        {
            char	szID[32];
            GDAL_GCP   *psGCP = poDS->pasGCPList + poDS->nGCPCount;
            
            if( !EQUAL(psNode->pszValue,"Tie_Point") )
                continue;

            poDS->nGCPCount++ ;

            sprintf( szID, "%d", poDS->nGCPCount );
            psGCP->pszId = CPLStrdup( szID );
            psGCP->pszInfo = CPLStrdup("");
            psGCP->dfGCPPixel = 
                atof(CPLGetXMLValue(psNode,"TIE_POINT_DATA_X","0"))-0.5;
            psGCP->dfGCPLine = 
                atof(CPLGetXMLValue(psNode,"TIE_POINT_DATA_Y","0"))-0.5;
            psGCP->dfGCPX = 
                atof(CPLGetXMLValue(psNode,"TIE_POINT_CRS_X",""));
            psGCP->dfGCPY = 
                atof(CPLGetXMLValue(psNode,"TIE_POINT_CRS_Y",""));
            psGCP->dfGCPZ = 
                atof(CPLGetXMLValue(psNode,"TIE_POINT_CRS_Z",""));
        }
    }

/* -------------------------------------------------------------------- */
/*      Collect the CRS.  For now we look only for EPSG codes.          */
/* -------------------------------------------------------------------- */
    const char *pszSRS = CPLGetXMLValue( 
        psDoc, 
        "Coordinate_Reference_System.Horizontal_CS.HORIZONTAL_CS_CODE", 
        NULL );

    if( pszSRS != NULL )
    {
        OGRSpatialReference oSRS;
        if( oSRS.SetFromUserInput( pszSRS ) == OGRERR_NONE )
        {
            if( poDS->nGCPCount > 0 )
            {
                CPLFree(poDS->pszGCPProjection);
                oSRS.exportToWkt( &(poDS->pszGCPProjection) );
            }
            else
            {
                char *pszProjection = NULL;
                oSRS.exportToWkt( &pszProjection );
                poDS->osProjection = pszProjection;
                CPLFree( pszProjection );
            }
        }
    }

/* -------------------------------------------------------------------- */
/*      Translate other metadata of interest.                           */
/* -------------------------------------------------------------------- */
    static const char *apszMetadataTranslation[] = 
        {
            "Production", "", 
            "Production.Facility", "FACILITY_", 
            "Dataset_Sources.Source_Information.Scene_Source", "",
            "Data_Processing", "",
            "Image_Interpretation.Spectral_Band_Info", "SPECTRAL_", 
            NULL, NULL
        };

    int iTrItem;
    
    for( iTrItem = 0; apszMetadataTranslation[iTrItem] != NULL; iTrItem += 2 )
    {
        CPLXMLNode *psParent = 
            CPLGetXMLNode( psDoc, apszMetadataTranslation[iTrItem] );

        if( psParent == NULL )
            continue;

        // hackey logic to support directly access a name/value entry
        // or a parent element with many name/values. 

        CPLXMLNode *psTarget;
        if( psParent->psChild != NULL 
            && psParent->psChild->eType == CXT_Text )
            psTarget = psParent;
        else
            psTarget = psParent->psChild;

        for( ; psTarget != NULL && psTarget != psParent; 
             psTarget = psTarget->psNext ) 
        {
            if( psTarget->eType == CXT_Element
                && psTarget->psChild != NULL
                && psTarget->psChild->eType == CXT_Text )
            {
                CPLString osName = apszMetadataTranslation[iTrItem+1];

                osName += psTarget->pszValue;
                poDS->SetMetadataItem( osName, psTarget->psChild->pszValue );
            }
        }
    }

/* -------------------------------------------------------------------- */
/*      Set Band metadata from the <Spectral_Band_Info> content         */
/* -------------------------------------------------------------------- */

    CPLXMLNode *psImageInterpretationNode = 
            CPLGetXMLNode( psDoc, "Image_Interpretation" );
    if (psImageInterpretationNode != NULL)
    {
        CPLXMLNode *psSpectralBandInfoNode = psImageInterpretationNode->psChild;
        while (psSpectralBandInfoNode != NULL)
        {
            if (psSpectralBandInfoNode->eType == CXT_Element &&
                EQUAL(psSpectralBandInfoNode->pszValue, "Spectral_Band_Info"))
            {
                CPLXMLNode *psTag = psSpectralBandInfoNode->psChild;
                int nBandIndex = 0;
                while(psTag != NULL)
                {
                    if (psTag->eType == CXT_Element && psTag->psChild != NULL &&
                        psTag->psChild->eType == CXT_Text && psTag->pszValue != NULL)
                    {
                        if (EQUAL(psTag->pszValue, "BAND_INDEX"))
                        {
                            nBandIndex = atoi(psTag->psChild->pszValue);
                            if (nBandIndex <= 0 ||
                                nBandIndex > poDS->poImageDS->GetRasterCount())
                            {
                                CPLError(CE_Warning, CPLE_AppDefined,
                                         "Bad BAND_INDEX value : %s", psTag->psChild->pszValue);
                                nBandIndex = 0;
                            }
                        }
                        else if (nBandIndex >= 1)
                        {
                            poDS->GetRasterBand(nBandIndex)->SetMetadataItem(
                                    psTag->pszValue, psTag->psChild->pszValue);
                        }
                    }
                    psTag = psTag->psNext;
                }
            }
            psSpectralBandInfoNode = psSpectralBandInfoNode->psNext;
        }
    }

/* -------------------------------------------------------------------- */
/*      Initialize any PAM information.                                 */
/* -------------------------------------------------------------------- */
    poDS->SetDescription( osMDFilename );
    poDS->TryLoadXML();

/* -------------------------------------------------------------------- */
/*      Check for overviews.                                            */
/* -------------------------------------------------------------------- */
    poDS->oOvManager.Initialize( poDS, osMDFilename );

    return( poDS );
}
Example #16
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;
}
Example #17
0
GDALDataset *TSXDataset::Open( GDALOpenInfo *poOpenInfo ) {
/* -------------------------------------------------------------------- */
/*      Is this a TerraSAR-X product file?                              */
/* -------------------------------------------------------------------- */
	if (!TSXDataset::Identify( poOpenInfo )) {
		return NULL; /* nope */
	}
    
/* -------------------------------------------------------------------- */
/*      Confirm the requested access is supported.                      */
/* -------------------------------------------------------------------- */
    if( poOpenInfo->eAccess == GA_Update )
    {
        CPLError( CE_Failure, CPLE_NotSupported, 
                  "The TSX driver does not support update access to existing"
                  " datasets.\n" );
        return NULL;
    }
    
	/* Ingest the XML */
	CPLXMLNode *psData, *psComponents, *psProductInfo;
	psData = CPLParseXMLFile( poOpenInfo->pszFilename );

	/* find the product components */
	psComponents = CPLGetXMLNode( psData, "=level1Product.productComponents" );
	if (psComponents == NULL) {
		CPLError( CE_Failure, CPLE_OpenFailed, 
			"Unable to find <productComponents> tag in file.\n" );
		return NULL;
	}

	/* find the product info tag */
	psProductInfo = CPLGetXMLNode( psData, "=level1Product.productInfo" );
	if (psComponents == NULL) {
		CPLError( CE_Failure, CPLE_OpenFailed,
			"Unable to find <productInfo> tag in file.\n" );
		return NULL;
	}

/* -------------------------------------------------------------------- */
/*      Create the dataset.                                             */
/* -------------------------------------------------------------------- */
	
    TSXDataset *poDS = new TSXDataset();
	poDS->fp = poOpenInfo->fp;
	poOpenInfo->fp = NULL;

/* -------------------------------------------------------------------- */
/*      Read in product info.                                           */
/* -------------------------------------------------------------------- */

    poDS->SetMetadataItem( "SCENE_CENTRE_TIME", CPLGetXMLValue( psProductInfo,
        "sceneInfo.sceneCenterCoord.azimuthTimeUTC", "unknown" ) );
	poDS->SetMetadataItem( "OPERATIONAL_MODE", CPLGetXMLValue( psProductInfo, 
		"generationInfo.groundOperationsType", "unknown" ) );
	poDS->SetMetadataItem( "ORBIT_CYCLE", CPLGetXMLValue( psProductInfo,
		"missionInfo.orbitCycle", "unknown" ) );
	poDS->SetMetadataItem( "ABSOLUTE_ORBIT", CPLGetXMLValue( psProductInfo,
		"missionInfo.absOrbit", "unknown" ) );
	poDS->SetMetadataItem( "ORBIT_DIRECTION", CPLGetXMLValue( psProductInfo,
		"missionInfo.orbitDirection", "unknown" ) );
	poDS->SetMetadataItem( "IMAGING_MODE", CPLGetXMLValue( psProductInfo,
		"acquisitionInfo.imagingMode", "unknown" ) );
	poDS->SetMetadataItem( "PRODUCT_VARIANT", CPLGetXMLValue( psProductInfo,
		"productVariantInfo.productVariant", "unknown" ) ); 
	char *pszDataType = strdup( CPLGetXMLValue( psProductInfo,
		"imageDataInfo.imageDataType", "unknown" ) );
	poDS->SetMetadataItem( "IMAGE_TYPE", pszDataType ); 
	
	/* Get raster information */
	int nRows = atoi( CPLGetXMLValue( psProductInfo,
		"imageDataInfo.imageRaster.numberOfRows", "" ) );
	int nCols = atoi( CPLGetXMLValue( psProductInfo,
		"imageDataInfo.imageRaster.numberOfColumns", "" ) );

	poDS->nRasterXSize = nCols;
	poDS->nRasterYSize = nRows;

	poDS->SetMetadataItem( "ROW_SPACING", CPLGetXMLValue( psProductInfo,
		"imageDataInfo.imageRaster.rowSpacing", "unknown" ) );
	poDS->SetMetadataItem( "COL_SPACING", CPLGetXMLValue( psProductInfo,
		"imageDataInfo.imageRaster.columnSpacing", "unknown" ) );
    poDS->SetMetadataItem( "COL_SPACING_UNITS", CPLGetXMLValue( psProductInfo,
        "imageDataInfo.imageRaster.columnSpacing.units", "unknown" ) );

	/* Get equivalent number of looks */
	poDS->SetMetadataItem( "AZIMUTH_LOOKS", CPLGetXMLValue( psProductInfo,
		"imageDataInfo.imageRaster.azimuthLooks", "unknown" ) );
	poDS->SetMetadataItem( "RANGE_LOOKS", CPLGetXMLValue( psProductInfo,
		"imageDataInfo.imageRaster.rangeLooks", "unknown" ) );

    const char *pszProductVariant;
    pszProductVariant = CPLGetXMLValue( psProductInfo, 
        "productVariantInfo.productVariant", "unknown" );

    poDS->SetMetadataItem( "PRODUCT_VARIANT", pszProductVariant );

    /* Determine what product variant this is */
    if (EQUALN(pszProductVariant,"SSC",3))
        poDS->nProduct = eSSC;
    else if (EQUALN(pszProductVariant,"MGD",3))
        poDS->nProduct = eMGD;
    else if (EQUALN(pszProductVariant,"EEC",3))
        poDS->nProduct = eEEC;
    else if (EQUALN(pszProductVariant,"GEC",3))
        poDS->nProduct = eGEC;
    else
        poDS->nProduct = eUnknown;

	/* Start reading in the product components */
	const char *pszPath;
	char *pszGeorefFile = NULL;
	CPLXMLNode *psComponent;
	for (psComponent = psComponents->psChild; psComponent != NULL;
		 psComponent = psComponent->psNext)
	{
		char *pszType;
		pszPath = CPLFormFilename( 
				CPLGetDirname( poOpenInfo->pszFilename ),
				GetFilePath(psComponent, &pszType), 
				"" );
		const char *pszPolLayer = CPLGetXMLValue(psComponent, "polLayer", " ");

		if ( !EQUALN(pszType," ",1) ) {
			if (EQUALN(pszType, "MAPPING_GRID", 12) ) {
				/* the mapping grid... save as a metadata item this path */
				poDS->SetMetadataItem( "MAPPING_GRID", pszPath );	
			}
			else if (EQUALN(pszType, "GEOREF", 6)) {
				/* save the path to the georef data for later use */
				pszGeorefFile = strdup( pszPath );
			}
			CPLFree(pszType);
		}
		else if( !EQUALN(pszPolLayer, " ", 1) && 
			EQUALN(psComponent->pszValue, "imageData", 9) ) {
			/* determine the polarization of this band */
			ePolarization ePol;
			if ( EQUALN(pszPolLayer, "HH", 2) ) {
				ePol = HH;
			}
			else if ( EQUALN(pszPolLayer, "HV" , 2) ) {
				ePol = HV;
			}
			else if ( EQUALN(pszPolLayer, "VH", 2) ) {
				ePol = VH;
			}
			else {
				ePol = VV;
			}

			GDALDataType eDataType = EQUALN(pszDataType, "COMPLEX", 7) ?
				GDT_CInt16 : GDT_UInt16;

			/* try opening the file that represents that band */
			TSXRasterBand *poBand;
			GDALDataset *poBandData;

			poBandData = (GDALDataset *) GDALOpen( pszPath, GA_ReadOnly );
			if ( poBandData != NULL ) {
				poBand = new TSXRasterBand( poDS, eDataType, ePol, 
					poBandData );
				poDS->SetBand( poDS->GetRasterCount() + 1, poBand );
			}
		}
	}

	CPLFree(pszDataType);


/* -------------------------------------------------------------------- */
/*      Check and set matrix representation.                            */
/* -------------------------------------------------------------------- */

	if (poDS->GetRasterCount() == 4) {
		poDS->SetMetadataItem( "MATRIX_REPRESENTATION", "SCATTERING" );
	}

/* -------------------------------------------------------------------- */
/*      Read the four corners and centre GCPs in                        */
/* -------------------------------------------------------------------- */

    CPLXMLNode *psSceneInfo = CPLGetXMLNode( psData, 
        "=level1Product.productInfo.sceneInfo" );
    /* for SSC products */
    if (poDS->nProduct == eSSC && psSceneInfo != NULL) {
        CPLXMLNode *psNode;
        int nGCP = 0;
        double dfAvgHeight = atof(CPLGetXMLValue(psSceneInfo, 
            "sceneAverageHeight", "0.0"));
        char szID[3];

        poDS->nGCPCount = 5; /* 5 GCPs provided */
        poDS->pasGCPList = (GDAL_GCP *)CPLCalloc(sizeof(GDAL_GCP), 
            poDS->nGCPCount);

        /* iterate over GCPs */
        for (psNode = psSceneInfo->psChild; psNode != NULL; 
             psNode = psNode->psNext )
        {
            GDAL_GCP *psGCP = poDS->pasGCPList + nGCP;

            if (!EQUAL(psNode->pszValue, "sceneCenterCoord") && 
                !EQUAL(psNode->pszValue, "sceneCornerCoord"))
                continue;

            CPLSPrintf( szID, "%d", nGCP );
            
            psGCP->dfGCPPixel = atof(CPLGetXMLValue(psNode, "refColumn", 
                "0.0"));
            psGCP->dfGCPLine = atof(CPLGetXMLValue(psNode, "refRow", "0.0"));
            psGCP->dfGCPX = atof(CPLGetXMLValue(psNode, "lon", "0.0"));
            psGCP->dfGCPY = atof(CPLGetXMLValue(psNode, "lat", "0.0"));
            psGCP->dfGCPZ = dfAvgHeight;
            psGCP->pszId = CPLStrdup( szID );
            psGCP->pszInfo = CPLStrdup("");

            nGCP++;
        }
    }
    else if (psSceneInfo != NULL) {
        /* extract the GCPs from the provided file */

        /* TODO */
    }
    else {
        CPLError(CE_Warning, CPLE_AppDefined, 
            "Unable to find sceneInfo tag in XML document. " 
            "Proceeding with caution.");
    }

/* -------------------------------------------------------------------- */
/*      Initialize any PAM information.                                 */
/* -------------------------------------------------------------------- */
    poDS->SetDescription( poOpenInfo->pszFilename );
    poDS->TryLoadXML();

/* -------------------------------------------------------------------- */
/*      Check for overviews.                                            */
/* -------------------------------------------------------------------- */
    poDS->oOvManager.Initialize( poDS, poOpenInfo->pszFilename );

    CPLDestroyXMLNode(psData);

    return poDS;
}
Example #18
0
CPLErr VRTWarpedDataset::XMLInit( CPLXMLNode *psTree, const char *pszVRTPath )

{
    CPLErr eErr;

/* -------------------------------------------------------------------- */
/*      Initialize blocksize before calling sub-init so that the        */
/*      band initializers can get it from the dataset object when       */
/*      they are created.                                               */
/* -------------------------------------------------------------------- */
    nBlockXSize = atoi(CPLGetXMLValue(psTree,"BlockXSize","512"));
    nBlockYSize = atoi(CPLGetXMLValue(psTree,"BlockYSize","128"));

/* -------------------------------------------------------------------- */
/*      Initialize all the general VRT stuff.  This will even           */
/*      create the VRTWarpedRasterBands and initialize them.            */
/* -------------------------------------------------------------------- */
    eErr = VRTDataset::XMLInit( psTree, pszVRTPath );

    if( eErr != CE_None )
        return eErr;

/* -------------------------------------------------------------------- */
/*      Find the GDALWarpOptions XML tree.                              */
/* -------------------------------------------------------------------- */
    CPLXMLNode *psOptionsTree;
    psOptionsTree = CPLGetXMLNode( psTree, "GDALWarpOptions" );
    if( psOptionsTree == NULL )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Count not find required GDALWarpOptions in XML." );
        return CE_Failure;
    }

/* -------------------------------------------------------------------- */
/*      Adjust the SourceDataset in the warp options to take into       */
/*      account that it is relative to the VRT if appropriate.          */
/* -------------------------------------------------------------------- */
    int bRelativeToVRT = 
        atoi(CPLGetXMLValue(psOptionsTree,
                            "SourceDataset.relativeToVRT", "0" ));

    const char *pszRelativePath = CPLGetXMLValue(psOptionsTree,
                                                 "SourceDataset", "" );
    char *pszAbsolutePath;

    if( bRelativeToVRT )
        pszAbsolutePath = 
            CPLStrdup(CPLProjectRelativeFilename( pszVRTPath, 
                                                  pszRelativePath ) );
    else
        pszAbsolutePath = CPLStrdup(pszRelativePath);

    CPLSetXMLValue( psOptionsTree, "SourceDataset", pszAbsolutePath );
    CPLFree( pszAbsolutePath );

/* -------------------------------------------------------------------- */
/*      And instantiate the warp options, and corresponding warp        */
/*      operation.                                                      */
/* -------------------------------------------------------------------- */
    GDALWarpOptions *psWO;

    psWO = GDALDeserializeWarpOptions( psOptionsTree );
    if( psWO == NULL )
        return CE_Failure;

    this->eAccess = GA_Update;
    psWO->hDstDS = this;

/* -------------------------------------------------------------------- */
/*      Instantiate the warp operation.                                 */
/* -------------------------------------------------------------------- */
    poWarper = new GDALWarpOperation();

    eErr = poWarper->Initialize( psWO );
    if( eErr != CE_None)
    {
/* -------------------------------------------------------------------- */
/*      We are responsible for cleaning up the transformer outselves.   */
/* -------------------------------------------------------------------- */
        if( psWO->pTransformerArg != NULL )
            GDALDestroyTransformer( psWO->pTransformerArg );
    }

    GDALDestroyWarpOptions( psWO );
    if( eErr != CE_None )
    {
        delete poWarper;
        poWarper = NULL;
    }

/* -------------------------------------------------------------------- */
/*      Generate overviews, if appropriate.                             */
/* -------------------------------------------------------------------- */
    char **papszTokens = CSLTokenizeString( 
        CPLGetXMLValue( psTree, "OverviewList", "" ));
    int iOverview;

    for( iOverview = 0; 
         papszTokens != NULL && papszTokens[iOverview] != NULL;
         iOverview++ )
    {
        int nOvFactor = atoi(papszTokens[iOverview]);

        if (nOvFactor > 0)
            BuildOverviews( "NEAREST", 1, &nOvFactor, 0, NULL, NULL, NULL );
        else
            CPLError(CE_Failure, CPLE_AppDefined,
                     "Bad value for overview factor : %s", papszTokens[iOverview]);
    }

    CSLDestroy( papszTokens );

    return eErr;
}
Example #19
0
bool TSXDataset::getGCPsFromGEOREF_XML(char *pszGeorefFilename)
{
    //open GEOREF.xml
    CPLXMLNode *psGeorefData = CPLParseXMLFile( pszGeorefFilename );
    if (psGeorefData==NULL)
        return false;

    //get the ellipsoid and semi-major, semi-minor axes
    OGRSpatialReference osr;
    CPLXMLNode *psSphere = CPLGetXMLNode( psGeorefData, "=geoReference.referenceFrames.sphere" );
    if (psSphere!=NULL)
    {
        const char *pszEllipsoidName
            = CPLGetXMLValue( psSphere, "ellipsoidID", "" );
        const double minor_axis = CPLAtof(CPLGetXMLValue( psSphere, "semiMinorAxis", "0.0" ));
        const double major_axis = CPLAtof(CPLGetXMLValue( psSphere, "semiMajorAxis", "0.0" ));
        //save datum parameters to the spatial reference
        if ( EQUAL(pszEllipsoidName, "") || minor_axis==0.0 || major_axis==0.0 )
        {
            CPLError(CE_Warning,CPLE_AppDefined,"Warning- incomplete"
                " ellipsoid information.  Using wgs-84 parameters.\n");
            osr.SetWellKnownGeogCS( "WGS84" );
        }
        else if ( EQUAL( pszEllipsoidName, "WGS84" ) ) {
            osr.SetWellKnownGeogCS( "WGS84" );
        }
        else {
            const double inv_flattening = major_axis/(major_axis - minor_axis);
            osr.SetGeogCS( "","",pszEllipsoidName, major_axis, inv_flattening);
        }
    }

    //get gcps
    CPLXMLNode *psGeolocationGrid
        = CPLGetXMLNode( psGeorefData, "=geoReference.geolocationGrid" );
    if (psGeolocationGrid==NULL)
    {
        CPLDestroyXMLNode( psGeorefData );
        return false;
    }
    nGCPCount
        = atoi(CPLGetXMLValue( psGeolocationGrid, "numberOfGridPoints.total", "0" ));
    //count the gcps if the given count value is invalid
    CPLXMLNode *psNode;
    if (nGCPCount<=0)
    {
        for( psNode = psGeolocationGrid->psChild; psNode != NULL; psNode = psNode->psNext )
            if( EQUAL(psNode->pszValue,"gridPoint") )
                nGCPCount++ ;
    }
    //if there are no gcps, fail
    if(nGCPCount<=0)
    {
        CPLDestroyXMLNode( psGeorefData );
        return false;
    }

    //put some reasonable limits of the number of gcps
    if (nGCPCount>MAX_GCPS )
        nGCPCount=MAX_GCPS;
    //allocate memory for the gcps
    pasGCPList = reinterpret_cast<GDAL_GCP *>(
        CPLCalloc(sizeof(GDAL_GCP), nGCPCount) );

    //loop through all gcps and set info

    //save the number allocated to ensure it does not run off the end of the array
    const int gcps_allocated = nGCPCount;
    nGCPCount=0;    //reset to zero and count
    //do a check on the grid point to make sure it has lat,long row, and column
    //it seems that only SSC products contain row, col - how to map lat long otherwise??
    //for now fail if row and col are not present - just check the first and assume the rest are the same
    for( psNode = psGeolocationGrid->psChild; psNode != NULL; psNode = psNode->psNext )
    {
         if( !EQUAL(psNode->pszValue,"gridPoint") )
             continue;

         if (    !strcmp(CPLGetXMLValue(psNode,"col","error"), "error") ||
                 !strcmp(CPLGetXMLValue(psNode,"row","error"), "error") ||
                 !strcmp(CPLGetXMLValue(psNode,"lon","error"), "error") ||
                 !strcmp(CPLGetXMLValue(psNode,"lat","error"), "error"))
        {
            CPLDestroyXMLNode( psGeorefData );
            return false;
        }
    }
    for( psNode = psGeolocationGrid->psChild; psNode != NULL; psNode = psNode->psNext )
    {
        //break out if the end of the array has been reached
        if (nGCPCount >= gcps_allocated)
        {
            CPLError(CE_Warning, CPLE_AppDefined, "GDAL TSX driver: Truncating the number of GCPs.");
            break;
        }

         GDAL_GCP   *psGCP = pasGCPList + nGCPCount;

         if( !EQUAL(psNode->pszValue,"gridPoint") )
             continue;

         nGCPCount++ ;

         char szID[32];
         snprintf( szID, sizeof(szID), "%d", nGCPCount );
         psGCP->pszId = CPLStrdup( szID );
         psGCP->pszInfo = CPLStrdup("");
         psGCP->dfGCPPixel = CPLAtof(CPLGetXMLValue(psNode,"col","0"));
         psGCP->dfGCPLine = CPLAtof(CPLGetXMLValue(psNode,"row","0"));
         psGCP->dfGCPX = CPLAtof(CPLGetXMLValue(psNode,"lon",""));
         psGCP->dfGCPY = CPLAtof(CPLGetXMLValue(psNode,"lat",""));
         //looks like height is in meters - should it be converted so xyz are all on the same scale??
         psGCP->dfGCPZ = 0;
             //CPLAtof(CPLGetXMLValue(psNode,"height",""));
    }

    CPLFree(pszGCPProjection);
    osr.exportToWkt( &(pszGCPProjection) );

    CPLDestroyXMLNode( psGeorefData );

    return true;
}
Example #20
0
static
GMLFeatureClass* GMLParseFeatureType(CPLXMLNode *psSchemaNode,
                                     const char* pszName,
                                     CPLXMLNode *psComplexType)
{

/* -------------------------------------------------------------------- */
/*      Grab the sequence of extensions greatgrandchild.                */
/* -------------------------------------------------------------------- */
    CPLXMLNode *psAttrSeq =
        CPLGetXMLNode( psComplexType,
                        "complexContent.extension.sequence" );

    if( psAttrSeq == NULL )
    {
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      We are pretty sure this going to be a valid Feature class       */
/*      now, so create it.                                              */
/* -------------------------------------------------------------------- */
    GMLFeatureClass *poClass = new GMLFeatureClass( pszName );

/* -------------------------------------------------------------------- */
/*      Loop over each of the attribute elements being defined for      */
/*      this feature class.                                             */
/* -------------------------------------------------------------------- */
    CPLXMLNode *psAttrDef;
    int nAttributeIndex = 0;

    int bGotUnrecognizedType = FALSE;

    for( psAttrDef = psAttrSeq->psChild;
            psAttrDef != NULL;
            psAttrDef = psAttrDef->psNext )
    {
        if( strcmp(psAttrDef->pszValue,"group") == 0 )
        {
            /* Too complex schema for us. Aborts parsing */
            delete poClass;
            return NULL;
        }

        if( !EQUAL(psAttrDef->pszValue,"element") )
            continue;

        /* MapServer WFS writes element type as an attribute of element */
        /* not as a simpleType definition */
        const char* pszType = CPLGetXMLValue( psAttrDef, "type", NULL );
        const char* pszElementName = CPLGetXMLValue( psAttrDef, "name", NULL );
        if (pszType != NULL)
        {
            const char* pszStrippedNSType = StripNS(pszType);
            int nWidth = 0, nPrecision = 0;

            GMLPropertyType gmlType = GMLPT_Untyped;
            if (EQUAL(pszStrippedNSType, "string") ||
                EQUAL(pszStrippedNSType, "Character"))
                gmlType = GMLPT_String;
            /* TODO: Would be nice to have a proper date type */
            else if (EQUAL(pszStrippedNSType, "date") ||
                     EQUAL(pszStrippedNSType, "dateTime"))
                gmlType = GMLPT_String;
            else if (EQUAL(pszStrippedNSType, "real") ||
                     EQUAL(pszStrippedNSType, "double") ||
                     EQUAL(pszStrippedNSType, "float") ||
                     EQUAL(pszStrippedNSType, "decimal"))
                gmlType = GMLPT_Real;
            else if (EQUAL(pszStrippedNSType, "short") ||
                     EQUAL(pszStrippedNSType, "int") ||
                     EQUAL(pszStrippedNSType, "integer") ||
                     EQUAL(pszStrippedNSType, "long"))
                gmlType = GMLPT_Integer;
            else if (strncmp(pszType, "gml:", 4) == 0)
            {
                const AssocNameType* psIter = apsPropertyTypes;
                while(psIter->pszName)
                {
                    if (strncmp(pszType + 4, psIter->pszName, strlen(psIter->pszName)) == 0)
                    {
                        if (poClass->GetGeometryAttributeIndex() != -1)
                        {
                            CPLDebug("GML", "Geometry field already found ! Ignoring the following ones");
                        }
                        else
                        {
                            poClass->SetGeometryElement(pszElementName);
                            poClass->SetGeometryType(psIter->eType);
                            poClass->SetGeometryAttributeIndex( nAttributeIndex );

                            nAttributeIndex ++;
                        }
                        
                        break;
                    }

                    psIter ++;
                }

                if (psIter->pszName == NULL)
                {
                    /* Can be a non geometry gml type */
                    /* Too complex schema for us. Aborts parsing */
                    delete poClass;
                    return NULL;
                }

                if (poClass->GetGeometryAttributeIndex() == -1)
                    bGotUnrecognizedType = TRUE;

                continue;
            }

            /* Integraph stuff */
            else if (strcmp(pszType, "G:Point_MultiPointPropertyType") == 0 ||
                     strcmp(pszType, "gmgml:Point_MultiPointPropertyType") == 0)
            {
                poClass->SetGeometryElement(pszElementName);
                poClass->SetGeometryType(wkbMultiPoint);
                poClass->SetGeometryAttributeIndex( nAttributeIndex );

                nAttributeIndex ++;
                continue;
            }
            else if (strcmp(pszType, "G:LineString_MultiLineStringPropertyType") == 0 ||
                     strcmp(pszType, "gmgml:LineString_MultiLineStringPropertyType") == 0)
            {
                poClass->SetGeometryElement(pszElementName);
                poClass->SetGeometryType(wkbMultiLineString);
                poClass->SetGeometryAttributeIndex( nAttributeIndex );

                nAttributeIndex ++;
                continue;
            }
            else if (strcmp(pszType, "G:Polygon_MultiPolygonPropertyType") == 0 ||
                     strcmp(pszType, "gmgml:Polygon_MultiPolygonPropertyType") == 0 ||
                     strcmp(pszType, "gmgml:Polygon_Surface_MultiSurface_CompositeSurfacePropertyType") == 0)
            {
                poClass->SetGeometryElement(pszElementName);
                poClass->SetGeometryType(wkbMultiPolygon);
                poClass->SetGeometryAttributeIndex( nAttributeIndex );

                nAttributeIndex ++;
                continue;
            }

            /* ERDAS Apollo stuff (like in http://apollo.erdas.com/erdas-apollo/vector/WORLDWIDE?SERVICE=WFS&VERSION=1.0.0&REQUEST=DescribeFeatureType&TYPENAME=wfs:cntry98) */
            else if (strcmp(pszType, "wfs:MixedPolygonPropertyType") == 0)
            {
                poClass->SetGeometryElement(pszElementName);
                poClass->SetGeometryType(wkbMultiPolygon);
                poClass->SetGeometryAttributeIndex( nAttributeIndex );

                nAttributeIndex ++;
                continue;
            }

            else
            {
                gmlType = GMLPT_Untyped;
                if ( ! LookForSimpleType(psSchemaNode, pszStrippedNSType,
                                         &gmlType, &nWidth, &nPrecision) )
                {
                    /* Too complex schema for us. Aborts parsing */
                    delete poClass;
                    return NULL;
                }
            }

            if (pszElementName == NULL)
                pszElementName = "unnamed";
            GMLPropertyDefn *poProp = new GMLPropertyDefn(
                pszElementName, pszElementName );

            poProp->SetType( gmlType );
            poProp->SetAttributeIndex( nAttributeIndex );
            poProp->SetWidth( nWidth );
            poProp->SetPrecision( nPrecision );

            if (poClass->AddProperty( poProp ) < 0)
                delete poProp;
            else
                nAttributeIndex ++;

            continue;
        }

        // For now we skip geometries .. fixup later.
        CPLXMLNode* psSimpleType = CPLGetXMLNode( psAttrDef, "simpleType" );
        if( psSimpleType == NULL )
        {
            const char* pszRef = CPLGetXMLValue( psAttrDef, "ref", NULL );

            /* FME .xsd */
            if (pszRef != NULL && strncmp(pszRef, "gml:", 4) == 0)
            {
                const AssocNameType* psIter = apsRefTypes;
                while(psIter->pszName)
                {
                    if (strncmp(pszRef + 4, psIter->pszName, strlen(psIter->pszName)) == 0)
                    {
                        if (poClass->GetGeometryAttributeIndex() != -1)
                        {
                            OGRwkbGeometryType eNewType = psIter->eType;
                            OGRwkbGeometryType eOldType = (OGRwkbGeometryType)poClass->GetGeometryType();
                            if ((eNewType == wkbMultiPoint && eOldType == wkbPoint) ||
                                (eNewType == wkbMultiLineString && eOldType == wkbLineString) ||
                                (eNewType == wkbMultiPolygon && eOldType == wkbPolygon))
                            {
                                poClass->SetGeometryType(eNewType);
                            }
                            else
                            {
                                CPLDebug("GML", "Geometry field already found ! Ignoring the following ones");
                            }
                        }
                        else
                        {
                            poClass->SetGeometryElement(pszElementName);
                            poClass->SetGeometryType(psIter->eType);
                            poClass->SetGeometryAttributeIndex( nAttributeIndex );

                            nAttributeIndex ++;
                        }

                        break;
                    }

                    psIter ++;
                }

                if (psIter->pszName == NULL)
                {
                    /* Can be a non geometry gml type */
                    /* Too complex schema for us. Aborts parsing */
                    delete poClass;
                    return NULL;
                }

                if (poClass->GetGeometryAttributeIndex() == -1)
                    bGotUnrecognizedType = TRUE;

                continue;
            }

            /* Parse stuff like the following found in http://199.29.1.81:8181/miwfs/GetFeature.ashx?REQUEST=GetFeature&MAXFEATURES=1&SERVICE=WFS&VERSION=1.0.0&TYPENAME=miwfs:World :
            <xs:element name="Obj" minOccurs="0" maxOccurs="1">
                <xs:complexType>
                    <xs:sequence>
                        <xs:element ref="gml:_Geometry"/>
                    </xs:sequence>
                </xs:complexType>
            </xs:element>
            */
            CPLXMLNode* psComplexType = GetSingleChildElement( psAttrDef, "complexType" );
            CPLXMLNode* psComplexTypeSequence = GetSingleChildElement( psComplexType, "sequence" );
            CPLXMLNode* psComplexTypeSequenceElement = GetSingleChildElement( psComplexTypeSequence, "element" );

            if( pszElementName != NULL &&
                CheckMinMaxOccursCardinality(psAttrDef) &&
                psComplexTypeSequenceElement != NULL &&
                CheckMinMaxOccursCardinality(psComplexTypeSequence) &&
                strcmp(CPLGetXMLValue( psComplexTypeSequenceElement, "ref", "" ), "gml:_Geometry") == 0 )
            {
                poClass->SetGeometryElement(pszElementName);
                poClass->SetGeometryType(wkbUnknown);
                poClass->SetGeometryAttributeIndex( nAttributeIndex );

                nAttributeIndex ++;

                continue;
            }
            else
            {
                /* Too complex schema for us. Aborts parsing */
                delete poClass;
                return NULL;
            }
        }

        if (pszElementName == NULL)
            pszElementName = "unnamed";
        GMLPropertyDefn *poProp = new GMLPropertyDefn(
            pszElementName, pszElementName );

        GMLPropertyType eType = GMLPT_Untyped;
        int nWidth = 0, nPrecision = 0;
        GetSimpleTypeProperties(psSimpleType, &eType, &nWidth, &nPrecision);
        poProp->SetType( eType );
        poProp->SetWidth( nWidth );
        poProp->SetPrecision( nPrecision );
        poProp->SetAttributeIndex( nAttributeIndex );

        if (poClass->AddProperty( poProp ) < 0)
            delete poProp;
        else
            nAttributeIndex ++;
    }

    /* Only report wkbNone if we didn't find a known geometry type */
    /* and there were not any unknown types (in case this unknown type */
    /* would be a geometry type) */
    if (poClass->GetGeometryAttributeIndex() == -1 &&
        !bGotUnrecognizedType)
    {
        poClass->SetGeometryType(wkbNone);
    }

/* -------------------------------------------------------------------- */
/*      Class complete, add to reader class list.                       */
/* -------------------------------------------------------------------- */
    poClass->SetSchemaLocked( TRUE );

    return poClass;
}
Example #21
0
void *GDALDeserializeGCPTransformer( CPLXMLNode *psTree )

{
    GDAL_GCP *pasGCPList = 0;
    int nGCPCount = 0;
    void *pResult;
    int nReqOrder;
    int bReversed;
    int bRefine;
    int nMinimumGcps;
    double dfTolerance;

    /* -------------------------------------------------------------------- */
    /*      Check for GCPs.                                                 */
    /* -------------------------------------------------------------------- */
    CPLXMLNode *psGCPList = CPLGetXMLNode( psTree, "GCPList" );

    if( psGCPList != NULL )
    {
        int  nGCPMax = 0;
        CPLXMLNode *psXMLGCP;
         
        // Count GCPs.
        for( psXMLGCP = psGCPList->psChild; psXMLGCP != NULL; 
             psXMLGCP = psXMLGCP->psNext )
            nGCPMax++;
         
        pasGCPList = (GDAL_GCP *) CPLCalloc(sizeof(GDAL_GCP),nGCPMax);

        for( psXMLGCP = psGCPList->psChild; psXMLGCP != NULL; 
             psXMLGCP = psXMLGCP->psNext )
        {
            GDAL_GCP *psGCP = pasGCPList + nGCPCount;

            if( !EQUAL(psXMLGCP->pszValue,"GCP") || 
                psXMLGCP->eType != CXT_Element )
                continue;
             
            GDALInitGCPs( 1, psGCP );
             
            CPLFree( psGCP->pszId );
            psGCP->pszId = CPLStrdup(CPLGetXMLValue(psXMLGCP,"Id",""));
             
            CPLFree( psGCP->pszInfo );
            psGCP->pszInfo = CPLStrdup(CPLGetXMLValue(psXMLGCP,"Info",""));
             
            psGCP->dfGCPPixel = atof(CPLGetXMLValue(psXMLGCP,"Pixel","0.0"));
            psGCP->dfGCPLine = atof(CPLGetXMLValue(psXMLGCP,"Line","0.0"));
             
            psGCP->dfGCPX = atof(CPLGetXMLValue(psXMLGCP,"X","0.0"));
            psGCP->dfGCPY = atof(CPLGetXMLValue(psXMLGCP,"Y","0.0"));
            psGCP->dfGCPZ = atof(CPLGetXMLValue(psXMLGCP,"Z","0.0"));
            nGCPCount++;
        }
    }

/* -------------------------------------------------------------------- */
/*      Get other flags.                                                */
/* -------------------------------------------------------------------- */
    nReqOrder = atoi(CPLGetXMLValue(psTree,"Order","3"));
    bReversed = atoi(CPLGetXMLValue(psTree,"Reversed","0"));
    bRefine = atoi(CPLGetXMLValue(psTree,"Refine","0"));
    nMinimumGcps = atoi(CPLGetXMLValue(psTree,"MinimumGcps","6"));
    dfTolerance = atof(CPLGetXMLValue(psTree,"Tolerance","1.0"));

/* -------------------------------------------------------------------- */
/*      Generate transformation.                                        */
/* -------------------------------------------------------------------- */
    if(bRefine)
    {
        pResult = GDALCreateGCPRefineTransformer( nGCPCount, pasGCPList, nReqOrder, 
                                        bReversed, dfTolerance, nMinimumGcps );
    }
    else
    {
        pResult = GDALCreateGCPTransformer( nGCPCount, pasGCPList, nReqOrder, 
                                        bReversed );
    }
    
/* -------------------------------------------------------------------- */
/*      Cleanup GCP copy.                                               */
/* -------------------------------------------------------------------- */
    GDALDeinitGCPs( nGCPCount, pasGCPList );
    CPLFree( pasGCPList );

    return pResult;
}
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 );
    }
}
Example #23
0
CPLErr VRTRasterBand::XMLInit( CPLXMLNode * psTree, 
                               const char *pszVRTPath )

{
/* -------------------------------------------------------------------- */
/*      Validate a bit.                                                 */
/* -------------------------------------------------------------------- */
    if( psTree == NULL || psTree->eType != CXT_Element
        || !EQUAL(psTree->pszValue,"VRTRasterBand") )
    {
        CPLError( CE_Failure, CPLE_AppDefined, 
                  "Invalid node passed to VRTRasterBand::XMLInit()." );
        return CE_Failure;
    }

/* -------------------------------------------------------------------- */
/*      Set the band if provided as an attribute.                       */
/* -------------------------------------------------------------------- */
    const char* pszBand = CPLGetXMLValue( psTree, "band", NULL);
    if( pszBand != NULL )
    {
        nBand = atoi(pszBand);
    }

/* -------------------------------------------------------------------- */
/*      Set the band if provided as an attribute.                       */
/* -------------------------------------------------------------------- */
    const char *pszDataType = CPLGetXMLValue( psTree, "dataType", NULL);
    if( pszDataType != NULL )
    {
        eDataType = GDALGetDataTypeByName(pszDataType);
    }

/* -------------------------------------------------------------------- */
/*      Apply any band level metadata.                                  */
/* -------------------------------------------------------------------- */
    oMDMD.XMLInit( psTree, TRUE );

/* -------------------------------------------------------------------- */
/*      Collect various other items of metadata.                        */
/* -------------------------------------------------------------------- */
    SetDescription( CPLGetXMLValue( psTree, "Description", "" ) );
    
    if( CPLGetXMLValue( psTree, "NoDataValue", NULL ) != NULL )
        SetNoDataValue( CPLAtofM(CPLGetXMLValue( psTree, "NoDataValue", "0" )) );

    if( CPLGetXMLValue( psTree, "HideNoDataValue", NULL ) != NULL )
        bHideNoDataValue = CSLTestBoolean( CPLGetXMLValue( psTree, "HideNoDataValue", "0" ) );

    SetUnitType( CPLGetXMLValue( psTree, "UnitType", NULL ) );

    SetOffset( atof(CPLGetXMLValue( psTree, "Offset", "0.0" )) );
    SetScale( atof(CPLGetXMLValue( psTree, "Scale", "1.0" )) );

    if( CPLGetXMLValue( psTree, "ColorInterp", NULL ) != NULL )
    {
        const char *pszInterp = CPLGetXMLValue( psTree, "ColorInterp", NULL );
        SetColorInterpretation(GDALGetColorInterpretationByName(pszInterp));
    }

/* -------------------------------------------------------------------- */
/*      Category names.                                                 */
/* -------------------------------------------------------------------- */
    if( CPLGetXMLNode( psTree, "CategoryNames" ) != NULL )
    {
        CPLXMLNode *psEntry;

        CSLDestroy( papszCategoryNames );
        papszCategoryNames = NULL;

        CPLStringList oCategoryNames;

        for( psEntry = CPLGetXMLNode( psTree, "CategoryNames" )->psChild;
             psEntry != NULL; psEntry = psEntry->psNext )
        {
            if( psEntry->eType != CXT_Element 
                || !EQUAL(psEntry->pszValue,"Category") 
                || (psEntry->psChild != NULL && psEntry->psChild->eType != CXT_Text) )
                continue;
            
            oCategoryNames.AddString(
                                (psEntry->psChild) ? psEntry->psChild->pszValue : "");
        }

        papszCategoryNames = oCategoryNames.StealList();
    }

/* -------------------------------------------------------------------- */
/*      Collect a color table.                                          */
/* -------------------------------------------------------------------- */
    if( CPLGetXMLNode( psTree, "ColorTable" ) != NULL )
    {
        CPLXMLNode *psEntry;
        GDALColorTable oTable;
        int        iEntry = 0;

        for( psEntry = CPLGetXMLNode( psTree, "ColorTable" )->psChild;
             psEntry != NULL; psEntry = psEntry->psNext )
        {
            GDALColorEntry sCEntry;

            sCEntry.c1 = (short) atoi(CPLGetXMLValue( psEntry, "c1", "0" ));
            sCEntry.c2 = (short) atoi(CPLGetXMLValue( psEntry, "c2", "0" ));
            sCEntry.c3 = (short) atoi(CPLGetXMLValue( psEntry, "c3", "0" ));
            sCEntry.c4 = (short) atoi(CPLGetXMLValue( psEntry, "c4", "255" ));

            oTable.SetColorEntry( iEntry++, &sCEntry );
        }
        
        SetColorTable( &oTable );
    }

/* -------------------------------------------------------------------- */
/*      Histograms                                                      */
/* -------------------------------------------------------------------- */
    CPLXMLNode *psHist = CPLGetXMLNode( psTree, "Histograms" );
    if( psHist != NULL )
    {
        CPLXMLNode *psNext = psHist->psNext;
        psHist->psNext = NULL;

        psSavedHistograms = CPLCloneXMLTree( psHist );
        psHist->psNext = psNext;
    }

/* ==================================================================== */
/*      Overviews                                                       */
/* ==================================================================== */
    CPLXMLNode *psNode;

    for( psNode = psTree->psChild; psNode != NULL; psNode = psNode->psNext )
    {
        if( psNode->eType != CXT_Element
            || !EQUAL(psNode->pszValue,"Overview") )
            continue;

/* -------------------------------------------------------------------- */
/*      Prepare filename.                                               */
/* -------------------------------------------------------------------- */
        char *pszSrcDSName = NULL;
        CPLXMLNode* psFileNameNode=CPLGetXMLNode(psNode,"SourceFilename");
        const char *pszFilename = 
            psFileNameNode ? CPLGetXMLValue(psFileNameNode,NULL, NULL) : NULL;

        if( pszFilename == NULL )
        {
            CPLError( CE_Warning, CPLE_AppDefined, 
                      "Missing <SourceFilename> element in Overview." );
            return CE_Failure;
        }

        if (EQUALN(pszFilename, "MEM:::", 6) && pszVRTPath != NULL &&
            !CSLTestBoolean(CPLGetConfigOption("VRT_ALLOW_MEM_DRIVER", "NO")))
        {
            CPLError( CE_Failure, CPLE_AppDefined,
                    "<SourceFilename> points to a MEM dataset, which is rather suspect! "
                    "If you know what you are doing, define the VRT_ALLOW_MEM_DRIVER configuration option to YES" );
            return CE_Failure;
        }

        if( pszVRTPath != NULL
            && atoi(CPLGetXMLValue( psFileNameNode, "relativetoVRT", "0")) )
        {
            pszSrcDSName = CPLStrdup(
                CPLProjectRelativeFilename( pszVRTPath, pszFilename ) );
        }
        else
            pszSrcDSName = CPLStrdup( pszFilename );

/* -------------------------------------------------------------------- */
/*      Get the raster band.                                            */
/* -------------------------------------------------------------------- */
        int nSrcBand = atoi(CPLGetXMLValue(psNode,"SourceBand","1"));

        apoOverviews.resize( apoOverviews.size() + 1 );
        apoOverviews[apoOverviews.size()-1].osFilename = pszSrcDSName;
        apoOverviews[apoOverviews.size()-1].nBand = nSrcBand;
        
        CPLFree( pszSrcDSName );
    }

/* ==================================================================== */
/*      Mask band (specific to that raster band)                        */
/* ==================================================================== */
    CPLXMLNode* psMaskBandNode = CPLGetXMLNode(psTree, "MaskBand");
    if (psMaskBandNode)
        psNode = psMaskBandNode->psChild;
    else
        psNode = NULL;
    for( ; psNode != NULL; psNode = psNode->psNext )
    {
        if( psNode->eType != CXT_Element
            || !EQUAL(psNode->pszValue,"VRTRasterBand") )
            continue;

        if( ((VRTDataset*)poDS)->poMaskBand != NULL)
        {
            CPLError( CE_Warning, CPLE_AppDefined,
                       "Illegal mask band at raster band level when a dataset mask band already exists." );
            break;
        }

        const char *pszSubclass = CPLGetXMLValue( psNode, "subclass",
                                                    "VRTSourcedRasterBand" );
        VRTRasterBand  *poBand = NULL;

        if( EQUAL(pszSubclass,"VRTSourcedRasterBand") )
            poBand = new VRTSourcedRasterBand( GetDataset(), 0 );
        else if( EQUAL(pszSubclass, "VRTDerivedRasterBand") )
            poBand = new VRTDerivedRasterBand( GetDataset(), 0 );
        else if( EQUAL(pszSubclass, "VRTRawRasterBand") )
            poBand = new VRTRawRasterBand( GetDataset(), 0 );
        else if( EQUAL(pszSubclass, "VRTWarpedRasterBand") )
            poBand = new VRTWarpedRasterBand( GetDataset(), 0 );
        else
        {
            CPLError( CE_Failure, CPLE_AppDefined,
                        "VRTRasterBand of unrecognised subclass '%s'.",
                        pszSubclass );
            break;
        }


        if( poBand->XMLInit( psNode, pszVRTPath ) == CE_None )
        {
            SetMaskBand(poBand);
        }

        break;
    }

    return CE_None;
}
Example #24
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;
}
Example #25
0
int GMLParseXSD( const char *pszFile,
                 std::vector<GMLFeatureClass*> & aosClasses)

{
    if( pszFile == NULL )
        return FALSE;

/* -------------------------------------------------------------------- */
/*      Load the raw XML file.                                          */
/* -------------------------------------------------------------------- */
    CPLXMLNode *psXSDTree = CPLParseXMLFile( pszFile );
    
    if( psXSDTree == NULL )
        return FALSE;

/* -------------------------------------------------------------------- */
/*      Strip off any namespace qualifiers.                             */
/* -------------------------------------------------------------------- */
    CPLStripXMLNamespace( psXSDTree, NULL, TRUE );

/* -------------------------------------------------------------------- */
/*      Find <schema> root element.                                     */
/* -------------------------------------------------------------------- */
    CPLXMLNode *psSchemaNode = CPLGetXMLNode( psXSDTree, "=schema" );
    if( psSchemaNode == NULL )
    {
        CPLDestroyXMLNode( psXSDTree );
        return FALSE;
    }

/* ==================================================================== */
/*      Process each feature class definition.                          */
/* ==================================================================== */
    CPLXMLNode *psThis;

    for( psThis = psSchemaNode->psChild; 
         psThis != NULL; psThis = psThis->psNext )
    {
/* -------------------------------------------------------------------- */
/*      Check for <xs:element> node.                                    */
/* -------------------------------------------------------------------- */
        if( psThis->eType != CXT_Element 
            || !EQUAL(psThis->pszValue,"element") )
            continue;

/* -------------------------------------------------------------------- */
/*      Check the substitution group.                                   */
/* -------------------------------------------------------------------- */
        const char *pszSubGroup = 
            StripNS(CPLGetXMLValue(psThis,"substitutionGroup",""));

        // Old OGR produced elements for the feature collection.
        if( EQUAL(pszSubGroup, "_FeatureCollection") )
            continue;

        if( !EQUAL(pszSubGroup, "_Feature") &&
            !EQUAL(pszSubGroup, "AbstractFeature") /* AbstractFeature used by GML 3.2 */ )
        {
            continue;
        }
        
/* -------------------------------------------------------------------- */
/*      Get name                                                        */
/* -------------------------------------------------------------------- */
        const char *pszName;

        pszName = CPLGetXMLValue( psThis, "name", NULL );
        if( pszName == NULL )
        {
            continue;
        }

/* -------------------------------------------------------------------- */
/*      Get type and verify relationship with name.                     */
/* -------------------------------------------------------------------- */
        const char *pszType;

        pszType = CPLGetXMLValue( psThis, "type", NULL );
        if (pszType == NULL)
        {
            CPLXMLNode *psComplexType = CPLGetXMLNode( psThis, "complexType" );
            if (psComplexType)
            {
                GMLFeatureClass* poClass =
                        GMLParseFeatureType(psSchemaNode, pszName, psComplexType);
                if (poClass)
                    aosClasses.push_back(poClass);
            }
            continue;
        }
        if( strstr( pszType, ":" ) != NULL )
            pszType = strstr( pszType, ":" ) + 1;
        if( EQUAL(pszType, pszName) )
        {
            /* A few WFS servers return a type name which is the element name */
            /* without any _Type or Type suffix */
            /* e.g. : http://apollo.erdas.com/erdas-apollo/vector/Cherokee?SERVICE=WFS&VERSION=1.0.0&REQUEST=DescribeFeatureType&TYPENAME=iwfs:Air */
        }
        else if( !EQUALN(pszType,pszName,strlen(pszName))
            || !(EQUAL(pszType+strlen(pszName),"_Type") ||
                    EQUAL(pszType+strlen(pszName),"Type")) )
        {
            continue;
        }

        /* CanVec .xsd contains weird types that are not used in the related GML */
        if (strncmp(pszName, "XyZz", 4) == 0 ||
            strncmp(pszName, "XyZ1", 4) == 0 ||
            strncmp(pszName, "XyZ2", 4) == 0)
            continue;

        GMLFeatureClass* poClass =
                GMLParseFeatureType(psSchemaNode, pszName, pszType);
        if (poClass)
            aosClasses.push_back(poClass);
    }

    CPLDestroyXMLNode( psXSDTree );

    if( aosClasses.size() > 0 )
    {
        return TRUE;
    }
    else
        return FALSE;
}
Example #26
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;
}
Example #27
0
CPLErr VRTDataset::XMLInit( CPLXMLNode *psTree, const char *pszVRTPath )

{
    if( pszVRTPath != NULL )
        this->pszVRTPath = CPLStrdup(pszVRTPath);

/* -------------------------------------------------------------------- */
/*      Check for an SRS node.                                          */
/* -------------------------------------------------------------------- */
    if( strlen(CPLGetXMLValue(psTree, "SRS", "")) > 0 )
    {
        OGRSpatialReference oSRS;

        CPLFree( pszProjection );
        pszProjection = NULL;

        if( oSRS.SetFromUserInput( CPLGetXMLValue(psTree, "SRS", "") )
            == OGRERR_NONE )
            oSRS.exportToWkt( &pszProjection );
    }

/* -------------------------------------------------------------------- */
/*      Check for a GeoTransform node.                                  */
/* -------------------------------------------------------------------- */
    if( strlen(CPLGetXMLValue(psTree, "GeoTransform", "")) > 0 )
    {
        const char *pszGT = CPLGetXMLValue(psTree, "GeoTransform", "");
        char	**papszTokens;

        papszTokens = CSLTokenizeStringComplex( pszGT, ",", FALSE, FALSE );
        if( CSLCount(papszTokens) != 6 )
        {
            CPLError( CE_Warning, CPLE_AppDefined,
                      "GeoTransform node does not have expected six values.");
        }
        else
        {
            for( int iTA = 0; iTA < 6; iTA++ )
                adfGeoTransform[iTA] = atof(papszTokens[iTA]);
            bGeoTransformSet = TRUE;
        }

        CSLDestroy( papszTokens );
    }

/* -------------------------------------------------------------------- */
/*      Check for GCPs.                                                 */
/* -------------------------------------------------------------------- */
    CPLXMLNode *psGCPList = CPLGetXMLNode( psTree, "GCPList" );

    if( psGCPList != NULL )
    {
        CPLXMLNode *psXMLGCP;
        OGRSpatialReference oSRS;
        const char *pszRawProj = CPLGetXMLValue(psGCPList, "Projection", "");

        CPLFree( pszGCPProjection );

        if( strlen(pszRawProj) > 0 
            && oSRS.SetFromUserInput( pszRawProj ) == OGRERR_NONE )
            oSRS.exportToWkt( &pszGCPProjection );
        else
            pszGCPProjection = CPLStrdup("");

        // Count GCPs.
        int  nGCPMax = 0;
         
        for( psXMLGCP = psGCPList->psChild; psXMLGCP != NULL; 
             psXMLGCP = psXMLGCP->psNext )
            nGCPMax++;
         
        pasGCPList = (GDAL_GCP *) CPLCalloc(sizeof(GDAL_GCP),nGCPMax);
         
        for( psXMLGCP = psGCPList->psChild; psXMLGCP != NULL; 
             psXMLGCP = psXMLGCP->psNext )
        {
            GDAL_GCP *psGCP = pasGCPList + nGCPCount;

            if( !EQUAL(psXMLGCP->pszValue,"GCP") || 
                psXMLGCP->eType != CXT_Element )
                continue;
             
            GDALInitGCPs( 1, psGCP );
             
            CPLFree( psGCP->pszId );
            psGCP->pszId = CPLStrdup(CPLGetXMLValue(psXMLGCP,"Id",""));
             
            CPLFree( psGCP->pszInfo );
            psGCP->pszInfo = CPLStrdup(CPLGetXMLValue(psXMLGCP,"Info",""));
             
            psGCP->dfGCPPixel = atof(CPLGetXMLValue(psXMLGCP,"Pixel","0.0"));
            psGCP->dfGCPLine = atof(CPLGetXMLValue(psXMLGCP,"Line","0.0"));
             
            psGCP->dfGCPX = atof(CPLGetXMLValue(psXMLGCP,"X","0.0"));
            psGCP->dfGCPY = atof(CPLGetXMLValue(psXMLGCP,"Y","0.0"));
            psGCP->dfGCPZ = atof(CPLGetXMLValue(psXMLGCP,"Z","0.0"));

            nGCPCount++;
        }
    }
     
/* -------------------------------------------------------------------- */
/*      Apply any dataset level metadata.                               */
/* -------------------------------------------------------------------- */
    oMDMD.XMLInit( psTree, TRUE );

/* -------------------------------------------------------------------- */
/*      Create dataset mask band.                                       */
/* -------------------------------------------------------------------- */
    CPLXMLNode *psChild;

    /* Parse dataset mask band first */
    CPLXMLNode* psMaskBandNode = CPLGetXMLNode(psTree, "MaskBand");
    if (psMaskBandNode)
        psChild = psMaskBandNode->psChild;
    else
        psChild = NULL;
    for( ; psChild != NULL; psChild=psChild->psNext )
    {
        if( psChild->eType == CXT_Element
            && EQUAL(psChild->pszValue,"VRTRasterBand") )
        {
            VRTRasterBand  *poBand = NULL;
            const char *pszSubclass = CPLGetXMLValue( psChild, "subclass",
                                                      "VRTSourcedRasterBand" );

            if( EQUAL(pszSubclass,"VRTSourcedRasterBand") )
                poBand = new VRTSourcedRasterBand( this, 0 );
            else if( EQUAL(pszSubclass, "VRTDerivedRasterBand") )
                poBand = new VRTDerivedRasterBand( this, 0 );
            else if( EQUAL(pszSubclass, "VRTRawRasterBand") )
                poBand = new VRTRawRasterBand( this, 0 );
            else if( EQUAL(pszSubclass, "VRTWarpedRasterBand") )
                poBand = new VRTWarpedRasterBand( this, 0 );
            else
                CPLError( CE_Failure, CPLE_AppDefined,
                          "VRTRasterBand of unrecognised subclass '%s'.",
                          pszSubclass );

            if( poBand != NULL
                && poBand->XMLInit( psChild, pszVRTPath ) == CE_None )
            {
                SetMaskBand(poBand);
                break;
            }
            else
            {
                if( poBand )
                    delete poBand;
                return CE_Failure;
            }
        }
    }

/* -------------------------------------------------------------------- */
/*      Create band information objects.                                */
/* -------------------------------------------------------------------- */
    int		nBands = 0;
    for( psChild=psTree->psChild; psChild != NULL; psChild=psChild->psNext )
    {
        if( psChild->eType == CXT_Element
            && EQUAL(psChild->pszValue,"VRTRasterBand") )
        {
            VRTRasterBand  *poBand = NULL;
            const char *pszSubclass = CPLGetXMLValue( psChild, "subclass", 
                                                      "VRTSourcedRasterBand" );

            if( EQUAL(pszSubclass,"VRTSourcedRasterBand") )
                poBand = new VRTSourcedRasterBand( this, nBands+1 );
            else if( EQUAL(pszSubclass, "VRTDerivedRasterBand") )
                poBand = new VRTDerivedRasterBand( this, nBands+1 );
            else if( EQUAL(pszSubclass, "VRTRawRasterBand") )
                poBand = new VRTRawRasterBand( this, nBands+1 );
            else if( EQUAL(pszSubclass, "VRTWarpedRasterBand") )
                poBand = new VRTWarpedRasterBand( this, nBands+1 );
            else
                CPLError( CE_Failure, CPLE_AppDefined,
                          "VRTRasterBand of unrecognised subclass '%s'.",
                          pszSubclass );

            if( poBand != NULL 
                && poBand->XMLInit( psChild, pszVRTPath ) == CE_None )
            {
                SetBand( ++nBands, poBand );
            }
            else
            {
                if( poBand )
                    delete poBand; 
                return CE_Failure;
            }
        }
    }
    
    return CE_None;
}
Example #28
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;
}
Example #29
0
CPLErr GDALPamRasterBand::XMLInit( CPLXMLNode *psTree, const char *pszUnused )

{
    PamInitialize();

/* -------------------------------------------------------------------- */
/*      Apply any dataset level metadata.                               */
/* -------------------------------------------------------------------- */
    oMDMD.XMLInit( psTree, TRUE );

/* -------------------------------------------------------------------- */
/*      Collect various other items of metadata.                        */
/* -------------------------------------------------------------------- */
    GDALMajorObject::SetDescription( CPLGetXMLValue( psTree, "Description", "" ) );
    
    if( CPLGetXMLValue( psTree, "NoDataValue", NULL ) != NULL )
    {
        const char *pszLEHex = 
            CPLGetXMLValue( psTree, "NoDataValue.le_hex_equiv", NULL );
        if( pszLEHex != NULL )
        {
            int nBytes;
            GByte *pabyBin = CPLHexToBinary( pszLEHex, &nBytes );
            if( nBytes == 8 )
            {
                CPL_LSBPTR64( pabyBin );
                
                GDALPamRasterBand::SetNoDataValue( *((double *) pabyBin) );
            }
            else
            {
                GDALPamRasterBand::SetNoDataValue( 
                    atof(CPLGetXMLValue( psTree, "NoDataValue", "0" )) );
            }
            CPLFree( pabyBin );
        }
        else
        {
            GDALPamRasterBand::SetNoDataValue( 
                atof(CPLGetXMLValue( psTree, "NoDataValue", "0" )) );
        }
    }

    GDALPamRasterBand::SetOffset( 
        atof(CPLGetXMLValue( psTree, "Offset", "0.0" )) );
    GDALPamRasterBand::SetScale( 
        atof(CPLGetXMLValue( psTree, "Scale", "1.0" )) );

    GDALPamRasterBand::SetUnitType( CPLGetXMLValue( psTree, "UnitType", NULL));

    if( CPLGetXMLValue( psTree, "ColorInterp", NULL ) != NULL )
    {
        const char *pszInterp = CPLGetXMLValue( psTree, "ColorInterp", NULL );
        GDALPamRasterBand::SetColorInterpretation(
                                GDALGetColorInterpretationByName(pszInterp));
    }

/* -------------------------------------------------------------------- */
/*      Category names.                                                 */
/* -------------------------------------------------------------------- */
    if( CPLGetXMLNode( psTree, "CategoryNames" ) != NULL )
    {
        CPLXMLNode *psEntry;
        char **papszCategoryNames = NULL;

        for( psEntry = CPLGetXMLNode( psTree, "CategoryNames" )->psChild;
             psEntry != NULL; psEntry = psEntry->psNext )
        {
            /* Don't skeep <Category> tag with empty content */
            if( psEntry->eType != CXT_Element 
                || !EQUAL(psEntry->pszValue,"Category") 
                || (psEntry->psChild != NULL && psEntry->psChild->eType != CXT_Text) )
                continue;
            
            papszCategoryNames = CSLAddString( papszCategoryNames, 
                                 (psEntry->psChild) ? psEntry->psChild->pszValue : "" );
        }
        
        GDALPamRasterBand::SetCategoryNames( papszCategoryNames );
    }

/* -------------------------------------------------------------------- */
/*      Collect a color table.                                          */
/* -------------------------------------------------------------------- */
    if( CPLGetXMLNode( psTree, "ColorTable" ) != NULL )
    {
        CPLXMLNode *psEntry;
        GDALColorTable oTable;
        int        iEntry = 0;

        for( psEntry = CPLGetXMLNode( psTree, "ColorTable" )->psChild;
             psEntry != NULL; psEntry = psEntry->psNext )
        {
            GDALColorEntry sCEntry;

            sCEntry.c1 = (short) atoi(CPLGetXMLValue( psEntry, "c1", "0" ));
            sCEntry.c2 = (short) atoi(CPLGetXMLValue( psEntry, "c2", "0" ));
            sCEntry.c3 = (short) atoi(CPLGetXMLValue( psEntry, "c3", "0" ));
            sCEntry.c4 = (short) atoi(CPLGetXMLValue( psEntry, "c4", "255" ));

            oTable.SetColorEntry( iEntry++, &sCEntry );
        }
        
        GDALPamRasterBand::SetColorTable( &oTable );
    }

/* -------------------------------------------------------------------- */
/*      Do we have a complete set of stats?                             */
/* -------------------------------------------------------------------- */
    if( CPLGetXMLNode( psTree, "Minimum" ) != NULL 
        && CPLGetXMLNode( psTree, "Maximum" ) != NULL )
    {
        psPam->bHaveMinMax = TRUE;
        psPam->dfMin = atof(CPLGetXMLValue(psTree, "Minimum","0"));
        psPam->dfMax = atof(CPLGetXMLValue(psTree, "Maximum","0"));
    }

    if( CPLGetXMLNode( psTree, "Mean" ) != NULL 
        && CPLGetXMLNode( psTree, "StandardDeviation" ) != NULL )
    {
        psPam->bHaveStats = TRUE;
        psPam->dfMean = atof(CPLGetXMLValue(psTree, "Mean","0"));
        psPam->dfStdDev = atof(CPLGetXMLValue(psTree,"StandardDeviation","0"));
    }

/* -------------------------------------------------------------------- */
/*      Histograms                                                      */
/* -------------------------------------------------------------------- */
    CPLXMLNode *psHist = CPLGetXMLNode( psTree, "Histograms" );
    if( psHist != NULL )
    {
        CPLXMLNode *psNext = psHist->psNext;
        psHist->psNext = NULL;

        psPam->psSavedHistograms = CPLCloneXMLTree( psHist );
        psHist->psNext = psNext;
    }

/* -------------------------------------------------------------------- */
/*      Raster Attribute Table                                          */
/* -------------------------------------------------------------------- */
    CPLXMLNode *psRAT = CPLGetXMLNode( psTree, "GDALRasterAttributeTable" );
    if( psRAT != NULL )
    {
        psPam->poDefaultRAT = new GDALRasterAttributeTable();
        psPam->poDefaultRAT->XMLInit( psRAT, "" );
    }

    return CE_None;
}
Example #30
0
OGRLayer*  OGRVRTDataSource::InstanciateWarpedLayer(
                                        CPLXMLNode *psLTree,
                                        const char *pszVRTDirectory,
                                        int bUpdate,
                                        int nRecLevel)
{
    if( !EQUAL(psLTree->pszValue,"OGRVRTWarpedLayer") )
        return NULL;

    CPLXMLNode *psSubNode;
    OGRLayer* poSrcLayer = NULL;

    for( psSubNode=psLTree->psChild;
         psSubNode != NULL;
         psSubNode=psSubNode->psNext )
    {
        if( psSubNode->eType != CXT_Element )
            continue;

        poSrcLayer = InstanciateLayer(psSubNode, pszVRTDirectory,
                                 bUpdate, nRecLevel + 1);
        if( poSrcLayer != NULL )
            break;
    }

    if( poSrcLayer == NULL )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Cannot instanciate source layer" );
        return NULL;
    }

    const char* pszTargetSRS = CPLGetXMLValue(psLTree, "TargetSRS", NULL);
    if( pszTargetSRS == NULL )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Missing TargetSRS element within OGRVRTWarpedLayer" );
        delete poSrcLayer;
        return NULL;
    }

    const char* pszGeomFieldName = CPLGetXMLValue(psLTree, "WarpedGeomFieldName", NULL);
    int iGeomField = 0;
    if( pszGeomFieldName != NULL )
    {
        iGeomField = poSrcLayer->GetLayerDefn()->GetGeomFieldIndex(pszGeomFieldName);
        if( iGeomField < 0 )
        {
            CPLError( CE_Failure, CPLE_AppDefined,
                  "Cannot find source geometry field '%s'", pszGeomFieldName );
            delete poSrcLayer;
            return NULL;
        }
    }

    OGRSpatialReference* poSrcSRS;
    OGRSpatialReference* poTargetSRS;
    const char* pszSourceSRS = CPLGetXMLValue(psLTree, "SrcSRS", NULL);

    if( pszSourceSRS == NULL )
    {
        poSrcSRS = poSrcLayer->GetLayerDefn()->GetGeomFieldDefn(iGeomField)->GetSpatialRef();
        if( poSrcSRS != NULL)
            poSrcSRS = poSrcSRS->Clone();
    }
    else
    {
        poSrcSRS = new OGRSpatialReference();
        if( poSrcSRS->SetFromUserInput(pszSourceSRS) != OGRERR_NONE )
        {
            delete poSrcSRS;
            poSrcSRS = NULL;
        }
    }

    if( poSrcSRS == NULL )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Failed to import source SRS" );
        delete poSrcLayer;
        return NULL;
    }

    poTargetSRS = new OGRSpatialReference();
    if( poTargetSRS->SetFromUserInput(pszTargetSRS) != OGRERR_NONE )
    {
        delete poTargetSRS;
        poTargetSRS = NULL;
    }

    if( poTargetSRS == NULL )
    {
        CPLError( CE_Failure, CPLE_AppDefined,
                  "Failed to import target SRS" );
        delete poSrcSRS;
        delete poSrcLayer;
        return NULL;
    }

    if( pszSourceSRS == NULL && poSrcSRS->IsSame(poTargetSRS) )
    {
        delete poSrcSRS;
        delete poTargetSRS;
        return poSrcLayer;
    }

    OGRCoordinateTransformation* poCT =
        OGRCreateCoordinateTransformation( poSrcSRS, poTargetSRS );
    OGRCoordinateTransformation* poReversedCT = (poCT != NULL) ?
        OGRCreateCoordinateTransformation( poTargetSRS, poSrcSRS ) : NULL;

    delete poSrcSRS;
    delete poTargetSRS;

    if( poCT == NULL )
    {
        delete poSrcLayer;
        return NULL;
    }

/* -------------------------------------------------------------------- */
/*      Build the OGRWarpedLayer.                                       */
/* -------------------------------------------------------------------- */

    OGRWarpedLayer* poLayer = new OGRWarpedLayer(poSrcLayer, iGeomField,
                                                 TRUE, poCT, poReversedCT);

/* -------------------------------------------------------------------- */
/*      Set Extent if provided                                          */
/* -------------------------------------------------------------------- */
    const char* pszExtentXMin = CPLGetXMLValue( psLTree, "ExtentXMin", NULL );
    const char* pszExtentYMin = CPLGetXMLValue( psLTree, "ExtentYMin", NULL );
    const char* pszExtentXMax = CPLGetXMLValue( psLTree, "ExtentXMax", NULL );
    const char* pszExtentYMax = CPLGetXMLValue( psLTree, "ExtentYMax", NULL );
    if( pszExtentXMin != NULL && pszExtentYMin != NULL &&
        pszExtentXMax != NULL && pszExtentYMax != NULL )
    {
        poLayer->SetExtent( CPLAtof(pszExtentXMin),
                            CPLAtof(pszExtentYMin),
                            CPLAtof(pszExtentXMax),
                            CPLAtof(pszExtentYMax) );
    }

    return poLayer;
}