LCOV - code coverage report
Current view: directory - ogr/ogrsf_frmts/mitab - mitab_feature_mif.cpp (source / functions) Found Hit Coverage
Test: gdal_filtered.info Lines: 891 180 20.2 %
Date: 2012-12-26 Functions: 29 9 31.0 %

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

Generated by: LCOV version 1.7