📄 mitab_feature_mif.cpp
字号:
/**********************************************************************
* $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 + -