int GMLFeatureClass::InitializeFromXML( CPLXMLNode *psRoot ) { /* -------------------------------------------------------------------- */ /* Do some rudimentary checking that this is a well formed */ /* node. */ /* -------------------------------------------------------------------- */ if( psRoot == NULL || psRoot->eType != CXT_Element || !EQUAL(psRoot->pszValue,"GMLFeatureClass") ) { CPLError( CE_Failure, CPLE_AppDefined, "GMLFeatureClass::InitializeFromXML() called on %s node!", psRoot->pszValue ); return FALSE; } if( CPLGetXMLValue( psRoot, "Name", NULL ) == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "GMLFeatureClass has no <Name> element." ); return FALSE; } /* -------------------------------------------------------------------- */ /* Collect base info. */ /* -------------------------------------------------------------------- */ CPLFree( m_pszName ); m_pszName = CPLStrdup( CPLGetXMLValue( psRoot, "Name", NULL ) ); n_nNameLen = strlen(m_pszName); SetElementName( CPLGetXMLValue( psRoot, "ElementPath", m_pszName ) ); const char *pszGPath = CPLGetXMLValue( psRoot, "GeometryElementPath", "" ); if( strlen( pszGPath ) > 0 ) SetGeometryElement( pszGPath ); const char* pszGeometryType = CPLGetXMLValue( psRoot, "GeometryType", NULL ); if( pszGeometryType != NULL ) { int nGeomType = atoi(pszGeometryType) & (~wkb25DBit); if ((nGeomType >= 0 && nGeomType <= 7) || nGeomType == 100) SetGeometryType( atoi(pszGeometryType) ); else { CPLError(CE_Warning, CPLE_AppDefined, "Unrecognised geometry type : %s", pszGeometryType); } } SetSRSName( CPLGetXMLValue( psRoot, "SRSName", NULL ) ); /* -------------------------------------------------------------------- */ /* Collect dataset specific info. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psDSI = CPLGetXMLNode( psRoot, "DatasetSpecificInfo" ); if( psDSI != NULL ) { const char *pszValue; pszValue = CPLGetXMLValue( psDSI, "FeatureCount", NULL ); if( pszValue != NULL ) SetFeatureCount( atoi(pszValue) ); // Eventually we should support XML subtrees. pszValue = CPLGetXMLValue( psDSI, "ExtraInfo", NULL ); if( pszValue != NULL ) SetExtraInfo( pszValue ); if( CPLGetXMLValue( psDSI, "ExtentXMin", NULL ) != NULL && CPLGetXMLValue( psDSI, "ExtentXMax", NULL ) != NULL && CPLGetXMLValue( psDSI, "ExtentYMin", NULL ) != NULL && CPLGetXMLValue( psDSI, "ExtentYMax", NULL ) != NULL ) { SetExtents( CPLAtof(CPLGetXMLValue( psDSI, "ExtentXMin", "0.0" )), CPLAtof(CPLGetXMLValue( psDSI, "ExtentXMax", "0.0" )), CPLAtof(CPLGetXMLValue( psDSI, "ExtentYMin", "0.0" )), CPLAtof(CPLGetXMLValue( psDSI, "ExtentYMax", "0.0" )) ); } } /* -------------------------------------------------------------------- */ /* Collect property definitions. */ /* -------------------------------------------------------------------- */ for( CPLXMLNode *psThis = psRoot->psChild; psThis != NULL; psThis = psThis->psNext ) { if( EQUAL(psThis->pszValue, "PropertyDefn") ) { const char *pszName = CPLGetXMLValue( psThis, "Name", NULL ); const char *pszType = CPLGetXMLValue( psThis, "Type", "Untyped" ); GMLPropertyDefn *poPDefn; if( pszName == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "GMLFeatureClass %s has a PropertyDefn without a <Name>..", m_pszName ); return FALSE; } poPDefn = new GMLPropertyDefn( pszName, CPLGetXMLValue( psThis, "ElementPath", NULL ) ); if( EQUAL(pszType,"Untyped") ) poPDefn->SetType( GMLPT_Untyped ); else if( EQUAL(pszType,"String") ) { poPDefn->SetType( GMLPT_String ); poPDefn->SetWidth( atoi( CPLGetXMLValue( psThis, "Width", "0" ) ) ); } else if( EQUAL(pszType,"Integer") ) { poPDefn->SetType( GMLPT_Integer ); poPDefn->SetWidth( atoi( CPLGetXMLValue( psThis, "Width", "0" ) ) ); } else if( EQUAL(pszType,"Real") ) { poPDefn->SetType( GMLPT_Real ); poPDefn->SetWidth( atoi( CPLGetXMLValue( psThis, "Width", "0" ) ) ); poPDefn->SetPrecision( atoi( CPLGetXMLValue( psThis, "Precision", "0" ) ) ); } else if( EQUAL(pszType,"StringList") ) poPDefn->SetType( GMLPT_StringList ); else if( EQUAL(pszType,"IntegerList") ) poPDefn->SetType( GMLPT_IntegerList ); else if( EQUAL(pszType,"RealList") ) poPDefn->SetType( GMLPT_RealList ); else if( EQUAL(pszType,"Complex") ) poPDefn->SetType( GMLPT_Complex ); else { CPLError( CE_Failure, CPLE_AppDefined, "Unrecognised property type %s.", pszType ); delete poPDefn; return FALSE; } AddProperty( poPDefn ); } } return TRUE; }
int GMLFeatureClass::InitializeFromXML( CPLXMLNode *psRoot ) { /* -------------------------------------------------------------------- */ /* Do some rudimentary checking that this is a well formed */ /* node. */ /* -------------------------------------------------------------------- */ if( psRoot == NULL || psRoot->eType != CXT_Element || !EQUAL(psRoot->pszValue,"GMLFeatureClass") ) { CPLError( CE_Failure, CPLE_AppDefined, "GMLFeatureClass::InitializeFromXML() called on %s node!", psRoot->pszValue ); return FALSE; } if( CPLGetXMLValue( psRoot, "Name", NULL ) == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "GMLFeatureClass has no <Name> element." ); return FALSE; } /* -------------------------------------------------------------------- */ /* Collect base info. */ /* -------------------------------------------------------------------- */ CPLFree( m_pszName ); m_pszName = CPLStrdup( CPLGetXMLValue( psRoot, "Name", NULL ) ); n_nNameLen = strlen(m_pszName); SetElementName( CPLGetXMLValue( psRoot, "ElementPath", m_pszName ) ); /* -------------------------------------------------------------------- */ /* Collect geometry properties. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psThis; int bHasValidGeometryName = FALSE; int bHasValidGeometryElementPath = FALSE; int bHasFoundGeomType = FALSE; int bHasFoundGeomElements = FALSE; const char* pszGName = ""; const char* pszGPath = ""; int nGeomType = wkbUnknown; for( psThis = psRoot->psChild; psThis != NULL; psThis = psThis->psNext ) { if( psThis->eType == CXT_Element && EQUAL(psThis->pszValue, "GeomPropertyDefn") ) { const char *pszName = CPLGetXMLValue( psThis, "Name", "" ); const char *pszElementPath = CPLGetXMLValue( psThis, "ElementPath", "" ); const char *pszType = CPLGetXMLValue( psThis, "Type", NULL ); int bNullable = CSLTestBoolean(CPLGetXMLValue( psThis, "Nullable", "true") ); nGeomType = wkbUnknown; if( pszType != NULL && !EQUAL(pszType, "0") ) { nGeomType = atoi(pszType); OGRwkbGeometryType nFlattenGeomType = wkbFlatten(nGeomType); if( nGeomType != 0 && !(nFlattenGeomType >= wkbPoint && nFlattenGeomType <= wkbMultiSurface) ) { nGeomType = wkbUnknown; CPLError(CE_Warning, CPLE_AppDefined, "Unrecognised geometry type : %s", pszType); } else if( nGeomType == 0 ) nGeomType = OGRFromOGCGeomType(pszType); } bHasFoundGeomElements = TRUE; AddGeometryProperty( new GMLGeometryPropertyDefn( pszName, pszElementPath, nGeomType, -1, bNullable ) ); bHasValidGeometryName = FALSE; bHasValidGeometryElementPath = FALSE; bHasFoundGeomType = FALSE; } else if( psThis->eType == CXT_Element && strcmp(psThis->pszValue, "GeometryName") == 0 ) { bHasFoundGeomElements = TRUE; if( bHasValidGeometryName ) { AddGeometryProperty( new GMLGeometryPropertyDefn( pszGName, pszGPath, nGeomType, -1, TRUE ) ); bHasValidGeometryName = FALSE; bHasValidGeometryElementPath = FALSE; bHasFoundGeomType = FALSE; pszGPath = ""; nGeomType = wkbUnknown; } pszGName = CPLGetXMLValue( psThis, NULL, "" ); bHasValidGeometryName = TRUE; } else if( psThis->eType == CXT_Element && strcmp(psThis->pszValue, "GeometryElementPath") == 0 ) { bHasFoundGeomElements = TRUE; if( bHasValidGeometryElementPath ) { AddGeometryProperty( new GMLGeometryPropertyDefn( pszGName, pszGPath, nGeomType, -1, TRUE ) ); bHasValidGeometryName = FALSE; bHasValidGeometryElementPath = FALSE; bHasFoundGeomType = FALSE; pszGName = ""; nGeomType = wkbUnknown; } pszGPath = CPLGetXMLValue( psThis, NULL, "" ); bHasValidGeometryElementPath = TRUE; } else if( psThis->eType == CXT_Element && strcmp(psThis->pszValue, "GeometryType") == 0 ) { bHasFoundGeomElements = TRUE; if( bHasFoundGeomType ) { AddGeometryProperty( new GMLGeometryPropertyDefn( pszGName, pszGPath, nGeomType, -1, TRUE ) ); bHasValidGeometryName = FALSE; bHasValidGeometryElementPath = FALSE; bHasFoundGeomType = FALSE; pszGName = ""; pszGPath = ""; nGeomType = wkbUnknown; } const char* pszGeometryType = CPLGetXMLValue( psThis, NULL, NULL ); nGeomType = wkbUnknown; if( pszGeometryType != NULL && !EQUAL(pszGeometryType, "0") ) { nGeomType = atoi(pszGeometryType); OGRwkbGeometryType nFlattenGeomType = wkbFlatten(nGeomType); if( nGeomType == 100 || EQUAL(pszGeometryType, "NONE") ) { bHasValidGeometryElementPath = FALSE; bHasFoundGeomType = FALSE; break; } else if( nGeomType != 0 && !(nFlattenGeomType >= wkbPoint && nFlattenGeomType <= wkbMultiSurface) ) { nGeomType = wkbUnknown; CPLError(CE_Warning, CPLE_AppDefined, "Unrecognised geometry type : %s", pszGeometryType); } else if( nGeomType == 0 ) nGeomType = OGRFromOGCGeomType(pszGeometryType); } bHasFoundGeomType = TRUE; } } /* If there was a dangling <GeometryElementPath> or <GeometryType> or */ /* that no explicit geometry information has been found, then add */ /* a geometry field */ if( bHasValidGeometryElementPath || bHasFoundGeomType || !bHasFoundGeomElements ) { AddGeometryProperty( new GMLGeometryPropertyDefn( pszGName, pszGPath, nGeomType, -1, TRUE ) ); } SetSRSName( CPLGetXMLValue( psRoot, "SRSName", NULL ) ); /* -------------------------------------------------------------------- */ /* Collect dataset specific info. */ /* -------------------------------------------------------------------- */ CPLXMLNode *psDSI = CPLGetXMLNode( psRoot, "DatasetSpecificInfo" ); if( psDSI != NULL ) { const char *pszValue; pszValue = CPLGetXMLValue( psDSI, "FeatureCount", NULL ); if( pszValue != NULL ) SetFeatureCount( CPLAtoGIntBig(pszValue) ); // Eventually we should support XML subtrees. pszValue = CPLGetXMLValue( psDSI, "ExtraInfo", NULL ); if( pszValue != NULL ) SetExtraInfo( pszValue ); if( CPLGetXMLValue( psDSI, "ExtentXMin", NULL ) != NULL && CPLGetXMLValue( psDSI, "ExtentXMax", NULL ) != NULL && CPLGetXMLValue( psDSI, "ExtentYMin", NULL ) != NULL && CPLGetXMLValue( psDSI, "ExtentYMax", NULL ) != NULL ) { SetExtents( CPLAtof(CPLGetXMLValue( psDSI, "ExtentXMin", "0.0" )), CPLAtof(CPLGetXMLValue( psDSI, "ExtentXMax", "0.0" )), CPLAtof(CPLGetXMLValue( psDSI, "ExtentYMin", "0.0" )), CPLAtof(CPLGetXMLValue( psDSI, "ExtentYMax", "0.0" )) ); } } /* -------------------------------------------------------------------- */ /* Collect property definitions. */ /* -------------------------------------------------------------------- */ for( psThis = psRoot->psChild; psThis != NULL; psThis = psThis->psNext ) { if( psThis->eType == CXT_Element && EQUAL(psThis->pszValue, "PropertyDefn") ) { const char *pszName = CPLGetXMLValue( psThis, "Name", NULL ); const char *pszType = CPLGetXMLValue( psThis, "Type", "Untyped" ); const char *pszSubType = CPLGetXMLValue( psThis, "Subtype", "" ); const char *pszCondition = CPLGetXMLValue( psThis, "Condition", NULL ); int bNullable = CSLTestBoolean(CPLGetXMLValue( psThis, "Nullable", "true") ); GMLPropertyDefn *poPDefn; if( pszName == NULL ) { CPLError( CE_Failure, CPLE_AppDefined, "GMLFeatureClass %s has a PropertyDefn without a <Name>..", m_pszName ); return FALSE; } poPDefn = new GMLPropertyDefn( pszName, CPLGetXMLValue( psThis, "ElementPath", NULL ) ); poPDefn->SetNullable(bNullable); if( EQUAL(pszType,"Untyped") ) poPDefn->SetType( GMLPT_Untyped ); else if( EQUAL(pszType,"String") ) { if( EQUAL(pszSubType, "Boolean") ) { poPDefn->SetType( GMLPT_Boolean ); poPDefn->SetWidth( 1 ); } else { poPDefn->SetType( GMLPT_String ); poPDefn->SetWidth( atoi( CPLGetXMLValue( psThis, "Width", "0" ) ) ); } } else if( EQUAL(pszType,"Integer") ) { if( EQUAL(pszSubType, "Short") ) { poPDefn->SetType( GMLPT_Short ); } else if( EQUAL(pszSubType, "Integer64") ) { poPDefn->SetType( GMLPT_Integer64 ); } else { poPDefn->SetType( GMLPT_Integer ); } poPDefn->SetWidth( atoi( CPLGetXMLValue( psThis, "Width", "0" ) ) ); } else if( EQUAL(pszType,"Real") ) { if( EQUAL(pszSubType, "Float") ) { poPDefn->SetType( GMLPT_Float ); } else { poPDefn->SetType( GMLPT_Real ); } poPDefn->SetWidth( atoi( CPLGetXMLValue( psThis, "Width", "0" ) ) ); poPDefn->SetPrecision( atoi( CPLGetXMLValue( psThis, "Precision", "0" ) ) ); } else if( EQUAL(pszType,"StringList") ) { if( EQUAL(pszSubType, "Boolean") ) poPDefn->SetType( GMLPT_BooleanList ); else poPDefn->SetType( GMLPT_StringList ); } else if( EQUAL(pszType,"IntegerList") ) { if( EQUAL(pszSubType, "Integer64") ) poPDefn->SetType( GMLPT_Integer64List ); else poPDefn->SetType( GMLPT_IntegerList ); } else if( EQUAL(pszType,"RealList") ) poPDefn->SetType( GMLPT_RealList ); else if( EQUAL(pszType,"Complex") ) poPDefn->SetType( GMLPT_Complex ); else if( EQUAL(pszType,"FeatureProperty") ) poPDefn->SetType( GMLPT_FeatureProperty ); else if( EQUAL(pszType,"FeaturePropertyList") ) poPDefn->SetType( GMLPT_FeaturePropertyList ); else { CPLError( CE_Failure, CPLE_AppDefined, "Unrecognised property type %s.", pszType ); delete poPDefn; return FALSE; } if( pszCondition != NULL ) poPDefn->SetCondition(pszCondition); AddProperty( poPDefn ); } } return TRUE; }