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