EVOLUTION-MANAGER
Edit File: gfstemplate.cpp
/****************************************************************************** * $Id: gfstemplate.cpp 27132 2014-04-05 21:48:58Z rouault $ * * Project: GML Reader * Purpose: Implementation of GML GFS template management * Author: Alessandro Furieri, a.furitier@lqt.it * ****************************************************************************** * Copyright (c) 2011, Alessandro Furieri * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * ****************************************************************************** * Contributor: Alessandro Furieri, a.furieri@lqt.it * Developed for Faunalia ( http://www.faunalia.it) with funding from * Regione Toscana - Settore SISTEMA INFORMATIVO TERRITORIALE ED AMBIENTALE * ****************************************************************************/ #include "gmlreaderp.h" #include "ogr_gml.h" CPL_CVSID("$Id: gfstemplate.cpp 27132 2014-04-05 21:48:58Z rouault $"); /************************************************************************/ /* GFSTemplateItem */ /************************************************************************/ class GFSTemplateItem { private: char *m_pszName; int n_nItemCount; int n_nGeomCount; GFSTemplateItem *pNext; public: GFSTemplateItem( const char *pszName ); ~GFSTemplateItem(); const char *GetName() { return m_pszName; } void Update( int b_has_geom ); int GetCount() { return n_nItemCount; } int GetGeomCount() { return n_nGeomCount; } void SetNext( GFSTemplateItem *pN ) { pNext = pN; } GFSTemplateItem *GetNext() { return pNext; } }; /***************************************************/ /* gmlUpdateFeatureClasses() */ /***************************************************/ void gmlUpdateFeatureClasses ( GFSTemplateList *pCC, GMLReader *pReader, int *pbSequentialLayers ) { /* updating the FeatureClass list */ int clIdx; for (clIdx = 0; clIdx < pReader->GetClassCount(); clIdx++) { GMLFeatureClass* poClass = pReader->GetClass( clIdx ); if (poClass != NULL) poClass->SetFeatureCount( 0 ); } int m_bValid = FALSE; GFSTemplateItem *pItem = pCC->GetFirst(); while ( pItem != NULL ) { /* updating Classes */ GMLFeatureClass* poClass = pReader->GetClass( pItem->GetName() ); if (poClass != NULL) { poClass->SetFeatureCount( pItem->GetCount() ); if ( pItem->GetGeomCount() != 0 && poClass->GetGeometryPropertyCount() == 0 ) poClass->AddGeometryProperty( new GMLGeometryPropertyDefn( "", "", wkbUnknown ) ); m_bValid = TRUE; } pItem = pItem->GetNext(); } if ( m_bValid == TRUE && pCC->HaveSequentialLayers() == TRUE ) *pbSequentialLayers = TRUE; } /***************************************************/ /* GMLReader::ReArrangeTemplateClasses() */ /***************************************************/ int GMLReader::ReArrangeTemplateClasses ( GFSTemplateList *pCC ) { /* rearranging the final FeatureClass list [SEQUENTIAL] */ int m_nSavedClassCount = GetClassCount(); /* saving the previous FeatureClass list */ GMLFeatureClass **m_papoSavedClass = (GMLFeatureClass **) CPLMalloc( sizeof(void*) * m_nSavedClassCount ); int clIdx; for (clIdx = 0; clIdx < GetClassCount(); clIdx++) { /* tranferring any previous FeatureClass */ m_papoSavedClass[clIdx] = m_papoClass[clIdx]; } /* cleaning the previous FeatureClass list */ SetClassListLocked( FALSE ); CPLFree( m_papoClass ); m_nClassCount = 0; m_papoClass = NULL; GFSTemplateItem *pItem = pCC->GetFirst(); while ( pItem != NULL ) { /* * re-inserting any required FeatureClassup * accordingly to actual SEQUENTIAL layout */ GMLFeatureClass* poClass = NULL; for( int iClass = 0; iClass < m_nSavedClassCount; iClass++ ) { GMLFeatureClass* poItem = m_papoSavedClass[iClass]; if( EQUAL(poItem->GetName(), pItem->GetName() )) { poClass = poItem; break; } } if (poClass != NULL) { if (poClass->GetFeatureCount() > 0) AddClass( poClass ); } pItem = pItem->GetNext(); } SetClassListLocked( TRUE ); /* destroying the saved List and any unused FeatureClass */ for( int iClass = 0; iClass < m_nSavedClassCount; iClass++ ) { int bUnused = TRUE; GMLFeatureClass* poClass = m_papoSavedClass[iClass]; for( int iClass2 = 0; iClass2 < m_nClassCount; iClass2++ ) { if (m_papoClass[iClass2] == poClass) { bUnused = FALSE; break; } } if ( bUnused == TRUE ) delete poClass; } CPLFree( m_papoSavedClass ); return 1; } /***************************************************/ /* GMLReader::PrescanForTemplate() */ /***************************************************/ int GMLReader::PrescanForTemplate () { int iCount = 0; GMLFeature *poFeature; //int bSequentialLayers = TRUE; GFSTemplateList *pCC = new GFSTemplateList(); /* processing GML features */ while( (poFeature = NextFeature()) != NULL ) { GMLFeatureClass *poClass = poFeature->GetClass(); const CPLXMLNode* const * papsGeomList = poFeature->GetGeometryList(); int b_has_geom = FALSE; if( papsGeomList != NULL ) { int i = 0; const CPLXMLNode *psNode = papsGeomList[i]; while( psNode != NULL ) { b_has_geom = TRUE; i++; psNode = papsGeomList[i]; } } pCC->Update( poClass->GetElementName(), b_has_geom ); delete poFeature; } gmlUpdateFeatureClasses( pCC, this, &m_bSequentialLayers ); if ( m_bSequentialLayers == TRUE ) ReArrangeTemplateClasses( pCC ); iCount = pCC->GetClassCount(); delete pCC; CleanupParser(); return iCount > 0; } /***************************************************/ /* GFSTemplateList() */ /***************************************************/ GFSTemplateList::GFSTemplateList( void ) { m_bSequentialLayers = TRUE; pFirst = NULL; pLast = NULL; } /***************************************************/ /* GFSTemplateList() */ /***************************************************/ GFSTemplateList::~GFSTemplateList() { GFSTemplateItem *pNext; GFSTemplateItem *pItem = pFirst; while ( pItem != NULL ) { pNext = pItem->GetNext(); delete pItem; pItem = pNext; } } /***************************************************/ /* GFSTemplateList::Insert() */ /***************************************************/ GFSTemplateItem *GFSTemplateList::Insert( const char *pszName ) { GFSTemplateItem *pItem; pItem = new GFSTemplateItem( pszName ); /* inserting into the linked list */ if( pFirst == NULL ) pFirst = pItem; if( pLast != NULL ) pLast->SetNext( pItem ); pLast = pItem; return pItem; } /***************************************************/ /* GFSTemplateList::Update() */ /***************************************************/ void GFSTemplateList::Update( const char *pszName, int bHasGeom ) { GFSTemplateItem *pItem; if( pFirst == NULL ) { /* empty List: first item */ pItem = Insert( pszName ); pItem->Update( bHasGeom ); return; } if( EQUAL(pszName, pLast->GetName() ) ) { /* continuing with the current Class Item */ pLast->Update( bHasGeom ); return; } pItem = pFirst; while( pItem != NULL ) { if( EQUAL(pszName, pItem->GetName() )) { /* Class Item previously declared: NOT SEQUENTIAL */ m_bSequentialLayers = FALSE; pItem->Update( bHasGeom ); return; } pItem = pItem->GetNext(); } /* inserting a new Class Item */ pItem = Insert( pszName ); pItem->Update( bHasGeom ); } /***************************************************/ /* GFSTemplateList::GetClassCount() */ /***************************************************/ int GFSTemplateList::GetClassCount( ) { int iCount = 0; GFSTemplateItem *pItem; pItem = pFirst; while( pItem != NULL ) { iCount++; pItem = pItem->GetNext(); } return iCount; } /***************************************************/ /* GFSTemplateItem() */ /***************************************************/ GFSTemplateItem::GFSTemplateItem( const char *pszName ) { m_pszName = CPLStrdup( pszName ); n_nItemCount = 0; n_nGeomCount = 0; pNext = NULL; } /***************************************************/ /* ~GFSTemplateItem() */ /***************************************************/ GFSTemplateItem::~GFSTemplateItem() { CPLFree(m_pszName); } /***************************************************/ /* GFSTemplateItem::Update() */ /***************************************************/ void GFSTemplateItem::Update( int bHasGeom ) { n_nItemCount++; if( bHasGeom == TRUE ) n_nGeomCount++; }