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