void OGRNASDataSource::PopulateRelations()

{
    GMLFeature  *poFeature;

    poReader->ResetReading();
    while( (poFeature = poReader->NextFeature()) != NULL )
    {
        char **papszOBProperties = poFeature->GetOBProperties();
        int i;

        for( i = 0; papszOBProperties != NULL && papszOBProperties[i] != NULL;
             i++ )
        {
            const GMLProperty *psGMLId = poFeature->GetProperty( "gml_id" );
            char *pszName = NULL;
            const char *pszValue = CPLParseNameValue( papszOBProperties[i], 
                                                      &pszName );

            if( EQUALN(pszValue,"urn:adv:oid:",12) 
                && psGMLId != NULL && psGMLId->nSubProperties == 1 )
            {
                poRelationLayer->AddRelation( psGMLId->papszSubProperties[0],
                                              pszName, 
                                              pszValue + 12 );
            }
            CPLFree( pszName );
        }
        
        delete poFeature;
    }

    poRelationLayer->MarkRelationsPopulated();
}
示例#2
0
void NASReader::CheckForRelations( const char *pszElement,
                                   const Attributes &attrs,
                                   char **ppszCurField )

{
    GMLFeature *poFeature = GetState()->m_poFeature;

    CPLAssert( poFeature  != NULL );

    int nIndex;
    XMLCh  Name[100];

    tr_strcpy( Name, "xlink:href" );
    nIndex = attrs.getIndex( Name );

    if( nIndex != -1 )
    {
        char *pszHRef = tr_strdup( attrs.getValue( nIndex ) );

        if( EQUALN(pszHRef,"urn:adv:oid:", 12 ) )
        {
            poFeature->AddOBProperty( pszElement, pszHRef );
            CPLFree( *ppszCurField );
            *ppszCurField = CPLStrdup( pszHRef + 12 );
        }

        CPLFree( pszHRef );
    }
}
示例#3
0
void GMLReader::SetFeatureProperty( const char *pszElement, 
                                    const char *pszValue )

{
    GMLFeature *poFeature = GetState()->m_poFeature;

    CPLAssert( poFeature  != NULL );

/* -------------------------------------------------------------------- */
/*      Does this property exist in the feature class?  If not, add     */
/*      it.                                                             */
/* -------------------------------------------------------------------- */
    GMLFeatureClass *poClass = poFeature->GetClass();
    int      iProperty;

    for( iProperty=0; iProperty < poClass->GetPropertyCount(); iProperty++ )
    {
        if( EQUAL(poClass->GetProperty( iProperty )->GetSrcElement(),
                  pszElement ) )
            break;
    }
    
    if( iProperty == poClass->GetPropertyCount() )
    {
        if( poClass->IsSchemaLocked() )
        {
            CPLDebug("GML","Encountered property missing from class schema.");
            return;
        }

        GMLPropertyDefn *poPDefn = new GMLPropertyDefn(pszElement,pszElement);

        if( EQUAL(CPLGetConfigOption( "GML_FIELDTYPES", ""), "ALWAYS_STRING") )
            poPDefn->SetType( GMLPT_String );

        poClass->AddProperty( poPDefn );

    }

/* -------------------------------------------------------------------- */
/*      Set the property                                                */
/* -------------------------------------------------------------------- */
    poFeature->SetProperty( iProperty, pszValue );

/* -------------------------------------------------------------------- */
/*      Do we need to update the property type?                         */
/* -------------------------------------------------------------------- */
    if( !poClass->IsSchemaLocked() )
        poClass->GetProperty( iProperty )->AnalysePropertyValue(pszValue);
}
示例#4
0
void GMLReader::PushFeature( const char *pszElement, 
                             const char *pszFID )

{
    int iClass;

/* -------------------------------------------------------------------- */
/*      Find the class of this element.                                 */
/* -------------------------------------------------------------------- */
    for( iClass = 0; iClass < GetClassCount(); iClass++ )
    {
        if( EQUAL(pszElement,GetClass(iClass)->GetElementName()) )
            break;
    }

/* -------------------------------------------------------------------- */
/*      Create a new feature class for this element, if there is no     */
/*      existing class for it.                                          */
/* -------------------------------------------------------------------- */
    if( iClass == GetClassCount() )
    {
        CPLAssert( !IsClassListLocked() );

        GMLFeatureClass *poNewClass = new GMLFeatureClass( pszElement );

        AddClass( poNewClass );
    }

/* -------------------------------------------------------------------- */
/*      Create a feature of this feature class.  Try to set the fid     */
/*      if available.                                                   */
/* -------------------------------------------------------------------- */
    GMLFeature *poFeature = new GMLFeature( GetClass( iClass ) );
    if( pszFID != NULL )
    {
        poFeature->SetFID( pszFID );
    }

/* -------------------------------------------------------------------- */
/*      Create and push a new read state.                               */
/* -------------------------------------------------------------------- */
    GMLReadState *poState;

    poState = new GMLReadState();
    poState->m_poFeature = poFeature;
    PushState( poState );
}
示例#5
0
int GMLReader::PrescanForTemplate ()
{
    int iCount = 0;
    GMLFeature      *poFeature;
    //int bSequentialLayers = TRUE;
    GFSTemplateList *pCC = new GFSTemplateList();

    /* processing GML features */
    while( (poFeature = NextFeature()) != NULL )
    {
        GMLFeatureClass *poClass = poFeature->GetClass();
        const CPLXMLNode* const * papsGeomList = poFeature->GetGeometryList();
        int b_has_geom = FALSE;

        if( papsGeomList != NULL )
        {
            int i = 0;
            const CPLXMLNode *psNode = papsGeomList[i];
            while( psNode != NULL )
            {
                b_has_geom = TRUE;
                i++;
                psNode = papsGeomList[i];
            }
        }
        pCC->Update( poClass->GetElementName(), b_has_geom );

        delete poFeature;
    }

    gmlUpdateFeatureClasses( pCC, this, &m_bSequentialLayers );
    if ( m_bSequentialLayers == TRUE )
        ReArrangeTemplateClasses( pCC );
    iCount = pCC->GetClassCount();
    delete pCC;
    CleanupParser();
    return iCount > 0;
}
示例#6
0
void OGRNASDataSource::PopulateRelations()

{
    poReader->ResetReading();

    GMLFeature  *poFeature = NULL;
    while( (poFeature = poReader->NextFeature()) != NULL )
    {
        char **papszOBProperties = poFeature->GetOBProperties();

        for( int i = 0;
             papszOBProperties != NULL && papszOBProperties[i] != NULL;
             i++ )
        {
            const int nGMLIdIndex =
                poFeature->GetClass()->GetPropertyIndex( "gml_id" );
            const GMLProperty *psGMLId =
              (nGMLIdIndex >= 0) ? poFeature->GetProperty(nGMLIdIndex ) : NULL;
            char *l_pszName = NULL;
            const char *pszValue = CPLParseNameValue( papszOBProperties[i],
                                                      &l_pszName );

            if( STARTS_WITH_CI(pszValue, "urn:adv:oid:")
                && psGMLId != NULL && psGMLId->nSubProperties == 1 )
            {
                poRelationLayer->AddRelation( psGMLId->papszSubProperties[0],
                                              l_pszName,
                                              pszValue + 12 );
            }
            CPLFree( l_pszName );
        }

        delete poFeature;
    }

    poRelationLayer->MarkRelationsPopulated();
}
示例#7
0
OGRFeature *OGRNASLayer::GetNextFeature()

{
    GMLFeature  *poNASFeature = NULL;
    OGRGeometry *poGeom = NULL;

    if( iNextNASId == 0 )
        ResetReading();

/* ==================================================================== */
/*      Loop till we find and translate a feature meeting all our       */
/*      requirements.                                                   */
/* ==================================================================== */
    while( TRUE )
    {
/* -------------------------------------------------------------------- */
/*      Cleanup last feature, and get a new raw nas feature.            */
/* -------------------------------------------------------------------- */
        delete poNASFeature;
        delete poGeom;

        poNASFeature = NULL;
        poGeom = NULL;

        poNASFeature = poDS->GetReader()->NextFeature();
        if( poNASFeature == NULL )
            return NULL;

/* -------------------------------------------------------------------- */
/*      Is it of the proper feature class?                              */
/* -------------------------------------------------------------------- */

        // We count reading low level NAS features as a feature read for
        // work checking purposes, though at least we didn't necessary
        // have to turn it into an OGRFeature.
        m_nFeaturesRead++;

        if( poNASFeature->GetClass() != poFClass )
            continue;

        iNextNASId++;

/* -------------------------------------------------------------------- */
/*      Does it satisfy the spatial query, if there is one?             */
/* -------------------------------------------------------------------- */
        const CPLXMLNode* const * papsGeometry = poNASFeature->GetGeometryList();
        if (papsGeometry[0] != NULL)
        {
            poGeom = (OGRGeometry*) OGR_G_CreateFromGMLTree(papsGeometry[0]);

            // We assume the createFromNAS() function would have already
            // reported the error. 
            if( poGeom == NULL )
            {
                delete poNASFeature;
                return NULL;
            }
            
            if( m_poFilterGeom != NULL && !FilterGeometry( poGeom ) )
                continue;
        }
        
/* -------------------------------------------------------------------- */
/*      Convert the whole feature into an OGRFeature.                   */
/* -------------------------------------------------------------------- */
        int iField;
        OGRFeature *poOGRFeature = new OGRFeature( GetLayerDefn() );

        poOGRFeature->SetFID( iNextNASId );

        for( iField = 0; iField < poFClass->GetPropertyCount(); iField++ )
        {
            const GMLProperty *psGMLProperty = poNASFeature->GetProperty( iField );
            if( psGMLProperty == NULL || psGMLProperty->nSubProperties == 0 )
                continue;

            switch( poFClass->GetProperty(iField)->GetType()  )
            {
              case GMLPT_Real:
              {
                  poOGRFeature->SetField( iField, CPLAtof(psGMLProperty->papszSubProperties[0]) );
              }
              break;

              case GMLPT_IntegerList:
              {
                  int nCount = psGMLProperty->nSubProperties;
                  int *panIntList = (int *) CPLMalloc(sizeof(int) * nCount );
                  int i;

                  for( i = 0; i < nCount; i++ )
                      panIntList[i] = atoi(psGMLProperty->papszSubProperties[i]);

                  poOGRFeature->SetField( iField, nCount, panIntList );
                  CPLFree( panIntList );
              }
              break;

              case GMLPT_RealList:
              {
                  int nCount = psGMLProperty->nSubProperties;
                  double *padfList = (double *)CPLMalloc(sizeof(double)*nCount);
                  int i;

                  for( i = 0; i < nCount; i++ )
                      padfList[i] = CPLAtof(psGMLProperty->papszSubProperties[i]);

                  poOGRFeature->SetField( iField, nCount, padfList );
                  CPLFree( padfList );
              }
              break;

              case GMLPT_StringList:
              {
                  poOGRFeature->SetField( iField, psGMLProperty->papszSubProperties );
              }
              break;

              default:
                poOGRFeature->SetField( iField, psGMLProperty->papszSubProperties[0] );
                break;
            }
        }

/* -------------------------------------------------------------------- */
/*      Test against the attribute query.                               */
/* -------------------------------------------------------------------- */
        if( m_poAttrQuery != NULL
            && !m_poAttrQuery->Evaluate( poOGRFeature ) )
        {
            delete poOGRFeature;
            continue;
        }

/* -------------------------------------------------------------------- */
/*      Wow, we got our desired feature. Return it.                     */
/* -------------------------------------------------------------------- */
        delete poNASFeature;

        poOGRFeature->SetGeometryDirectly( poGeom );

        return poOGRFeature;
    }

    return NULL;
}
示例#8
0
int GMLReader::PrescanForSchema( int bGetExtents )

{
    GMLFeature  *poFeature;

    if( m_pszFilename == NULL )
        return FALSE;

    SetClassListLocked( FALSE );

    ClearClasses();
    if( !SetupParser() )
        return FALSE;

    while( (poFeature = NextFeature()) != NULL )
    {
        GMLFeatureClass *poClass = poFeature->GetClass();

        if( poClass->GetFeatureCount() == -1 )
            poClass->SetFeatureCount( 1 );
        else
            poClass->SetFeatureCount( poClass->GetFeatureCount() + 1 );

#ifdef SUPPORT_GEOMETRY
        if( bGetExtents )
        {
            OGRGeometry *poGeometry = NULL;

            if( poFeature->GetGeometry() != NULL 
                && strlen(poFeature->GetGeometry()) != 0 )
            {
                poGeometry = OGRGeometryFactory::createFromGML( 
                    poFeature->GetGeometry() );
            }

            if( poGeometry != NULL )
            {
                double  dfXMin, dfXMax, dfYMin, dfYMax;
                OGREnvelope sEnvelope;

                poGeometry->getEnvelope( &sEnvelope );
                delete poGeometry;
                if( poClass->GetExtents(&dfXMin, &dfXMax, &dfYMin, &dfYMax) )
                {
                    dfXMin = MIN(dfXMin,sEnvelope.MinX);
                    dfXMax = MAX(dfXMax,sEnvelope.MaxX);
                    dfYMin = MIN(dfYMin,sEnvelope.MinY);
                    dfYMax = MAX(dfYMax,sEnvelope.MaxY);
                }
                else
                {
                    dfXMin = sEnvelope.MinX;
                    dfXMax = sEnvelope.MaxX;
                    dfYMin = sEnvelope.MinY;
                    dfYMax = sEnvelope.MaxY;
                }

                poClass->SetExtents( dfXMin, dfXMax, dfYMin, dfYMax );
            }
#endif /* def SUPPORT_GEOMETRY */
        }
        
        delete poFeature;
    }

    CleanupParser();

    return GetClassCount() > 0;
}
OGRFeature *OGRGMLLayer::GetNextFeature()

{
    GMLFeature  *poGMLFeature = NULL;
    OGRGeometry *poGeom = NULL;

    if (bWriter)
    {
        CPLError(CE_Failure, CPLE_NotSupported,
                 "Cannot read features when writing a GML file");
        return NULL;
    }

    if( iNextGMLId == 0 )
        ResetReading();

/* ==================================================================== */
/*      Loop till we find and translate a feature meeting all our       */
/*      requirements.                                                   */
/* ==================================================================== */
    while( TRUE )
    {
/* -------------------------------------------------------------------- */
/*      Cleanup last feature, and get a new raw gml feature.            */
/* -------------------------------------------------------------------- */
        if( poGMLFeature != NULL )
            delete poGMLFeature;

        if( poGeom != NULL )
        {
            delete poGeom;
            poGeom = NULL;
        }

        poGMLFeature = poDS->GetReader()->NextFeature();
        if( poGMLFeature == NULL )
            return NULL;

/* -------------------------------------------------------------------- */
/*      Is it of the proper feature class?                              */
/* -------------------------------------------------------------------- */

        // We count reading low level GML features as a feature read for
        // work checking purposes, though at least we didn't necessary
        // have to turn it into an OGRFeature.
        m_nFeaturesRead++;

        if( poGMLFeature->GetClass() != poFClass )
            continue;

/* -------------------------------------------------------------------- */
/*      Extract the fid:                                                */
/*      -Assumes the fids are non-negative integers with an optional    */
/*       prefix                                                         */
/*      -If a prefix differs from the prefix of the first feature from  */
/*       the poDS then the fids from the poDS are ignored and are       */
/*       assigned serially thereafter                                   */
/* -------------------------------------------------------------------- */
        int nFID = -1;
        const char * pszGML_FID = poGMLFeature->GetFID();
        if( bInvalidFIDFound )
        {
            nFID = iNextGMLId++;
        }
        else if( pszGML_FID == NULL )
        {
            bInvalidFIDFound = TRUE;
            nFID = iNextGMLId++;
        }
        else if( iNextGMLId == 0 )
        {
            int i = strlen( pszGML_FID )-1, j = 0;
            while( i >= 0 && pszGML_FID[i] >= '0'
                          && pszGML_FID[i] <= '9' && j<8)
                i--, j++;
            /* i points the last character of the fid */
            if( i >= 0 && j < 8 && pszFIDPrefix == NULL)
            {
                pszFIDPrefix = (char *) CPLMalloc(i+2);
                pszFIDPrefix[i+1] = '\0';
                strncpy(pszFIDPrefix, pszGML_FID, i+1);
            }
            /* pszFIDPrefix now contains the prefix or NULL if no prefix is found */
            if( j < 8 && sscanf(pszGML_FID+i+1, "%d", &nFID)==1)
            {
                if( iNextGMLId <= nFID )
                    iNextGMLId = nFID + 1;
            }
            else
            {
                bInvalidFIDFound = TRUE;
                nFID = iNextGMLId++;
            }
        }
        else if( iNextGMLId != 0 )
        {
            const char* pszFIDPrefix_notnull = pszFIDPrefix;
            if (pszFIDPrefix_notnull == NULL) pszFIDPrefix_notnull = "";
            int nLenPrefix = strlen(pszFIDPrefix_notnull);

            if(  strncmp(pszGML_FID, pszFIDPrefix_notnull, nLenPrefix) == 0 &&
                 strlen(pszGML_FID+nLenPrefix) <= 9 &&
                 sscanf(pszGML_FID+nLenPrefix, "%d", &nFID) == 1 )
            { /* fid with the prefix. Using its numerical part */
                if( iNextGMLId < nFID )
                    iNextGMLId = nFID + 1;
            }
            else
            { /* fid without the aforementioned prefix or a valid numerical part */
                bInvalidFIDFound = TRUE;
                nFID = iNextGMLId++;
            }
        }

/* -------------------------------------------------------------------- */
/*      Does it satisfy the spatial query, if there is one?             */
/* -------------------------------------------------------------------- */

        char** papszGeometryList = poGMLFeature->GetGeometryList();
        if( papszGeometryList != NULL )
        {
            const char* pszSRSName = poDS->GetGlobalSRSName();
            poGeom = GML_BuildOGRGeometryFromList(papszGeometryList, TRUE,
                                                  m_bInvertAxisOrderIfLatLong, pszSRSName);
            if (poGeom != NULL && poSRS != NULL)
                poGeom->assignSpatialReference(poSRS);

            // We assume the createFromGML() function would have already
            // reported the error. 
            if( poGeom == NULL )
            {
                delete poGMLFeature;
                return NULL;
            }
            
            if( m_poFilterGeom != NULL && !FilterGeometry( poGeom ) )
                continue;
        }
        
/* -------------------------------------------------------------------- */
/*      Convert the whole feature into an OGRFeature.                   */
/* -------------------------------------------------------------------- */
        int iField;
        int iDstField = 0;
        OGRFeature *poOGRFeature = new OGRFeature( GetLayerDefn() );

        poOGRFeature->SetFID( nFID );
        if (poDS->ExposeGMLId())
        {
            if (pszGML_FID)
                poOGRFeature->SetField( iDstField, pszGML_FID );
            iDstField ++;
        }

        for( iField = 0; iField < poFClass->GetPropertyCount(); iField++, iDstField ++ )
        {
            const GMLProperty *psGMLProperty = poGMLFeature->GetProperty( iField );
            if( psGMLProperty == NULL || psGMLProperty->nSubProperties == 0 )
                continue;

            switch( poFClass->GetProperty(iField)->GetType()  )
            {
              case GMLPT_Real:
              {
                  poOGRFeature->SetField( iDstField, CPLAtof(psGMLProperty->papszSubProperties[0]) );
              }
              break;

              case GMLPT_IntegerList:
              {
                  int nCount = psGMLProperty->nSubProperties;
                  int *panIntList = (int *) CPLMalloc(sizeof(int) * nCount );
                  int i;

                  for( i = 0; i < nCount; i++ )
                      panIntList[i] = atoi(psGMLProperty->papszSubProperties[i]);

                  poOGRFeature->SetField( iDstField, nCount, panIntList );
                  CPLFree( panIntList );
              }
              break;

              case GMLPT_RealList:
              {
                  int nCount = psGMLProperty->nSubProperties;
                  double *padfList = (double *)CPLMalloc(sizeof(double)*nCount);
                  int i;

                  for( i = 0; i < nCount; i++ )
                      padfList[i] = CPLAtof(psGMLProperty->papszSubProperties[i]);

                  poOGRFeature->SetField( iDstField, nCount, padfList );
                  CPLFree( padfList );
              }
              break;

              case GMLPT_StringList:
              {
                  poOGRFeature->SetField( iDstField, psGMLProperty->papszSubProperties );
              }
              break;

              default:
                poOGRFeature->SetField( iDstField, psGMLProperty->papszSubProperties[0] );
                break;
            }
        }

/* -------------------------------------------------------------------- */
/*      Test against the attribute query.                               */
/* -------------------------------------------------------------------- */
        if( m_poAttrQuery != NULL
            && !m_poAttrQuery->Evaluate( poOGRFeature ) )
        {
            delete poOGRFeature;
            continue;
        }

/* -------------------------------------------------------------------- */
/*      Wow, we got our desired feature. Return it.                     */
/* -------------------------------------------------------------------- */
        delete poGMLFeature;

        poOGRFeature->SetGeometryDirectly( poGeom );

        return poOGRFeature;
    }

    return NULL;
}
示例#10
0
int NASReader::PrescanForSchema( int bGetExtents )

{
    GMLFeature  *poFeature;

    if( m_pszFilename == NULL )
        return FALSE;

    SetClassListLocked( FALSE );

    ClearClasses();
    if( !SetupParser() )
        return FALSE;

    while( (poFeature = NextFeature()) != NULL )
    {
        GMLFeatureClass *poClass = poFeature->GetClass();

        if( poClass->GetFeatureCount() == -1 )
            poClass->SetFeatureCount( 1 );
        else
            poClass->SetFeatureCount( poClass->GetFeatureCount() + 1 );

#ifdef SUPPORT_GEOMETRY
        if( bGetExtents )
        {
            OGRGeometry *poGeometry = NULL;

            if( poFeature->GetGeometry() != NULL 
                && strlen(poFeature->GetGeometry()) != 0 )
            {
                poGeometry = (OGRGeometry *) OGR_G_CreateFromGML( 
                    poFeature->GetGeometry() );
            }

            if( poGeometry != NULL )
            {
                double  dfXMin, dfXMax, dfYMin, dfYMax;
                OGREnvelope sEnvelope;
                OGRwkbGeometryType eGType = (OGRwkbGeometryType) 
                    poClass->GetGeometryType();

                // Merge geometry type into layer.
                if( poClass->GetFeatureCount() == 1 && eGType == wkbUnknown )
                    eGType = wkbNone;

                poClass->SetGeometryType( 
                    (int) OGRMergeGeometryTypes(
                        eGType, poGeometry->getGeometryType() ) );

                // merge extents.
                poGeometry->getEnvelope( &sEnvelope );
                delete poGeometry;
                if( poClass->GetExtents(&dfXMin, &dfXMax, &dfYMin, &dfYMax) )
                {
                    dfXMin = MIN(dfXMin,sEnvelope.MinX);
                    dfXMax = MAX(dfXMax,sEnvelope.MaxX);
                    dfYMin = MIN(dfYMin,sEnvelope.MinY);
                    dfYMax = MAX(dfYMax,sEnvelope.MaxY);
                }
                else
                {
                    dfXMin = sEnvelope.MinX;
                    dfXMax = sEnvelope.MaxX;
                    dfYMin = sEnvelope.MinY;
                    dfYMax = sEnvelope.MaxY;
                }

                poClass->SetExtents( dfXMin, dfXMax, dfYMin, dfYMax );
            }
            else 
            {
                if( poClass->GetGeometryType() == (int) wkbUnknown 
                    && poClass->GetFeatureCount() == 1 )
                    poClass->SetGeometryType( wkbNone );
            }
#endif /* def SUPPORT_GEOMETRY */
        }
        
        delete poFeature;
    }

    CleanupParser();

    return GetClassCount() > 0;
}
示例#11
0
void NASReader::SetFeatureProperty( const char *pszElement, 
                                    const char *pszValue )

{
    GMLFeature *poFeature = GetState()->m_poFeature;

    CPLAssert( poFeature  != NULL );

/* -------------------------------------------------------------------- */
/*      Does this property exist in the feature class?  If not, add     */
/*      it.                                                             */
/* -------------------------------------------------------------------- */
    GMLFeatureClass *poClass = poFeature->GetClass();
    int      iProperty;

    for( iProperty=0; iProperty < poClass->GetPropertyCount(); iProperty++ )
    {
        if( EQUAL(poClass->GetProperty( iProperty )->GetSrcElement(),
                  pszElement ) )
            break;
    }
    
    if( iProperty == poClass->GetPropertyCount() )
    {
        if( poClass->IsSchemaLocked() )
        {
            CPLDebug("GML","Encountered property missing from class schema.");
            return;
        }

        CPLString osFieldName;
        
        if( strchr(pszElement,'|') == NULL )
            osFieldName = pszElement;
        else
        {
            osFieldName = strrchr(pszElement,'|') + 1;
            if( poClass->GetPropertyIndex(osFieldName) != -1 )
                osFieldName = pszElement;
        }

        // Does this conflict with an existing property name? 
        while( poClass->GetProperty(osFieldName) != NULL )
        {
            osFieldName += "_";
        }

        GMLPropertyDefn *poPDefn = new GMLPropertyDefn(osFieldName,pszElement);

        if( EQUAL(CPLGetConfigOption( "GML_FIELDTYPES", ""), "ALWAYS_STRING") )
            poPDefn->SetType( GMLPT_String );

        poClass->AddProperty( poPDefn );
    }

/* -------------------------------------------------------------------- */
/*      Set the property                                                */
/* -------------------------------------------------------------------- */
    poFeature->SetProperty( iProperty, pszValue );

/* -------------------------------------------------------------------- */
/*      Do we need to update the property type?                         */
/* -------------------------------------------------------------------- */
    if( !poClass->IsSchemaLocked() )
    {
        poClass->GetProperty(iProperty)->AnalysePropertyValue(
                             poFeature->GetProperty(iProperty));
    }
}
示例#12
0
int NASReader::PrescanForSchema( int bGetExtents )

{
    GMLFeature  *poFeature;

    if( m_pszFilename == NULL )
        return FALSE;

    SetClassListLocked( FALSE );

    ClearClasses();
    if( !SetupParser() )
        return FALSE;

    std::string osWork;

    while( (poFeature = NextFeature()) != NULL )
    {
        GMLFeatureClass *poClass = poFeature->GetClass();

        if( poClass->GetFeatureCount() == -1 )
            poClass->SetFeatureCount( 1 );
        else
            poClass->SetFeatureCount( poClass->GetFeatureCount() + 1 );

#ifdef SUPPORT_GEOMETRY
        if( bGetExtents )
        {
            OGRGeometry *poGeometry = NULL;

            const CPLXMLNode* const * papsGeometry = poFeature->GetGeometryList();
            if( papsGeometry[0] != NULL )
            {
                poGeometry = (OGRGeometry*) OGR_G_CreateFromGMLTree(papsGeometry[0]);
            }

            if( poGeometry != NULL )
            {
                double  dfXMin, dfXMax, dfYMin, dfYMax;
                OGREnvelope sEnvelope;
                OGRwkbGeometryType eGType = (OGRwkbGeometryType) 
                    poClass->GetGeometryType();

                // Merge SRSName into layer.
                const char* pszSRSName = GML_ExtractSrsNameFromGeometry(papsGeometry, osWork, FALSE);
//                if (pszSRSName != NULL)
//                    m_bCanUseGlobalSRSName = FALSE;
                poClass->MergeSRSName(pszSRSName);

                // Merge geometry type into layer.
                if( poClass->GetFeatureCount() == 1 && eGType == wkbUnknown )
                    eGType = wkbNone;

                poClass->SetGeometryType( 
                    (int) OGRMergeGeometryTypes(
                        eGType, poGeometry->getGeometryType() ) );

                // merge extents.
                poGeometry->getEnvelope( &sEnvelope );
                delete poGeometry;
                if( poClass->GetExtents(&dfXMin, &dfXMax, &dfYMin, &dfYMax) )
                {
                    dfXMin = MIN(dfXMin,sEnvelope.MinX);
                    dfXMax = MAX(dfXMax,sEnvelope.MaxX);
                    dfYMin = MIN(dfYMin,sEnvelope.MinY);
                    dfYMax = MAX(dfYMax,sEnvelope.MaxY);
                }
                else
                {
                    dfXMin = sEnvelope.MinX;
                    dfXMax = sEnvelope.MaxX;
                    dfYMin = sEnvelope.MinY;
                    dfYMax = sEnvelope.MaxY;
                }

                poClass->SetExtents( dfXMin, dfXMax, dfYMin, dfYMax );
            }
            else 
            {
                if( poClass->GetGeometryType() == (int) wkbUnknown 
                    && poClass->GetFeatureCount() == 1 )
                    poClass->SetGeometryType( wkbNone );
            }
#endif /* def SUPPORT_GEOMETRY */
        }
        
        delete poFeature;
    }

    CleanupParser();

    return GetClassCount() > 0;
}
示例#13
0
void NASReader::SetFeaturePropertyDirectly( const char *pszElement,
                                            char *pszValue )

{
    GMLFeature *poFeature = GetState()->m_poFeature;

    CPLAssert( poFeature  != NULL );

/* -------------------------------------------------------------------- */
/*      Does this property exist in the feature class?  If not, add     */
/*      it.                                                             */
/* -------------------------------------------------------------------- */
    GMLFeatureClass *poClass = poFeature->GetClass();
    int      iProperty;

    for( iProperty=0; iProperty < poClass->GetPropertyCount(); iProperty++ )
    {
        if( EQUAL(poClass->GetProperty( iProperty )->GetSrcElement(),
                  pszElement ) )
            break;
    }
    
    if( iProperty == poClass->GetPropertyCount() )
    {
        if( poClass->IsSchemaLocked() )
        {
            CPLDebug("NAS","Encountered property missing from class schema.");
            CPLFree(pszValue);
            return;
        }

        CPLString osFieldName;
        
        if( strchr(pszElement,'|') == NULL )
            osFieldName = pszElement;
        else
        {
            osFieldName = strrchr(pszElement,'|') + 1;
            if( poClass->GetPropertyIndex(osFieldName) != -1 )
                osFieldName = pszElement;
        }

        // Does this conflict with an existing property name? 
        while( poClass->GetProperty(osFieldName) != NULL )
        {
            osFieldName += "_";
        }

        GMLPropertyDefn *poPDefn = new GMLPropertyDefn(osFieldName,pszElement);

        if( EQUAL(CPLGetConfigOption( "GML_FIELDTYPES", ""), "ALWAYS_STRING") )
            poPDefn->SetType( GMLPT_String );

        poClass->AddProperty( poPDefn );
    }

/* -------------------------------------------------------------------- */
/*      We want to handle <lage> specially to ensure it is zero         */
/*      filled, and treated as a string depspite the numeric            */
/*      content. https://trac.wheregroup.com/PostNAS/ticket/9           */
/* -------------------------------------------------------------------- */
    if( strcmp(poClass->GetProperty(iProperty)->GetName(),"lage") == 0 )
    {
        if( strlen(pszValue) < 5 )
        {
            CPLString osValue = "00000";
            osValue += pszValue;
            poFeature->SetPropertyDirectly( iProperty, CPLStrdup(osValue + osValue.size() - 5) );
            CPLFree(pszValue);
        }
        else
            poFeature->SetPropertyDirectly( iProperty, pszValue );

        
        if( !poClass->IsSchemaLocked() )
        {
            poClass->GetProperty(iProperty)->SetWidth( 5 );
            poClass->GetProperty(iProperty)->SetType( GMLPT_String );
        }
        return;
    }

/* -------------------------------------------------------------------- */
/*      Set the property                                                */
/* -------------------------------------------------------------------- */
    poFeature->SetPropertyDirectly( iProperty, pszValue );

/* -------------------------------------------------------------------- */
/*      Do we need to update the property type?                         */
/* -------------------------------------------------------------------- */
    if( !poClass->IsSchemaLocked() )
    {
        // Special handling for punktkennung per NAS #12
        if( strcmp(poClass->GetProperty(iProperty)->GetName(),
                   "punktkennung") == 0)
        {
            poClass->GetProperty(iProperty)->SetWidth( 15 );
            poClass->GetProperty(iProperty)->SetType( GMLPT_String );
        }
        // Special handling for artDerFlurstuecksgrenze per http://trac.osgeo.org/gdal/ticket/4255
        else if( strcmp(poClass->GetProperty(iProperty)->GetName(),
                   "artDerFlurstuecksgrenze") == 0)
        {
            poClass->GetProperty(iProperty)->SetType( GMLPT_IntegerList );
        }
        else
            poClass->GetProperty(iProperty)->AnalysePropertyValue(
                poFeature->GetProperty(iProperty));
    }
}
示例#14
0
OGRFeature *OGRGMLLayer::GetNextFeature()

{
    if (bWriter)
    {
        CPLError(CE_Failure, CPLE_NotSupported,
                 "Cannot read features when writing a GML file");
        return NULL;
    }

    if( poDS->GetLastReadLayer() != this )
    {
        if( poDS->GetReadMode() != INTERLEAVED_LAYERS )
            ResetReading();
        poDS->SetLastReadLayer(this);
    }

/* ==================================================================== */
/*      Loop till we find and translate a feature meeting all our       */
/*      requirements.                                                   */
/* ==================================================================== */
    while( true )
    {
        GMLFeature  *poGMLFeature = NULL;
        OGRGeometry *poGeom = NULL;

        poGMLFeature = poDS->PeekStoredGMLFeature();
        if (poGMLFeature != NULL)
            poDS->SetStoredGMLFeature(NULL);
        else
        {
            poGMLFeature = poDS->GetReader()->NextFeature();
            if( poGMLFeature == NULL )
                return NULL;

            // We count reading low level GML features as a feature read for
            // work checking purposes, though at least we didn't necessary
            // have to turn it into an OGRFeature.
            m_nFeaturesRead++;
        }

/* -------------------------------------------------------------------- */
/*      Is it of the proper feature class?                              */
/* -------------------------------------------------------------------- */

        if( poGMLFeature->GetClass() != poFClass )
        {
            if( poDS->GetReadMode() == INTERLEAVED_LAYERS ||
                (poDS->GetReadMode() == SEQUENTIAL_LAYERS && iNextGMLId != 0) )
            {
                CPLAssert(poDS->PeekStoredGMLFeature() == NULL);
                poDS->SetStoredGMLFeature(poGMLFeature);
                return NULL;
            }
            else
            {
                delete poGMLFeature;
                continue;
            }
        }

/* -------------------------------------------------------------------- */
/*      Extract the fid:                                                */
/*      -Assumes the fids are non-negative integers with an optional    */
/*       prefix                                                         */
/*      -If a prefix differs from the prefix of the first feature from  */
/*       the poDS then the fids from the poDS are ignored and are       */
/*       assigned serially thereafter                                   */
/* -------------------------------------------------------------------- */
        GIntBig nFID = -1;
        const char * pszGML_FID = poGMLFeature->GetFID();
        if( bInvalidFIDFound )
        {
            nFID = iNextGMLId++;
        }
        else if( pszGML_FID == NULL )
        {
            bInvalidFIDFound = true;
            nFID = iNextGMLId++;
        }
        else if( iNextGMLId == 0 )
        {
            int j = 0;
            int i = static_cast<int>(strlen( pszGML_FID ))-1;
            while( i >= 0 && pszGML_FID[i] >= '0'
                          && pszGML_FID[i] <= '9' && j<20)
                i--, j++;
            /* i points the last character of the fid */
            if( i >= 0 && j < 20 && pszFIDPrefix == NULL)
            {
                pszFIDPrefix = (char *) CPLMalloc(i+2);
                pszFIDPrefix[i+1] = '\0';
                strncpy(pszFIDPrefix, pszGML_FID, i+1);
            }
            /* pszFIDPrefix now contains the prefix or NULL if no prefix is found */
            if( j < 20 && sscanf(pszGML_FID+i+1, CPL_FRMT_GIB, &nFID)==1)
            {
                if( iNextGMLId <= nFID )
                    iNextGMLId = nFID + 1;
            }
            else
            {
                bInvalidFIDFound = true;
                nFID = iNextGMLId++;
            }
        }
        else if( iNextGMLId != 0 )
        {
            const char* pszFIDPrefix_notnull = pszFIDPrefix;
            if (pszFIDPrefix_notnull == NULL) pszFIDPrefix_notnull = "";
            int nLenPrefix = static_cast<int>(strlen(pszFIDPrefix_notnull));

            if(  strncmp(pszGML_FID, pszFIDPrefix_notnull, nLenPrefix) == 0 &&
                 strlen(pszGML_FID+nLenPrefix) < 20 &&
                 sscanf(pszGML_FID+nLenPrefix, CPL_FRMT_GIB, &nFID) == 1 )
            { /* fid with the prefix. Using its numerical part */
                if( iNextGMLId < nFID )
                    iNextGMLId = nFID + 1;
            }
            else
            { /* fid without the aforementioned prefix or a valid numerical part */
                bInvalidFIDFound = true;
                nFID = iNextGMLId++;
            }
        }

/* -------------------------------------------------------------------- */
/*      Does it satisfy the spatial query, if there is one?             */
/* -------------------------------------------------------------------- */

        OGRGeometry** papoGeometries = NULL;
        const CPLXMLNode* const * papsGeometry = poGMLFeature->GetGeometryList();

        if( poFeatureDefn->GetGeomFieldCount() > 1 )
        {
            papoGeometries = (OGRGeometry**)
                CPLCalloc( poFeatureDefn->GetGeomFieldCount(), sizeof(OGRGeometry*) );
            const char* pszSRSName = poDS->GetGlobalSRSName();
            for( int i=0; i < poFeatureDefn->GetGeomFieldCount(); i++ )
            {
                const CPLXMLNode* psGeom = poGMLFeature->GetGeometryRef(i);
                if( psGeom != NULL )
                {
                    const CPLXMLNode* myGeometryList[2];
                    myGeometryList[0] = psGeom;
                    myGeometryList[1] = NULL;
                    poGeom = GML_BuildOGRGeometryFromList(myGeometryList, true,
                                                  poDS->GetInvertAxisOrderIfLatLong(),
                                                  pszSRSName,
                                                  poDS->GetConsiderEPSGAsURN(),
                                                  poDS->GetSecondaryGeometryOption(),
                                                  hCacheSRS,
                                                  bFaceHoleNegative );

                    /* Do geometry type changes if needed to match layer geometry type */
                    if (poGeom != NULL)
                    {
                        papoGeometries[i] = OGRGeometryFactory::forceTo(poGeom,
                                    poFeatureDefn->GetGeomFieldDefn(i)->GetType());
                        poGeom = NULL;
                    }
                    else
                    // We assume the createFromGML() function would have already
                    // reported the error.
                    {
                        for( i=0; i < poFeatureDefn->GetGeomFieldCount(); i++)
                        {
                            delete papoGeometries[i];
                        }
                        CPLFree(papoGeometries);
                        delete poGMLFeature;
                        return NULL;
                    }
                }
            }

            if( m_poFilterGeom != NULL &&
                m_iGeomFieldFilter >= 0 &&
                m_iGeomFieldFilter < poFeatureDefn->GetGeomFieldCount() &&
                papoGeometries[m_iGeomFieldFilter] &&
                !FilterGeometry( papoGeometries[m_iGeomFieldFilter] ) )
            {
                for( int i=0; i < poFeatureDefn->GetGeomFieldCount(); i++ )
                {
                    delete papoGeometries[i];
                }
                CPLFree(papoGeometries);
                delete poGMLFeature;
                continue;
            }
        }
        else if (papsGeometry[0] != NULL)
        {
            const char* pszSRSName = poDS->GetGlobalSRSName();
            poGeom = GML_BuildOGRGeometryFromList(papsGeometry, true,
                                                  poDS->GetInvertAxisOrderIfLatLong(),
                                                  pszSRSName,
                                                  poDS->GetConsiderEPSGAsURN(),
                                                  poDS->GetSecondaryGeometryOption(),
                                                  hCacheSRS,
                                                  bFaceHoleNegative );

            /* Do geometry type changes if needed to match layer geometry type */
            if (poGeom != NULL)
            {
                poGeom = OGRGeometryFactory::forceTo(poGeom, GetGeomType());
            }
            else
            // We assume the createFromGML() function would have already
            // reported the error.
            {
                delete poGMLFeature;
                return NULL;
            }

            if( m_poFilterGeom != NULL && !FilterGeometry( poGeom ) )
            {
                delete poGMLFeature;
                delete poGeom;
                continue;
            }
        }

/* -------------------------------------------------------------------- */
/*      Convert the whole feature into an OGRFeature.                   */
/* -------------------------------------------------------------------- */
        int iField;
        int iDstField = 0;
        OGRFeature *poOGRFeature = new OGRFeature( poFeatureDefn );

        poOGRFeature->SetFID( nFID );
        if (poDS->ExposeId())
        {
            if (pszGML_FID)
                poOGRFeature->SetField( iDstField, pszGML_FID );
            iDstField ++;
        }

        int nPropertyCount = poFClass->GetPropertyCount();
        for( iField = 0; iField < nPropertyCount; iField++, iDstField ++ )
        {
            const GMLProperty *psGMLProperty = poGMLFeature->GetProperty( iField );
            if( psGMLProperty == NULL || psGMLProperty->nSubProperties == 0 )
                continue;

            switch( poFClass->GetProperty(iField)->GetType()  )
            {
              case GMLPT_Real:
              {
                  poOGRFeature->SetField( iDstField, CPLAtof(psGMLProperty->papszSubProperties[0]) );
              }
              break;

              case GMLPT_IntegerList:
              {
                  int nCount = psGMLProperty->nSubProperties;
                  int *panIntList = (int *) CPLMalloc(sizeof(int) * nCount );

                  for( int i = 0; i < nCount; i++ )
                      panIntList[i]
                          = atoi(psGMLProperty->papszSubProperties[i]);

                  poOGRFeature->SetField( iDstField, nCount, panIntList );
                  CPLFree( panIntList );
              }
              break;

              case GMLPT_Integer64List:
              {
                  int nCount = psGMLProperty->nSubProperties;
                  GIntBig *panIntList = (GIntBig *) CPLMalloc(sizeof(GIntBig) * nCount );

                  for( int i = 0; i < nCount; i++ )
                      panIntList[i]
                          = CPLAtoGIntBig(psGMLProperty->papszSubProperties[i]);

                  poOGRFeature->SetField( iDstField, nCount, panIntList );
                  CPLFree( panIntList );
              }
              break;

              case GMLPT_RealList:
              {
                  int nCount = psGMLProperty->nSubProperties;
                  double *padfList = (double *)CPLMalloc(sizeof(double)*nCount);

                  for( int i = 0; i < nCount; i++ )
                      padfList[i]
                          = CPLAtof(psGMLProperty->papszSubProperties[i]);

                  poOGRFeature->SetField( iDstField, nCount, padfList );
                  CPLFree( padfList );
              }
              break;

              case GMLPT_StringList:
              case GMLPT_FeaturePropertyList:
              {
                  poOGRFeature->SetField( iDstField, psGMLProperty->papszSubProperties );
              }
              break;

              case GMLPT_Boolean:
              {
                  if( strcmp(psGMLProperty->papszSubProperties[0], "true") == 0 ||
                      strcmp(psGMLProperty->papszSubProperties[0], "1") == 0 )
                  {
                      poOGRFeature->SetField( iDstField, 1);
                  }
                  else if( strcmp(psGMLProperty->papszSubProperties[0], "false") == 0 ||
                           strcmp(psGMLProperty->papszSubProperties[0], "0") == 0 )
                  {
                      poOGRFeature->SetField( iDstField, 0);
                  }
                  else
                      poOGRFeature->SetField( iDstField, psGMLProperty->papszSubProperties[0] );
                  break;
              }

              case GMLPT_BooleanList:
              {
                  int nCount = psGMLProperty->nSubProperties;
                  int *panIntList = (int *) CPLMalloc(sizeof(int) * nCount );

                  for( int i = 0; i < nCount; i++ )
                  {
                      panIntList[i] = (
                          strcmp(psGMLProperty->papszSubProperties[i],
                                 "true") == 0 ||
                          strcmp(psGMLProperty->papszSubProperties[i],
                                 "1") == 0 );
                  }

                  poOGRFeature->SetField( iDstField, nCount, panIntList );
                  CPLFree( panIntList );
                  break;
              }

              default:
                poOGRFeature->SetField( iDstField, psGMLProperty->papszSubProperties[0] );
                break;
            }
        }

        delete poGMLFeature;
        poGMLFeature = NULL;

        /* Assign the geometry before the attribute filter because */
        /* the attribute filter may use a special field like OGR_GEOMETRY */
        if( papoGeometries != NULL )
        {
            for( int i=0; i < poFeatureDefn->GetGeomFieldCount(); i++ )
            {
                poOGRFeature->SetGeomFieldDirectly( i, papoGeometries[i] );
            }
            CPLFree(papoGeometries);
            papoGeometries = NULL;
        }
        else
            poOGRFeature->SetGeometryDirectly( poGeom );

        /* Assign SRS */
        for( int i=0; i < poFeatureDefn->GetGeomFieldCount(); i++ )
        {
            poGeom = poOGRFeature->GetGeomFieldRef(i);
            if( poGeom != NULL )
            {
                OGRSpatialReference* poSRS
                    = poFeatureDefn->GetGeomFieldDefn(i)->GetSpatialRef();
                if (poSRS != NULL)
                    poGeom->assignSpatialReference(poSRS);
            }
        }

/* -------------------------------------------------------------------- */
/*      Test against the attribute query.                               */
/* -------------------------------------------------------------------- */
        if( m_poAttrQuery != NULL
            && !m_poAttrQuery->Evaluate( poOGRFeature ) )
        {
            delete poOGRFeature;
            continue;
        }

/* -------------------------------------------------------------------- */
/*      Wow, we got our desired feature. Return it.                     */
/* -------------------------------------------------------------------- */

        return poOGRFeature;
    }

    return NULL;
}