~ubuntu-branches/debian/sid/gdal/sid

« back to all changes in this revision

Viewing changes to ogr/ogrsf_frmts/mdb/ogrmdblayer.cpp

  • Committer: Package Import Robot
  • Author(s): Francesco Paolo Lovergine
  • Date: 2012-05-07 15:04:42 UTC
  • mfrom: (5.5.16 experimental)
  • Revision ID: package-import@ubuntu.com-20120507150442-2eks97loeh6rq005
Tags: 1.9.0-1
* Ready for sid, starting transition.
* All symfiles updated to latest builds.
* Added dh_numpy call in debian/rules to depend on numpy ABI.
* Policy bumped to 3.9.3, no changes required.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/******************************************************************************
 
2
 * $Id: ogrmdblayer.cpp 22156 2011-04-13 20:08:07Z rouault $
 
3
 *
 
4
 * Project:  OpenGIS Simple Features Reference Implementation
 
5
 * Purpose:  Implements OGRMDBLayer 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 "ogrpgeogeometry.h"
 
34
#include "ogrgeomediageometry.h"
 
35
 
 
36
CPL_CVSID("$Id: ogrmdblayer.cpp 22156 2011-04-13 20:08:07Z rouault $");
 
37
 
 
38
/************************************************************************/
 
39
/*                            OGRMDBLayer()                            */
 
40
/************************************************************************/
 
41
 
 
42
OGRMDBLayer::OGRMDBLayer(OGRMDBDataSource* poDS, OGRMDBTable* poMDBTable)
 
43
 
 
44
{
 
45
    this->poDS = poDS;
 
46
    this->poMDBTable = poMDBTable;
 
47
 
 
48
    eGeometryType = MDB_GEOM_NONE;
 
49
 
 
50
    iGeomColumn = -1;
 
51
    pszGeomColumn = NULL;
 
52
    pszFIDColumn = NULL;
 
53
 
 
54
    panFieldOrdinals = NULL;
 
55
 
 
56
    poFeatureDefn = NULL;
 
57
 
 
58
    iNextShapeId = 0;
 
59
 
 
60
    poSRS = NULL;
 
61
    nSRSId = -2; // we haven't even queried the database for it yet.
 
62
 
 
63
    bHasExtent = FALSE;
 
64
}
 
65
 
 
66
/************************************************************************/
 
67
/*                            ~OGRMDBLayer()                             */
 
68
/************************************************************************/
 
69
 
 
70
OGRMDBLayer::~OGRMDBLayer()
 
71
 
 
72
{
 
73
    if( m_nFeaturesRead > 0 && poFeatureDefn != NULL )
 
74
    {
 
75
        CPLDebug( "MDB", "%d features read on layer '%s'.",
 
76
                  (int) m_nFeaturesRead, 
 
77
                  poFeatureDefn->GetName() );
 
78
    }
 
79
 
 
80
    if( poFeatureDefn != NULL )
 
81
    {
 
82
        poFeatureDefn->Release();
 
83
        poFeatureDefn = NULL;
 
84
    }
 
85
 
 
86
    CPLFree( pszGeomColumn );
 
87
    CPLFree( pszFIDColumn );
 
88
 
 
89
    CPLFree( panFieldOrdinals );
 
90
 
 
91
    if( poSRS != NULL )
 
92
    {
 
93
        poSRS->Release();
 
94
        poSRS = NULL;
 
95
    }
 
96
 
 
97
    delete poMDBTable;
 
98
}
 
99
 
 
100
/************************************************************************/
 
101
/*                          BuildFeatureDefn()                          */
 
102
/*                                                                      */
 
103
/*      Build feature definition from a set of column definitions       */
 
104
/*      set on a statement.  Sift out geometry and FID fields.          */
 
105
/************************************************************************/
 
106
 
 
107
CPLErr OGRMDBLayer::BuildFeatureDefn()
 
108
 
 
109
{
 
110
    poFeatureDefn = new OGRFeatureDefn( poMDBTable->GetName() );
 
111
 
 
112
    poFeatureDefn->Reference();
 
113
 
 
114
 
 
115
    int nRawColumns = poMDBTable->GetColumnCount();
 
116
    panFieldOrdinals = (int *) CPLMalloc( sizeof(int) * nRawColumns );
 
117
 
 
118
    for( int iCol = 0; iCol < nRawColumns; iCol++ )
 
119
    {
 
120
        const char* pszColName = poMDBTable->GetColumnName(iCol);
 
121
        OGRFieldDefn    oField(pszColName, OFTString );
 
122
 
 
123
        if( pszGeomColumn != NULL
 
124
            && EQUAL(pszColName,pszGeomColumn) )
 
125
            continue;
 
126
 
 
127
        if( eGeometryType == MDB_GEOM_PGEO
 
128
            && pszFIDColumn == NULL
 
129
            && EQUAL(pszColName,"OBJECTID") )
 
130
        {
 
131
            pszFIDColumn = CPLStrdup(pszColName);
 
132
        }
 
133
 
 
134
        if( eGeometryType == MDB_GEOM_PGEO
 
135
            && pszGeomColumn == NULL 
 
136
            && EQUAL(pszColName,"Shape") )
 
137
        {
 
138
            pszGeomColumn = CPLStrdup(pszColName);
 
139
            continue;
 
140
        }
 
141
        
 
142
        switch( poMDBTable->GetColumnType(iCol) )
 
143
        {
 
144
          case MDB_Boolean:
 
145
            oField.SetType( OFTInteger );
 
146
            oField.SetWidth(1);
 
147
            break;
 
148
 
 
149
          case MDB_Byte:
 
150
          case MDB_Short:
 
151
          case MDB_Int:
 
152
            oField.SetType( OFTInteger );
 
153
            break;
 
154
 
 
155
          case MDB_Binary:
 
156
          case MDB_OLE:
 
157
            oField.SetType( OFTBinary );
 
158
            break;
 
159
 
 
160
          case MDB_Float:
 
161
          case MDB_Double:
 
162
            oField.SetType( OFTReal );
 
163
            break;
 
164
 
 
165
          case MDB_Text:
 
166
            oField.SetWidth(poMDBTable->GetColumnLength(iCol));
 
167
            break;
 
168
 
 
169
          default:
 
170
            /* leave it as OFTString */;
 
171
        }
 
172
 
 
173
        poFeatureDefn->AddFieldDefn( &oField );
 
174
        panFieldOrdinals[poFeatureDefn->GetFieldCount() - 1] = iCol+1;
 
175
    }
 
176
 
 
177
    return CE_None;
 
178
}
 
179
 
 
180
 
 
181
/************************************************************************/
 
182
/*                            ResetReading()                            */
 
183
/************************************************************************/
 
184
 
 
185
void OGRMDBLayer::ResetReading()
 
186
 
 
187
{
 
188
    iNextShapeId = 0;
 
189
    poMDBTable->ResetReading();
 
190
}
 
191
 
 
192
/************************************************************************/
 
193
/*                          GetFeatureCount()                           */
 
194
/************************************************************************/
 
195
 
 
196
int OGRMDBLayer::GetFeatureCount(int bForce)
 
197
{
 
198
    if (m_poFilterGeom != NULL || m_poAttrQuery != NULL)
 
199
        return OGRLayer::GetFeatureCount(bForce);
 
200
    return poMDBTable->GetRowCount();
 
201
}
 
202
 
 
203
/************************************************************************/
 
204
/*                           GetNextFeature()                           */
 
205
/************************************************************************/
 
206
 
 
207
OGRFeature *OGRMDBLayer::GetNextFeature()
 
208
 
 
209
{
 
210
    for( ; TRUE; )
 
211
    {
 
212
        OGRFeature      *poFeature;
 
213
 
 
214
        poFeature = GetNextRawFeature();
 
215
        if( poFeature == NULL )
 
216
            return NULL;
 
217
 
 
218
        if( (m_poFilterGeom == NULL
 
219
            || FilterGeometry( poFeature->GetGeometryRef() ) )
 
220
            && (m_poAttrQuery == NULL
 
221
                || m_poAttrQuery->Evaluate( poFeature )) )
 
222
            return poFeature;
 
223
 
 
224
        delete poFeature;
 
225
    }
 
226
}
 
227
 
 
228
/************************************************************************/
 
229
/*                         GetNextRawFeature()                          */
 
230
/************************************************************************/
 
231
 
 
232
OGRFeature *OGRMDBLayer::GetNextRawFeature()
 
233
 
 
234
{
 
235
    OGRErr err = OGRERR_NONE;
 
236
 
 
237
    if( !poMDBTable->GetNextRow() )
 
238
        return NULL;
 
239
 
 
240
/* -------------------------------------------------------------------- */
 
241
/*      Create a feature from the current result.                       */
 
242
/* -------------------------------------------------------------------- */
 
243
    int         iField;
 
244
    OGRFeature *poFeature = new OGRFeature( poFeatureDefn );
 
245
 
 
246
    if( pszFIDColumn != NULL && poMDBTable->GetColumnIndex(pszFIDColumn) > -1 )
 
247
        poFeature->SetFID( 
 
248
            poMDBTable->GetColumnAsInt(poMDBTable->GetColumnIndex(pszFIDColumn)) );
 
249
    else
 
250
        poFeature->SetFID( iNextShapeId );
 
251
 
 
252
    iNextShapeId++;
 
253
    m_nFeaturesRead++;
 
254
 
 
255
/* -------------------------------------------------------------------- */
 
256
/*      Set the fields.                                                 */
 
257
/* -------------------------------------------------------------------- */
 
258
    for( iField = 0; iField < poFeatureDefn->GetFieldCount(); iField++ )
 
259
    {
 
260
        int iSrcField = panFieldOrdinals[iField]-1;
 
261
        char *pszValue = poMDBTable->GetColumnAsString( iSrcField );
 
262
        OGRFieldType eType = poFeature->GetFieldDefnRef(iField)->GetType();
 
263
 
 
264
        if( pszValue == NULL )
 
265
            /* no value */;
 
266
        else if( eType == OFTBinary )
 
267
        {
 
268
            int nBytes = 0;
 
269
            GByte* pData = poMDBTable->GetColumnAsBinary( iSrcField, &nBytes);
 
270
            poFeature->SetField( iField, 
 
271
                                 nBytes,
 
272
                                 pData );
 
273
            CPLFree(pData);
 
274
        }
 
275
        else if ( eType == OFTInteger && EQUAL(pszValue, "true"))
 
276
        {
 
277
           poFeature->SetField( iField, 1 );
 
278
        }
 
279
        else
 
280
        {
 
281
           poFeature->SetField( iField, pszValue );
 
282
        }
 
283
 
 
284
        CPLFree(pszValue);
 
285
    }
 
286
 
 
287
/* -------------------------------------------------------------------- */
 
288
/*      Try to extract a geometry.                                      */
 
289
/* -------------------------------------------------------------------- */
 
290
    if( eGeometryType == MDB_GEOM_PGEO && iGeomColumn >= 0)
 
291
    {
 
292
        int nBytes = 0;
 
293
        GByte* pData = poMDBTable->GetColumnAsBinary( iGeomColumn, &nBytes);
 
294
        OGRGeometry *poGeom = NULL;
 
295
 
 
296
        if( pData != NULL )
 
297
        {
 
298
            err = OGRCreateFromShapeBin( pData, &poGeom, nBytes );
 
299
            if( OGRERR_NONE != err )
 
300
            {
 
301
                CPLDebug( "MDB",
 
302
                          "Translation shape binary to OGR geometry failed (FID=%ld)",
 
303
                           (long)poFeature->GetFID() );
 
304
            }
 
305
        }
 
306
 
 
307
        CPLFree(pData);
 
308
 
 
309
        if( poGeom != NULL && OGRERR_NONE == err )
 
310
        {
 
311
            poGeom->assignSpatialReference( poSRS );
 
312
            poFeature->SetGeometryDirectly( poGeom );
 
313
        }
 
314
    }
 
315
    else if( eGeometryType == MDB_GEOM_GEOMEDIA && iGeomColumn >= 0)
 
316
    {
 
317
        int nBytes = 0;
 
318
        GByte* pData = poMDBTable->GetColumnAsBinary( iGeomColumn, &nBytes);
 
319
        OGRGeometry *poGeom = NULL;
 
320
 
 
321
        if( pData != NULL )
 
322
        {
 
323
            err = OGRCreateFromGeomedia( pData, &poGeom, nBytes );
 
324
            if( OGRERR_NONE != err )
 
325
            {
 
326
                CPLDebug( "MDB",
 
327
                          "Translation geomedia binary to OGR geometry failed (FID=%ld)",
 
328
                           (long)poFeature->GetFID() );
 
329
            }
 
330
        }
 
331
 
 
332
        CPLFree(pData);
 
333
 
 
334
        if( poGeom != NULL && OGRERR_NONE == err )
 
335
        {
 
336
            poGeom->assignSpatialReference( poSRS );
 
337
            poFeature->SetGeometryDirectly( poGeom );
 
338
        }
 
339
    }
 
340
 
 
341
    return poFeature;
 
342
}
 
343
 
 
344
/************************************************************************/
 
345
/*                             GetFeature()                             */
 
346
/************************************************************************/
 
347
 
 
348
OGRFeature *OGRMDBLayer::GetFeature( long nFeatureId )
 
349
 
 
350
{
 
351
    /* This should be implemented directly! */
 
352
 
 
353
    return OGRLayer::GetFeature( nFeatureId );
 
354
}
 
355
 
 
356
/************************************************************************/
 
357
/*                           TestCapability()                           */
 
358
/************************************************************************/
 
359
 
 
360
int OGRMDBLayer::TestCapability( const char * pszCap )
 
361
 
 
362
{
 
363
    /*if( EQUAL(pszCap,OLCRandomRead) )
 
364
        return TRUE;
 
365
 
 
366
    else*/
 
367
    if( EQUAL(pszCap,OLCFastFeatureCount) ||
 
368
        EQUAL(pszCap,OLCFastGetExtent) )
 
369
        return m_poFilterGeom == NULL && m_poAttrQuery == NULL;
 
370
 
 
371
    else
 
372
        return FALSE;
 
373
}
 
374
 
 
375
/************************************************************************/
 
376
/*                           GetSpatialRef()                            */
 
377
/************************************************************************/
 
378
 
 
379
OGRSpatialReference *OGRMDBLayer::GetSpatialRef()
 
380
 
 
381
{
 
382
    return poSRS;
 
383
}
 
384
 
 
385
/************************************************************************/
 
386
/*                           LookupSRID()                               */
 
387
/************************************************************************/
 
388
 
 
389
void OGRMDBLayer::LookupSRID( int nSRID )
 
390
 
 
391
{
 
392
/* -------------------------------------------------------------------- */
 
393
/*      Fetch the corresponding WKT from the SpatialRef table.          */
 
394
/* -------------------------------------------------------------------- */
 
395
    OGRMDBDatabase* poDB = poMDBTable->GetDB();
 
396
    OGRMDBTable* poSRSTable = poDB->GetTable("GDB_SpatialRefs");
 
397
    if (poSRSTable == NULL)
 
398
        return;
 
399
 
 
400
    int iSRTEXT = poSRSTable->GetColumnIndex("SRTEXT", TRUE);
 
401
    int iSRID = poSRSTable->GetColumnIndex("SRID", TRUE);
 
402
 
 
403
    if (iSRTEXT < 0 || iSRID < 0)
 
404
    {
 
405
        delete poSRSTable;
 
406
        return;
 
407
    }
 
408
 
 
409
    char* pszSRText = NULL;
 
410
    while(poSRSTable->GetNextRow())
 
411
    {
 
412
        int nTableSRID = poSRSTable->GetColumnAsInt(iSRID);
 
413
        if (nTableSRID == nSRID)
 
414
        {
 
415
            pszSRText = poSRSTable->GetColumnAsString(iSRTEXT);
 
416
            break;
 
417
        }
 
418
    }
 
419
 
 
420
    if (pszSRText == NULL)
 
421
    {
 
422
        delete poSRSTable;
 
423
        return;
 
424
    }
 
425
 
 
426
/* -------------------------------------------------------------------- */
 
427
/*      Check that it isn't just a GUID.  We don't know how to          */
 
428
/*      translate those.                                                */
 
429
/* -------------------------------------------------------------------- */
 
430
 
 
431
    if( pszSRText[0] == '{' )
 
432
    {
 
433
        CPLDebug( "MDB", "Ignoreing GUID SRTEXT: %s", pszSRText );
 
434
        delete poSRSTable;
 
435
        CPLFree(pszSRText);
 
436
        return;
 
437
    }
 
438
 
 
439
/* -------------------------------------------------------------------- */
 
440
/*      Turn it into an OGRSpatialReference.                            */
 
441
/* -------------------------------------------------------------------- */
 
442
    poSRS = new OGRSpatialReference();
 
443
 
 
444
    char* pszSRTextPtr = pszSRText;
 
445
    if( poSRS->importFromWkt( &pszSRTextPtr ) != OGRERR_NONE )
 
446
    {
 
447
        CPLError( CE_Failure, CPLE_AppDefined, 
 
448
                  "importFromWKT() failed on SRS '%s'.",
 
449
                  pszSRText);
 
450
        delete poSRS;
 
451
        poSRS = NULL;
 
452
    }
 
453
    else if( poSRS->morphFromESRI() != OGRERR_NONE )
 
454
    {
 
455
        CPLError( CE_Failure, CPLE_AppDefined, 
 
456
                  "morphFromESRI() failed on SRS." );
 
457
        delete poSRS;
 
458
        poSRS = NULL;
 
459
    }
 
460
    else
 
461
        nSRSId = nSRID;
 
462
 
 
463
    delete poSRSTable;
 
464
    CPLFree(pszSRText);
 
465
}
 
466
 
 
467
/************************************************************************/
 
468
/*                            GetFIDColumn()                            */
 
469
/************************************************************************/
 
470
 
 
471
const char *OGRMDBLayer::GetFIDColumn()
 
472
 
 
473
{
 
474
    if( pszFIDColumn != NULL )
 
475
        return pszFIDColumn;
 
476
    else
 
477
        return "";
 
478
}
 
479
 
 
480
/************************************************************************/
 
481
/*                         GetGeometryColumn()                          */
 
482
/************************************************************************/
 
483
 
 
484
const char *OGRMDBLayer::GetGeometryColumn()
 
485
 
 
486
{
 
487
    if( pszGeomColumn != NULL )
 
488
        return pszGeomColumn;
 
489
    else
 
490
        return "";
 
491
}
 
492
 
 
493
 
 
494
/************************************************************************/
 
495
/*                             Initialize()                             */
 
496
/************************************************************************/
 
497
 
 
498
CPLErr OGRMDBLayer::Initialize( const char *pszTableName,
 
499
                                const char *pszGeomCol,
 
500
                                int nShapeType,
 
501
                                double dfExtentLeft,
 
502
                                double dfExtentRight,
 
503
                                double dfExtentBottom,
 
504
                                double dfExtentTop,
 
505
                                int nSRID,
 
506
                                int bHasZ )
 
507
 
 
508
 
 
509
{
 
510
    CPLFree( pszGeomColumn );
 
511
 
 
512
    if( pszGeomCol == NULL )
 
513
        pszGeomColumn = NULL;
 
514
    else
 
515
    {
 
516
        pszGeomColumn = CPLStrdup( pszGeomCol );
 
517
        iGeomColumn = poMDBTable->GetColumnIndex( pszGeomColumn );
 
518
    }
 
519
 
 
520
    CPLFree( pszFIDColumn );
 
521
    pszFIDColumn = NULL;
 
522
 
 
523
    bHasExtent = TRUE;
 
524
    sExtent.MinX = dfExtentLeft;
 
525
    sExtent.MaxX = dfExtentRight;
 
526
    sExtent.MinY = dfExtentBottom;
 
527
    sExtent.MaxY = dfExtentTop;
 
528
 
 
529
    LookupSRID( nSRID );
 
530
 
 
531
    eGeometryType = MDB_GEOM_PGEO;
 
532
 
 
533
    CPLErr eErr;
 
534
    eErr = BuildFeatureDefn();
 
535
    if( eErr != CE_None )
 
536
        return eErr;
 
537
 
 
538
/* -------------------------------------------------------------------- */
 
539
/*      Setup geometry type.                                            */
 
540
/* -------------------------------------------------------------------- */
 
541
    OGRwkbGeometryType  eOGRType;
 
542
 
 
543
    switch( nShapeType )
 
544
    {
 
545
        case ESRI_LAYERGEOMTYPE_NULL:
 
546
            eOGRType = wkbNone;
 
547
            break;
 
548
 
 
549
        case ESRI_LAYERGEOMTYPE_POINT:
 
550
            eOGRType = wkbPoint;
 
551
            break;
 
552
 
 
553
        case ESRI_LAYERGEOMTYPE_MULTIPOINT:
 
554
            eOGRType = wkbMultiPoint;
 
555
            break;
 
556
 
 
557
        case ESRI_LAYERGEOMTYPE_POLYLINE:
 
558
            eOGRType = wkbLineString;
 
559
            break;
 
560
 
 
561
        case ESRI_LAYERGEOMTYPE_POLYGON:
 
562
        case ESRI_LAYERGEOMTYPE_MULTIPATCH:
 
563
            eOGRType = wkbPolygon;
 
564
            break;
 
565
 
 
566
        default:
 
567
            CPLDebug("MDB", "Unexpected value for shape type : %d", nShapeType);
 
568
            eOGRType = wkbUnknown;
 
569
            break;
 
570
    }
 
571
 
 
572
    if( eOGRType != wkbUnknown && eOGRType != wkbNone && bHasZ )
 
573
        eOGRType = (OGRwkbGeometryType)(((int) eOGRType) | wkb25DBit);
 
574
 
 
575
    poFeatureDefn->SetGeomType(eOGRType);
 
576
 
 
577
    return CE_None;
 
578
}
 
579
 
 
580
 
 
581
/************************************************************************/
 
582
/*                             Initialize()                             */
 
583
/************************************************************************/
 
584
 
 
585
CPLErr OGRMDBLayer::Initialize( const char *pszTableName,
 
586
                                const char *pszGeomCol,
 
587
                                OGRSpatialReference* poSRS )
 
588
 
 
589
 
 
590
{
 
591
    CPLFree( pszGeomColumn );
 
592
 
 
593
    if( pszGeomCol == NULL )
 
594
        pszGeomColumn = NULL;
 
595
    else
 
596
    {
 
597
        pszGeomColumn = CPLStrdup( pszGeomCol );
 
598
        iGeomColumn = poMDBTable->GetColumnIndex( pszGeomColumn );
 
599
    }
 
600
 
 
601
    CPLFree( pszFIDColumn );
 
602
    pszFIDColumn = NULL;
 
603
 
 
604
    eGeometryType = MDB_GEOM_GEOMEDIA;
 
605
 
 
606
    this->poSRS = poSRS;
 
607
 
 
608
    CPLErr eErr;
 
609
    eErr = BuildFeatureDefn();
 
610
    if( eErr != CE_None )
 
611
        return eErr;
 
612
 
 
613
    return CE_None;
 
614
}
 
615
 
 
616
/************************************************************************/
 
617
/*                             GetExtent()                              */
 
618
/************************************************************************/
 
619
 
 
620
OGRErr OGRMDBLayer::GetExtent( OGREnvelope *psExtent, int bForce )
 
621
 
 
622
{
 
623
    if (bHasExtent)
 
624
    {
 
625
        *psExtent = sExtent;
 
626
        return OGRERR_NONE;
 
627
    }
 
628
    else
 
629
    {
 
630
        return OGRLayer::GetExtent(psExtent, bForce);
 
631
    }
 
632
}