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

📄 avc_e00write.c

📁 用于读取TAB、MIF、SHP文件的类
💻 C
📖 第 1 页 / 共 3 页
字号:
/********************************************************************** * $Id: avc_e00write.c,v 1.20 2006/06/27 18:38:43 dmorissette Exp $ * * Name:     avc_e00write.c * Project:  Arc/Info vector coverage (AVC)  E00->BIN conversion library * Language: ANSI C * Purpose:  Functions to create a binary coverage from a stream of *           ASCII E00 lines. * Author:   Daniel Morissette, dmorissette@dmsolutions.ca * ********************************************************************** * Copyright (c) 1999-2001, Daniel Morissette * * 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. ********************************************************************** * * $Log: avc_e00write.c,v $ * Revision 1.20  2006/06/27 18:38:43  dmorissette * Cleaned up E00 reading (bug 1497, patch from James F.) * * Revision 1.19  2006/06/14 16:31:28  daniel * Added support for AVCCoverPC2 type (bug 1491) * * Revision 1.18  2006/03/02 22:46:26  daniel * Accept empty subclass names for TX6/TX7 sections (bug 1261) * * Revision 1.17  2005/06/03 03:49:59  daniel * Update email address, website url, and copyright dates * * Revision 1.16  2002/08/27 15:46:15  daniel * Applied fix made in GDAL/OGR by 'aubin' (moved include ctype.h after avc.h) * * Revision 1.15  2002/04/16 21:19:10  daniel * Use VSIRmdir() * * Revision 1.14  2002/03/18 19:00:44  daniel * Use VSIMkdir() and not VSIMkDir() * * Revision 1.13  2002/02/18 21:16:33  warmerda * modified to use VSIMkDir * * Revision 1.12  2001/05/23 15:23:17  daniel * Remove trailing '/' in info directory path when creating the info dir. * * Revision 1.11  2000/09/26 20:21:04  daniel * Added AVCCoverPC write * * Revision 1.10  2000/09/22 19:45:21  daniel * Switch to MIT-style license * * Revision 1.9  2000/05/29 22:47:39  daniel * Made validation on new coverage name more flexible. * * Revision 1.8  2000/05/29 15:31:31  daniel * Added Japanese DBCS support * * Revision 1.7  2000/02/14 17:19:53  daniel * Accept '-' cahracter in new coverage name * * Revision 1.6  2000/01/10 02:57:44  daniel * Little changes to accomodate read support for "weird" coverages * * Revision 1.5  1999/12/24 07:18:34  daniel * Added PC Arc/Info coverages support * * Revision 1.4  1999/08/26 17:36:36  daniel * Avoid overwriting arc.dir on Windows... happened only when several * coverages are created by the same process on Windows. * * Revision 1.3  1999/08/23 18:23:35  daniel * Added AVCE00DeleteCoverage() * * Revision 1.2  1999/05/17 16:23:36  daniel * Added AVC_DEFAULT_PREC + more cover name validation in AVCE00WriteOpen(). * * Revision 1.1  1999/05/11 02:34:46  daniel * Initial revision * **********************************************************************/#include "cpl_vsi.h"#include "avc.h"#include <ctype.h>      /* tolower() */static GBool _IsStringAlnum(const char *pszFname);/********************************************************************** *                          AVCE00WriteOpen() * * Open (create) an Arc/Info coverage, ready to be receive a stream * of ASCII E00 lines and convert that to the binary coverage format. * * For now, writing to or overwriting existing coverages is not supported * (and may quite well never be!)... you can only create new coverages. * * Important Note: The E00 source lines are assumed to be valid... the * library performs no validation on the consistency of what it is  * given as input (i.e. topology, polygons consistency, etc.). * So the coverage that will be created will be only as good as the  * E00 input that is used to generate it. * * pszCoverPath MUST be the name of the coverage directory, including  * the path to it. * (contrary to AVCE00ReadOpen(), you cannot pass the name of one of *  the files in the coverage directory). * The name of the coverage MUST be included in pszCoverPath... this  * means that passing "." is invalid. * * eNewCoverType is the type of coverage to create.   *               Either AVCCoverV7 (Arc/Info V7 (Unix) coverage) *               or     AVCCoverPC (PC Arc/Info coverage) * * nPrecision should always be AVC_DEFAULT_PREC to automagically detect the *            source coverage's precision and use that same precision *            for the new coverage.   * *            This parameter has been included to allow adding the  *            possibility to eventually create coverages with a precision  *            different from the source E00. *            Given the way the lib is built, it could be possible to *            also pass  AVC_SINGLE_PREC or AVC_DOUBLE_PREC to explicitly *            request the creation of a coverage with that precision,  *            but the library does not (not yet!) properly convert the  *            TABLE attributes' precision, and the resulting coverage may *            be invalid in some cases.   *            This improvement is on the ToDo list! * * Returns a new AVCE00WritePtr handle or NULL if the coverage could  * not be created or if a coverage with that name already exists. * * The handle will eventually have to be released with AVCE00ReadClose(). **********************************************************************/AVCE00WritePtr  AVCE00WriteOpen(const char *pszCoverPath,                                 AVCCoverType eNewCoverType, int nPrecision ){    AVCE00WritePtr  psInfo;    int             i, nLen;    VSIStatBuf      sStatBuf;    CPLErrorReset();    /*-----------------------------------------------------------------     * Create pszCoverPath directory.       *----------------------------------------------------------------*/    if (pszCoverPath == NULL || strlen(pszCoverPath) == 0)    {        CPLError(CE_Failure, CPLE_AssertionFailed,                  "Invalid (empty) coverage directory name.");        return NULL;    }    else if ( VSIStat(pszCoverPath, &sStatBuf) == 0 &&              VSI_ISDIR(sStatBuf.st_mode) )    {        /*-------------------------------------------------------------         * Directory already exists... make sure it is empty         * otherwise we can't use it as a coverage directory.         *------------------------------------------------------------*/        char **papszFiles;        papszFiles = CPLReadDir(pszCoverPath);        for(i=0; papszFiles && papszFiles[i]; i++)        {            if (!EQUAL(".", papszFiles[i]) &&                !EQUAL("..", papszFiles[i]))            {                CPLError(CE_Failure, CPLE_OpenFailed,                          "Cannot create coverage %s: directory already exists "                         "and is not empty.", pszCoverPath);                CSLDestroy(papszFiles);                papszFiles = NULL;                return NULL;            }        }        CSLDestroy(papszFiles);        papszFiles = NULL;    }    else    {        /*-------------------------------------------------------------         * Create new pszCoverPath directory.           * This will fail if a file with the same name already exists.         *------------------------------------------------------------*/        if( VSIMkdir(pszCoverPath, 0777) != 0 )        {            CPLError(CE_Failure, CPLE_OpenFailed,                      "Unable to create coverage directory: %s.", pszCoverPath);            return NULL;        }    }    /*-----------------------------------------------------------------     * Alloc the AVCE00WritePtr handle     *----------------------------------------------------------------*/    psInfo = (AVCE00WritePtr)CPLCalloc(1, sizeof(struct AVCE00WriteInfo_t));    /*-----------------------------------------------------------------     * Validate and store coverage type     *----------------------------------------------------------------*/    if (eNewCoverType == AVCCoverV7 || eNewCoverType == AVCCoverPC)        psInfo->eCoverType = eNewCoverType;    else    {        CPLError(CE_Failure, CPLE_NotSupported,                  "Requested coverage type cannot be created.  Please use "                 "the AVCCoverV7 or AVCCoverPC coverage type.");        CPLFree(psInfo);        return NULL;    }    /*-----------------------------------------------------------------     * Requested precision for the new coverage... for now only     * AVC_DEFAULT_PREC is supported.  When the first section is     * read, then this section's precision will be used for the whole     * coverage.  (This is done inside AVCE00WriteNextLine())     *----------------------------------------------------------------*/    if (psInfo->eCoverType == AVCCoverPC)        psInfo->nPrecision = AVC_SINGLE_PREC; /* PC Cover always single prec.*/    else if (nPrecision == AVC_DEFAULT_PREC)        psInfo->nPrecision = nPrecision;    else    {        CPLError(CE_Failure, CPLE_IllegalArg,                  "Coverages can only be created using AVC_DEFAULT_PREC. "                 "Please see the documentation for AVCE00WriteOpen().");        CPLFree(psInfo);        return NULL;    }    /*-----------------------------------------------------------------     * Make sure coverage directory name is terminated with a '/' (or '\\')     *----------------------------------------------------------------*/    nLen = strlen(pszCoverPath);    if (pszCoverPath[nLen-1] == '/' || pszCoverPath[nLen-1] == '\\')        psInfo->pszCoverPath = CPLStrdup(pszCoverPath);    else    {#ifdef WIN32        psInfo->pszCoverPath = CPLStrdup(CPLSPrintf("%s\\",pszCoverPath));#else        psInfo->pszCoverPath = CPLStrdup(CPLSPrintf("%s/",pszCoverPath));#endif    }    /*-----------------------------------------------------------------     * Extract the coverage name from the coverage path.  Note that     * for this the coverage path must be in the form:     * "dir1/dir2/dir3/covername/" ... if it is not the case, then     * we would have to use getcwd() to find the current directory name...     * but for now we'll just produce an error if this happens.     *----------------------------------------------------------------*/    nLen = 0;    for( i = strlen(psInfo->pszCoverPath)-1; 	 i > 0 && psInfo->pszCoverPath[i-1] != '/' &&	          psInfo->pszCoverPath[i-1] != '\\'&&	          psInfo->pszCoverPath[i-1] != ':';	 i-- )     {        nLen++;    }    if (nLen > 0)    {        psInfo->pszCoverName = CPLStrdup(psInfo->pszCoverPath+i);        psInfo->pszCoverName[nLen] = '\0';    }    else    {        CPLError(CE_Failure, CPLE_OpenFailed,                  "Invalid coverage path (%s): "                 "coverage name must be included in path.", pszCoverPath);        CPLFree(psInfo->pszCoverPath);        CPLFree(psInfo);        return NULL;    }    if (strlen(psInfo->pszCoverName) > 13 ||        !_IsStringAlnum(psInfo->pszCoverName) )    {        CPLError(CE_Failure, CPLE_OpenFailed,                  "Invalid coverage name (%s): "                 "coverage name must be 13 chars or less and contain only "                 "alphanumerical characters, '-' or '_'.",                  psInfo->pszCoverName);        CPLFree(psInfo->pszCoverPath);        CPLFree(psInfo->pszCoverName);        CPLFree(psInfo);        return NULL;    }    if (psInfo->eCoverType == AVCCoverPC || psInfo->eCoverType == AVCCoverPC2)    {        /*-------------------------------------------------------------         * No 'info' directory is required for PC coverages         *------------------------------------------------------------*/        psInfo->pszInfoPath = NULL;    }    else    {        /*-------------------------------------------------------------         * Lazy way to build the INFO path: simply add "../info/"...         * this could probably be improved!         *------------------------------------------------------------*/        psInfo->pszInfoPath = (char*)CPLMalloc((strlen(psInfo->pszCoverPath)+9)                                               *sizeof(char));#ifdef WIN32#  define AVC_INFOPATH "..\\info\\"#else#  define AVC_INFOPATH "../info/"#endif        sprintf(psInfo->pszInfoPath, "%s%s", psInfo->pszCoverPath,                                              AVC_INFOPATH);        /*-------------------------------------------------------------         * Check if the info directory exists and contains the "arc.dir"         * if the info dir does not exist, then make sure we can create         * the arc.dir file (i.e. try to create an empty one)         *         * Note: On Windows, this VSIStat() call seems to sometimes fail even 

⌨️ 快捷键说明

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