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

📄 ogrshapedatasource.cpp

📁 用于读取TAB、MIF、SHP文件的类
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************** * $Id: ogrshapedatasource.cpp,v 1.33 2006/04/05 20:34:57 fwarmerdam Exp $ * * Project:  OpenGIS Simple Features Reference Implementation * Purpose:  Implements OGRShapeDataSource class. * Author:   Frank Warmerdam, warmerdam@pobox.com * ****************************************************************************** * Copyright (c) 1999,  Les Technologies SoftMap Inc. * * 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: ogrshapedatasource.cpp,v $ * Revision 1.33  2006/04/05 20:34:57  fwarmerdam * ensure only-dbf errors are cleared: Bug 1115 * * Revision 1.32  2006/03/28 23:22:08  fwarmerdam * update contact info * * Revision 1.31  2006/01/11 03:03:19  fwarmerdam * Assign .prj filename to temporary string. * * Revision 1.30  2006/01/10 16:37:57  fwarmerdam * implemented REPACK support * * Revision 1.29  2006/01/06 19:07:37  fwarmerdam * Pass wkbNone to OGRShapeLayer as the requested type when opening * existing files so their type won't get reset by the "first feature" * logic in CreateFeature() when appending to empty shapefiles. * * Revision 1.28  2005/12/14 16:17:52  fwarmerdam * Fixed wkbMultiPolygon to map to POLYGON, not POLYGONZ. * * Revision 1.27  2005/11/07 17:05:26  fwarmerdam * Ensure morphToESRI() is used on spatial reference before writing .prj file. * * Revision 1.26  2005/01/04 03:43:22  fwarmerdam * added support for create/destroy spatial index sql commands * * Revision 1.25  2005/01/03 22:26:21  fwarmerdam * updated to use spatial indexing * * Revision 1.24  2004/03/01 18:41:00  warmerda * added fix for bug 493: ignore pc arcinfo coverages * * Revision 1.23  2003/07/13 23:06:28  warmerda * Added case for wkbMultiPoint25D to SHPT_MULTIPOINTZ. * * Revision 1.22  2003/05/27 21:39:53  warmerda * added support for writing MULTILINESTRINGs as ARCs * * Revision 1.21  2003/05/21 04:03:54  warmerda * expand tabs * * Revision 1.20  2003/03/27 22:12:14  warmerda * Yow ... fix to second last fix. * * Revision 1.19  2003/03/27 22:11:39  warmerda * Fixed similar bug to the last. * * Revision 1.18  2003/03/27 22:09:43  warmerda * fixed shallow copy problem with return result from CPLGetBasename() * as per http://bugzilla.remotesensing.org/show_bug.cgi?id=310. * * Revision 1.17  2003/03/20 19:11:30  warmerda * free pszBasename after it is used * * Revision 1.16  2003/03/04 05:49:05  warmerda * added attribute indexing support */#include "ogrshape.h"#include "cpl_conv.h"#include "cpl_string.h"CPL_CVSID("$Id: ogrshapedatasource.cpp,v 1.33 2006/04/05 20:34:57 fwarmerdam Exp $");/************************************************************************//*                         OGRShapeDataSource()                         *//************************************************************************/OGRShapeDataSource::OGRShapeDataSource(){    pszName = NULL;    papoLayers = NULL;    nLayers = 0;    bSingleNewFile = FALSE;}/************************************************************************//*                        ~OGRShapeDataSource()                         *//************************************************************************/OGRShapeDataSource::~OGRShapeDataSource(){    CPLFree( pszName );    for( int i = 0; i < nLayers; i++ )        delete papoLayers[i];        CPLFree( papoLayers );}/************************************************************************//*                                Open()                                *//************************************************************************/int OGRShapeDataSource::Open( const char * pszNewName, int bUpdate,                              int bTestOpen, int bSingleNewFileIn ){    VSIStatBuf  stat;        CPLAssert( nLayers == 0 );        pszName = CPLStrdup( pszNewName );    bDSUpdate = bUpdate;    bSingleNewFile = bSingleNewFileIn;/* -------------------------------------------------------------------- *//*      If bSingleNewFile is TRUE we don't try to do anything else.     *//*      This is only utilized when the OGRShapeDriver::Create()         *//*      method wants to create a stub OGRShapeDataSource for a          *//*      single shapefile.  The driver will take care of creating the    *//*      file by calling CreateLayer().                                  *//* -------------------------------------------------------------------- */    if( bSingleNewFile )        return TRUE;    /* -------------------------------------------------------------------- *//*      Is the given path a directory or a regular file?                *//* -------------------------------------------------------------------- */    if( CPLStat( pszNewName, &stat ) != 0         || (!VSI_ISDIR(stat.st_mode) && !VSI_ISREG(stat.st_mode)) )    {        if( !bTestOpen )            CPLError( CE_Failure, CPLE_AppDefined,                   "%s is neither a file or directory, Shape access failed.\n",                      pszNewName );        return FALSE;    }    /* -------------------------------------------------------------------- *//*      Build a list of filenames we figure are Shape files.            *//* -------------------------------------------------------------------- */    if( VSI_ISREG(stat.st_mode) )    {        if( !OpenFile( pszNewName, bUpdate, bTestOpen ) )        {            if( !bTestOpen )                CPLError( CE_Failure, CPLE_OpenFailed,                          "Failed to open shapefile %s.\n"                          "It may be corrupt.\n",                          pszNewName );            return FALSE;        }        return TRUE;    }    else    {        char      **papszCandidates = CPLReadDir( pszNewName );        int       iCan, nCandidateCount = CSLCount( papszCandidates );        int       bMightBeOldCoverage = FALSE;        for( iCan = 0; iCan < nCandidateCount; iCan++ )        {            char        *pszFilename;            const char  *pszCandidate = papszCandidates[iCan];            if( EQUAL(pszCandidate,"ARC") )                bMightBeOldCoverage = TRUE;            if( strlen(pszCandidate) < 4                || !EQUAL(pszCandidate+strlen(pszCandidate)-4,".shp") )                continue;            pszFilename =                CPLStrdup(CPLFormFilename(pszNewName, pszCandidate, NULL));            if( !OpenFile( pszFilename, bUpdate, bTestOpen )                && !bTestOpen )            {                CPLError( CE_Failure, CPLE_OpenFailed,                          "Failed to open shapefile %s.\n"                          "It may be corrupt.\n",                          pszFilename );                CPLFree( pszFilename );                return FALSE;            }                        CPLFree( pszFilename );        }        // Try and .dbf files without apparent associated shapefiles.         for( iCan = 0; iCan < nCandidateCount; iCan++ )        {            char        *pszFilename;            const char  *pszCandidate = papszCandidates[iCan];            const char  *pszLayerName;            int         iLayer, bGotAlready = FALSE;            // We don't consume .dbf files in a directory that looks like            // an old style Arc/Info (for PC?) that unless we found at least            // some shapefiles.  See Bug 493.             if( bMightBeOldCoverage && nLayers == 0 )                continue;            if( strlen(pszCandidate) < 4                || !EQUAL(pszCandidate+strlen(pszCandidate)-4,".dbf") )                continue;            pszLayerName = CPLGetBasename(pszCandidate);            for( iLayer = 0; iLayer < nLayers; iLayer++ )            {                if( EQUAL(pszLayerName,                          GetLayer(iLayer)->GetLayerDefn()->GetName()) )                    bGotAlready = TRUE;            }                        if( bGotAlready )                continue;            // We don't want to access .dbf files with an associated .tab            // file, or it will never get recognised as a mapinfo dataset.            int  iCan2, bFoundTAB = FALSE;            for( iCan2 = 0; iCan2 < nCandidateCount; iCan2++ )            {                const char *pszCandidate2 = papszCandidates[iCan2];                if( EQUALN(pszCandidate2,pszLayerName,strlen(pszLayerName))                    && EQUAL(pszCandidate2 + strlen(pszLayerName), ".tab") )                    bFoundTAB = TRUE;            }            if( bFoundTAB )                continue;                        pszFilename =                CPLStrdup(CPLFormFilename(pszNewName, pszCandidate, NULL));            if( !OpenFile( pszFilename, bUpdate, bTestOpen )                && !bTestOpen )            {                CPLError( CE_Failure, CPLE_OpenFailed,                          "Failed to open dbf file %s.\n"                          "It may be corrupt.\n",                          pszFilename );                CPLFree( pszFilename );                return FALSE;            }                        CPLFree( pszFilename );        }        CSLDestroy( papszCandidates );                if( !bTestOpen && nLayers == 0 && !bUpdate )        {            CPLError( CE_Failure, CPLE_OpenFailed,                      "No Shapefiles found in directory %s\n",                      pszNewName );        }    }    return nLayers > 0 || bUpdate;}/************************************************************************//*                              OpenFile()                              *//************************************************************************/int OGRShapeDataSource::OpenFile( const char *pszNewName, int bUpdate,                                  int bTestOpen ){    SHPHandle   hSHP;    DBFHandle   hDBF;    const char *pszExtension = CPLGetExtension( pszNewName );    (void) bTestOpen;    if( !EQUAL(pszExtension,"shp") && !EQUAL(pszExtension,"shx")        && !EQUAL(pszExtension,"dbf") )        return FALSE;/* -------------------------------------------------------------------- *//*      SHPOpen() should include better (CPL based) error reporting,    *//*      and we should be trying to distinquish at this point whether    *//*      failure is a result of trying to open a non-shapefile, or       *//*      whether it was a shapefile and we want to report the error      *//*      up.                                                             *//*                                                                      *//*      Care is taken to suppress the error and only reissue it if      *//*      we think it is appropriate.                                     *//* -------------------------------------------------------------------- */    CPLPushErrorHandler( CPLQuietErrorHandler );    if( bUpdate )        hSHP = SHPOpen( pszNewName, "r+" );    else        hSHP = SHPOpen( pszNewName, "r" );    CPLPopErrorHandler();    if( hSHP == NULL         && (!EQUAL(CPLGetExtension(pszNewName),"dbf")             || strstr(CPLGetLastErrorMsg(),".shp") == NULL) )    {        CPLString osMsg = CPLGetLastErrorMsg();        CPLError( CE_Failure, CPLE_OpenFailed, "%s", osMsg.c_str() );        return FALSE;    }    CPLErrorReset();    /* -------------------------------------------------------------------- *//*      Open the .dbf file, if it exists.  To open a dbf file, the      *//*      filename has to either refer to a successfully opened shp       *//*      file or has to refer to the actual .dbf file.                   *//* -------------------------------------------------------------------- */    if( hSHP != NULL || EQUAL(CPLGetExtension(pszNewName),"dbf") )    {        if( bUpdate )            hDBF = DBFOpen( pszNewName, "r+" );        else            hDBF = DBFOpen( pszNewName, "r" );    }    else        hDBF = NULL;            if( hDBF == NULL && hSHP == NULL )        return FALSE;/* -------------------------------------------------------------------- *//*      Is there an associated .prj file we can read?                   *//* -------------------------------------------------------------------- */    OGRSpatialReference *poSRS = NULL;    const char  *pszPrjFile = CPLResetExtension( pszNewName, "prj" );    FILE        *fp;    fp = VSIFOpen( pszPrjFile, "r" );    if( fp != NULL )    {        char    **papszLines;        VSIFClose( fp );                papszLines = CSLLoad( pszPrjFile );        poSRS = new OGRSpatialReference();        if( poSRS->importFromESRI( papszLines ) != OGRERR_NONE )        {            delete poSRS;            poSRS = NULL;        }        CSLDestroy( papszLines );    }/* -------------------------------------------------------------------- *//*      Create the layer object.                                        *//* -------------------------------------------------------------------- */    OGRShapeLayer       *poLayer;    poLayer = new OGRShapeLayer( pszNewName, hSHP, hDBF, poSRS, bUpdate,                                 wkbNone );    poLayer->InitializeIndexSupport( pszNewName );

⌨️ 快捷键说明

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