⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ogr_srsnode.cpp

📁 mitab,读取MapInfo的地图文件
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    {
        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 + -