LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/pcidsk - ogrpcidsklayer.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 296 219 74.0 %
Date: 2012-12-26 Functions: 17 14 82.4 %

       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                 : }

Generated by: LCOV version 1.7