예제 #1
0
int OGRGeomediaDataSource::Open( const char * pszNewName, int bUpdate,
                              int bTestOpen )

{
    CPLAssert( nLayers == 0 );

/* -------------------------------------------------------------------- */
/*      If this is the name of an MDB file, then construct the          */
/*      appropriate connection string.  Otherwise clip of GEOMEDIA: to  */
/*      get the DSN.                                                    */
/*                                                                      */
/* -------------------------------------------------------------------- */
    char *pszDSN;
    if( EQUALN(pszNewName,"GEOMEDIA:",9) )
        pszDSN = CPLStrdup( pszNewName + 9 );
    else
    {
        const char *pszDSNStringTemplate = NULL;
        pszDSNStringTemplate = CPLGetConfigOption( "GEOMEDIA_DRIVER_TEMPLATE", "DRIVER=Microsoft Access Driver (*.mdb);DBQ=%s");
        if (!CheckDSNStringTemplate(pszDSNStringTemplate))
        {
            CPLError( CE_Failure, CPLE_AppDefined,
                      "Illegal value for GEOMEDIA_DRIVER_TEMPLATE option");
            return FALSE;
        }
        pszDSN = (char *) CPLMalloc(strlen(pszNewName)+strlen(pszDSNStringTemplate)+100);
        sprintf( pszDSN, pszDSNStringTemplate,  pszNewName );
    }

/* -------------------------------------------------------------------- */
/*      Initialize based on the DSN.                                    */
/* -------------------------------------------------------------------- */
    CPLDebug( "Geomedia", "EstablishSession(%s)", pszDSN );

    if( !oSession.EstablishSession( pszDSN, NULL, NULL ) )
    {
        CPLError( CE_Failure, CPLE_AppDefined, 
                  "Unable to initialize ODBC connection to DSN for %s,\n"
                  "%s", pszDSN, oSession.GetLastError() );
        CPLFree( pszDSN );
        return FALSE;
    }

    CPLFree( pszDSN );

    pszName = CPLStrdup( pszNewName );
    
    bDSUpdate = bUpdate;

/* -------------------------------------------------------------------- */
/*      Collect list of tables and their supporting info from           */
/*      GAliasTable.                                                    */
/* -------------------------------------------------------------------- */
    CPLString osGFeaturesTable = GetTableNameFromType("INGRFeatures");
    if (osGFeaturesTable.size() == 0)
        return FALSE;

    CPLString osGeometryProperties = GetTableNameFromType("INGRGeometryProperties");
    CPLString osGCoordSystemTable = GetTableNameFromType("GCoordSystemTable");

    std::vector<char **> apapszGeomColumns;
    {
        CPLODBCStatement oStmt( &oSession );
        oStmt.Appendf( "SELECT FeatureName, PrimaryGeometryFieldName FROM %s", osGFeaturesTable.c_str() );

        if( !oStmt.ExecuteSQL() )
        {
            CPLDebug( "GEOMEDIA",
                    "SELECT on %s fails, perhaps not a geomedia geodatabase?\n%s",
                    osGFeaturesTable.c_str(),
                    oSession.GetLastError() );
            return FALSE;
        }

        while( oStmt.Fetch() )
        {
            int i, iNew = apapszGeomColumns.size();
            char **papszRecord = NULL;
            for( i = 0; i < 2; i++ )
                papszRecord = CSLAddString( papszRecord,
                                            oStmt.GetColData(i) );
            apapszGeomColumns.resize(iNew+1);
            apapszGeomColumns[iNew] = papszRecord;
        }
    }

    std::vector<OGRSpatialReference*> apoSRS;
    if (osGeometryProperties.size() != 0 && osGCoordSystemTable.size() != 0)
    {
        std::vector<CPLString> aosGUID;
        {
            CPLODBCStatement oStmt( &oSession );
            oStmt.Appendf( "SELECT GCoordSystemGUID FROM %s", osGeometryProperties.c_str() );

            if( !oStmt.ExecuteSQL() )
            {
                CPLDebug( "GEOMEDIA",
                        "SELECT on %s fails, perhaps not a geomedia geodatabase?\n%s",
                        osGeometryProperties.c_str(),
                        oSession.GetLastError() );
                return FALSE;
            }

            while( oStmt.Fetch() )
            {
                aosGUID.push_back(oStmt.GetColData(0));
            }

            if (apapszGeomColumns.size() != aosGUID.size())
            {
                CPLDebug( "GEOMEDIA", "%s and %s don't have the same size",
                        osGFeaturesTable.c_str(), osGeometryProperties.c_str() );
                return FALSE;
            }
        }

        int i;
        for(i=0; i<(int)aosGUID.size();i++)
        {
            apoSRS.push_back(GetGeomediaSRS(osGCoordSystemTable, aosGUID[i]));
        }
    }

/* -------------------------------------------------------------------- */
/*      Create a layer for each spatial table.                          */
/* -------------------------------------------------------------------- */
    unsigned int iTable;

    papoLayers = (OGRGeomediaLayer **) CPLCalloc(apapszGeomColumns.size(),
                                             sizeof(void*));

    for( iTable = 0; iTable < apapszGeomColumns.size(); iTable++ )
    {
        char **papszRecord = apapszGeomColumns[iTable];
        OGRGeomediaTableLayer  *poLayer;

        poLayer = new OGRGeomediaTableLayer( this );

        if( poLayer->Initialize( papszRecord[0], papszRecord[1], (apoSRS.size()) ? apoSRS[iTable] : NULL )
            != CE_None )
        {
            delete poLayer;
        }
        else
        {
            papoLayers[nLayers++] = poLayer;
        }
        CSLDestroy(papszRecord);
    }

    return TRUE;
}
예제 #2
0
int OGRMDBDataSource::OpenGeomediaWarehouse(OGRMDBTable* poGAliasTable)
{
    int iTableName = poGAliasTable->GetColumnIndex("TableName", TRUE);
    int iTableType = poGAliasTable->GetColumnIndex("TableType", TRUE);

    if (iTableName < 0 || iTableType < 0)
        return FALSE;

    char* pszFeatureTableName = NULL;
    char* pszGeometryProperties = NULL;
    char* pszGCoordSystemTable = NULL;
    while(poGAliasTable->GetNextRow())
    {
        char* pszTableType = poGAliasTable->GetColumnAsString(iTableType);
        if (pszTableType == NULL)
            continue;

        if (strcmp(pszTableType, "INGRFeatures") == 0)
        {
            pszFeatureTableName = poGAliasTable->GetColumnAsString(iTableName);
        }
        else if (strcmp(pszTableType, "INGRGeometryProperties") == 0)
        {
            pszGeometryProperties = poGAliasTable->GetColumnAsString(iTableName);
        }
        else if (strcmp(pszTableType, "GCoordSystemTable") == 0)
        {
            pszGCoordSystemTable = poGAliasTable->GetColumnAsString(iTableName);
        }

        CPLFree(pszTableType);
    }

    if (pszFeatureTableName == NULL)
    {
        CPLFree(pszGeometryProperties);
        CPLFree(pszGCoordSystemTable);
        return FALSE;
    }

    OGRMDBTable* poGFeaturesTable = poDB->GetTable(pszFeatureTableName);
    CPLFree(pszFeatureTableName);
    pszFeatureTableName = NULL;

    OGRMDBTable* poGeometryPropertiesTable;
    if (pszGeometryProperties)
        poGeometryPropertiesTable = poDB->GetTable(pszGeometryProperties);
    else
        poGeometryPropertiesTable = NULL;
    CPLFree(pszGeometryProperties);
    pszGeometryProperties = NULL;

    if (poGFeaturesTable == NULL)
    {
        delete poGeometryPropertiesTable;
        CPLFree(pszGCoordSystemTable);
        return FALSE;
    }

    int iFeatureName = poGFeaturesTable->GetColumnIndex("FeatureName", TRUE);
    int iGeometryType = poGFeaturesTable->GetColumnIndex("GeometryType", TRUE);
    int iPrimaryGeometryFieldName = poGFeaturesTable->GetColumnIndex("PrimaryGeometryFieldName", TRUE);

    if (iFeatureName < 0 || iGeometryType < 0 || iPrimaryGeometryFieldName < 0)
    {
        delete poGeometryPropertiesTable;
        delete poGFeaturesTable;
        CPLFree(pszGCoordSystemTable);
        return FALSE;
    }

    if (poGeometryPropertiesTable != NULL && poGeometryPropertiesTable->GetRowCount() != poGFeaturesTable->GetRowCount())
    {
        delete poGeometryPropertiesTable;
        poGeometryPropertiesTable = NULL;
    }

    int iGCoordSystemGUID = -1;
    if (poGeometryPropertiesTable)
    {
        iGCoordSystemGUID = poGeometryPropertiesTable->GetColumnIndex("GCoordSystemGUID", TRUE);
        if (iGCoordSystemGUID < 0)
        {
            delete poGeometryPropertiesTable;
            delete poGFeaturesTable;
            CPLFree(pszGCoordSystemTable);
            return FALSE;
        }
    }

    while(poGFeaturesTable->GetNextRow() &&
          (poGeometryPropertiesTable == NULL || poGeometryPropertiesTable->GetNextRow()))
    {
        char* pszFeatureName = poGFeaturesTable->GetColumnAsString(iFeatureName);
        //int nGeometryType = poGFeaturesTable->GetColumnAsInt(iGeometryType);
        char* pszGeometryFieldName = poGFeaturesTable->GetColumnAsString(iPrimaryGeometryFieldName);
        char* pszGCoordSystemGUID;
        if (poGeometryPropertiesTable)
            pszGCoordSystemGUID = poGeometryPropertiesTable->GetColumnAsString(iGCoordSystemGUID);
        else
            pszGCoordSystemGUID = NULL;
        if (pszFeatureName && pszGeometryFieldName)
        {
            OGRMDBTable* poTable = poDB->GetTable(pszFeatureName);
            if (poTable)
            {
                OGRMDBLayer* poLayer = new OGRMDBLayer( this, poTable );

                if( poLayer->Initialize( pszFeatureName,
                                         pszGeometryFieldName,
                                         GetGeomediaSRS(pszGCoordSystemTable, pszGCoordSystemGUID) )
                    != CE_None )
                {
                    delete poLayer;
                }
                else
                {
                    papoLayers = (OGRMDBLayer**)CPLRealloc(papoLayers, (nLayers+1) * sizeof(OGRMDBLayer*));
                    papoLayers[nLayers++] = poLayer;
                }
            }
        }
        CPLFree(pszFeatureName);
        CPLFree(pszGeometryFieldName);
        CPLFree(pszGCoordSystemGUID);
    }

    delete poGeometryPropertiesTable;
    delete poGFeaturesTable;
    CPLFree(pszGCoordSystemTable);

    return TRUE;
}