gmlhandler.cpp
来自「支持各种栅格图像和矢量图像读取的库」· C++ 代码 · 共 303 行
CPP
303 行
/********************************************************************** * $Id: gmlhandler.cpp 10646 2007-01-18 02:38:10Z warmerdam $ * * Project: GML Reader * Purpose: Implementation of GMLHandler class. * Author: Frank Warmerdam, warmerdam@pobox.com * ********************************************************************** * Copyright (c) 2002, Frank Warmerdam * * 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. ****************************************************************************/#include <ctype.h>#include "gmlreaderp.h"#include "cpl_conv.h"#define MAX_TOKEN_SIZE 1000/************************************************************************//* GMLHandler() *//************************************************************************/GMLHandler::GMLHandler( GMLReader *poReader ){ m_poReader = poReader; m_pszCurField = NULL; m_pszGeometry = NULL; m_nGeomAlloc = m_nGeomLen = 0;}/************************************************************************//* ~GMLHandler() *//************************************************************************/GMLHandler::~GMLHandler(){ CPLFree( m_pszCurField ); CPLFree( m_pszGeometry );}/************************************************************************//* startElement() *//************************************************************************/void GMLHandler::startElement(const XMLCh* const uri, const XMLCh* const localname, const XMLCh* const qname, const Attributes& attrs ){ char szElementName[MAX_TOKEN_SIZE]; GMLReadState *poState = m_poReader->GetState(); tr_strcpy( szElementName, localname );/* -------------------------------------------------------------------- *//* If we are in the midst of collecting a feature attribute *//* value, then this must be a complex attribute which we don't *//* try to collect for now, so just terminate the field *//* collection. *//* -------------------------------------------------------------------- */ if( m_pszCurField != NULL ) { CPLFree( m_pszCurField ); m_pszCurField = NULL; }/* -------------------------------------------------------------------- *//* If we are collecting geometry, or if we determine this is a *//* geometry element then append to the geometry info. *//* -------------------------------------------------------------------- */ if( m_pszGeometry != NULL || IsGeometryElement( szElementName ) ) { int nLNLen = tr_strlen( localname ); /* should save attributes too! */ if( m_pszGeometry == NULL ) m_nGeometryDepth = poState->m_nPathLength; if( m_nGeomLen + nLNLen + 4 > m_nGeomAlloc ) { m_nGeomAlloc = (int) (m_nGeomAlloc * 1.3 + nLNLen + 1000); m_pszGeometry = (char *) CPLRealloc( m_pszGeometry, m_nGeomAlloc); } strcpy( m_pszGeometry+m_nGeomLen, "<" ); tr_strcpy( m_pszGeometry+m_nGeomLen+1, localname ); strcat( m_pszGeometry+m_nGeomLen+nLNLen+1, ">" ); m_nGeomLen += strlen(m_pszGeometry+m_nGeomLen); } /* -------------------------------------------------------------------- *//* Is it a feature? If so push a whole new state, and return. *//* -------------------------------------------------------------------- */ else if( m_poReader->IsFeatureElement( szElementName ) ) { m_poReader->PushFeature( szElementName, attrs ); return; }/* -------------------------------------------------------------------- *//* If it is (or at least potentially is) a simple attribute, *//* then start collecting it. *//* -------------------------------------------------------------------- */ else if( m_poReader->IsAttributeElement( szElementName ) ) { CPLFree( m_pszCurField ); m_pszCurField = CPLStrdup(""); }/* -------------------------------------------------------------------- *//* Push the element onto the current state's path. *//* -------------------------------------------------------------------- */ poState->PushPath( szElementName );}/************************************************************************//* endElement() *//************************************************************************/void GMLHandler::endElement(const XMLCh* const uri, const XMLCh* const localname, const XMLCh* const qname ){ char szElementName[MAX_TOKEN_SIZE]; GMLReadState *poState = m_poReader->GetState(); tr_strcpy( szElementName, localname );/* -------------------------------------------------------------------- *//* Is this closing off an attribute value? We assume so if *//* we are collecting an attribute value and got to this point. *//* We don't bother validating that the closing tag matches the *//* opening tag. *//* -------------------------------------------------------------------- */ if( m_pszCurField != NULL ) { CPLAssert( poState->m_poFeature != NULL ); m_poReader->SetFeatureProperty( szElementName, m_pszCurField ); CPLFree( m_pszCurField ); m_pszCurField = NULL; }/* -------------------------------------------------------------------- *//* If we are collecting Geometry than store it, and consider if *//* this is the end of the geometry. *//* -------------------------------------------------------------------- */ if( m_pszGeometry != NULL ) { int nLNLen = tr_strlen( localname ); /* should save attributes too! */ if( m_nGeomLen + nLNLen + 4 > m_nGeomAlloc ) { m_nGeomAlloc = (int) (m_nGeomAlloc * 1.3 + nLNLen + 1000); m_pszGeometry = (char *) CPLRealloc( m_pszGeometry, m_nGeomAlloc); } strcat( m_pszGeometry+m_nGeomLen, "</" ); tr_strcpy( m_pszGeometry+m_nGeomLen+2, localname ); strcat( m_pszGeometry+m_nGeomLen+nLNLen+2, ">" ); m_nGeomLen += strlen(m_pszGeometry+m_nGeomLen); if( poState->m_nPathLength == m_nGeometryDepth+1 ) { if( poState->m_poFeature != NULL ) poState->m_poFeature->SetGeometryDirectly( m_pszGeometry ); else CPLFree( m_pszGeometry ); m_pszGeometry = NULL; m_nGeomAlloc = m_nGeomLen = 0; } }/* -------------------------------------------------------------------- *//* If we are collecting a feature, and this element tag matches *//* element name for the class, then we have finished the *//* feature, and we pop the feature read state. *//* -------------------------------------------------------------------- */ if( poState->m_poFeature != NULL && EQUAL(szElementName, poState->m_poFeature->GetClass()->GetElementName()) ) { m_poReader->PopState(); }/* -------------------------------------------------------------------- *//* Otherwise, we just pop the element off the local read states *//* element stack. *//* -------------------------------------------------------------------- */ else { if( EQUAL(szElementName,poState->GetLastComponent()) ) poState->PopPath(); else { CPLAssert( FALSE ); } }}/************************************************************************//* characters() *//************************************************************************/void GMLHandler::characters(const XMLCh* const chars_in, const unsigned int length ){ const XMLCh *chars = chars_in; if( m_pszCurField != NULL ) { int nCurFieldLength = strlen(m_pszCurField); while( *chars == ' ' || *chars == 10 || *chars == 13 || *chars == '\t') chars++; m_pszCurField = (char *) CPLRealloc( m_pszCurField, nCurFieldLength+tr_strlen(chars)+1 ); tr_strcpy( m_pszCurField + nCurFieldLength, chars ); } else if( m_pszGeometry != NULL ) { // Ignore white space while( *chars == ' ' || *chars == 10 || *chars == 13 || *chars == '\t') chars++; int nCharsLen = tr_strlen( chars ); if( m_nGeomLen + nCharsLen + 4 > m_nGeomAlloc ) { m_nGeomAlloc = (int) (m_nGeomAlloc * 1.3 + nCharsLen + 1000); m_pszGeometry = (char *) CPLRealloc( m_pszGeometry, m_nGeomAlloc); } tr_strcpy( m_pszGeometry+m_nGeomLen, chars ); m_nGeomLen += strlen(m_pszGeometry+m_nGeomLen); }}/************************************************************************//* fatalError() *//************************************************************************/void GMLHandler::fatalError( const SAXParseException &exception){ char *pszErrorMessage; pszErrorMessage = tr_strdup( exception.getMessage() ); CPLError( CE_Failure, CPLE_AppDefined, "XML Parsing Error: %s\n", pszErrorMessage ); CPLFree( pszErrorMessage );}/************************************************************************//* IsGeometryElement() *//************************************************************************/int GMLHandler::IsGeometryElement( const char *pszElement ){ return EQUAL(pszElement,"Polygon") || EQUAL(pszElement,"MultiPolygon") || EQUAL(pszElement,"MultiPoint") || EQUAL(pszElement,"MultiLineString") || EQUAL(pszElement,"GeometryCollection") || EQUAL(pszElement,"Point") || EQUAL(pszElement,"LineString");}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?