LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/pcidsk - ogrpcidsklayer.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 294 215 73.1 %
Date: 2012-04-28 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              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                 : }

Generated by: LCOV version 1.7