LTP GCOV extension - code coverage report
Current view: directory - ogr/ogrsf_frmts/gml - ogrgmllayer.cpp
Test: gdal_filtered.info
Date: 2010-07-12 Instrumented lines: 210
Code covered: 64.8 % Executed lines: 136

       1                 : /******************************************************************************
       2                 :  * $Id: ogrgmllayer.cpp 20027 2010-07-11 17:58:47Z rouault $
       3                 :  *
       4                 :  * Project:  OGR
       5                 :  * Purpose:  Implements OGRGMLLayer class.
       6                 :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       7                 :  *
       8                 :  ******************************************************************************
       9                 :  * Copyright (c) 2002, Frank Warmerdam <warmerdam@pobox.com>
      10                 :  *
      11                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      12                 :  * copy of this software and associated documentation files (the "Software"),
      13                 :  * to deal in the Software without restriction, including without limitation
      14                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      15                 :  * and/or sell copies of the Software, and to permit persons to whom the
      16                 :  * Software is furnished to do so, subject to the following conditions:
      17                 :  *
      18                 :  * The above copyright notice and this permission notice shall be included
      19                 :  * in all copies or substantial portions of the Software.
      20                 :  *
      21                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
      22                 :  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      23                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
      24                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      25                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      26                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
      27                 :  * DEALINGS IN THE SOFTWARE.
      28                 :  ****************************************************************************/
      29                 : 
      30                 : #include "ogr_gml.h"
      31                 : #include "cpl_conv.h"
      32                 : #include "cpl_port.h"
      33                 : #include "cpl_string.h"
      34                 : #include "ogr_p.h"
      35                 : 
      36                 : CPL_CVSID("$Id: ogrgmllayer.cpp 20027 2010-07-11 17:58:47Z rouault $");
      37                 : 
      38                 : /************************************************************************/
      39                 : /*                           OGRGMLLayer()                              */
      40                 : /************************************************************************/
      41                 : 
      42                 : OGRGMLLayer::OGRGMLLayer( const char * pszName,
      43                 :                           OGRSpatialReference *poSRSIn, int bWriterIn,
      44                 :                           OGRwkbGeometryType eReqType,
      45              19 :                           OGRGMLDataSource *poDSIn )
      46                 : 
      47                 : {
      48              19 :     if( poSRSIn == NULL )
      49              19 :         poSRS = NULL;
      50                 :     else
      51               0 :         poSRS = poSRSIn->Clone();
      52                 :     
      53              19 :     iNextGMLId = 0;
      54              19 :     nTotalGMLCount = -1;
      55              19 :     bInvalidFIDFound = FALSE;
      56              19 :     pszFIDPrefix = NULL;
      57                 :         
      58              19 :     poDS = poDSIn;
      59                 : 
      60              19 :     if ( EQUALN(pszName, "ogr:", 4) )
      61               0 :       poFeatureDefn = new OGRFeatureDefn( pszName+4 );
      62                 :     else
      63              19 :       poFeatureDefn = new OGRFeatureDefn( pszName );
      64              19 :     poFeatureDefn->Reference();
      65              19 :     poFeatureDefn->SetGeomType( eReqType );
      66                 : 
      67              19 :     bWriter = bWriterIn;
      68                 : 
      69                 : /* -------------------------------------------------------------------- */
      70                 : /*      Reader's should get the corresponding GMLFeatureClass and       */
      71                 : /*      cache it.                                                       */
      72                 : /* -------------------------------------------------------------------- */
      73              19 :     if( !bWriter )
      74              17 :         poFClass = poDS->GetReader()->GetClass( pszName );
      75                 :     else
      76               2 :         poFClass = NULL;
      77              19 : }
      78                 : 
      79                 : /************************************************************************/
      80                 : /*                           ~OGRGMLLayer()                           */
      81                 : /************************************************************************/
      82                 : 
      83              19 : OGRGMLLayer::~OGRGMLLayer()
      84                 : 
      85                 : {
      86              19 :     CPLFree(pszFIDPrefix);
      87                 : 
      88              19 :     if( poFeatureDefn )
      89              19 :         poFeatureDefn->Release();
      90                 : 
      91              19 :     if( poSRS != NULL )
      92               0 :         poSRS->Release();
      93              19 : }
      94                 : 
      95                 : /************************************************************************/
      96                 : /*                            ResetReading()                            */
      97                 : /************************************************************************/
      98                 : 
      99              18 : void OGRGMLLayer::ResetReading()
     100                 : 
     101                 : {
     102              18 :     iNextGMLId = 0;
     103              18 :     poDS->GetReader()->ResetReading();
     104              18 : }
     105                 : 
     106                 : /************************************************************************/
     107                 : /*                           GetNextFeature()                           */
     108                 : /************************************************************************/
     109                 : 
     110              42 : OGRFeature *OGRGMLLayer::GetNextFeature()
     111                 : 
     112                 : {
     113              42 :     GMLFeature  *poGMLFeature = NULL;
     114              42 :     OGRGeometry *poGeom = NULL;
     115                 : 
     116              42 :     if (bWriter)
     117                 :     {
     118                 :         CPLError(CE_Failure, CPLE_NotSupported,
     119               0 :                  "Cannot read features when writing a GML file");
     120               0 :         return NULL;
     121                 :     }
     122                 : 
     123              42 :     if( iNextGMLId == 0 )
     124              15 :         ResetReading();
     125                 : 
     126                 : /* ==================================================================== */
     127                 : /*      Loop till we find and translate a feature meeting all our       */
     128                 : /*      requirements.                                                   */
     129                 : /* ==================================================================== */
     130               2 :     while( TRUE )
     131                 :     {
     132                 : /* -------------------------------------------------------------------- */
     133                 : /*      Cleanup last feature, and get a new raw gml feature.            */
     134                 : /* -------------------------------------------------------------------- */
     135              44 :         if( poGMLFeature != NULL )
     136               2 :             delete poGMLFeature;
     137                 : 
     138              44 :         if( poGeom != NULL )
     139                 :         {
     140               1 :             delete poGeom;
     141               1 :             poGeom = NULL;
     142                 :         }
     143                 : 
     144              44 :         poGMLFeature = poDS->GetReader()->NextFeature();
     145              44 :         if( poGMLFeature == NULL )
     146               9 :             return NULL;
     147                 : 
     148                 : /* -------------------------------------------------------------------- */
     149                 : /*      Is it of the proper feature class?                              */
     150                 : /* -------------------------------------------------------------------- */
     151                 : 
     152                 :         // We count reading low level GML features as a feature read for
     153                 :         // work checking purposes, though at least we didn't necessary
     154                 :         // have to turn it into an OGRFeature.
     155              35 :         m_nFeaturesRead++;
     156                 : 
     157              35 :         if( poGMLFeature->GetClass() != poFClass )
     158               1 :             continue;
     159                 : 
     160                 : /* -------------------------------------------------------------------- */
     161                 : /*      Extract the fid:                                                */
     162                 : /*      -Assumes the fids are non-negative integers with an optional    */
     163                 : /*       prefix                                                         */
     164                 : /*      -If a prefix differs from the prefix of the first feature from  */
     165                 : /*       the poDS then the fids from the poDS are ignored and are       */
     166                 : /*       assigned serially thereafter                                   */
     167                 : /* -------------------------------------------------------------------- */
     168                 :         int nFID;
     169              34 :         const char * pszGML_FID = poGMLFeature->GetFID();
     170              34 :         if( bInvalidFIDFound )
     171                 :         {
     172               6 :             nFID = iNextGMLId++;
     173                 :         }
     174              28 :         else if( pszGML_FID == NULL )
     175                 :         {
     176               3 :             bInvalidFIDFound = TRUE;
     177               3 :             nFID = iNextGMLId++;
     178                 :         }
     179              25 :         else if( iNextGMLId == 0 )
     180                 :         {
     181              12 :             int i = strlen( pszGML_FID )-1, j = 0;
     182              61 :             while( i >= 0 && pszGML_FID[i] >= '0'
     183                 :                           && pszGML_FID[i] <= '9' && j<8)
     184              37 :                 i--, j++;
     185                 :             /* i points the last character of the fid */
     186              12 :             if( i >= 0 && j < 8 && pszFIDPrefix == NULL)
     187                 :             {
     188               9 :                 pszFIDPrefix = (char *) CPLMalloc(i+2);
     189               9 :                 pszFIDPrefix[i+1] = '\0';
     190               9 :                 strncpy(pszFIDPrefix, pszGML_FID, i+1);
     191                 :             }
     192                 :             /* pszFIDPrefix now contains the prefix or NULL if no prefix is found */
     193              12 :             if( j < 8 && sscanf(pszGML_FID+i+1, "%d", &nFID)==1)
     194                 :             {
     195              10 :                 if( iNextGMLId <= nFID )
     196              10 :                     iNextGMLId = nFID + 1;
     197                 :             }
     198                 :             else
     199                 :             {
     200               2 :                 bInvalidFIDFound = TRUE;
     201               2 :                 nFID = iNextGMLId++;
     202                 :             }
     203                 :         }
     204              13 :         else if( iNextGMLId != 0 )
     205                 :         {
     206              13 :             const char* pszFIDPrefix_notnull = pszFIDPrefix;
     207              13 :             if (pszFIDPrefix_notnull == NULL) pszFIDPrefix_notnull = "";
     208              13 :             int nLenPrefix = strlen(pszFIDPrefix_notnull);
     209                 : 
     210              13 :             if(  strncmp(pszGML_FID, pszFIDPrefix_notnull, nLenPrefix) == 0 &&
     211                 :                  strlen(pszGML_FID+nLenPrefix) <= 9 &&
     212                 :                  sscanf(pszGML_FID+nLenPrefix, "%d", &nFID) == 1 )
     213                 :             { /* fid with the prefix. Using its numerical part */
     214              11 :                 if( iNextGMLId < nFID )
     215               5 :                     iNextGMLId = nFID + 1;
     216                 :             }
     217                 :             else
     218                 :             { /* fid without the aforementioned prefix or a valid numerical part */
     219               2 :                 bInvalidFIDFound = TRUE;
     220               2 :                 nFID = iNextGMLId++;
     221                 :             }
     222                 :         }
     223                 : 
     224                 : /* -------------------------------------------------------------------- */
     225                 : /*      Does it satisfy the spatial query, if there is one?             */
     226                 : /* -------------------------------------------------------------------- */
     227                 : 
     228              34 :         if( poGMLFeature->GetGeometry() != NULL )
     229                 :         {
     230              32 :             poGeom = OGRGeometryFactory::createFromGML( poGMLFeature->GetGeometry() );
     231                 :             // We assume the createFromGML() function would have already
     232                 :             // reported the error. 
     233              32 :             if( poGeom == NULL )
     234                 :             {
     235               0 :                 delete poGMLFeature;
     236               0 :                 return NULL;
     237                 :             }
     238                 :             
     239              32 :             if( m_poFilterGeom != NULL && !FilterGeometry( poGeom ) )
     240               0 :                 continue;
     241                 :         }
     242                 :         
     243                 : /* -------------------------------------------------------------------- */
     244                 : /*      Convert the whole feature into an OGRFeature.                   */
     245                 : /* -------------------------------------------------------------------- */
     246                 :         int iField;
     247              34 :         OGRFeature *poOGRFeature = new OGRFeature( GetLayerDefn() );
     248                 : 
     249              34 :         poOGRFeature->SetFID( nFID );
     250                 : 
     251             155 :         for( iField = 0; iField < poFClass->GetPropertyCount(); iField++ )
     252                 :         {
     253             121 :             const char *pszProperty = poGMLFeature->GetProperty( iField );
     254             121 :             if( pszProperty == NULL )
     255               3 :                 continue;
     256                 : 
     257             118 :             switch( poFClass->GetProperty(iField)->GetType()  )
     258                 :             {
     259                 :               case GMLPT_Real:
     260                 :               {
     261              27 :                   poOGRFeature->SetField( iField, CPLAtof(pszProperty) );
     262                 :               }
     263              27 :               break;
     264                 : 
     265                 :               case GMLPT_IntegerList:
     266                 :               {
     267                 :                   char **papszItems = 
     268               0 :                       CSLTokenizeString2( pszProperty, ",", 0 );
     269               0 :                   int nCount = CSLCount(papszItems);
     270               0 :                   int *panIntList = (int *) CPLMalloc(sizeof(int) * nCount );
     271                 :                   int i;
     272                 : 
     273               0 :                   for( i = 0; i < nCount; i++ )
     274               0 :                       panIntList[i] = atoi(papszItems[i]);
     275                 : 
     276               0 :                   poOGRFeature->SetField( iField, nCount, panIntList );
     277               0 :                   CPLFree( panIntList );
     278               0 :                   CSLDestroy( papszItems );
     279                 :               }
     280               0 :               break;
     281                 : 
     282                 :               case GMLPT_RealList:
     283                 :               {
     284                 :                   char **papszItems = 
     285               0 :                       CSLTokenizeString2( pszProperty, ",", 0 );
     286               0 :                   int nCount = CSLCount(papszItems);
     287               0 :                   double *padfList = (double *)CPLMalloc(sizeof(double)*nCount);
     288                 :                   int i;
     289                 : 
     290               0 :                   for( i = 0; i < nCount; i++ )
     291               0 :                       padfList[i] = CPLAtof(papszItems[i]);
     292                 : 
     293               0 :                   poOGRFeature->SetField( iField, nCount, padfList );
     294               0 :                   CPLFree( padfList );
     295               0 :                   CSLDestroy( papszItems );
     296                 :               }
     297               0 :               break;
     298                 : 
     299                 :               case GMLPT_StringList:
     300                 :               {
     301                 :                   char **papszItems = 
     302               0 :                       CSLTokenizeString2( pszProperty, ",", 0 );
     303                 :                   
     304               0 :                   poOGRFeature->SetField( iField, papszItems );
     305               0 :                   CSLDestroy( papszItems );
     306                 :               }
     307               0 :               break;
     308                 : 
     309                 :               default:
     310              91 :                 poOGRFeature->SetField( iField, pszProperty );
     311                 :                 break;
     312                 :             }
     313                 :         }
     314                 : 
     315                 : /* -------------------------------------------------------------------- */
     316                 : /*      Test against the attribute query.                               */
     317                 : /* -------------------------------------------------------------------- */
     318              34 :         if( m_poAttrQuery != NULL
     319                 :             && !m_poAttrQuery->Evaluate( poOGRFeature ) )
     320                 :         {
     321               1 :             delete poOGRFeature;
     322               1 :             continue;
     323                 :         }
     324                 : 
     325                 : /* -------------------------------------------------------------------- */
     326                 : /*      Wow, we got our desired feature. Return it.                     */
     327                 : /* -------------------------------------------------------------------- */
     328              33 :         delete poGMLFeature;
     329                 : 
     330              33 :         poOGRFeature->SetGeometryDirectly( poGeom );
     331                 : 
     332              33 :         return poOGRFeature;
     333                 :     }
     334                 : 
     335                 :     return NULL;
     336                 : }
     337                 : 
     338                 : /************************************************************************/
     339                 : /*                          GetFeatureCount()                           */
     340                 : /************************************************************************/
     341                 : 
     342               2 : int OGRGMLLayer::GetFeatureCount( int bForce )
     343                 : 
     344                 : {
     345               2 :     if( poFClass == NULL )
     346               0 :         return 0;
     347                 : 
     348               2 :     if( m_poFilterGeom != NULL || m_poAttrQuery != NULL )
     349               0 :         return OGRLayer::GetFeatureCount( bForce );
     350                 :     else
     351                 :     {
     352                 :         /* If the schema is read from a .xsd file, we haven't read */
     353                 :         /* the feature count, so compute it now */
     354               2 :         int nFeatureCount = poFClass->GetFeatureCount();
     355               2 :         if (nFeatureCount < 0)
     356                 :         {
     357               1 :             nFeatureCount = OGRLayer::GetFeatureCount(bForce);
     358               1 :             poFClass->SetFeatureCount(nFeatureCount);
     359                 :         }
     360               2 :         return nFeatureCount;
     361                 :     }
     362                 : }
     363                 : 
     364                 : /************************************************************************/
     365                 : /*                             GetExtent()                              */
     366                 : /************************************************************************/
     367                 : 
     368               0 : OGRErr OGRGMLLayer::GetExtent(OGREnvelope *psExtent, int bForce )
     369                 : 
     370                 : {
     371                 :     double dfXMin, dfXMax, dfYMin, dfYMax;
     372                 : 
     373               0 :     if( poFClass != NULL && 
     374                 :         poFClass->GetExtents( &dfXMin, &dfXMax, &dfYMin, &dfYMax ) )
     375                 :     {
     376               0 :         psExtent->MinX = dfXMin;
     377               0 :         psExtent->MaxX = dfXMax;
     378               0 :         psExtent->MinY = dfYMin;
     379               0 :         psExtent->MaxY = dfYMax;
     380                 : 
     381               0 :         return OGRERR_NONE;
     382                 :     }
     383                 :     else 
     384               0 :         return OGRLayer::GetExtent( psExtent, bForce );
     385                 : }
     386                 : 
     387                 : /************************************************************************/
     388                 : /*                           CreateFeature()                            */
     389                 : /************************************************************************/
     390                 : 
     391               2 : OGRErr OGRGMLLayer::CreateFeature( OGRFeature *poFeature )
     392                 : 
     393                 : {
     394               2 :     FILE        *fp = poDS->GetOutputFP();
     395                 : 
     396               2 :     if( !bWriter )
     397               0 :         return OGRERR_FAILURE;
     398                 : 
     399               2 :     poDS->PrintLine( fp, "  <gml:featureMember>" );
     400                 : 
     401               2 :     if( poFeature->GetFID() == OGRNullFID )
     402               2 :         poFeature->SetFID( iNextGMLId++ );
     403                 : 
     404                 :     poDS->PrintLine( fp, "    <ogr:%s fid=\"F%ld\">", 
     405                 :                 poFeatureDefn->GetName(),
     406               2 :                 poFeature->GetFID() );
     407                 : 
     408                 :     // Write out Geometry - for now it isn't indented properly.
     409               2 :     if( poFeature->GetGeometryRef() != NULL )
     410                 :     {
     411                 :         char    *pszGeometry;
     412               0 :         OGREnvelope sGeomBounds;
     413                 : 
     414               0 :         pszGeometry = poFeature->GetGeometryRef()->exportToGML();
     415                 :         poDS->PrintLine( fp, "      <ogr:geometryProperty>%s</ogr:geometryProperty>",
     416               0 :                     pszGeometry );
     417               0 :         CPLFree( pszGeometry );
     418                 : 
     419               0 :         poFeature->GetGeometryRef()->getEnvelope( &sGeomBounds );
     420               0 :         poDS->GrowExtents( &sGeomBounds );
     421                 :     }
     422                 : 
     423                 :     // Write all "set" fields. 
     424               8 :     for( int iField = 0; iField < poFeatureDefn->GetFieldCount(); iField++ )
     425                 :     {
     426                 :         
     427               6 :         OGRFieldDefn *poFieldDefn = poFeatureDefn->GetFieldDefn( iField );
     428                 : 
     429               6 :         if( poFeature->IsFieldSet( iField ) )
     430                 :         {
     431               6 :             const char *pszRaw = poFeature->GetFieldAsString( iField );
     432                 : 
     433              12 :             while( *pszRaw == ' ' )
     434               0 :                 pszRaw++;
     435                 : 
     436               6 :             char *pszEscaped = OGRGetXML_UTF8_EscapedString( pszRaw );
     437                 : 
     438               6 :             if (poFieldDefn->GetType() == OFTReal)
     439                 :             {
     440                 :                 /* Use point as decimal separator */
     441               2 :                 char* pszComma = strchr(pszEscaped, ',');
     442               2 :                 if (pszComma)
     443               0 :                     *pszComma = '.';
     444                 :             }
     445                 : 
     446                 :             poDS->PrintLine( fp, "      <ogr:%s>%s</ogr:%s>", 
     447                 :                         poFieldDefn->GetNameRef(), pszEscaped, 
     448               6 :                         poFieldDefn->GetNameRef() );
     449               6 :             CPLFree( pszEscaped );
     450                 :         }
     451                 :     }
     452                 : 
     453               2 :     poDS->PrintLine( fp, "    </ogr:%s>", poFeatureDefn->GetName() );
     454               2 :     poDS->PrintLine( fp, "  </gml:featureMember>" );
     455                 : 
     456               2 :     return OGRERR_NONE;
     457                 : }
     458                 : 
     459                 : /************************************************************************/
     460                 : /*                           TestCapability()                           */
     461                 : /************************************************************************/
     462                 : 
     463               0 : int OGRGMLLayer::TestCapability( const char * pszCap )
     464                 : 
     465                 : {
     466               0 :     if( EQUAL(pszCap,OLCSequentialWrite) )
     467               0 :         return bWriter;
     468                 : 
     469               0 :     else if( EQUAL(pszCap,OLCCreateField) )
     470               0 :         return bWriter && iNextGMLId == 0;
     471                 : 
     472               0 :     else if( EQUAL(pszCap,OLCFastGetExtent) )
     473                 :     {
     474                 :         double  dfXMin, dfXMax, dfYMin, dfYMax;
     475                 : 
     476               0 :         if( poFClass == NULL )
     477               0 :             return FALSE;
     478                 : 
     479               0 :         return poFClass->GetExtents( &dfXMin, &dfXMax, &dfYMin, &dfYMax );
     480                 :     }
     481                 : 
     482               0 :     else if( EQUAL(pszCap,OLCFastFeatureCount) )
     483                 :     {
     484               0 :         if( poFClass == NULL 
     485                 :             || m_poFilterGeom != NULL 
     486                 :             || m_poAttrQuery != NULL )
     487               0 :             return FALSE;
     488                 : 
     489               0 :         return poFClass->GetFeatureCount() != -1;
     490                 :     }
     491                 : 
     492               0 :     else if( EQUAL(pszCap,OLCStringsAsUTF8) )
     493               0 :         return TRUE;
     494                 : 
     495                 :     else 
     496               0 :         return FALSE;
     497                 : }
     498                 : 
     499                 : /************************************************************************/
     500                 : /*                            CreateField()                             */
     501                 : /************************************************************************/
     502                 : 
     503               6 : OGRErr OGRGMLLayer::CreateField( OGRFieldDefn *poField, int bApproxOK )
     504                 : 
     505                 : {
     506               6 :     if( !bWriter || iNextGMLId != 0 )
     507               0 :         return OGRERR_FAILURE;
     508                 : 
     509                 : /* -------------------------------------------------------------------- */
     510                 : /*      Enforce XML naming semantics on element name.                   */
     511                 : /* -------------------------------------------------------------------- */
     512               6 :     OGRFieldDefn oCleanCopy( poField );
     513               6 :     char *pszName = CPLStrdup( poField->GetNameRef() );
     514               6 :     CPLCleanXMLElementName( pszName );
     515                 :     
     516               6 :     if( strcmp(pszName,poField->GetNameRef()) != 0 )
     517                 :     {
     518               0 :         if( !bApproxOK )
     519                 :         {
     520               0 :             CPLFree( pszName );
     521                 :             CPLError( CE_Failure, CPLE_AppDefined, 
     522                 :                       "Unable to create field with name '%s', it would not\n"
     523                 :                       "be valid as an XML element name.",
     524               0 :                       poField->GetNameRef() );
     525               6 :             return OGRERR_FAILURE;
     526                 :         }
     527                 : 
     528               0 :         oCleanCopy.SetName( pszName );
     529                 :         CPLError( CE_Warning, CPLE_AppDefined, 
     530                 :                   "Field name '%s' adjusted to '%s' to be a valid\n"
     531                 :                   "XML element name.",
     532               0 :                   poField->GetNameRef(), pszName );
     533                 :     }
     534                 : 
     535               6 :     CPLFree( pszName );
     536                 : 
     537                 :     
     538               6 :     poFeatureDefn->AddFieldDefn( &oCleanCopy );
     539                 : 
     540               6 :     return OGRERR_NONE;
     541                 : }
     542                 : 
     543                 : /************************************************************************/
     544                 : /*                           GetSpatialRef()                            */
     545                 : /************************************************************************/
     546                 : 
     547               0 : OGRSpatialReference *OGRGMLLayer::GetSpatialRef()
     548                 : 
     549                 : {
     550               0 :     return poSRS;
     551                 : }
     552                 : 
     553                 : /************************************************************************/
     554                 : /*                         GetGeometryColumn()                          */
     555                 : /************************************************************************/
     556                 : 
     557               2 : const char* OGRGMLLayer::GetGeometryColumn()
     558                 : {
     559               2 :     if( poFClass == NULL || poFClass->GetGeometryElement() == NULL )
     560               0 :         return "";
     561                 : 
     562               2 :     return poFClass->GetGeometryElement();
     563                 : }

Generated by: LTP GCOV extension version 1.5