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; }
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; }