LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/mem - ogrmemlayer.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 130 106 81.5 %
Date: 2010-01-09 Functions: 14 13 92.9 %

       1                 : /******************************************************************************
       2                 :  * $Id: ogrmemlayer.cpp 17807 2009-10-13 18:18:09Z rouault $
       3                 :  *
       4                 :  * Project:  OpenGIS Simple Features Reference Implementation
       5                 :  * Purpose:  Implements OGRMemLayer class.
       6                 :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 2003, 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_mem.h"
      31                 : #include "cpl_conv.h"
      32                 : 
      33                 : CPL_CVSID("$Id: ogrmemlayer.cpp 17807 2009-10-13 18:18:09Z rouault $");
      34                 : 
      35                 : /************************************************************************/
      36                 : /*                            OGRMemLayer()                             */
      37                 : /************************************************************************/
      38                 : 
      39              12 : OGRMemLayer::OGRMemLayer( const char * pszName, OGRSpatialReference *poSRSIn, 
      40              12 :                           OGRwkbGeometryType eReqType )
      41                 : 
      42                 : {
      43              12 :     if( poSRSIn == NULL )
      44              10 :         poSRS = NULL;
      45                 :     else
      46               2 :         poSRS = poSRSIn->Clone();
      47                 :     
      48              12 :     iNextReadFID = 0;
      49              12 :     iNextCreateFID = 0;
      50                 : 
      51              12 :     nFeatureCount = 0;
      52              12 :     nMaxFeatureCount = 0;
      53              12 :     papoFeatures = NULL;
      54                 : 
      55              12 :     poFeatureDefn = new OGRFeatureDefn( pszName );
      56              12 :     poFeatureDefn->SetGeomType( eReqType );
      57              12 :     poFeatureDefn->Reference();
      58              12 : }
      59                 : 
      60                 : /************************************************************************/
      61                 : /*                           ~OGRMemLayer()                           */
      62                 : /************************************************************************/
      63                 : 
      64              24 : OGRMemLayer::~OGRMemLayer()
      65                 : 
      66                 : {
      67              12 :     if( m_nFeaturesRead > 0 && poFeatureDefn != NULL )
      68                 :     {
      69                 :         CPLDebug( "Mem", "%d features read on layer '%s'.",
      70                 :                   (int) m_nFeaturesRead, 
      71               8 :                   poFeatureDefn->GetName() );
      72                 :     }
      73                 : 
      74             312 :     for( int i = 0; i < nMaxFeatureCount; i++ )
      75                 :     {
      76             300 :         if( papoFeatures[i] != NULL )
      77             185 :             delete papoFeatures[i];
      78                 :     }
      79              12 :     CPLFree( papoFeatures );
      80                 : 
      81              12 :     if( poFeatureDefn )
      82              12 :         poFeatureDefn->Release();
      83                 : 
      84              12 :     if( poSRS )
      85               2 :         poSRS->Release();
      86              24 : }
      87                 : 
      88                 : /************************************************************************/
      89                 : /*                            ResetReading()                            */
      90                 : /************************************************************************/
      91                 : 
      92              36 : void OGRMemLayer::ResetReading()
      93                 : 
      94                 : {
      95              36 :     iNextReadFID = 0;
      96              36 : }
      97                 : 
      98                 : /************************************************************************/
      99                 : /*                           GetNextFeature()                           */
     100                 : /************************************************************************/
     101                 : 
     102              99 : OGRFeature *OGRMemLayer::GetNextFeature()
     103                 : 
     104                 : {
     105             594 :     while( iNextReadFID < nMaxFeatureCount )
     106                 :     {
     107             484 :         OGRFeature *poFeature = papoFeatures[iNextReadFID++];
     108                 : 
     109             484 :         if( poFeature == NULL )
     110             111 :             continue;
     111                 : 
     112             373 :         if( (m_poFilterGeom == NULL
     113                 :              || FilterGeometry( poFeature->GetGeometryRef() ) )
     114                 :             && (m_poAttrQuery == NULL
     115                 :                 || m_poAttrQuery->Evaluate( poFeature ) ) )
     116                 :         {
     117              88 :             m_nFeaturesRead++;
     118              88 :             return poFeature->Clone();
     119                 :         }
     120                 :     }
     121                 : 
     122              11 :     return NULL;
     123                 : }
     124                 : 
     125                 : /************************************************************************/
     126                 : /*                           SetNextByIndex()                           */
     127                 : /************************************************************************/
     128                 : 
     129               0 : OGRErr OGRMemLayer::SetNextByIndex( long nIndex )
     130                 : 
     131                 : {
     132               0 :     if( m_poFilterGeom != NULL || m_poAttrQuery != NULL )
     133               0 :         return OGRLayer::SetNextByIndex( nIndex );
     134                 :         
     135               0 :     if (iNextReadFID < 0 || iNextReadFID >= nMaxFeatureCount)
     136               0 :         return OGRERR_FAILURE;
     137                 : 
     138               0 :     iNextReadFID = nIndex;
     139                 : 
     140               0 :     return OGRERR_NONE;
     141                 : }
     142                 : 
     143                 : /************************************************************************/
     144                 : /*                             GetFeature()                             */
     145                 : /************************************************************************/
     146                 : 
     147               3 : OGRFeature *OGRMemLayer::GetFeature( long nFeatureId )
     148                 : 
     149                 : {
     150               3 :     if( nFeatureId < 0 || nFeatureId >= nMaxFeatureCount )
     151               0 :         return NULL;
     152               3 :     else if( papoFeatures[nFeatureId] == NULL )
     153               1 :         return NULL;
     154                 :     else
     155               2 :         return papoFeatures[nFeatureId]->Clone();
     156                 : }
     157                 : 
     158                 : /************************************************************************/
     159                 : /*                             SetFeature()                             */
     160                 : /************************************************************************/
     161                 : 
     162             188 : OGRErr OGRMemLayer::SetFeature( OGRFeature *poFeature )
     163                 : 
     164                 : {
     165             188 :     if( poFeature == NULL )
     166               0 :         return OGRERR_FAILURE;
     167                 : 
     168             188 :     if( poFeature->GetFID() == OGRNullFID )
     169                 :     {
     170             542 :         while( iNextCreateFID < nMaxFeatureCount 
     171             170 :                && papoFeatures[iNextCreateFID] != NULL )
     172               0 :             iNextCreateFID++;
     173             186 :         poFeature->SetFID( iNextCreateFID++ );
     174                 :     }
     175               2 :     else if ( poFeature->GetFID() < OGRNullFID )
     176                 :     {
     177                 :         CPLError(CE_Failure, CPLE_NotSupported,
     178               0 :                  "negative FID are not supported");
     179               0 :         return OGRERR_FAILURE;
     180                 :     }
     181                 : 
     182             188 :     if( poFeature->GetFID() >= nMaxFeatureCount )
     183                 :     {
     184              16 :         int nNewCount = MAX(2*nMaxFeatureCount+10, poFeature->GetFID() + 1 );
     185                 : 
     186                 :         OGRFeature** papoNewFeatures = (OGRFeature **) 
     187              16 :             VSIRealloc( papoFeatures, sizeof(OGRFeature *) * nNewCount);
     188              16 :         if (papoNewFeatures == NULL)
     189                 :         {
     190                 :             CPLError(CE_Failure, CPLE_OutOfMemory,
     191               0 :                      "Cannot allocate array of %d elements", nNewCount);
     192               0 :             return OGRERR_FAILURE;
     193                 :         }
     194              16 :         papoFeatures = papoNewFeatures;
     195                 :         memset( papoFeatures + nMaxFeatureCount, 0, 
     196              16 :                 sizeof(OGRFeature *) * (nNewCount - nMaxFeatureCount) );
     197              16 :         nMaxFeatureCount = nNewCount;
     198                 :     }
     199                 : 
     200             188 :     if( papoFeatures[poFeature->GetFID()] != NULL )
     201                 :     {
     202               2 :         delete papoFeatures[poFeature->GetFID()];
     203               2 :         papoFeatures[poFeature->GetFID()] = NULL;
     204               2 :         nFeatureCount--;
     205                 :     }
     206                 : 
     207             188 :     papoFeatures[poFeature->GetFID()] = poFeature->Clone();
     208             188 :     nFeatureCount++;
     209                 : 
     210             188 :     return OGRERR_NONE;
     211                 : }
     212                 : 
     213                 : /************************************************************************/
     214                 : /*                           CreateFeature()                            */
     215                 : /************************************************************************/
     216                 : 
     217             186 : OGRErr OGRMemLayer::CreateFeature( OGRFeature *poFeature )
     218                 : 
     219                 : {
     220             186 :     if( poFeature->GetFID() != OGRNullFID 
     221                 :         && poFeature->GetFID() >= 0
     222                 :         && poFeature->GetFID() < nMaxFeatureCount )
     223                 :     {
     224               6 :         if( papoFeatures[poFeature->GetFID()] != NULL )
     225               6 :             poFeature->SetFID( OGRNullFID );
     226                 :     }
     227                 : 
     228             186 :     if( poFeature->GetFID() > 10000000 )
     229               0 :         poFeature->SetFID( OGRNullFID );
     230                 : 
     231             186 :     return SetFeature( poFeature );
     232                 : }
     233                 : 
     234                 : /************************************************************************/
     235                 : /*                           DeleteFeature()                            */
     236                 : /************************************************************************/
     237                 : 
     238               1 : OGRErr OGRMemLayer::DeleteFeature( long nFID )
     239                 : 
     240                 : {
     241               2 :     if( nFID < 0 || nFID >= nMaxFeatureCount 
     242               1 :         || papoFeatures[nFID] == NULL )
     243                 :     {
     244               0 :         return OGRERR_FAILURE;
     245                 :     }
     246                 :     else 
     247                 :     {
     248               1 :         delete papoFeatures[nFID];
     249               1 :         papoFeatures[nFID] = NULL;
     250               1 :         nFeatureCount--;
     251               1 :         return OGRERR_NONE;
     252                 :     }
     253                 : }
     254                 : 
     255                 : /************************************************************************/
     256                 : /*                          GetFeatureCount()                           */
     257                 : /*                                                                      */
     258                 : /*      If a spatial filter is in effect, we turn control over to       */
     259                 : /*      the generic counter.  Otherwise we return the total count.      */
     260                 : /*      Eventually we should consider implementing a more efficient     */
     261                 : /*      way of counting features matching a spatial query.              */
     262                 : /************************************************************************/
     263                 : 
     264               9 : int OGRMemLayer::GetFeatureCount( int bForce )
     265                 : 
     266                 : {
     267               9 :     if( m_poFilterGeom != NULL || m_poAttrQuery != NULL )
     268               1 :         return OGRLayer::GetFeatureCount( bForce );
     269                 :     else
     270               8 :         return nFeatureCount;
     271                 : }
     272                 : 
     273                 : /************************************************************************/
     274                 : /*                           TestCapability()                           */
     275                 : /************************************************************************/
     276                 : 
     277               4 : int OGRMemLayer::TestCapability( const char * pszCap )
     278                 : 
     279                 : {
     280               4 :     if( EQUAL(pszCap,OLCRandomRead) )
     281               0 :         return TRUE;
     282                 : 
     283               4 :     else if( EQUAL(pszCap,OLCSequentialWrite) 
     284                 :              || EQUAL(pszCap,OLCRandomWrite) )
     285               3 :         return TRUE;
     286                 : 
     287               1 :     else if( EQUAL(pszCap,OLCFastFeatureCount) )
     288               0 :         return m_poFilterGeom == NULL && m_poAttrQuery == NULL;
     289                 : 
     290               1 :     else if( EQUAL(pszCap,OLCFastSpatialFilter) )
     291               0 :         return FALSE;
     292                 : 
     293               1 :     else if( EQUAL(pszCap,OLCDeleteFeature) )
     294               1 :         return TRUE;
     295                 : 
     296               0 :     else if( EQUAL(pszCap,OLCCreateField) )
     297               0 :         return TRUE;
     298                 : 
     299               0 :     else if( EQUAL(pszCap,OLCFastSetNextByIndex) )
     300               0 :         return m_poFilterGeom == NULL && m_poAttrQuery == NULL;
     301                 : 
     302                 :     else 
     303               0 :         return FALSE;
     304                 : }
     305                 : 
     306                 : /************************************************************************/
     307                 : /*                            CreateField()                             */
     308                 : /************************************************************************/
     309                 : 
     310              14 : OGRErr OGRMemLayer::CreateField( OGRFieldDefn *poField, int bApproxOK )
     311                 : 
     312                 : {
     313                 : /* -------------------------------------------------------------------- */
     314                 : /*      simple case, no features exist yet.                             */
     315                 : /* -------------------------------------------------------------------- */
     316              14 :     if( nFeatureCount == 0 )
     317                 :     {
     318              13 :         poFeatureDefn->AddFieldDefn( poField );
     319              13 :         return OGRERR_NONE;
     320                 :     }
     321                 : 
     322                 : /* -------------------------------------------------------------------- */
     323                 : /*      Add field definition and setup remap definition.                */
     324                 : /* -------------------------------------------------------------------- */
     325                 :     int  *panRemap;
     326                 :     int   i;
     327                 : 
     328               1 :     poFeatureDefn->AddFieldDefn( poField );
     329                 : 
     330               1 :     panRemap = (int *) CPLMalloc(sizeof(int) * poFeatureDefn->GetFieldCount());
     331               6 :     for( i = 0; i < poFeatureDefn->GetFieldCount(); i++ )
     332                 :     {
     333               5 :         if( i < poFeatureDefn->GetFieldCount() - 1 )
     334               4 :             panRemap[i] = i;
     335                 :         else
     336               1 :             panRemap[i] = -1;
     337                 :     }
     338                 : 
     339                 : /* -------------------------------------------------------------------- */
     340                 : /*      Remap all the internal features.  Hopefully there aren't any    */
     341                 : /*      external features referring to our OGRFeatureDefn!              */
     342                 : /* -------------------------------------------------------------------- */
     343              31 :     for( i = 0; i < nMaxFeatureCount; i++ )
     344                 :     {
     345              30 :         if( papoFeatures[i] != NULL )
     346              17 :             papoFeatures[i]->RemapFields( NULL, panRemap );
     347                 :     }
     348                 : 
     349               1 :     CPLFree( panRemap );
     350                 : 
     351               1 :     return OGRERR_NONE;
     352                 : }
     353                 : 
     354                 : /************************************************************************/
     355                 : /*                           GetSpatialRef()                            */
     356                 : /************************************************************************/
     357                 : 
     358               2 : OGRSpatialReference *OGRMemLayer::GetSpatialRef()
     359                 : 
     360                 : {
     361               2 :     return poSRS;
     362                 : }

Generated by: LCOV version 1.7