LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/gml - gmlfeatureclass.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 190 129 67.9 %
Date: 2010-01-09 Functions: 16 12 75.0 %

       1                 : /**********************************************************************
       2                 :  * $Id: gmlfeatureclass.cpp 17629 2009-09-10 14:51:45Z chaitanya $
       3                 :  *
       4                 :  * Project:  GML Reader
       5                 :  * Purpose:  Implementation of GMLFeatureClass.
       6                 :  * Author:   Frank Warmerdam, warmerdam@pobox.com
       7                 :  *
       8                 :  **********************************************************************
       9                 :  * Copyright (c) 2002, Frank Warmerdam
      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                 : #include "gmlreader.h"
      31                 : #include "cpl_conv.h"
      32                 : 
      33                 : /************************************************************************/
      34                 : /*                          GMLFeatureClass()                           */
      35                 : /************************************************************************/
      36                 : 
      37              15 : GMLFeatureClass::GMLFeatureClass( const char *pszName )
      38                 : 
      39                 : {
      40              15 :     m_pszName = CPLStrdup( pszName );
      41              15 :     m_pszElementName = NULL;
      42              15 :     m_pszGeometryElement = NULL;
      43              15 :     m_nPropertyCount = 0;
      44              15 :     m_papoProperty = NULL;
      45              15 :     m_bSchemaLocked = FALSE;
      46                 : 
      47              15 :     m_pszExtraInfo = NULL;
      48              15 :     m_bHaveExtents = FALSE;
      49              15 :     m_nFeatureCount = -1; // unknown
      50                 : 
      51              15 :     m_nGeometryType = 0; // wkbUnknown
      52              15 : }
      53                 : 
      54                 : /************************************************************************/
      55                 : /*                          ~GMLFeatureClass()                          */
      56                 : /************************************************************************/
      57                 : 
      58              15 : GMLFeatureClass::~GMLFeatureClass()
      59                 : 
      60                 : {
      61              15 :     CPLFree( m_pszName );
      62              15 :     CPLFree( m_pszElementName );
      63              15 :     CPLFree( m_pszGeometryElement );
      64                 : 
      65              64 :     for( int i = 0; i < m_nPropertyCount; i++ )
      66              49 :         delete m_papoProperty[i];
      67              15 :     CPLFree( m_papoProperty );
      68              15 : }
      69                 : 
      70                 : /************************************************************************/
      71                 : /*                           GetProperty(int)                           */
      72                 : /************************************************************************/
      73                 : 
      74             871 : GMLPropertyDefn *GMLFeatureClass::GetProperty( int iIndex ) const
      75                 : 
      76                 : {
      77             871 :     if( iIndex < 0 || iIndex >= m_nPropertyCount )
      78               0 :         return NULL;
      79                 :     else
      80             871 :         return m_papoProperty[iIndex];
      81                 : }
      82                 : 
      83                 : /************************************************************************/
      84                 : /*                          GetPropertyIndex()                          */
      85                 : /************************************************************************/
      86                 : 
      87               0 : int GMLFeatureClass::GetPropertyIndex( const char *pszName ) const
      88                 : 
      89                 : {
      90               0 :     for( int i = 0; i < m_nPropertyCount; i++ )
      91               0 :         if( EQUAL(pszName,m_papoProperty[i]->GetName()) )
      92               0 :             return i;
      93                 : 
      94               0 :     return -1;
      95                 : }
      96                 : 
      97                 : /************************************************************************/
      98                 : /*                            AddProperty()                             */
      99                 : /************************************************************************/
     100                 : 
     101              49 : int GMLFeatureClass::AddProperty( GMLPropertyDefn *poDefn )
     102                 : 
     103                 : {
     104                 :     CPLAssert( GetProperty(poDefn->GetName()) == NULL );
     105                 : 
     106              49 :     m_nPropertyCount++;
     107                 :     m_papoProperty = (GMLPropertyDefn **)
     108              49 :         CPLRealloc( m_papoProperty, sizeof(void*) * m_nPropertyCount );
     109                 : 
     110              49 :     m_papoProperty[m_nPropertyCount-1] = poDefn;
     111                 : 
     112              49 :     return m_nPropertyCount-1;
     113                 : }
     114                 : 
     115                 : /************************************************************************/
     116                 : /*                           SetElementName()                           */
     117                 : /************************************************************************/
     118                 : 
     119               4 : void GMLFeatureClass::SetElementName( const char *pszElementName )
     120                 : 
     121                 : {
     122               4 :     CPLFree( m_pszElementName );
     123               4 :     m_pszElementName = CPLStrdup( pszElementName );
     124               4 : }
     125                 : 
     126                 : /************************************************************************/
     127                 : /*                           GetElementName()                           */
     128                 : /************************************************************************/
     129                 : 
     130             126 : const char *GMLFeatureClass::GetElementName() const
     131                 : 
     132                 : {
     133             126 :     if( m_pszElementName == NULL )
     134             111 :         return m_pszName;
     135                 :     else
     136              15 :         return m_pszElementName;
     137                 : }
     138                 : 
     139                 : /************************************************************************/
     140                 : /*                         SetGeometryElement()                         */
     141                 : /************************************************************************/
     142                 : 
     143               0 : void GMLFeatureClass::SetGeometryElement( const char *pszElement )
     144                 : 
     145                 : {
     146               0 :     CPLFree( m_pszGeometryElement );
     147               0 :     m_pszGeometryElement = CPLStrdup( pszElement );
     148               0 : }
     149                 : 
     150                 : /************************************************************************/
     151                 : /*                          GetFeatureCount()                           */
     152                 : /************************************************************************/
     153                 : 
     154              38 : int GMLFeatureClass::GetFeatureCount()
     155                 : 
     156                 : {
     157              38 :     return m_nFeatureCount;
     158                 : }
     159                 : 
     160                 : /************************************************************************/
     161                 : /*                          SetFeatureCount()                           */
     162                 : /************************************************************************/
     163                 : 
     164              27 : void GMLFeatureClass::SetFeatureCount( int nNewCount )
     165                 : 
     166                 : {
     167              27 :     m_nFeatureCount = nNewCount;
     168              27 : }
     169                 : 
     170                 : /************************************************************************/
     171                 : /*                            GetExtraInfo()                            */
     172                 : /************************************************************************/
     173                 : 
     174               0 : const char *GMLFeatureClass::GetExtraInfo()
     175                 : 
     176                 : {
     177               0 :     return m_pszExtraInfo;
     178                 : }
     179                 : 
     180                 : /************************************************************************/
     181                 : /*                            SetExtraInfo()                            */
     182                 : /************************************************************************/
     183                 : 
     184               0 : void GMLFeatureClass::SetExtraInfo( const char *pszExtraInfo )
     185                 : 
     186                 : {
     187               0 :     CPLFree( m_pszExtraInfo );
     188               0 :     m_pszExtraInfo = NULL;
     189                 : 
     190               0 :     if( pszExtraInfo != NULL )
     191               0 :         m_pszExtraInfo = CPLStrdup( pszExtraInfo );
     192               0 : }
     193                 : 
     194                 : /************************************************************************/
     195                 : /*                             SetExtents()                             */
     196                 : /************************************************************************/
     197                 : 
     198              26 : void GMLFeatureClass::SetExtents( double dfXMin, double dfXMax, 
     199                 :                                   double dfYMin, double dfYMax )
     200                 : 
     201                 : {
     202              26 :     m_dfXMin = dfXMin;
     203              26 :     m_dfXMax = dfXMax;
     204              26 :     m_dfYMin = dfYMin;
     205              26 :     m_dfYMax = dfYMax;
     206                 : 
     207              26 :     m_bHaveExtents = TRUE;
     208              26 : }
     209                 : 
     210                 : /************************************************************************/
     211                 : /*                             GetExtents()                             */
     212                 : /************************************************************************/
     213                 : 
     214              22 : int GMLFeatureClass::GetExtents( double *pdfXMin, double *pdfXMax, 
     215                 :                                  double *pdfYMin, double *pdfYMax )
     216                 : 
     217                 : {
     218              22 :     if( m_bHaveExtents )
     219                 :     {
     220              14 :         *pdfXMin = m_dfXMin;
     221              14 :         *pdfXMax = m_dfXMax;
     222              14 :         *pdfYMin = m_dfYMin;
     223              14 :         *pdfYMax = m_dfYMax;
     224                 :     }
     225                 : 
     226              22 :     return m_bHaveExtents;
     227                 : }
     228                 : 
     229                 : /************************************************************************/
     230                 : /*                         InitializeFromXML()                          */
     231                 : /************************************************************************/
     232                 : 
     233               4 : int GMLFeatureClass::InitializeFromXML( CPLXMLNode *psRoot )
     234                 : 
     235                 : {
     236                 : /* -------------------------------------------------------------------- */
     237                 : /*      Do some rudimentary checking that this is a well formed         */
     238                 : /*      node.                                                           */
     239                 : /* -------------------------------------------------------------------- */
     240               4 :     if( psRoot == NULL 
     241                 :         || psRoot->eType != CXT_Element 
     242                 :         || !EQUAL(psRoot->pszValue,"GMLFeatureClass") )
     243                 :     {
     244                 :         CPLError( CE_Failure, CPLE_AppDefined, 
     245                 :                   "GMLFeatureClass::InitializeFromXML() called on %s node!",
     246               0 :                   psRoot->pszValue );
     247               0 :         return FALSE;
     248                 :     }
     249                 : 
     250               4 :     if( CPLGetXMLValue( psRoot, "Name", NULL ) == NULL )
     251                 :     {
     252                 :         CPLError( CE_Failure, CPLE_AppDefined, 
     253               0 :                   "GMLFeatureClass has no <Name> element." );
     254               0 :         return FALSE;
     255                 :     }
     256                 : 
     257                 : /* -------------------------------------------------------------------- */
     258                 : /*      Collect base info.                                              */
     259                 : /* -------------------------------------------------------------------- */
     260               4 :     CPLFree( m_pszName );
     261               4 :     m_pszName = CPLStrdup( CPLGetXMLValue( psRoot, "Name", NULL ) );
     262                 :     
     263               4 :     SetElementName( CPLGetXMLValue( psRoot, "ElementPath", m_pszName ) );
     264                 : 
     265               4 :     const char *pszGPath = CPLGetXMLValue( psRoot, "GeometryElementPath", "" );
     266                 :     
     267               4 :     if( strlen( pszGPath ) > 0 )
     268               0 :         SetGeometryElement( pszGPath );
     269                 : 
     270               4 :     if( CPLGetXMLValue( psRoot, "GeometryType", NULL ) != NULL )
     271                 :     {
     272               0 :         SetGeometryType( atoi(CPLGetXMLValue( psRoot, "GeometryType", NULL )) );
     273                 :     }
     274                 : 
     275                 : /* -------------------------------------------------------------------- */
     276                 : /*      Collect dataset specific info.                                  */
     277                 : /* -------------------------------------------------------------------- */
     278               4 :     CPLXMLNode *psDSI = CPLGetXMLNode( psRoot, "DatasetSpecificInfo" );
     279               4 :     if( psDSI != NULL )
     280                 :     {
     281                 :         const char *pszValue;
     282                 : 
     283               4 :         pszValue = CPLGetXMLValue( psDSI, "FeatureCount", NULL );
     284               4 :         if( pszValue != NULL )
     285               4 :             SetFeatureCount( atoi(pszValue) );
     286                 : 
     287                 :         // Eventually we should support XML subtrees.
     288               4 :         pszValue = CPLGetXMLValue( psDSI, "ExtraInfo", NULL );
     289               4 :         if( pszValue != NULL )
     290               0 :             SetExtraInfo( pszValue );
     291                 : 
     292               4 :         if( CPLGetXMLValue( psDSI, "ExtentXMin", NULL ) != NULL 
     293                 :             && CPLGetXMLValue( psDSI, "ExtentXMax", NULL ) != NULL
     294                 :             && CPLGetXMLValue( psDSI, "ExtentYMin", NULL ) != NULL
     295                 :             && CPLGetXMLValue( psDSI, "ExtentYMax", NULL ) != NULL )
     296                 :         {
     297                 :             SetExtents( atof(CPLGetXMLValue( psDSI, "ExtentXMin", "0.0" )),
     298                 :                         atof(CPLGetXMLValue( psDSI, "ExtentXMax", "0.0" )),
     299                 :                         atof(CPLGetXMLValue( psDSI, "ExtentYMin", "0.0" )),
     300               4 :                         atof(CPLGetXMLValue( psDSI, "ExtentYMax", "0.0" )) );
     301                 :         }
     302                 :     }
     303                 :     
     304                 : /* -------------------------------------------------------------------- */
     305                 : /*      Collect property definitions.                                   */
     306                 : /* -------------------------------------------------------------------- */
     307              35 :     for( CPLXMLNode *psThis = psRoot->psChild;
     308                 :          psThis != NULL; psThis = psThis->psNext )
     309                 :     {
     310              31 :         if( EQUAL(psThis->pszValue, "PropertyDefn") )
     311                 :         {
     312              19 :             const char *pszName = CPLGetXMLValue( psThis, "Name", NULL );
     313              19 :             const char *pszType = CPLGetXMLValue( psThis, "Type", "Untyped" );
     314                 :             GMLPropertyDefn *poPDefn;
     315                 : 
     316              19 :             if( pszName == NULL )
     317                 :             {
     318                 :                 CPLError( CE_Failure, CPLE_AppDefined, 
     319                 :                           "GMLFeatureClass %s has a PropertyDefn without a <Name>..",
     320               0 :                           m_pszName );
     321               0 :                 return FALSE;
     322                 :             }
     323                 : 
     324                 :             poPDefn = new GMLPropertyDefn( 
     325              19 :                 pszName, CPLGetXMLValue( psThis, "ElementPath", NULL ) );
     326                 :             
     327              19 :             if( EQUAL(pszType,"Untyped") )
     328               0 :                 poPDefn->SetType( GMLPT_Untyped );
     329              19 :             else if( EQUAL(pszType,"String") ) 
     330                 :             {
     331              11 :                 poPDefn->SetType( GMLPT_String );
     332              11 :                 poPDefn->SetWidth( atoi( CPLGetXMLValue( psThis, "Width", "0" ) ) );
     333                 :             }
     334               8 :             else if( EQUAL(pszType,"Integer") )
     335                 :             {
     336               8 :                 poPDefn->SetType( GMLPT_Integer );
     337               8 :                 poPDefn->SetWidth( atoi( CPLGetXMLValue( psThis, "Width", "0" ) ) );
     338                 :             }
     339               0 :             else if( EQUAL(pszType,"Real") )
     340                 :             {
     341               0 :                 poPDefn->SetType( GMLPT_Real );
     342               0 :                 poPDefn->SetWidth( atoi( CPLGetXMLValue( psThis, "Width", "0" ) ) );
     343               0 :                 poPDefn->SetPrecision( atoi( CPLGetXMLValue( psThis, "Precision", "0" ) ) );
     344                 :             }
     345               0 :             else if( EQUAL(pszType,"StringList") ) 
     346               0 :                 poPDefn->SetType( GMLPT_StringList );
     347               0 :             else if( EQUAL(pszType,"IntegerList") )
     348               0 :                 poPDefn->SetType( GMLPT_IntegerList );
     349               0 :             else if( EQUAL(pszType,"RealList") )
     350               0 :                 poPDefn->SetType( GMLPT_RealList );
     351               0 :             else if( EQUAL(pszType,"Complex") )
     352               0 :                 poPDefn->SetType( GMLPT_Complex );
     353                 :             else
     354                 :             {
     355                 :                 CPLError( CE_Failure, CPLE_AppDefined, 
     356                 :                           "Unrecognised property type %s.", 
     357               0 :                           pszType );
     358               0 :                 return FALSE;
     359                 :             }
     360                 : 
     361              19 :             AddProperty( poPDefn );
     362                 :         }
     363                 :     }
     364                 : 
     365               4 :     return TRUE;
     366                 : }
     367                 : 
     368                 : /************************************************************************/
     369                 : /*                           SerializeToXML()                           */
     370                 : /************************************************************************/
     371                 : 
     372               8 : CPLXMLNode *GMLFeatureClass::SerializeToXML()
     373                 : 
     374                 : {
     375                 :     CPLXMLNode  *psRoot;
     376                 :     int         iProperty;
     377                 : 
     378                 : /* -------------------------------------------------------------------- */
     379                 : /*      Set feature class and core information.                         */
     380                 : /* -------------------------------------------------------------------- */
     381               8 :     psRoot = CPLCreateXMLNode( NULL, CXT_Element, "GMLFeatureClass" );
     382                 : 
     383               8 :     CPLCreateXMLElementAndValue( psRoot, "Name", GetName() );
     384               8 :     CPLCreateXMLElementAndValue( psRoot, "ElementPath", GetElementName() );
     385               8 :     if( GetGeometryElement() != NULL && strlen(GetGeometryElement()) > 0 )
     386                 :         CPLCreateXMLElementAndValue( psRoot, "GeometryElementPath", 
     387               0 :                                      GetGeometryElement() );
     388                 :     
     389               8 :     if( GetGeometryType() != 0 /* wkbUnknown */ )
     390                 :     {
     391                 :         char szValue[128];
     392                 : 
     393               0 :         sprintf( szValue, "%d", GetGeometryType() );
     394               0 :         CPLCreateXMLElementAndValue( psRoot, "GeometryType", szValue );
     395                 :     }
     396                 : 
     397                 : /* -------------------------------------------------------------------- */
     398                 : /*      Write out dataset specific information.                         */
     399                 : /* -------------------------------------------------------------------- */
     400                 :     CPLXMLNode *psDSI;
     401                 : 
     402               8 :     if( m_bHaveExtents || m_nFeatureCount != -1 || m_pszExtraInfo != NULL )
     403                 :     {
     404               8 :         psDSI = CPLCreateXMLNode( psRoot, CXT_Element, "DatasetSpecificInfo" );
     405                 : 
     406               8 :         if( m_nFeatureCount != -1 )
     407                 :         {
     408                 :             char szValue[128];
     409                 : 
     410               8 :             sprintf( szValue, "%d", m_nFeatureCount );
     411               8 :             CPLCreateXMLElementAndValue( psDSI, "FeatureCount", szValue );
     412                 :         }
     413                 : 
     414               8 :         if( m_bHaveExtents )
     415                 :         {
     416                 :             char szValue[128];
     417                 : 
     418               8 :             sprintf( szValue, "%.5f", m_dfXMin );
     419               8 :             CPLCreateXMLElementAndValue( psDSI, "ExtentXMin", szValue );
     420                 : 
     421               8 :             sprintf( szValue, "%.5f", m_dfXMax );
     422               8 :             CPLCreateXMLElementAndValue( psDSI, "ExtentXMax", szValue );
     423                 : 
     424               8 :             sprintf( szValue, "%.5f", m_dfYMin );
     425               8 :             CPLCreateXMLElementAndValue( psDSI, "ExtentYMin", szValue );
     426                 : 
     427               8 :             sprintf( szValue, "%.5f", m_dfYMax );
     428               8 :             CPLCreateXMLElementAndValue( psDSI, "ExtentYMax", szValue );
     429                 :         }
     430                 : 
     431               8 :         if( m_pszExtraInfo )
     432               0 :             CPLCreateXMLElementAndValue( psDSI, "ExtraInfo", m_pszExtraInfo );
     433                 :     }
     434                 :     
     435                 : /* -------------------------------------------------------------------- */
     436                 : /*      emit property information.                                      */
     437                 : /* -------------------------------------------------------------------- */
     438              29 :     for( iProperty = 0; iProperty < GetPropertyCount(); iProperty++ )
     439                 :     {
     440              21 :         GMLPropertyDefn *poPDefn = GetProperty( iProperty );
     441                 :         CPLXMLNode *psPDefnNode;
     442              21 :         const char *pszTypeName = "Unknown";
     443                 : 
     444              21 :         psPDefnNode = CPLCreateXMLNode( psRoot, CXT_Element, "PropertyDefn" );
     445                 :         CPLCreateXMLElementAndValue( psPDefnNode, "Name", 
     446              21 :                                      poPDefn->GetName() );
     447                 :         CPLCreateXMLElementAndValue( psPDefnNode, "ElementPath", 
     448              21 :                                      poPDefn->GetSrcElement() );
     449              21 :         switch( poPDefn->GetType() )
     450                 :         {
     451                 :           case GMLPT_Untyped:
     452               0 :             pszTypeName = "Untyped";
     453               0 :             break;
     454                 :             
     455                 :           case GMLPT_String:
     456               5 :             pszTypeName = "String";
     457               5 :             break;
     458                 :             
     459                 :           case GMLPT_Integer:
     460              12 :             pszTypeName = "Integer";
     461              12 :             break;
     462                 :             
     463                 :           case GMLPT_Real:
     464               4 :             pszTypeName = "Real";
     465               4 :             break;
     466                 :             
     467                 :           case GMLPT_Complex:
     468               0 :             pszTypeName = "Complex";
     469               0 :             break;
     470                 : 
     471                 :           case GMLPT_IntegerList:
     472               0 :             pszTypeName = "IntegerList";
     473               0 :             break;
     474                 : 
     475                 :           case GMLPT_RealList:
     476               0 :             pszTypeName = "RealList";
     477               0 :             break;
     478                 : 
     479                 :           case GMLPT_StringList:
     480               0 :             pszTypeName = "StringList";
     481                 :             break;
     482                 :         }
     483              21 :         CPLCreateXMLElementAndValue( psPDefnNode, "Type", pszTypeName );
     484                 : 
     485              21 :         if( EQUAL(pszTypeName,"String") )
     486                 :         {
     487                 :             char szMaxLength[48];
     488               5 :             sprintf(szMaxLength, "%d", poPDefn->GetWidth());
     489               5 :             CPLCreateXMLElementAndValue ( psPDefnNode, "Width", szMaxLength );
     490                 :         }
     491              21 :         if( poPDefn->GetWidth() > 0 && EQUAL(pszTypeName,"Integer") )
     492                 :         {
     493                 :             char szLength[48];
     494               0 :             sprintf(szLength, "%d", poPDefn->GetWidth());
     495               0 :             CPLCreateXMLElementAndValue ( psPDefnNode, "Width", szLength );
     496                 :         }
     497              21 :         if( poPDefn->GetWidth() > 0 && EQUAL(pszTypeName,"Real") )
     498                 :         {
     499                 :             char szLength[48];
     500               0 :             sprintf(szLength, "%d", poPDefn->GetWidth());
     501               0 :             CPLCreateXMLElementAndValue ( psPDefnNode, "Width", szLength );
     502                 :             char szPrecision[48];
     503               0 :             sprintf(szPrecision, "%d", poPDefn->GetPrecision());
     504               0 :             CPLCreateXMLElementAndValue ( psPDefnNode, "Precision", szPrecision );
     505                 :         }
     506                 :     }
     507                 : 
     508               8 :     return psRoot;
     509                 : }
     510                 : 

Generated by: LCOV version 1.7