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

📄 mitab_feature_mif.cpp

📁 mitab,读取MapInfo的地图文件
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/**********************************************************************
 * $Id: mitab_feature_mif.cpp,v 1.33 2008/02/01 20:30:59 dmorissette Exp $
 *
 * Name:     mitab_feature.cpp
 * Project:  MapInfo TAB Read/Write library
 * Language: C++
 * Purpose:  Implementation of R/W Fcts for (Mid/Mif) in feature classes 
 *           specific to MapInfo files.
 * Author:   Stephane Villeneuve, stephane.v@videotron.ca
 *
 **********************************************************************
 * Copyright (c) 1999-2002, Stephane Villeneuve
 *
 * 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: mitab_feature_mif.cpp,v $
 * Revision 1.33  2008/02/01 20:30:59  dmorissette
 * Use %.15g instead of %.16g as number precision in .MIF output
 *
 * Revision 1.32  2007/06/07 20:27:21  dmorissette
 * Fixed memory leaks when reading multipoint objects from .MIF files
 *
 * Revision 1.31  2006/01/27 13:44:44  fwarmerdam
 * fixed Mills.mif reading, crash at file end
 *
 * Revision 1.30  2006/01/26 21:26:36  fwarmerdam
 * fixed bug with multi character delimeters in .mid file
 *
 * Revision 1.29  2005/10/04 19:36:10  dmorissette
 * Added support for reading collections from MIF files (bug 1126)
 *
 * Revision 1.28  2005/10/04 15:44:31  dmorissette
 * First round of support for Collection objects. Currently supports reading
 * from .TAB/.MAP and writing to .MIF. Still lacks symbol support and write
 * support. (Based in part on patch and docs from Jim Hope, bug 1126)
 *
 * Revision 1.27  2005/10/04 15:35:52  dmorissette
 * Fixed an instance of hardcoded delimiter (",") in WriteRecordToMIDFile()
 * (patch by KB Kieron, bug 1126)
 *
 * Revision 1.26  2005/07/14 16:15:05  jlacroix
 * \n and \ are now unescaped internally.
 *
 * Revision 1.25  2003/12/19 07:52:34  fwarmerdam
 * write 3d as 2d
 *
 * Revision 1.24  2002/11/27 22:51:52  daniel
 * Bug 1631:Do not produce an error if .mid data records end with a stray ','
 * Treat tabs (\t) as a blank space delimiter when reading .mif coordinates
 *
 * Revision 1.23  2002/10/29 21:09:20  warmerda
 * Ensure that a blank line in a mid file is treated as one field containing
 * an empty string.
 *
 * Revision 1.22  2002/04/26 14:16:49  julien
 * Finishing the implementation of Multipoint (support for MIF)
 *
 * Revision 1.21  2002/03/26 01:48:40  daniel
 * Added Multipoint object type (V650)
 *
 * Revision 1.20  2002/01/23 20:31:21  daniel
 * Fixed warning produced by CPLAssert() in non-DEBUG mode.
 *
 * Revision 1.19  2001/06/25 01:50:42  daniel
 * Fixed MIF Text object output: negative text angles were lost.  Also use
 * TABText::SetTextAngle() when reading MIF instead of setting class members
 * directly so that negative angles get converted to the [0..360] range.
 *
 * Revision 1.18  2001/02/28 07:15:09  daniel
 * Added support for text label line end point
 *
 * Revision 1.17  2001/01/22 16:03:58  warmerda
 * expanded tabs
 *
 * Revision 1.16  2000/10/03 19:29:51  daniel
 * Include OGR StyleString stuff (implemented by Stephane)
 *
 * Revision 1.15  2000/09/28 16:39:44  warmerda
 * avoid warnings for unused, and unitialized variables
 *
 * Revision 1.14  2000/09/19 17:23:53  daniel
 * Maintain and/or compute valid region and polyline center/label point
 *
 * Revision 1.13  2000/03/27 03:33:45  daniel
 * Treat SYMBOL line as optional when reading TABPoint
 *
 * Revision 1.12  2000/02/28 16:56:32  daniel
 * Support pen width in points (width values 11 to 2047)
 *
 * Revision 1.11  2000/01/15 22:30:44  daniel
 * Switch to MIT/X-Consortium OpenSource license
 *
 * Revision 1.10  2000/01/14 23:51:37  daniel
 * Fixed handling of "\n" in TABText strings... now the external interface
 * of the lib returns and expects escaped "\"+"n" as described in MIF specs
 *
 * Revision 1.9  1999/12/19 17:37:14  daniel
 * Fixed memory leaks
 *
 * Revision 1.8  1999/12/19 01:02:50  stephane
 * Add a test on the CENTER information
 *
 * Revision 1.7  1999/12/18 23:23:23  stephane
 * Change the format of the output double from %g to %.16g
 *
 * Revision 1.6  1999/12/18 08:22:57  daniel
 * Removed stray break statement in PLINE MULTIPLE write code
 *
 * Revision 1.5  1999/12/18 07:21:30  daniel
 * Fixed test on geometry type when writing OGRMultiLineStrings
 *
 * Revision 1.4  1999/12/18 07:11:57  daniel
 * Return regions as OGRMultiPolygons instead of multiple rings OGRPolygons
 *
 * Revision 1.3  1999/12/16 17:16:44  daniel
 * Use addRing/GeometryDirectly() (prevents leak), and rounded rectangles
 * always return real corner radius from file even if it is bigger than MBR
 *
 * Revision 1.2  1999/11/11 01:22:05  stephane
 * Remove DebugFeature call, Point Reading error, add IsValidFeature() to 
 * test correctly if we are on a feature
 *
 * Revision 1.1  1999/11/08 19:20:30  stephane
 * First version
 *
 * Revision 1.1  1999/11/08 04:16:07  stephane
 * First Revision
 *
 *
 **********************************************************************/

#include "mitab.h"
#include "mitab_utils.h"
#include <ctype.h>

/*=====================================================================
 *                      class TABFeature
 *====================================================================*/

/************************************************************************/
/*                            MIDTokenize()                             */
/*                                                                      */
/*      We implement a special tokenize function so we can handle       */
/*      multibyte delimeters (ie. MITAB bug 1266).                      */
/*                                                                      */
/*      http://bugzilla.maptools.org/show_bug.cgi?id=1266               */
/************************************************************************/
static char **MIDTokenize( const char *pszLine, const char *pszDelim )

{
    char **papszResult = NULL;
    int iChar, iTokenChar = 0, bInQuotes = FALSE;
    char *pszToken = (char *) CPLMalloc(strlen(pszLine)+1);
    int nDelimLen = strlen(pszDelim);

    for( iChar = 0; pszLine[iChar] != '\0'; iChar++ )
    {
        if( bInQuotes && pszLine[iChar] == '\\' && pszLine[iChar+1] == '"' )
        {
            pszToken[iTokenChar++] = '"';
            iChar++;
        }
        else if( pszLine[iChar] == '"' )
        {
            bInQuotes = !bInQuotes;
        }
        else if( !bInQuotes && strncmp(pszLine+iChar,pszDelim,nDelimLen) == 0 )
        {
            pszToken[iTokenChar++] = '\0';
            papszResult = CSLAddString( papszResult, pszToken );
            
            iChar += strlen(pszDelim) - 1;
            iTokenChar = 0;
        }
        else
        {
            pszToken[iTokenChar++] = pszLine[iChar];
        }
    }

    pszToken[iTokenChar++] = '\0';
    papszResult = CSLAddString( papszResult, pszToken );

    CPLFree( pszToken );

    return papszResult;
}

/**********************************************************************
 *                   TABFeature::ReadRecordFromMIDFile()
 *
 *  This method is used to read the Record (Attributs) for all type of
 *  feature included in a mid/mif file.
 * 
 * Returns 0 on success, -1 on error, in which case CPLError() will have
 * been called.
 **********************************************************************/
int TABFeature::ReadRecordFromMIDFile(MIDDATAFile *fp)
{
    const char       *pszLine;
    char            **papszToken;
    int               nFields,i;

    nFields = GetFieldCount();
    
    pszLine = fp->GetLastLine();

    if (pszLine == NULL)
    {
        CPLError(CE_Failure, CPLE_FileIO,
               "Unexpected EOF while reading attribute record from MID file.");
        return -1;
    }

    papszToken = MIDTokenize( pszLine, fp->GetDelimiter() );

    // Ensure that a blank line in a mid file is treated as one field 
    // containing an empty string.
    if( nFields == 1 && CSLCount(papszToken) == 0 && pszLine[0] == '\0' )
        papszToken = CSLAddString(papszToken,"");

    // Make sure we found at least the expected number of field values.
    // Note that it is possible to have a stray delimiter at the end of
    // the line (mif/mid files from Geomedia), so don't produce an error
    // if we find more tokens than expected.
    if (CSLCount(papszToken) < nFields)
    {
        CSLDestroy(papszToken);
        return -1;
    }

    for (i=0;i<nFields;i++)
    {
        SetField(i,papszToken[i]);
    }
    
    fp->GetLine();

    CSLDestroy(papszToken);

    return 0;
}

/**********************************************************************
 *                   TABFeature::WriteRecordToMIDFile()
 *
 *  This methode is used to write the Record (Attributs) for all type
 *  of feature included in a mid file.
 *
 *  Return 0 on success, -1 on error
 **********************************************************************/
int TABFeature::WriteRecordToMIDFile(MIDDATAFile *fp)
{
    int                  iField, numFields;
    OGRFieldDefn        *poFDefn = NULL;

    CPLAssert(fp);
    
    const char *delimiter = fp->GetDelimiter();

    numFields = GetFieldCount();

    for(iField=0; iField<numFields; iField++)
    {
        if (iField != 0)
          fp->WriteLine(delimiter);
        poFDefn = GetFieldDefnRef( iField );

        switch(poFDefn->GetType())
        {
          case OFTString:
            fp->WriteLine("\"%s\"",GetFieldAsString(iField));
            break;          
          default:
            fp->WriteLine("%s",GetFieldAsString(iField));
        }
    }

    fp->WriteLine("\n");

    return 0;
}

/**********************************************************************
 *                   TABFeature::ReadGeometryFromMIFFile()
 *
 * In derived classes, this method should be reimplemented to
 * fill the geometry and representation (color, etc...) part of the
 * feature from the contents of the .MAP object pointed to by poMAPFile.
 *
 * It is assumed that before calling ReadGeometryFromMAPFile(), poMAPFile
 * currently points to the beginning of a map object.
 *
 * The current implementation does nothing since instances of TABFeature
 * objects contain no geometry (i.e. TAB_GEOM_NONE).
 * 
 * Returns 0 on success, -1 on error, in which case CPLError() will have
 * been called.
 **********************************************************************/
int TABFeature::ReadGeometryFromMIFFile(MIDDATAFile *fp)
{
    const char *pszLine;
    
    /* Go to the first line of the next feature */

    while (((pszLine = fp->GetLine()) != NULL) && 
           fp->IsValidFeature(pszLine) == FALSE)
      ;

    return 0;
}

/**********************************************************************
 *                   TABFeature::WriteGeometryToMIFFile()
 *
 *
 * In derived classes, this method should be reimplemented to
 * write the geometry and representation (color, etc...) part of the
 * feature to the .MAP object pointed to by poMAPFile.
 *
 * It is assumed that before calling WriteGeometryToMAPFile(), poMAPFile
 * currently points to a valid map object.
 *
 * The current implementation does nothing since instances of TABFeature
 * objects contain no geometry.
 * 
 * Returns 0 on success, -1 on error, in which case CPLError() will have
 * been called.
 **********************************************************************/
int TABFeature::WriteGeometryToMIFFile(MIDDATAFile *fp)
{
    fp->WriteLine("NONE\n");
    return 0;
}

/**********************************************************************
 *
 **********************************************************************/
int TABPoint::ReadGeometryFromMIFFile(MIDDATAFile *fp)
{  
    OGRGeometry         *poGeometry;
    
    char               **papszToken;
    const char *pszLine;
    double dfX,dfY;
    papszToken = CSLTokenizeString2(fp->GetSavedLine(), 
                                    " \t", CSLT_HONOURSTRINGS);
     
    if (CSLCount(papszToken) !=3)
    {
        CSLDestroy(papszToken);
        return -1;
    }
    
    dfX = fp->GetXTrans(atof(papszToken[1]));
    dfY = fp->GetYTrans(atof(papszToken[2]));

    CSLDestroy(papszToken);
    papszToken = NULL;

    // Read optional SYMBOL line...

⌨️ 快捷键说明

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