LTP GCOV extension - code coverage report
Current view: directory - ogr/ogrsf_frmts/mitab - mitab_feature_mif.cpp
Test: gdal_filtered.info
Date: 2010-07-12 Instrumented lines: 833
Code covered: 20.9 % Executed lines: 174

       1                 : /**********************************************************************
       2                 :  * $Id: mitab_feature_mif.cpp,v 1.35 2008/09/23 14:56:03 aboudreault Exp $
       3                 :  *
       4                 :  * Name:     mitab_feature.cpp
       5                 :  * Project:  MapInfo TAB Read/Write library
       6                 :  * Language: C++
       7                 :  * Purpose:  Implementation of R/W Fcts for (Mid/Mif) in feature classes 
       8                 :  *           specific to MapInfo files.
       9                 :  * Author:   Stephane Villeneuve, stephane.v@videotron.ca
      10                 :  *
      11                 :  **********************************************************************
      12                 :  * Copyright (c) 1999-2002, Stephane Villeneuve
      13                 :  *
      14                 :  * Permission is hereby granted, free of charge, to any person obtaining a
      15                 :  * copy of this software and associated documentation files (the "Software"),
      16                 :  * to deal in the Software without restriction, including without limitation
      17                 :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      18                 :  * and/or sell copies of the Software, and to permit persons to whom the
      19                 :  * Software is furnished to do so, subject to the following conditions:
      20                 :  * 
      21                 :  * The above copyright notice and this permission notice shall be included
      22                 :  * in all copies or substantial portions of the Software.
      23                 :  * 
      24                 :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      25                 :  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      26                 :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
      27                 :  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      28                 :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
      29                 :  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
      30                 :  * DEALINGS IN THE SOFTWARE.
      31                 :  **********************************************************************
      32                 :  *
      33                 :  * $Log: mitab_feature_mif.cpp,v $
      34                 :  * Revision 1.35  2008/09/23 14:56:03  aboudreault
      35                 :  * Fixed an error related to the " character when converting mif to tab file.
      36                 :  *
      37                 :  * Revision 1.34  2008/09/23 13:45:03  aboudreault
      38                 :  * Fixed bug with the characters ",\n in the tab2tab application. (bug 1945)
      39                 :  *
      40                 :  * Revision 1.33  2008/02/01 20:30:59  dmorissette
      41                 :  * Use %.15g instead of %.16g as number precision in .MIF output
      42                 :  *
      43                 :  * Revision 1.32  2007/06/07 20:27:21  dmorissette
      44                 :  * Fixed memory leaks when reading multipoint objects from .MIF files
      45                 :  *
      46                 :  * Revision 1.31  2006/01/27 13:44:44  fwarmerdam
      47                 :  * fixed Mills.mif reading, crash at file end
      48                 :  *
      49                 :  * Revision 1.30  2006/01/26 21:26:36  fwarmerdam
      50                 :  * fixed bug with multi character delimeters in .mid file
      51                 :  *
      52                 :  * Revision 1.29  2005/10/04 19:36:10  dmorissette
      53                 :  * Added support for reading collections from MIF files (bug 1126)
      54                 :  *
      55                 :  * Revision 1.28  2005/10/04 15:44:31  dmorissette
      56                 :  * First round of support for Collection objects. Currently supports reading
      57                 :  * from .TAB/.MAP and writing to .MIF. Still lacks symbol support and write
      58                 :  * support. (Based in part on patch and docs from Jim Hope, bug 1126)
      59                 :  *
      60                 :  * Revision 1.27  2005/10/04 15:35:52  dmorissette
      61                 :  * Fixed an instance of hardcoded delimiter (",") in WriteRecordToMIDFile()
      62                 :  * (patch by KB Kieron, bug 1126)
      63                 :  *
      64                 :  * Revision 1.26  2005/07/14 16:15:05  jlacroix
      65                 :  * \n and \ are now unescaped internally.
      66                 :  *
      67                 :  * Revision 1.25  2003/12/19 07:52:34  fwarmerdam
      68                 :  * write 3d as 2d
      69                 :  *
      70                 :  * Revision 1.24  2002/11/27 22:51:52  daniel
      71                 :  * Bug 1631:Do not produce an error if .mid data records end with a stray ','
      72                 :  * Treat tabs (\t) as a blank space delimiter when reading .mif coordinates
      73                 :  *
      74                 :  * Revision 1.23  2002/10/29 21:09:20  warmerda
      75                 :  * Ensure that a blank line in a mid file is treated as one field containing
      76                 :  * an empty string.
      77                 :  *
      78                 :  * Revision 1.22  2002/04/26 14:16:49  julien
      79                 :  * Finishing the implementation of Multipoint (support for MIF)
      80                 :  *
      81                 :  * Revision 1.21  2002/03/26 01:48:40  daniel
      82                 :  * Added Multipoint object type (V650)
      83                 :  *
      84                 :  * Revision 1.20  2002/01/23 20:31:21  daniel
      85                 :  * Fixed warning produced by CPLAssert() in non-DEBUG mode.
      86                 :  *
      87                 :  * Revision 1.19  2001/06/25 01:50:42  daniel
      88                 :  * Fixed MIF Text object output: negative text angles were lost.  Also use
      89                 :  * TABText::SetTextAngle() when reading MIF instead of setting class members
      90                 :  * directly so that negative angles get converted to the [0..360] range.
      91                 :  *
      92                 :  * Revision 1.18  2001/02/28 07:15:09  daniel
      93                 :  * Added support for text label line end point
      94                 :  *
      95                 :  * Revision 1.17  2001/01/22 16:03:58  warmerda
      96                 :  * expanded tabs
      97                 :  *
      98                 :  * Revision 1.16  2000/10/03 19:29:51  daniel
      99                 :  * Include OGR StyleString stuff (implemented by Stephane)
     100                 :  *
     101                 :  * Revision 1.15  2000/09/28 16:39:44  warmerda
     102                 :  * avoid warnings for unused, and unitialized variables
     103                 :  *
     104                 :  * Revision 1.14  2000/09/19 17:23:53  daniel
     105                 :  * Maintain and/or compute valid region and polyline center/label point
     106                 :  *
     107                 :  * Revision 1.13  2000/03/27 03:33:45  daniel
     108                 :  * Treat SYMBOL line as optional when reading TABPoint
     109                 :  *
     110                 :  * Revision 1.12  2000/02/28 16:56:32  daniel
     111                 :  * Support pen width in points (width values 11 to 2047)
     112                 :  *
     113                 :  * Revision 1.11  2000/01/15 22:30:44  daniel
     114                 :  * Switch to MIT/X-Consortium OpenSource license
     115                 :  *
     116                 :  * Revision 1.10  2000/01/14 23:51:37  daniel
     117                 :  * Fixed handling of "\n" in TABText strings... now the external interface
     118                 :  * of the lib returns and expects escaped "\"+"n" as described in MIF specs
     119                 :  *
     120                 :  * Revision 1.9  1999/12/19 17:37:14  daniel
     121                 :  * Fixed memory leaks
     122                 :  *
     123                 :  * Revision 1.8  1999/12/19 01:02:50  stephane
     124                 :  * Add a test on the CENTER information
     125                 :  *
     126                 :  * Revision 1.7  1999/12/18 23:23:23  stephane
     127                 :  * Change the format of the output double from %g to %.16g
     128                 :  *
     129                 :  * Revision 1.6  1999/12/18 08:22:57  daniel
     130                 :  * Removed stray break statement in PLINE MULTIPLE write code
     131                 :  *
     132                 :  * Revision 1.5  1999/12/18 07:21:30  daniel
     133                 :  * Fixed test on geometry type when writing OGRMultiLineStrings
     134                 :  *
     135                 :  * Revision 1.4  1999/12/18 07:11:57  daniel
     136                 :  * Return regions as OGRMultiPolygons instead of multiple rings OGRPolygons
     137                 :  *
     138                 :  * Revision 1.3  1999/12/16 17:16:44  daniel
     139                 :  * Use addRing/GeometryDirectly() (prevents leak), and rounded rectangles
     140                 :  * always return real corner radius from file even if it is bigger than MBR
     141                 :  *
     142                 :  * Revision 1.2  1999/11/11 01:22:05  stephane
     143                 :  * Remove DebugFeature call, Point Reading error, add IsValidFeature() to 
     144                 :  * test correctly if we are on a feature
     145                 :  *
     146                 :  * Revision 1.1  1999/11/08 19:20:30  stephane
     147                 :  * First version
     148                 :  *
     149                 :  * Revision 1.1  1999/11/08 04:16:07  stephane
     150                 :  * First Revision
     151                 :  *
     152                 :  *
     153                 :  **********************************************************************/
     154                 : 
     155                 : #include "mitab.h"
     156                 : #include "mitab_utils.h"
     157                 : #include <ctype.h>
     158                 : 
     159                 : /*=====================================================================
     160                 :  *                      class TABFeature
     161                 :  *====================================================================*/
     162                 : 
     163                 : /************************************************************************/
     164                 : /*                            MIDTokenize()                             */
     165                 : /*                                                                      */
     166                 : /*      We implement a special tokenize function so we can handle       */
     167                 : /*      multibyte delimeters (ie. MITAB bug 1266).                      */
     168                 : /*                                                                      */
     169                 : /*      http://bugzilla.maptools.org/show_bug.cgi?id=1266               */
     170                 : /************************************************************************/
     171              44 : static char **MIDTokenize( const char *pszLine, const char *pszDelim )
     172                 : 
     173                 : {
     174              44 :     char **papszResult = NULL;
     175              44 :     int iChar, iTokenChar = 0, bInQuotes = FALSE;
     176              44 :     char *pszToken = (char *) CPLMalloc(strlen(pszLine)+1);
     177              44 :     int nDelimLen = strlen(pszDelim);
     178                 : 
     179            1174 :     for( iChar = 0; pszLine[iChar] != '\0'; iChar++ )
     180                 :     {
     181            1138 :         if( bInQuotes && pszLine[iChar] == '"' && pszLine[iChar+1] == '"' )
     182                 :         {
     183               8 :             pszToken[iTokenChar++] = '"';
     184               8 :             iChar++;
     185                 :         }
     186            1122 :         else if( pszLine[iChar] == '"' )
     187                 :         {
     188             104 :             bInQuotes = !bInQuotes;
     189                 :         }
     190            1110 :         else if( !bInQuotes && strncmp(pszLine+iChar,pszDelim,nDelimLen) == 0 )
     191                 :         {
     192              92 :             pszToken[iTokenChar++] = '\0';
     193              92 :             papszResult = CSLAddString( papszResult, pszToken );
     194                 :             
     195              92 :             iChar += strlen(pszDelim) - 1;
     196              92 :             iTokenChar = 0;
     197                 :         }
     198                 :         else
     199                 :         {
     200             926 :             pszToken[iTokenChar++] = pszLine[iChar];
     201                 :         }
     202                 :     }
     203                 : 
     204              44 :     pszToken[iTokenChar++] = '\0';
     205              44 :     papszResult = CSLAddString( papszResult, pszToken );
     206                 : 
     207              44 :     CPLFree( pszToken );
     208                 : 
     209              44 :     return papszResult;
     210                 : }
     211                 : 
     212                 : /**********************************************************************
     213                 :  *                   TABFeature::ReadRecordFromMIDFile()
     214                 :  *
     215                 :  *  This method is used to read the Record (Attributs) for all type of
     216                 :  *  feature included in a mid/mif file.
     217                 :  * 
     218                 :  * Returns 0 on success, -1 on error, in which case CPLError() will have
     219                 :  * been called.
     220                 :  **********************************************************************/
     221              44 : int TABFeature::ReadRecordFromMIDFile(MIDDATAFile *fp)
     222                 : {
     223                 :     const char       *pszLine;
     224                 :     char            **papszToken;
     225                 :     int               nFields,i;
     226                 : 
     227              44 :     nFields = GetFieldCount();
     228                 :     
     229              44 :     pszLine = fp->GetLastLine();
     230                 : 
     231              44 :     if (pszLine == NULL)
     232                 :     {
     233                 :         CPLError(CE_Failure, CPLE_FileIO,
     234               0 :                "Unexpected EOF while reading attribute record from MID file.");
     235               0 :         return -1;
     236                 :     }
     237                 : 
     238              44 :     papszToken = MIDTokenize( pszLine, fp->GetDelimiter() );
     239                 : 
     240                 :     // Ensure that a blank line in a mid file is treated as one field 
     241                 :     // containing an empty string.
     242              44 :     if( nFields == 1 && CSLCount(papszToken) == 0 && pszLine[0] == '\0' )
     243               0 :         papszToken = CSLAddString(papszToken,"");
     244                 : 
     245                 :     // Make sure we found at least the expected number of field values.
     246                 :     // Note that it is possible to have a stray delimiter at the end of
     247                 :     // the line (mif/mid files from Geomedia), so don't produce an error
     248                 :     // if we find more tokens than expected.
     249              44 :     if (CSLCount(papszToken) < nFields)
     250                 :     {
     251               0 :         CSLDestroy(papszToken);
     252               0 :         return -1;
     253                 :     }
     254                 : 
     255             180 :     for (i=0;i<nFields;i++)
     256                 :     {
     257             136 :         SetField(i,papszToken[i]);
     258                 :     }
     259                 :     
     260              44 :     fp->GetLine();
     261                 : 
     262              44 :     CSLDestroy(papszToken);
     263                 : 
     264              44 :     return 0;
     265                 : }
     266                 : 
     267                 : /**********************************************************************
     268                 :  *                   TABFeature::WriteRecordToMIDFile()
     269                 :  *
     270                 :  *  This methode is used to write the Record (Attributs) for all type
     271                 :  *  of feature included in a mid file.
     272                 :  *
     273                 :  *  Return 0 on success, -1 on error
     274                 :  **********************************************************************/
     275              20 : int TABFeature::WriteRecordToMIDFile(MIDDATAFile *fp)
     276                 : {
     277                 :     int                  iField, numFields;
     278              20 :     OGRFieldDefn        *poFDefn = NULL;
     279                 : 
     280              20 :     CPLAssert(fp);
     281                 :     
     282              20 :     const char *delimiter = fp->GetDelimiter();
     283                 : 
     284              20 :     numFields = GetFieldCount();
     285                 : 
     286              64 :     for(iField=0; iField<numFields; iField++)
     287                 :     {
     288              44 :         if (iField != 0)
     289              24 :           fp->WriteLine(delimiter);
     290              44 :         poFDefn = GetFieldDefnRef( iField );
     291                 : 
     292              44 :         switch(poFDefn->GetType())
     293                 :         {
     294                 :           case OFTString: 
     295                 :           {
     296              18 :             int nStringLen = strlen(GetFieldAsString(iField));
     297              18 :             char *pszString = (char*)CPLMalloc((nStringLen+1)*sizeof(char));
     298              18 :             strcpy(pszString, GetFieldAsString(iField));
     299              18 :             char *pszWorkString = (char*)CPLMalloc((2*(nStringLen)+1)*sizeof(char));
     300              18 :             int j = 0;
     301             142 :             for (int i =0; i < nStringLen; ++i)
     302                 :             { 
     303             124 :               if (pszString[i] == '"')
     304                 :               {
     305               0 :                 pszWorkString[j] = pszString[i];
     306               0 :                 ++j;
     307               0 :                 pszWorkString[j] = pszString[i];
     308                 :               }
     309             124 :               else if (pszString[i] == '\n')
     310                 :               {
     311               0 :                 pszWorkString[j] = '\\';
     312               0 :                 ++j;
     313               0 :                 pszWorkString[j] = 'n';
     314                 :               }
     315                 :               else
     316             124 :                 pszWorkString[j] = pszString[i];
     317             124 :               ++j;
     318                 :             }
     319                 :             
     320              18 :             pszWorkString[j] = '\0';
     321              18 :             CPLFree(pszString);
     322              18 :             pszString = (char*)CPLMalloc((strlen(pszWorkString)+1)*sizeof(char));
     323              18 :             strcpy(pszString, pszWorkString);
     324              18 :             CPLFree(pszWorkString);
     325              18 :             fp->WriteLine("\"%s\"",pszString);
     326              18 :             CPLFree(pszString);
     327              18 :             break;
     328                 :           }
     329                 :           default:
     330              26 :             fp->WriteLine("%s",GetFieldAsString(iField));
     331                 :         }
     332                 :     }
     333                 : 
     334              20 :     fp->WriteLine("\n");
     335                 : 
     336              20 :     return 0;
     337                 : }
     338                 : 
     339                 : /**********************************************************************
     340                 :  *                   TABFeature::ReadGeometryFromMIFFile()
     341                 :  *
     342                 :  * In derived classes, this method should be reimplemented to
     343                 :  * fill the geometry and representation (color, etc...) part of the
     344                 :  * feature from the contents of the .MAP object pointed to by poMAPFile.
     345                 :  *
     346                 :  * It is assumed that before calling ReadGeometryFromMAPFile(), poMAPFile
     347                 :  * currently points to the beginning of a map object.
     348                 :  *
     349                 :  * The current implementation does nothing since instances of TABFeature
     350                 :  * objects contain no geometry (i.e. TAB_GEOM_NONE).
     351                 :  * 
     352                 :  * Returns 0 on success, -1 on error, in which case CPLError() will have
     353                 :  * been called.
     354                 :  **********************************************************************/
     355              12 : int TABFeature::ReadGeometryFromMIFFile(MIDDATAFile *fp)
     356                 : {
     357                 :     const char *pszLine;
     358                 :     
     359                 :     /* Go to the first line of the next feature */
     360                 : 
     361              12 :     while (((pszLine = fp->GetLine()) != NULL) && 
     362                 :            fp->IsValidFeature(pszLine) == FALSE)
     363                 :       ;
     364                 : 
     365              12 :     return 0;
     366                 : }
     367                 : 
     368                 : /**********************************************************************
     369                 :  *                   TABFeature::WriteGeometryToMIFFile()
     370                 :  *
     371                 :  *
     372                 :  * In derived classes, this method should be reimplemented to
     373                 :  * write the geometry and representation (color, etc...) part of the
     374                 :  * feature to the .MAP object pointed to by poMAPFile.
     375                 :  *
     376                 :  * It is assumed that before calling WriteGeometryToMAPFile(), poMAPFile
     377                 :  * currently points to a valid map object.
     378                 :  *
     379                 :  * The current implementation does nothing since instances of TABFeature
     380                 :  * objects contain no geometry.
     381                 :  * 
     382                 :  * Returns 0 on success, -1 on error, in which case CPLError() will have
     383                 :  * been called.
     384                 :  **********************************************************************/
     385               6 : int TABFeature::WriteGeometryToMIFFile(MIDDATAFile *fp)
     386                 : {
     387               6 :     fp->WriteLine("NONE\n");
     388               6 :     return 0;
     389                 : }
     390                 : 
     391                 : /**********************************************************************
     392                 :  *
     393                 :  **********************************************************************/
     394               4 : int TABPoint::ReadGeometryFromMIFFile(MIDDATAFile *fp)
     395                 : {  
     396                 :     OGRGeometry         *poGeometry;
     397                 :     
     398                 :     char               **papszToken;
     399                 :     const char *pszLine;
     400                 :     double dfX,dfY;
     401                 :     papszToken = CSLTokenizeString2(fp->GetSavedLine(), 
     402               4 :                                     " \t", CSLT_HONOURSTRINGS);
     403                 :      
     404               4 :     if (CSLCount(papszToken) !=3)
     405                 :     {
     406               0 :         CSLDestroy(papszToken);
     407               0 :         return -1;
     408                 :     }
     409                 :     
     410               4 :     dfX = fp->GetXTrans(atof(papszToken[1]));
     411               4 :     dfY = fp->GetYTrans(atof(papszToken[2]));
     412                 : 
     413               4 :     CSLDestroy(papszToken);
     414               4 :     papszToken = NULL;
     415                 : 
     416                 :     // Read optional SYMBOL line...
     417               4 :     pszLine = fp->GetLastLine();
     418               4 :     if( pszLine != NULL )
     419                 :         papszToken = CSLTokenizeStringComplex(pszLine," ,()\t",
     420               4 :                                               TRUE,FALSE);
     421               4 :     if (CSLCount(papszToken) == 4 && EQUAL(papszToken[0], "SYMBOL") )
     422                 :     {
     423               4 :         SetSymbolNo(atoi(papszToken[1]));
     424               4 :         SetSymbolColor(atoi(papszToken[2]));
     425               4 :         SetSymbolSize(atoi(papszToken[3]));
     426                 :     }
     427                 : 
     428               4 :     CSLDestroy(papszToken); 
     429               4 :     papszToken = NULL;
     430                 : 
     431                 :     // scan until we reach 1st line of next feature
     432                 :     // Since SYMBOL is optional, we have to test IsValidFeature() on that
     433                 :     // line as well.
     434              12 :     while (pszLine && fp->IsValidFeature(pszLine) == FALSE)
     435                 :     {
     436               4 :         pszLine = fp->GetLine();
     437                 :     }
     438                 :     
     439               4 :     poGeometry = new OGRPoint(dfX, dfY);
     440                 :     
     441               4 :     SetGeometryDirectly(poGeometry);
     442                 : 
     443               4 :     SetMBR(dfX, dfY, dfX, dfY);
     444                 :     
     445                 : 
     446               4 :     return 0; 
     447                 : }
     448                 : 
     449                 : /**********************************************************************
     450                 :  *
     451                 :  **********************************************************************/
     452               4 : int TABPoint::WriteGeometryToMIFFile(MIDDATAFile *fp)
     453                 : { 
     454                 :     OGRGeometry         *poGeom;
     455                 :     OGRPoint            *poPoint;
     456                 :  
     457                 :     /*-----------------------------------------------------------------
     458                 :      * Fetch and validate geometry
     459                 :      *----------------------------------------------------------------*/
     460               4 :     poGeom = GetGeometryRef();
     461               4 :     if (poGeom && wkbFlatten(poGeom->getGeometryType()) == wkbPoint)
     462               4 :         poPoint = (OGRPoint*)poGeom;
     463                 :     else
     464                 :     {
     465                 :         CPLError(CE_Failure, CPLE_AssertionFailed,
     466               0 :                  "TABPoint: Missing or Invalid Geometry!");
     467               0 :         return -1;
     468                 :     }
     469                 : 
     470               4 :     fp->WriteLine("Point %.15g %.15g\n",poPoint->getX(),poPoint->getY());
     471                 :     fp->WriteLine("    Symbol (%d,%d,%d)\n",GetSymbolNo(),GetSymbolColor(),
     472               4 :                   GetSymbolSize());
     473                 : 
     474               4 :     return 0; 
     475                 : }
     476                 : 
     477                 : /**********************************************************************
     478                 :  *
     479                 :  **********************************************************************/
     480               0 : int TABFontPoint::ReadGeometryFromMIFFile(MIDDATAFile *fp)
     481                 : {   
     482                 :     OGRGeometry         *poGeometry;
     483                 :     
     484                 :     char               **papszToken;
     485                 :     const char *pszLine;
     486                 :     double dfX,dfY;
     487                 :     papszToken = CSLTokenizeString2(fp->GetSavedLine(), 
     488               0 :                                     " \t", CSLT_HONOURSTRINGS);
     489                 : 
     490               0 :     if (CSLCount(papszToken) !=3)
     491                 :     {
     492               0 :         CSLDestroy(papszToken);
     493               0 :         return -1;
     494                 :     }
     495                 : 
     496               0 :     dfX = fp->GetXTrans(atof(papszToken[1]));
     497               0 :     dfY = fp->GetYTrans(atof(papszToken[2]));
     498                 :     
     499               0 :     CSLDestroy(papszToken);
     500                 :     
     501                 :     papszToken = CSLTokenizeStringComplex(fp->GetLastLine()," ,()\t",
     502               0 :                                           TRUE,FALSE);
     503                 : 
     504               0 :     if (CSLCount(papszToken) !=7)
     505                 :     {
     506               0 :         CSLDestroy(papszToken);
     507               0 :         return -1;
     508                 :     }
     509                 :     
     510               0 :     SetSymbolNo(atoi(papszToken[1]));
     511               0 :     SetSymbolColor(atoi(papszToken[2]));
     512               0 :     SetSymbolSize(atoi(papszToken[3]));
     513               0 :     SetFontName(papszToken[4]);
     514               0 :     SetFontStyleMIFValue(atoi(papszToken[5]));
     515               0 :     SetSymbolAngle(atof(papszToken[6]));
     516                 : 
     517               0 :     CSLDestroy(papszToken);
     518                 :     
     519               0 :     poGeometry = new OGRPoint(dfX, dfY);
     520                 :     
     521               0 :     SetGeometryDirectly(poGeometry);
     522                 : 
     523               0 :     SetMBR(dfX, dfY, dfX, dfY);
     524                 : 
     525                 :     /* Go to the first line of the next feature */
     526                 : 
     527               0 :     while (((pszLine = fp->GetLine()) != NULL) && 
     528                 :            fp->IsValidFeature(pszLine) == FALSE)
     529                 :       ;
     530               0 :     return 0; 
     531                 : }
     532                 : 
     533                 : /**********************************************************************
     534                 :  *
     535                 :  **********************************************************************/
     536               0 : int TABFontPoint::WriteGeometryToMIFFile(MIDDATAFile *fp)
     537                 : { 
     538                 :     OGRGeometry         *poGeom;
     539                 :     OGRPoint            *poPoint;
     540                 :  
     541                 :     /*-----------------------------------------------------------------
     542                 :      * Fetch and validate geometry
     543                 :      *----------------------------------------------------------------*/
     544               0 :     poGeom = GetGeometryRef();
     545               0 :     if (poGeom && wkbFlatten(poGeom->getGeometryType()) == wkbPoint)
     546               0 :         poPoint = (OGRPoint*)poGeom;
     547                 :     else
     548                 :     {
     549                 :         CPLError(CE_Failure, CPLE_AssertionFailed,
     550               0 :                  "TABFontPoint: Missing or Invalid Geometry!");
     551               0 :         return -1;
     552                 :     }
     553                 : 
     554               0 :     fp->WriteLine("Point %.15g %.15g\n",poPoint->getX(),poPoint->getY());
     555                 :     fp->WriteLine("    Symbol (%d,%d,%d,\"%s\",%d,%.15g)\n",
     556                 :                   GetSymbolNo(),GetSymbolColor(),
     557                 :                   GetSymbolSize(),GetFontNameRef(),GetFontStyleMIFValue(),
     558               0 :                   GetSymbolAngle());
     559                 : 
     560               0 :     return 0; 
     561                 : }
     562                 : 
     563                 : /**********************************************************************
     564                 :  *
     565                 :  **********************************************************************/
     566               0 : int TABCustomPoint::ReadGeometryFromMIFFile(MIDDATAFile *fp)
     567                 : {   
     568                 :     OGRGeometry         *poGeometry;
     569                 :     
     570                 :     char               **papszToken;
     571                 :     const char          *pszLine;
     572                 :     double               dfX,dfY;
     573                 : 
     574                 :     papszToken = CSLTokenizeString2(fp->GetSavedLine(), 
     575               0 :                                     " \t", CSLT_HONOURSTRINGS);
     576                 : 
     577                 :     
     578               0 :     if (CSLCount(papszToken) !=3)
     579                 :     {
     580               0 :         CSLDestroy(papszToken);
     581               0 :         return -1;
     582                 :     }
     583                 : 
     584               0 :     dfX = fp->GetXTrans(atof(papszToken[1]));
     585               0 :     dfY = fp->GetYTrans(atof(papszToken[2]));
     586                 : 
     587               0 :     CSLDestroy(papszToken);
     588                 :     
     589                 :     papszToken = CSLTokenizeStringComplex(fp->GetLastLine()," ,()\t",
     590               0 :                                           TRUE,FALSE);
     591               0 :     if (CSLCount(papszToken) !=5)
     592                 :     {
     593                 :         
     594               0 :         CSLDestroy(papszToken);
     595               0 :         return -1;
     596                 :     }
     597                 :     
     598               0 :     SetFontName(papszToken[1]);
     599               0 :     SetSymbolColor(atoi(papszToken[2]));
     600               0 :     SetSymbolSize(atoi(papszToken[3]));
     601               0 :     m_nCustomStyle = atoi(papszToken[4]);
     602                 :     
     603               0 :     CSLDestroy(papszToken);
     604                 :     
     605               0 :     poGeometry = new OGRPoint(dfX, dfY);
     606                 :     
     607               0 :     SetGeometryDirectly(poGeometry);
     608                 : 
     609               0 :     SetMBR(dfX, dfY, dfX, dfY);
     610                 : 
     611                 :     /* Go to the first line of the next feature */
     612                 : 
     613               0 :     while (((pszLine = fp->GetLine()) != NULL) && 
     614                 :            fp->IsValidFeature(pszLine) == FALSE)
     615                 :       ;
     616                 :  
     617               0 :     return 0; 
     618                 : 
     619                 : }
     620                 : 
     621                 : /**********************************************************************
     622                 :  *
     623                 :  **********************************************************************/
     624               0 : int TABCustomPoint::WriteGeometryToMIFFile(MIDDATAFile *fp)
     625                 : { 
     626                 :     OGRGeometry         *poGeom;
     627                 :     OGRPoint            *poPoint;
     628                 :  
     629                 :     /*-----------------------------------------------------------------
     630                 :      * Fetch and validate geometry
     631                 :      *----------------------------------------------------------------*/
     632               0 :     poGeom = GetGeometryRef();
     633               0 :     if (poGeom && wkbFlatten(poGeom->getGeometryType()) == wkbPoint)
     634               0 :         poPoint = (OGRPoint*)poGeom;
     635                 :     else
     636                 :     {
     637                 :         CPLError(CE_Failure, CPLE_AssertionFailed,
     638               0 :                  "TABCustomPoint: Missing or Invalid Geometry!");
     639               0 :         return -1;
     640                 :     }
     641                 :  
     642                 : 
     643               0 :     fp->WriteLine("Point %.15g %.15g\n",poPoint->getX(),poPoint->getY());
     644                 :     fp->WriteLine("    Symbol (\"%s\",%d,%d,%d)\n",GetFontNameRef(),
     645               0 :                   GetSymbolColor(), GetSymbolSize(),m_nCustomStyle);
     646                 : 
     647               0 :     return 0; 
     648                 : }
     649                 : 
     650                 : /**********************************************************************
     651                 :  *
     652                 :  **********************************************************************/
     653               0 : int TABPolyline::ReadGeometryFromMIFFile(MIDDATAFile *fp)
     654                 : {
     655                 :     const char          *pszLine;
     656                 :     char               **papszToken;
     657                 :     OGRLineString       *poLine;
     658                 :     OGRMultiLineString  *poMultiLine;
     659               0 :     GBool                bMultiple = FALSE;
     660               0 :     int                  nNumPoints,nNumSec=0,i,j;
     661               0 :     OGREnvelope          sEnvelope;
     662                 :     
     663                 : 
     664                 :     papszToken = CSLTokenizeString2(fp->GetLastLine(), 
     665               0 :                                     " \t", CSLT_HONOURSTRINGS);
     666                 :     
     667               0 :     if (CSLCount(papszToken) < 1)
     668                 :     {
     669               0 :         CSLDestroy(papszToken);
     670               0 :         return -1;
     671                 :     }
     672                 : 
     673               0 :     if (EQUALN(papszToken[0],"LINE",4))
     674                 :     {
     675               0 :         if (CSLCount(papszToken) != 5)
     676               0 :           return -1;
     677                 : 
     678               0 :         poLine = new OGRLineString();
     679               0 :         poLine->setNumPoints(2);
     680                 :         poLine->setPoint(0, fp->GetXTrans(atof(papszToken[1])),
     681               0 :                          fp->GetYTrans(atof(papszToken[2])));
     682                 :         poLine->setPoint(1, fp->GetXTrans(atof(papszToken[3])),
     683               0 :                          fp->GetYTrans(atof(papszToken[4])));
     684               0 :         SetGeometryDirectly(poLine);
     685               0 :         poLine->getEnvelope(&sEnvelope);
     686               0 :         SetMBR(sEnvelope.MinX, sEnvelope.MinY,sEnvelope.MaxX,sEnvelope.MaxY);
     687                 :     }
     688               0 :     else if (EQUALN(papszToken[0],"PLINE",5))
     689                 :     {
     690               0 :         switch (CSLCount(papszToken))
     691                 :         {
     692                 :           case 1:
     693               0 :             bMultiple = FALSE;
     694               0 :             pszLine = fp->GetLine();
     695               0 :             nNumPoints = atoi(pszLine);
     696               0 :             break;
     697                 :           case 2:
     698               0 :             bMultiple = FALSE;
     699               0 :             nNumPoints = atoi(papszToken[1]);
     700               0 :             break;
     701                 :           case 3:
     702               0 :             if (EQUALN(papszToken[1],"MULTIPLE",8))
     703                 :             {
     704               0 :                 bMultiple = TRUE;
     705               0 :                 nNumSec = atoi(papszToken[2]);
     706               0 :                 pszLine = fp->GetLine();
     707               0 :                 nNumPoints = atoi(pszLine);
     708               0 :                 break;
     709                 :             }
     710                 :             else
     711                 :             {
     712               0 :               CSLDestroy(papszToken);
     713               0 :               return -1;
     714                 :             }
     715                 :             break;
     716                 :           case 4:
     717               0 :             if (EQUALN(papszToken[1],"MULTIPLE",8))
     718                 :             {
     719               0 :                 bMultiple = TRUE;
     720               0 :                 nNumSec = atoi(papszToken[2]);
     721               0 :                 nNumPoints = atoi(papszToken[3]);
     722               0 :                 break;
     723                 :             }
     724                 :             else
     725                 :             {
     726               0 :                 CSLDestroy(papszToken);
     727               0 :                 return -1;
     728                 :             }
     729                 :             break;
     730                 :           default:
     731               0 :             CSLDestroy(papszToken);
     732               0 :             return -1;
     733                 :             break;
     734                 :         }
     735                 : 
     736               0 :         if (bMultiple)
     737                 :         {
     738               0 :             poMultiLine = new OGRMultiLineString();
     739               0 :             for (j=0;j<nNumSec;j++)
     740                 :             {
     741               0 :                 poLine = new OGRLineString();
     742               0 :                 if (j != 0)
     743               0 :                     nNumPoints = atoi(fp->GetLine());
     744               0 :                 if (nNumPoints < 2)
     745                 :                 {
     746                 :                     CPLError(CE_Failure, CPLE_FileIO,
     747                 :                              "Invalid number of vertices (%d) in PLINE "
     748               0 :                              "MULTIPLE segment.", nNumPoints);
     749               0 :                     return -1;
     750                 :                 }
     751               0 :                 poLine->setNumPoints(nNumPoints);
     752               0 :                 for (i=0;i<nNumPoints;i++)
     753                 :                 {
     754               0 :                     CSLDestroy(papszToken);
     755                 :                     papszToken = CSLTokenizeString2(fp->GetLine(), 
     756               0 :                                                     " \t", CSLT_HONOURSTRINGS);
     757                 :                     poLine->setPoint(i,fp->GetXTrans(atof(papszToken[0])),
     758               0 :                                      fp->GetYTrans(atof(papszToken[1])));
     759                 :                 }
     760               0 :                 if (poMultiLine->addGeometryDirectly(poLine) != OGRERR_NONE)
     761                 :                 {
     762               0 :                     CPLAssert(FALSE); // Just in case OGR is modified
     763                 :                 }
     764                 :             }
     765               0 :             if (SetGeometryDirectly(poMultiLine) != OGRERR_NONE)
     766                 :             {
     767               0 :                 CPLAssert(FALSE); // Just in case OGR is modified
     768                 :             }
     769               0 :             poMultiLine->getEnvelope(&sEnvelope);
     770                 :             SetMBR(sEnvelope.MinX, sEnvelope.MinY,
     771               0 :                    sEnvelope.MaxX,sEnvelope.MaxY);
     772                 :         }
     773                 :         else
     774                 :         {
     775               0 :             poLine = new OGRLineString();
     776               0 :             poLine->setNumPoints(nNumPoints);
     777               0 :             for (i=0;i<nNumPoints;i++)
     778                 :             {
     779               0 :                 CSLDestroy(papszToken);
     780                 :                 papszToken = CSLTokenizeString2(fp->GetLine(), 
     781               0 :                                                 " \t", CSLT_HONOURSTRINGS);
     782                 :     
     783               0 :                 if (CSLCount(papszToken) != 2)
     784               0 :                   return -1;
     785                 :                 poLine->setPoint(i,fp->GetXTrans(atof(papszToken[0])),
     786               0 :                                  fp->GetYTrans(atof(papszToken[1])));
     787                 :             }
     788               0 :             SetGeometryDirectly(poLine);
     789               0 :             poLine->getEnvelope(&sEnvelope);
     790                 :             SetMBR(sEnvelope.MinX, sEnvelope.MinY,
     791               0 :                    sEnvelope.MaxX,sEnvelope.MaxY);
     792                 :         }
     793                 :     }    
     794                 :     
     795               0 :     CSLDestroy(papszToken);
     796               0 :     papszToken = NULL;
     797                 :     
     798               0 :     while (((pszLine = fp->GetLine()) != NULL) && 
     799                 :            fp->IsValidFeature(pszLine) == FALSE)
     800                 :     {
     801                 :         papszToken = CSLTokenizeStringComplex(pszLine,"() ,",
     802               0 :                                               TRUE,FALSE);
     803                 :         
     804               0 :         if (CSLCount(papszToken) >= 1)
     805                 :         {
     806               0 :             if (EQUALN(papszToken[0],"PEN",3))
     807                 :             {
     808                 :                 
     809               0 :                 if (CSLCount(papszToken) == 4)
     810                 :                 {                   
     811               0 :                     SetPenWidthMIF(atoi(papszToken[1]));
     812               0 :                     SetPenPattern(atoi(papszToken[2]));
     813               0 :                     SetPenColor(atoi(papszToken[3]));
     814                 :                 }
     815                 :                 
     816                 :             }
     817               0 :             else if (EQUALN(papszToken[0],"SMOOTH",6))
     818                 :             {
     819               0 :                 m_bSmooth = TRUE;
     820                 :             }             
     821                 :         }
     822               0 :         CSLDestroy(papszToken);
     823                 :     }
     824               0 :     return 0; 
     825                 : }
     826                 : 
     827                 : /**********************************************************************
     828                 :  *
     829                 :  **********************************************************************/
     830               0 : int TABPolyline::WriteGeometryToMIFFile(MIDDATAFile *fp)
     831                 : { 
     832                 :     OGRGeometry   *poGeom;
     833               0 :     OGRMultiLineString *poMultiLine = NULL;
     834               0 :     OGRLineString *poLine = NULL;
     835                 :     int nNumPoints,i;
     836                 : 
     837                 :   
     838                 :     /*-----------------------------------------------------------------
     839                 :      * Fetch and validate geometry
     840                 :      *----------------------------------------------------------------*/
     841               0 :     poGeom = GetGeometryRef();
     842               0 :     if (poGeom && wkbFlatten(poGeom->getGeometryType()) == wkbLineString)
     843                 :     {
     844                 :         /*-------------------------------------------------------------
     845                 :          * Simple polyline
     846                 :          *------------------------------------------------------------*/
     847               0 :         poLine = (OGRLineString*)poGeom;
     848               0 :         nNumPoints = poLine->getNumPoints();
     849               0 :         if (nNumPoints == 2)
     850                 :         {
     851                 :             fp->WriteLine("Line %.15g %.15g %.15g %.15g\n",poLine->getX(0),poLine->getY(0),
     852               0 :                           poLine->getX(1),poLine->getY(1));
     853                 :         }
     854                 :         else
     855                 :         {
     856                 :             
     857               0 :             fp->WriteLine("Pline %d\n",nNumPoints);
     858               0 :             for (i=0;i<nNumPoints;i++)
     859                 :             {
     860               0 :                 fp->WriteLine("%.15g %.15g\n",poLine->getX(i),poLine->getY(i));
     861                 :             }
     862                 :         }
     863                 :     }
     864               0 :     else if (poGeom && wkbFlatten(poGeom->getGeometryType()) == wkbMultiLineString)
     865                 :     {
     866                 :         /*-------------------------------------------------------------
     867                 :          * Multiple polyline... validate all components
     868                 :          *------------------------------------------------------------*/
     869                 :         int iLine, numLines;
     870               0 :         poMultiLine = (OGRMultiLineString*)poGeom;
     871               0 :         numLines = poMultiLine->getNumGeometries();
     872                 : 
     873               0 :         fp->WriteLine("PLINE MULTIPLE %d\n", numLines);
     874                 : 
     875               0 :         for(iLine=0; iLine < numLines; iLine++)
     876                 :         {
     877               0 :             poGeom = poMultiLine->getGeometryRef(iLine);
     878               0 :             if (poGeom && wkbFlatten(poGeom->getGeometryType()) == wkbLineString)
     879                 :             { 
     880               0 :                 poLine = (OGRLineString*)poGeom;
     881               0 :                 nNumPoints = poLine->getNumPoints();
     882                 :         
     883               0 :                 fp->WriteLine("  %d\n",nNumPoints);
     884               0 :                 for (i=0;i<nNumPoints;i++)
     885                 :                 {
     886               0 :                     fp->WriteLine("%.15g %.15g\n",poLine->getX(i),poLine->getY(i));
     887                 :                 }
     888                 :             }
     889                 :             else
     890                 :             {
     891                 :                 CPLError(CE_Failure, CPLE_AssertionFailed,
     892               0 :                          "TABPolyline: Object contains an invalid Geometry!");
     893                 :             }
     894                 :         }
     895                 :     }
     896                 :     else
     897                 :     {
     898                 :         CPLError(CE_Failure, CPLE_AssertionFailed,
     899               0 :                  "TABPolyline: Missing or Invalid Geometry!");
     900                 :     }
     901                 :     
     902               0 :     if (GetPenPattern())
     903                 :       fp->WriteLine("    Pen (%d,%d,%d)\n",GetPenWidthMIF(),GetPenPattern(),
     904               0 :                     GetPenColor());
     905               0 :     if (m_bSmooth)
     906               0 :       fp->WriteLine("    Smooth\n");
     907                 : 
     908               0 :     return 0; 
     909                 : 
     910                 : }
     911                 : 
     912                 : /**********************************************************************
     913                 :  *                   TABRegion::ReadGeometryFromMIFFile()
     914                 :  *
     915                 :  * Fill the geometry and representation (color, etc...) part of the
     916                 :  * feature from the contents of the .MIF file
     917                 :  *
     918                 :  * Returns 0 on success, -1 on error, in which case CPLError() will have
     919                 :  * been called.
     920                 :  **********************************************************************/
     921              28 : int TABRegion::ReadGeometryFromMIFFile(MIDDATAFile *fp)
     922                 : {
     923                 :     double               dX, dY;
     924                 :     OGRLinearRing       *poRing;
     925              28 :     OGRGeometry         *poGeometry = NULL;
     926              28 :     OGRPolygon          *poPolygon = NULL;
     927              28 :     OGRMultiPolygon     *poMultiPolygon = NULL;
     928              28 :     int                  i,iSection, numLineSections=0;
     929                 :     char               **papszToken;
     930                 :     const char          *pszLine;
     931              28 :     OGREnvelope          sEnvelope;
     932                 : 
     933              28 :     m_bSmooth = FALSE;
     934                 :     /*=============================================================
     935                 :      * REGION (Similar to PLINE MULTIPLE)
     936                 :      *============================================================*/
     937                 :     papszToken = CSLTokenizeString2(fp->GetLastLine(), 
     938              28 :                                     " \t", CSLT_HONOURSTRINGS);
     939                 :     
     940              28 :     if (CSLCount(papszToken) ==2)
     941              28 :       numLineSections = atoi(papszToken[1]);
     942              28 :     CSLDestroy(papszToken);
     943              28 :     papszToken = NULL;
     944                 : 
     945                 :     /*-------------------------------------------------------------
     946                 :      * For 1-ring regions, we return an OGRPolygon with one single
     947                 :      * OGRLinearRing geometry. 
     948                 :      *
     949                 :      * REGIONs with multiple rings are returned as OGRMultiPolygon
     950                 :      * instead of as OGRPolygons since OGRPolygons require that the
     951                 :      * first ring be the outer ring, and the other all be inner 
     952                 :      * rings, but this is not guaranteed inside MapInfo files.  
     953                 :      *------------------------------------------------------------*/
     954              28 :     if (numLineSections > 1)
     955               0 :         poGeometry = poMultiPolygon = new OGRMultiPolygon;
     956                 :     else
     957              28 :         poGeometry = NULL;  // Will be set later
     958                 : 
     959              56 :     for(iSection=0; iSection<numLineSections; iSection++)
     960                 :     {
     961              28 :         int     numSectionVertices = 0;
     962                 : 
     963              28 :         poPolygon = new OGRPolygon();
     964                 : 
     965              28 :         if ((pszLine = fp->GetLine()) != NULL)
     966                 :         {
     967              28 :             numSectionVertices = atoi(pszLine);
     968                 :         }
     969                 : 
     970              28 :         poRing = new OGRLinearRing();
     971              28 :         poRing->setNumPoints(numSectionVertices);
     972                 : 
     973                 : 
     974             566 :         for(i=0; i<numSectionVertices; i++)
     975                 :         {
     976             538 :             pszLine = fp->GetLine();
     977             538 :             if (pszLine)
     978                 :             {
     979                 :                 papszToken = CSLTokenizeStringComplex(pszLine," ,\t",
     980             538 :                                                       TRUE,FALSE);
     981             538 :                 if (CSLCount(papszToken) == 2)
     982                 :                 {              
     983             538 :                     dX = fp->GetXTrans(atof(papszToken[0]));
     984             538 :                     dY = fp->GetYTrans(atof(papszToken[1]));
     985             538 :                     poRing->setPoint(i, dX, dY);
     986                 :                 }
     987             538 :                 CSLDestroy(papszToken);
     988             538 :                 papszToken = NULL;
     989                 :             }   
     990                 :         }
     991              28 :         poPolygon->addRingDirectly(poRing);
     992              28 :         poRing = NULL;
     993                 : 
     994              28 :         if (numLineSections > 1)
     995               0 :             poMultiPolygon->addGeometryDirectly(poPolygon);
     996                 :         else
     997              28 :             poGeometry = poPolygon;
     998                 : 
     999              28 :         poPolygon = NULL;
    1000                 :     }
    1001                 :   
    1002                 :   
    1003              28 :     SetGeometryDirectly(poGeometry);
    1004              28 :     poGeometry->getEnvelope(&sEnvelope);
    1005                 :     
    1006              28 :     SetMBR(sEnvelope.MinX, sEnvelope.MinY, sEnvelope.MaxX, sEnvelope.MaxY);
    1007                 : 
    1008             112 :     while (((pszLine = fp->GetLine()) != NULL) && 
    1009                 :            fp->IsValidFeature(pszLine) == FALSE)
    1010                 :     {
    1011                 :         papszToken = CSLTokenizeStringComplex(pszLine,"() ,",
    1012              56 :                                               TRUE,FALSE);
    1013                 :         
    1014              56 :         if (CSLCount(papszToken) > 1)
    1015                 :         {
    1016              56 :             if (EQUALN(papszToken[0],"PEN",3))
    1017                 :             {
    1018                 :                 
    1019              28 :                 if (CSLCount(papszToken) == 4)
    1020                 :                 {           
    1021              28 :                     SetPenWidthMIF(atoi(papszToken[1]));
    1022              28 :                     SetPenPattern(atoi(papszToken[2]));
    1023              28 :                     SetPenColor(atoi(papszToken[3]));
    1024                 :                 }
    1025                 :                 
    1026                 :             }
    1027              28 :             else if (EQUALN(papszToken[0],"BRUSH", 5))
    1028                 :             {
    1029              28 :                 if (CSLCount(papszToken) >= 3)
    1030                 :                 {
    1031              28 :                     SetBrushFGColor(atoi(papszToken[2]));
    1032              28 :                     SetBrushPattern(atoi(papszToken[1]));
    1033                 :                     
    1034              28 :                     if (CSLCount(papszToken) == 4)
    1035              28 :                        SetBrushBGColor(atoi(papszToken[3]));
    1036                 :                     else
    1037               0 :                       SetBrushTransparent(TRUE);
    1038                 :                 }
    1039                 :                 
    1040                 :             }
    1041               0 :             else if (EQUALN(papszToken[0],"CENTER",6))
    1042                 :             {
    1043               0 :                 if (CSLCount(papszToken) == 3)
    1044                 :                 {
    1045                 :                     SetCenter(fp->GetXTrans(atof(papszToken[1])),
    1046               0 :                               fp->GetYTrans(atof(papszToken[2])) );
    1047                 :                 }
    1048                 :             }
    1049                 :         }
    1050              56 :         CSLDestroy(papszToken);
    1051              56 :         papszToken = NULL;
    1052                 :     }
    1053                 :     
    1054                 :     
    1055              28 :     return 0; 
    1056                 : }
    1057                 :     
    1058                 : /**********************************************************************
    1059                 :  *                   TABRegion::WriteGeometryToMIFFile()
    1060                 :  *
    1061                 :  * Write the geometry and representation (color, etc...) part of the
    1062                 :  * feature to the .MIF file
    1063                 :  *
    1064                 :  * Returns 0 on success, -1 on error, in which case CPLError() will have
    1065                 :  * been called.
    1066                 :  **********************************************************************/
    1067              10 : int TABRegion::WriteGeometryToMIFFile(MIDDATAFile *fp)
    1068                 : { 
    1069                 :     OGRGeometry         *poGeom;
    1070                 : 
    1071              10 :     poGeom = GetGeometryRef();
    1072                 : 
    1073              10 :     if (poGeom && (wkbFlatten(poGeom->getGeometryType()) == wkbPolygon ||
    1074                 :                    wkbFlatten(poGeom->getGeometryType()) == wkbMultiPolygon ) )
    1075                 :     {
    1076                 :         /*=============================================================
    1077                 :          * REGIONs are similar to PLINE MULTIPLE
    1078                 :          *
    1079                 :          * We accept both OGRPolygons (with one or multiple rings) and 
    1080                 :          * OGRMultiPolygons as input.
    1081                 :          *============================================================*/
    1082                 :         int     i, iRing, numRingsTotal, numPoints;
    1083                 : 
    1084              10 :         numRingsTotal = GetNumRings();
    1085                 :         
    1086              10 :         fp->WriteLine("Region %d\n",numRingsTotal);
    1087                 :         
    1088              20 :         for(iRing=0; iRing < numRingsTotal; iRing++)
    1089                 :         {
    1090                 :             OGRLinearRing       *poRing;
    1091                 : 
    1092              10 :             poRing = GetRingRef(iRing);
    1093              10 :             if (poRing == NULL)
    1094                 :             {
    1095                 :                 CPLError(CE_Failure, CPLE_AssertionFailed,
    1096               0 :                          "TABRegion: Object Geometry contains NULL rings!");
    1097               0 :                 return -1;
    1098                 :             }
    1099                 : 
    1100              10 :             numPoints = poRing->getNumPoints();
    1101                 : 
    1102              10 :             fp->WriteLine("  %d\n",numPoints);
    1103             255 :             for(i=0; i<numPoints; i++)
    1104                 :             {
    1105             245 :                 fp->WriteLine("%.15g %.15g\n",poRing->getX(i), poRing->getY(i));
    1106                 :             }
    1107                 :         }
    1108                 :         
    1109              10 :         if (GetPenPattern())
    1110                 :           fp->WriteLine("    Pen (%d,%d,%d)\n",
    1111                 :                           GetPenWidthMIF(),GetPenPattern(),
    1112              10 :                           GetPenColor());
    1113                 :         
    1114                 : 
    1115              10 :         if (GetBrushPattern())
    1116                 :         {
    1117              10 :             if (GetBrushTransparent() == 0)
    1118                 :               fp->WriteLine("    Brush (%d,%d,%d)\n",GetBrushPattern(),
    1119              10 :                             GetBrushFGColor(),GetBrushBGColor());
    1120                 :             else
    1121                 :               fp->WriteLine("    Brush (%d,%d)\n",GetBrushPattern(),
    1122               0 :                             GetBrushFGColor());
    1123                 :         }
    1124                 : 
    1125              10 :         if (m_bCenterIsSet)
    1126                 :         {
    1127               0 :             fp->WriteLine("    Center %.15g %.15g\n", m_dCenterX, m_dCenterY);
    1128                 :         }
    1129                 : 
    1130                 : 
    1131                 :     }
    1132                 :     else
    1133                 :     {
    1134                 :         CPLError(CE_Failure, CPLE_AssertionFailed,
    1135               0 :                  "TABRegion: Object contains an invalid Geometry!");
    1136               0 :         return -1;
    1137                 :     }
    1138                 : 
    1139              10 :     return 0; 
    1140                 : }
    1141                 : 
    1142                 : /**********************************************************************
    1143                 :  *
    1144                 :  **********************************************************************/
    1145               0 : int TABRectangle::ReadGeometryFromMIFFile(MIDDATAFile *fp)
    1146                 : {
    1147                 :     const char          *pszLine;
    1148                 :     char               **papszToken;
    1149                 :     double               dXMin, dYMin, dXMax, dYMax;
    1150                 :     OGRPolygon          *poPolygon;
    1151                 :     OGRLinearRing       *poRing;
    1152                 : 
    1153                 :     papszToken = CSLTokenizeString2(fp->GetLastLine(), 
    1154               0 :                                     " \t", CSLT_HONOURSTRINGS);
    1155                 : 
    1156               0 :     if (CSLCount(papszToken) <  5)
    1157                 :     {
    1158               0 :         CSLDestroy(papszToken);
    1159               0 :         return -1;
    1160                 :     }
    1161                 : 
    1162               0 :     dXMin = fp->GetXTrans(atof(papszToken[1]));
    1163               0 :     dXMax = fp->GetXTrans(atof(papszToken[3]));
    1164               0 :     dYMin = fp->GetYTrans(atof(papszToken[2]));
    1165               0 :     dYMax = fp->GetYTrans(atof(papszToken[4]));
    1166                 :     
    1167                 :     /*-----------------------------------------------------------------
    1168                 :      * Call SetMBR() and GetMBR() now to make sure that min values are
    1169                 :      * really smaller than max values.
    1170                 :      *----------------------------------------------------------------*/
    1171               0 :     SetMBR(dXMin, dYMin, dXMax, dYMax);
    1172               0 :     GetMBR(dXMin, dYMin, dXMax, dYMax);
    1173                 :     
    1174               0 :     m_bRoundCorners = FALSE;
    1175               0 :     m_dRoundXRadius  = 0.0;
    1176               0 :     m_dRoundYRadius  = 0.0;
    1177                 :     
    1178               0 :     if (EQUALN(papszToken[0],"ROUNDRECT",9))
    1179                 :     {
    1180               0 :         m_bRoundCorners = TRUE;
    1181               0 :         if (CSLCount(papszToken) == 6)
    1182               0 :           m_dRoundXRadius = m_dRoundYRadius = atof(papszToken[5])/2.0;
    1183                 :         else
    1184                 :         {
    1185               0 :             CSLDestroy(papszToken);
    1186                 :             papszToken = CSLTokenizeString2(fp->GetLine(), 
    1187               0 :                                             " \t", CSLT_HONOURSTRINGS);
    1188               0 :             if (CSLCount(papszToken) !=1 )
    1189               0 :               m_dRoundXRadius = m_dRoundYRadius = atof(papszToken[1])/2.0;
    1190                 :         }
    1191                 :     }
    1192               0 :     CSLDestroy(papszToken);
    1193               0 :     papszToken = NULL;
    1194                 : 
    1195                 :     /*-----------------------------------------------------------------
    1196                 :      * Create and fill geometry object
    1197                 :      *----------------------------------------------------------------*/
    1198                 :         
    1199               0 :     poPolygon = new OGRPolygon;
    1200               0 :     poRing = new OGRLinearRing();
    1201               0 :     if (m_bRoundCorners && m_dRoundXRadius != 0.0 && m_dRoundYRadius != 0.0)
    1202                 :     {
    1203                 :         /*-------------------------------------------------------------
    1204                 :          * For rounded rectangles, we generate arcs with 45 line
    1205                 :          * segments for each corner.  We start with lower-left corner 
    1206                 :          * and proceed counterclockwise
    1207                 :          * We also have to make sure that rounding radius is not too
    1208                 :          * large for the MBR however, we 
    1209                 :          * always return the true X/Y radius (not adjusted) since this
    1210                 :          * is the way MapInfo seems to do it when a radius bigger than
    1211                 :          * the MBR is passed from TBA to MIF.
    1212                 :          *------------------------------------------------------------*/
    1213               0 :         double dXRadius = MIN(m_dRoundXRadius, (dXMax-dXMin)/2.0);
    1214               0 :         double dYRadius = MIN(m_dRoundYRadius, (dYMax-dYMin)/2.0);
    1215                 :         TABGenerateArc(poRing, 45, 
    1216                 :                        dXMin + dXRadius, dYMin + dYRadius, dXRadius, dYRadius,
    1217               0 :                        PI, 3.0*PI/2.0);
    1218                 :         TABGenerateArc(poRing, 45, 
    1219                 :                        dXMax - dXRadius, dYMin + dYRadius, dXRadius, dYRadius,
    1220               0 :                        3.0*PI/2.0, 2.0*PI);
    1221                 :         TABGenerateArc(poRing, 45, 
    1222                 :                        dXMax - dXRadius, dYMax - dYRadius, dXRadius, dYRadius,
    1223               0 :                        0.0, PI/2.0);
    1224                 :         TABGenerateArc(poRing, 45, 
    1225                 :                        dXMin + dXRadius, dYMax - dYRadius, dXRadius, dYRadius,
    1226               0 :                        PI/2.0, PI);
    1227                 :                        
    1228               0 :         TABCloseRing(poRing);
    1229                 :     }
    1230                 :     else
    1231                 :     {
    1232               0 :         poRing->addPoint(dXMin, dYMin);
    1233               0 :         poRing->addPoint(dXMax, dYMin);
    1234               0 :         poRing->addPoint(dXMax, dYMax);
    1235               0 :         poRing->addPoint(dXMin, dYMax);
    1236               0 :         poRing->addPoint(dXMin, dYMin);
    1237                 :     }
    1238                 : 
    1239               0 :     poPolygon->addRingDirectly(poRing);
    1240               0 :     SetGeometryDirectly(poPolygon);
    1241                 : 
    1242                 : 
    1243               0 :    while (((pszLine = fp->GetLine()) != NULL) && 
    1244                 :           fp->IsValidFeature(pszLine) == FALSE)
    1245                 :    {
    1246                 :        papszToken = CSLTokenizeStringComplex(pszLine,"() ,",
    1247               0 :                                              TRUE,FALSE);
    1248                 : 
    1249               0 :        if (CSLCount(papszToken) > 1)
    1250                 :        {
    1251               0 :            if (EQUALN(papszToken[0],"PEN",3))
    1252                 :            {       
    1253               0 :                if (CSLCount(papszToken) == 4)
    1254                 :                {   
    1255               0 :                    SetPenWidthMIF(atoi(papszToken[1]));
    1256               0 :                    SetPenPattern(atoi(papszToken[2]));
    1257               0 :                    SetPenColor(atoi(papszToken[3]));
    1258                 :                }
    1259                 :               
    1260                 :            }
    1261               0 :            else if (EQUALN(papszToken[0],"BRUSH", 5))
    1262                 :            {
    1263               0 :                if (CSLCount(papszToken) >=3)
    1264                 :                {
    1265               0 :                    SetBrushFGColor(atoi(papszToken[2]));
    1266               0 :                    SetBrushPattern(atoi(papszToken[1]));
    1267                 : 
    1268               0 :                    if (CSLCount(papszToken) == 4)
    1269               0 :                        SetBrushBGColor(atoi(papszToken[3]));
    1270                 :                    else
    1271               0 :                       SetBrushTransparent(TRUE);
    1272                 :                }
    1273                 :               
    1274                 :            }
    1275                 :        }
    1276               0 :        CSLDestroy(papszToken);
    1277               0 :        papszToken = NULL;
    1278                 :    }
    1279                 :  
    1280               0 :    return 0; 
    1281                 : 
    1282                 : }    
    1283                 : 
    1284                 : 
    1285                 : /**********************************************************************
    1286                 :  *
    1287                 :  **********************************************************************/
    1288               0 : int TABRectangle::WriteGeometryToMIFFile(MIDDATAFile *fp)
    1289                 : { 
    1290                 :     OGRGeometry         *poGeom;
    1291                 :     OGRPolygon          *poPolygon;
    1292               0 :     OGREnvelope         sEnvelope;
    1293                 :     
    1294                 :      /*-----------------------------------------------------------------
    1295                 :      * Fetch and validate geometry
    1296                 :      *----------------------------------------------------------------*/
    1297               0 :     poGeom = GetGeometryRef();
    1298               0 :     if (poGeom && wkbFlatten(poGeom->getGeometryType()) == wkbPolygon)
    1299               0 :         poPolygon = (OGRPolygon*)poGeom;
    1300                 :     else
    1301                 :     {
    1302                 :         CPLError(CE_Failure, CPLE_AssertionFailed,
    1303               0 :                  "TABRectangle: Missing or Invalid Geometry!");
    1304               0 :         return -1;
    1305                 :     }
    1306                 :     /*-----------------------------------------------------------------
    1307                 :      * Note that we will simply use the rectangle's MBR and don't really 
    1308                 :      * read the polygon geometry... this should be OK unless the 
    1309                 :      * polygon geometry was not really a rectangle.
    1310                 :      *----------------------------------------------------------------*/
    1311               0 :     poPolygon->getEnvelope(&sEnvelope);
    1312                 : 
    1313               0 :     if (m_bRoundCorners == TRUE)
    1314                 :     {
    1315                 :         fp->WriteLine("Roundrect %.15g %.15g %.15g %.15g %.15g\n", 
    1316                 :                       sEnvelope.MinX, sEnvelope.MinY,
    1317               0 :                       sEnvelope.MaxX, sEnvelope.MaxY, m_dRoundXRadius*2.0);
    1318                 :     }
    1319                 :     else
    1320                 :     {
    1321                 :         fp->WriteLine("Rect %.15g %.15g %.15g %.15g\n", 
    1322                 :                       sEnvelope.MinX, sEnvelope.MinY,
    1323               0 :                       sEnvelope.MaxX, sEnvelope.MaxY);
    1324                 :     }
    1325                 :     
    1326               0 :     if (GetPenPattern())
    1327                 :       fp->WriteLine("    Pen (%d,%d,%d)\n",GetPenWidthMIF(),GetPenPattern(),
    1328               0 :                     GetPenColor());
    1329                 : 
    1330               0 :     if (GetBrushPattern())
    1331                 :     {
    1332               0 :         if (GetBrushTransparent() == 0)
    1333                 :           fp->WriteLine("    Brush (%d,%d,%d)\n",GetBrushPattern(),
    1334               0 :                         GetBrushFGColor(),GetBrushBGColor());
    1335                 :         else
    1336                 :           fp->WriteLine("    Brush (%d,%d)\n",GetBrushPattern(),
    1337               0 :                         GetBrushFGColor());
    1338                 :     }
    1339               0 :     return 0; 
    1340                 : }
    1341                 : 
    1342                 : /**********************************************************************
    1343                 :  *
    1344                 :  **********************************************************************/
    1345               0 : int TABEllipse::ReadGeometryFromMIFFile(MIDDATAFile *fp)
    1346                 : {   
    1347                 :     const char *pszLine;
    1348                 :     char **papszToken;
    1349                 :     double              dXMin, dYMin, dXMax, dYMax;
    1350                 :     OGRPolygon          *poPolygon;
    1351                 :     OGRLinearRing       *poRing;
    1352                 : 
    1353                 :     papszToken = CSLTokenizeString2(fp->GetLastLine(), 
    1354               0 :                                     " \t", CSLT_HONOURSTRINGS);
    1355                 : 
    1356               0 :     if (CSLCount(papszToken) != 5)
    1357                 :     {
    1358               0 :         CSLDestroy(papszToken);
    1359               0 :         return -1;
    1360                 :     }
    1361                 : 
    1362               0 :     dXMin = fp->GetXTrans(atof(papszToken[1]));
    1363               0 :     dXMax = fp->GetXTrans(atof(papszToken[3]));
    1364               0 :     dYMin = fp->GetYTrans(atof(papszToken[2]));
    1365               0 :     dYMax = fp->GetYTrans(atof(papszToken[4]));
    1366                 : 
    1367               0 :     CSLDestroy(papszToken);
    1368               0 :     papszToken = NULL;
    1369                 : 
    1370                 :      /*-----------------------------------------------------------------
    1371                 :      * Save info about the ellipse def. inside class members
    1372                 :      *----------------------------------------------------------------*/
    1373               0 :     m_dCenterX = (dXMin + dXMax) / 2.0;
    1374               0 :     m_dCenterY = (dYMin + dYMax) / 2.0;
    1375               0 :     m_dXRadius = ABS( (dXMax - dXMin) / 2.0 );
    1376               0 :     m_dYRadius = ABS( (dYMax - dYMin) / 2.0 );
    1377                 : 
    1378               0 :     SetMBR(dXMin, dYMin, dXMax, dYMax);
    1379                 : 
    1380                 :     /*-----------------------------------------------------------------
    1381                 :      * Create and fill geometry object
    1382                 :      *----------------------------------------------------------------*/
    1383               0 :     poPolygon = new OGRPolygon;
    1384               0 :     poRing = new OGRLinearRing();
    1385                 : 
    1386                 :     /*-----------------------------------------------------------------
    1387                 :      * For the OGR geometry, we generate an ellipse with 2 degrees line
    1388                 :      * segments.
    1389                 :      *----------------------------------------------------------------*/
    1390                 :     TABGenerateArc(poRing, 180, 
    1391                 :                    m_dCenterX, m_dCenterY,
    1392                 :                    m_dXRadius, m_dYRadius,
    1393               0 :                    0.0, 2.0*PI);
    1394               0 :     TABCloseRing(poRing);
    1395                 : 
    1396               0 :     poPolygon->addRingDirectly(poRing);
    1397               0 :     SetGeometryDirectly(poPolygon);
    1398                 : 
    1399               0 :     while (((pszLine = fp->GetLine()) != NULL) && 
    1400                 :            fp->IsValidFeature(pszLine) == FALSE)
    1401                 :     {
    1402                 :         papszToken = CSLTokenizeStringComplex(pszLine,"() ,",
    1403               0 :                                               TRUE,FALSE);
    1404                 :         
    1405               0 :         if (CSLCount(papszToken) > 1)
    1406                 :         {
    1407               0 :             if (EQUALN(papszToken[0],"PEN",3))
    1408                 :             {       
    1409               0 :                 if (CSLCount(papszToken) == 4)
    1410                 :                 {   
    1411               0 :                     SetPenWidthMIF(atoi(papszToken[1]));
    1412               0 :                     SetPenPattern(atoi(papszToken[2]));
    1413               0 :                    SetPenColor(atoi(papszToken[3]));
    1414                 :                 }
    1415                 :                 
    1416                 :             }
    1417               0 :             else if (EQUALN(papszToken[0],"BRUSH", 5))
    1418                 :             {
    1419               0 :                 if (CSLCount(papszToken) >= 3)
    1420                 :                 {
    1421               0 :                     SetBrushFGColor(atoi(papszToken[2]));
    1422               0 :                     SetBrushPattern(atoi(papszToken[1]));
    1423                 :                     
    1424               0 :                     if (CSLCount(papszToken) == 4)
    1425               0 :                       SetBrushBGColor(atoi(papszToken[3]));
    1426                 :                     else
    1427               0 :                       SetBrushTransparent(TRUE);
    1428                 :                     
    1429                 :                 }
    1430                 :                 
    1431                 :             }
    1432                 :         }
    1433               0 :         CSLDestroy(papszToken);
    1434               0 :         papszToken = NULL;
    1435                 :     }
    1436               0 :     return 0; 
    1437                 : }
    1438                 : 
    1439                 : /**********************************************************************
    1440                 :  *
    1441                 :  **********************************************************************/
    1442               0 : int TABEllipse::WriteGeometryToMIFFile(MIDDATAFile *fp)
    1443                 : {
    1444                 :     OGRGeometry         *poGeom;
    1445               0 :     OGREnvelope         sEnvelope;
    1446                 :  
    1447               0 :     poGeom = GetGeometryRef();
    1448               0 :     if ( (poGeom && wkbFlatten(poGeom->getGeometryType()) == wkbPolygon ) ||
    1449                 :          (poGeom && wkbFlatten(poGeom->getGeometryType()) == wkbPoint )  )
    1450               0 :         poGeom->getEnvelope(&sEnvelope);
    1451                 :     else
    1452                 :     {
    1453                 :         CPLError(CE_Failure, CPLE_AssertionFailed,
    1454               0 :                  "TABEllipse: Missing or Invalid Geometry!");
    1455               0 :         return -1;
    1456                 :     }
    1457                 :       
    1458                 :     fp->WriteLine("Ellipse %.15g %.15g %.15g %.15g\n",sEnvelope.MinX, sEnvelope.MinY,
    1459               0 :                   sEnvelope.MaxX,sEnvelope.MaxY);
    1460                 :     
    1461               0 :     if (GetPenPattern())
    1462                 :       fp->WriteLine("    Pen (%d,%d,%d)\n",GetPenWidthMIF(),GetPenPattern(),
    1463               0 :                     GetPenColor());
    1464                 :     
    1465               0 :     if (GetBrushPattern())
    1466                 :     {       
    1467               0 :         if (GetBrushTransparent() == 0)
    1468                 :           fp->WriteLine("    Brush (%d,%d,%d)\n",GetBrushPattern(),
    1469               0 :                         GetBrushFGColor(),GetBrushBGColor());
    1470                 :         else
    1471                 :           fp->WriteLine("    Brush (%d,%d)\n",GetBrushPattern(),
    1472               0 :                         GetBrushFGColor());
    1473                 :     }
    1474               0 :     return 0; 
    1475                 : }
    1476                 : 
    1477                 : /**********************************************************************
    1478                 :  *
    1479                 :  **********************************************************************/
    1480               0 : int TABArc::ReadGeometryFromMIFFile(MIDDATAFile *fp)
    1481                 : {
    1482                 :     const char          *pszLine;
    1483                 :     OGRLineString       *poLine;
    1484                 :     char               **papszToken;
    1485                 :     double               dXMin,dXMax, dYMin,dYMax;
    1486                 :     int                  numPts;
    1487                 :     
    1488                 :     papszToken = CSLTokenizeString2(fp->GetLastLine(), 
    1489               0 :                                     " \t", CSLT_HONOURSTRINGS);
    1490                 : 
    1491               0 :     if (CSLCount(papszToken) == 5)
    1492                 :     {
    1493               0 :         dXMin = fp->GetXTrans(atof(papszToken[1]));
    1494               0 :         dXMax = fp->GetXTrans(atof(papszToken[3]));
    1495               0 :         dYMin = fp->GetYTrans(atof(papszToken[2]));
    1496               0 :         dYMax = fp->GetYTrans(atof(papszToken[4]));
    1497                 : 
    1498               0 :         CSLDestroy(papszToken);
    1499                 :         papszToken = CSLTokenizeString2(fp->GetLine(), 
    1500               0 :                                         " \t", CSLT_HONOURSTRINGS);
    1501               0 :         if (CSLCount(papszToken) != 2)
    1502                 :         {
    1503               0 :             CSLDestroy(papszToken);
    1504               0 :             return -1;
    1505                 :         }
    1506                 : 
    1507               0 :         m_dStartAngle = atof(papszToken[0]);
    1508               0 :         m_dEndAngle = atof(papszToken[1]);
    1509                 :     }
    1510               0 :     else if (CSLCount(papszToken) == 7)
    1511                 :     {
    1512               0 :         dXMin = fp->GetXTrans(atof(papszToken[1]));
    1513               0 :         dXMax = fp->GetXTrans(atof(papszToken[3]));
    1514               0 :         dYMin = fp->GetYTrans(atof(papszToken[2]));
    1515               0 :         dYMax = fp->GetYTrans(atof(papszToken[4]));
    1516               0 :         m_dStartAngle = atof(papszToken[5]);
    1517               0 :         m_dEndAngle = atof(papszToken[6]);
    1518                 :     }
    1519                 :     else
    1520                 :     {
    1521               0 :         CSLDestroy(papszToken);
    1522               0 :         return -1;
    1523                 :     }
    1524                 : 
    1525               0 :     CSLDestroy(papszToken);
    1526               0 :     papszToken = NULL;
    1527                 : 
    1528                 :     /*-------------------------------------------------------------
    1529                 :      * Start/End angles
    1530                 :      * Since the angles are specified for integer coordinates, and
    1531                 :      * that these coordinates can have the X axis reversed, we have to
    1532                 :      * adjust the angle values for the change in the X axis
    1533                 :      * direction.
    1534                 :      *
    1535                 :      * This should be necessary only when X axis is flipped.
    1536                 :      * __TODO__ Why is order of start/end values reversed as well???
    1537                 :      *------------------------------------------------------------*/
    1538                 : 
    1539               0 :     if (fp->GetXMultiplier() <= 0.0)
    1540                 :     {
    1541               0 :         m_dStartAngle = 360.0 - m_dStartAngle;
    1542               0 :         m_dEndAngle = 360.0 - m_dEndAngle;
    1543                 :     }
    1544                 :     
    1545               0 :     m_dCenterX = (dXMin + dXMax) / 2.0;
    1546               0 :     m_dCenterY = (dYMin + dYMax) / 2.0;
    1547               0 :     m_dXRadius = ABS( (dXMax - dXMin) / 2.0 );
    1548               0 :     m_dYRadius = ABS( (dYMax - dYMin) / 2.0 );
    1549                 : 
    1550                 :     /*-----------------------------------------------------------------
    1551                 :      * Create and fill geometry object
    1552                 :      * For the OGR geometry, we generate an arc with 2 degrees line
    1553                 :      * segments.
    1554                 :      *----------------------------------------------------------------*/
    1555               0 :     poLine = new OGRLineString;
    1556                 : 
    1557               0 :     if (m_dEndAngle < m_dStartAngle)
    1558               0 :         numPts = (int) ABS( ((m_dEndAngle+360.0)-m_dStartAngle)/2.0 ) + 1;
    1559                 :     else
    1560               0 :         numPts = (int) ABS( (m_dEndAngle-m_dStartAngle)/2.0 ) + 1;
    1561               0 :     numPts = MAX(2, numPts);
    1562                 : 
    1563                 :     TABGenerateArc(poLine, numPts,
    1564                 :                    m_dCenterX, m_dCenterY,
    1565                 :                    m_dXRadius, m_dYRadius,
    1566               0 :                    m_dStartAngle*PI/180.0, m_dEndAngle*PI/180.0);
    1567                 : 
    1568               0 :     SetMBR(dXMin, dYMin, dXMax, dYMax);
    1569               0 :     SetGeometryDirectly(poLine);
    1570                 : 
    1571               0 :     while (((pszLine = fp->GetLine()) != NULL) && 
    1572                 :            fp->IsValidFeature(pszLine) == FALSE)
    1573                 :     {
    1574                 :         papszToken = CSLTokenizeStringComplex(pszLine,"() ,",
    1575               0 :                                               TRUE,FALSE);
    1576                 :         
    1577               0 :         if (CSLCount(papszToken) > 1)
    1578                 :         {
    1579               0 :             if (EQUALN(papszToken[0],"PEN",3))
    1580                 :             {
    1581                 :                 
    1582               0 :                 if (CSLCount(papszToken) == 4)
    1583                 :                 {    
    1584               0 :                     SetPenWidthMIF(atoi(papszToken[1]));
    1585               0 :                     SetPenPattern(atoi(papszToken[2]));
    1586               0 :                     SetPenColor(atoi(papszToken[3]));
    1587                 :                 }
    1588                 :                 
    1589                 :             }
    1590                 :         }
    1591               0 :         CSLDestroy(papszToken);
    1592               0 :         papszToken = NULL;
    1593                 :    }
    1594               0 :    return 0; 
    1595                 : }
    1596                 : 
    1597                 : /**********************************************************************
    1598                 :  *
    1599                 :  **********************************************************************/
    1600               0 : int TABArc::WriteGeometryToMIFFile(MIDDATAFile *fp)
    1601                 : { 
    1602                 :     /*-------------------------------------------------------------
    1603                 :      * Start/End angles
    1604                 :      * Since we ALWAYS produce files in quadrant 1 then we can
    1605                 :      * ignore the special angle conversion required by flipped axis.
    1606                 :      *------------------------------------------------------------*/
    1607                 : 
    1608                 :      
    1609                 :     // Write the Arc's actual MBR
    1610                 :      fp->WriteLine("Arc %.15g %.15g %.15g %.15g\n", m_dCenterX-m_dXRadius, 
    1611                 :                    m_dCenterY-m_dYRadius, m_dCenterX+m_dXRadius, 
    1612               0 :                    m_dCenterY+m_dYRadius);
    1613                 : 
    1614               0 :      fp->WriteLine("  %.15g %.15g\n",m_dStartAngle,m_dEndAngle); 
    1615                 :      
    1616               0 :      if (GetPenPattern())
    1617                 :        fp->WriteLine("    Pen (%d,%d,%d)\n",GetPenWidthMIF(),GetPenPattern(),
    1618               0 :                      GetPenColor());
    1619                 :      
    1620                 :    
    1621               0 :     return 0; 
    1622                 : 
    1623                 : }
    1624                 : 
    1625                 : /**********************************************************************
    1626                 :  *
    1627                 :  **********************************************************************/
    1628               0 : int TABText::ReadGeometryFromMIFFile(MIDDATAFile *fp)
    1629                 : { 
    1630                 :     double               dXMin, dYMin, dXMax, dYMax;
    1631                 :     OGRGeometry         *poGeometry;
    1632                 :     const char          *pszLine;
    1633                 :     char               **papszToken;
    1634                 :     const char          *pszString;
    1635                 :     char                *pszTmpString;
    1636                 :   
    1637                 :     papszToken = CSLTokenizeString2(fp->GetLastLine(), 
    1638               0 :                                     " \t", CSLT_HONOURSTRINGS);
    1639                 : 
    1640               0 :     if (CSLCount(papszToken) == 1)
    1641                 :     {
    1642               0 :         CSLDestroy(papszToken);
    1643                 :         papszToken = CSLTokenizeString2(fp->GetLine(), 
    1644               0 :                                         " \t", CSLT_HONOURSTRINGS);
    1645               0 :         if (CSLCount(papszToken) != 1)
    1646                 :         {
    1647               0 :             CSLDestroy(papszToken);
    1648               0 :             return -1;
    1649                 :         }
    1650                 :         else
    1651               0 :           pszString = papszToken[0];
    1652                 :     }
    1653               0 :     else if (CSLCount(papszToken) == 2)
    1654                 :     {
    1655               0 :         pszString = papszToken[1];
    1656                 :     }
    1657                 :     else
    1658                 :      {
    1659               0 :         CSLDestroy(papszToken);
    1660               0 :         return -1;
    1661                 :     }
    1662                 : 
    1663                 :     /*-------------------------------------------------------------
    1664                 :      * Note: The text string may contain escaped "\n" chars, and we
    1665                 :      * sstore them in memory in the UnEscaped form to be OGR 
    1666                 :      * compliant. See Maptools bug 1107 for more details.
    1667                 :      *------------------------------------------------------------*/
    1668               0 :     pszTmpString = CPLStrdup(pszString);
    1669               0 :     m_pszString = TABUnEscapeString(pszTmpString, TRUE);
    1670               0 :     if (pszTmpString != m_pszString)
    1671               0 :         CPLFree(pszTmpString);
    1672                 : 
    1673               0 :     CSLDestroy(papszToken);
    1674                 :     papszToken = CSLTokenizeString2(fp->GetLine(), 
    1675               0 :                                     " \t", CSLT_HONOURSTRINGS);
    1676               0 :     if (CSLCount(papszToken) != 4)
    1677                 :     {
    1678               0 :         CSLDestroy(papszToken);
    1679               0 :         return -1;
    1680                 :     }
    1681                 :     else
    1682                 :     {
    1683               0 :         dXMin = fp->GetXTrans(atof(papszToken[0]));
    1684               0 :         dXMax = fp->GetXTrans(atof(papszToken[2]));
    1685               0 :         dYMin = fp->GetYTrans(atof(papszToken[1]));
    1686               0 :         dYMax = fp->GetYTrans(atof(papszToken[3]));
    1687                 : 
    1688               0 :         m_dHeight = dYMax - dYMin;  //SetTextBoxHeight(dYMax - dYMin);
    1689               0 :         m_dWidth  = dXMax - dXMin;  //SetTextBoxWidth(dXMax - dXMin);
    1690                 :         
    1691               0 :         if (m_dHeight <0.0)
    1692               0 :           m_dHeight*=-1.0;
    1693               0 :         if (m_dWidth <0.0)
    1694               0 :           m_dWidth*=-1.0;
    1695                 :     }
    1696                 : 
    1697               0 :     CSLDestroy(papszToken);
    1698               0 :     papszToken = NULL;
    1699                 : 
    1700                 :     /* Set/retrieve the MBR to make sure Mins are smaller than Maxs
    1701                 :      */
    1702                 : 
    1703               0 :     SetMBR(dXMin, dYMin, dXMax, dYMax);
    1704               0 :     GetMBR(dXMin, dYMin, dXMax, dYMax);
    1705                 :     
    1706               0 :     while (((pszLine = fp->GetLine()) != NULL) && 
    1707                 :            fp->IsValidFeature(pszLine) == FALSE)
    1708                 :     {
    1709                 :         papszToken = CSLTokenizeStringComplex(pszLine,"() ,",
    1710               0 :                                               TRUE,FALSE);
    1711                 :         
    1712               0 :         if (CSLCount(papszToken) > 1)
    1713                 :         {
    1714               0 :             if (EQUALN(papszToken[0],"FONT",4))
    1715                 :             {
    1716               0 :                 if (CSLCount(papszToken) >= 5)
    1717                 :                 {    
    1718               0 :                     SetFontName(papszToken[1]);
    1719               0 :                     SetFontFGColor(atoi(papszToken[4]));
    1720               0 :                     if (CSLCount(papszToken) ==6)
    1721                 :                     {
    1722               0 :                         SetFontBGColor(atoi(papszToken[5]));
    1723               0 :                         SetFontStyleMIFValue(atoi(papszToken[2]),TRUE);
    1724                 :                     }
    1725                 :                     else
    1726               0 :                       SetFontStyleMIFValue(atoi(papszToken[2]));
    1727                 : 
    1728                 :                     // papsztoken[3] = Size ???
    1729                 :                 }
    1730                 :                 
    1731                 :             }
    1732               0 :             else if (EQUALN(papszToken[0],"SPACING",7))
    1733                 :             {
    1734               0 :                 if (CSLCount(papszToken) >= 2)
    1735                 :                 {   
    1736               0 :                     if (EQUALN(papszToken[1],"2",1))
    1737                 :                     {
    1738               0 :                         SetTextSpacing(TABTSDouble);
    1739                 :                     }
    1740               0 :                     else if (EQUALN(papszToken[1],"1.5",3))
    1741                 :                     {
    1742               0 :                         SetTextSpacing(TABTS1_5);
    1743                 :                     }
    1744                 :                 }
    1745                 :                 
    1746               0 :                 if (CSLCount(papszToken) == 7)
    1747                 :                 {
    1748               0 :                     if (EQUALN(papszToken[2],"LAbel",5))
    1749                 :                     {
    1750               0 :                         if (EQUALN(papszToken[4],"simple",6))
    1751                 :                         {
    1752               0 :                             SetTextLineType(TABTLSimple);
    1753                 :                             SetTextLineEndPoint(fp->GetXTrans(atof(papszToken[5])),
    1754               0 :                                                 fp->GetYTrans(atof(papszToken[6])));
    1755                 :                         }
    1756               0 :                         else if (EQUALN(papszToken[4],"arrow", 5))
    1757                 :                         {
    1758               0 :                             SetTextLineType(TABTLArrow);
    1759                 :                             SetTextLineEndPoint(fp->GetXTrans(atof(papszToken[5])),
    1760               0 :                                                 fp->GetYTrans(atof(papszToken[6])));
    1761                 :                         }
    1762                 :                     }
    1763                 :                 }               
    1764                 :             }
    1765               0 :             else if (EQUALN(papszToken[0],"Justify",7))
    1766                 :             {
    1767               0 :                 if (CSLCount(papszToken) == 2)
    1768                 :                 {
    1769               0 :                     if (EQUALN( papszToken[1],"Center",6))
    1770                 :                     {
    1771               0 :                         SetTextJustification(TABTJCenter);
    1772                 :                     }
    1773               0 :                     else  if (EQUALN( papszToken[1],"Right",5))
    1774                 :                     {
    1775               0 :                         SetTextJustification(TABTJRight);
    1776                 :                     }
    1777                 :                     
    1778                 :                 }
    1779                 :                 
    1780                 :             }
    1781               0 :             else if (EQUALN(papszToken[0],"Angle",5))
    1782                 :             {
    1783               0 :                 if (CSLCount(papszToken) == 2)
    1784                 :                 {    
    1785               0 :                     SetTextAngle(atof(papszToken[1]));
    1786                 :                 }
    1787                 :                 
    1788                 :             }
    1789               0 :             else if (EQUALN(papszToken[0],"LAbel",5))
    1790                 :             {
    1791               0 :                 if (CSLCount(papszToken) == 5)
    1792                 :                 {    
    1793               0 :                     if (EQUALN(papszToken[2],"simple",6))
    1794                 :                     {
    1795               0 :                         SetTextLineType(TABTLSimple);
    1796                 :                         SetTextLineEndPoint(fp->GetXTrans(atof(papszToken[3])),
    1797               0 :                                            fp->GetYTrans(atof(papszToken[4])));
    1798                 :                     }
    1799               0 :                     else if (EQUALN(papszToken[2],"arrow", 5))
    1800                 :                     {
    1801               0 :                         SetTextLineType(TABTLArrow);
    1802                 :                         SetTextLineEndPoint(fp->GetXTrans(atof(papszToken[3])),
    1803               0 :                                            fp->GetYTrans(atof(papszToken[4])));
    1804                 :                     }
    1805                 :                 }
    1806                 :                 
    1807                 : 
    1808                 :                 // What I do with the XY coordonate
    1809                 :             }
    1810                 :         }
    1811               0 :         CSLDestroy(papszToken);
    1812               0 :         papszToken = NULL;
    1813                 :     }
    1814                 :     /*-----------------------------------------------------------------
    1815                 :      * Create an OGRPoint Geometry... 
    1816                 :      * The point X,Y values will be the coords of the lower-left corner before
    1817                 :      * rotation is applied.  (Note that the rotation in MapInfo is done around
    1818                 :      * the upper-left corner)
    1819                 :      * We need to calculate the true lower left corner of the text based
    1820                 :      * on the MBR after rotation, the text height and the rotation angle.
    1821                 :      *---------------------------------------------------------------- */
    1822                 :     double dCos, dSin, dX, dY;
    1823               0 :     dSin = sin(m_dAngle*PI/180.0);
    1824               0 :     dCos = cos(m_dAngle*PI/180.0);
    1825               0 :     if (dSin > 0.0  && dCos > 0.0)
    1826                 :     {
    1827               0 :         dX = dXMin + m_dHeight * dSin;
    1828               0 :         dY = dYMin;
    1829                 :     }
    1830               0 :     else if (dSin > 0.0  && dCos < 0.0)
    1831                 :     {
    1832               0 :         dX = dXMax;
    1833               0 :         dY = dYMin - m_dHeight * dCos;
    1834                 :     }
    1835               0 :     else if (dSin < 0.0  && dCos < 0.0)
    1836                 :     {
    1837               0 :         dX = dXMax + m_dHeight * dSin;
    1838               0 :         dY = dYMax;
    1839                 :     }
    1840                 :     else  // dSin < 0 && dCos > 0
    1841                 :     {   
    1842               0 :         dX = dXMin;
    1843               0 :         dY = dYMax - m_dHeight * dCos;
    1844                 :     }
    1845                 :     
    1846                 :     
    1847               0 :     poGeometry = new OGRPoint(dX, dY);
    1848                 : 
    1849               0 :     SetGeometryDirectly(poGeometry);
    1850                 : 
    1851                 :     /*-----------------------------------------------------------------
    1852                 :      * Compute Text Width: the width of the Text MBR before rotation 
    1853                 :      * in ground units... unfortunately this value is not stored in the
    1854                 :      * file, so we have to compute it with the MBR after rotation and 
    1855                 :      * the height of the MBR before rotation:
    1856                 :      * With  W = Width of MBR before rotation
    1857                 :      *       H = Height of MBR before rotation
    1858                 :      *       dX = Width of MBR after rotation
    1859                 :      *       dY = Height of MBR after rotation
    1860                 :      *       teta = rotation angle
    1861                 :      *
    1862                 :      *  For [-PI/4..teta..+PI/4] or [3*PI/4..teta..5*PI/4], we'll use:
    1863                 :      *   W = H * (dX - H * sin(teta)) / (H * cos(teta))
    1864                 :      *
    1865                 :      * and for other teta values, use:
    1866                 :      *   W = H * (dY - H * cos(teta)) / (H * sin(teta))
    1867                 :      *---------------------------------------------------------------- */
    1868               0 :     dSin = ABS(dSin);
    1869               0 :     dCos = ABS(dCos);
    1870               0 :     if (m_dHeight == 0.0)
    1871               0 :         m_dWidth = 0.0;
    1872               0 :     else if ( dCos > dSin )
    1873                 :         m_dWidth = m_dHeight * ((dXMax-dXMin) - m_dHeight*dSin) / 
    1874               0 :                                                         (m_dHeight*dCos);
    1875                 :     else
    1876                 :         m_dWidth = m_dHeight * ((dYMax-dYMin) - m_dHeight*dCos) /
    1877               0 :                                                         (m_dHeight*dSin);
    1878               0 :     m_dWidth = ABS(m_dWidth);
    1879                 :     
    1880               0 :    return 0; 
    1881                 : }
    1882                 : 
    1883                 : /**********************************************************************
    1884                 :  *
    1885                 :  **********************************************************************/
    1886               0 : int TABText::WriteGeometryToMIFFile(MIDDATAFile *fp)
    1887                 : {
    1888                 :     double dXMin,dYMin,dXMax,dYMax;
    1889                 :     char   *pszTmpString;
    1890                 : 
    1891                 :     /*-------------------------------------------------------------
    1892                 :      * Note: The text string may contain unescaped "\n" chars or 
    1893                 :      * "\\" chars and we expect to receive them in an unescaped 
    1894                 :      * form. Those characters are unescaped in memory to be like
    1895                 :      * other OGR drivers. See MapTools bug 1107 for more details.
    1896                 :      *------------------------------------------------------------*/
    1897               0 :     pszTmpString = TABEscapeString(m_pszString);
    1898               0 :     if(pszTmpString == NULL)
    1899               0 :         fp->WriteLine("Text \"\"\n" );
    1900                 :     else
    1901               0 :         fp->WriteLine("Text \"%s\"\n", pszTmpString );
    1902               0 :     if (pszTmpString != m_pszString)
    1903               0 :         CPLFree(pszTmpString);
    1904                 : 
    1905                 :     //    UpdateTextMBR();
    1906               0 :     GetMBR(dXMin, dYMin, dXMax, dYMax);
    1907               0 :     fp->WriteLine("    %.15g %.15g %.15g %.15g\n",dXMin, dYMin,dXMax, dYMax); 
    1908                 :  
    1909               0 :     if (IsFontBGColorUsed())
    1910                 :       fp->WriteLine("    Font (\"%s\",%d,%d,%d,%d)\n", GetFontNameRef(), 
    1911                 :                     GetFontStyleMIFValue(),0,GetFontFGColor(),
    1912               0 :                     GetFontBGColor());
    1913                 :     else
    1914                 :       fp->WriteLine("    Font (\"%s\",%d,%d,%d)\n", GetFontNameRef(), 
    1915               0 :                     GetFontStyleMIFValue(),0,GetFontFGColor());
    1916                 : 
    1917               0 :     switch (GetTextSpacing())
    1918                 :     {
    1919                 :       case   TABTS1_5:
    1920               0 :         fp->WriteLine("    Spacing 1.5\n");
    1921               0 :         break;
    1922                 :       case TABTSDouble:
    1923               0 :         fp->WriteLine("    Spacing 2.0\n");
    1924                 :         break;    
    1925                 :       case TABTSSingle:
    1926                 :       default:
    1927                 :         break;
    1928                 :     }
    1929                 : 
    1930               0 :     switch (GetTextJustification())
    1931                 :     {
    1932                 :       case TABTJCenter:
    1933               0 :         fp->WriteLine("    Justify Center\n");
    1934               0 :         break;
    1935                 :       case TABTJRight:
    1936               0 :         fp->WriteLine("    Justify Right\n");
    1937                 :         break;
    1938                 :       case TABTJLeft:
    1939                 :       default:
    1940                 :         break;
    1941                 :     }
    1942                 : 
    1943               0 :     if (ABS(GetTextAngle()) >  0.000001)
    1944               0 :         fp->WriteLine("    Angle %.15g\n",GetTextAngle());
    1945                 : 
    1946               0 :     switch (GetTextLineType())
    1947                 :     {
    1948                 :       case TABTLSimple:
    1949               0 :         if (m_bLineEndSet)
    1950                 :             fp->WriteLine("    Label Line Simple %.15g %.15g \n",
    1951               0 :                           m_dfLineEndX, m_dfLineEndY );
    1952               0 :         break;
    1953                 :       case TABTLArrow:
    1954               0 :         if (m_bLineEndSet)
    1955                 :             fp->WriteLine("    Label Line Arrow %.15g %.15g \n",
    1956               0 :                           m_dfLineEndX, m_dfLineEndY );
    1957                 :         break;
    1958                 :       case TABTLNoLine:
    1959                 :       default:
    1960                 :         break;
    1961                 :     }
    1962               0 :     return 0; 
    1963                 : 
    1964                 : }
    1965                 : 
    1966                 : /**********************************************************************
    1967                 :  *
    1968                 :  **********************************************************************/
    1969               0 : int TABMultiPoint::ReadGeometryFromMIFFile(MIDDATAFile *fp)
    1970                 : {
    1971                 :     OGRPoint            *poPoint;
    1972                 :     OGRMultiPoint       *poMultiPoint;
    1973                 :     char                **papszToken;
    1974                 :     const char          *pszLine;
    1975                 :     int                 nNumPoint, i;
    1976                 :     double              dfX,dfY;
    1977               0 :     OGREnvelope         sEnvelope;
    1978                 : 
    1979                 :     papszToken = CSLTokenizeString2(fp->GetLastLine(), 
    1980               0 :                                     " \t", CSLT_HONOURSTRINGS);
    1981                 :      
    1982               0 :     if (CSLCount(papszToken) !=2)
    1983                 :     {
    1984               0 :         CSLDestroy(papszToken);
    1985               0 :         return -1;
    1986                 :     }
    1987                 :     
    1988               0 :     nNumPoint = atoi(papszToken[1]);
    1989               0 :     poMultiPoint = new OGRMultiPoint;
    1990                 : 
    1991               0 :     CSLDestroy(papszToken);
    1992               0 :     papszToken = NULL;
    1993                 : 
    1994                 :     // Get each point and add them to the multipoint feature
    1995               0 :     for(i=0; i<nNumPoint; i++)
    1996                 :     {
    1997               0 :         pszLine = fp->GetLine();
    1998                 :         papszToken = CSLTokenizeString2(fp->GetLastLine(), 
    1999               0 :                                         " \t", CSLT_HONOURSTRINGS);
    2000               0 :         if (CSLCount(papszToken) !=2)
    2001                 :         {
    2002               0 :             CSLDestroy(papszToken);
    2003               0 :             return -1;
    2004                 :         }
    2005                 : 
    2006               0 :         dfX = fp->GetXTrans(atof(papszToken[0]));
    2007               0 :         dfY = fp->GetXTrans(atof(papszToken[1]));
    2008               0 :         poPoint = new OGRPoint(dfX, dfY);
    2009               0 :         if ( poMultiPoint->addGeometryDirectly( poPoint ) != OGRERR_NONE)
    2010                 :         {
    2011               0 :             CPLAssert(FALSE); // Just in case OGR is modified
    2012                 :         }
    2013                 : 
    2014                 :         // Set center
    2015               0 :         if(i == 0)
    2016                 :         {
    2017               0 :             SetCenter( dfX, dfY );
    2018                 :         }
    2019               0 :         CSLDestroy(papszToken);
    2020                 :     }
    2021                 : 
    2022               0 :     if( SetGeometryDirectly( poMultiPoint ) != OGRERR_NONE)
    2023                 :     {
    2024               0 :         CPLAssert(FALSE); // Just in case OGR is modified
    2025                 :     }
    2026                 : 
    2027               0 :     poMultiPoint->getEnvelope(&sEnvelope);
    2028                 :     SetMBR(sEnvelope.MinX, sEnvelope.MinY,
    2029               0 :            sEnvelope.MaxX,sEnvelope.MaxY);
    2030                 : 
    2031                 :     // Read optional SYMBOL line...
    2032                 : 
    2033               0 :     while (((pszLine = fp->GetLine()) != NULL) && 
    2034                 :            fp->IsValidFeature(pszLine) == FALSE)
    2035                 :     {
    2036                 :         papszToken = CSLTokenizeStringComplex(pszLine," ,()\t",
    2037               0 :                                               TRUE,FALSE);
    2038               0 :         if (CSLCount(papszToken) == 4 && EQUAL(papszToken[0], "SYMBOL") )
    2039                 :         {
    2040               0 :             SetSymbolNo(atoi(papszToken[1]));
    2041               0 :             SetSymbolColor(atoi(papszToken[2]));
    2042               0 :             SetSymbolSize(atoi(papszToken[3]));
    2043                 :         }
    2044               0 :         CSLDestroy(papszToken);
    2045                 :     }
    2046                 : 
    2047               0 :     return 0; 
    2048                 : }
    2049                 : 
    2050                 : /**********************************************************************
    2051                 :  *
    2052                 :  **********************************************************************/
    2053               0 : int TABMultiPoint::WriteGeometryToMIFFile(MIDDATAFile *fp)
    2054                 : { 
    2055                 :     OGRGeometry         *poGeom;
    2056                 :     OGRPoint            *poPoint;
    2057                 :     OGRMultiPoint       *poMultiPoint;
    2058                 :     int                 nNumPoints, iPoint;
    2059                 :  
    2060                 :     /*-----------------------------------------------------------------
    2061                 :      * Fetch and validate geometry
    2062                 :      *----------------------------------------------------------------*/
    2063               0 :     poGeom = GetGeometryRef();
    2064               0 :     if (poGeom && wkbFlatten(poGeom->getGeometryType()) == wkbMultiPoint)
    2065                 :     {
    2066               0 :         poMultiPoint = (OGRMultiPoint*)poGeom;
    2067               0 :         nNumPoints = poMultiPoint->getNumGeometries();
    2068                 : 
    2069               0 :         fp->WriteLine("MultiPoint %d\n", nNumPoints);
    2070                 : 
    2071               0 :         for(iPoint=0; iPoint < nNumPoints; iPoint++)
    2072                 :         {
    2073                 :             /*------------------------------------------------------------
    2074                 :              * Validate each point
    2075                 :              *-----------------------------------------------------------*/
    2076               0 :             poGeom = poMultiPoint->getGeometryRef(iPoint);
    2077               0 :             if (poGeom && wkbFlatten(poGeom->getGeometryType()) == wkbPoint)
    2078                 :             { 
    2079               0 :                 poPoint = (OGRPoint*)poGeom;
    2080               0 :                 fp->WriteLine("%.15g %.15g\n",poPoint->getX(),poPoint->getY());
    2081                 :             }
    2082                 :             else
    2083                 :             {
    2084                 :                 CPLError(CE_Failure, CPLE_AssertionFailed,
    2085               0 :                          "TABMultiPoint: Missing or Invalid Geometry!");
    2086               0 :                 return -1;
    2087                 :             }
    2088                 :         }
    2089                 :         // Write symbol
    2090                 :         fp->WriteLine("    Symbol (%d,%d,%d)\n",GetSymbolNo(),GetSymbolColor(),
    2091               0 :                       GetSymbolSize());
    2092                 :     }
    2093                 : 
    2094               0 :     return 0; 
    2095                 : }
    2096                 : 
    2097                 : 
    2098                 : /**********************************************************************
    2099                 :  *
    2100                 :  **********************************************************************/
    2101               0 : int TABCollection::ReadGeometryFromMIFFile(MIDDATAFile *fp)
    2102                 : {
    2103                 :     char                **papszToken;
    2104                 :     const char          *pszLine;
    2105                 :     int                 numParts, i;
    2106               0 :     OGREnvelope         sEnvelope;
    2107                 : 
    2108                 :     /*-----------------------------------------------------------------
    2109                 :      * Fetch number of parts in "COLLECTION %d" line
    2110                 :      *----------------------------------------------------------------*/
    2111                 :     papszToken = CSLTokenizeString2(fp->GetLastLine(), 
    2112               0 :                                     " \t", CSLT_HONOURSTRINGS);
    2113                 :      
    2114               0 :     if (CSLCount(papszToken) !=2)
    2115                 :     {
    2116               0 :         CSLDestroy(papszToken);
    2117               0 :         return -1;
    2118                 :     }
    2119                 :     
    2120               0 :     numParts = atoi(papszToken[1]);
    2121               0 :     CSLDestroy(papszToken);
    2122               0 :     papszToken = NULL;
    2123                 : 
    2124                 :     // Make sure collection is empty
    2125               0 :     EmptyCollection();
    2126                 : 
    2127               0 :     pszLine = fp->GetLine();
    2128                 : 
    2129                 :     /*-----------------------------------------------------------------
    2130                 :      * Read each part and add them to the feature
    2131                 :      *----------------------------------------------------------------*/
    2132               0 :     for (i=0; i < numParts; i++)
    2133                 :     {
    2134               0 :         if (pszLine == NULL)
    2135                 :         {
    2136                 :             CPLError(CE_Failure, CPLE_FileIO,
    2137               0 :                   "Unexpected EOF while reading TABCollection from MIF file.");
    2138               0 :             return -1;
    2139                 :          }
    2140                 : 
    2141               0 :         while(*pszLine == ' ' || *pszLine == '\t')
    2142               0 :             pszLine++;  // skip leading spaces
    2143                 : 
    2144               0 :         if (*pszLine == '\0')
    2145               0 :             continue;  // Skip blank lines
    2146                 : 
    2147               0 :         if (EQUALN(pszLine,"REGION",6))
    2148                 :         {
    2149               0 :             m_poRegion = new TABRegion(GetDefnRef());
    2150               0 :             if (m_poRegion->ReadGeometryFromMIFFile(fp) != 0)
    2151                 :             {
    2152                 :                 CPLError(CE_Failure, CPLE_NotSupported,
    2153               0 :                          "TABCollection: Error reading REGION part.");
    2154               0 :                 delete m_poRegion;
    2155               0 :                 m_poRegion = NULL;
    2156               0 :                 return -1;
    2157                 :             }
    2158                 :         }  
    2159               0 :         else if (EQUALN(pszLine,"LINE",4) ||
    2160                 :                  EQUALN(pszLine,"PLINE",5))
    2161                 :         {
    2162               0 :             m_poPline = new TABPolyline(GetDefnRef());
    2163               0 :             if (m_poPline->ReadGeometryFromMIFFile(fp) != 0)
    2164                 :             {
    2165                 :                 CPLError(CE_Failure, CPLE_NotSupported,
    2166               0 :                          "TABCollection: Error reading PLINE part.");
    2167               0 :                 delete m_poPline;
    2168               0 :                 m_poPline = NULL;
    2169               0 :                 return -1;
    2170                 :             }
    2171                 :         }
    2172               0 :         else if (EQUALN(pszLine,"MULTIPOINT",10))
    2173                 :         {
    2174               0 :             m_poMpoint = new TABMultiPoint(GetDefnRef());
    2175               0 :             if (m_poMpoint->ReadGeometryFromMIFFile(fp) != 0)
    2176                 :             {
    2177                 :                 CPLError(CE_Failure, CPLE_NotSupported,
    2178               0 :                          "TABCollection: Error reading MULTIPOINT part.");
    2179               0 :                 delete m_poMpoint;
    2180               0 :                 m_poMpoint = NULL;
    2181               0 :                 return -1;
    2182                 :             }
    2183                 :         }
    2184                 :         else
    2185                 :         {
    2186                 :             CPLError(CE_Failure, CPLE_FileIO,
    2187                 :                      "Reading TABCollection from MIF failed, expecting one "
    2188                 :                      "of REGION, PLINE or MULTIPOINT, got: '%s'",
    2189               0 :                      pszLine);
    2190               0 :             return -1;
    2191                 :         }
    2192                 : 
    2193               0 :         pszLine = fp->GetLastLine();
    2194                 :     }
    2195                 : 
    2196                 :     /*-----------------------------------------------------------------
    2197                 :      * Set the main OGRFeature Geometry 
    2198                 :      * (this is actually duplicating geometries from each member)
    2199                 :      *----------------------------------------------------------------*/
    2200                 :     // use addGeometry() rather than addGeometryDirectly() as this clones
    2201                 :     // the added geometry so won't leave dangling ptrs when the above features
    2202                 :     // are deleted
    2203                 : 
    2204               0 :     OGRGeometryCollection *poGeomColl = new OGRGeometryCollection();
    2205               0 :     if(m_poRegion && m_poRegion->GetGeometryRef() != NULL)
    2206               0 :         poGeomColl->addGeometry(m_poRegion->GetGeometryRef());
    2207                 :     
    2208               0 :     if(m_poPline && m_poPline->GetGeometryRef() != NULL)
    2209               0 :         poGeomColl->addGeometry(m_poPline->GetGeometryRef());
    2210                 : 
    2211               0 :     if(m_poMpoint && m_poMpoint->GetGeometryRef() != NULL)
    2212               0 :         poGeomColl->addGeometry(m_poMpoint->GetGeometryRef());
    2213                 : 
    2214               0 :     this->SetGeometryDirectly(poGeomColl);
    2215                 : 
    2216               0 :     poGeomColl->getEnvelope(&sEnvelope);
    2217                 :     SetMBR(sEnvelope.MinX, sEnvelope.MinY,
    2218               0 :            sEnvelope.MaxX, sEnvelope.MaxY);
    2219                 : 
    2220               0 :     return 0;
    2221                 : }
    2222                 : 
    2223                 : /**********************************************************************
    2224                 :  *
    2225                 :  **********************************************************************/
    2226               0 : int TABCollection::WriteGeometryToMIFFile(MIDDATAFile *fp)
    2227                 : {
    2228               0 :     int numParts = 0;
    2229               0 :     if (m_poRegion)     numParts++;
    2230               0 :     if (m_poPline)      numParts++;
    2231               0 :     if (m_poMpoint)     numParts++;
    2232                 : 
    2233               0 :     fp->WriteLine("COLLECTION %d\n", numParts);
    2234                 : 
    2235               0 :     if (m_poRegion)
    2236                 :     {
    2237               0 :         if (m_poRegion->WriteGeometryToMIFFile(fp) != 0)
    2238               0 :             return -1;
    2239                 :     }
    2240                 : 
    2241               0 :     if (m_poPline)
    2242                 :     {
    2243               0 :         if (m_poPline->WriteGeometryToMIFFile(fp) != 0)
    2244               0 :             return -1;
    2245                 :     }
    2246                 : 
    2247               0 :     if (m_poMpoint)
    2248                 :     {
    2249               0 :         if (m_poMpoint->WriteGeometryToMIFFile(fp) != 0)
    2250               0 :             return -1;
    2251                 :     }
    2252                 : 
    2253               0 :     return 0;
    2254                 : }
    2255                 : 
    2256                 : /**********************************************************************
    2257                 :  *
    2258                 :  **********************************************************************/
    2259               0 : int TABDebugFeature::ReadGeometryFromMIFFile(MIDDATAFile *fp)
    2260                 : { 
    2261                 :    const char *pszLine;
    2262                 :   
    2263                 :    
    2264                 :   /* Go to the first line of the next feature */
    2265               0 :    printf("%s\n", fp->GetLastLine());
    2266                 : 
    2267               0 :    while (((pszLine = fp->GetLine()) != NULL) && 
    2268                 :           fp->IsValidFeature(pszLine) == FALSE)
    2269                 :      ;
    2270                 :   
    2271               0 :    return 0; 
    2272                 : }
    2273                 : 
    2274                 : 
    2275                 : /**********************************************************************
    2276                 :  *
    2277                 :  **********************************************************************/
    2278               0 : int TABDebugFeature::WriteGeometryToMIFFile(MIDDATAFile *fp){ return -1; }
    2279                 : 
    2280                 : 
    2281                 : 
    2282                 : 

Generated by: LTP GCOV extension version 1.5