LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/mdb - ogrmdbdatasource.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 199 68 34.2 %
Date: 2012-12-26 Functions: 12 7 58.3 %

       1                 : /******************************************************************************
       2                 :  * $Id: ogrmdbdatasource.cpp 21562 2011-01-23 12:29:25Z rouault $
       3                 :  *
       4                 :  * Project:  OpenGIS Simple Features Reference Implementation
       5                 :  * Purpose:  Implements OGRMDBDataSource class.
       6                 :  * Author:   Even Rouault, <even dot rouault at mines dash paris dot org>
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 2011, Even Rouault, <even dot rouault at mines dash paris dot org>
      10                 :  *
      11                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      12                 :  * copy of this software and associated documentation files (the "Software"),
      13                 :  * to deal in the Software without restriction, including without limitation
      14                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      15                 :  * and/or sell copies of the Software, and to permit persons to whom the
      16                 :  * Software is furnished to do so, subject to the following conditions:
      17                 :  *
      18                 :  * The above copyright notice and this permission notice shall be included
      19                 :  * in all copies or substantial portions of the Software.
      20                 :  *
      21                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      22                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      23                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      24                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      25                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      26                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      27                 :  * DEALINGS IN THE SOFTWARE.
      28                 :  ****************************************************************************/
      29                 : 
      30                 : #include "ogr_mdb.h"
      31                 : #include "cpl_conv.h"
      32                 : #include "cpl_string.h"
      33                 : #include <vector>
      34                 : #include "ogrgeomediageometry.h"
      35                 : 
      36                 : CPL_CVSID("$Id: ogrmdbdatasource.cpp 21562 2011-01-23 12:29:25Z rouault $");
      37                 : 
      38                 : /************************************************************************/
      39                 : /*                         OGRMDBDataSource()                          */
      40                 : /************************************************************************/
      41                 : 
      42               6 : OGRMDBDataSource::OGRMDBDataSource()
      43                 : 
      44                 : {
      45               6 :     pszName = NULL;
      46               6 :     papoLayers = NULL;
      47               6 :     papoLayersInvisible = NULL;
      48               6 :     nLayers = 0;
      49               6 :     nLayersWithInvisible = 0;
      50               6 :     poDB = NULL;
      51               6 : }
      52                 : 
      53                 : /************************************************************************/
      54                 : /*                         ~OGRMDBDataSource()                         */
      55                 : /************************************************************************/
      56                 : 
      57               6 : OGRMDBDataSource::~OGRMDBDataSource()
      58                 : 
      59                 : {
      60                 :     int         i;
      61                 : 
      62               6 :     CPLFree( pszName );
      63                 : 
      64              24 :     for( i = 0; i < nLayers; i++ )
      65              18 :         delete papoLayers[i];
      66               6 :     CPLFree( papoLayers );
      67                 : 
      68               6 :     for( i = 0; i < nLayersWithInvisible; i++ )
      69               0 :         delete papoLayersInvisible[i];
      70               6 :     CPLFree( papoLayersInvisible );
      71                 : 
      72                 : 
      73               6 :     delete poDB;
      74               6 : }
      75                 : 
      76                 : 
      77                 : /************************************************************************/
      78                 : /*                              OpenGDB()                               */
      79                 : /************************************************************************/
      80                 : 
      81               6 : int OGRMDBDataSource::OpenGDB(OGRMDBTable* poGDB_GeomColumns)
      82                 : {
      83               6 :     int iTableName = poGDB_GeomColumns->GetColumnIndex("TableName", TRUE);
      84               6 :     int iFieldName = poGDB_GeomColumns->GetColumnIndex("FieldName", TRUE);
      85               6 :     int iShapeType = poGDB_GeomColumns->GetColumnIndex("ShapeType", TRUE);
      86               6 :     int iExtentLeft = poGDB_GeomColumns->GetColumnIndex("ExtentLeft", TRUE);
      87               6 :     int iExtentRight = poGDB_GeomColumns->GetColumnIndex("ExtentRight", TRUE);
      88               6 :     int iExtentBottom = poGDB_GeomColumns->GetColumnIndex("ExtentBottom", TRUE);
      89               6 :     int iExtentTop = poGDB_GeomColumns->GetColumnIndex("ExtentTop", TRUE);
      90               6 :     int iSRID = poGDB_GeomColumns->GetColumnIndex("SRID", TRUE);
      91               6 :     int iHasZ = poGDB_GeomColumns->GetColumnIndex("HasZ", TRUE);
      92                 : 
      93               6 :     if (iTableName < 0 || iFieldName < 0 || iShapeType < 0 ||
      94                 :         iExtentLeft < 0 || iExtentRight < 0 || iExtentBottom < 0 ||
      95                 :         iExtentTop < 0 || iSRID < 0 || iHasZ < 0)
      96               0 :         return FALSE;
      97                 : 
      98              30 :     while(poGDB_GeomColumns->GetNextRow())
      99                 :     {
     100                 :         OGRMDBLayer  *poLayer;
     101                 : 
     102              18 :         char* pszTableName = poGDB_GeomColumns->GetColumnAsString(iTableName);
     103              18 :         char* pszFieldName = poGDB_GeomColumns->GetColumnAsString(iFieldName);
     104              18 :         if (pszTableName == NULL || pszFieldName == NULL)
     105                 :         {
     106               0 :             CPLFree(pszTableName);
     107               0 :             CPLFree(pszFieldName);
     108               0 :             continue;
     109                 :         }
     110                 : 
     111              18 :         OGRMDBTable* poTable = poDB->GetTable(pszTableName);
     112              18 :         if (poTable == NULL)
     113                 :         {
     114               0 :             CPLFree(pszTableName);
     115               0 :             CPLFree(pszFieldName);
     116               0 :             continue;
     117                 :         }
     118                 : 
     119              18 :         poLayer = new OGRMDBLayer( this, poTable );
     120                 : 
     121              18 :         if( poLayer->Initialize( pszTableName,
     122                 :                                  pszFieldName,
     123                 :                                  poGDB_GeomColumns->GetColumnAsInt(iShapeType),
     124                 :                                  poGDB_GeomColumns->GetColumnAsDouble(iExtentLeft),
     125                 :                                  poGDB_GeomColumns->GetColumnAsDouble(iExtentRight),
     126                 :                                  poGDB_GeomColumns->GetColumnAsDouble(iExtentBottom),
     127                 :                                  poGDB_GeomColumns->GetColumnAsDouble(iExtentTop),
     128                 :                                  poGDB_GeomColumns->GetColumnAsInt(iSRID),
     129                 :                                  poGDB_GeomColumns->GetColumnAsInt(iHasZ) )
     130                 :             != CE_None )
     131                 :         {
     132               0 :             delete poLayer;
     133                 :         }
     134                 :         else
     135                 :         {
     136              18 :             papoLayers = (OGRMDBLayer**)CPLRealloc(papoLayers, (nLayers+1) * sizeof(OGRMDBLayer*));
     137              18 :             papoLayers[nLayers++] = poLayer;
     138                 :         }
     139                 : 
     140              18 :         CPLFree(pszTableName);
     141              18 :         CPLFree(pszFieldName);
     142                 :     }
     143                 : 
     144               6 :     return TRUE;
     145                 : }
     146                 : 
     147                 : /************************************************************************/
     148                 : /*                        OpenGeomediaWarehouse()                       */
     149                 : /************************************************************************/
     150                 : 
     151               0 : int OGRMDBDataSource::OpenGeomediaWarehouse(OGRMDBTable* poGAliasTable)
     152                 : {
     153               0 :     int iTableName = poGAliasTable->GetColumnIndex("TableName", TRUE);
     154               0 :     int iTableType = poGAliasTable->GetColumnIndex("TableType", TRUE);
     155                 : 
     156               0 :     if (iTableName < 0 || iTableType < 0)
     157               0 :         return FALSE;
     158                 : 
     159               0 :     char* pszFeatureTableName = NULL;
     160               0 :     char* pszGeometryProperties = NULL;
     161               0 :     char* pszGCoordSystemTable = NULL;
     162               0 :     while(poGAliasTable->GetNextRow())
     163                 :     {
     164               0 :         char* pszTableType = poGAliasTable->GetColumnAsString(iTableType);
     165               0 :         if (pszTableType == NULL)
     166               0 :             continue;
     167                 : 
     168               0 :         if (strcmp(pszTableType, "INGRFeatures") == 0)
     169                 :         {
     170               0 :             pszFeatureTableName = poGAliasTable->GetColumnAsString(iTableName);
     171                 :         }
     172               0 :         else if (strcmp(pszTableType, "INGRGeometryProperties") == 0)
     173                 :         {
     174               0 :             pszGeometryProperties = poGAliasTable->GetColumnAsString(iTableName);
     175                 :         }
     176               0 :         else if (strcmp(pszTableType, "GCoordSystemTable") == 0)
     177                 :         {
     178               0 :             pszGCoordSystemTable = poGAliasTable->GetColumnAsString(iTableName);
     179                 :         }
     180                 : 
     181               0 :         CPLFree(pszTableType);
     182                 :     }
     183                 : 
     184               0 :     if (pszFeatureTableName == NULL)
     185                 :     {
     186               0 :         CPLFree(pszGeometryProperties);
     187               0 :         CPLFree(pszGCoordSystemTable);
     188               0 :         return FALSE;
     189                 :     }
     190                 : 
     191               0 :     OGRMDBTable* poGFeaturesTable = poDB->GetTable(pszFeatureTableName);
     192               0 :     CPLFree(pszFeatureTableName);
     193               0 :     pszFeatureTableName = NULL;
     194                 : 
     195                 :     OGRMDBTable* poGeometryPropertiesTable;
     196               0 :     if (pszGeometryProperties)
     197               0 :         poGeometryPropertiesTable = poDB->GetTable(pszGeometryProperties);
     198                 :     else
     199               0 :         poGeometryPropertiesTable = NULL;
     200               0 :     CPLFree(pszGeometryProperties);
     201               0 :     pszGeometryProperties = NULL;
     202                 : 
     203               0 :     if (poGFeaturesTable == NULL)
     204                 :     {
     205               0 :         delete poGeometryPropertiesTable;
     206               0 :         CPLFree(pszGCoordSystemTable);
     207               0 :         return FALSE;
     208                 :     }
     209                 : 
     210               0 :     int iFeatureName = poGFeaturesTable->GetColumnIndex("FeatureName", TRUE);
     211               0 :     int iGeometryType = poGFeaturesTable->GetColumnIndex("GeometryType", TRUE);
     212               0 :     int iPrimaryGeometryFieldName = poGFeaturesTable->GetColumnIndex("PrimaryGeometryFieldName", TRUE);
     213                 : 
     214               0 :     if (iFeatureName < 0 || iGeometryType < 0 || iPrimaryGeometryFieldName < 0)
     215                 :     {
     216               0 :         delete poGeometryPropertiesTable;
     217               0 :         delete poGFeaturesTable;
     218               0 :         CPLFree(pszGCoordSystemTable);
     219               0 :         return FALSE;
     220                 :     }
     221                 : 
     222               0 :     if (poGeometryPropertiesTable != NULL && poGeometryPropertiesTable->GetRowCount() != poGFeaturesTable->GetRowCount())
     223                 :     {
     224               0 :         delete poGeometryPropertiesTable;
     225               0 :         poGeometryPropertiesTable = NULL;
     226                 :     }
     227                 : 
     228               0 :     int iGCoordSystemGUID = -1;
     229               0 :     if (poGeometryPropertiesTable)
     230                 :     {
     231               0 :         iGCoordSystemGUID = poGeometryPropertiesTable->GetColumnIndex("GCoordSystemGUID", TRUE);
     232               0 :         if (iGCoordSystemGUID < 0)
     233                 :         {
     234               0 :             delete poGeometryPropertiesTable;
     235               0 :             delete poGFeaturesTable;
     236               0 :             CPLFree(pszGCoordSystemTable);
     237               0 :             return FALSE;
     238                 :         }
     239                 :     }
     240                 : 
     241               0 :     while(poGFeaturesTable->GetNextRow() &&
     242                 :           (poGeometryPropertiesTable == NULL || poGeometryPropertiesTable->GetNextRow()))
     243                 :     {
     244               0 :         char* pszFeatureName = poGFeaturesTable->GetColumnAsString(iFeatureName);
     245                 :         //int nGeometryType = poGFeaturesTable->GetColumnAsInt(iGeometryType);
     246               0 :         char* pszGeometryFieldName = poGFeaturesTable->GetColumnAsString(iPrimaryGeometryFieldName);
     247                 :         char* pszGCoordSystemGUID;
     248               0 :         if (poGeometryPropertiesTable)
     249               0 :             pszGCoordSystemGUID = poGeometryPropertiesTable->GetColumnAsString(iGCoordSystemGUID);
     250                 :         else
     251               0 :             pszGCoordSystemGUID = NULL;
     252               0 :         if (pszFeatureName && pszGeometryFieldName)
     253                 :         {
     254               0 :             OGRMDBTable* poTable = poDB->GetTable(pszFeatureName);
     255               0 :             if (poTable)
     256                 :             {
     257               0 :                 OGRMDBLayer* poLayer = new OGRMDBLayer( this, poTable );
     258                 : 
     259               0 :                 if( poLayer->Initialize( pszFeatureName,
     260                 :                                          pszGeometryFieldName,
     261                 :                                          GetGeomediaSRS(pszGCoordSystemTable, pszGCoordSystemGUID) )
     262                 :                     != CE_None )
     263                 :                 {
     264               0 :                     delete poLayer;
     265                 :                 }
     266                 :                 else
     267                 :                 {
     268               0 :                     papoLayers = (OGRMDBLayer**)CPLRealloc(papoLayers, (nLayers+1) * sizeof(OGRMDBLayer*));
     269               0 :                     papoLayers[nLayers++] = poLayer;
     270                 :                 }
     271                 :             }
     272                 :         }
     273               0 :         CPLFree(pszFeatureName);
     274               0 :         CPLFree(pszGeometryFieldName);
     275               0 :         CPLFree(pszGCoordSystemGUID);
     276                 :     }
     277                 : 
     278               0 :     delete poGeometryPropertiesTable;
     279               0 :     delete poGFeaturesTable;
     280               0 :     CPLFree(pszGCoordSystemTable);
     281                 : 
     282               0 :     return TRUE;
     283                 : }
     284                 : 
     285                 : /************************************************************************/
     286                 : /*                                Open()                                */
     287                 : /************************************************************************/
     288                 : 
     289               6 : int OGRMDBDataSource::Open( const char * pszNewName, int bUpdate,
     290                 :                               int bTestOpen )
     291                 : 
     292                 : {
     293               6 :     CPLAssert( nLayers == 0 );
     294                 : 
     295               6 :     pszName = CPLStrdup( pszNewName );
     296                 : 
     297               6 :     if (!env.Init())
     298               0 :         return FALSE;
     299                 : 
     300               6 :     poDB = OGRMDBDatabase::Open(&env, pszNewName);
     301               6 :     if (!poDB)
     302               0 :         return FALSE;
     303                 : 
     304               6 :     poDB->FetchTableNames();
     305                 : 
     306                 :     /* Is it a ESRI Personal Geodatabase ? */
     307               6 :     OGRMDBTable* poGDB_GeomColumns = poDB->GetTable("GDB_GeomColumns");
     308               6 :     if (poGDB_GeomColumns && !CSLTestBoolean(CPLGetConfigOption("MDB_RAW", "OFF")))
     309                 :     {
     310               6 :         int nRet = OpenGDB(poGDB_GeomColumns);
     311               6 :         delete poGDB_GeomColumns;
     312               6 :         return nRet;
     313                 :     }
     314               0 :     delete poGDB_GeomColumns;
     315                 : 
     316                 :     /* Is it a Geomedia warehouse ? */
     317               0 :     OGRMDBTable* poGAliasTable = poDB->GetTable("GAliasTable");
     318               0 :     if (poGAliasTable && !CSLTestBoolean(CPLGetConfigOption("MDB_RAW", "OFF")))
     319                 :     {
     320               0 :         int nRet = OpenGeomediaWarehouse(poGAliasTable);
     321               0 :         delete poGAliasTable;
     322               0 :         return nRet;
     323                 :     }
     324               0 :     delete poGAliasTable;
     325                 : 
     326                 :     /* Well, no, just a regular MDB */
     327               0 :     int nTables = (int) poDB->apoTableNames.size();
     328               0 :     for(int i=0;i<nTables;i++)
     329                 :     {
     330               0 :         OGRMDBTable* poTable = poDB->GetTable(poDB->apoTableNames[i]);
     331               0 :         if (poTable == NULL)
     332               0 :             continue;
     333                 : 
     334               0 :         OGRMDBLayer* poLayer = new OGRMDBLayer( this, poTable );
     335               0 :         if( poLayer->BuildFeatureDefn() != CE_None )
     336                 :         {
     337               0 :             delete poLayer;
     338               0 :             continue;
     339                 :         }
     340                 : 
     341               0 :         papoLayers = (OGRMDBLayer**)CPLRealloc(papoLayers, (nLayers+1) * sizeof(OGRMDBLayer*));
     342               0 :         papoLayers[nLayers++] = poLayer;
     343                 :     }
     344                 : 
     345               0 :     return TRUE;
     346                 : }
     347                 : 
     348                 : /************************************************************************/
     349                 : /*                           TestCapability()                           */
     350                 : /************************************************************************/
     351                 : 
     352               2 : int OGRMDBDataSource::TestCapability( const char * pszCap )
     353                 : 
     354                 : {
     355               2 :     return FALSE;
     356                 : }
     357                 : 
     358                 : /************************************************************************/
     359                 : /*                              GetLayer()                              */
     360                 : /************************************************************************/
     361                 : 
     362              71 : OGRLayer *OGRMDBDataSource::GetLayer( int iLayer )
     363                 : 
     364                 : {
     365              71 :     if( iLayer < 0 || iLayer >= nLayers )
     366               4 :         return NULL;
     367                 :     else
     368              67 :         return papoLayers[iLayer];
     369                 : }
     370                 : 
     371                 : /************************************************************************/
     372                 : /*                              GetLayer()                              */
     373                 : /************************************************************************/
     374                 : 
     375              26 : OGRLayer *OGRMDBDataSource::GetLayerByName( const char* pszName )
     376                 : 
     377                 : {
     378              26 :     if (pszName == NULL)
     379               0 :         return NULL;
     380              26 :     OGRLayer* poLayer = OGRDataSource::GetLayerByName(pszName);
     381              26 :     if (poLayer)
     382              24 :         return poLayer;
     383                 : 
     384               2 :     for( int i = 0; i < nLayersWithInvisible; i++ )
     385                 :     {
     386               0 :         poLayer = papoLayersInvisible[i];
     387                 : 
     388               0 :         if( strcmp( pszName, poLayer->GetName() ) == 0 )
     389               0 :             return poLayer;
     390                 :     }
     391                 : 
     392               2 :     OGRMDBTable* poTable = poDB->GetTable(pszName);
     393               2 :     if (poTable == NULL)
     394               2 :         return NULL;
     395                 : 
     396               0 :     OGRMDBLayer* poMDBLayer = new OGRMDBLayer( this, poTable );
     397               0 :     if( poMDBLayer->BuildFeatureDefn() != CE_None )
     398                 :     {
     399               0 :         delete poMDBLayer;
     400               0 :         return NULL;
     401                 :     }
     402                 : 
     403                 :     papoLayersInvisible = (OGRMDBLayer**)CPLRealloc(papoLayersInvisible,
     404               0 :                             (nLayersWithInvisible+1) * sizeof(OGRMDBLayer*));
     405               0 :     papoLayersInvisible[nLayersWithInvisible++] = poMDBLayer;
     406                 : 
     407               0 :     return poMDBLayer;
     408                 : }
     409                 : 
     410                 : /************************************************************************/
     411                 : /*                          GetGeomediaSRS()                            */
     412                 : /************************************************************************/
     413                 : 
     414               0 : OGRSpatialReference* OGRMDBDataSource::GetGeomediaSRS(const char* pszGCoordSystemTable,
     415                 :                                                       const char* pszGCoordSystemGUID)
     416                 : {
     417               0 :     if (pszGCoordSystemTable == NULL || pszGCoordSystemGUID == NULL)
     418               0 :         return NULL;
     419                 : 
     420               0 :     OGRLayer* poGCoordSystemTable = GetLayerByName(pszGCoordSystemTable);
     421               0 :     if (poGCoordSystemTable == NULL)
     422               0 :         return NULL;
     423                 : 
     424               0 :     poGCoordSystemTable->ResetReading();
     425                 :     
     426                 :     OGRFeature* poFeature;
     427               0 :     while((poFeature = poGCoordSystemTable->GetNextFeature()) != NULL)
     428                 :     {
     429               0 :         const char* pszCSGUID = poFeature->GetFieldAsString("CSGUID");
     430               0 :         if (pszCSGUID && strcmp(pszCSGUID, pszGCoordSystemGUID) == 0)
     431                 :         {
     432               0 :             OGRSpatialReference* poSRS = OGRGetGeomediaSRS(poFeature);
     433               0 :             delete poFeature;
     434               0 :             return poSRS;
     435                 :         }
     436                 : 
     437               0 :         delete poFeature;
     438                 :     }
     439                 : 
     440               0 :     return NULL;
     441                 : }

Generated by: LCOV version 1.7