OGRErr GMLHandler::endElement(const char* pszName )

{
    m_nDepth --;

    if (m_bIgnoreFeature && m_nDepth >= m_nDepthFeature)
    {
        if (m_nDepth == m_nDepthFeature)
        {
             m_bIgnoreFeature = FALSE;
             m_nDepthFeature = 0;
        }
        return CE_None;
    }

    GMLReadState *poState = m_poReader->GetState();

    if( m_bInBoundedBy && strcmp(pszName, "boundedBy") == 0 &&
        m_inBoundedByDepth == m_nDepth)
    {
        m_bInBoundedBy = FALSE;
    }

    else if( m_bInCityGMLGenericAttr )
    {
        if( m_pszCityGMLGenericAttrName != NULL && m_pszCurField != NULL )
        {
            CPLAssert( poState->m_poFeature != NULL );

            m_poReader->SetFeatureProperty( m_pszCityGMLGenericAttrName, m_pszCurField );
            CPLFree( m_pszCurField );
            m_pszCurField = NULL;
            CPLFree(m_pszCityGMLGenericAttrName);
            m_pszCityGMLGenericAttrName = NULL;
        }

        if( m_inCityGMLGenericAttrDepth == m_nDepth )
        {
            m_bInCityGMLGenericAttr = 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.                                                    */
/* -------------------------------------------------------------------- */
    else if( m_pszCurField != NULL )
    {
        CPLAssert( poState->m_poFeature != NULL );

        if ( m_pszHref != NULL && (m_pszCurField == NULL || EQUAL(m_pszCurField, "")))
        {
            CPLString osPropNameHref = CPLSPrintf("%s_href", poState->m_pszPath);
            m_poReader->SetFeatureProperty( osPropNameHref, m_pszHref );
        }
        else
        {
            if (EQUAL(m_pszCurField, "") && m_pszValue != NULL)
                m_poReader->SetFeatureProperty( poState->m_pszPath, m_pszValue );
            else
                m_poReader->SetFeatureProperty( poState->m_pszPath, m_pszCurField );

            if (m_pszHref != NULL)
            {
                CPLString osPropNameHref = CPLSPrintf("%s_href", poState->m_pszPath);
                m_poReader->SetFeatureProperty( osPropNameHref, m_pszHref );
            }
        }
        if (m_pszUom != NULL)
        {
            CPLString osPropNameUom = CPLSPrintf("%s_uom", poState->m_pszPath);
            m_poReader->SetFeatureProperty( osPropNameUom, m_pszUom );
        }

        CPLFree( m_pszCurField );
        m_pszCurField = NULL;
        CPLFree( m_pszHref );
        m_pszHref = NULL;
        CPLFree( m_pszUom );
        m_pszUom = NULL;
        CPLFree( m_pszValue );
        m_pszValue = NULL;
    }

/* -------------------------------------------------------------------- */
/*      If we are collecting Geometry than store it, and consider if    */
/*      this is the end of the geometry.                                */
/* -------------------------------------------------------------------- */
    if( m_pszGeometry != NULL )
    {
        /* should save attributes too! */

        size_t nLNLenBytes = strlen(pszName);

        if( m_nGeomLen + nLNLenBytes + 4 > m_nGeomAlloc )
        {
            m_nGeomAlloc = (size_t) (m_nGeomAlloc * 1.3 + nLNLenBytes + 1000);
            char* pszNewGeometry = (char *)
                VSIRealloc( m_pszGeometry, m_nGeomAlloc);
            if (pszNewGeometry == NULL)
            {
                return CE_Failure;
            }
            m_pszGeometry = pszNewGeometry;
        }

        strcat( m_pszGeometry+m_nGeomLen, "</" );
        strcpy( m_pszGeometry+m_nGeomLen+2, pszName );
        strcat( m_pszGeometry+m_nGeomLen+nLNLenBytes+2, ">" );
        m_nGeomLen += nLNLenBytes + 3;

        if( m_nDepth == m_nGeometryDepth )
        {
            if( poState->m_poFeature != NULL )
            {
                /* AIXM ElevatedPoint. We want to parse this */
                /* a bit specially because ElevatedPoint is aixm: stuff and */
                /* the srsDimension of the <gml:pos> can be set to TRUE although */
                /* they are only 2 coordinates in practice */
                if ( m_bIsAIXM && strcmp(pszName, "ElevatedPoint") == 0 )
                {
                    CPLXMLNode *psGML = CPLParseXMLString( m_pszGeometry );
                    if (psGML)
                    {
                        const char* pszElevation =
                            CPLGetXMLValue( psGML, "elevation", NULL );
                        if (pszElevation)
                        {
                            m_poReader->SetFeatureProperty( "elevation",
                                                            pszElevation );
                            const char* pszElevationUnit =
                                CPLGetXMLValue( psGML, "elevation.uom", NULL );
                            if (pszElevationUnit)
                            {
                                m_poReader->SetFeatureProperty( "elevation_uom",
                                                             pszElevationUnit );
                            }
                        }

                        const char* pszGeoidUndulation =
                            CPLGetXMLValue( psGML, "geoidUndulation", NULL );
                        if (pszGeoidUndulation)
                        {
                            m_poReader->SetFeatureProperty( "geoidUndulation",
                                                            pszGeoidUndulation );
                            const char* pszGeoidUndulationUnit =
                                CPLGetXMLValue( psGML, "geoidUndulation.uom", NULL );
                            if (pszGeoidUndulationUnit)
                            {
                                m_poReader->SetFeatureProperty( "geoidUndulation_uom",
                                                             pszGeoidUndulationUnit );
                            }
                        }

                        const char* pszPos =
                                        CPLGetXMLValue( psGML, "pos", NULL );
                        const char* pszCoordinates =
                                  CPLGetXMLValue( psGML, "coordinates", NULL );
                        if (pszPos != NULL)
                        {
                            char* pszNewGeometry = CPLStrdup(CPLSPrintf(
                                "<gml:Point><gml:pos>%s</gml:pos></gml:Point>",
                                                                      pszPos));
                            CPLFree(m_pszGeometry);
                            m_pszGeometry = pszNewGeometry;
                        }
                        else if (pszCoordinates != NULL)
                        {
                            char* pszNewGeometry = CPLStrdup(CPLSPrintf(
                                "<gml:Point><gml:coordinates>%s</gml:coordinates></gml:Point>",
                                                              pszCoordinates));
                            CPLFree(m_pszGeometry);
                            m_pszGeometry = pszNewGeometry;
                        }
                        else
                        {
                            CPLFree(m_pszGeometry);
                            m_pszGeometry = NULL;
                        }
                        CPLDestroyXMLNode( psGML );
                    }
                    else
                    {
                        CPLFree(m_pszGeometry);
                        m_pszGeometry = NULL;
                    }
                }
                if (m_pszGeometry)
                {
                    if (m_poReader->FetchAllGeometries())
                        poState->m_poFeature->AddGeometry( m_pszGeometry );
                    else
                        poState->m_poFeature->SetGeometryDirectly( m_pszGeometry );
                }
            }
            else
                CPLFree( m_pszGeometry );

            m_pszGeometry = NULL;
            m_nGeomAlloc = m_nGeomLen = 0;
        }
    }

    if ( m_nGeometryDepth != 0 && m_nDepth == m_nGeometryDepth )
        m_nGeometryDepth = 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.                     */
/* -------------------------------------------------------------------- */
    if( m_nDepth == m_nDepthFeature && poState->m_poFeature != NULL
        && strcmp(pszName,
                 poState->m_poFeature->GetClass()->GetElementName()) == 0 )
    {
        m_nDepthFeature = 0;
        m_poReader->PopState();
    }

/* -------------------------------------------------------------------- */
/*      Otherwise, we just pop the element off the local read states    */
/*      element stack.                                                  */
/* -------------------------------------------------------------------- */
    else
    {
        if( strcmp(pszName,poState->GetLastComponent()) == 0 )
            poState->PopPath();
        else
        {
            CPLAssert( FALSE );
        }
    }

    return CE_None;
}
Esempio n. 2
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 );
        }
    }
}
Esempio n. 3
0
OGRErr GMLHandler::endElement(const char* pszName )

{
    m_nDepth --;

    GMLReadState *poState = m_poReader->GetState();

    int nLNLenBytes = strlen(pszName);

/* -------------------------------------------------------------------- */
/*      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->SetFeatureProperty( pszName, m_pszCurField );
        CPLFree( 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 )
    {
        /* should save attributes too! */

        if( m_nGeomLen + nLNLenBytes + 4 > m_nGeomAlloc )
        {
            m_nGeomAlloc = (int) (m_nGeomAlloc * 1.3 + nLNLenBytes + 1000);
            char* pszNewGeometry = (char *) 
                VSIRealloc( m_pszGeometry, m_nGeomAlloc);
            if (pszNewGeometry == NULL)
            {
                return CE_Failure;
            }
            m_pszGeometry = pszNewGeometry;
        }

        strcat( m_pszGeometry+m_nGeomLen, "</" );
        strcpy( m_pszGeometry+m_nGeomLen+2, pszName );
        strcat( m_pszGeometry+m_nGeomLen+nLNLenBytes+2, ">" );
        m_nGeomLen += nLNLenBytes + 3;

        if( poState->m_nPathLength == m_nGeometryDepth+1 )
        {
            if( poState->m_poFeature != NULL )
                poState->m_poFeature->SetGeometryDirectly( m_pszGeometry );
            else
                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.                     */
/* -------------------------------------------------------------------- */
    if( m_nDepth == m_nDepthFeature && poState->m_poFeature != NULL
        && strcmp(pszName,
                 poState->m_poFeature->GetClass()->GetElementName()) == 0 )
    {
        m_poReader->PopState();
    }

/* -------------------------------------------------------------------- */
/*      Otherwise, we just pop the element off the local read states    */
/*      element stack.                                                  */
/* -------------------------------------------------------------------- */
    else
    {
        if( strcmp(pszName,poState->GetLastComponent()) == 0 )
            poState->PopPath();
        else
        {
            CPLAssert( FALSE );
        }
    }

    return CE_None;
}