LCOV - code coverage report
Current view: directory - ogr - ogr2gmlgeometry.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 181 146 80.7 %
Date: 2010-01-09 Functions: 8 6 75.0 %

       1                 : /******************************************************************************
       2                 :  * $Id: ogr2gmlgeometry.cpp 18025 2009-11-14 19:09:50Z rouault $
       3                 :  *
       4                 :  * Project:  GML Translator
       5                 :  * Purpose:  Code to translate OGRGeometry to GML string representation.
       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 OR
      22                 :  * 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                 :  * Independent Security Audit 2003/04/17 Andrey Kiselev:
      31                 :  *   Completed audit of this module. All functions may be used without buffer
      32                 :  *   overflows and stack corruptions if caller could be trusted.
      33                 :  *
      34                 :  * Security Audit 2003/03/28 warmerda:
      35                 :  *   Completed security audit.  I believe that this module may be safely used 
      36                 :  *   to generate GML from arbitrary but well formed OGRGeomety objects that
      37                 :  *   come from a potentially hostile source, but through a trusted OGR importer
      38                 :  *   without compromising the system.
      39                 :  *
      40                 :  */
      41                 : 
      42                 : #include "cpl_minixml.h"
      43                 : #include "ogr_geometry.h"
      44                 : #include "ogr_api.h"
      45                 : #include "ogr_p.h"
      46                 : #include "cpl_error.h"
      47                 : #include "cpl_conv.h"
      48                 : 
      49                 : /************************************************************************/
      50                 : /*                        MakeGMLCoordinate()                           */
      51                 : /************************************************************************/
      52                 : 
      53             157 : static void MakeGMLCoordinate( char *pszTarget, 
      54                 :                                double x, double y, double z, int b3D )
      55                 : 
      56                 : {
      57             157 :     OGRMakeWktCoordinate( pszTarget, x, y, z, b3D ? 3 : 2 );
      58            4110 :     while( *pszTarget != '\0' )
      59                 :     {
      60            3796 :         if( *pszTarget == ' ' )
      61             180 :             *pszTarget = ',';
      62            3796 :         pszTarget++;
      63                 :     }
      64                 : 
      65                 : #ifdef notdef
      66                 :     if( !b3D )
      67                 :     {
      68                 :         if( x == (int) x && y == (int) y )
      69                 :             sprintf( pszTarget, "%d,%d", (int) x, (int) y );
      70                 :         else if( fabs(x) < 370 && fabs(y) < 370 )
      71                 :             sprintf( pszTarget, "%.16g,%.16g", x, y );
      72                 :         else if( fabs(x) > 100000000.0 || fabs(y) > 100000000.0 )
      73                 :             sprintf( pszTarget, "%.16g,%.16g", x, y );
      74                 :         else
      75                 :             sprintf( pszTarget, "%.3f,%.3f", x, y );
      76                 :     }
      77                 :     else
      78                 :     {
      79                 :         if( x == (int) x && y == (int) y && z == (int) z )
      80                 :             sprintf( pszTarget, "%d,%d,%d", (int) x, (int) y, (int) z );
      81                 :         else if( fabs(x) < 370 && fabs(y) < 370 )
      82                 :             sprintf( pszTarget, "%.16g,%.16g,%.16g", x, y, z );
      83                 :         else if( fabs(x) > 100000000.0 || fabs(y) > 100000000.0 
      84                 :                  || fabs(z) > 100000000.0 )
      85                 :             sprintf( pszTarget, "%.16g,%.16g,%.16g", x, y, z );
      86                 :         else
      87                 :             sprintf( pszTarget, "%.3f,%.3f,%.3f", x, y, z );
      88                 :     }
      89                 : #endif
      90             157 : }
      91                 : 
      92                 : /************************************************************************/
      93                 : /*                            _GrowBuffer()                             */
      94                 : /************************************************************************/
      95                 : 
      96             489 : static void _GrowBuffer( int nNeeded, char **ppszText, int *pnMaxLength )
      97                 : 
      98                 : {
      99             489 :     if( nNeeded+1 >= *pnMaxLength )
     100                 :     {
     101             117 :         *pnMaxLength = MAX(*pnMaxLength * 2,nNeeded+1);
     102             117 :         *ppszText = (char *) CPLRealloc(*ppszText, *pnMaxLength);
     103                 :     }
     104             489 : }
     105                 : 
     106                 : /************************************************************************/
     107                 : /*                            AppendString()                            */
     108                 : /************************************************************************/
     109                 : 
     110             276 : static void AppendString( char **ppszText, int *pnLength, int *pnMaxLength,
     111                 :                           const char *pszTextToAppend )
     112                 : 
     113                 : {
     114                 :     _GrowBuffer( *pnLength + strlen(pszTextToAppend) + 1, 
     115             276 :                  ppszText, pnMaxLength );
     116                 : 
     117             276 :     strcat( *ppszText + *pnLength, pszTextToAppend );
     118             276 :     *pnLength += strlen( *ppszText + *pnLength );
     119             276 : }
     120                 : 
     121                 : 
     122                 : /************************************************************************/
     123                 : /*                        AppendCoordinateList()                        */
     124                 : /************************************************************************/
     125                 : 
     126              28 : static void AppendCoordinateList( OGRLineString *poLine, 
     127                 :                                   char **ppszText, int *pnLength, 
     128                 :                                   int *pnMaxLength )
     129                 : 
     130                 : {
     131                 :     char        szCoordinate[256];
     132              28 :     int         b3D = (poLine->getGeometryType() & wkb25DBit);
     133                 : 
     134              28 :     *pnLength += strlen(*ppszText + *pnLength);
     135              28 :     _GrowBuffer( *pnLength + 20, ppszText, pnMaxLength );
     136                 : 
     137              28 :     strcat( *ppszText + *pnLength, "<gml:coordinates>" );
     138              28 :     *pnLength += strlen(*ppszText + *pnLength);
     139                 : 
     140                 :     
     141             164 :     for( int iPoint = 0; iPoint < poLine->getNumPoints(); iPoint++ )
     142                 :     {
     143                 :         MakeGMLCoordinate( szCoordinate, 
     144                 :                            poLine->getX(iPoint),
     145                 :                            poLine->getY(iPoint),
     146                 :                            poLine->getZ(iPoint),
     147             136 :                            b3D );
     148                 :         _GrowBuffer( *pnLength + strlen(szCoordinate)+1, 
     149             136 :                      ppszText, pnMaxLength );
     150                 : 
     151             136 :         if( iPoint != 0 )
     152             108 :             strcat( *ppszText + *pnLength, " " );
     153                 :             
     154             136 :         strcat( *ppszText + *pnLength, szCoordinate );
     155             136 :         *pnLength += strlen(*ppszText + *pnLength);
     156                 :     }
     157                 :     
     158              28 :     _GrowBuffer( *pnLength + 20, ppszText, pnMaxLength );
     159              28 :     strcat( *ppszText + *pnLength, "</gml:coordinates>" );
     160              28 :     *pnLength += strlen(*ppszText + *pnLength);
     161              28 : }
     162                 : 
     163                 : /************************************************************************/
     164                 : /*                       OGR2GMLGeometryAppend()                        */
     165                 : /************************************************************************/
     166                 : 
     167              70 : static int OGR2GMLGeometryAppend( OGRGeometry *poGeometry, 
     168                 :                                   char **ppszText, int *pnLength, 
     169                 :                                   int *pnMaxLength,
     170                 :                                   int bIsSubGeometry )
     171                 : 
     172                 : {
     173                 : 
     174                 : /* -------------------------------------------------------------------- */
     175                 : /*      Check for Spatial Reference System attached to given geometry   */
     176                 : /* -------------------------------------------------------------------- */
     177                 : 
     178                 :     // Buffer for srsName attribute (srsName="...")
     179              70 :     char szSrsName[30] = { 0 }; 
     180              70 :     int nSrsNameLength = 0;
     181                 : 
     182              70 :     const OGRSpatialReference* poSRS = NULL;
     183              70 :     poSRS = poGeometry->getSpatialReference();
     184                 : 
     185              70 :     if( NULL != poSRS && !bIsSubGeometry )
     186                 :     {
     187               8 :         const char* pszAuthName = NULL;
     188               8 :         const char* pszAuthCode = NULL;
     189               8 :         const char* pszTarget = NULL;
     190                 : 
     191               8 :         if (poSRS->IsProjected())
     192               0 :             pszTarget = "PROJCS";
     193                 :         else
     194               8 :             pszTarget = "GEOGCS";
     195                 : 
     196               8 :         pszAuthName = poSRS->GetAuthorityName( pszTarget );
     197               8 :         if( NULL != pszAuthName )
     198                 :         {
     199               8 :             if( EQUAL( pszAuthName, "EPSG" ) )
     200                 :             {
     201               8 :                 pszAuthCode = poSRS->GetAuthorityCode( pszTarget );
     202               8 :                 if( NULL != pszAuthCode && strlen(pszAuthCode) < 10 )
     203                 :                 {
     204                 :                     sprintf( szSrsName, " srsName=\"%s:%s\"",
     205               8 :                             pszAuthName, pszAuthCode );
     206                 : 
     207               8 :                     nSrsNameLength = strlen(szSrsName);
     208                 :                 }
     209                 :             }
     210                 :         }
     211                 :     }
     212                 : 
     213                 : /* -------------------------------------------------------------------- */
     214                 : /*      2D Point                                                        */
     215                 : /* -------------------------------------------------------------------- */
     216              70 :     if( poGeometry->getGeometryType() == wkbPoint )
     217                 :     {
     218                 :         char    szCoordinate[256];
     219              17 :         OGRPoint *poPoint = (OGRPoint *) poGeometry;
     220                 : 
     221                 :         MakeGMLCoordinate( szCoordinate, 
     222              17 :                            poPoint->getX(), poPoint->getY(), 0.0, FALSE );
     223                 : 
     224                 :         _GrowBuffer( *pnLength + strlen(szCoordinate) + 60 + nSrsNameLength, 
     225              17 :                      ppszText, pnMaxLength );
     226                 : 
     227                 :         sprintf( *ppszText + *pnLength, 
     228                 :                 "<gml:Point%s><gml:coordinates>%s</gml:coordinates></gml:Point>",
     229              17 :                  szSrsName, szCoordinate );
     230                 : 
     231              17 :         *pnLength += strlen( *ppszText + *pnLength );
     232                 :     }
     233                 : /* -------------------------------------------------------------------- */
     234                 : /*      3D Point                                                        */
     235                 : /* -------------------------------------------------------------------- */
     236              53 :     else if( poGeometry->getGeometryType() == wkbPoint25D )
     237                 :     {
     238                 :         char    szCoordinate[256];
     239               4 :         OGRPoint *poPoint = (OGRPoint *) poGeometry;
     240                 : 
     241                 :         MakeGMLCoordinate( szCoordinate, 
     242                 :                            poPoint->getX(), poPoint->getY(), poPoint->getZ(), 
     243               4 :                            TRUE );
     244                 :                            
     245                 :         _GrowBuffer( *pnLength + strlen(szCoordinate) + 70 + nSrsNameLength, 
     246               4 :                      ppszText, pnMaxLength );
     247                 : 
     248                 :         sprintf( *ppszText + *pnLength, 
     249                 :                 "<gml:Point%s><gml:coordinates>%s</gml:coordinates></gml:Point>",
     250               4 :                  szSrsName, szCoordinate );
     251                 : 
     252               4 :         *pnLength += strlen( *ppszText + *pnLength );
     253                 :     }
     254                 : 
     255                 : /* -------------------------------------------------------------------- */
     256                 : /*      LineString and LinearRing                                       */
     257                 : /* -------------------------------------------------------------------- */
     258              75 :     else if( poGeometry->getGeometryType() == wkbLineString 
     259              26 :              || poGeometry->getGeometryType() == wkbLineString25D )
     260                 :     {
     261              28 :         int bRing = EQUAL(poGeometry->getGeometryName(),"LINEARRING");
     262                 : 
     263                 :         // Buffer for tag name + srsName attribute if set
     264              28 :         const size_t nLineTagLength = 16;
     265              28 :         char* pszLineTagName = NULL;
     266              28 :         pszLineTagName = (char *) CPLMalloc( nLineTagLength + nSrsNameLength + 1 );
     267                 : 
     268              28 :         if( bRing )
     269                 :         {
     270              13 :             sprintf( pszLineTagName, "<gml:LinearRing%s>", szSrsName );
     271                 : 
     272                 :             AppendString( ppszText, pnLength, pnMaxLength,
     273              13 :                           pszLineTagName );
     274                 :         }
     275                 :         else
     276                 :         {
     277              15 :             sprintf( pszLineTagName, "<gml:LineString%s>", szSrsName );
     278                 : 
     279                 :             AppendString( ppszText, pnLength, pnMaxLength,
     280              15 :                           pszLineTagName );
     281                 :         }
     282                 : 
     283                 :         // FREE TAG BUFFER
     284              28 :         CPLFree( pszLineTagName );
     285                 : 
     286                 :         AppendCoordinateList( (OGRLineString *) poGeometry, 
     287              28 :                               ppszText, pnLength, pnMaxLength );
     288                 :         
     289              28 :         if( bRing )
     290                 :             AppendString( ppszText, pnLength, pnMaxLength,
     291              13 :                           "</gml:LinearRing>" );
     292                 :         else
     293                 :             AppendString( ppszText, pnLength, pnMaxLength,
     294              15 :                           "</gml:LineString>" );
     295                 :     }
     296                 : 
     297                 : /* -------------------------------------------------------------------- */
     298                 : /*      Polygon                                                         */
     299                 : /* -------------------------------------------------------------------- */
     300              33 :     else if( poGeometry->getGeometryType() == wkbPolygon 
     301              12 :              || poGeometry->getGeometryType() == wkbPolygon25D )
     302                 :     {
     303              11 :         OGRPolygon      *poPolygon = (OGRPolygon *) poGeometry;
     304                 : 
     305                 :         // Buffer for polygon tag name + srsName attribute if set
     306              11 :         const size_t nPolyTagLength = 13;
     307              11 :         char* pszPolyTagName = NULL;
     308              11 :         pszPolyTagName = (char *) CPLMalloc( nPolyTagLength + nSrsNameLength + 1 );
     309                 : 
     310                 :         // Compose Polygon tag with or without srsName attribute
     311              11 :         sprintf( pszPolyTagName, "<gml:Polygon%s>", szSrsName );
     312                 : 
     313                 :         AppendString( ppszText, pnLength, pnMaxLength,
     314              11 :                       pszPolyTagName );
     315                 : 
     316                 :         // FREE TAG BUFFER
     317              11 :         CPLFree( pszPolyTagName );
     318                 : 
     319                 :         // Don't add srsName to polygon rings
     320                 : 
     321              11 :         if( poPolygon->getExteriorRing() != NULL )
     322                 :         {
     323                 :             AppendString( ppszText, pnLength, pnMaxLength,
     324              11 :                           "<gml:outerBoundaryIs>" );
     325                 : 
     326              11 :             if( !OGR2GMLGeometryAppend( poPolygon->getExteriorRing(), 
     327                 :                                         ppszText, pnLength, pnMaxLength,
     328                 :                                         TRUE ) )
     329                 :             {
     330               0 :                 return FALSE;
     331                 :             }
     332                 :             
     333                 :             AppendString( ppszText, pnLength, pnMaxLength,
     334              11 :                           "</gml:outerBoundaryIs>" );
     335                 :         }
     336                 : 
     337              13 :         for( int iRing = 0; iRing < poPolygon->getNumInteriorRings(); iRing++ )
     338                 :         {
     339               2 :             OGRLinearRing *poRing = poPolygon->getInteriorRing(iRing);
     340                 : 
     341                 :             AppendString( ppszText, pnLength, pnMaxLength,
     342               2 :                           "<gml:innerBoundaryIs>" );
     343                 :             
     344               2 :             if( !OGR2GMLGeometryAppend( poRing, ppszText, pnLength, 
     345                 :                                         pnMaxLength, TRUE ) )
     346               0 :                 return FALSE;
     347                 :             
     348                 :             AppendString( ppszText, pnLength, pnMaxLength,
     349               2 :                           "</gml:innerBoundaryIs>" );
     350                 :         }
     351                 : 
     352                 :         AppendString( ppszText, pnLength, pnMaxLength,
     353              11 :                       "</gml:Polygon>" );
     354                 :     }
     355                 : 
     356                 : /* -------------------------------------------------------------------- */
     357                 : /*      MultiPolygon                                                    */
     358                 : /* -------------------------------------------------------------------- */
     359              27 :     else if( wkbFlatten(poGeometry->getGeometryType()) == wkbMultiPolygon 
     360               8 :              || wkbFlatten(poGeometry->getGeometryType()) == wkbMultiLineString
     361               6 :              || wkbFlatten(poGeometry->getGeometryType()) == wkbMultiPoint
     362               3 :              || wkbFlatten(poGeometry->getGeometryType()) == wkbGeometryCollection )
     363                 :     {
     364              10 :         OGRGeometryCollection *poGC = (OGRGeometryCollection *) poGeometry;
     365                 :         int             iMember;
     366              10 :         const char *pszElemClose = NULL;
     367              10 :         const char *pszMemberElem = NULL;
     368                 : 
     369                 :         // Buffer for opening tag + srsName attribute
     370              10 :         char* pszElemOpen = NULL;
     371                 : 
     372              10 :         if( wkbFlatten(poGeometry->getGeometryType()) == wkbMultiPolygon )
     373                 :         {
     374               2 :             pszElemOpen = (char *) CPLMalloc( 13 + nSrsNameLength + 1 );
     375               2 :             sprintf( pszElemOpen, "MultiPolygon%s>", szSrsName );
     376                 : 
     377               2 :             pszElemClose = "MultiPolygon>";
     378               2 :             pszMemberElem = "polygonMember>";
     379                 :         }
     380               8 :         else if( wkbFlatten(poGeometry->getGeometryType()) == wkbMultiLineString )
     381                 :         {
     382               2 :             pszElemOpen = (char *) CPLMalloc( 16 + nSrsNameLength + 1 );
     383               2 :             sprintf( pszElemOpen, "MultiLineString%s>", szSrsName );
     384                 : 
     385               2 :             pszElemClose = "MultiLineString>";
     386               2 :             pszMemberElem = "lineStringMember>";
     387                 :         }
     388               6 :         else if( wkbFlatten(poGeometry->getGeometryType()) == wkbMultiPoint )
     389                 :         {
     390               3 :             pszElemOpen = (char *) CPLMalloc( 11 + nSrsNameLength + 1 );
     391               3 :             sprintf( pszElemOpen, "MultiPoint%s>", szSrsName );
     392                 : 
     393               3 :             pszElemClose = "MultiPoint>";
     394               3 :             pszMemberElem = "pointMember>";
     395                 :         }
     396                 :         else
     397                 :         {
     398               3 :             pszElemOpen = (char *) CPLMalloc( 19 + nSrsNameLength + 1 );
     399               3 :             sprintf( pszElemOpen, "GeometryCollection%s>", szSrsName );
     400                 : 
     401               3 :             pszElemClose = "GeometryCollection>";
     402               3 :             pszMemberElem = "geometryMember>";
     403                 :         }
     404                 : 
     405              10 :         AppendString( ppszText, pnLength, pnMaxLength, "<gml:" );
     406              10 :         AppendString( ppszText, pnLength, pnMaxLength, pszElemOpen );
     407                 : 
     408              43 :         for( iMember = 0; iMember < poGC->getNumGeometries(); iMember++)
     409                 :         {
     410              33 :             OGRGeometry *poMember = poGC->getGeometryRef( iMember );
     411                 : 
     412              33 :             AppendString( ppszText, pnLength, pnMaxLength, "<gml:" );
     413              33 :             AppendString( ppszText, pnLength, pnMaxLength, pszMemberElem );
     414                 :             
     415              33 :             if( !OGR2GMLGeometryAppend( poMember, 
     416                 :                                         ppszText, pnLength, pnMaxLength,
     417                 :                                         TRUE ) )
     418                 :             {
     419               0 :                 return FALSE;
     420                 :             }
     421                 :             
     422              33 :             AppendString( ppszText, pnLength, pnMaxLength, "</gml:" );
     423              33 :             AppendString( ppszText, pnLength, pnMaxLength, pszMemberElem );
     424                 :         }
     425                 : 
     426              10 :         AppendString( ppszText, pnLength, pnMaxLength, "</gml:" );
     427              10 :         AppendString( ppszText, pnLength, pnMaxLength, pszElemClose );
     428                 : 
     429                 :         // FREE TAG BUFFER
     430              10 :         CPLFree( pszElemOpen );
     431                 :     }
     432                 :     else
     433                 :     {
     434               0 :         return FALSE;
     435                 :     }
     436                 : 
     437              70 :     return TRUE;
     438                 : }
     439                 : 
     440                 : /************************************************************************/
     441                 : /*                   OGR_G_ExportEnvelopeToGMLTree()                    */
     442                 : /*                                                                      */
     443                 : /*      Export the envelope of a geometry as a gml:Box.                 */
     444                 : /************************************************************************/
     445                 : 
     446               0 : CPLXMLNode *OGR_G_ExportEnvelopeToGMLTree( OGRGeometryH hGeometry )
     447                 : 
     448                 : {
     449                 :     CPLXMLNode *psBox, *psCoord;
     450               0 :     OGREnvelope sEnvelope;
     451                 :     char        szCoordinate[256];
     452                 :     char       *pszY;
     453                 : 
     454               0 :     memset( &sEnvelope, 0, sizeof(sEnvelope) );
     455               0 :     ((OGRGeometry *) hGeometry)->getEnvelope( &sEnvelope );
     456                 : 
     457               0 :     if( sEnvelope.MinX == 0 && sEnvelope.MaxX == 0 
     458                 :         && sEnvelope.MaxX == 0 && sEnvelope.MaxY == 0 )
     459                 :     {
     460                 :         /* there is apparently a special way of representing a null box
     461                 :            geometry ... we should use it here eventually. */
     462                 : 
     463               0 :         return NULL;
     464                 :     }
     465                 : 
     466               0 :     psBox = CPLCreateXMLNode( NULL, CXT_Element, "gml:Box" );
     467                 : 
     468                 : /* -------------------------------------------------------------------- */
     469                 : /*      Add minxy coordinate.                                           */
     470                 : /* -------------------------------------------------------------------- */
     471               0 :     psCoord = CPLCreateXMLNode( psBox, CXT_Element, "gml:coord" );
     472                 :     
     473                 :     MakeGMLCoordinate( szCoordinate, sEnvelope.MinX, sEnvelope.MinY, 0.0, 
     474               0 :                        FALSE );
     475               0 :     pszY = strstr(szCoordinate,",") + 1;
     476               0 :     pszY[-1] = '\0';
     477                 : 
     478               0 :     CPLCreateXMLElementAndValue( psCoord, "gml:X", szCoordinate );
     479               0 :     CPLCreateXMLElementAndValue( psCoord, "gml:Y", pszY );
     480                 : 
     481                 : /* -------------------------------------------------------------------- */
     482                 : /*      Add maxxy coordinate.                                           */
     483                 : /* -------------------------------------------------------------------- */
     484               0 :     psCoord = CPLCreateXMLNode( psBox, CXT_Element, "gml:coord" );
     485                 :     
     486                 :     MakeGMLCoordinate( szCoordinate, sEnvelope.MaxX, sEnvelope.MaxY, 0.0, 
     487               0 :                        FALSE );
     488               0 :     pszY = strstr(szCoordinate,",") + 1;
     489               0 :     pszY[-1] = '\0';
     490                 : 
     491               0 :     CPLCreateXMLElementAndValue( psCoord, "gml:X", szCoordinate );
     492               0 :     CPLCreateXMLElementAndValue( psCoord, "gml:Y", pszY );
     493                 : 
     494               0 :     return psBox;
     495                 : }
     496                 : 
     497                 : /************************************************************************/
     498                 : /*                       OGR_G_ExportToGMLTree()                        */
     499                 : /************************************************************************/
     500                 : 
     501               0 : CPLXMLNode *OGR_G_ExportToGMLTree( OGRGeometryH hGeometry )
     502                 : 
     503                 : {
     504                 :     char        *pszText;
     505                 :     CPLXMLNode  *psTree;
     506                 : 
     507               0 :     pszText = OGR_G_ExportToGML( hGeometry );
     508               0 :     if( pszText == NULL )
     509               0 :         return NULL;
     510                 : 
     511               0 :     psTree = CPLParseXMLString( pszText );
     512                 : 
     513               0 :     CPLFree( pszText );
     514                 : 
     515               0 :     return psTree;
     516                 : }
     517                 : 
     518                 : /************************************************************************/
     519                 : /*                         OGR_G_ExportToGML()                          */
     520                 : /************************************************************************/
     521                 : 
     522              24 : char *OGR_G_ExportToGML( OGRGeometryH hGeometry )
     523                 : 
     524                 : {
     525                 :     char        *pszText;
     526              24 :     int         nLength = 0, nMaxLength = 1;
     527                 : 
     528              24 :     if( hGeometry == NULL )
     529               0 :         return CPLStrdup( "" );
     530                 : 
     531              24 :     pszText = (char *) CPLMalloc(nMaxLength);
     532              24 :     pszText[0] = '\0';
     533                 : 
     534              24 :     if( !OGR2GMLGeometryAppend( (OGRGeometry *) hGeometry, &pszText, 
     535                 :                                 &nLength, &nMaxLength, FALSE ))
     536                 :     {
     537               0 :         CPLFree( pszText );
     538               0 :         return NULL;
     539                 :     }
     540                 :     else
     541              24 :         return pszText;
     542                 : }

Generated by: LCOV version 1.7