LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/osm - ogrosmlayer.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 269 219 81.4 %
Date: 2013-03-30 Functions: 24 20 83.3 %

       1                 : /******************************************************************************
       2                 :  * $Id: ogrosmlayer.cpp 24950 2012-09-22 13:54:36Z rouault $
       3                 :  *
       4                 :  * Project:  OpenGIS Simple Features Reference Implementation
       5                 :  * Purpose:  Implements OGROSMLayer class
       6                 :  * Author:   Even Rouault, <even dot rouault at mines dash paris dot org>
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 2012, Even Rouault
      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_osm.h"
      31                 : #include "cpl_conv.h"
      32                 : #include "cpl_string.h"
      33                 : #include "cpl_time.h"
      34                 : #include "ogr_p.h"
      35                 : 
      36                 : CPL_CVSID("$Id: ogrosmlayer.cpp 24950 2012-09-22 13:54:36Z rouault $");
      37                 : 
      38                 : #define SWITCH_THRESHOLD   10000
      39                 : #define MAX_THRESHOLD      100000
      40                 : 
      41                 : #define ALLTAGS_LENGTH     8192
      42                 : 
      43                 : /************************************************************************/
      44                 : /*                          OGROSMLayer()                               */
      45                 : /************************************************************************/
      46                 : 
      47                 : 
      48              70 : OGROSMLayer::OGROSMLayer(OGROSMDataSource* poDS, const char* pszName )
      49                 : {
      50              70 :     this->poDS = poDS;
      51                 : 
      52              70 :     poFeatureDefn = new OGRFeatureDefn( pszName );
      53              70 :     poFeatureDefn->Reference();
      54                 : 
      55              70 :     poSRS = new OGRSpatialReference();
      56              70 :     poSRS->SetWellKnownGeogCS("WGS84");
      57                 : 
      58              70 :     nFeatureArraySize = 0;
      59              70 :     nFeatureArrayMaxSize = 0;
      60              70 :     nFeatureArrayIndex = 0;
      61              70 :     papoFeatures = NULL;
      62                 :     
      63              70 :     nFeatureCount = 0;
      64                 : 
      65              70 :     bHasOSMId = FALSE;
      66              70 :     nIndexOSMId = -1;
      67              70 :     nIndexOSMWayId = -1;
      68              70 :     bHasVersion = FALSE;
      69              70 :     bHasTimestamp = FALSE;
      70              70 :     bHasUID = FALSE;
      71              70 :     bHasUser = FALSE;
      72              70 :     bHasChangeset = FALSE;
      73              70 :     bHasOtherTags = TRUE;
      74                 : 
      75              70 :     bResetReadingAllowed = FALSE;
      76              70 :     bHasWarnedTooManyFeatures = FALSE;
      77                 : 
      78              70 :     pszAllTags = (char*)CPLMalloc(ALLTAGS_LENGTH);
      79              70 :     bHasWarnedAllTagsTruncated = FALSE;
      80                 : 
      81              70 :     bUserInterested = TRUE;
      82              70 : }
      83                 : 
      84                 : /************************************************************************/
      85                 : /*                          ~OGROSMLayer()                           */
      86                 : /************************************************************************/
      87                 : 
      88              70 : OGROSMLayer::~OGROSMLayer()
      89                 : {
      90                 :     int i;
      91                 :     
      92              70 :     poFeatureDefn->Release();
      93                 :     
      94              70 :     if (poSRS)
      95              70 :         poSRS->Release();
      96                 : 
      97             402 :     for(i=0;i<nFeatureArraySize;i++)
      98                 :     {
      99             332 :         if (papoFeatures[i])
     100             332 :             delete papoFeatures[i];
     101                 :     }
     102                 : 
     103             770 :     for(i=0;i<(int)apszNames.size();i++)
     104             700 :         CPLFree(apszNames[i]);
     105                 : 
     106             140 :     for(i=0;i<(int)apszUnsignificantKeys.size();i++)
     107              70 :         CPLFree(apszUnsignificantKeys[i]);
     108                 : 
     109             742 :     for(i=0;i<(int)apszIgnoreKeys.size();i++)
     110             672 :         CPLFree(apszIgnoreKeys[i]);
     111                 :     
     112              70 :     CPLFree(pszAllTags);
     113                 : 
     114              70 :     CPLFree(papoFeatures);
     115              70 : }
     116                 : 
     117                 : /************************************************************************/
     118                 : /*                            ResetReading()                            */
     119                 : /************************************************************************/
     120                 : 
     121              41 : void OGROSMLayer::ResetReading()
     122                 : {
     123              41 :     if ( !bResetReadingAllowed || poDS->IsInterleavedReading() )
     124              30 :         return;
     125                 : 
     126              11 :     poDS->ResetReading();
     127                 : }
     128                 : 
     129                 : /************************************************************************/
     130                 : /*                        ForceResetReading()                           */
     131                 : /************************************************************************/
     132                 : 
     133             125 : void OGROSMLayer::ForceResetReading()
     134                 : {
     135             129 :     for(int i=0;i<nFeatureArraySize;i++)
     136                 :     {
     137               4 :         if (papoFeatures[i])
     138               2 :             delete papoFeatures[i];
     139                 :     }
     140             125 :     nFeatureArrayIndex = 0;
     141             125 :     nFeatureArraySize = 0;
     142             125 :     nFeatureCount = 0;
     143             125 :     bResetReadingAllowed = FALSE;
     144             125 : }
     145                 : 
     146                 : /************************************************************************/
     147                 : /*                          GetFeatureCount()                           */
     148                 : /************************************************************************/
     149                 : 
     150               0 : int OGROSMLayer::GetFeatureCount( int bForce )
     151                 : {
     152               0 :     if( poDS->IsFeatureCountEnabled() )
     153               0 :         return OGRLayer::GetFeatureCount(bForce);
     154                 : 
     155               0 :     return -1;
     156                 : }
     157                 : 
     158                 : /************************************************************************/
     159                 : /*                           GetNextFeature()                           */
     160                 : /************************************************************************/
     161                 : 
     162             221 : OGRFeature *OGROSMLayer::GetNextFeature()
     163                 : {
     164             221 :     bResetReadingAllowed = TRUE;
     165                 : 
     166             221 :     if ( nFeatureArraySize == 0)
     167                 :     {
     168              69 :         if ( poDS->IsInterleavedReading() )
     169                 :         {
     170                 :             int i;
     171                 : 
     172              33 :             OGRLayer* poCurrentLayer = poDS->GetCurrentLayer();
     173              33 :             if ( poCurrentLayer == NULL )
     174                 :             {
     175              21 :                 poDS->SetCurrentLayer(this);
     176                 :             }
     177              12 :             else if( poCurrentLayer != this )
     178                 :             {
     179               0 :                 return NULL;
     180                 :             }
     181                 : 
     182                 :             /* If too many features have been accumulated in */
     183                 :             /* another layer, we force */
     184                 :             /* a switch to that layer, so that it gets emptied */
     185             198 :             for(i=0;i<poDS->GetLayerCount();i++)
     186                 :             {
     187             297 :                 if (poDS->papoLayers[i] != this &&
     188             132 :                     poDS->papoLayers[i]->nFeatureArraySize > SWITCH_THRESHOLD)
     189                 :                 {
     190               0 :                     poDS->SetCurrentLayer(poDS->papoLayers[i]);
     191                 :                     CPLDebug("OSM", "Switching to '%s' as they are too many "
     192                 :                                     "features in '%s'",
     193               0 :                              poDS->papoLayers[i]->GetName(),
     194               0 :                              GetName());
     195               0 :                     return NULL;
     196                 :                 }
     197                 :             }
     198                 : 
     199                 :             /* Read some more data and accumulate features */
     200              33 :             poDS->ParseNextChunk();
     201                 : 
     202              33 :             if ( nFeatureArraySize == 0 )
     203                 :             {
     204                 :                 /* If there are really no more features to read in the */
     205                 :                 /* current layer, force a switch to another non-empty layer */
     206                 : 
     207             153 :                 for(i=0;i<poDS->GetLayerCount();i++)
     208                 :                 {
     209             234 :                     if (poDS->papoLayers[i] != this &&
     210             102 :                         poDS->papoLayers[i]->nFeatureArraySize > 0)
     211                 :                     {
     212               9 :                         poDS->SetCurrentLayer(poDS->papoLayers[i]);
     213                 :                         CPLDebug("OSM",
     214                 :                                  "Switching to '%s' as they are no more feature in '%s'",
     215              27 :                                  poDS->papoLayers[i]->GetName(),
     216              36 :                                  GetName());
     217               9 :                         return NULL;
     218                 :                     }
     219                 :                 }
     220                 : 
     221                 :                 /* Game over : no more data to read from the stream */
     222              21 :                 poDS->SetCurrentLayer(NULL);
     223              21 :                 return NULL;
     224                 :             }
     225                 :         }
     226                 :         else
     227                 :         {
     228               2 :             while(TRUE)
     229                 :             {
     230              38 :                 int bRet = poDS->ParseNextChunk();
     231              38 :                 if (nFeatureArraySize != 0)
     232              17 :                     break;
     233              21 :                 if (bRet == FALSE)
     234              19 :                     return NULL;
     235                 :             }
     236                 :         }
     237                 :     }
     238                 : 
     239             172 :     OGRFeature* poFeature = papoFeatures[nFeatureArrayIndex];
     240                 :     
     241             172 :     papoFeatures[nFeatureArrayIndex] = NULL;
     242             172 :     nFeatureArrayIndex++;
     243                 : 
     244             172 :     if ( nFeatureArrayIndex == nFeatureArraySize)
     245              36 :         nFeatureArrayIndex = nFeatureArraySize = 0;
     246                 :     
     247             172 :     return poFeature;
     248                 : }
     249                 : 
     250                 : /************************************************************************/
     251                 : /*                           TestCapability()                           */
     252                 : /************************************************************************/
     253                 : 
     254               2 : int OGROSMLayer::TestCapability( const char * pszCap )
     255                 : {
     256               2 :     if( EQUAL(pszCap, OLCFastGetExtent) )
     257                 :     {
     258               0 :         OGREnvelope sExtent;
     259               0 :         if (poDS->GetExtent(&sExtent) == OGRERR_NONE)
     260               0 :             return TRUE;
     261                 :     }
     262                 : 
     263               2 :     return FALSE;
     264                 : }
     265                 : 
     266                 : /************************************************************************/
     267                 : /*                             AddToArray()                             */
     268                 : /************************************************************************/
     269                 : 
     270             506 : int  OGROSMLayer::AddToArray(OGRFeature* poFeature)
     271                 : {
     272             506 :     if( nFeatureArraySize > MAX_THRESHOLD)
     273                 :     {
     274               0 :         if( !bHasWarnedTooManyFeatures )
     275                 :         {
     276                 :             CPLError(CE_Failure, CPLE_AppDefined,
     277                 :                     "Too many features have accumulated in %s layer. "
     278                 :                     "Use OGR_INTERLEAVED_READING=YES mode",
     279               0 :                     GetName());
     280                 :         }
     281               0 :         bHasWarnedTooManyFeatures = TRUE;
     282               0 :         return FALSE;
     283                 :     }
     284                 : 
     285             506 :     if (nFeatureArraySize == nFeatureArrayMaxSize)
     286                 :     {
     287              39 :         nFeatureArrayMaxSize = nFeatureArrayMaxSize + nFeatureArrayMaxSize / 2 + 128;
     288              39 :         CPLDebug("OSM", "For layer %s, new max size is %d", GetName(), nFeatureArrayMaxSize);
     289                 :         OGRFeature** papoNewFeatures = (OGRFeature**)VSIRealloc(papoFeatures,
     290              39 :                                 nFeatureArrayMaxSize * sizeof(OGRFeature*));
     291              39 :         if (papoNewFeatures == NULL)
     292                 :         {
     293               0 :             delete poFeature;
     294               0 :             return FALSE;
     295                 :         }
     296              39 :         papoFeatures = papoNewFeatures;
     297                 :     }
     298             506 :     papoFeatures[nFeatureArraySize ++] = poFeature;
     299                 :     
     300             506 :     return TRUE;
     301                 : }
     302                 : 
     303                 : /************************************************************************/
     304                 : /*                        EvaluateAttributeFilter()                     */
     305                 : /************************************************************************/
     306                 : 
     307              11 : int OGROSMLayer::EvaluateAttributeFilter(OGRFeature* poFeature)
     308                 : {
     309                 :     return (m_poAttrQuery == NULL
     310              11 :             || m_poAttrQuery->Evaluate( poFeature ));
     311                 : }
     312                 : 
     313                 : /************************************************************************/
     314                 : /*                             AddFeature()                             */
     315                 : /************************************************************************/
     316                 : 
     317             535 : int  OGROSMLayer::AddFeature(OGRFeature* poFeature,
     318                 :                              int bAttrFilterAlreadyEvaluated,
     319                 :                              int* pbFilteredOut)
     320                 : {
     321             535 :     if( !bUserInterested )
     322                 :     {
     323               0 :         if (pbFilteredOut)
     324               0 :             *pbFilteredOut = TRUE;
     325               0 :         delete poFeature;
     326               0 :         return TRUE;
     327                 :     }
     328                 : 
     329             535 :     OGRGeometry* poGeom = poFeature->GetGeometryRef();
     330             535 :     if (poGeom)
     331             535 :         poGeom->assignSpatialReference( poSRS );
     332                 :     
     333             535 :     if( (m_poFilterGeom == NULL
     334                 :         || FilterGeometry( poFeature->GetGeometryRef() ) )
     335                 :         && (m_poAttrQuery == NULL || bAttrFilterAlreadyEvaluated
     336                 :             || m_poAttrQuery->Evaluate( poFeature )) )
     337                 :     {
     338             506 :         if (!AddToArray(poFeature))
     339                 :         {
     340               0 :             delete poFeature;
     341               0 :             return FALSE;
     342                 :         }
     343                 :     }
     344                 :     else
     345                 :     {
     346              29 :         if (pbFilteredOut)
     347              29 :             *pbFilteredOut = TRUE;
     348              29 :         delete poFeature;
     349              29 :         return TRUE;
     350                 :     }
     351                 :     
     352             506 :     if (pbFilteredOut)
     353             506 :         *pbFilteredOut = FALSE;
     354             506 :     return TRUE;
     355                 : }
     356                 : 
     357                 : /************************************************************************/
     358                 : /*                             GetExtent()                              */
     359                 : /************************************************************************/
     360                 : 
     361               1 : OGRErr OGROSMLayer::GetExtent( OGREnvelope *psExtent, int bForce )
     362                 : {
     363               1 :     if (poDS->GetExtent(psExtent) == OGRERR_NONE)
     364               1 :         return OGRERR_NONE;
     365                 : 
     366                 :     /* return OGRLayer::GetExtent(psExtent, bForce);*/
     367               0 :     return OGRERR_FAILURE;
     368                 : }
     369                 : 
     370                 : /************************************************************************/
     371                 : /*                          GetLaunderedFieldName()                     */
     372                 : /************************************************************************/
     373                 : 
     374             700 : const char* OGROSMLayer::GetLaunderedFieldName(const char* pszName)
     375                 : {
     376             700 :     if( poDS->DoesAttributeNameLaundering()  &&
     377                 :         strchr(pszName, ':') != NULL )
     378                 :     {
     379                 :         size_t i;
     380               0 :         for( i = 0;
     381               0 :              pszName[i] != '\0' && i < sizeof(szLaunderedFieldName) - 1; i++ )
     382                 :         {
     383               0 :             if( pszName[i] == ':' )
     384               0 :                 szLaunderedFieldName[i] = '_';
     385                 :             else
     386               0 :                 szLaunderedFieldName[i] = pszName[i];
     387                 :         }
     388               0 :         szLaunderedFieldName[i] = '\0';
     389               0 :         return szLaunderedFieldName;
     390                 :     }
     391                 :     else
     392             700 :         return pszName;
     393                 : }
     394                 : 
     395                 : /************************************************************************/
     396                 : /*                              AddField()                              */
     397                 : /************************************************************************/
     398                 : 
     399             700 : void OGROSMLayer::AddField(const char* pszName, OGRFieldType eFieldType)
     400                 : {
     401             700 :     const char* pszLaunderedName = GetLaunderedFieldName(pszName);
     402             700 :     OGRFieldDefn oField(pszLaunderedName, eFieldType);
     403             700 :     poFeatureDefn->AddFieldDefn(&oField);
     404                 : 
     405             700 :     int nIndex = poFeatureDefn->GetFieldCount() - 1;
     406             700 :     char* pszDupName = CPLStrdup(pszName);
     407             700 :     apszNames.push_back(pszDupName);
     408             700 :     oMapFieldNameToIndex[pszDupName] = nIndex;
     409                 : 
     410             700 :     if( strcmp(pszName, "osm_id") == 0 )
     411              70 :         nIndexOSMId = nIndex;
     412                 : 
     413             630 :     else if( strcmp(pszName, "osm_way_id") == 0 )
     414              14 :         nIndexOSMWayId = nIndex;
     415             700 : }
     416                 : 
     417                 : /************************************************************************/
     418                 : /*                              GetFieldIndex()                         */
     419                 : /************************************************************************/
     420                 : 
     421             883 : int OGROSMLayer::GetFieldIndex(const char* pszName)
     422                 : {
     423                 :     std::map<const char*, int, ConstCharComp>::iterator oIter =
     424             883 :         oMapFieldNameToIndex.find(pszName);
     425             883 :     if( oIter != oMapFieldNameToIndex.end() )
     426             569 :         return oIter->second;
     427                 :     else
     428             314 :         return -1;
     429                 : }
     430                 : 
     431                 : /************************************************************************/
     432                 : /*                              AddInOtherTag()                         */
     433                 : /************************************************************************/
     434                 : 
     435             314 : int OGROSMLayer::AddInOtherTag(const char* pszK)
     436                 : {
     437             314 :     int bAddToOtherTags = FALSE;
     438                 : 
     439             314 :     if ( aoSetIgnoreKeys.find(pszK) == aoSetIgnoreKeys.end() )
     440                 :     {
     441             114 :         char* pszColon = strchr((char*) pszK, ':');
     442             114 :         if( pszColon )
     443                 :         {
     444               0 :             char chBackup = pszColon[1];
     445               0 :             pszColon[1] = '\0';  /* Evil but OK */
     446                 :             bAddToOtherTags = ( aoSetIgnoreKeys.find(pszK) ==
     447               0 :                                 aoSetIgnoreKeys.end() );
     448               0 :             pszColon[1] = chBackup;
     449                 :         }
     450                 :         else
     451             114 :             bAddToOtherTags = TRUE;
     452                 :     }
     453                 : 
     454             314 :     return bAddToOtherTags;
     455                 : }
     456                 : 
     457                 : /************************************************************************/
     458                 : /*                        OGROSMFormatForHSTORE()                       */
     459                 : /************************************************************************/
     460                 : 
     461             228 : static int OGROSMFormatForHSTORE(const char* pszV, char* pszAllTags)
     462                 : {
     463                 :     int k;
     464             228 :     int bMustAddDoubleQuotes = FALSE;
     465                 :     
     466             228 :     int nAllTagsOff = 0;
     467                 : 
     468                 :     /* Follow the quoting rules of http://www.postgresql.org/docs/9.0/static/hstore.html */
     469            1916 :     for(k=0;pszV[k] != '\0'; k++)
     470                 :     {
     471            5070 :         if( pszV[k] == ' ' || pszV[k] == ','||
     472            3376 :             pszV[k] == '=' || pszV[k] == '>' )
     473                 :         {
     474               6 :             bMustAddDoubleQuotes = TRUE;
     475               6 :             break;
     476                 :         }
     477                 :     }
     478             228 :     if( bMustAddDoubleQuotes )
     479                 :     {
     480               6 :         pszAllTags[nAllTagsOff++] = '"';
     481                 :     }
     482                 : 
     483            2016 :     for(k=0;pszV[k] != '\0'; k++)
     484                 :     {
     485            1788 :         if( pszV[k] == '"' || pszV[k] == '\\' )
     486               0 :             pszAllTags[nAllTagsOff++] = '\\';
     487            1788 :         pszAllTags[nAllTagsOff++] = pszV[k];
     488                 :     }
     489                 : 
     490             228 :     if( bMustAddDoubleQuotes )
     491                 :     {
     492               6 :         pszAllTags[nAllTagsOff++] = '"';
     493                 :     }
     494                 : 
     495             228 :     return nAllTagsOff;
     496                 : }
     497                 : 
     498                 : /************************************************************************/
     499                 : /*                        SetFieldsFromTags()                           */
     500                 : /************************************************************************/
     501                 : 
     502             551 : void OGROSMLayer::SetFieldsFromTags(OGRFeature* poFeature,
     503                 :                                     GIntBig nID,
     504                 :                                     int bIsWayID,
     505                 :                                     unsigned int nTags, OSMTag* pasTags,
     506                 :                                     OSMInfo* psInfo)
     507                 : {
     508             551 :     if( !bIsWayID )
     509                 :     {
     510                 :         if( (long)nID == nID )
     511             425 :             poFeature->SetFID( (long)nID ); /* Will not work with 32bit GDAL if id doesn't fit into 32 bits */
     512                 : 
     513             425 :         if( bHasOSMId )
     514                 :         {
     515                 :             char szID[32];
     516             425 :             sprintf(szID, CPL_FRMT_GIB, nID );
     517             425 :             poFeature->SetField(nIndexOSMId, szID);
     518                 :         }
     519                 :     }
     520                 :     else
     521                 :     {
     522                 :         if( (long)nID == nID )
     523             126 :             poFeature->SetFID( (long)nID ); /* Will not work with 32bit GDAL if id doesn't fit into 32 bits */
     524                 : 
     525             126 :         if( nIndexOSMWayId >= 0 )
     526                 :         {
     527                 :             char szID[32];
     528             126 :             sprintf(szID, CPL_FRMT_GIB, nID );
     529             126 :             poFeature->SetField(nIndexOSMWayId, szID );
     530                 :         }
     531                 :     }
     532                 : 
     533             551 :     if( bHasVersion )
     534                 :     {
     535               0 :         poFeature->SetField("osm_version", psInfo->nVersion);
     536                 :     }
     537             551 :     if( bHasTimestamp )
     538                 :     {
     539               0 :         if( psInfo->bTimeStampIsStr )
     540                 :         {
     541                 :             int year, month, day, hour, minute, TZ;
     542                 :             float second;
     543               0 :             if (OGRParseXMLDateTime(psInfo->ts.pszTimeStamp, &year, &month, &day,
     544                 :                                     &hour, &minute, &second, &TZ))
     545                 :             {
     546                 :                 poFeature->SetField("osm_timestamp", year, month, day, hour,
     547               0 :                                     minute, (int)(second + .5), TZ);
     548                 :             }
     549                 :         }
     550                 :         else
     551                 :         {
     552                 :             struct tm brokendown;
     553               0 :             CPLUnixTimeToYMDHMS(psInfo->ts.nTimeStamp, &brokendown);
     554                 :             poFeature->SetField("osm_timestamp",
     555                 :                                 brokendown.tm_year + 1900,
     556                 :                                 brokendown.tm_mon + 1,
     557                 :                                 brokendown.tm_mday,
     558                 :                                 brokendown.tm_hour,
     559                 :                                 brokendown.tm_min,
     560                 :                                 brokendown.tm_sec,
     561               0 :                                 0);
     562                 :         }
     563                 : 
     564                 :     }
     565             551 :     if( bHasUID )
     566                 :     {
     567               0 :         poFeature->SetField("osm_uid", psInfo->nUID);
     568                 :     }
     569             551 :     if( bHasUser )
     570                 :     {
     571               0 :         poFeature->SetField("osm_user", psInfo->pszUserSID);
     572                 :     }
     573             551 :     if( bHasChangeset )
     574                 :     {
     575               0 :         poFeature->SetField("osm_changeset", (int) psInfo->nChangeset);
     576                 :     }
     577                 : 
     578             551 :     int nAllTagsOff = 0;
     579            1434 :     for(unsigned int j = 0; j < nTags; j++)
     580                 :     {
     581             883 :         const char* pszK = pasTags[j].pszK;
     582             883 :         const char* pszV = pasTags[j].pszV;
     583             883 :         int nIndex = GetFieldIndex(pszK);
     584             883 :         if( nIndex >= 0 )
     585             569 :             poFeature->SetField(nIndex, pszV);
     586             314 :         else if ( HasOtherTags() )
     587                 :         {
     588             314 :             if ( AddInOtherTag(pszK) )
     589                 :             {
     590             114 :                 int nLenK = (int)strlen(pszK);
     591             114 :                 int nLenV = (int)strlen(pszV);
     592             114 :                 if( nAllTagsOff +
     593                 :                     1 + 2 * nLenK + 1 +
     594                 :                     2 +
     595                 :                     1 + 2 * nLenV + 1 +
     596                 :                     1 >= ALLTAGS_LENGTH - 1 )
     597                 :                 {
     598               0 :                     if( !bHasWarnedAllTagsTruncated )
     599               0 :                         CPLDebug("OSM", "all_tags field truncated for feature " CPL_FRMT_GIB, nID);
     600               0 :                     bHasWarnedAllTagsTruncated = TRUE;
     601               0 :                     continue;
     602                 :                 }
     603                 : 
     604             114 :                 if( nAllTagsOff )
     605              38 :                     pszAllTags[nAllTagsOff++] = ',';
     606                 :                 
     607                 :                 nAllTagsOff += OGROSMFormatForHSTORE(pszK,
     608             114 :                                                      pszAllTags + nAllTagsOff);
     609                 : 
     610             114 :                 pszAllTags[nAllTagsOff++] = '=';
     611             114 :                 pszAllTags[nAllTagsOff++] = '>';
     612                 :                 
     613                 :                 nAllTagsOff += OGROSMFormatForHSTORE(pszV,
     614             114 :                                                      pszAllTags + nAllTagsOff);
     615                 :             }
     616                 : 
     617                 : #ifdef notdef
     618                 :             if ( aoSetWarnKeys.find(pszK) ==
     619                 :                  aoSetWarnKeys.end() )
     620                 :             {
     621                 :                 aoSetWarnKeys.insert(pszK);
     622                 :                 CPLDebug("OSM_KEY", "Ignored key : %s", pszK);
     623                 :             }
     624                 : #endif
     625                 :         }
     626                 :     }
     627                 : 
     628             551 :     if( nAllTagsOff )
     629                 :     {
     630              76 :         pszAllTags[nAllTagsOff] = '\0';
     631              76 :         poFeature->SetField(GetLayerDefn()->GetFieldCount() - 1, pszAllTags);
     632                 :     }
     633             551 : }
     634                 : 
     635                 : /************************************************************************/
     636                 : /*                      GetSpatialFilterEnvelope()                      */
     637                 : /************************************************************************/
     638                 : 
     639              31 : const OGREnvelope* OGROSMLayer::GetSpatialFilterEnvelope()
     640                 : {
     641              31 :     if( m_poFilterGeom != NULL )
     642               1 :         return &m_sFilterEnvelope;
     643                 :     else
     644              30 :         return NULL;
     645                 : }
     646                 : 
     647                 : /************************************************************************/
     648                 : /*                        AddUnsignificantKey()                         */
     649                 : /************************************************************************/
     650                 : 
     651              70 : void OGROSMLayer::AddUnsignificantKey(const char* pszK)
     652                 : {
     653              70 :     char* pszKDup = CPLStrdup(pszK);
     654              70 :     apszUnsignificantKeys.push_back(pszKDup);
     655              70 :     aoSetUnsignificantKeys[pszKDup] = 1;
     656              70 : }
     657                 : 
     658                 : /************************************************************************/
     659                 : /*                          AddIgnoreKey()                              */
     660                 : /************************************************************************/
     661                 : 
     662             672 : void OGROSMLayer::AddIgnoreKey(const char* pszK)
     663                 : {
     664             672 :     char* pszKDup = CPLStrdup(pszK);
     665             672 :     apszIgnoreKeys.push_back(pszKDup);
     666             672 :     aoSetIgnoreKeys[pszKDup] = 1;
     667             672 : }
     668                 : 
     669                 : /************************************************************************/
     670                 : /*                           AddWarnKey()                               */
     671                 : /************************************************************************/
     672                 : 
     673             672 : void OGROSMLayer::AddWarnKey(const char* pszK)
     674                 : {
     675             672 :     aoSetWarnKeys.insert(pszK);
     676             672 : }

Generated by: LCOV version 1.7