📄 ogr_srsnode.cpp
字号:
&& (*pszInput == '[' || *pszInput == ']' || *pszInput == ',' || *pszInput == '(' || *pszInput == ')' ) ) { break; } else if( !bInQuotedString && (*pszInput == ' ' || *pszInput == '\t' || *pszInput == 10 || *pszInput == 13) ) { /* just skip over whitespace */ } else { szToken[nTokenLen++] = *pszInput; } pszInput++; } if( *pszInput == '\0' || nTokenLen == sizeof(szToken) - 1 ) return OGRERR_CORRUPT_DATA; szToken[nTokenLen++] = '\0'; SetValue( szToken );/* -------------------------------------------------------------------- *//* Read children, if we have a sublist. *//* -------------------------------------------------------------------- */ if( *pszInput == '[' || *pszInput == '(' ) { do { OGR_SRSNode *poNewChild; OGRErr eErr; pszInput++; // Skip bracket or comma. poNewChild = new OGR_SRSNode(); eErr = poNewChild->importFromWkt( (char **) &pszInput ); if( eErr != OGRERR_NONE ) 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 + -