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

📄 mitab_utils.cpp

📁 mitab,读取MapInfo的地图文件
💻 CPP
📖 第 1 页 / 共 2 页
字号:

    /*-----------------------------------------------------------------
     * None of the extensions worked!  
     * Try adjusting cases in the whole path and filename 
     *----------------------------------------------------------------*/
    return TABAdjustCaseSensitiveFilename(pszFname);
}



/**********************************************************************
 *                       TABGetBasename()
 *
 * Extract the basename part of a complete file path.
 *
 * Returns a newly allocated string without the leading path (dirs) and
 * the extenstion.  The returned string should be freed using CPLFree().
 **********************************************************************/
char *TABGetBasename(const char *pszFname)
{
    const char *pszTmp = NULL;

    /*-----------------------------------------------------------------
     * Skip leading path or use whole name if no path dividers are
     * encountered.
     *----------------------------------------------------------------*/
    pszTmp = pszFname + strlen(pszFname) - 1;
    while ( pszTmp != pszFname 
            && *pszTmp != '/' && *pszTmp != '\\' ) 
        pszTmp--;

    if( pszTmp != pszFname )
        pszTmp++;

    /*-----------------------------------------------------------------
     * Now allocate our own copy and remove extension
     *----------------------------------------------------------------*/
    char *pszBasename = CPLStrdup(pszTmp);
    int i;
    for(i=0; pszBasename[i] != '\0'; i++)
    {
        if (pszBasename[i] == '.')
        {
            pszBasename[i] = '\0';
            break;
        }
    }

    return pszBasename;
}



/**********************************************************************
 *                       TAB_CSLLoad()
 *
 * Same as CSLLoad(), but does not produce an error if it fails... it
 * just returns NULL silently instead.
 *
 * Load a test file into a stringlist.
 *
 * Lines are limited in length by the size fo the CPLReadLine() buffer.
 **********************************************************************/
char **TAB_CSLLoad(const char *pszFname)
{
    FILE        *fp;
    const char  *pszLine;
    char        **papszStrList=NULL;

    fp = VSIFOpen(pszFname, "rt");

    if (fp)
    {
        while(!VSIFEof(fp))
        {
            if ( (pszLine = CPLReadLine(fp)) != NULL )
            {
                papszStrList = CSLAddString(papszStrList, pszLine);
            }
        }

        VSIFClose(fp);
    }

    return papszStrList;
}



/**********************************************************************
 *                       TABUnEscapeString()
 *
 * Convert a string that can possibly contain escaped "\n" chars in
 * into into a new one with binary newlines in it.
 *
 * Tries to work on hte original buffer unless bSrcIsConst=TRUE, in
 * which case the original is always untouched and a copy is allocated
 * ONLY IF NECESSARY.  This means that the caller should compare the
 * return value and the source (pszString) to see if a copy was returned,
 * in which case the caller becomes responsible of freeing both the
 * source and the copy.
 **********************************************************************/
char *TABUnEscapeString(char *pszString, GBool bSrcIsConst)
{

    /*-----------------------------------------------------------------
     * First check if we need to do any replacement
     *----------------------------------------------------------------*/
    if (pszString == NULL || strstr(pszString, "\\n") == NULL)
    {
        return pszString;
    }

    /*-----------------------------------------------------------------
     * Yes, we need to replace at least one "\n"
     * We try to work on the original buffer unless we have bSrcIsConst=TRUE
     *
     * Note that we do not worry about freeing the source buffer when we
     * return a copy... it is up to the caller to decide if he needs to 
     * free the source based on context and by comparing pszString with 
     * the returned pointer (pszWorkString) to see if they are identical.
     *----------------------------------------------------------------*/
    char *pszWorkString = NULL;
    int i =0;
    int j =0;

    if (bSrcIsConst)
    {
        // We have to create a copy to work on.
        pszWorkString = (char *)CPLMalloc(sizeof(char) * 
                                          (strlen(pszString) +1));
    }
    else
    {
        // We'll work on the original.
        pszWorkString = pszString;
    }


    while (pszString[i])
    {
        if (pszString[i] =='\\' && 
            pszString[i+1] == 'n')
        {
            pszWorkString[j++] = '\n';
            i+= 2;
        }
        else if (pszString[i] =='\\' && 
                 pszString[i+1] == '\\')
        {
            pszWorkString[j++] = '\\';
            i+= 2;
        }
        else
        {
            pszWorkString[j++] = pszString[i++];
        }
    }
    pszWorkString[j++] = '\0';
   
    return pszWorkString;
}

/**********************************************************************
 *                       TABEscapeString()
 *
 * Convert a string that can possibly contain binary "\n" chars in
 * into into a new one with escaped newlines ("\\" + "n") in it.
 *
 * The function returns the original string pointer if it did not need to
 * be modified, or a copy that has to be freed by the caller if the
 * string had to be modified.
 *
 * It is up to the caller to decide if he needs to free the returned 
 * string by comparing the source (pszString) pointer with the returned
 * pointer (pszWorkString) to see if they are identical.
 **********************************************************************/
char *TABEscapeString(char *pszString)
{
    /*-----------------------------------------------------------------
     * First check if we need to do any replacement
     *----------------------------------------------------------------*/
    if (pszString == NULL || strchr(pszString, '\n') == NULL)
    {
        return pszString;
    }

    /*-----------------------------------------------------------------
     * OK, we need to do some replacements... alloc a copy big enough
     * to hold the worst possible case
     *----------------------------------------------------------------*/
    char *pszWorkString = (char *)CPLMalloc(2*sizeof(char) * 
                                            (strlen(pszString) +1));

    int i =0;
    int j =0;

    while (pszString[i])
    {
        if (pszString[i] =='\n')
        {
            pszWorkString[j++] = '\\';
            pszWorkString[j++] = 'n';
            i++;
        }
        else if (pszString[i] =='\\')
        {
            pszWorkString[j++] = '\\';
            pszWorkString[j++] = '\\';
            i++;
        }
        else
        {
            pszWorkString[j++] = pszString[i++];
        }
    }
    pszWorkString[j++] = '\0';

    return pszWorkString;
}

/**********************************************************************
 *                       TABCleanFieldName()
 *
 * Return a copy of pszSrcName that contains only valid characters for a
 * TAB field name.  All invalid characters are replaced by '_'.
 *
 * The returned string should be freed by the caller.
 **********************************************************************/
char *TABCleanFieldName(const char *pszSrcName)
{
    char *pszNewName;
    int numInvalidChars = 0;

    pszNewName = CPLStrdup(pszSrcName);

    if (strlen(pszNewName) > 31)
    {
        pszNewName[31] = '\0';
        CPLError(CE_Warning, TAB_WarningInvalidFieldName,
                 "Field name '%s' is longer than the max of 31 characters. "
                 "'%s' will be used instead.", pszSrcName, pszNewName);
    }

#if defined(_WIN32) && !defined(unix) && !defined(WIN32CE)
    /*-----------------------------------------------------------------
     * On Windows, check if we're using a double-byte codepage, and
     * if so then just keep the field name as is... 
     *----------------------------------------------------------------*/
    if (_getmbcp() != 0)
        return pszNewName;
#endif

    /*-----------------------------------------------------------------
     * According to the MapInfo User's Guide (p. 240, v5.5)
     * New Table Command:
     *  Name:
     * Displays the field name in the name box. You can also enter new field
     * names here. Defaults are Field1, Field2, etc. A field name can contain
     * up to 31 alphanumeric characters. Use letters, numbers, and the 
     * underscore. Do not use spaces; instead, use the underscore character
     * (_) to separate words in a field name. Use upper and lower case for
     * legibility, but MapInfo is not case-sensitive.
     *
     * It was also verified that extended chars with accents are also 
     * accepted.
     *----------------------------------------------------------------*/
    for(int i=0; pszSrcName && pszSrcName[i] != '\0'; i++)
    {
        if ( !( pszSrcName[i] == '_' ||
                (pszSrcName[i]>='0' && pszSrcName[i]<='9') || 
                (pszSrcName[i]>='a' && pszSrcName[i]<='z') || 
                (pszSrcName[i]>='A' && pszSrcName[i]<='Z') ||
                (GByte)pszSrcName[i]>=192 ) )
        {
            pszNewName[i] = '_';
            numInvalidChars++;
        }
    }

    if (numInvalidChars > 0)
    {
        CPLError(CE_Warning, TAB_WarningInvalidFieldName,
                 "Field name '%s' contains invalid characters. "
                 "'%s' will be used instead.", pszSrcName, pszNewName);
    }

    return pszNewName;
}


/**********************************************************************
 * MapInfo Units string to numeric ID conversion
 **********************************************************************/
typedef struct 
{
    int         nUnitId;
    char        *pszAbbrev;
} MapInfoUnitsInfo;

static MapInfoUnitsInfo gasUnitsList[] = 
{
    {0, "mi"},
    {1, "km"},
    {2, "in"},
    {3, "ft"},
    {4, "yd"},
    {5, "mm"},
    {6, "cm"},
    {7, "m"},
    {8, "survey ft"},
    {9, "nmi"},
    {30, "li"},
    {31, "ch"},
    {32, "rd"},
    {-1, NULL}
};


/**********************************************************************
 *                       TABUnitIdToString()
 *
 * Return the MIF units name for specified units id.
 * Return "" if no match found.
 *
 * The returned string should not be freed by the caller.
 **********************************************************************/
const char *TABUnitIdToString(int nId)
{
    MapInfoUnitsInfo *psList;

    psList = gasUnitsList;

    while(psList->nUnitId != -1)
    {
        if (psList->nUnitId == nId) 
            return psList->pszAbbrev;
        psList++;
    }

    return "";
}

/**********************************************************************
 *                       TABUnitIdFromString()
 *
 * Return the units ID for specified MIF units name
 *
 * Returns -1 if no match found.
 **********************************************************************/
int TABUnitIdFromString(const char *pszName)
{
    MapInfoUnitsInfo *psList;

    psList = gasUnitsList;

    while(psList->nUnitId != -1)
    {
        if (EQUAL(psList->pszAbbrev, pszName)) 
            return psList->nUnitId;
        psList++;
    }

    return -1;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -