LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/generic - ogrunionlayer.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 458 418 91.3 %
Date: 2012-12-26 Functions: 33 30 90.9 %

       1                 : /******************************************************************************
       2                 :  * $Id: ogrunionlayer.cpp 24640 2012-07-01 19:37:38Z rouault $
       3                 :  *
       4                 :  * Project:  OpenGIS Simple Features Reference Implementation
       5                 :  * Purpose:  Implements OGRUnionLayer class
       6                 :  * Author:   Even Rouault, even dot rouault at mines dash paris dot org
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 2012, Even Rouault <even dot rouault at mines dash paris dot org>
      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 "ogrunionlayer.h"
      31                 : #include "ogrwarpedlayer.h"
      32                 : #include "ogr_p.h"
      33                 : 
      34                 : CPL_CVSID("$Id: ogrunionlayer.cpp 24640 2012-07-01 19:37:38Z rouault $");
      35                 : 
      36                 : /************************************************************************/
      37                 : /*                          OGRUnionLayer()                             */
      38                 : /************************************************************************/
      39                 : 
      40              59 : OGRUnionLayer::OGRUnionLayer( const char* pszName,
      41                 :                               int nSrcLayersIn,
      42                 :                               OGRLayer** papoSrcLayersIn,
      43              59 :                               int bTakeLayerOwnership )
      44                 : {
      45              59 :     CPLAssert(nSrcLayersIn > 0);
      46                 : 
      47              59 :     osName = pszName;
      48              59 :     nSrcLayers = nSrcLayersIn;
      49              59 :     papoSrcLayers = papoSrcLayersIn;
      50              59 :     bHasLayerOwnership = bTakeLayerOwnership;
      51                 : 
      52              59 :     poFeatureDefn = NULL;
      53              59 :     nFields = 0;
      54              59 :     papoFields = NULL;
      55              59 :     eFieldStrategy = FIELD_UNION_ALL_LAYERS;
      56                 : 
      57              59 :     eGeomType = wkbUnknown;
      58              59 :     eGeometryTypeStrategy = GEOMTYPE_UNION_ALL_LAYERS;
      59                 : 
      60              59 :     bPreserveSrcFID = FALSE;
      61                 : 
      62              59 :     nFeatureCount = -1;
      63                 : 
      64              59 :     poSRS = NULL;
      65              59 :     bSRSSet = FALSE;
      66                 : 
      67              59 :     iCurLayer = -1;
      68              59 :     pszAttributeFilter = NULL;
      69              59 :     nNextFID = 0;
      70              59 :     panMap = NULL;
      71              59 :     papszIgnoredFields = NULL;
      72              59 :     bAttrFilterPassThroughValue = -1;
      73                 : 
      74              59 :     pabModifiedLayers = (int*)CPLCalloc(sizeof(int), nSrcLayers);
      75              59 :     pabCheckIfAutoWrap = (int*)CPLCalloc(sizeof(int), nSrcLayers);
      76              59 : }
      77                 : 
      78                 : /************************************************************************/
      79                 : /*                         ~OGRUnionLayer()                             */
      80                 : /************************************************************************/
      81                 : 
      82              59 : OGRUnionLayer::~OGRUnionLayer()
      83                 : {
      84                 :     int i;
      85                 : 
      86              59 :     if( bHasLayerOwnership )
      87                 :     {
      88             177 :         for(i = 0; i < nSrcLayers; i++)
      89             118 :             delete papoSrcLayers[i];
      90                 :     }
      91              59 :     CPLFree(papoSrcLayers);
      92                 : 
      93              59 :     for(i = 0; i < nFields; i++)
      94               0 :         delete papoFields[i];
      95              59 :     CPLFree(papoFields);
      96                 : 
      97              59 :     CPLFree(pszAttributeFilter);
      98              59 :     CPLFree(panMap);
      99              59 :     CSLDestroy(papszIgnoredFields);
     100              59 :     CPLFree(pabModifiedLayers);
     101              59 :     CPLFree(pabCheckIfAutoWrap);
     102                 : 
     103              59 :     if( poSRS != NULL )
     104               9 :         poSRS->Release();
     105                 : 
     106              59 :     if( poFeatureDefn )
     107              50 :         poFeatureDefn->Release();
     108              59 : }
     109                 : 
     110                 : /************************************************************************/
     111                 : /*                               SetSRS()                               */
     112                 : /************************************************************************/
     113                 : 
     114               9 : void OGRUnionLayer::SetSRS(OGRSpatialReference *poSRSIn)
     115                 : {
     116               9 :     CPLAssert(poFeatureDefn == NULL);
     117                 : 
     118               9 :     bSRSSet = TRUE;
     119               9 :     if( poSRS )
     120               0 :         poSRS->Release();
     121               9 :     poSRS = (poSRSIn != NULL) ? poSRSIn->Clone() : NULL;
     122               9 : }
     123                 : 
     124                 : /************************************************************************/
     125                 : /*                              SetFields()                             */
     126                 : /************************************************************************/
     127                 : 
     128              57 : void OGRUnionLayer::SetFields(FieldUnionStrategy eFieldStrategyIn,
     129                 :                               int nFieldsIn,
     130                 :                               OGRFieldDefn** papoFieldsIn)
     131                 : {
     132              57 :     CPLAssert(nFields == 0);
     133              57 :     CPLAssert(poFeatureDefn == NULL);
     134                 : 
     135              57 :     eFieldStrategy = eFieldStrategyIn;
     136              57 :     if( nFieldsIn )
     137                 :     {
     138               0 :         nFields = nFieldsIn;
     139               0 :         papoFields = (OGRFieldDefn** )CPLMalloc(nFields * sizeof(OGRFieldDefn*));
     140               0 :         for(int i=0;i<nFields;i++)
     141               0 :             papoFields[i] = new OGRFieldDefn(papoFieldsIn[i]);
     142                 :     }
     143              57 : }
     144                 : 
     145                 : /************************************************************************/
     146                 : /*                          SetGeometryType()                           */
     147                 : /************************************************************************/
     148                 : 
     149              57 : void OGRUnionLayer::SetGeometryType(GeometryTypeUnionStrategy
     150                 :                                                     eGeometryTypeStrategyIn,
     151                 :                                     OGRwkbGeometryType eGeomTypeIn)
     152                 : {
     153              57 :     CPLAssert(poFeatureDefn == NULL);
     154                 : 
     155              57 :     eGeometryTypeStrategy = eGeometryTypeStrategyIn;
     156              57 :     eGeomType = eGeomTypeIn;
     157              57 : }
     158                 : 
     159                 : /************************************************************************/
     160                 : /*                        SetSourceLayerFieldName()                     */
     161                 : /************************************************************************/
     162                 : 
     163              57 : void OGRUnionLayer::SetSourceLayerFieldName(const char* pszSourceLayerFieldName)
     164                 : {
     165              57 :     CPLAssert(poFeatureDefn == NULL);
     166                 : 
     167              57 :     CPLAssert(osSourceLayerFieldName.size() == 0);
     168              57 :     if( pszSourceLayerFieldName != NULL )
     169               9 :         osSourceLayerFieldName = pszSourceLayerFieldName;
     170              57 : }
     171                 : 
     172                 : /************************************************************************/
     173                 : /*                           SetPreserveSrcFID()                        */
     174                 : /************************************************************************/
     175                 : 
     176              57 : void OGRUnionLayer::SetPreserveSrcFID(int bPreserveSrcFIDIn)
     177                 : {
     178              57 :     CPLAssert(poFeatureDefn == NULL);
     179                 : 
     180              57 :     bPreserveSrcFID = bPreserveSrcFIDIn;
     181              57 : }
     182                 : 
     183                 : /************************************************************************/
     184                 : /*                          SetFeatureCount()                           */
     185                 : /************************************************************************/
     186                 : 
     187               9 : void OGRUnionLayer::SetFeatureCount(int nFeatureCountIn)
     188                 : {
     189               9 :     CPLAssert(poFeatureDefn == NULL);
     190                 : 
     191               9 :     nFeatureCount = nFeatureCountIn;
     192               9 : }
     193                 : 
     194                 : /************************************************************************/
     195                 : /*                              SetExtent()                             */
     196                 : /************************************************************************/
     197                 : 
     198               9 : void OGRUnionLayer::SetExtent( double dfXMin, double dfYMin,
     199                 :                                double dfXMax, double dfYMax )
     200                 : {
     201               9 :     CPLAssert(poFeatureDefn == NULL);
     202                 : 
     203               9 :     sStaticEnvelope.MinX = dfXMin;
     204               9 :     sStaticEnvelope.MinY = dfYMin;
     205               9 :     sStaticEnvelope.MaxX = dfXMax;
     206               9 :     sStaticEnvelope.MaxY = dfYMax;
     207               9 : }
     208                 : 
     209                 : /************************************************************************/
     210                 : /*                         MergeFieldDefn()                             */
     211                 : /************************************************************************/
     212                 : 
     213              16 : static void MergeFieldDefn(OGRFieldDefn* poFieldDefn,
     214                 :                            OGRFieldDefn* poSrcFieldDefn)
     215                 : {
     216              16 :     if( poFieldDefn->GetType() != poSrcFieldDefn->GetType() )
     217                 :     {
     218               2 :         if( poSrcFieldDefn->GetType() == OFTReal &&
     219                 :             poFieldDefn->GetType() == OFTInteger)
     220               0 :             poFieldDefn->SetType(OFTReal);
     221                 :         else
     222               2 :             poFieldDefn->SetType(OFTString);
     223                 :     }
     224                 : 
     225              16 :     if( poFieldDefn->GetWidth() != poSrcFieldDefn->GetWidth() ||
     226                 :         poFieldDefn->GetPrecision() != poSrcFieldDefn->GetPrecision() )
     227                 :     {
     228               4 :         poFieldDefn->SetWidth(0);
     229               4 :         poFieldDefn->SetPrecision(0);
     230                 :     }
     231              16 : }
     232                 : 
     233                 : /************************************************************************/
     234                 : /*                             GetLayerDefn()                           */
     235                 : /************************************************************************/
     236                 : 
     237             293 : OGRFeatureDefn *OGRUnionLayer::GetLayerDefn()
     238                 : {
     239             293 :     if( poFeatureDefn != NULL )
     240             243 :         return poFeatureDefn;
     241                 : 
     242              50 :     poFeatureDefn = new OGRFeatureDefn( osName );
     243              50 :     poFeatureDefn->Reference();
     244                 : 
     245              50 :     int iCompareFirstIndex = 0;
     246              50 :     if( osSourceLayerFieldName.size() )
     247                 :     {
     248               4 :         OGRFieldDefn oField(osSourceLayerFieldName, OFTString);
     249               4 :         poFeatureDefn->AddFieldDefn(&oField);
     250               4 :         iCompareFirstIndex = 1;
     251                 :     }
     252                 : 
     253              50 :     if( eFieldStrategy == FIELD_SPECIFIED )
     254                 :     {
     255               0 :         for(int i = 0; i < nFields; i++)
     256               0 :             poFeatureDefn->AddFieldDefn(papoFields[i]);
     257                 :     }
     258              50 :     else if( eFieldStrategy == FIELD_FROM_FIRST_LAYER )
     259                 :     {
     260               0 :         OGRFeatureDefn* poSrcFeatureDefn = papoSrcLayers[0]->GetLayerDefn();
     261               0 :         for(int i = 0; i < poSrcFeatureDefn->GetFieldCount(); i++)
     262               0 :             poFeatureDefn->AddFieldDefn(poSrcFeatureDefn->GetFieldDefn(i));
     263                 :     }
     264              50 :     else if (eFieldStrategy == FIELD_UNION_ALL_LAYERS )
     265                 :     {
     266             138 :         for(int iLayer = 0; iLayer < nSrcLayers; iLayer++)
     267                 :         {
     268                 :             OGRFeatureDefn* poSrcFeatureDefn =
     269              92 :                                 papoSrcLayers[iLayer]->GetLayerDefn();
     270                 : 
     271                 :             /* Add any field that is found in the source layers */
     272             142 :             for(int i = 0; i < poSrcFeatureDefn->GetFieldCount(); i++)
     273                 :             {
     274              50 :                 OGRFieldDefn* poSrcFieldDefn = poSrcFeatureDefn->GetFieldDefn(i);
     275                 :                 int nIndex =
     276              50 :                     poFeatureDefn->GetFieldIndex(poSrcFieldDefn->GetNameRef());
     277              50 :                 if( nIndex < 0 )
     278              38 :                     poFeatureDefn->AddFieldDefn(poSrcFieldDefn);
     279                 :                 else
     280                 :                 {
     281                 :                     OGRFieldDefn* poFieldDefn =
     282              12 :                                         poFeatureDefn->GetFieldDefn(nIndex);
     283              12 :                     MergeFieldDefn(poFieldDefn, poSrcFieldDefn);
     284                 :                 }
     285                 :             }
     286                 :         }
     287                 :     }
     288               4 :     else if (eFieldStrategy == FIELD_INTERSECTION_ALL_LAYERS )
     289                 :     {
     290               4 :         OGRFeatureDefn* poSrcFeatureDefn = papoSrcLayers[0]->GetLayerDefn();
     291                 :         int i;
     292              12 :         for(i = 0; i < poSrcFeatureDefn->GetFieldCount(); i++)
     293               8 :             poFeatureDefn->AddFieldDefn(poSrcFeatureDefn->GetFieldDefn(i));
     294                 : 
     295                 :         /* Remove any field that is not found in the source layers */
     296               8 :         for(int iLayer = 1; iLayer < nSrcLayers; iLayer++)
     297                 :         {
     298                 :             OGRFeatureDefn* poSrcFeatureDefn =
     299               4 :                                         papoSrcLayers[iLayer]->GetLayerDefn();
     300              16 :             for(i = iCompareFirstIndex; i < poFeatureDefn->GetFieldCount();)
     301                 :             {
     302               8 :                 OGRFieldDefn* poFieldDefn = poFeatureDefn->GetFieldDefn(i);
     303                 :                 int nSrcIndex = poSrcFeatureDefn->GetFieldIndex(
     304               8 :                                                     poFieldDefn->GetNameRef());
     305               8 :                 if( nSrcIndex < 0 )
     306                 :                 {
     307               4 :                     poFeatureDefn->DeleteFieldDefn(i);
     308                 :                 }
     309                 :                 else
     310                 :                 {
     311                 :                     OGRFieldDefn* poSrcFieldDefn =
     312               4 :                         poSrcFeatureDefn->GetFieldDefn(nSrcIndex);
     313               4 :                     MergeFieldDefn(poFieldDefn, poSrcFieldDefn);
     314                 : 
     315               4 :                     i ++;
     316                 :                 }
     317                 :             }
     318                 :         }
     319                 :     }
     320                 : 
     321              50 :     poFeatureDefn->SetGeomType(GetGeomType());
     322                 : 
     323              50 :     return poFeatureDefn;
     324                 : }
     325                 : 
     326                 : /************************************************************************/
     327                 : /*                             GetGeomType()                            */
     328                 : /************************************************************************/
     329                 : 
     330              89 : OGRwkbGeometryType OGRUnionLayer::GetGeomType()
     331                 : {
     332              89 :     if( eGeometryTypeStrategy == GEOMTYPE_SPECIFIED )
     333              42 :         return eGeomType;
     334                 : 
     335              47 :     if( eGeometryTypeStrategy == GEOMTYPE_FROM_FIRST_LAYER )
     336                 :     {
     337               0 :         eGeomType = papoSrcLayers[0]->GetGeomType();
     338                 :     }
     339              47 :     else if( eGeometryTypeStrategy == GEOMTYPE_UNION_ALL_LAYERS )
     340                 :     {
     341              47 :         eGeomType = papoSrcLayers[0]->GetGeomType();
     342              94 :         for(int iLayer = 1; iLayer < nSrcLayers; iLayer++)
     343                 :         {
     344                 :             OGRwkbGeometryType eSrcGeomType =
     345              47 :                                     papoSrcLayers[iLayer]->GetGeomType();
     346              47 :             eGeomType = OGRMergeGeometryTypes(eGeomType, eSrcGeomType);
     347                 :         }
     348                 :     }
     349              47 :     eGeometryTypeStrategy = GEOMTYPE_SPECIFIED;
     350                 : 
     351              47 :     return eGeomType;
     352                 : }
     353                 : 
     354                 : /************************************************************************/
     355                 : /*                        ConfigureActiveLayer()                        */
     356                 : /************************************************************************/
     357                 : 
     358             129 : void OGRUnionLayer::ConfigureActiveLayer()
     359                 : {
     360             129 :     AutoWarpLayerIfNecessary(iCurLayer);
     361             129 :     ApplyAttributeFilterToSrcLayer(iCurLayer);
     362             129 :     papoSrcLayers[iCurLayer]->SetSpatialFilter(m_poFilterGeom);
     363             129 :     papoSrcLayers[iCurLayer]->ResetReading();
     364                 : 
     365                 :     /* Establish map */
     366             129 :     OGRFeatureDefn* poFeatureDefn = GetLayerDefn();
     367             129 :     OGRFeatureDefn* poSrcFeatureDefn = papoSrcLayers[iCurLayer]->GetLayerDefn();
     368             129 :     CPLFree(panMap);
     369             129 :     panMap = (int*) CPLMalloc(poSrcFeatureDefn->GetFieldCount() * sizeof(int));
     370             375 :     for(int i=0; i < poSrcFeatureDefn->GetFieldCount(); i++)
     371                 :     {
     372             246 :         OGRFieldDefn* poSrcFieldDefn = poSrcFeatureDefn->GetFieldDefn(i);
     373             246 :         if( CSLFindString(papszIgnoredFields,
     374                 :                           poSrcFieldDefn->GetNameRef() ) == -1 )
     375                 :         {
     376             236 :             panMap[i] =
     377             236 :                 poFeatureDefn->GetFieldIndex(poSrcFieldDefn->GetNameRef());
     378                 :         }
     379                 :         else
     380                 :         {
     381              10 :             panMap[i] = -1;
     382                 :         }
     383                 :     }
     384                 : 
     385             129 :     if( papoSrcLayers[iCurLayer]->TestCapability(OLCIgnoreFields) )
     386                 :     {
     387             122 :         char** papszIter = papszIgnoredFields;
     388             122 :         char** papszFieldsSrc = NULL;
     389             264 :         while ( papszIter != NULL && *papszIter != NULL )
     390                 :         {
     391              20 :             const char* pszFieldName = *papszIter;
     392              20 :             if ( EQUAL(pszFieldName, "OGR_GEOMETRY") ||
     393                 :                  EQUAL(pszFieldName, "OGR_STYLE") ||
     394                 :                  poSrcFeatureDefn->GetFieldIndex(pszFieldName) >= 0 )
     395                 :             {
     396              14 :                 papszFieldsSrc = CSLAddString(papszFieldsSrc, pszFieldName);
     397                 :             }
     398              20 :             papszIter++;
     399                 :         }
     400                 : 
     401                 :         int* panSrcFieldsUsed = (int*) CPLCalloc(sizeof(int),
     402             122 :                                           poSrcFeatureDefn->GetFieldCount());
     403             475 :         for(int iField = 0;
     404                 :                 iField < poFeatureDefn->GetFieldCount(); iField++)
     405                 :         {
     406             353 :             OGRFieldDefn* poFieldDefn = poFeatureDefn->GetFieldDefn(iField);
     407                 :             int iSrcField =
     408             353 :                     poSrcFeatureDefn->GetFieldIndex(poFieldDefn->GetNameRef());
     409             353 :             if (iSrcField >= 0)
     410             232 :                 panSrcFieldsUsed[iSrcField] = TRUE;
     411                 :         }
     412             364 :         for(int iSrcField = 0;
     413                 :                 iSrcField < poSrcFeatureDefn->GetFieldCount(); iSrcField ++)
     414                 :         {
     415             242 :             if( !panSrcFieldsUsed[iSrcField] )
     416                 :             {
     417                 :                 OGRFieldDefn *poSrcDefn =
     418              10 :                         poSrcFeatureDefn->GetFieldDefn( iSrcField );
     419                 :                 papszFieldsSrc =
     420              10 :                         CSLAddString(papszFieldsSrc, poSrcDefn->GetNameRef());
     421                 :             }
     422                 :         }
     423             122 :         CPLFree(panSrcFieldsUsed);
     424                 : 
     425             122 :         papoSrcLayers[iCurLayer]->SetIgnoredFields((const char**)papszFieldsSrc);
     426                 : 
     427             122 :         CSLDestroy(papszFieldsSrc);
     428                 :     }
     429             129 : }
     430                 : 
     431                 : /************************************************************************/
     432                 : /*                             ResetReading()                           */
     433                 : /************************************************************************/
     434                 : 
     435              97 : void OGRUnionLayer::ResetReading()
     436                 : {
     437              97 :     iCurLayer = 0;
     438              97 :     ConfigureActiveLayer();
     439              97 :     nNextFID = 0;
     440              97 : }
     441                 : 
     442                 : /************************************************************************/
     443                 : /*                         AutoWarpLayerIfNecessary()                   */
     444                 : /************************************************************************/
     445                 : 
     446             187 : void OGRUnionLayer::AutoWarpLayerIfNecessary(int iLayer)
     447                 : {
     448             187 :     if( !pabCheckIfAutoWrap[iLayer] )
     449                 :     {
     450              38 :         pabCheckIfAutoWrap[iLayer] = TRUE;
     451                 : 
     452              38 :         OGRSpatialReference* poSRS = GetSpatialRef();
     453              38 :         if( poSRS != NULL )
     454              26 :             poSRS->Reference();
     455                 : 
     456              38 :         OGRSpatialReference* poSRS2 = papoSrcLayers[iLayer]->GetSpatialRef();
     457                 : 
     458              38 :         if( (poSRS == NULL && poSRS2 != NULL) ||
     459                 :             (poSRS != NULL && poSRS2 == NULL) )
     460                 :         {
     461                 :             CPLError(CE_Warning, CPLE_AppDefined,
     462                 :                     "SRS of layer %s not consistant with layer SRS",
     463               0 :                     papoSrcLayers[iLayer]->GetName());
     464                 :         }
     465              38 :         else if (poSRS != NULL && poSRS2 != NULL &&
     466                 :                  poSRS != poSRS2 && !poSRS->IsSame(poSRS2))
     467                 :         {
     468                 :             CPLDebug("VRT", "SRS of layer %s not consistant with layer SRS. "
     469                 :                      "Trying auto warping",
     470               8 :                      papoSrcLayers[iLayer]->GetName());
     471                 :             OGRCoordinateTransformation* poCT =
     472               8 :                 OGRCreateCoordinateTransformation( poSRS2, poSRS );
     473                 :             OGRCoordinateTransformation* poReversedCT = (poCT != NULL) ?
     474               8 :                 OGRCreateCoordinateTransformation( poSRS, poSRS2 ) : NULL;
     475               8 :             if( poCT != NULL && poReversedCT != NULL )
     476               8 :                 papoSrcLayers[iLayer] = new OGRWarpedLayer(
     477               8 :                             papoSrcLayers[iLayer], TRUE, poCT, poReversedCT);
     478                 :         }
     479                 : 
     480              38 :         if( poSRS != NULL )
     481              26 :             poSRS->Release();
     482                 :     }
     483             187 : }
     484                 : 
     485                 : /************************************************************************/
     486                 : /*                           GetNextFeature()                           */
     487                 : /************************************************************************/
     488                 : 
     489            1040 : OGRFeature *OGRUnionLayer::GetNextFeature()
     490                 : {
     491            1040 :     if( poFeatureDefn == NULL ) GetLayerDefn();
     492            1040 :     if( iCurLayer < 0 )
     493               2 :         ResetReading();
     494                 : 
     495            1040 :     if( iCurLayer == nSrcLayers )
     496               0 :         return NULL;
     497                 : 
     498             333 :     while(TRUE)
     499                 :     {
     500            1373 :         OGRFeature* poSrcFeature = papoSrcLayers[iCurLayer]->GetNextFeature();
     501            1373 :         if( poSrcFeature == NULL )
     502                 :         {
     503              62 :             iCurLayer ++;
     504              62 :             if( iCurLayer < nSrcLayers )
     505                 :             {
     506              32 :                 ConfigureActiveLayer();
     507              32 :                 continue;
     508                 :             }
     509                 :             else
     510                 :                 break;
     511                 :         }
     512                 : 
     513            1311 :         OGRFeature* poFeature = TranslateFromSrcLayer(poSrcFeature);
     514            1311 :         delete poSrcFeature;
     515                 : 
     516            1311 :         if( (m_poFilterGeom == NULL ||
     517                 :              FilterGeometry( poFeature->GetGeometryRef() ) ) &&
     518                 :             (m_poAttrQuery == NULL ||
     519                 :              m_poAttrQuery->Evaluate( poFeature )) )
     520                 :         {
     521            1010 :             return poFeature;
     522                 :         }
     523                 : 
     524             301 :         delete poFeature;
     525                 :     }
     526              30 :     return NULL;
     527                 : }
     528                 : 
     529                 : /************************************************************************/
     530                 : /*                             GetFeature()                             */
     531                 : /************************************************************************/
     532                 : 
     533               4 : OGRFeature *OGRUnionLayer::GetFeature( long nFeatureId )
     534                 : {
     535               4 :     if( !bPreserveSrcFID )
     536               4 :         return OGRLayer::GetFeature(nFeatureId);
     537                 : 
     538               0 :     for(int i=0;i<nSrcLayers;i++)
     539                 :     {
     540               0 :         iCurLayer = i;
     541               0 :         ConfigureActiveLayer();
     542                 : 
     543               0 :         OGRFeature* poSrcFeature = papoSrcLayers[i]->GetFeature(nFeatureId);
     544               0 :         if( poSrcFeature != NULL )
     545                 :         {
     546               0 :             OGRFeature* poFeature = TranslateFromSrcLayer(poSrcFeature);
     547               0 :             delete poSrcFeature;
     548                 : 
     549               0 :             return poFeature;
     550                 :         }
     551                 :     }
     552                 : 
     553               0 :     ResetReading();
     554                 : 
     555               0 :     return NULL;
     556                 : }
     557                 : 
     558                 : /************************************************************************/
     559                 : /*                          CreateFeature()                             */
     560                 : /************************************************************************/
     561                 : 
     562               5 : OGRErr OGRUnionLayer::CreateFeature( OGRFeature* poFeature )
     563                 : {
     564               5 :     if( osSourceLayerFieldName.size() == 0 )
     565                 :     {
     566                 :         CPLError(CE_Failure, CPLE_NotSupported,
     567               1 :                  "CreateFeature() not supported when SourceLayerFieldName is not set");
     568               1 :         return OGRERR_FAILURE;
     569                 :     }
     570                 : 
     571               4 :     if( poFeature->GetFID() != OGRNullFID )
     572                 :     {
     573                 :         CPLError(CE_Failure, CPLE_NotSupported,
     574               1 :                  "CreateFeature() not supported when FID is set");
     575               1 :         return OGRERR_FAILURE;
     576                 :     }
     577                 : 
     578               3 :     if( !poFeature->IsFieldSet(0) )
     579                 :     {
     580                 :         CPLError(CE_Failure, CPLE_NotSupported,
     581                 :                  "CreateFeature() not supported when '%s' field is not set",
     582               1 :                  osSourceLayerFieldName.c_str());
     583               1 :         return OGRERR_FAILURE;
     584                 :     }
     585                 : 
     586               2 :     const char* pszSrcLayerName = poFeature->GetFieldAsString(0);
     587               5 :     for(int i=0;i<nSrcLayers;i++)
     588                 :     {
     589               4 :         if( strcmp(pszSrcLayerName, papoSrcLayers[i]->GetName()) == 0)
     590                 :         {
     591               1 :             pabModifiedLayers[i] = TRUE;
     592                 : 
     593                 :             OGRFeature* poSrcFeature =
     594               1 :                         new OGRFeature(papoSrcLayers[i]->GetLayerDefn());
     595               1 :             poSrcFeature->SetFrom(poFeature, TRUE);
     596               1 :             OGRErr eErr = papoSrcLayers[i]->CreateFeature(poSrcFeature);
     597               1 :             if( eErr == OGRERR_NONE )
     598               1 :                 poFeature->SetFID(poSrcFeature->GetFID());
     599               1 :             delete poSrcFeature;
     600               1 :             return eErr;
     601                 :         }
     602                 :     }
     603                 : 
     604                 :     CPLError(CE_Failure, CPLE_NotSupported,
     605                 :              "CreateFeature() not supported : '%s' source layer does not exist",
     606               1 :              pszSrcLayerName);
     607               1 :     return OGRERR_FAILURE;
     608                 : }
     609                 : 
     610                 : /************************************************************************/
     611                 : /*                             SetFeature()                             */
     612                 : /************************************************************************/
     613                 : 
     614               5 : OGRErr OGRUnionLayer::SetFeature( OGRFeature* poFeature )
     615                 : {
     616               5 :     if( !bPreserveSrcFID )
     617                 :     {
     618                 :         CPLError(CE_Failure, CPLE_NotSupported,
     619               1 :                  "SetFeature() not supported when PreserveSrcFID is OFF");
     620               1 :         return OGRERR_FAILURE;
     621                 :     }
     622                 : 
     623               4 :     if( osSourceLayerFieldName.size() == 0 )
     624                 :     {
     625                 :         CPLError(CE_Failure, CPLE_NotSupported,
     626               0 :                  "SetFeature() not supported when SourceLayerFieldName is not set");
     627               0 :         return OGRERR_FAILURE;
     628                 :     }
     629                 : 
     630               4 :     if( poFeature->GetFID() == OGRNullFID )
     631                 :     {
     632                 :         CPLError(CE_Failure, CPLE_NotSupported,
     633               1 :                  "SetFeature() not supported when FID is not set");
     634               1 :         return OGRERR_FAILURE;
     635                 :     }
     636                 : 
     637               3 :     if( !poFeature->IsFieldSet(0) )
     638                 :     {
     639                 :         CPLError(CE_Failure, CPLE_NotSupported,
     640                 :                  "SetFeature() not supported when '%s' field is not set",
     641               1 :                  osSourceLayerFieldName.c_str());
     642               1 :         return OGRERR_FAILURE;
     643                 :     }
     644                 : 
     645               2 :     const char* pszSrcLayerName = poFeature->GetFieldAsString(0);
     646               5 :     for(int i=0;i<nSrcLayers;i++)
     647                 :     {
     648               4 :         if( strcmp(pszSrcLayerName, papoSrcLayers[i]->GetName()) == 0)
     649                 :         {
     650               1 :             pabModifiedLayers[i] = TRUE;
     651                 : 
     652                 :             OGRFeature* poSrcFeature =
     653               1 :                         new OGRFeature(papoSrcLayers[i]->GetLayerDefn());
     654               1 :             poSrcFeature->SetFrom(poFeature, TRUE);
     655               1 :             poSrcFeature->SetFID(poFeature->GetFID());
     656               1 :             OGRErr eErr = papoSrcLayers[i]->SetFeature(poSrcFeature);
     657               2 :             delete poSrcFeature;
     658               1 :             return eErr;
     659                 :         }
     660                 :     }
     661                 : 
     662                 :     CPLError(CE_Failure, CPLE_NotSupported,
     663                 :              "SetFeature() not supported : '%s' source layer does not exist",
     664               1 :              pszSrcLayerName);
     665               1 :     return OGRERR_FAILURE;
     666                 : }
     667                 : 
     668                 : /************************************************************************/
     669                 : /*                           GetSpatialRef()                            */
     670                 : /************************************************************************/
     671                 : 
     672            1286 : OGRSpatialReference *OGRUnionLayer::GetSpatialRef()
     673                 : {
     674            1286 :     if( bSRSSet )
     675             109 :         return poSRS;
     676                 :     else
     677            1177 :         return papoSrcLayers[0]->GetSpatialRef();
     678                 : }
     679                 : 
     680                 : /************************************************************************/
     681                 : /*                      GetAttrFilterPassThroughValue()                 */
     682                 : /************************************************************************/
     683                 : 
     684             224 : int OGRUnionLayer::GetAttrFilterPassThroughValue()
     685                 : {
     686             224 :     if( m_poAttrQuery == NULL )
     687             164 :         return TRUE;
     688                 : 
     689              60 :     if( bAttrFilterPassThroughValue >= 0)
     690              50 :         return bAttrFilterPassThroughValue;
     691                 : 
     692              10 :     char** papszUsedFields = m_poAttrQuery->GetUsedFields();
     693              10 :     int bRet = TRUE;
     694                 : 
     695              30 :     for(int iLayer = 0; iLayer < nSrcLayers; iLayer++)
     696                 :     {
     697                 :         OGRFeatureDefn* poSrcFeatureDefn =
     698              20 :                                 papoSrcLayers[iLayer]->GetLayerDefn();
     699              20 :         char** papszIter = papszUsedFields;
     700              55 :         while( papszIter != NULL && *papszIter != NULL )
     701                 :         {
     702              22 :             int bIsSpecial = FALSE;
     703             116 :             for(int i = 0; i < SPECIAL_FIELD_COUNT; i++)
     704                 :             {
     705              98 :                 if( EQUAL(*papszIter, SpecialFieldNames[i]) )
     706                 :                 {
     707               4 :                     bIsSpecial = TRUE;
     708               4 :                     break;
     709                 :                 }
     710                 :             }
     711              22 :             if( !bIsSpecial &&
     712                 :                 poSrcFeatureDefn->GetFieldIndex(*papszIter) < 0 )
     713                 :             {
     714               7 :                 bRet = FALSE;
     715               7 :                 break;
     716                 :             }
     717              15 :             papszIter ++;
     718                 :         }
     719                 :     }
     720                 : 
     721              10 :     CSLDestroy(papszUsedFields);
     722                 : 
     723              10 :     bAttrFilterPassThroughValue = bRet;
     724                 : 
     725              10 :     return bRet;
     726                 : }
     727                 : 
     728                 : /************************************************************************/
     729                 : /*                  ApplyAttributeFilterToSrcLayer()                    */
     730                 : /************************************************************************/
     731                 : 
     732             195 : void OGRUnionLayer::ApplyAttributeFilterToSrcLayer(int iSubLayer)
     733                 : {
     734             195 :     CPLAssert(iSubLayer >= 0 && iSubLayer < nSrcLayers);
     735                 : 
     736             195 :     if( GetAttrFilterPassThroughValue() )
     737             160 :         papoSrcLayers[iSubLayer]->SetAttributeFilter(pszAttributeFilter);
     738                 :     else
     739              35 :         papoSrcLayers[iSubLayer]->SetAttributeFilter(NULL);
     740             195 : }
     741                 : 
     742                 : /************************************************************************/
     743                 : /*                          GetFeatureCount()                           */
     744                 : /************************************************************************/
     745                 : 
     746              27 : int OGRUnionLayer::GetFeatureCount( int bForce )
     747                 : {
     748              27 :     if (nFeatureCount >= 0 &&
     749                 :         m_poFilterGeom == NULL && m_poAttrQuery == NULL)
     750                 :     {
     751               1 :         return nFeatureCount;
     752                 :     }
     753                 : 
     754              26 :     if( !GetAttrFilterPassThroughValue() )
     755               5 :         return OGRLayer::GetFeatureCount(bForce);
     756                 : 
     757              21 :     int nRet = 0;
     758              63 :     for(int i = 0; i < nSrcLayers; i++)
     759                 :     {
     760              42 :         AutoWarpLayerIfNecessary(i);
     761              42 :         ApplyAttributeFilterToSrcLayer(i);
     762              42 :         papoSrcLayers[i]->SetSpatialFilter(m_poFilterGeom);
     763              42 :         nRet += papoSrcLayers[i]->GetFeatureCount(bForce);
     764                 :     }
     765              21 :     ResetReading();
     766              21 :     return nRet;
     767                 : }
     768                 : 
     769                 : /************************************************************************/
     770                 : /*                         SetAttributeFilter()                         */
     771                 : /************************************************************************/
     772                 : 
     773              24 : OGRErr OGRUnionLayer::SetAttributeFilter( const char * pszAttributeFilterIn )
     774                 : {
     775              24 :     if( pszAttributeFilterIn == NULL && pszAttributeFilter == NULL)
     776               8 :         return OGRERR_NONE;
     777              16 :     if( pszAttributeFilterIn != NULL && pszAttributeFilter != NULL &&
     778                 :         strcmp(pszAttributeFilterIn, pszAttributeFilter) == 0)
     779               0 :         return OGRERR_NONE;
     780                 : 
     781              16 :     if( poFeatureDefn == NULL ) GetLayerDefn();
     782                 : 
     783              16 :     bAttrFilterPassThroughValue = -1;
     784                 : 
     785              16 :     OGRErr eErr = OGRLayer::SetAttributeFilter(pszAttributeFilterIn);
     786              16 :     if( eErr != OGRERR_NONE )
     787               0 :         return eErr;
     788                 : 
     789              16 :     CPLFree(pszAttributeFilter);
     790                 :     pszAttributeFilter = pszAttributeFilterIn ?
     791              16 :                                 CPLStrdup(pszAttributeFilterIn) : NULL;
     792                 : 
     793              16 :     if( iCurLayer >= 0 && iCurLayer < nSrcLayers)
     794              16 :         ApplyAttributeFilterToSrcLayer(iCurLayer);
     795                 : 
     796              16 :     return OGRERR_NONE;
     797                 : }
     798                 : 
     799                 : /************************************************************************/
     800                 : /*                           TestCapability()                           */
     801                 : /************************************************************************/
     802                 : 
     803              37 : int  OGRUnionLayer::TestCapability( const char * pszCap )
     804                 : {
     805              37 :     if( EQUAL(pszCap, OLCFastFeatureCount ) )
     806                 :     {
     807               4 :         if( nFeatureCount >= 0 &&
     808                 :             m_poFilterGeom == NULL && m_poAttrQuery == NULL )
     809               1 :             return TRUE;
     810                 : 
     811               3 :         if( !GetAttrFilterPassThroughValue() )
     812               1 :             return FALSE;
     813                 : 
     814               6 :         for(int i = 0; i < nSrcLayers; i++)
     815                 :         {
     816               4 :             AutoWarpLayerIfNecessary(i);
     817               4 :             ApplyAttributeFilterToSrcLayer(i);
     818               4 :             papoSrcLayers[i]->SetSpatialFilter(m_poFilterGeom);
     819               4 :             if( !papoSrcLayers[i]->TestCapability(pszCap) )
     820               0 :                 return FALSE;
     821                 :         }
     822               2 :         return TRUE;
     823                 :     }
     824                 : 
     825              33 :     if( EQUAL(pszCap, OLCFastGetExtent ) )
     826                 :     {
     827               2 :         if( sStaticEnvelope.IsInit() )
     828               1 :             return TRUE;
     829                 : 
     830               3 :         for(int i = 0; i < nSrcLayers; i++)
     831                 :         {
     832               2 :             AutoWarpLayerIfNecessary(i);
     833               2 :             if( !papoSrcLayers[i]->TestCapability(pszCap) )
     834               0 :                 return FALSE;
     835                 :         }
     836               1 :         return TRUE;
     837                 :     }
     838                 : 
     839              31 :     if( EQUAL(pszCap, OLCFastSpatialFilter) )
     840                 :     {
     841               6 :         for(int i = 0; i < nSrcLayers; i++)
     842                 :         {
     843               4 :             AutoWarpLayerIfNecessary(i);
     844               4 :             ApplyAttributeFilterToSrcLayer(i);
     845               4 :             if( !papoSrcLayers[i]->TestCapability(pszCap) )
     846               0 :                 return FALSE;
     847                 :         }
     848               2 :         return TRUE;
     849                 :     }
     850                 : 
     851              29 :     if( EQUAL(pszCap, OLCStringsAsUTF8) )
     852                 :     {
     853              12 :         for(int i = 0; i < nSrcLayers; i++)
     854                 :         {
     855               8 :             if( !papoSrcLayers[i]->TestCapability(pszCap) )
     856               0 :                 return FALSE;
     857                 :         }
     858               4 :         return TRUE;
     859                 :     }
     860                 : 
     861              25 :     if( EQUAL(pszCap, OLCRandomRead ) )
     862                 :     {
     863               2 :         if( !bPreserveSrcFID )
     864               2 :             return FALSE;
     865                 : 
     866               0 :         for(int i = 0; i < nSrcLayers; i++)
     867                 :         {
     868               0 :             if( !papoSrcLayers[i]->TestCapability(pszCap) )
     869               0 :                 return FALSE;
     870                 :         }
     871               0 :         return TRUE;
     872                 :     }
     873                 : 
     874              23 :     if( EQUAL(pszCap, OLCRandomWrite ) )
     875                 :     {
     876               4 :         if( !bPreserveSrcFID || osSourceLayerFieldName.size() == 0)
     877               3 :             return FALSE;
     878                 : 
     879               3 :         for(int i = 0; i < nSrcLayers; i++)
     880                 :         {
     881               2 :             if( !papoSrcLayers[i]->TestCapability(pszCap) )
     882               0 :                 return FALSE;
     883                 :         }
     884               1 :         return TRUE;
     885                 :     }
     886                 : 
     887              19 :     if( EQUAL(pszCap, OLCSequentialWrite ) )
     888                 :     {
     889               4 :         if( osSourceLayerFieldName.size() == 0)
     890               3 :             return FALSE;
     891                 : 
     892               3 :         for(int i = 0; i < nSrcLayers; i++)
     893                 :         {
     894               2 :             if( !papoSrcLayers[i]->TestCapability(pszCap) )
     895               0 :                 return FALSE;
     896                 :         }
     897               1 :         return TRUE;
     898                 :     }
     899                 : 
     900              15 :     if( EQUAL(pszCap, OLCIgnoreFields) )
     901               9 :         return TRUE;
     902                 : 
     903               6 :     return FALSE;
     904                 : }
     905                 : 
     906                 : /************************************************************************/
     907                 : /*                             GetExtent()                              */
     908                 : /************************************************************************/
     909                 : 
     910               4 : OGRErr OGRUnionLayer::GetExtent( OGREnvelope *psExtent, int bForce )
     911                 : {
     912               4 :     if( sStaticEnvelope.IsInit() )
     913                 :     {
     914               1 :         memcpy(psExtent, &sStaticEnvelope, sizeof(OGREnvelope));
     915               1 :         return OGRERR_NONE;
     916                 :     }
     917                 : 
     918               3 :     int bInit = FALSE;
     919               9 :     for(int i = 0; i < nSrcLayers; i++)
     920                 :     {
     921               6 :         AutoWarpLayerIfNecessary(i);
     922               6 :         if( !bInit )
     923                 :         {
     924               3 :             if( papoSrcLayers[i]->GetExtent(psExtent, bForce) == OGRERR_NONE )
     925               3 :                 bInit = TRUE;
     926                 :         }
     927                 :         else
     928                 :         {
     929               3 :             OGREnvelope sExtent;
     930               3 :             if( papoSrcLayers[i]->GetExtent(&sExtent, bForce) == OGRERR_NONE )
     931                 :             {
     932               3 :                 psExtent->Merge(sExtent);
     933                 :             }
     934                 :         }
     935                 :     }
     936               3 :     return (bInit) ? OGRERR_NONE : OGRERR_FAILURE;
     937                 : }
     938                 : 
     939                 : /************************************************************************/
     940                 : /*                          SetSpatialFilter()                          */
     941                 : /************************************************************************/
     942                 : 
     943              22 : void OGRUnionLayer::SetSpatialFilter( OGRGeometry * poGeomIn )
     944                 : {
     945              22 :     OGRLayer::SetSpatialFilter(poGeomIn);
     946                 : 
     947              22 :     if( iCurLayer >= 0 && iCurLayer < nSrcLayers)
     948              18 :         papoSrcLayers[iCurLayer]->SetSpatialFilter(poGeomIn);
     949              22 : }
     950                 : 
     951                 : /************************************************************************/
     952                 : /*                        TranslateFromSrcLayer()                       */
     953                 : /************************************************************************/
     954                 : 
     955            1311 : OGRFeature* OGRUnionLayer::TranslateFromSrcLayer(OGRFeature* poSrcFeature)
     956                 : {
     957            1311 :     CPLAssert(panMap != NULL);
     958            1311 :     CPLAssert(iCurLayer >= 0 && iCurLayer < nSrcLayers);
     959                 : 
     960            1311 :     OGRFeature* poFeature = new OGRFeature(poFeatureDefn);
     961            1311 :     poFeature->SetFrom(poSrcFeature, panMap, TRUE);
     962                 : 
     963            1413 :     if( osSourceLayerFieldName.size() &&
     964                 :         !poFeatureDefn->GetFieldDefn(0)->IsIgnored() )
     965                 :     {
     966             102 :         poFeature->SetField(0, papoSrcLayers[iCurLayer]->GetName());
     967                 :     }
     968                 : 
     969            1311 :     if( poFeatureDefn->IsGeometryIgnored() )
     970             100 :         poFeature->SetGeometryDirectly(NULL);
     971                 :     else
     972                 :     {
     973            1211 :         OGRGeometry* poGeom = poFeature->GetGeometryRef();
     974            1211 :         if( poGeom != NULL )
     975            1209 :             poGeom->assignSpatialReference(GetSpatialRef());
     976                 :     }
     977                 : 
     978            1311 :     if( bPreserveSrcFID )
     979             102 :         poFeature->SetFID(poSrcFeature->GetFID());
     980                 :     else
     981            1209 :         poFeature->SetFID(nNextFID ++);
     982            1311 :     return poFeature;
     983                 : }
     984                 : 
     985                 : /************************************************************************/
     986                 : /*                          SetIgnoredFields()                          */
     987                 : /************************************************************************/
     988                 : 
     989              16 : OGRErr OGRUnionLayer::SetIgnoredFields( const char **papszFields )
     990                 : {
     991              16 :     OGRErr eErr = OGRLayer::SetIgnoredFields(papszFields);
     992              16 :     if( eErr != OGRERR_NONE )
     993               0 :         return eErr;
     994                 : 
     995              16 :     CSLDestroy(papszIgnoredFields);
     996              16 :     papszIgnoredFields = papszFields ? CSLDuplicate((char**)papszFields) : NULL;
     997                 : 
     998              16 :     return eErr;
     999                 : }
    1000                 : 
    1001                 : /************************************************************************/
    1002                 : /*                             SyncToDisk()                             */
    1003                 : /************************************************************************/
    1004                 : 
    1005               1 : OGRErr OGRUnionLayer::SyncToDisk()
    1006                 : {
    1007               3 :     for(int i = 0; i < nSrcLayers; i++)
    1008                 :     {
    1009               2 :         if (pabModifiedLayers[i])
    1010                 :         {
    1011               1 :             papoSrcLayers[i]->SyncToDisk();
    1012               1 :             pabModifiedLayers[i] = FALSE;
    1013                 :         }
    1014                 :     }
    1015                 : 
    1016               1 :     return OGRERR_NONE;
    1017                 : }

Generated by: LCOV version 1.7