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