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

« back to all changes in this revision

Viewing changes to ogr/ogrsf_frmts/pcidsk/ogrpcidsklayer.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:
35
35
/*                           OGRPCIDSKLayer()                           */
36
36
/************************************************************************/
37
37
 
38
 
OGRPCIDSKLayer::OGRPCIDSKLayer( PCIDSK::PCIDSKSegment *poSegIn )
 
38
OGRPCIDSKLayer::OGRPCIDSKLayer( PCIDSK::PCIDSKSegment *poSegIn,
 
39
                                bool bUpdate )
39
40
 
40
41
{
 
42
    poSRS = NULL;
 
43
    bUpdateAccess = bUpdate;
41
44
    poSeg = poSegIn;
42
45
    poVecSeg = dynamic_cast<PCIDSK::PCIDSKVectorSegment*>( poSeg );
43
46
 
63
66
            poFeatureDefn->SetGeomType( wkbNone );
64
67
    } catch(...) {}
65
68
 
 
69
 
66
70
/* -------------------------------------------------------------------- */
67
71
/*      Build field definitions.                                        */
68
72
/* -------------------------------------------------------------------- */
69
 
    iRingStartField = -1;
70
 
 
71
 
    for( int iField = 0; iField < poVecSeg->GetFieldCount(); iField++ )
72
 
    {
73
 
        OGRFieldDefn oField( poVecSeg->GetFieldName(iField).c_str(), OFTString);
74
 
 
75
 
        switch( poVecSeg->GetFieldType(iField) )
76
 
        {
77
 
          case PCIDSK::FieldTypeFloat:
78
 
          case PCIDSK::FieldTypeDouble:
79
 
            oField.SetType( OFTReal );
80
 
            break;
81
 
 
82
 
          case PCIDSK::FieldTypeInteger:
83
 
            oField.SetType( OFTInteger );
84
 
            break;
85
 
 
86
 
          case PCIDSK::FieldTypeString:
87
 
            oField.SetType( OFTString );
88
 
            break;
89
 
            
90
 
          case PCIDSK::FieldTypeCountedInt:
91
 
            oField.SetType( OFTIntegerList );
92
 
            break;
93
 
 
94
 
          default:
95
 
            CPLAssert( FALSE );
96
 
            break;
97
 
        }
98
 
 
99
 
        // we ought to try and extract some width/precision information
100
 
        // from the format string at some point.
101
 
 
102
 
        // If the last field is named RingStart we treat it specially.
103
 
        if( EQUAL(oField.GetNameRef(),"RingStart")
104
 
            && oField.GetType() == OFTIntegerList 
105
 
            && iField == poVecSeg->GetFieldCount()-1 )
106
 
            iRingStartField = iField;
107
 
        else
108
 
            poFeatureDefn->AddFieldDefn( &oField );
 
73
    try
 
74
    {
 
75
        iRingStartField = -1;
 
76
 
 
77
        for( int iField = 0; iField < poVecSeg->GetFieldCount(); iField++ )
 
78
        {
 
79
            OGRFieldDefn oField( poVecSeg->GetFieldName(iField).c_str(), OFTString);
 
80
            
 
81
            switch( poVecSeg->GetFieldType(iField) )
 
82
            {
 
83
              case PCIDSK::FieldTypeFloat:
 
84
              case PCIDSK::FieldTypeDouble:
 
85
                oField.SetType( OFTReal );
 
86
                break;
 
87
                
 
88
              case PCIDSK::FieldTypeInteger:
 
89
                oField.SetType( OFTInteger );
 
90
                break;
 
91
                
 
92
              case PCIDSK::FieldTypeString:
 
93
                oField.SetType( OFTString );
 
94
                break;
 
95
                
 
96
              case PCIDSK::FieldTypeCountedInt:
 
97
                oField.SetType( OFTIntegerList );
 
98
                break;
 
99
                
 
100
              default:
 
101
                CPLAssert( FALSE );
 
102
                break;
 
103
            }
 
104
            
 
105
            // we ought to try and extract some width/precision information
 
106
            // from the format string at some point.
 
107
            
 
108
            // If the last field is named RingStart we treat it specially.
 
109
            if( EQUAL(oField.GetNameRef(),"RingStart")
 
110
                && oField.GetType() == OFTIntegerList 
 
111
                && iField == poVecSeg->GetFieldCount()-1 )
 
112
                iRingStartField = iField;
 
113
            else
 
114
                poFeatureDefn->AddFieldDefn( &oField );
 
115
        }
 
116
 
 
117
/* -------------------------------------------------------------------- */
 
118
/*      Look for a coordinate system.                                   */
 
119
/* -------------------------------------------------------------------- */
 
120
        CPLString osGeosys;
 
121
        const char *pszUnits = NULL;
 
122
        std::vector<double> adfParameters;
 
123
 
 
124
        adfParameters = poVecSeg->GetProjection( osGeosys );
 
125
 
 
126
        if( ((PCIDSK::UnitCode)(int)adfParameters[16]) 
 
127
            == PCIDSK::UNIT_DEGREE )
 
128
            pszUnits = "DEGREE";
 
129
        else if( ((PCIDSK::UnitCode)(int)adfParameters[16]) 
 
130
                 == PCIDSK::UNIT_METER )
 
131
            pszUnits = "METER";
 
132
        else if( ((PCIDSK::UnitCode)(int)adfParameters[16]) 
 
133
                 == PCIDSK::UNIT_US_FOOT )
 
134
            pszUnits = "FOOT";
 
135
        else if( ((PCIDSK::UnitCode)(int)adfParameters[16]) 
 
136
                 == PCIDSK::UNIT_INTL_FOOT )
 
137
            pszUnits = "INTL FOOT";
 
138
 
 
139
        poSRS = new OGRSpatialReference();
 
140
 
 
141
        if( poSRS->importFromPCI( osGeosys, pszUnits, 
 
142
                                  &(adfParameters[0]) ) != OGRERR_NONE )
 
143
        {
 
144
            delete poSRS;
 
145
            poSRS = NULL;
 
146
        }
 
147
    }
 
148
 
 
149
/* -------------------------------------------------------------------- */
 
150
/*      Trap pcidsk exceptions.                                         */
 
151
/* -------------------------------------------------------------------- */
 
152
    catch( PCIDSK::PCIDSKException ex )
 
153
    {
 
154
        CPLError( CE_Failure, CPLE_AppDefined,
 
155
                  "PCIDSK Exception while initializing layer, operation likely impaired.\n%s", ex.what() );
 
156
    }
 
157
    catch(...)
 
158
    {
 
159
        CPLError( CE_Failure, CPLE_AppDefined, 
 
160
                  "Non-PCIDSK exception trapped while initializing layer, operation likely impaired." );
109
161
    }
110
162
}
111
163
 
124
176
    }
125
177
 
126
178
    poFeatureDefn->Release();
 
179
 
 
180
    if (poSRS)
 
181
        poSRS->Release();
 
182
}
 
183
 
 
184
/************************************************************************/
 
185
/*                           GetSpatialRef()                            */
 
186
/************************************************************************/
 
187
 
 
188
OGRSpatialReference *OGRPCIDSKLayer::GetSpatialRef()
 
189
 
 
190
{
 
191
    return poSRS;
127
192
}
128
193
 
129
194
/************************************************************************/
137
202
}
138
203
 
139
204
/************************************************************************/
 
205
/*                           GetNextFeature()                           */
 
206
/************************************************************************/
 
207
 
 
208
OGRFeature *OGRPCIDSKLayer::GetNextFeature()
 
209
 
 
210
{
 
211
    OGRFeature  *poFeature = NULL;
 
212
 
 
213
/* -------------------------------------------------------------------- */
 
214
/*      Read features till we find one that satisfies our current       */
 
215
/*      spatial criteria.                                               */
 
216
/* -------------------------------------------------------------------- */
 
217
    while( TRUE )
 
218
    {
 
219
        poFeature = GetNextUnfilteredFeature();
 
220
        if( poFeature == NULL )
 
221
            break;
 
222
 
 
223
        if( (m_poFilterGeom == NULL
 
224
            || FilterGeometry( poFeature->GetGeometryRef() ) )
 
225
            && (m_poAttrQuery == NULL
 
226
                || m_poAttrQuery->Evaluate( poFeature )) )
 
227
            break;
 
228
 
 
229
        delete poFeature;
 
230
    }
 
231
 
 
232
    return poFeature;
 
233
}
 
234
 
 
235
/************************************************************************/
140
236
/*                      GetNextUnfilteredFeature()                      */
141
237
/************************************************************************/
142
238
 
143
239
OGRFeature * OGRPCIDSKLayer::GetNextUnfilteredFeature()
144
240
 
145
241
{
146
 
    unsigned int i;
147
 
 
148
242
/* -------------------------------------------------------------------- */
149
243
/*      Get the next shapeid.                                           */
150
244
/* -------------------------------------------------------------------- */
156
250
    if( hLastShapeId == PCIDSK::NullShapeId )
157
251
        return NULL;
158
252
 
 
253
    return GetFeature( hLastShapeId );
 
254
}
 
255
 
 
256
/************************************************************************/
 
257
/*                             GetFeature()                             */
 
258
/************************************************************************/
 
259
 
 
260
OGRFeature *OGRPCIDSKLayer::GetFeature( long nFID )
 
261
 
 
262
{
159
263
/* -------------------------------------------------------------------- */
160
264
/*      Create the OGR feature.                                         */
161
265
/* -------------------------------------------------------------------- */
162
266
    OGRFeature *poFeature;
163
267
 
164
268
    poFeature = new OGRFeature( poFeatureDefn );
165
 
    poFeature->SetFID( (int) hLastShapeId );
 
269
    poFeature->SetFID( (int) nFID );
166
270
 
167
271
/* -------------------------------------------------------------------- */
168
272
/*      Set attributes for any indicated attribute records.             */
169
273
/* -------------------------------------------------------------------- */
170
 
    std::vector<PCIDSK::ShapeField> aoFields;
171
 
 
172
 
    poVecSeg->GetFields( hLastShapeId, aoFields );
173
 
    for( i=0; i < aoFields.size(); i++ )
174
 
    {
175
 
        if( (int) i == iRingStartField )
176
 
            continue;
177
 
 
178
 
        switch( aoFields[i].GetType() )
 
274
    try {
 
275
        std::vector<PCIDSK::ShapeField> aoFields;
 
276
        unsigned int i;
 
277
 
 
278
        poVecSeg->GetFields( (int) nFID, aoFields );
 
279
        for( i=0; i < aoFields.size(); i++ )
179
280
        {
180
 
          case PCIDSK::FieldTypeNone:
181
 
            // null field value.
182
 
            break;
183
 
 
184
 
          case PCIDSK::FieldTypeInteger:
185
 
            poFeature->SetField( i, aoFields[i].GetValueInteger() );
186
 
            break;
187
 
                                 
188
 
          case PCIDSK::FieldTypeFloat:
189
 
            poFeature->SetField( i, aoFields[i].GetValueFloat() );
190
 
            break;
191
 
                                 
192
 
          case PCIDSK::FieldTypeDouble:
193
 
            poFeature->SetField( i, aoFields[i].GetValueDouble() );
194
 
            break;
195
 
                                 
196
 
          case PCIDSK::FieldTypeString:
197
 
            poFeature->SetField( i, aoFields[i].GetValueString().c_str() );
198
 
            break;
199
 
                                 
200
 
          case PCIDSK::FieldTypeCountedInt:
201
 
            std::vector<PCIDSK::int32> list = aoFields[i].GetValueCountedInt();
 
281
            if( (int) i == iRingStartField )
 
282
                continue;
 
283
 
 
284
            switch( aoFields[i].GetType() )
 
285
            {
 
286
              case PCIDSK::FieldTypeNone:
 
287
                // null field value.
 
288
                break;
 
289
 
 
290
              case PCIDSK::FieldTypeInteger:
 
291
                poFeature->SetField( i, aoFields[i].GetValueInteger() );
 
292
                break;
 
293
                                 
 
294
              case PCIDSK::FieldTypeFloat:
 
295
                poFeature->SetField( i, aoFields[i].GetValueFloat() );
 
296
                break;
 
297
                                 
 
298
              case PCIDSK::FieldTypeDouble:
 
299
                poFeature->SetField( i, aoFields[i].GetValueDouble() );
 
300
                break;
 
301
                                 
 
302
              case PCIDSK::FieldTypeString:
 
303
                poFeature->SetField( i, aoFields[i].GetValueString().c_str() );
 
304
                break;
 
305
                                 
 
306
              case PCIDSK::FieldTypeCountedInt:
 
307
                std::vector<PCIDSK::int32> list = aoFields[i].GetValueCountedInt();
202
308
            
203
 
            poFeature->SetField( i, list.size(), &(list[0]) );
204
 
            break;
 
309
                poFeature->SetField( i, list.size(), &(list[0]) );
 
310
                break;
 
311
            }
205
312
        }
206
 
    }
207
313
 
208
314
/* -------------------------------------------------------------------- */
209
315
/*      Translate the geometry.                                         */
210
316
/* -------------------------------------------------------------------- */
211
 
    std::vector<PCIDSK::ShapeVertex> aoVertices;
 
317
        std::vector<PCIDSK::ShapeVertex> aoVertices;
212
318
 
213
 
    poVecSeg->GetVertices( hLastShapeId, aoVertices );
 
319
        poVecSeg->GetVertices( (int) nFID, aoVertices );
214
320
 
215
321
/* -------------------------------------------------------------------- */
216
322
/*      Point                                                           */
217
323
/* -------------------------------------------------------------------- */
218
 
    if( poFeatureDefn->GetGeomType() == wkbPoint25D 
219
 
        || (wkbFlatten(poFeatureDefn->GetGeomType()) == wkbUnknown 
220
 
            && aoVertices.size() == 1) )
221
 
    {
222
 
        if( aoVertices.size() == 1 )
223
 
        {
224
 
            poFeature->SetGeometryDirectly(
225
 
                new OGRPoint( aoVertices[0].x, 
226
 
                              aoVertices[0].y, 
227
 
                              aoVertices[0].z ) );
228
 
        }
229
 
        else
230
 
        {
231
 
            // report issue?
232
 
        }
233
 
    }    
 
324
        if( poFeatureDefn->GetGeomType() == wkbPoint25D 
 
325
            || (wkbFlatten(poFeatureDefn->GetGeomType()) == wkbUnknown 
 
326
                && aoVertices.size() == 1) )
 
327
        {
 
328
            if( aoVertices.size() == 1 )
 
329
            {
 
330
                OGRPoint* poPoint =
 
331
                    new OGRPoint( aoVertices[0].x,
 
332
                                  aoVertices[0].y, 
 
333
                                  aoVertices[0].z );
 
334
                if (poSRS)
 
335
                    poPoint->assignSpatialReference(poSRS);
 
336
                poFeature->SetGeometryDirectly(poPoint);
 
337
            }
 
338
            else
 
339
            {
 
340
                // report issue?
 
341
            }
 
342
        }    
234
343
 
235
344
/* -------------------------------------------------------------------- */
236
345
/*      LineString                                                      */
237
346
/* -------------------------------------------------------------------- */
238
 
    else if( poFeatureDefn->GetGeomType() == wkbLineString25D 
239
 
             || (wkbFlatten(poFeatureDefn->GetGeomType()) == wkbUnknown 
240
 
                 && aoVertices.size() > 1) )
241
 
    {
242
 
        // We should likely be applying ringstart to break things into 
243
 
        // a multilinestring in some cases.
244
 
        if( aoVertices.size() > 1 )
 
347
        else if( poFeatureDefn->GetGeomType() == wkbLineString25D 
 
348
                 || (wkbFlatten(poFeatureDefn->GetGeomType()) == wkbUnknown 
 
349
                     && aoVertices.size() > 1) )
245
350
        {
246
 
            OGRLineString *poLS = new OGRLineString();
 
351
            // We should likely be applying ringstart to break things into 
 
352
            // a multilinestring in some cases.
 
353
            if( aoVertices.size() > 1 )
 
354
            {
 
355
                OGRLineString *poLS = new OGRLineString();
247
356
 
248
 
            poLS->setNumPoints( aoVertices.size() );
 
357
                poLS->setNumPoints( aoVertices.size() );
249
358
            
250
 
            for( i = 0; i < aoVertices.size(); i++ )
251
 
                poLS->setPoint( i,
252
 
                                aoVertices[i].x, 
253
 
                                aoVertices[i].y, 
254
 
                                aoVertices[i].z );
 
359
                for( i = 0; i < aoVertices.size(); i++ )
 
360
                    poLS->setPoint( i,
 
361
                                    aoVertices[i].x, 
 
362
                                    aoVertices[i].y, 
 
363
                                    aoVertices[i].z );
 
364
                if (poSRS)
 
365
                    poLS->assignSpatialReference(poSRS);
255
366
 
256
 
            poFeature->SetGeometryDirectly( poLS );
257
 
        }
258
 
        else
259
 
        {
260
 
            // report issue?
261
 
        }
262
 
    }    
 
367
                poFeature->SetGeometryDirectly( poLS );
 
368
            }
 
369
            else
 
370
            {
 
371
                // report issue?
 
372
            }
 
373
        }    
263
374
 
264
375
/* -------------------------------------------------------------------- */
265
376
/*      Polygon - Currently we have no way to recognise if we are       */
268
379
/*      order, not necessarily outside first which we are not yet       */
269
380
/*      ready to address in the following code.                         */
270
381
/* -------------------------------------------------------------------- */
271
 
    else if( poFeatureDefn->GetGeomType() == wkbPolygon25D )
272
 
    {
273
 
        std::vector<PCIDSK::int32> anRingStart;
274
 
        OGRPolygon *poPoly = new OGRPolygon();
275
 
        unsigned int iRing;
276
 
 
277
 
        if( iRingStartField != -1 )
278
 
            anRingStart = aoFields[iRingStartField].GetValueCountedInt();
279
 
 
280
 
        for( iRing = 0; iRing < anRingStart.size()+1; iRing++ )
 
382
        else if( poFeatureDefn->GetGeomType() == wkbPolygon25D )
281
383
        {
282
 
            unsigned int iStartVertex, iEndVertex, iVertex;
283
 
            OGRLinearRing *poRing = new OGRLinearRing();
284
 
 
285
 
            if( iRing == 0 )
286
 
                iStartVertex = 0;
287
 
            else
288
 
                iStartVertex = anRingStart[iRing-1];
289
 
 
290
 
            if( iRing == anRingStart.size() )
291
 
                iEndVertex = aoVertices.size() - 1;
292
 
            else
293
 
                iEndVertex = anRingStart[iRing] - 1;
294
 
 
295
 
            poRing->setNumPoints( iEndVertex - iStartVertex + 1 );
296
 
            for( iVertex = iStartVertex; iVertex <= iEndVertex; iVertex++ )
 
384
            std::vector<PCIDSK::int32> anRingStart;
 
385
            OGRPolygon *poPoly = new OGRPolygon();
 
386
            unsigned int iRing;
 
387
 
 
388
            if( iRingStartField != -1 )
 
389
                anRingStart = aoFields[iRingStartField].GetValueCountedInt();
 
390
 
 
391
            for( iRing = 0; iRing < anRingStart.size()+1; iRing++ )
297
392
            {
298
 
                poRing->setPoint( iVertex - iStartVertex,
299
 
                                  aoVertices[iVertex].x, 
300
 
                                  aoVertices[iVertex].y, 
301
 
                                  aoVertices[iVertex].z );
 
393
                int iStartVertex, iEndVertex, iVertex;
 
394
                OGRLinearRing *poRing = new OGRLinearRing();
 
395
 
 
396
                if( iRing == 0 )
 
397
                    iStartVertex = 0;
 
398
                else
 
399
                    iStartVertex = anRingStart[iRing-1];
 
400
 
 
401
                if( iRing == anRingStart.size() )
 
402
                    iEndVertex = aoVertices.size() - 1;
 
403
                else
 
404
                    iEndVertex = anRingStart[iRing] - 1;
 
405
 
 
406
                poRing->setNumPoints( iEndVertex - iStartVertex + 1 );
 
407
                for( iVertex = iStartVertex; iVertex <= iEndVertex; iVertex++ )
 
408
                {
 
409
                    poRing->setPoint( iVertex - iStartVertex,
 
410
                                      aoVertices[iVertex].x, 
 
411
                                      aoVertices[iVertex].y, 
 
412
                                      aoVertices[iVertex].z );
 
413
                }
 
414
 
 
415
                poPoly->addRingDirectly( poRing );
302
416
            }
303
417
 
304
 
            poPoly->addRingDirectly( poRing );
305
 
        }
 
418
            if (poSRS)
 
419
                poPoly->assignSpatialReference(poSRS);
306
420
 
307
 
        poFeature->SetGeometryDirectly( poPoly );
308
 
    }    
 
421
            poFeature->SetGeometryDirectly( poPoly );
 
422
        }    
 
423
    }
309
424
    
 
425
/* -------------------------------------------------------------------- */
 
426
/*      Trap exceptions and report as CPL errors.                       */
 
427
/* -------------------------------------------------------------------- */
 
428
    catch( PCIDSK::PCIDSKException ex )
 
429
    {
 
430
        CPLError( CE_Failure, CPLE_AppDefined, 
 
431
                  "%s", ex.what() );
 
432
        return NULL;
 
433
    }
 
434
    catch(...)
 
435
    {
 
436
        CPLError( CE_Failure, CPLE_AppDefined, 
 
437
                  "Non-PCIDSK exception trapped." );
 
438
        return NULL;
 
439
    }
 
440
 
310
441
    m_nFeaturesRead++;
311
442
 
312
443
    return poFeature;
313
444
}
314
445
 
315
 
 
316
 
/************************************************************************/
317
 
/*                           GetNextFeature()                           */
318
 
/************************************************************************/
319
 
 
320
 
OGRFeature *OGRPCIDSKLayer::GetNextFeature()
321
 
 
322
 
{
323
 
    OGRFeature  *poFeature = NULL;
324
 
 
325
 
/* -------------------------------------------------------------------- */
326
 
/*      Read features till we find one that satisfies our current       */
327
 
/*      spatial criteria.                                               */
328
 
/* -------------------------------------------------------------------- */
329
 
    while( TRUE )
330
 
    {
331
 
        poFeature = GetNextUnfilteredFeature();
332
 
        if( poFeature == NULL )
333
 
            break;
334
 
 
335
 
        if( (m_poFilterGeom == NULL
336
 
            || FilterGeometry( poFeature->GetGeometryRef() ) )
337
 
            && (m_poAttrQuery == NULL
338
 
                || m_poAttrQuery->Evaluate( poFeature )) )
339
 
            break;
340
 
 
341
 
        delete poFeature;
342
 
    }
343
 
 
344
 
    return poFeature;
345
 
}
346
 
 
347
446
/************************************************************************/
348
447
/*                           TestCapability()                           */
349
448
/************************************************************************/
351
450
int OGRPCIDSKLayer::TestCapability( const char * pszCap )
352
451
 
353
452
{
354
 
    return FALSE;
355
 
}
356
 
 
 
453
    if( EQUAL(pszCap,OLCRandomRead) )
 
454
        return TRUE;
 
455
 
 
456
    else if( EQUAL(pszCap,OLCFastFeatureCount) )
 
457
        return m_poFilterGeom == NULL && m_poAttrQuery == NULL;
 
458
 
 
459
    else if( EQUAL(pszCap,OLCSequentialWrite) 
 
460
             || EQUAL(pszCap,OLCRandomWrite) )
 
461
        return bUpdateAccess;
 
462
 
 
463
    else if( EQUAL(pszCap,OLCDeleteFeature) )
 
464
        return bUpdateAccess;
 
465
 
 
466
    else if( EQUAL(pszCap,OLCCreateField) )
 
467
        return bUpdateAccess;
 
468
 
 
469
    else 
 
470
        return FALSE;
 
471
}
 
472
 
 
473
/************************************************************************/
 
474
/*                          GetFeatureCount()                           */
 
475
/************************************************************************/
 
476
 
 
477
int OGRPCIDSKLayer::GetFeatureCount( int bForce )
 
478
 
 
479
{
 
480
    if( m_poFilterGeom != NULL || m_poAttrQuery != NULL )
 
481
        return OGRLayer::GetFeatureCount( bForce );
 
482
    else
 
483
    {
 
484
        try {
 
485
            return poVecSeg->GetShapeCount();
 
486
        } catch(...) {
 
487
            return 0;
 
488
        }
 
489
    }
 
490
}
 
491
 
 
492
/************************************************************************/
 
493
/*                             GetExtent()                              */
 
494
/************************************************************************/
 
495
 
 
496
OGRErr OGRPCIDSKLayer::GetExtent (OGREnvelope *psExtent, int bForce)
 
497
 
 
498
{
 
499
    if( !bForce )
 
500
        return OGRERR_FAILURE;
 
501
    
 
502
/* -------------------------------------------------------------------- */
 
503
/*      Loop over all features, but just read the geometry.  This is    */
 
504
/*      a fair amount quicker than actually processing all the          */
 
505
/*      attributes, forming features and then exaimining the            */
 
506
/*      geometries as the default implemntation would do.               */
 
507
/* -------------------------------------------------------------------- */
 
508
    try
 
509
    {
 
510
        bool bHaveExtent = FALSE;
 
511
 
 
512
        std::vector<PCIDSK::ShapeVertex> asVertices;
 
513
 
 
514
        for( PCIDSK::ShapeIterator oIt = poVecSeg->begin(); 
 
515
             oIt != poVecSeg->end();
 
516
             oIt++ )
 
517
        {
 
518
            unsigned int i;
 
519
 
 
520
            poVecSeg->GetVertices( *oIt, asVertices );
 
521
 
 
522
            for( i = 0; i < asVertices.size(); i++ )
 
523
            {
 
524
                if( !bHaveExtent )
 
525
                {
 
526
                    psExtent->MinX = psExtent->MaxX = asVertices[i].x;
 
527
                    psExtent->MinY = psExtent->MaxY = asVertices[i].y;
 
528
                    bHaveExtent = true;
 
529
                }
 
530
                else
 
531
                {
 
532
                    psExtent->MinX = MIN(psExtent->MinX,asVertices[i].x);
 
533
                    psExtent->MaxX = MAX(psExtent->MaxX,asVertices[i].x);
 
534
                    psExtent->MinY = MIN(psExtent->MinY,asVertices[i].y);
 
535
                    psExtent->MaxY = MAX(psExtent->MaxY,asVertices[i].y);
 
536
                }
 
537
            }
 
538
        }
 
539
 
 
540
        if( bHaveExtent )
 
541
            return OGRERR_NONE;
 
542
        else
 
543
            return OGRERR_FAILURE;
 
544
    }
 
545
 
 
546
/* -------------------------------------------------------------------- */
 
547
/*      Trap pcidsk exceptions.                                         */
 
548
/* -------------------------------------------------------------------- */
 
549
    catch( PCIDSK::PCIDSKException ex )
 
550
    {
 
551
        CPLError( CE_Failure, CPLE_AppDefined,
 
552
                  "PCIDSK Exception while initializing layer, operation likely impaired.\n%s", ex.what() );
 
553
        return OGRERR_FAILURE;
 
554
    }
 
555
    catch(...)
 
556
    {
 
557
        CPLError( CE_Failure, CPLE_AppDefined, 
 
558
                  "Non-PCIDSK exception trapped while initializing layer, operation likely impaired." );
 
559
        return OGRERR_FAILURE;
 
560
    }
 
561
}
 
562
 
 
563
/************************************************************************/
 
564
/*                           DeleteFeature()                            */
 
565
/************************************************************************/
 
566
 
 
567
OGRErr OGRPCIDSKLayer::DeleteFeature( long nFID )
 
568
 
 
569
{
 
570
    try {
 
571
 
 
572
        poVecSeg->DeleteShape( (PCIDSK::ShapeId) nFID );
 
573
 
 
574
        return OGRERR_NONE;
 
575
    }
 
576
 
 
577
/* -------------------------------------------------------------------- */
 
578
/*      Trap exceptions and report as CPL errors.                       */
 
579
/* -------------------------------------------------------------------- */
 
580
    catch( PCIDSK::PCIDSKException ex )
 
581
    {
 
582
        CPLError( CE_Failure, CPLE_AppDefined, 
 
583
                  "%s", ex.what() );
 
584
        return OGRERR_FAILURE;
 
585
    }
 
586
    catch(...)
 
587
    {
 
588
        CPLError( CE_Failure, CPLE_AppDefined, 
 
589
                  "Non-PCIDSK exception trapped." );
 
590
        return OGRERR_FAILURE;
 
591
    }
 
592
}
 
593
 
 
594
/************************************************************************/
 
595
/*                           CreateFeature()                            */
 
596
/************************************************************************/
 
597
 
 
598
OGRErr OGRPCIDSKLayer::CreateFeature( OGRFeature *poFeature )
 
599
 
 
600
{
 
601
    try {
 
602
 
 
603
        PCIDSK::ShapeId id = poVecSeg->CreateShape( 
 
604
            (PCIDSK::ShapeId) poFeature->GetFID() );
 
605
 
 
606
        poFeature->SetFID( (long) id );
 
607
 
 
608
        return SetFeature( poFeature );
 
609
    }
 
610
/* -------------------------------------------------------------------- */
 
611
/*      Trap exceptions and report as CPL errors.                       */
 
612
/* -------------------------------------------------------------------- */
 
613
    catch( PCIDSK::PCIDSKException ex )
 
614
    {
 
615
        CPLError( CE_Failure, CPLE_AppDefined, 
 
616
                  "%s", ex.what() );
 
617
        return OGRERR_FAILURE;
 
618
    }
 
619
    catch(...)
 
620
    {
 
621
        CPLError( CE_Failure, CPLE_AppDefined, 
 
622
                  "Non-PCIDSK exception trapped." );
 
623
        return OGRERR_FAILURE;
 
624
    }
 
625
    
 
626
}
 
627
 
 
628
/************************************************************************/
 
629
/*                             SetFeature()                             */
 
630
/************************************************************************/
 
631
 
 
632
OGRErr OGRPCIDSKLayer::SetFeature( OGRFeature *poFeature )
 
633
 
 
634
{
 
635
    PCIDSK::ShapeId id = (PCIDSK::ShapeId) poFeature->GetFID();
 
636
    
 
637
/* -------------------------------------------------------------------- */
 
638
/*      Translate attribute fields.                                     */
 
639
/* -------------------------------------------------------------------- */
 
640
    try {
 
641
 
 
642
        int iPCI;
 
643
        std::vector<PCIDSK::ShapeField>  aoPCIFields;
 
644
 
 
645
        aoPCIFields.resize(poVecSeg->GetFieldCount());
 
646
 
 
647
        for( iPCI = 0; iPCI < poVecSeg->GetFieldCount(); iPCI++ )
 
648
        {
 
649
            int iOGR;
 
650
 
 
651
            iOGR = poFeatureDefn->GetFieldIndex(
 
652
                poVecSeg->GetFieldName(iPCI).c_str() );
 
653
 
 
654
            if( iOGR == -1 )
 
655
                continue;
 
656
 
 
657
            switch( poVecSeg->GetFieldType(iPCI) )
 
658
            {
 
659
              case PCIDSK::FieldTypeInteger:
 
660
                aoPCIFields[iPCI].SetValue(
 
661
                    poFeature->GetFieldAsInteger( iOGR ) );
 
662
                break;
 
663
 
 
664
              case PCIDSK::FieldTypeFloat:
 
665
                aoPCIFields[iPCI].SetValue(
 
666
                    (float) poFeature->GetFieldAsDouble( iOGR ) );
 
667
                break;
 
668
 
 
669
              case PCIDSK::FieldTypeDouble:
 
670
                aoPCIFields[iPCI].SetValue(
 
671
                    (double) poFeature->GetFieldAsDouble( iOGR ) );
 
672
                break;
 
673
 
 
674
              case PCIDSK::FieldTypeString:
 
675
                aoPCIFields[iPCI].SetValue(
 
676
                    poFeature->GetFieldAsString( iOGR ) );
 
677
                break;
 
678
 
 
679
              case PCIDSK::FieldTypeCountedInt:
 
680
              {
 
681
                  int nCount;
 
682
                  const int *panList = 
 
683
                      poFeature->GetFieldAsIntegerList( iOGR, &nCount );
 
684
                  std::vector<PCIDSK::int32> anList;
 
685
                  
 
686
                  anList.resize( nCount );
 
687
                  memcpy( &(anList[0]), panList, 4 * anList.size() );
 
688
                  aoPCIFields[iPCI].SetValue( anList );
 
689
              }
 
690
              break;
 
691
 
 
692
              default:
 
693
                CPLAssert( FALSE );
 
694
                break;
 
695
            }
 
696
        }
 
697
 
 
698
        if( poVecSeg->GetFieldCount() > 0 )
 
699
            poVecSeg->SetFields( id, aoPCIFields );
 
700
 
 
701
/* -------------------------------------------------------------------- */
 
702
/*      Translate the geometry.                                         */
 
703
/* -------------------------------------------------------------------- */
 
704
        std::vector<PCIDSK::ShapeVertex> aoVertices;
 
705
        OGRGeometry *poGeometry = poFeature->GetGeometryRef();
 
706
 
 
707
        if( poGeometry == NULL )
 
708
        {
 
709
        }
 
710
 
 
711
        else if( wkbFlatten(poGeometry->getGeometryType()) == wkbPoint )
 
712
        {
 
713
            OGRPoint *poPoint = (OGRPoint *) poGeometry;
 
714
 
 
715
            aoVertices.resize(1);
 
716
            aoVertices[0].x = poPoint->getX();
 
717
            aoVertices[0].y = poPoint->getY();
 
718
            aoVertices[0].z = poPoint->getZ();
 
719
        }
 
720
 
 
721
        else if( wkbFlatten(poGeometry->getGeometryType()) == wkbLineString )
 
722
        {
 
723
            OGRLineString *poLS = (OGRLineString *) poGeometry;
 
724
            unsigned int i;
 
725
 
 
726
            aoVertices.resize(poLS->getNumPoints());
 
727
 
 
728
            for( i = 0; i < aoVertices.size(); i++ )
 
729
            {
 
730
                aoVertices[i].x = poLS->getX(i);
 
731
                aoVertices[i].y = poLS->getY(i);
 
732
                aoVertices[i].z = poLS->getZ(i);
 
733
            }
 
734
        }
 
735
 
 
736
        else
 
737
        {
 
738
            CPLDebug( "PCIDSK", "Unsupported geometry type in SetFeature(): %s",
 
739
                      poGeometry->getGeometryName() );
 
740
        }
 
741
 
 
742
        poVecSeg->SetVertices( id, aoVertices );
 
743
 
 
744
    } /* try */
 
745
 
 
746
/* -------------------------------------------------------------------- */
 
747
/*      Trap exceptions and report as CPL errors.                       */
 
748
/* -------------------------------------------------------------------- */
 
749
    catch( PCIDSK::PCIDSKException ex )
 
750
    {
 
751
        CPLError( CE_Failure, CPLE_AppDefined, 
 
752
                  "%s", ex.what() );
 
753
        return OGRERR_FAILURE;
 
754
    }
 
755
    catch(...)
 
756
    {
 
757
        CPLError( CE_Failure, CPLE_AppDefined, 
 
758
                  "Non-PCIDSK exception trapped." );
 
759
        return OGRERR_FAILURE;
 
760
    }
 
761
 
 
762
    return OGRERR_NONE;
 
763
}
 
764
 
 
765
/************************************************************************/
 
766
/*                            CreateField()                             */
 
767
/************************************************************************/
 
768
 
 
769
OGRErr OGRPCIDSKLayer::CreateField( OGRFieldDefn *poFieldDefn,
 
770
                                    int bApproxOK )
 
771
 
 
772
{
 
773
    try {
 
774
        
 
775
        if( poFieldDefn->GetType() == OFTInteger )
 
776
        {
 
777
            poVecSeg->AddField( poFieldDefn->GetNameRef(), 
 
778
                                PCIDSK::FieldTypeInteger, 
 
779
                                "", "" );
 
780
            poFeatureDefn->AddFieldDefn( poFieldDefn );
 
781
        }
 
782
        else if( poFieldDefn->GetType() == OFTReal )
 
783
        {
 
784
            poVecSeg->AddField( poFieldDefn->GetNameRef(), 
 
785
                                PCIDSK::FieldTypeDouble, 
 
786
                                "", "" );
 
787
            poFeatureDefn->AddFieldDefn( poFieldDefn );
 
788
        }
 
789
        else if( poFieldDefn->GetType() == OFTString )
 
790
        {
 
791
            poVecSeg->AddField( poFieldDefn->GetNameRef(), 
 
792
                                PCIDSK::FieldTypeString, 
 
793
                                "", "" );
 
794
            poFeatureDefn->AddFieldDefn( poFieldDefn );
 
795
        }
 
796
        else if( poFieldDefn->GetType() == OFTIntegerList )
 
797
        {
 
798
            poVecSeg->AddField( poFieldDefn->GetNameRef(), 
 
799
                                PCIDSK::FieldTypeCountedInt, 
 
800
                                "", "" );
 
801
            poFeatureDefn->AddFieldDefn( poFieldDefn );
 
802
        }
 
803
        else if( bApproxOK )
 
804
        {
 
805
            // Fallback to treating everything else as a string field.
 
806
            OGRFieldDefn oModFieldDefn(poFieldDefn);
 
807
            oModFieldDefn.SetType( OFTString );
 
808
            poVecSeg->AddField( poFieldDefn->GetNameRef(), 
 
809
                                PCIDSK::FieldTypeString, 
 
810
                                "", "" );
 
811
            poFeatureDefn->AddFieldDefn( &oModFieldDefn );
 
812
        }
 
813
        else
 
814
        {
 
815
            CPLError( CE_Failure, CPLE_AppDefined,
 
816
                      "Attempt to create field '%s' of unsupported data type.",
 
817
                      poFieldDefn->GetNameRef() );
 
818
        }
 
819
    }
 
820
 
 
821
/* -------------------------------------------------------------------- */
 
822
/*      Trap exceptions and report as CPL errors.                       */
 
823
/* -------------------------------------------------------------------- */
 
824
    catch( PCIDSK::PCIDSKException ex )
 
825
    {
 
826
        CPLError( CE_Failure, CPLE_AppDefined, 
 
827
                  "%s", ex.what() );
 
828
        return OGRERR_FAILURE;
 
829
    }
 
830
    catch(...)
 
831
    {
 
832
        CPLError( CE_Failure, CPLE_AppDefined, 
 
833
                  "Non-PCIDSK exception trapped." );
 
834
        return OGRERR_FAILURE;
 
835
    }
 
836
 
 
837
    return OGRERR_NONE;
 
838
}