📄 ogrutils.cpp
字号:
/******************************************************************************
* $Id: ogrutils.cpp 11034 2007-03-21 04:38:04Z mloskot $
*
* Project: OpenGIS Simple Features Reference Implementation
* Purpose: Utility functions for OGR classes, including some related to
* parsing well known text format vectors.
* Author: Frank Warmerdam, warmerdam@pobox.com
*
******************************************************************************
* Copyright (c) 1999, 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 "ogr_geometry.h"
#include "ogr_p.h"
#ifdef OGR_ENABLED
# include "ogrsf_frmts.h"
#endif /* OGR_ENABLED */
CPL_CVSID("$Id: ogrutils.cpp 11034 2007-03-21 04:38:04Z mloskot $");
/************************************************************************/
/* OGRTrimExtraZeros() */
/************************************************************************/
static void OGRTrimExtraZeros( char *pszTarget )
{
int i = 0;
while( pszTarget[i] != '\0' )
i++;
/* -------------------------------------------------------------------- */
/* Trim trailing 000001's as they are likely roundoff error. */
/* -------------------------------------------------------------------- */
if( i > 10
&& pszTarget[i-1] == '1'
&& pszTarget[i-2] == '0'
&& pszTarget[i-3] == '0'
&& pszTarget[i-4] == '0'
&& pszTarget[i-5] == '0'
&& pszTarget[i-6] == '0' )
{
pszTarget[--i] = '\0';
}
/* -------------------------------------------------------------------- */
/* Trim trailing zeros. */
/* -------------------------------------------------------------------- */
while( i > 2 && pszTarget[i-1] == '0' && pszTarget[i-2] != '.' )
{
pszTarget[--i] = '\0';
}
}
/************************************************************************/
/* OGRMakeWktCoordinate() */
/* */
/* Format a well known text coordinate, trying to keep the */
/* ASCII representation compact, but accurate. These rules */
/* will have to tighten up in the future. */
/* */
/* Currently a new point should require no more than 64 */
/* characters barring the X or Y value being extremely large. */
/************************************************************************/
void OGRMakeWktCoordinate( char *pszTarget, double x, double y, double z,
int nDimension )
{
char szX[40], szY[40], szZ[40];
szZ[0] = '\0';
if( x == (int) x && y == (int) y && z == (int) z )
{
sprintf( szX, "%d", (int) x );
sprintf( szY, " %d", (int) y );
}
else
{
sprintf( szX, "%.15f", x );
OGRTrimExtraZeros( szX );
sprintf( szY, " %.15f", y );
OGRTrimExtraZeros( szY );
}
if( nDimension == 3 )
{
if( z == (int) z )
sprintf( szZ, " %d", (int) z );
else
{
sprintf( szZ, " %.15f", z );
OGRTrimExtraZeros( szZ );
}
}
if( strlen(szX) + strlen(szY) + strlen(szZ) > 75 )
{
strcpy( szX, "0" );
strcpy( szY, "0" );
if( nDimension == 3 )
strcpy( szZ, "0" );
#ifdef DEBUG
CPLDebug( "OGR",
"Yow! Got this big result in OGRMakeWktCoordinate()\n"
"%s %s %s",
szX, szY, szZ );
#endif
}
strcpy( pszTarget, szX );
strcat( pszTarget, szY );
strcat( pszTarget, szZ );
}
/************************************************************************/
/* OGRWktReadToken() */
/* */
/* Read one token or delimeter and put into token buffer. Pre */
/* and post white space is swallowed. */
/************************************************************************/
const char *OGRWktReadToken( const char * pszInput, char * pszToken )
{
if( pszInput == NULL )
return NULL;
/* -------------------------------------------------------------------- */
/* Swallow pre-white space. */
/* -------------------------------------------------------------------- */
while( *pszInput == ' ' || *pszInput == '\t' )
pszInput++;
/* -------------------------------------------------------------------- */
/* If this is a delimeter, read just one character. */
/* -------------------------------------------------------------------- */
if( *pszInput == '(' || *pszInput == ')' || *pszInput == ',' )
{
pszToken[0] = *pszInput;
pszToken[1] = '\0';
pszInput++;
}
/* -------------------------------------------------------------------- */
/* Or if it alpha numeric read till we reach non-alpha numeric */
/* text. */
/* -------------------------------------------------------------------- */
else
{
int iChar = 0;
while( iChar < OGR_WKT_TOKEN_MAX-1
&& ((*pszInput >= 'a' && *pszInput <= 'z')
|| (*pszInput >= 'A' && *pszInput <= 'Z')
|| (*pszInput >= '0' && *pszInput <= '9')
|| *pszInput == '.'
|| *pszInput == '+'
|| *pszInput == '-') )
{
pszToken[iChar++] = *(pszInput++);
}
pszToken[iChar++] = '\0';
}
/* -------------------------------------------------------------------- */
/* Eat any trailing white space. */
/* -------------------------------------------------------------------- */
while( *pszInput == ' ' || *pszInput == '\t' )
pszInput++;
return( pszInput );
}
/************************************************************************/
/* OGRWktReadPoints() */
/* */
/* Read a point string. The point list must be contained in */
/* brackets and each point pair separated by a comma. */
/************************************************************************/
const char * OGRWktReadPoints( const char * pszInput,
OGRRawPoint ** ppaoPoints, double **ppadfZ,
int * pnMaxPoints,
int * pnPointsRead )
{
const char *pszOrigInput = pszInput;
*pnPointsRead = 0;
if( pszInput == NULL )
return NULL;
/* -------------------------------------------------------------------- */
/* Eat any leading white space. */
/* -------------------------------------------------------------------- */
while( *pszInput == ' ' || *pszInput == '\t' )
pszInput++;
/* -------------------------------------------------------------------- */
/* If this isn't an opening bracket then we have a problem! */
/* -------------------------------------------------------------------- */
if( *pszInput != '(' )
{
CPLDebug( "OGR",
"Expected '(', but got %s in OGRWktReadPoints().\n",
pszInput );
return pszInput;
}
pszInput++;
/* ==================================================================== */
/* This loop reads a single point. It will continue till we */
/* run out of well formed points, or a closing bracket is */
/* encountered. */
/* ==================================================================== */
char szDelim[OGR_WKT_TOKEN_MAX];
do {
/* -------------------------------------------------------------------- */
/* Read the X and Y values, verify they are numeric. */
/* -------------------------------------------------------------------- */
char szTokenX[OGR_WKT_TOKEN_MAX];
char szTokenY[OGR_WKT_TOKEN_MAX];
pszInput = OGRWktReadToken( pszInput, szTokenX );
pszInput = OGRWktReadToken( pszInput, szTokenY );
if( (!isdigit(szTokenX[0]) && szTokenX[0] != '-' && szTokenX[0] != '.' )
|| (!isdigit(szTokenY[0]) && szTokenY[0] != '-' && szTokenY[0] != '.') )
return NULL;
/* -------------------------------------------------------------------- */
/* Do we need to grow the point list to hold this point? */
/* -------------------------------------------------------------------- */
if( *pnPointsRead == *pnMaxPoints )
{
*pnMaxPoints = *pnMaxPoints * 2 + 10;
*ppaoPoints = (OGRRawPoint *)
CPLRealloc(*ppaoPoints, sizeof(OGRRawPoint) * *pnMaxPoints);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -