?? ogr_srsnode.cpp
字號:
{
do
{
OGR_SRSNode *poNewChild;
OGRErr eErr;
pszInput++; // Skip bracket or comma.
poNewChild = new OGR_SRSNode();
eErr = poNewChild->importFromWkt( (char **) &pszInput );
if( eErr != OGRERR_NONE )
{
delete poNewChild;
return eErr;
}
AddChild( poNewChild );
} while( *pszInput == ',' );
if( *pszInput != ')' && *pszInput != ']' )
return OGRERR_CORRUPT_DATA;
pszInput++;
}
*ppszInput = (char *) pszInput;
return OGRERR_NONE;
}
/************************************************************************/
/* MakeValueSafe() */
/************************************************************************/
/**
* Massage value string, stripping special characters so it will be a
* database safe string.
*
* The operation is also applies to all subnodes of the current node.
*/
void OGR_SRSNode::MakeValueSafe()
{
int i, j;
/* -------------------------------------------------------------------- */
/* First process subnodes. */
/* -------------------------------------------------------------------- */
for( int iChild = 0; iChild < GetChildCount(); iChild++ )
{
GetChild(iChild)->MakeValueSafe();
}
/* -------------------------------------------------------------------- */
/* Skip numeric nodes. */
/* -------------------------------------------------------------------- */
if( (pszValue[0] >= '0' && pszValue[0] <= '9') || pszValue[0] != '.' )
return;
/* -------------------------------------------------------------------- */
/* Translate non-alphanumeric values to underscores. */
/* -------------------------------------------------------------------- */
for( i = 0; pszValue[i] != '\0'; i++ )
{
if( !(pszValue[i] >= 'A' && pszValue[i] <= 'Z')
&& !(pszValue[i] >= 'a' && pszValue[i] <= 'z')
&& !(pszValue[i] >= '0' && pszValue[i] <= '9') )
{
pszValue[i] = '_';
}
}
/* -------------------------------------------------------------------- */
/* Remove repeated and trailing underscores. */
/* -------------------------------------------------------------------- */
for( i = 1, j = 0; pszValue[i] != '\0'; i++ )
{
if( pszValue[j] == '_' && pszValue[i] == '_' )
continue;
pszValue[++j] = pszValue[i];
}
if( pszValue[j] == '_' )
pszValue[j] = '\0';
else
pszValue[j+1] = '\0';
}
/************************************************************************/
/* applyRemapper() */
/************************************************************************/
/**
* Remap node values matching list.
*
* Remap the value of this node or any of it's children if it matches
* one of the values in the source list to the corresponding value from
* the destination list. If the pszNode value is set, only do so if the
* parent node matches that value. Even if a replacement occurs, searching
* continues.
*
* @param pszNode Restrict remapping to children of this type of node
* (eg. "PROJECTION")
* @param papszSrcValues a NULL terminated array of source string. If the
* node value matches one of these (case insensitive) then replacement occurs.
* @param papszDstValues an array of destination strings. On a match, the
* one corresponding to a source value will be used to replace a node.
* @param nStepSize increment when stepping through source and destination
* arrays, allowing source and destination arrays to be one interleaved array
* for instances. Defaults to 1.
* @param bChildOfHit Only TRUE if we the current node is the child of a match,
* and so needs to be set. Application code would normally pass FALSE for this
* argument.
*
* @return returns OGRERR_NONE unless something bad happens. There is no
* indication returned about whether any replacement occured.
*/
OGRErr OGR_SRSNode::applyRemapper( const char *pszNode,
char **papszSrcValues,
char **papszDstValues,
int nStepSize, int bChildOfHit )
{
int i;
/* -------------------------------------------------------------------- */
/* Scan for value, and replace if our parent was a "hit". */
/* -------------------------------------------------------------------- */
if( bChildOfHit || pszNode == NULL )
{
for( i = 0; papszSrcValues[i] != NULL; i += nStepSize )
{
if( EQUAL(papszSrcValues[i],pszValue) )
{
SetValue( papszDstValues[i] );
break;
}
}
}
/* -------------------------------------------------------------------- */
/* Are the the target node? */
/* -------------------------------------------------------------------- */
if( pszNode != NULL )
bChildOfHit = EQUAL(pszValue,pszNode);
/* -------------------------------------------------------------------- */
/* Recurse */
/* -------------------------------------------------------------------- */
for( i = 0; i < GetChildCount(); i++ )
{
GetChild(i)->applyRemapper( pszNode, papszSrcValues,
papszDstValues, nStepSize, bChildOfHit );
}
return OGRERR_NONE;
}
/************************************************************************/
/* StripNodes() */
/************************************************************************/
/**
* Strip child nodes matching name.
*
* Removes any decendent nodes of this node that match the given name.
* Of course children of removed nodes are also discarded.
*
* @param pszName the name for nodes that should be removed.
*/
void OGR_SRSNode::StripNodes( const char * pszName )
{
/* -------------------------------------------------------------------- */
/* Strip any children matching this name. */
/* -------------------------------------------------------------------- */
while( FindChild( pszName ) >= 0 )
DestroyChild( FindChild( pszName ) );
/* -------------------------------------------------------------------- */
/* Recurse */
/* -------------------------------------------------------------------- */
for( int i = 0; i < GetChildCount(); i++ )
GetChild(i)->StripNodes( pszName );
}
/************************************************************************/
/* FixupOrdering() */
/************************************************************************/
/**
* Correct parameter ordering to match CT Specification.
*
* Some mechanisms to create WKT using OGRSpatialReference, and some
* imported WKT fail to maintain the order of parameters required according
* to the BNF definitions in the OpenGIS SF-SQL and CT Specifications. This
* method attempts to massage things back into the required order.
*
* This method will reorder the children of the node it is invoked on and
* then recurse to all children to fix up their children.
*
* @return OGRERR_NONE on success or an error code if something goes
* wrong.
*/
static char *apszPROJCSRule[] =
{ "PROJCS", "GEOGCS", "PROJECTION", "PARAMETER", "UNIT", "AXIS", "AUTHORITY",
NULL };
static char *apszDATUMRule[] =
{ "DATUM", "SPHEROID", "TOWGS84", "AUTHORITY", NULL };
static char *apszGEOGCSRule[] =
{ "GEOGCS", "DATUM", "PRIMEM", "UNIT", "AXIS", "AUTHORITY", NULL };
static char **apszOrderingRules[] = {
apszPROJCSRule, apszGEOGCSRule, apszDATUMRule, NULL };
OGRErr OGR_SRSNode::FixupOrdering()
{
int i;
/* -------------------------------------------------------------------- */
/* Recurse ordering children. */
/* -------------------------------------------------------------------- */
for( i = 0; i < GetChildCount(); i++ )
GetChild(i)->FixupOrdering();
if( GetChildCount() < 3 )
return OGRERR_NONE;
/* -------------------------------------------------------------------- */
/* Is this a node for which an ordering rule exists? */
/* -------------------------------------------------------------------- */
char **papszRule = NULL;
for( i = 0; apszOrderingRules[i] != NULL; i++ )
{
if( EQUAL(apszOrderingRules[i][0],pszValue) )
{
papszRule = apszOrderingRules[i] + 1;
break;
}
}
if( papszRule == NULL )
return OGRERR_NONE;
/* -------------------------------------------------------------------- */
/* If we have a rule, apply it. We create an array */
/* (panChildPr) with the priority code for each child (derived */
/* from the rule) and we then bubble sort based on this. */
/* -------------------------------------------------------------------- */
int *panChildKey = (int *) CPLCalloc(sizeof(int),GetChildCount());
for( i = 1; i < GetChildCount(); i++ )
{
panChildKey[i] = CSLFindString( papszRule, GetChild(i)->GetValue() );
if( panChildKey[i] == -1 )
{
CPLDebug( "OGRSpatialReference",
"Found unexpected key %s when trying to order SRS nodes.",
GetChild(i)->GetValue() );
}
}
/* -------------------------------------------------------------------- */
/* Sort - Note we don't try to do anything with the first child */
/* which we assume is a name string. */
/* -------------------------------------------------------------------- */
int j, bChange = TRUE;
for( i = 1; bChange && i < GetChildCount()-1; i++ )
{
bChange = FALSE;
for( j = 1; j < GetChildCount()-i; j++ )
{
if( panChildKey[j] == -1 || panChildKey[j+1] == -1 )
continue;
if( panChildKey[j] > panChildKey[j+1] )
{
OGR_SRSNode *poTemp = papoChildNodes[j];
int nKeyTemp = panChildKey[j];
papoChildNodes[j] = papoChildNodes[j+1];
papoChildNodes[j+1] = poTemp;
nKeyTemp = panChildKey[j];
panChildKey[j] = panChildKey[j+1];
panChildKey[j+1] = nKeyTemp;
bChange = TRUE;
}
}
}
CPLFree( panChildKey );
return OGRERR_NONE;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -