63
66
poFeatureDefn->SetGeomType( wkbNone );
66
70
/* -------------------------------------------------------------------- */
67
71
/* Build field definitions. */
68
72
/* -------------------------------------------------------------------- */
71
for( int iField = 0; iField < poVecSeg->GetFieldCount(); iField++ )
73
OGRFieldDefn oField( poVecSeg->GetFieldName(iField).c_str(), OFTString);
75
switch( poVecSeg->GetFieldType(iField) )
77
case PCIDSK::FieldTypeFloat:
78
case PCIDSK::FieldTypeDouble:
79
oField.SetType( OFTReal );
82
case PCIDSK::FieldTypeInteger:
83
oField.SetType( OFTInteger );
86
case PCIDSK::FieldTypeString:
87
oField.SetType( OFTString );
90
case PCIDSK::FieldTypeCountedInt:
91
oField.SetType( OFTIntegerList );
99
// we ought to try and extract some width/precision information
100
// from the format string at some point.
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;
108
poFeatureDefn->AddFieldDefn( &oField );
77
for( int iField = 0; iField < poVecSeg->GetFieldCount(); iField++ )
79
OGRFieldDefn oField( poVecSeg->GetFieldName(iField).c_str(), OFTString);
81
switch( poVecSeg->GetFieldType(iField) )
83
case PCIDSK::FieldTypeFloat:
84
case PCIDSK::FieldTypeDouble:
85
oField.SetType( OFTReal );
88
case PCIDSK::FieldTypeInteger:
89
oField.SetType( OFTInteger );
92
case PCIDSK::FieldTypeString:
93
oField.SetType( OFTString );
96
case PCIDSK::FieldTypeCountedInt:
97
oField.SetType( OFTIntegerList );
105
// we ought to try and extract some width/precision information
106
// from the format string at some point.
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;
114
poFeatureDefn->AddFieldDefn( &oField );
117
/* -------------------------------------------------------------------- */
118
/* Look for a coordinate system. */
119
/* -------------------------------------------------------------------- */
121
const char *pszUnits = NULL;
122
std::vector<double> adfParameters;
124
adfParameters = poVecSeg->GetProjection( osGeosys );
126
if( ((PCIDSK::UnitCode)(int)adfParameters[16])
127
== PCIDSK::UNIT_DEGREE )
129
else if( ((PCIDSK::UnitCode)(int)adfParameters[16])
130
== PCIDSK::UNIT_METER )
132
else if( ((PCIDSK::UnitCode)(int)adfParameters[16])
133
== PCIDSK::UNIT_US_FOOT )
135
else if( ((PCIDSK::UnitCode)(int)adfParameters[16])
136
== PCIDSK::UNIT_INTL_FOOT )
137
pszUnits = "INTL FOOT";
139
poSRS = new OGRSpatialReference();
141
if( poSRS->importFromPCI( osGeosys, pszUnits,
142
&(adfParameters[0]) ) != OGRERR_NONE )
149
/* -------------------------------------------------------------------- */
150
/* Trap pcidsk exceptions. */
151
/* -------------------------------------------------------------------- */
152
catch( PCIDSK::PCIDSKException ex )
154
CPLError( CE_Failure, CPLE_AppDefined,
155
"PCIDSK Exception while initializing layer, operation likely impaired.\n%s", ex.what() );
159
CPLError( CE_Failure, CPLE_AppDefined,
160
"Non-PCIDSK exception trapped while initializing layer, operation likely impaired." );
156
250
if( hLastShapeId == PCIDSK::NullShapeId )
253
return GetFeature( hLastShapeId );
256
/************************************************************************/
258
/************************************************************************/
260
OGRFeature *OGRPCIDSKLayer::GetFeature( long nFID )
159
263
/* -------------------------------------------------------------------- */
160
264
/* Create the OGR feature. */
161
265
/* -------------------------------------------------------------------- */
162
266
OGRFeature *poFeature;
164
268
poFeature = new OGRFeature( poFeatureDefn );
165
poFeature->SetFID( (int) hLastShapeId );
269
poFeature->SetFID( (int) nFID );
167
271
/* -------------------------------------------------------------------- */
168
272
/* Set attributes for any indicated attribute records. */
169
273
/* -------------------------------------------------------------------- */
170
std::vector<PCIDSK::ShapeField> aoFields;
172
poVecSeg->GetFields( hLastShapeId, aoFields );
173
for( i=0; i < aoFields.size(); i++ )
175
if( (int) i == iRingStartField )
178
switch( aoFields[i].GetType() )
275
std::vector<PCIDSK::ShapeField> aoFields;
278
poVecSeg->GetFields( (int) nFID, aoFields );
279
for( i=0; i < aoFields.size(); i++ )
180
case PCIDSK::FieldTypeNone:
184
case PCIDSK::FieldTypeInteger:
185
poFeature->SetField( i, aoFields[i].GetValueInteger() );
188
case PCIDSK::FieldTypeFloat:
189
poFeature->SetField( i, aoFields[i].GetValueFloat() );
192
case PCIDSK::FieldTypeDouble:
193
poFeature->SetField( i, aoFields[i].GetValueDouble() );
196
case PCIDSK::FieldTypeString:
197
poFeature->SetField( i, aoFields[i].GetValueString().c_str() );
200
case PCIDSK::FieldTypeCountedInt:
201
std::vector<PCIDSK::int32> list = aoFields[i].GetValueCountedInt();
281
if( (int) i == iRingStartField )
284
switch( aoFields[i].GetType() )
286
case PCIDSK::FieldTypeNone:
290
case PCIDSK::FieldTypeInteger:
291
poFeature->SetField( i, aoFields[i].GetValueInteger() );
294
case PCIDSK::FieldTypeFloat:
295
poFeature->SetField( i, aoFields[i].GetValueFloat() );
298
case PCIDSK::FieldTypeDouble:
299
poFeature->SetField( i, aoFields[i].GetValueDouble() );
302
case PCIDSK::FieldTypeString:
303
poFeature->SetField( i, aoFields[i].GetValueString().c_str() );
306
case PCIDSK::FieldTypeCountedInt:
307
std::vector<PCIDSK::int32> list = aoFields[i].GetValueCountedInt();
203
poFeature->SetField( i, list.size(), &(list[0]) );
309
poFeature->SetField( i, list.size(), &(list[0]) );
208
314
/* -------------------------------------------------------------------- */
209
315
/* Translate the geometry. */
210
316
/* -------------------------------------------------------------------- */
211
std::vector<PCIDSK::ShapeVertex> aoVertices;
317
std::vector<PCIDSK::ShapeVertex> aoVertices;
213
poVecSeg->GetVertices( hLastShapeId, aoVertices );
319
poVecSeg->GetVertices( (int) nFID, aoVertices );
215
321
/* -------------------------------------------------------------------- */
217
323
/* -------------------------------------------------------------------- */
218
if( poFeatureDefn->GetGeomType() == wkbPoint25D
219
|| (wkbFlatten(poFeatureDefn->GetGeomType()) == wkbUnknown
220
&& aoVertices.size() == 1) )
222
if( aoVertices.size() == 1 )
224
poFeature->SetGeometryDirectly(
225
new OGRPoint( aoVertices[0].x,
324
if( poFeatureDefn->GetGeomType() == wkbPoint25D
325
|| (wkbFlatten(poFeatureDefn->GetGeomType()) == wkbUnknown
326
&& aoVertices.size() == 1) )
328
if( aoVertices.size() == 1 )
331
new OGRPoint( aoVertices[0].x,
335
poPoint->assignSpatialReference(poSRS);
336
poFeature->SetGeometryDirectly(poPoint);
235
344
/* -------------------------------------------------------------------- */
237
346
/* -------------------------------------------------------------------- */
238
else if( poFeatureDefn->GetGeomType() == wkbLineString25D
239
|| (wkbFlatten(poFeatureDefn->GetGeomType()) == wkbUnknown
240
&& aoVertices.size() > 1) )
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) )
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 )
355
OGRLineString *poLS = new OGRLineString();
248
poLS->setNumPoints( aoVertices.size() );
357
poLS->setNumPoints( aoVertices.size() );
250
for( i = 0; i < aoVertices.size(); i++ )
359
for( i = 0; i < aoVertices.size(); i++ )
365
poLS->assignSpatialReference(poSRS);
256
poFeature->SetGeometryDirectly( poLS );
367
poFeature->SetGeometryDirectly( poLS );
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 )
273
std::vector<PCIDSK::int32> anRingStart;
274
OGRPolygon *poPoly = new OGRPolygon();
277
if( iRingStartField != -1 )
278
anRingStart = aoFields[iRingStartField].GetValueCountedInt();
280
for( iRing = 0; iRing < anRingStart.size()+1; iRing++ )
382
else if( poFeatureDefn->GetGeomType() == wkbPolygon25D )
282
unsigned int iStartVertex, iEndVertex, iVertex;
283
OGRLinearRing *poRing = new OGRLinearRing();
288
iStartVertex = anRingStart[iRing-1];
290
if( iRing == anRingStart.size() )
291
iEndVertex = aoVertices.size() - 1;
293
iEndVertex = anRingStart[iRing] - 1;
295
poRing->setNumPoints( iEndVertex - iStartVertex + 1 );
296
for( iVertex = iStartVertex; iVertex <= iEndVertex; iVertex++ )
384
std::vector<PCIDSK::int32> anRingStart;
385
OGRPolygon *poPoly = new OGRPolygon();
388
if( iRingStartField != -1 )
389
anRingStart = aoFields[iRingStartField].GetValueCountedInt();
391
for( iRing = 0; iRing < anRingStart.size()+1; iRing++ )
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();
399
iStartVertex = anRingStart[iRing-1];
401
if( iRing == anRingStart.size() )
402
iEndVertex = aoVertices.size() - 1;
404
iEndVertex = anRingStart[iRing] - 1;
406
poRing->setNumPoints( iEndVertex - iStartVertex + 1 );
407
for( iVertex = iStartVertex; iVertex <= iEndVertex; iVertex++ )
409
poRing->setPoint( iVertex - iStartVertex,
410
aoVertices[iVertex].x,
411
aoVertices[iVertex].y,
412
aoVertices[iVertex].z );
415
poPoly->addRingDirectly( poRing );
304
poPoly->addRingDirectly( poRing );
419
poPoly->assignSpatialReference(poSRS);
307
poFeature->SetGeometryDirectly( poPoly );
421
poFeature->SetGeometryDirectly( poPoly );
425
/* -------------------------------------------------------------------- */
426
/* Trap exceptions and report as CPL errors. */
427
/* -------------------------------------------------------------------- */
428
catch( PCIDSK::PCIDSKException ex )
430
CPLError( CE_Failure, CPLE_AppDefined,
436
CPLError( CE_Failure, CPLE_AppDefined,
437
"Non-PCIDSK exception trapped." );
310
441
m_nFeaturesRead++;
312
443
return poFeature;
316
/************************************************************************/
317
/* GetNextFeature() */
318
/************************************************************************/
320
OGRFeature *OGRPCIDSKLayer::GetNextFeature()
323
OGRFeature *poFeature = NULL;
325
/* -------------------------------------------------------------------- */
326
/* Read features till we find one that satisfies our current */
327
/* spatial criteria. */
328
/* -------------------------------------------------------------------- */
331
poFeature = GetNextUnfilteredFeature();
332
if( poFeature == NULL )
335
if( (m_poFilterGeom == NULL
336
|| FilterGeometry( poFeature->GetGeometryRef() ) )
337
&& (m_poAttrQuery == NULL
338
|| m_poAttrQuery->Evaluate( poFeature )) )
347
446
/************************************************************************/
348
447
/* TestCapability() */
349
448
/************************************************************************/
351
450
int OGRPCIDSKLayer::TestCapability( const char * pszCap )
453
if( EQUAL(pszCap,OLCRandomRead) )
456
else if( EQUAL(pszCap,OLCFastFeatureCount) )
457
return m_poFilterGeom == NULL && m_poAttrQuery == NULL;
459
else if( EQUAL(pszCap,OLCSequentialWrite)
460
|| EQUAL(pszCap,OLCRandomWrite) )
461
return bUpdateAccess;
463
else if( EQUAL(pszCap,OLCDeleteFeature) )
464
return bUpdateAccess;
466
else if( EQUAL(pszCap,OLCCreateField) )
467
return bUpdateAccess;
473
/************************************************************************/
474
/* GetFeatureCount() */
475
/************************************************************************/
477
int OGRPCIDSKLayer::GetFeatureCount( int bForce )
480
if( m_poFilterGeom != NULL || m_poAttrQuery != NULL )
481
return OGRLayer::GetFeatureCount( bForce );
485
return poVecSeg->GetShapeCount();
492
/************************************************************************/
494
/************************************************************************/
496
OGRErr OGRPCIDSKLayer::GetExtent (OGREnvelope *psExtent, int bForce)
500
return OGRERR_FAILURE;
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
/* -------------------------------------------------------------------- */
510
bool bHaveExtent = FALSE;
512
std::vector<PCIDSK::ShapeVertex> asVertices;
514
for( PCIDSK::ShapeIterator oIt = poVecSeg->begin();
515
oIt != poVecSeg->end();
520
poVecSeg->GetVertices( *oIt, asVertices );
522
for( i = 0; i < asVertices.size(); i++ )
526
psExtent->MinX = psExtent->MaxX = asVertices[i].x;
527
psExtent->MinY = psExtent->MaxY = asVertices[i].y;
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);
543
return OGRERR_FAILURE;
546
/* -------------------------------------------------------------------- */
547
/* Trap pcidsk exceptions. */
548
/* -------------------------------------------------------------------- */
549
catch( PCIDSK::PCIDSKException ex )
551
CPLError( CE_Failure, CPLE_AppDefined,
552
"PCIDSK Exception while initializing layer, operation likely impaired.\n%s", ex.what() );
553
return OGRERR_FAILURE;
557
CPLError( CE_Failure, CPLE_AppDefined,
558
"Non-PCIDSK exception trapped while initializing layer, operation likely impaired." );
559
return OGRERR_FAILURE;
563
/************************************************************************/
564
/* DeleteFeature() */
565
/************************************************************************/
567
OGRErr OGRPCIDSKLayer::DeleteFeature( long nFID )
572
poVecSeg->DeleteShape( (PCIDSK::ShapeId) nFID );
577
/* -------------------------------------------------------------------- */
578
/* Trap exceptions and report as CPL errors. */
579
/* -------------------------------------------------------------------- */
580
catch( PCIDSK::PCIDSKException ex )
582
CPLError( CE_Failure, CPLE_AppDefined,
584
return OGRERR_FAILURE;
588
CPLError( CE_Failure, CPLE_AppDefined,
589
"Non-PCIDSK exception trapped." );
590
return OGRERR_FAILURE;
594
/************************************************************************/
595
/* CreateFeature() */
596
/************************************************************************/
598
OGRErr OGRPCIDSKLayer::CreateFeature( OGRFeature *poFeature )
603
PCIDSK::ShapeId id = poVecSeg->CreateShape(
604
(PCIDSK::ShapeId) poFeature->GetFID() );
606
poFeature->SetFID( (long) id );
608
return SetFeature( poFeature );
610
/* -------------------------------------------------------------------- */
611
/* Trap exceptions and report as CPL errors. */
612
/* -------------------------------------------------------------------- */
613
catch( PCIDSK::PCIDSKException ex )
615
CPLError( CE_Failure, CPLE_AppDefined,
617
return OGRERR_FAILURE;
621
CPLError( CE_Failure, CPLE_AppDefined,
622
"Non-PCIDSK exception trapped." );
623
return OGRERR_FAILURE;
628
/************************************************************************/
630
/************************************************************************/
632
OGRErr OGRPCIDSKLayer::SetFeature( OGRFeature *poFeature )
635
PCIDSK::ShapeId id = (PCIDSK::ShapeId) poFeature->GetFID();
637
/* -------------------------------------------------------------------- */
638
/* Translate attribute fields. */
639
/* -------------------------------------------------------------------- */
643
std::vector<PCIDSK::ShapeField> aoPCIFields;
645
aoPCIFields.resize(poVecSeg->GetFieldCount());
647
for( iPCI = 0; iPCI < poVecSeg->GetFieldCount(); iPCI++ )
651
iOGR = poFeatureDefn->GetFieldIndex(
652
poVecSeg->GetFieldName(iPCI).c_str() );
657
switch( poVecSeg->GetFieldType(iPCI) )
659
case PCIDSK::FieldTypeInteger:
660
aoPCIFields[iPCI].SetValue(
661
poFeature->GetFieldAsInteger( iOGR ) );
664
case PCIDSK::FieldTypeFloat:
665
aoPCIFields[iPCI].SetValue(
666
(float) poFeature->GetFieldAsDouble( iOGR ) );
669
case PCIDSK::FieldTypeDouble:
670
aoPCIFields[iPCI].SetValue(
671
(double) poFeature->GetFieldAsDouble( iOGR ) );
674
case PCIDSK::FieldTypeString:
675
aoPCIFields[iPCI].SetValue(
676
poFeature->GetFieldAsString( iOGR ) );
679
case PCIDSK::FieldTypeCountedInt:
683
poFeature->GetFieldAsIntegerList( iOGR, &nCount );
684
std::vector<PCIDSK::int32> anList;
686
anList.resize( nCount );
687
memcpy( &(anList[0]), panList, 4 * anList.size() );
688
aoPCIFields[iPCI].SetValue( anList );
698
if( poVecSeg->GetFieldCount() > 0 )
699
poVecSeg->SetFields( id, aoPCIFields );
701
/* -------------------------------------------------------------------- */
702
/* Translate the geometry. */
703
/* -------------------------------------------------------------------- */
704
std::vector<PCIDSK::ShapeVertex> aoVertices;
705
OGRGeometry *poGeometry = poFeature->GetGeometryRef();
707
if( poGeometry == NULL )
711
else if( wkbFlatten(poGeometry->getGeometryType()) == wkbPoint )
713
OGRPoint *poPoint = (OGRPoint *) poGeometry;
715
aoVertices.resize(1);
716
aoVertices[0].x = poPoint->getX();
717
aoVertices[0].y = poPoint->getY();
718
aoVertices[0].z = poPoint->getZ();
721
else if( wkbFlatten(poGeometry->getGeometryType()) == wkbLineString )
723
OGRLineString *poLS = (OGRLineString *) poGeometry;
726
aoVertices.resize(poLS->getNumPoints());
728
for( i = 0; i < aoVertices.size(); i++ )
730
aoVertices[i].x = poLS->getX(i);
731
aoVertices[i].y = poLS->getY(i);
732
aoVertices[i].z = poLS->getZ(i);
738
CPLDebug( "PCIDSK", "Unsupported geometry type in SetFeature(): %s",
739
poGeometry->getGeometryName() );
742
poVecSeg->SetVertices( id, aoVertices );
746
/* -------------------------------------------------------------------- */
747
/* Trap exceptions and report as CPL errors. */
748
/* -------------------------------------------------------------------- */
749
catch( PCIDSK::PCIDSKException ex )
751
CPLError( CE_Failure, CPLE_AppDefined,
753
return OGRERR_FAILURE;
757
CPLError( CE_Failure, CPLE_AppDefined,
758
"Non-PCIDSK exception trapped." );
759
return OGRERR_FAILURE;
765
/************************************************************************/
767
/************************************************************************/
769
OGRErr OGRPCIDSKLayer::CreateField( OGRFieldDefn *poFieldDefn,
775
if( poFieldDefn->GetType() == OFTInteger )
777
poVecSeg->AddField( poFieldDefn->GetNameRef(),
778
PCIDSK::FieldTypeInteger,
780
poFeatureDefn->AddFieldDefn( poFieldDefn );
782
else if( poFieldDefn->GetType() == OFTReal )
784
poVecSeg->AddField( poFieldDefn->GetNameRef(),
785
PCIDSK::FieldTypeDouble,
787
poFeatureDefn->AddFieldDefn( poFieldDefn );
789
else if( poFieldDefn->GetType() == OFTString )
791
poVecSeg->AddField( poFieldDefn->GetNameRef(),
792
PCIDSK::FieldTypeString,
794
poFeatureDefn->AddFieldDefn( poFieldDefn );
796
else if( poFieldDefn->GetType() == OFTIntegerList )
798
poVecSeg->AddField( poFieldDefn->GetNameRef(),
799
PCIDSK::FieldTypeCountedInt,
801
poFeatureDefn->AddFieldDefn( poFieldDefn );
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,
811
poFeatureDefn->AddFieldDefn( &oModFieldDefn );
815
CPLError( CE_Failure, CPLE_AppDefined,
816
"Attempt to create field '%s' of unsupported data type.",
817
poFieldDefn->GetNameRef() );
821
/* -------------------------------------------------------------------- */
822
/* Trap exceptions and report as CPL errors. */
823
/* -------------------------------------------------------------------- */
824
catch( PCIDSK::PCIDSKException ex )
826
CPLError( CE_Failure, CPLE_AppDefined,
828
return OGRERR_FAILURE;
832
CPLError( CE_Failure, CPLE_AppDefined,
833
"Non-PCIDSK exception trapped." );
834
return OGRERR_FAILURE;