Exemplo n.º 1
0
int OGRFMELayer::Initialize( IFMEFeature * poSchemaFeature,
                             OGRSpatialReference *poSRS )

{
    IFMEString  *poFMEString = NULL;
    
    poFMEString = poDS->GetFMESession()->createString();
    poFMEFeature = poDS->GetFMESession()->createFeature();

    if( poSRS != NULL )
        poSpatialRef = poSRS->Clone();

/* -------------------------------------------------------------------- */
/*      Create the definition with the definition name being the        */
/*      same as the FME feature type.                                   */
/* -------------------------------------------------------------------- */
    poSchemaFeature->getFeatureType( *poFMEString );

    poFeatureDefn = new OGRFeatureDefn( poFMEString->data() );
    SetDescription( poFeatureDefn->GetName() );
    poFeatureDefn->Reference();

    poDS->GetFMESession()->destroyString( poFMEString );

/* -------------------------------------------------------------------- */
/*      Get the list of attribute names.                                */
/* -------------------------------------------------------------------- */
    IFMEStringArray     *poAttrNames;

    poAttrNames = poDS->GetFMESession()->createStringArray();
    poSchemaFeature->getAllAttributeNames( *poAttrNames );

/* ==================================================================== */
/*      Loop over attributes, adding them to our feature defn.          */
/* ==================================================================== */
    OGRwkbGeometryType eGeomType = wkbNone;
    IFMEString  *poAttrValue;
    poAttrValue = poDS->GetFMESession()->createString();
    
    for( int iAttr = 0; iAttr < (int)poAttrNames->entries(); iAttr++ )
    {
        const char       *pszAttrName = (*poAttrNames)(iAttr);

/* -------------------------------------------------------------------- */
/*      Get the attribute value.                                        */
/* -------------------------------------------------------------------- */
        if( !poSchemaFeature->getAttribute(pszAttrName,*poAttrValue) )
            continue;

/* -------------------------------------------------------------------- */
/*      Handle geometry attributes.  Use them to try and establish      */
/*      the geometry type of this layer.  If we get conflicting         */
/*      geometries just fall back to the generic geometry type.         */
/* -------------------------------------------------------------------- */
        if( EQUALN(pszAttrName,"fme_geometry",12) )
        {
            OGRwkbGeometryType eAttrGeomType = wkbNone;

            if( EQUAL(poAttrValue->data(),"fme_point") )
                eAttrGeomType = wkbPoint;
            else if( EQUAL(poAttrValue->data(),"fme_text") )
                eAttrGeomType = wkbPoint;
            else if( EQUAL(poAttrValue->data(),"fme_area") )
                eAttrGeomType = wkbPolygon;
            else if( EQUAL(poAttrValue->data(),"fme_polygon") )
                eAttrGeomType = wkbPolygon;
            else if( EQUAL(poAttrValue->data(),"fme_rectangle") )
                eAttrGeomType = wkbPolygon;
            else if( EQUAL(poAttrValue->data(),"fme_rounded_rectangle") )
                eAttrGeomType = wkbPolygon;
            else if( EQUAL(poAttrValue->data(),"fme_line") )
                eAttrGeomType = wkbLineString;
            else if( EQUAL(poAttrValue->data(),"fme_arc") )
                eAttrGeomType = wkbLineString;
            else if( EQUAL(poAttrValue->data(),"fme_aggregate") )
                eAttrGeomType = wkbGeometryCollection;
            else if( EQUAL(poAttrValue->data(),"fme_no_geom") )
                eAttrGeomType = wkbNone;
            else
            {
                CPLDebug( "FME_OLEDB", 
                          "geometry field %s has unknown value %s, ignored.",
                          pszAttrName, 
                          poAttrValue->data() );
                continue;
            }

            if( eGeomType == wkbNone )
                eGeomType = eAttrGeomType;
            else if( eGeomType != eAttrGeomType )
                eGeomType = wkbUnknown;
        }

/* -------------------------------------------------------------------- */
/*      Skip '*' attributes which appear to be the raw attribute        */
/*      names from the source reader.  The versions that don't start    */
/*      with * appear to be massaged suitably for use, with fme         */
/*      standard data types.                                            */
/* -------------------------------------------------------------------- */
        if( EQUALN(pszAttrName,"fme_geometry",12) 
            || pszAttrName[0] == '*'
            || EQUALN(pszAttrName,"fme_geomattr",12) )
        {
            continue;
        }

/* -------------------------------------------------------------------- */
/*      Parse the type into tokens for easier use.                      */
/* -------------------------------------------------------------------- */
        char      **papszTokens;

        papszTokens = CSLTokenizeStringComplex( poAttrValue->data(),
                                                "(,", FALSE, FALSE );

/* -------------------------------------------------------------------- */
/*      Establish new fields.                                           */
/* -------------------------------------------------------------------- */
        OGRFieldType      eType;
        int               nWidth, nPrecision = 0;

        if( CSLCount(papszTokens) == 2 && EQUAL(papszTokens[0],"fme_char") )
        {
            eType = OFTString;
            nWidth = atoi(papszTokens[1]);
        }
        else if( CSLCount(papszTokens) == 3 
                 && EQUAL(papszTokens[0],"fme_decimal") )
        {
            nWidth = atoi(papszTokens[1]);
            nPrecision = atoi(papszTokens[2]);
            if( nPrecision == 0 )
                eType = OFTInteger;
            else
                eType = OFTReal;
        }
        else if( CSLCount(papszTokens) == 1
                 && EQUAL(papszTokens[0],"fme_int16") )
        {
            nWidth = 6;
            nPrecision = 0;
            eType = OFTInteger;
        }
        else if( CSLCount(papszTokens) == 1
                 && EQUAL(papszTokens[0],"fme_int32") )
        {
            nWidth = 0;
            nPrecision = 0;
            eType = OFTInteger;
        }
        else if( CSLCount(papszTokens) == 1
                 && (EQUAL(papszTokens[0],"fme_real32") 
                     || EQUAL(papszTokens[0],"fme_real64")) )
        {
            nWidth = 0;
            nPrecision = 0;
            eType = OFTReal;
        }
        else if( CSLCount(papszTokens) == 1
                 && EQUAL(papszTokens[0],"fme_boolean") )
        {
            nWidth = 1;
            nPrecision = 0;
            eType = OFTInteger;
        }
        else
        {
            printf( "Not able to translate field type: %s\n", 
                    poAttrValue->data() );
            CSLDestroy( papszTokens );
            continue;
        }

/* -------------------------------------------------------------------- */
/*      Add the field to the feature definition.                        */
/* -------------------------------------------------------------------- */
        OGRFieldDefn  oFieldDefn( pszAttrName, eType );
        
        oFieldDefn.SetWidth( nWidth );
        oFieldDefn.SetPrecision( nPrecision );

        poFeatureDefn->AddFieldDefn( &oFieldDefn );

        CSLDestroy( papszTokens );
    }

/* -------------------------------------------------------------------- */
/*      Assign the geometry type ... try to apply 3D-ness as well.      */
/* -------------------------------------------------------------------- */
    if( poSchemaFeature->getDimension() == FME_THREE_D )
        eGeomType = (OGRwkbGeometryType) (((int)eGeomType) | wkb25DBit);

    poFeatureDefn->SetGeomType( eGeomType );

/* -------------------------------------------------------------------- */
/*      Translate the spatial reference system.                         */
/* -------------------------------------------------------------------- */
    if( poSchemaFeature->getCoordSys() != NULL 
        && strlen(poSchemaFeature->getCoordSys()) > 0
        && poSpatialRef == NULL )
    {
        CPLDebug( "FME_OLEDB", "Layer %s has COORDSYS=%s on schema feature.",
                  poFeatureDefn->GetName(), 
                  poSchemaFeature->getCoordSys() );
        poSpatialRef = poDS->FME2OGRSpatialRef(poSchemaFeature->getCoordSys());
    }

/* -------------------------------------------------------------------- */
/*      Cleanup                                                         */
/* -------------------------------------------------------------------- */
    poDS->GetFMESession()->destroyString( poAttrValue );
    poDS->GetFMESession()->destroyStringArray( poAttrNames );

    return TRUE;
}
Exemplo n.º 2
0
int OGRFMELayerDB::CreateReader()

{
    FME_MsgNum    err;
    IFMESession  *poSession = poDS->GetFMESession();
    FME_UInt32   i;

    CPLAssert( poReader == NULL && nPreviousFeature == -1 );

/* -------------------------------------------------------------------- */
/*      Make a copy of the user directives, so we won't be altering     */
/*      the originals.                                                  */
/* -------------------------------------------------------------------- */
    IFMEStringArray  *poUDC = poSession->createStringArray();

    for( i = 0; i < poUserDirectives->entries(); i++ )
        poUDC->append( (*poUserDirectives)(i) );

/* -------------------------------------------------------------------- */
/*      Update the IDLIST to just select the desired table.             */
/* -------------------------------------------------------------------- */

    for( i = 0; i < poUDC->entries(); i++ )
    {
        if( EQUAL((const char *) (*poUDC)(i),"IDLIST") )
        {
            IFMEString    *poIDList = poSession->createString();
            *poIDList = GetLayerDefn()->GetName();
            poUDC->setElement( i+1, *poIDList );
            poSession->destroyString( poIDList );
            break;
        }
    }

    if( i == poUDC->entries() )
    {
        poUDC->append( "IDLIST" );
        poUDC->append( GetLayerDefn()->GetName() );
    }
/* -------------------------------------------------------------------- */
/*      Update the macros for source information, if needed.            */
/* -------------------------------------------------------------------- */
    if( m_poFilterGeom != NULL )
    {
        const char *pszDirective = "RUNTIME_MACROS";

        if( !poUDC->contains(pszDirective) )
        {
            poUDC->append(pszDirective);
            poUDC->append("");
        }
        for( i = 0; i < poUDC->entries(); i++ )
        {
            if( EQUAL((const char *) (*poUDC)(i),pszDirective) )
            {
                IFMEString  *poMacroValue = poSession->createString();
                char      szSEARCH_ENVELOPE[1024];
                OGREnvelope      oEnvelope;

                poUDC->getElement( i+1, *poMacroValue );

                m_poFilterGeom->getEnvelope( &oEnvelope );

                if( STARTS_WITH_CI(pszReaderName, "SDE") )
                {
                    sprintf( szSEARCH_ENVELOPE, "%.16f", oEnvelope.MinX );
                    SetMacro( poMacroValue, "_SDE3MINX", szSEARCH_ENVELOPE );

                    sprintf( szSEARCH_ENVELOPE, "%.16f", oEnvelope.MinY );
                    SetMacro( poMacroValue, "_SDE3MINY", szSEARCH_ENVELOPE );

                    sprintf( szSEARCH_ENVELOPE, "%.16f", oEnvelope.MaxX );
                    SetMacro( poMacroValue, "_SDE3MAXX", szSEARCH_ENVELOPE );

                    sprintf( szSEARCH_ENVELOPE, "%.16f", oEnvelope.MaxY );
                    SetMacro( poMacroValue, "_SDE3MAXY", szSEARCH_ENVELOPE );
                }
                else
                {
                    sprintf( szSEARCH_ENVELOPE, "%.16f", oEnvelope.MinX );
                    SetMacro( poMacroValue, "_ORACLE_MINX", szSEARCH_ENVELOPE);

                    sprintf( szSEARCH_ENVELOPE, "%.16f", oEnvelope.MinY );
                    SetMacro( poMacroValue, "_ORACLE_MINY", szSEARCH_ENVELOPE);

                    sprintf( szSEARCH_ENVELOPE, "%.16f", oEnvelope.MaxX );
                    SetMacro( poMacroValue, "_ORACLE_MAXX", szSEARCH_ENVELOPE);

                    sprintf( szSEARCH_ENVELOPE, "%.16f", oEnvelope.MaxY );
                    SetMacro( poMacroValue, "_ORACLE_MAXY", szSEARCH_ENVELOPE);
                }

                poUDC->setElement( i+1, *poMacroValue );

                CPLDebug( "FMEOLEDB", "Update %s to:\n%s",
                          pszDirective, poMacroValue->data() );

                poSession->destroyString( poMacroValue );
                break;
            }
        }
    }

/* -------------------------------------------------------------------- */
/*      Create new reader with desired constraints.                     */
/* -------------------------------------------------------------------- */
    poReader = poSession->createReader(pszReaderName, FME_FALSE, poUDC);
    poSession->destroyStringArray( poUDC );
    if( poReader == NULL )
    {
        CPLFMEError( poSession,
                     "Failed to create reader of type `%s'.\n",
                     pszReaderName );
        return FALSE;
    }

/* -------------------------------------------------------------------- */
/*      Setup constraints applied in open().                            */
/* -------------------------------------------------------------------- */
    IFMEStringArray     *poParms = poSession->createStringArray();

    if( pszAttributeFilter != NULL && strlen(pszAttributeFilter) > 0 )
    {
        if( STARTS_WITH_CI(pszReaderName, "SDE") )
            poParms->append( "WHERE" );
        else
            poParms->append( "WHERE_CLAUSE" );

        poParms->append( pszAttributeFilter );
    }
#ifdef notdef
    if( m_poFilterGeom != NULL )
    {
        char      szSEARCH_ENVELOPE[1024];
        OGREnvelope      oEnvelope;

        m_poFilterGeom->getEnvelope( &oEnvelope );

        sprintf( szSEARCH_ENVELOPE, "%.16f", oEnvelope.MinX );
        poParms->append( "SEARCH_ENVELOPE" );
        poParms->append( szSEARCH_ENVELOPE );

        sprintf( szSEARCH_ENVELOPE, "%.16f", oEnvelope.MinY );
        poParms->append( "SEARCH_ENVELOPE" );
        poParms->append( szSEARCH_ENVELOPE );

        sprintf( szSEARCH_ENVELOPE, "%.16f", oEnvelope.MaxX );
        poParms->append( "SEARCH_ENVELOPE" );
        poParms->append( szSEARCH_ENVELOPE );

        sprintf( szSEARCH_ENVELOPE, "%.16f", oEnvelope.MaxY );
        poParms->append( "SEARCH_ENVELOPE" );
        poParms->append( szSEARCH_ENVELOPE );
    }
#endif

    for( i = 0; i < poParms->entries(); i++ )
    {
        CPLDebug( "FMEOLEDB", "openParms[%d] = %s",
                  i, (const char *) (*poParms)(i) );
    }

/* -------------------------------------------------------------------- */
/*      Now try to open the dataset.                                    */
/* -------------------------------------------------------------------- */
    err = poReader->open( pszDataset, *poParms );
    if( err )
    {
        CPLFMEError( poSession,
                     "Failed to open dataset `%s' with reader of type `%s'.\n",
                     pszDataset, pszReaderName );
        return FALSE;
    }

    poSession->destroyStringArray( poParms );

    return TRUE;
}