LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/mitab - mitab.h (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 115 220 52.3 %
Date: 2024-05-05 22:37:24 Functions: 49 100 49.0 %

          Line data    Source code
       1             : /**********************************************************************
       2             :  * $Id$
       3             :  *
       4             :  * Name:     mitab.h
       5             :  * Project:  MapInfo TAB Read/Write library
       6             :  * Language: C++
       7             :  * Purpose:  Header file containing public definitions for the library.
       8             :  * Author:   Daniel Morissette, dmorissette@dmsolutions.ca
       9             :  *
      10             :  **********************************************************************
      11             :  * Copyright (c) 1999-2005, Daniel Morissette
      12             :  * Copyright (c) 2014, Even Rouault <even.rouault at spatialys.com>
      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             : #ifndef MITAB_H_INCLUDED_
      34             : #define MITAB_H_INCLUDED_
      35             : 
      36             : #include "mitab_priv.h"
      37             : #include "ogr_feature.h"
      38             : #include "ogr_featurestyle.h"
      39             : #include "ogrsf_frmts.h"
      40             : 
      41             : #include <set>
      42             : 
      43             : /*---------------------------------------------------------------------
      44             :  * Current version of the MITAB library... always useful!
      45             :  *--------------------------------------------------------------------*/
      46             : #define MITAB_VERSION "2.0.0-dev (2008-10)"
      47             : #define MITAB_VERSION_INT 2000000 /* version x.y.z -> xxxyyyzzz */
      48             : 
      49             : #ifndef ROUND_INT
      50             : #define ROUND_INT(dX) static_cast<int>((dX) < 0.0 ? (dX)-0.5 : (dX) + 0.5)
      51             : #endif
      52             : 
      53             : #define MITAB_AREA(x1, y1, x2, y2)                                             \
      54             :     ((static_cast<double>(x2) - (x1)) * (static_cast<double>(y2) - (y1)))
      55             : 
      56             : class TABFeature;
      57             : 
      58             : /*---------------------------------------------------------------------
      59             :  * Codes for the GetFileClass() in the IMapInfoFile-derived  classes
      60             :  *--------------------------------------------------------------------*/
      61             : typedef enum
      62             : {
      63             :     TABFC_IMapInfoFile = 0,
      64             :     TABFC_TABFile,
      65             :     TABFC_TABView,
      66             :     TABFC_TABSeamless,
      67             :     TABFC_MIFFile
      68             : } TABFileClass;
      69             : 
      70             : /*---------------------------------------------------------------------
      71             :  *                      class IMapInfoFile
      72             :  *
      73             :  * Virtual base class for the TABFile and MIFFile classes.
      74             :  *
      75             :  * This is the definition of the public interface methods that should
      76             :  * be available for any type of MapInfo dataset.
      77             :  *--------------------------------------------------------------------*/
      78             : 
      79             : class IMapInfoFile CPL_NON_FINAL : public OGRLayer
      80             : {
      81             :     CPL_DISALLOW_COPY_ASSIGN(IMapInfoFile)
      82             : 
      83             :   protected:
      84             :     GDALDataset *m_poDS = nullptr;
      85             :     GIntBig m_nCurFeatureId;
      86             :     TABFeature *m_poCurFeature;
      87             :     GBool m_bBoundsSet;
      88             : 
      89             :     char *m_pszCharset;
      90             :     std::set<CPLString> m_oSetFields{};
      91             :     TABFeature *CreateTABFeature(OGRFeature *poFeature);
      92             : 
      93             :   public:
      94             :     IMapInfoFile(GDALDataset *poDS);
      95             :     virtual ~IMapInfoFile();
      96             : 
      97           0 :     virtual TABFileClass GetFileClass()
      98             :     {
      99           0 :         return TABFC_IMapInfoFile;
     100             :     }
     101             : 
     102             :     virtual int Open(const char *pszFname, const char *pszAccess,
     103             :                      GBool bTestOpenNoError = FALSE,
     104             :                      const char *pszCharset = nullptr);
     105             : 
     106             :     virtual int Open(const char *pszFname, TABAccess eAccess,
     107             :                      GBool bTestOpenNoError = FALSE,
     108             :                      const char *pszCharset = nullptr) = 0;
     109             :     virtual int Close() = 0;
     110             : 
     111             :     virtual int
     112           0 :     SetQuickSpatialIndexMode(CPL_UNUSED GBool bQuickSpatialIndexMode = TRUE)
     113             :     {
     114           0 :         return -1;
     115             :     }
     116             : 
     117             :     virtual const char *GetTableName() = 0;
     118             : 
     119             :     ///////////////
     120             :     // Static method to detect file type, create an object to read that
     121             :     // file and open it.
     122             :     static IMapInfoFile *SmartOpen(GDALDataset *poDS, const char *pszFname,
     123             :                                    GBool bUpdate = FALSE,
     124             :                                    GBool bTestOpenNoError = FALSE);
     125             : 
     126             :     ///////////////
     127             :     //  OGR methods for read support
     128             :     virtual void ResetReading() override = 0;
     129             :     virtual GIntBig GetFeatureCount(int bForce) override = 0;
     130             :     virtual OGRFeature *GetNextFeature() override;
     131             :     virtual OGRFeature *GetFeature(GIntBig nFeatureId) override;
     132             :     virtual OGRErr ICreateFeature(OGRFeature *poFeature) override;
     133             :     virtual int TestCapability(const char *pszCap) override = 0;
     134             :     virtual OGRErr GetExtent(OGREnvelope *psExtent, int bForce) override = 0;
     135             : 
     136           0 :     virtual OGRErr GetExtent(int iGeomField, OGREnvelope *psExtent,
     137             :                              int bForce) override
     138             :     {
     139           0 :         return OGRLayer::GetExtent(iGeomField, psExtent, bForce);
     140             :     }
     141             : 
     142          23 :     GDALDataset *GetDataset() override
     143             :     {
     144          23 :         return m_poDS;
     145             :     }
     146             : 
     147             :     ///////////////
     148             :     // Read access specific stuff
     149             :     //
     150             :     virtual GIntBig GetNextFeatureId(GIntBig nPrevId) = 0;
     151             :     virtual TABFeature *GetFeatureRef(GIntBig nFeatureId) = 0;
     152             :     virtual OGRFeatureDefn *GetLayerDefn() override = 0;
     153             : 
     154             :     virtual TABFieldType GetNativeFieldType(int nFieldId) = 0;
     155             : 
     156             :     virtual int GetBounds(double &dXMin, double &dYMin, double &dXMax,
     157             :                           double &dYMax, GBool bForce = TRUE) = 0;
     158             : 
     159             :     virtual OGRSpatialReference *GetSpatialRef() override = 0;
     160             : 
     161             :     virtual int GetFeatureCountByType(int &numPoints, int &numLines,
     162             :                                       int &numRegions, int &numTexts,
     163             :                                       GBool bForce = TRUE) = 0;
     164             : 
     165             :     virtual GBool IsFieldIndexed(int nFieldId) = 0;
     166             :     virtual GBool IsFieldUnique(int nFieldId) = 0;
     167             : 
     168             :     ///////////////
     169             :     // Write access specific stuff
     170             :     //
     171         200 :     GBool IsBoundsSet()
     172             :     {
     173         200 :         return m_bBoundsSet;
     174             :     }
     175             : 
     176             :     virtual int SetBounds(double dXMin, double dYMin, double dXMax,
     177             :                           double dYMax) = 0;
     178             :     virtual int
     179             :     SetFeatureDefn(OGRFeatureDefn *poFeatureDefn,
     180             :                    TABFieldType *paeMapInfoNativeFieldTypes = nullptr) = 0;
     181             :     virtual int AddFieldNative(const char *pszName, TABFieldType eMapInfoType,
     182             :                                int nWidth = 0, int nPrecision = 0,
     183             :                                GBool bIndexed = FALSE, GBool bUnique = FALSE,
     184             :                                int bApproxOK = TRUE) = 0;
     185             :     virtual OGRErr CreateField(const OGRFieldDefn *poField,
     186             :                                int bApproxOK = TRUE) override;
     187             : 
     188             :     virtual int SetSpatialRef(OGRSpatialReference *poSpatialRef) = 0;
     189             : 
     190             :     virtual OGRErr CreateFeature(TABFeature *poFeature) = 0;
     191             : 
     192             :     virtual int SetFieldIndexed(int nFieldId) = 0;
     193             : 
     194             :     virtual int SetCharset(const char *charset);
     195             : 
     196             :     virtual const char *GetCharset() const;
     197             : 
     198             :     static const char *CharsetToEncoding(const char *);
     199             :     static const char *EncodingToCharset(const char *);
     200             : 
     201             :     void SetEncoding(const char *);
     202             :     const char *GetEncoding() const;
     203             :     int TestUtf8Capability() const;
     204             :     CPLString NormalizeFieldName(const char *pszName) const;
     205             :     ///////////////
     206             :     // semi-private.
     207             :     virtual int GetProjInfo(TABProjInfo *poPI) = 0;
     208             :     virtual int SetProjInfo(TABProjInfo *poPI) = 0;
     209             :     virtual int SetMIFCoordSys(const char *pszMIFCoordSys) = 0;
     210             : 
     211             :     static int GetTABType(const OGRFieldDefn *poField, TABFieldType *peTABType,
     212             :                           int *pnWidth, int *pnPrecision);
     213             : 
     214             : #ifdef DEBUG
     215             :     virtual void Dump(FILE *fpOut = nullptr) = 0;
     216             : #endif
     217             : };
     218             : 
     219             : /*---------------------------------------------------------------------
     220             :  *                      class TABFile
     221             :  *
     222             :  * The main class for TAB datasets.  External programs should use this
     223             :  * class to open a TAB dataset and read/write features from/to it.
     224             :  *
     225             :  *--------------------------------------------------------------------*/
     226             : class TABFile final : public IMapInfoFile
     227             : {
     228             :     CPL_DISALLOW_COPY_ASSIGN(TABFile)
     229             : 
     230             :   private:
     231             :     char *m_pszFname;
     232             :     TABAccess m_eAccessMode;
     233             :     char **m_papszTABFile;
     234             :     int m_nVersion;
     235             :     int *m_panIndexNo;
     236             :     TABTableType m_eTableType;  // NATIVE (.DAT) or DBF
     237             : 
     238             :     TABDATFile *m_poDATFile;  // Attributes file
     239             :     TABMAPFile *m_poMAPFile;  // Object Geometry file
     240             :     TABINDFile *m_poINDFile;  // Attributes index file
     241             : 
     242             :     OGRFeatureDefn *m_poDefn;
     243             :     OGRSpatialReference *m_poSpatialRef;
     244             :     int bUseSpatialTraversal;
     245             : 
     246             :     int m_nLastFeatureId;
     247             : 
     248             :     GIntBig *m_panMatchingFIDs;
     249             :     int m_iMatchingFID;
     250             : 
     251             :     int m_bNeedTABRewrite;
     252             : 
     253             :     int m_bLastOpWasRead;
     254             :     int m_bLastOpWasWrite;
     255             :     ///////////////
     256             :     // Private Read access specific stuff
     257             :     //
     258             :     int ParseTABFileFirstPass(GBool bTestOpenNoError);
     259             :     int ParseTABFileFields();
     260             : 
     261             :     ///////////////
     262             :     // Private Write access specific stuff
     263             :     //
     264             :     int WriteTABFile();
     265             : 
     266             :   public:
     267             :     explicit TABFile(GDALDataset *poDS);
     268             :     virtual ~TABFile();
     269             : 
     270          61 :     virtual TABFileClass GetFileClass() override
     271             :     {
     272          61 :         return TABFC_TABFile;
     273             :     }
     274             : 
     275           0 :     virtual int Open(const char *pszFname, const char *pszAccess,
     276             :                      GBool bTestOpenNoError = FALSE,
     277             :                      const char *pszCharset = nullptr) override
     278             :     {
     279           0 :         return IMapInfoFile::Open(pszFname, pszAccess, bTestOpenNoError,
     280           0 :                                   pszCharset);
     281             :     }
     282             : 
     283        1301 :     virtual int Open(const char *pszFname, TABAccess eAccess,
     284             :                      GBool bTestOpenNoError = FALSE,
     285             :                      const char *pszCharset = nullptr) override
     286             :     {
     287        1301 :         return Open(pszFname, eAccess, bTestOpenNoError, 512, pszCharset);
     288             :     }
     289             : 
     290             :     virtual int Open(const char *pszFname, TABAccess eAccess,
     291             :                      GBool bTestOpenNoError, int nBlockSizeForCreate,
     292             :                      const char *pszCharset);
     293             : 
     294             :     virtual int Close() override;
     295             : 
     296             :     virtual int
     297             :     SetQuickSpatialIndexMode(GBool bQuickSpatialIndexMode = TRUE) override;
     298             : 
     299           0 :     virtual const char *GetTableName() override
     300             :     {
     301           0 :         return m_poDefn ? m_poDefn->GetName() : "";
     302             :     }
     303             : 
     304             :     virtual void ResetReading() override;
     305             :     virtual int TestCapability(const char *pszCap) override;
     306             :     virtual GIntBig GetFeatureCount(int bForce) override;
     307             :     virtual OGRErr GetExtent(OGREnvelope *psExtent, int bForce) override;
     308             : 
     309          15 :     virtual OGRErr GetExtent(int iGeomField, OGREnvelope *psExtent,
     310             :                              int bForce) override
     311             :     {
     312          15 :         return OGRLayer::GetExtent(iGeomField, psExtent, bForce);
     313             :     }
     314             : 
     315             :     /* Implement OGRLayer's SetFeature() for random write, only with TABFile */
     316             :     virtual OGRErr ISetFeature(OGRFeature *) override;
     317             :     virtual OGRErr DeleteFeature(GIntBig nFeatureId) override;
     318             : 
     319             :     virtual OGRErr DeleteField(int iField) override;
     320             :     virtual OGRErr ReorderFields(int *panMap) override;
     321             :     virtual OGRErr AlterFieldDefn(int iField, OGRFieldDefn *poNewFieldDefn,
     322             :                                   int nFlags) override;
     323             : 
     324             :     virtual OGRErr SyncToDisk() override;
     325             : 
     326             :     virtual CPLErr SetMetadataItem(const char *pszName, const char *pszValue,
     327             :                                    const char *pszDomain = "") override;
     328             : 
     329             :     ///////////////
     330             :     // Read access specific stuff
     331             :     //
     332             : 
     333             :     int GetNextFeatureId_Spatial(int nPrevId);
     334             : 
     335             :     virtual GIntBig GetNextFeatureId(GIntBig nPrevId) override;
     336             :     virtual TABFeature *GetFeatureRef(GIntBig nFeatureId) override;
     337             :     virtual OGRFeatureDefn *GetLayerDefn() override;
     338             : 
     339             :     virtual TABFieldType GetNativeFieldType(int nFieldId) override;
     340             : 
     341             :     virtual int GetBounds(double &dXMin, double &dYMin, double &dXMax,
     342             :                           double &dYMax, GBool bForce = TRUE) override;
     343             : 
     344             :     virtual OGRSpatialReference *GetSpatialRef() override;
     345             : 
     346             :     static OGRSpatialReference *
     347             :     GetSpatialRefFromTABProj(const TABProjInfo &sTABProj);
     348             :     static int GetTABProjFromSpatialRef(const OGRSpatialReference *poSpatialRef,
     349             :                                         TABProjInfo &sTABProj,
     350             :                                         int &nParamCount);
     351             : 
     352             :     virtual int GetFeatureCountByType(int &numPoints, int &numLines,
     353             :                                       int &numRegions, int &numTexts,
     354             :                                       GBool bForce = TRUE) override;
     355             : 
     356             :     virtual GBool IsFieldIndexed(int nFieldId) override;
     357             : 
     358           0 :     virtual GBool IsFieldUnique(int /*nFieldId*/) override
     359             :     {
     360           0 :         return FALSE;
     361             :     }
     362             : 
     363           0 :     virtual int GetVersion()
     364             :     {
     365           0 :         return m_nVersion;
     366             :     }
     367             : 
     368             :     ///////////////
     369             :     // Write access specific stuff
     370             :     //
     371             :     virtual int SetBounds(double dXMin, double dYMin, double dXMax,
     372             :                           double dYMax) override;
     373             :     virtual int
     374             :     SetFeatureDefn(OGRFeatureDefn *poFeatureDefn,
     375             :                    TABFieldType *paeMapInfoNativeFieldTypes = nullptr) override;
     376             :     virtual int AddFieldNative(const char *pszName, TABFieldType eMapInfoType,
     377             :                                int nWidth = 0, int nPrecision = 0,
     378             :                                GBool bIndexed = FALSE, GBool bUnique = FALSE,
     379             :                                int bApproxOK = TRUE) override;
     380             :     virtual int SetSpatialRef(OGRSpatialReference *poSpatialRef) override;
     381             : 
     382             :     virtual OGRErr CreateFeature(TABFeature *poFeature) override;
     383             : 
     384             :     virtual int SetFieldIndexed(int nFieldId) override;
     385             : 
     386             :     ///////////////
     387             :     // semi-private.
     388           0 :     virtual int GetProjInfo(TABProjInfo *poPI) override
     389             :     {
     390           0 :         return m_poMAPFile->GetHeaderBlock()->GetProjInfo(poPI);
     391             :     }
     392             : 
     393             :     virtual int SetProjInfo(TABProjInfo *poPI) override;
     394             :     virtual int SetMIFCoordSys(const char *pszMIFCoordSys) override;
     395             : 
     396             :     int GetFieldIndexNumber(int nFieldId);
     397             :     TABINDFile *GetINDFileRef();
     398             : 
     399             :     TABMAPFile *GetMAPFileRef()
     400             :     {
     401             :         return m_poMAPFile;
     402             :     }
     403             : 
     404             :     int WriteFeature(TABFeature *poFeature);
     405             :     virtual int SetCharset(const char *pszCharset) override;
     406             : #ifdef DEBUG
     407             :     virtual void Dump(FILE *fpOut = nullptr) override;
     408             : #endif
     409             : };
     410             : 
     411             : /*---------------------------------------------------------------------
     412             :  *                      class TABView
     413             :  *
     414             :  * TABView is used to handle special type of .TAB files that are
     415             :  * composed of a number of .TAB datasets linked through some indexed
     416             :  * fields.
     417             :  *
     418             :  * NOTE: The current implementation supports only TABViews composed
     419             :  *       of 2 TABFiles linked through an indexed field of integer type.
     420             :  *       It is unclear if any other type of views could exist anyways.
     421             :  *--------------------------------------------------------------------*/
     422             : class TABView final : public IMapInfoFile
     423             : {
     424             :     CPL_DISALLOW_COPY_ASSIGN(TABView)
     425             : 
     426             :   private:
     427             :     char *m_pszFname;
     428             :     TABAccess m_eAccessMode;
     429             :     char **m_papszTABFile;
     430             :     char *m_pszVersion;
     431             : 
     432             :     char **m_papszTABFnames;
     433             :     TABFile **m_papoTABFiles;
     434             :     int m_numTABFiles;
     435             :     int m_nMainTableIndex;  // The main table is the one that also
     436             :                             // contains the geometries
     437             :     char **m_papszFieldNames;
     438             :     char **m_papszWhereClause;
     439             : 
     440             :     TABRelation *m_poRelation;
     441             :     GBool m_bRelFieldsCreated;
     442             : 
     443             :     ///////////////
     444             :     // Private Read access specific stuff
     445             :     //
     446             :     int ParseTABFile(const char *pszDatasetPath,
     447             :                      GBool bTestOpenNoError = FALSE);
     448             : 
     449             :     int OpenForRead(const char *pszFname, GBool bTestOpenNoError = FALSE);
     450             : 
     451             :     ///////////////
     452             :     // Private Write access specific stuff
     453             :     //
     454             :     int OpenForWrite(const char *pszFname);
     455             :     int WriteTABFile();
     456             : 
     457             :   public:
     458             :     explicit TABView(GDALDataset *poDS);
     459             :     virtual ~TABView();
     460             : 
     461           0 :     virtual TABFileClass GetFileClass() override
     462             :     {
     463           0 :         return TABFC_TABView;
     464             :     }
     465             : 
     466           0 :     virtual int Open(const char *pszFname, const char *pszAccess,
     467             :                      GBool bTestOpenNoError = FALSE,
     468             :                      const char *pszCharset = nullptr) override
     469             :     {
     470           0 :         return IMapInfoFile::Open(pszFname, pszAccess, bTestOpenNoError,
     471           0 :                                   pszCharset);
     472             :     }
     473             : 
     474             :     virtual int Open(const char *pszFname, TABAccess eAccess,
     475             :                      GBool bTestOpenNoError = FALSE,
     476             :                      const char *pszCharset = nullptr) override;
     477             :     virtual int Close() override;
     478             : 
     479             :     virtual int
     480             :     SetQuickSpatialIndexMode(GBool bQuickSpatialIndexMode = TRUE) override;
     481             : 
     482           0 :     virtual const char *GetTableName() override
     483             :     {
     484           0 :         return m_poRelation ? m_poRelation->GetFeatureDefn()->GetName() : "";
     485             :     }
     486             : 
     487             :     virtual void ResetReading() override;
     488             :     virtual int TestCapability(const char *pszCap) override;
     489             :     virtual GIntBig GetFeatureCount(int bForce) override;
     490             :     virtual OGRErr GetExtent(OGREnvelope *psExtent, int bForce) override;
     491             : 
     492           0 :     virtual OGRErr GetExtent(int iGeomField, OGREnvelope *psExtent,
     493             :                              int bForce) override
     494             :     {
     495           0 :         return OGRLayer::GetExtent(iGeomField, psExtent, bForce);
     496             :     }
     497             : 
     498             :     ///////////////
     499             :     // Read access specific stuff
     500             :     //
     501             : 
     502             :     virtual GIntBig GetNextFeatureId(GIntBig nPrevId) override;
     503             :     virtual TABFeature *GetFeatureRef(GIntBig nFeatureId) override;
     504             :     virtual OGRFeatureDefn *GetLayerDefn() override;
     505             : 
     506             :     virtual TABFieldType GetNativeFieldType(int nFieldId) override;
     507             : 
     508             :     virtual int GetBounds(double &dXMin, double &dYMin, double &dXMax,
     509             :                           double &dYMax, GBool bForce = TRUE) override;
     510             : 
     511             :     virtual OGRSpatialReference *GetSpatialRef() override;
     512             : 
     513             :     virtual int GetFeatureCountByType(int &numPoints, int &numLines,
     514             :                                       int &numRegions, int &numTexts,
     515             :                                       GBool bForce = TRUE) override;
     516             : 
     517             :     virtual GBool IsFieldIndexed(int nFieldId) override;
     518             :     virtual GBool IsFieldUnique(int nFieldId) override;
     519             : 
     520             :     ///////////////
     521             :     // Write access specific stuff
     522             :     //
     523             :     virtual int SetBounds(double dXMin, double dYMin, double dXMax,
     524             :                           double dYMax) override;
     525             :     virtual int
     526             :     SetFeatureDefn(OGRFeatureDefn *poFeatureDefn,
     527             :                    TABFieldType *paeMapInfoNativeFieldTypes = nullptr) override;
     528             :     virtual int AddFieldNative(const char *pszName, TABFieldType eMapInfoType,
     529             :                                int nWidth = 0, int nPrecision = 0,
     530             :                                GBool bIndexed = FALSE, GBool bUnique = FALSE,
     531             :                                int bApproxOK = TRUE) override;
     532             :     virtual int SetSpatialRef(OGRSpatialReference *poSpatialRef) override;
     533             : 
     534             :     virtual OGRErr CreateFeature(TABFeature *poFeature) override;
     535             : 
     536             :     virtual int SetFieldIndexed(int nFieldId) override;
     537             : 
     538             :     ///////////////
     539             :     // semi-private.
     540           0 :     virtual int GetProjInfo(TABProjInfo *poPI) override
     541             :     {
     542           0 :         return m_nMainTableIndex != -1
     543           0 :                    ? m_papoTABFiles[m_nMainTableIndex]->GetProjInfo(poPI)
     544           0 :                    : -1;
     545             :     }
     546             : 
     547           0 :     virtual int SetProjInfo(TABProjInfo *poPI) override
     548             :     {
     549           0 :         return m_nMainTableIndex != -1
     550           0 :                    ? m_papoTABFiles[m_nMainTableIndex]->SetProjInfo(poPI)
     551           0 :                    : -1;
     552             :     }
     553             : 
     554           0 :     virtual int SetMIFCoordSys(const char * /*pszMIFCoordSys*/) override
     555             :     {
     556           0 :         return -1;
     557             :     }
     558             : 
     559             :     virtual int SetCharset(const char *pszCharset) override;
     560             : 
     561             : #ifdef DEBUG
     562             :     virtual void Dump(FILE *fpOut = nullptr) override;
     563             : #endif
     564             : };
     565             : 
     566             : /*---------------------------------------------------------------------
     567             :  *                      class TABSeamless
     568             :  *
     569             :  * TABSeamless is used to handle seamless .TAB files that are
     570             :  * composed of a main .TAB file in which each feature is the MBR of
     571             :  * a base table.
     572             :  *
     573             :  * TABSeamless are supported for read access only.
     574             :  *--------------------------------------------------------------------*/
     575             : class TABSeamless final : public IMapInfoFile
     576             : {
     577             :     CPL_DISALLOW_COPY_ASSIGN(TABSeamless)
     578             : 
     579             :   private:
     580             :     char *m_pszFname;
     581             :     char *m_pszPath;
     582             :     TABAccess m_eAccessMode;
     583             :     OGRFeatureDefn *m_poFeatureDefnRef;
     584             : 
     585             :     TABFile *m_poIndexTable;
     586             :     int m_nTableNameField;
     587             :     int m_nCurBaseTableId;
     588             :     TABFile *m_poCurBaseTable;
     589             :     GBool m_bEOF;
     590             : 
     591             :     ///////////////
     592             :     // Private Read access specific stuff
     593             :     //
     594             :     int OpenForRead(const char *pszFname, GBool bTestOpenNoError = FALSE);
     595             :     int OpenBaseTable(TABFeature *poIndexFeature,
     596             :                       GBool bTestOpenNoError = FALSE);
     597             :     int OpenBaseTable(int nTableId, GBool bTestOpenNoError = FALSE);
     598             :     int OpenNextBaseTable(GBool bTestOpenNoError = FALSE);
     599             :     static GIntBig EncodeFeatureId(int nTableId, int nBaseFeatureId);
     600             :     static int ExtractBaseTableId(GIntBig nEncodedFeatureId);
     601             :     static int ExtractBaseFeatureId(GIntBig nEncodedFeatureId);
     602             : 
     603             :   public:
     604             :     explicit TABSeamless(GDALDataset *poDS);
     605             :     virtual ~TABSeamless();
     606             : 
     607           0 :     virtual TABFileClass GetFileClass() override
     608             :     {
     609           0 :         return TABFC_TABSeamless;
     610             :     }
     611             : 
     612           0 :     virtual int Open(const char *pszFname, const char *pszAccess,
     613             :                      GBool bTestOpenNoError = FALSE,
     614             :                      const char *pszCharset = nullptr) override
     615             :     {
     616           0 :         return IMapInfoFile::Open(pszFname, pszAccess, bTestOpenNoError,
     617           0 :                                   pszCharset);
     618             :     }
     619             : 
     620             :     virtual int Open(const char *pszFname, TABAccess eAccess,
     621             :                      GBool bTestOpenNoError = FALSE,
     622             :                      const char *pszCharset = nullptr) override;
     623             :     virtual int Close() override;
     624             : 
     625           0 :     virtual const char *GetTableName() override
     626             :     {
     627           0 :         return m_poFeatureDefnRef ? m_poFeatureDefnRef->GetName() : "";
     628             :     }
     629             : 
     630             :     virtual void SetSpatialFilter(OGRGeometry *) override;
     631             : 
     632           0 :     virtual void SetSpatialFilter(int iGeomField, OGRGeometry *poGeom) override
     633             :     {
     634           0 :         OGRLayer::SetSpatialFilter(iGeomField, poGeom);
     635           0 :     }
     636             : 
     637             :     virtual void ResetReading() override;
     638             :     virtual int TestCapability(const char *pszCap) override;
     639             :     virtual GIntBig GetFeatureCount(int bForce) override;
     640             :     virtual OGRErr GetExtent(OGREnvelope *psExtent, int bForce) override;
     641             : 
     642           0 :     virtual OGRErr GetExtent(int iGeomField, OGREnvelope *psExtent,
     643             :                              int bForce) override
     644             :     {
     645           0 :         return OGRLayer::GetExtent(iGeomField, psExtent, bForce);
     646             :     }
     647             : 
     648             :     ///////////////
     649             :     // Read access specific stuff
     650             :     //
     651             : 
     652             :     virtual GIntBig GetNextFeatureId(GIntBig nPrevId) override;
     653             :     virtual TABFeature *GetFeatureRef(GIntBig nFeatureId) override;
     654             :     virtual OGRFeatureDefn *GetLayerDefn() override;
     655             : 
     656             :     virtual TABFieldType GetNativeFieldType(int nFieldId) override;
     657             : 
     658             :     virtual int GetBounds(double &dXMin, double &dYMin, double &dXMax,
     659             :                           double &dYMax, GBool bForce = TRUE) override;
     660             : 
     661             :     virtual OGRSpatialReference *GetSpatialRef() override;
     662             : 
     663             :     virtual int GetFeatureCountByType(int &numPoints, int &numLines,
     664             :                                       int &numRegions, int &numTexts,
     665             :                                       GBool bForce = TRUE) override;
     666             : 
     667             :     virtual GBool IsFieldIndexed(int nFieldId) override;
     668             :     virtual GBool IsFieldUnique(int nFieldId) override;
     669             : 
     670             :     ///////////////
     671             :     // Write access specific stuff
     672             :     //
     673           0 :     virtual int SetBounds(CPL_UNUSED double dXMin, CPL_UNUSED double dYMin,
     674             :                           CPL_UNUSED double dXMax,
     675             :                           CPL_UNUSED double dYMax) override
     676             :     {
     677           0 :         return -1;
     678             :     }
     679             : 
     680           0 :     virtual int SetFeatureDefn(
     681             :         CPL_UNUSED OGRFeatureDefn *poFeatureDefn,
     682             :         CPL_UNUSED TABFieldType *paeMapInfoNativeFieldTypes = nullptr) override
     683             :     {
     684           0 :         return -1;
     685             :     }
     686             : 
     687           0 :     virtual int AddFieldNative(CPL_UNUSED const char *pszName,
     688             :                                CPL_UNUSED TABFieldType eMapInfoType,
     689             :                                CPL_UNUSED int nWidth = 0,
     690             :                                CPL_UNUSED int nPrecision = 0,
     691             :                                CPL_UNUSED GBool bIndexed = FALSE,
     692             :                                CPL_UNUSED GBool bUnique = FALSE,
     693             :                                CPL_UNUSED int bApproxOK = TRUE) override
     694             :     {
     695           0 :         return -1;
     696             :     }
     697             : 
     698             :     virtual int
     699           0 :     SetSpatialRef(CPL_UNUSED OGRSpatialReference *poSpatialRef) override
     700             :     {
     701           0 :         return -1;
     702             :     }
     703             : 
     704           0 :     virtual OGRErr CreateFeature(CPL_UNUSED TABFeature *poFeature) override
     705             :     {
     706           0 :         return OGRERR_UNSUPPORTED_OPERATION;
     707             :     }
     708             : 
     709           0 :     virtual int SetFieldIndexed(CPL_UNUSED int nFieldId) override
     710             :     {
     711           0 :         return -1;
     712             :     }
     713             : 
     714             :     ///////////////
     715             :     // semi-private.
     716           0 :     virtual int GetProjInfo(TABProjInfo *poPI) override
     717             :     {
     718           0 :         return m_poIndexTable ? m_poIndexTable->GetProjInfo(poPI) : -1;
     719             :     }
     720             : 
     721           0 :     virtual int SetProjInfo(CPL_UNUSED TABProjInfo *poPI) override
     722             :     {
     723           0 :         return -1;
     724             :     }
     725             : 
     726           0 :     virtual int SetMIFCoordSys(const char * /*pszMIFCoordSys*/) override
     727             :     {
     728           0 :         return -1;
     729             :     }
     730             : 
     731             : #ifdef DEBUG
     732             :     virtual void Dump(FILE *fpOut = nullptr) override;
     733             : #endif
     734             : };
     735             : 
     736             : /*---------------------------------------------------------------------
     737             :  *                      class MIFFile
     738             :  *
     739             :  * The main class for (MID/MIF) datasets.  External programs should use this
     740             :  * class to open a (MID/MIF) dataset and read/write features from/to it.
     741             :  *
     742             :  *--------------------------------------------------------------------*/
     743             : class MIFFile final : public IMapInfoFile
     744             : {
     745             :     CPL_DISALLOW_COPY_ASSIGN(MIFFile)
     746             : 
     747             :   private:
     748             :     char *m_pszFname;
     749             :     TABAccess m_eAccessMode;
     750             :     int m_nVersion; /* Dataset version: 300, 450, 600, 900, etc. */
     751             :     char *m_pszDelimiter;
     752             :     char *m_pszUnique;
     753             :     char *m_pszIndex;
     754             :     char *m_pszCoordSys;
     755             : 
     756             :     TABFieldType *m_paeFieldType;
     757             :     GBool *m_pabFieldIndexed;
     758             :     GBool *m_pabFieldUnique;
     759             : 
     760             :     double m_dfXMultiplier;
     761             :     double m_dfYMultiplier;
     762             :     double m_dfXDisplacement;
     763             :     double m_dfYDisplacement;
     764             : 
     765             :     /* these are the projection bounds, possibly much broader than extents */
     766             :     double m_dXMin;
     767             :     double m_dYMin;
     768             :     double m_dXMax;
     769             :     double m_dYMax;
     770             : 
     771             :     /* extents, as cached by MIFFile::PreParseFile() */
     772             :     int m_bExtentsSet;
     773             :     OGREnvelope m_sExtents{};
     774             : 
     775             :     int m_nPoints;
     776             :     int m_nLines;
     777             :     int m_nRegions;
     778             :     int m_nTexts;
     779             : 
     780             :     int m_nPreloadedId;        // preloaded mif line is for this feature id
     781             :     MIDDATAFile *m_poMIDFile;  // Mid file
     782             :     MIDDATAFile *m_poMIFFile;  // Mif File
     783             : 
     784             :     OGRFeatureDefn *m_poDefn;
     785             :     OGRSpatialReference *m_poSpatialRef;
     786             : 
     787             :     int m_nFeatureCount;
     788             :     int m_nWriteFeatureId;
     789             :     int m_nAttribute;
     790             : 
     791             :     ///////////////
     792             :     // Private Read access specific stuff
     793             :     //
     794             :     int ReadFeatureDefn();
     795             :     int ParseMIFHeader(int *pbIsEmpty);
     796             :     void PreParseFile();
     797             :     int AddFields(const char *pszLine);
     798             :     int GotoFeature(int nFeatureId);
     799             : 
     800             :     ///////////////
     801             :     // Private Write access specific stuff
     802             :     //
     803             :     GBool m_bPreParsed;
     804             :     GBool m_bHeaderWrote;
     805             : 
     806             :     int WriteMIFHeader();
     807             :     void UpdateExtents(double dfX, double dfY);
     808             : 
     809             :   public:
     810             :     explicit MIFFile(GDALDataset *poDS);
     811             :     virtual ~MIFFile();
     812             : 
     813          81 :     virtual TABFileClass GetFileClass() override
     814             :     {
     815          81 :         return TABFC_MIFFile;
     816             :     }
     817             : 
     818           0 :     virtual int Open(const char *pszFname, const char *pszAccess,
     819             :                      GBool bTestOpenNoError = FALSE,
     820             :                      const char *pszCharset = nullptr) override
     821             :     {
     822           0 :         return IMapInfoFile::Open(pszFname, pszAccess, bTestOpenNoError,
     823           0 :                                   pszCharset);
     824             :     }
     825             : 
     826             :     virtual int Open(const char *pszFname, TABAccess eAccess,
     827             :                      GBool bTestOpenNoError = FALSE,
     828             :                      const char *pszCharset = nullptr) override;
     829             :     virtual int Close() override;
     830             : 
     831           0 :     virtual const char *GetTableName() override
     832             :     {
     833           0 :         return m_poDefn ? m_poDefn->GetName() : "";
     834             :     }
     835             : 
     836             :     virtual int TestCapability(const char *pszCap) override;
     837             :     virtual GIntBig GetFeatureCount(int bForce) override;
     838             :     virtual void ResetReading() override;
     839             :     virtual OGRErr GetExtent(OGREnvelope *psExtent, int bForce) override;
     840             : 
     841           4 :     virtual OGRErr GetExtent(int iGeomField, OGREnvelope *psExtent,
     842             :                              int bForce) override
     843             :     {
     844           4 :         return OGRLayer::GetExtent(iGeomField, psExtent, bForce);
     845             :     }
     846             : 
     847             :     ///////////////
     848             :     // Read access specific stuff
     849             :     //
     850             : 
     851             :     virtual GIntBig GetNextFeatureId(GIntBig nPrevId) override;
     852             :     virtual TABFeature *GetFeatureRef(GIntBig nFeatureId) override;
     853             :     virtual OGRFeatureDefn *GetLayerDefn() override;
     854             : 
     855             :     virtual TABFieldType GetNativeFieldType(int nFieldId) override;
     856             : 
     857             :     virtual int GetBounds(double &dXMin, double &dYMin, double &dXMax,
     858             :                           double &dYMax, GBool bForce = TRUE) override;
     859             : 
     860             :     virtual OGRSpatialReference *GetSpatialRef() override;
     861             : 
     862             :     virtual int GetFeatureCountByType(int &numPoints, int &numLines,
     863             :                                       int &numRegions, int &numTexts,
     864             :                                       GBool bForce = TRUE) override;
     865             : 
     866             :     virtual GBool IsFieldIndexed(int nFieldId) override;
     867             :     virtual GBool IsFieldUnique(int nFieldId) override;
     868             : 
     869           0 :     virtual int GetVersion()
     870             :     {
     871           0 :         return m_nVersion;
     872             :     }
     873             : 
     874             :     ///////////////
     875             :     // Write access specific stuff
     876             :     //
     877             :     virtual int SetBounds(double dXMin, double dYMin, double dXMax,
     878             :                           double dYMax) override;
     879             :     virtual int
     880             :     SetFeatureDefn(OGRFeatureDefn *poFeatureDefn,
     881             :                    TABFieldType *paeMapInfoNativeFieldTypes = nullptr) override;
     882             :     virtual int AddFieldNative(const char *pszName, TABFieldType eMapInfoType,
     883             :                                int nWidth = 0, int nPrecision = 0,
     884             :                                GBool bIndexed = FALSE, GBool bUnique = FALSE,
     885             :                                int bApproxOK = TRUE) override;
     886             :     /* TODO */
     887             :     virtual int SetSpatialRef(OGRSpatialReference *poSpatialRef) override;
     888             : 
     889             :     virtual OGRErr CreateFeature(TABFeature *poFeature) override;
     890             : 
     891             :     virtual int SetFieldIndexed(int nFieldId) override;
     892             : 
     893             :     ///////////////
     894             :     // semi-private.
     895           0 :     virtual int GetProjInfo(TABProjInfo * /*poPI*/) override
     896             :     {
     897           0 :         return -1;
     898             :     }
     899             : 
     900             :     /*  { return m_poMAPFile->GetHeaderBlock()->GetProjInfo( poPI ); }*/
     901           0 :     virtual int SetProjInfo(TABProjInfo * /*poPI*/) override
     902             :     {
     903           0 :         return -1;
     904             :     }
     905             : 
     906             :     /*  { return m_poMAPFile->GetHeaderBlock()->SetProjInfo( poPI ); }*/
     907             :     virtual int SetMIFCoordSys(const char *pszMIFCoordSys) override;
     908             :     virtual int SetCharset(const char *pszCharset) override;
     909             : 
     910             : #ifdef DEBUG
     911           0 :     virtual void Dump(FILE * /*fpOut*/ = nullptr) override
     912             :     {
     913           0 :     }
     914             : #endif
     915             : };
     916             : 
     917             : /*---------------------------------------------------------------------
     918             :  * Define some error codes specific to this lib.
     919             :  *--------------------------------------------------------------------*/
     920             : #define TAB_WarningFeatureTypeNotSupported 501
     921             : #define TAB_WarningInvalidFieldName 502
     922             : #define TAB_WarningBoundsOverflow 503
     923             : 
     924             : /*---------------------------------------------------------------------
     925             :  * Codes for the feature classes
     926             :  *--------------------------------------------------------------------*/
     927             : typedef enum
     928             : {
     929             :     TABFCNoGeomFeature = 0,
     930             :     TABFCPoint = 1,
     931             :     TABFCFontPoint = 2,
     932             :     TABFCCustomPoint = 3,
     933             :     TABFCText = 4,
     934             :     TABFCPolyline = 5,
     935             :     TABFCArc = 6,
     936             :     TABFCRegion = 7,
     937             :     TABFCRectangle = 8,
     938             :     TABFCEllipse = 9,
     939             :     TABFCMultiPoint = 10,
     940             :     TABFCCollection = 11,
     941             :     TABFCDebugFeature
     942             : } TABFeatureClass;
     943             : 
     944             : /*---------------------------------------------------------------------
     945             :  * Definitions for text attributes
     946             :  *--------------------------------------------------------------------*/
     947             : typedef enum TABTextJust_t
     948             : {
     949             :     TABTJLeft = 0,  // Default: Left Justification
     950             :     TABTJCenter,
     951             :     TABTJRight
     952             : } TABTextJust;
     953             : 
     954             : typedef enum TABTextSpacing_t
     955             : {
     956             :     TABTSSingle = 0,  // Default: Single spacing
     957             :     TABTS1_5,         // 1.5
     958             :     TABTSDouble
     959             : } TABTextSpacing;
     960             : 
     961             : typedef enum TABTextLineType_t
     962             : {
     963             :     TABTLNoLine = 0,  // Default: No line
     964             :     TABTLSimple,
     965             :     TABTLArrow
     966             : } TABTextLineType;
     967             : 
     968             : typedef enum TABFontStyle_t  // Can be OR'ed
     969             : {                            // except box and halo are mutually exclusive
     970             :     TABFSNone = 0,
     971             :     TABFSBold = 0x0001,
     972             :     TABFSItalic = 0x0002,
     973             :     TABFSUnderline = 0x0004,
     974             :     TABFSStrikeout = 0x0008,
     975             :     TABFSOutline = 0x0010,
     976             :     TABFSShadow = 0x0020,
     977             :     TABFSInverse = 0x0040,
     978             :     TABFSBlink = 0x0080,
     979             :     TABFSBox = 0x0100,      // See note about box vs halo below.
     980             :     TABFSHalo = 0x0200,     // MIF uses 256, see MIF docs, App.A
     981             :     TABFSAllCaps = 0x0400,  // MIF uses 512
     982             :     TABFSExpanded = 0x0800  // MIF uses 1024
     983             : } TABFontStyle;
     984             : 
     985             : /* TABFontStyle enum notes:
     986             :  *
     987             :  * The enumeration values above correspond to the values found in a .MAP
     988             :  * file. However, they differ a little from what is found in a MIF file:
     989             :  * Values 0x01 to 0x80 are the same in .MIF and .MAP files.
     990             :  * Values 0x200 to 0x800 in .MAP are 0x100 to 0x400 in .MIF
     991             :  *
     992             :  * What about TABFSBox (0x100) ?
     993             :  * TABFSBox is stored just like the other styles in .MAP files but it is not
     994             :  * explicitly stored in a MIF file.
     995             :  * If a .MIF FONT() clause contains the optional BG color, then this implies
     996             :  * that either Halo or Box was set.  Thus if TABFSHalo (value 256 in MIF)
     997             :  * is not set in the style, then this implies that TABFSBox should be set.
     998             :  */
     999             : 
    1000             : typedef enum TABCustSymbStyle_t  // Can be OR'ed
    1001             : {
    1002             :     TABCSNone = 0,          // Transparent BG, use default colors
    1003             :     TABCSBGOpaque = 0x01,   // White pixels are opaque
    1004             :     TABCSApplyColor = 0x02  // non-white pixels drawn using symbol color
    1005             : } TABCustSymbStyle;
    1006             : 
    1007             : /*=====================================================================
    1008             :   Base classes to be used to add supported drawing tools to each feature type
    1009             :  =====================================================================*/
    1010             : 
    1011             : class ITABFeaturePen
    1012             : {
    1013             :   protected:
    1014             :     int m_nPenDefIndex;
    1015             :     TABPenDef m_sPenDef;
    1016             : 
    1017             :   public:
    1018             :     ITABFeaturePen();
    1019             : 
    1020        7550 :     virtual ~ITABFeaturePen()
    1021        7550 :     {
    1022        7550 :     }
    1023             : 
    1024             :     int GetPenDefIndex() const
    1025             :     {
    1026             :         return m_nPenDefIndex;
    1027             :     }
    1028             : 
    1029           0 :     TABPenDef *GetPenDefRef()
    1030             :     {
    1031           0 :         return &m_sPenDef;
    1032             :     }
    1033             : 
    1034             :     const TABPenDef *GetPenDefRef() const
    1035             :     {
    1036             :         return &m_sPenDef;
    1037             :     }
    1038             : 
    1039             :     GByte GetPenWidthPixel() const;
    1040             :     double GetPenWidthPoint() const;
    1041             :     int GetPenWidthMIF() const;
    1042             : 
    1043         232 :     GByte GetPenPattern() const
    1044             :     {
    1045         232 :         return m_sPenDef.nLinePattern;
    1046             :     }
    1047             : 
    1048          21 :     GInt32 GetPenColor() const
    1049             :     {
    1050          21 :         return m_sPenDef.rgbColor;
    1051             :     }
    1052             : 
    1053             :     void SetPenWidthPixel(GByte val);
    1054             :     void SetPenWidthPoint(double val);
    1055             :     void SetPenWidthMIF(int val);
    1056             : 
    1057        2448 :     void SetPenPattern(GByte val)
    1058             :     {
    1059        2448 :         m_sPenDef.nLinePattern = val;
    1060        2448 :     }
    1061             : 
    1062        2449 :     void SetPenColor(GInt32 clr)
    1063             :     {
    1064        2449 :         m_sPenDef.rgbColor = clr;
    1065        2449 :     }
    1066             : 
    1067             :     const char *GetPenStyleString() const;
    1068             :     void SetPenFromStyleString(const char *pszStyleString);
    1069             : 
    1070             :     void DumpPenDef(FILE *fpOut = nullptr);
    1071             : };
    1072             : 
    1073             : class ITABFeatureBrush
    1074             : {
    1075             :   protected:
    1076             :     int m_nBrushDefIndex;
    1077             :     TABBrushDef m_sBrushDef;
    1078             : 
    1079             :   public:
    1080             :     ITABFeatureBrush();
    1081             : 
    1082        2504 :     virtual ~ITABFeatureBrush()
    1083        2504 :     {
    1084        2504 :     }
    1085             : 
    1086             :     int GetBrushDefIndex() const
    1087             :     {
    1088             :         return m_nBrushDefIndex;
    1089             :     }
    1090             : 
    1091           0 :     TABBrushDef *GetBrushDefRef()
    1092             :     {
    1093           0 :         return &m_sBrushDef;
    1094             :     }
    1095             : 
    1096             :     const TABBrushDef *GetBrushDefRef() const
    1097             :     {
    1098             :         return &m_sBrushDef;
    1099             :     }
    1100             : 
    1101          21 :     GInt32 GetBrushFGColor() const
    1102             :     {
    1103          21 :         return m_sBrushDef.rgbFGColor;
    1104             :     }
    1105             : 
    1106          21 :     GInt32 GetBrushBGColor() const
    1107             :     {
    1108          21 :         return m_sBrushDef.rgbBGColor;
    1109             :     }
    1110             : 
    1111          42 :     GByte GetBrushPattern() const
    1112             :     {
    1113          42 :         return m_sBrushDef.nFillPattern;
    1114             :     }
    1115             : 
    1116          71 :     GByte GetBrushTransparent() const
    1117             :     {
    1118          71 :         return m_sBrushDef.bTransparentFill;
    1119             :     }
    1120             : 
    1121        1561 :     void SetBrushFGColor(GInt32 clr)
    1122             :     {
    1123        1561 :         m_sBrushDef.rgbFGColor = clr;
    1124        1561 :     }
    1125             : 
    1126        1553 :     void SetBrushBGColor(GInt32 clr)
    1127             :     {
    1128        1553 :         m_sBrushDef.rgbBGColor = clr;
    1129        1553 :     }
    1130             : 
    1131        1561 :     void SetBrushPattern(GByte val)
    1132             :     {
    1133        1561 :         m_sBrushDef.nFillPattern = val;
    1134        1561 :     }
    1135             : 
    1136           8 :     void SetBrushTransparent(GByte val)
    1137             :     {
    1138           8 :         m_sBrushDef.bTransparentFill = val;
    1139           8 :     }
    1140             : 
    1141             :     const char *GetBrushStyleString() const;
    1142             :     void SetBrushFromStyleString(const char *pszStyleString);
    1143             : 
    1144             :     void DumpBrushDef(FILE *fpOut = nullptr);
    1145             : };
    1146             : 
    1147             : class ITABFeatureFont
    1148             : {
    1149             :   protected:
    1150             :     int m_nFontDefIndex;
    1151             :     TABFontDef m_sFontDef;
    1152             : 
    1153             :   public:
    1154             :     ITABFeatureFont();
    1155             : 
    1156        1638 :     virtual ~ITABFeatureFont()
    1157        1638 :     {
    1158        1638 :     }
    1159             : 
    1160             :     int GetFontDefIndex() const
    1161             :     {
    1162             :         return m_nFontDefIndex;
    1163             :     }
    1164             : 
    1165           0 :     TABFontDef *GetFontDefRef()
    1166             :     {
    1167           0 :         return &m_sFontDef;
    1168             :     }
    1169             : 
    1170             :     const TABFontDef *GetFontDefRef() const
    1171             :     {
    1172             :         return &m_sFontDef;
    1173             :     }
    1174             : 
    1175          38 :     const char *GetFontNameRef() const
    1176             :     {
    1177          38 :         return m_sFontDef.szFontName;
    1178             :     }
    1179             : 
    1180             :     void SetFontName(const char *pszName);
    1181             : 
    1182             :     void DumpFontDef(FILE *fpOut = nullptr);
    1183             : };
    1184             : 
    1185             : class ITABFeatureSymbol
    1186             : {
    1187             :   protected:
    1188             :     int m_nSymbolDefIndex;
    1189             :     TABSymbolDef m_sSymbolDef;
    1190             : 
    1191             :   public:
    1192             :     ITABFeatureSymbol();
    1193             : 
    1194      531864 :     virtual ~ITABFeatureSymbol()
    1195      531864 :     {
    1196      531864 :     }
    1197             : 
    1198             :     int GetSymbolDefIndex() const
    1199             :     {
    1200             :         return m_nSymbolDefIndex;
    1201             :     }
    1202             : 
    1203           4 :     TABSymbolDef *GetSymbolDefRef()
    1204             :     {
    1205           4 :         return &m_sSymbolDef;
    1206             :     }
    1207             : 
    1208             :     const TABSymbolDef *GetSymbolDefRef() const
    1209             :     {
    1210             :         return &m_sSymbolDef;
    1211             :     }
    1212             : 
    1213          79 :     GInt16 GetSymbolNo() const
    1214             :     {
    1215          79 :         return m_sSymbolDef.nSymbolNo;
    1216             :     }
    1217             : 
    1218          79 :     GInt16 GetSymbolSize() const
    1219             :     {
    1220          79 :         return m_sSymbolDef.nPointSize;
    1221             :     }
    1222             : 
    1223          79 :     GInt32 GetSymbolColor() const
    1224             :     {
    1225          79 :         return m_sSymbolDef.rgbColor;
    1226             :     }
    1227             : 
    1228         767 :     void SetSymbolNo(GInt16 val)
    1229             :     {
    1230         767 :         m_sSymbolDef.nSymbolNo = val;
    1231         767 :     }
    1232             : 
    1233        1447 :     void SetSymbolSize(GInt16 val)
    1234             :     {
    1235        1447 :         m_sSymbolDef.nPointSize = val;
    1236        1447 :     }
    1237             : 
    1238        1447 :     void SetSymbolColor(GInt32 clr)
    1239             :     {
    1240        1447 :         m_sSymbolDef.rgbColor = clr;
    1241        1447 :     }
    1242             : 
    1243             :     static TABFeatureClass GetSymbolFeatureClass(const char *pszStyleString);
    1244             :     virtual const char *GetSymbolStyleString(double dfAngle = 0.0) const;
    1245             :     void SetSymbolFromStyleString(const char *pszStyleString);
    1246             :     virtual void SetSymbolFromStyle(OGRStyleSymbol *poSymbolStyle);
    1247             : 
    1248             :     void DumpSymbolDef(FILE *fpOut = nullptr);
    1249             : };
    1250             : 
    1251             : /*=====================================================================
    1252             :                         Feature Classes
    1253             :  =====================================================================*/
    1254             : 
    1255             : /*---------------------------------------------------------------------
    1256             :  *                      class TABFeature
    1257             :  *
    1258             :  * Extend the OGRFeature to support MapInfo specific extensions related
    1259             :  * to geometry types, representation strings, etc.
    1260             :  *
    1261             :  * TABFeature will be used as a base class for all the feature classes.
    1262             :  *
    1263             :  * This class will also be used to instantiate objects with no Geometry
    1264             :  * (i.e. type TAB_GEOM_NONE) which is a valid case in MapInfo.
    1265             :  *
    1266             :  * The logic to read/write the object from/to the .DAT and .MAP files is also
    1267             :  * implemented as part of this class and derived classes.
    1268             :  *--------------------------------------------------------------------*/
    1269             : class TABFeature : public OGRFeature
    1270             : {
    1271             :   protected:
    1272             :     TABGeomType m_nMapInfoType;
    1273             : 
    1274             :     double m_dXMin;
    1275             :     double m_dYMin;
    1276             :     double m_dXMax;
    1277             :     double m_dYMax;
    1278             : 
    1279             :     GBool m_bDeletedFlag;
    1280             : 
    1281             :     void CopyTABFeatureBase(TABFeature *poDestFeature);
    1282             : 
    1283             :     // Compr. Origin is set for TAB files by ValidateCoordType()
    1284             :     GInt32 m_nXMin;
    1285             :     GInt32 m_nYMin;
    1286             :     GInt32 m_nXMax;
    1287             :     GInt32 m_nYMax;
    1288             :     GInt32 m_nComprOrgX;
    1289             :     GInt32 m_nComprOrgY;
    1290             : 
    1291             :     virtual int UpdateMBR(TABMAPFile *poMapFile = nullptr);
    1292             : 
    1293             :   public:
    1294             :     explicit TABFeature(OGRFeatureDefn *poDefnIn);
    1295             :     virtual ~TABFeature();
    1296             : 
    1297             :     static TABFeature *CreateFromMapInfoType(int nMapInfoType,
    1298             :                                              OGRFeatureDefn *poDefn);
    1299             : 
    1300             :     virtual TABFeature *CloneTABFeature(OGRFeatureDefn *pNewDefn = nullptr);
    1301             : 
    1302          74 :     virtual TABFeatureClass GetFeatureClass()
    1303             :     {
    1304          74 :         return TABFCNoGeomFeature;
    1305             :     }
    1306             : 
    1307           0 :     virtual TABGeomType GetMapInfoType()
    1308             :     {
    1309           0 :         return m_nMapInfoType;
    1310             :     }
    1311             : 
    1312             :     virtual TABGeomType
    1313          57 :     ValidateMapInfoType(CPL_UNUSED TABMAPFile *poMapFile = nullptr)
    1314             :     {
    1315          57 :         m_nMapInfoType = TAB_GEOM_NONE;
    1316          57 :         return m_nMapInfoType;
    1317             :     }
    1318             : 
    1319             :     GBool IsRecordDeleted()
    1320             :     {
    1321             :         return m_bDeletedFlag;
    1322             :     }
    1323             : 
    1324      516678 :     void SetRecordDeleted(GBool bDeleted)
    1325             :     {
    1326      516678 :         m_bDeletedFlag = bDeleted;
    1327      516678 :     }
    1328             : 
    1329             :     /*-----------------------------------------------------------------
    1330             :      * TAB Support
    1331             :      *----------------------------------------------------------------*/
    1332             : 
    1333             :     virtual int ReadRecordFromDATFile(TABDATFile *poDATFile);
    1334             :     virtual int
    1335             :     ReadGeometryFromMAPFile(TABMAPFile *poMapFile, TABMAPObjHdr *,
    1336             :                             GBool bCoordDataOnly = FALSE,
    1337             :                             TABMAPCoordBlock **ppoCoordBlock = nullptr);
    1338             : 
    1339             :     virtual int WriteRecordToDATFile(TABDATFile *poDATFile,
    1340             :                                      TABINDFile *poINDFile, int *panIndexNo);
    1341             :     virtual int
    1342             :     WriteGeometryToMAPFile(TABMAPFile *poMapFile, TABMAPObjHdr *,
    1343             :                            GBool bCoordDataOnly = FALSE,
    1344             :                            TABMAPCoordBlock **ppoCoordBlock = nullptr);
    1345             :     GBool ValidateCoordType(TABMAPFile *poMapFile);
    1346             :     void ForceCoordTypeAndOrigin(TABGeomType nMapInfoType, GBool bCompr,
    1347             :                                  GInt32 nComprOrgX, GInt32 nComprOrgY,
    1348             :                                  GInt32 nXMin, GInt32 nYMin, GInt32 nXMax,
    1349             :                                  GInt32 nYMax);
    1350             : 
    1351             :     /*-----------------------------------------------------------------
    1352             :      * Mid/Mif Support
    1353             :      *----------------------------------------------------------------*/
    1354             : 
    1355             :     virtual int ReadRecordFromMIDFile(MIDDATAFile *fp);
    1356             :     virtual int ReadGeometryFromMIFFile(MIDDATAFile *fp);
    1357             : 
    1358             :     virtual int WriteRecordToMIDFile(MIDDATAFile *fp);
    1359             :     virtual int WriteGeometryToMIFFile(MIDDATAFile *fp);
    1360             : 
    1361             :     void ReadMIFParameters(MIDDATAFile *fp);
    1362             :     void WriteMIFParameters(MIDDATAFile *fp);
    1363             : 
    1364             :     /*-----------------------------------------------------------------
    1365             :      *----------------------------------------------------------------*/
    1366             : 
    1367             :     void SetMBR(double dXMin, double dYMin, double dXMax, double dYMax);
    1368             :     void GetMBR(double &dXMin, double &dYMin, double &dXMax, double &dYMax);
    1369             :     void SetIntMBR(GInt32 nXMin, GInt32 nYMin, GInt32 nXMax, GInt32 nYMax);
    1370             :     void GetIntMBR(GInt32 &nXMin, GInt32 &nYMin, GInt32 &nXMax, GInt32 &nYMax);
    1371             : 
    1372             :     virtual void DumpMID(FILE *fpOut = nullptr);
    1373             :     virtual void DumpMIF(FILE *fpOut = nullptr);
    1374             : };
    1375             : 
    1376             : /*---------------------------------------------------------------------
    1377             :  *                      class TABPoint
    1378             :  *
    1379             :  * Feature class to handle old style MapInfo point symbols:
    1380             :  *
    1381             :  *     TAB_GEOM_SYMBOL_C        0x01
    1382             :  *     TAB_GEOM_SYMBOL          0x02
    1383             :  *
    1384             :  * Feature geometry will be a OGRPoint
    1385             :  *
    1386             :  * The symbol number is in the range [31..67], with 31=None and corresponds
    1387             :  * to one of the 35 predefined "Old MapInfo Symbols"
    1388             :  *
    1389             :  * NOTE: This class is also used as a base class for the other point
    1390             :  * symbol types TABFontPoint and TABCustomPoint.
    1391             :  *--------------------------------------------------------------------*/
    1392             : class TABPoint : public TABFeature, public ITABFeatureSymbol
    1393             : {
    1394             :     CPL_DISALLOW_COPY_ASSIGN(TABPoint)
    1395             : 
    1396             :   public:
    1397             :     explicit TABPoint(OGRFeatureDefn *poDefnIn);
    1398             :     virtual ~TABPoint();
    1399             : 
    1400       15433 :     virtual TABFeatureClass GetFeatureClass() override
    1401             :     {
    1402       15433 :         return TABFCPoint;
    1403             :     }
    1404             : 
    1405             :     virtual TABGeomType
    1406             :     ValidateMapInfoType(TABMAPFile *poMapFile = nullptr) override;
    1407             : 
    1408             :     virtual TABFeature *
    1409             :     CloneTABFeature(OGRFeatureDefn *poNewDefn = nullptr) override;
    1410             : 
    1411             :     double GetX();
    1412             :     double GetY();
    1413             : 
    1414             :     virtual int ReadGeometryFromMAPFile(
    1415             :         TABMAPFile *poMapFile, TABMAPObjHdr *, GBool bCoordDataOnly = FALSE,
    1416             :         TABMAPCoordBlock **ppoCoordBlock = nullptr) override;
    1417             :     virtual int
    1418             :     WriteGeometryToMAPFile(TABMAPFile *poMapFile, TABMAPObjHdr *,
    1419             :                            GBool bCoordDataOnly = FALSE,
    1420             :                            TABMAPCoordBlock **ppoCoordBlock = nullptr) override;
    1421             : 
    1422             :     virtual int ReadGeometryFromMIFFile(MIDDATAFile *fp) override;
    1423             :     virtual int WriteGeometryToMIFFile(MIDDATAFile *fp) override;
    1424             : 
    1425             :     virtual const char *GetStyleString() const override;
    1426             : 
    1427             :     virtual void DumpMIF(FILE *fpOut = nullptr) override;
    1428             : };
    1429             : 
    1430             : /*---------------------------------------------------------------------
    1431             :  *                      class TABFontPoint
    1432             :  *
    1433             :  * Feature class to handle MapInfo Font Point Symbol types:
    1434             :  *
    1435             :  *     TAB_GEOM_FONTSYMBOL_C    0x28
    1436             :  *     TAB_GEOM_FONTSYMBOL      0x29
    1437             :  *
    1438             :  * Feature geometry will be a OGRPoint
    1439             :  *
    1440             :  * The symbol number refers to a character code in the specified Windows
    1441             :  * Font (e.g. "Windings").
    1442             :  *--------------------------------------------------------------------*/
    1443             : class TABFontPoint final : public TABPoint, public ITABFeatureFont
    1444             : {
    1445             :     CPL_DISALLOW_COPY_ASSIGN(TABFontPoint)
    1446             : 
    1447             :   protected:
    1448             :     double m_dAngle;
    1449             :     GInt16 m_nFontStyle;  // Bold/shadow/halo/etc.
    1450             : 
    1451             :   public:
    1452             :     explicit TABFontPoint(OGRFeatureDefn *poDefnIn);
    1453             :     virtual ~TABFontPoint();
    1454             : 
    1455         637 :     virtual TABFeatureClass GetFeatureClass() override
    1456             :     {
    1457         637 :         return TABFCFontPoint;
    1458             :     }
    1459             : 
    1460             :     virtual TABFeature *
    1461             :     CloneTABFeature(OGRFeatureDefn *poNewDefn = nullptr) override;
    1462             : 
    1463             :     virtual int ReadGeometryFromMAPFile(
    1464             :         TABMAPFile *poMapFile, TABMAPObjHdr *, GBool bCoordDataOnly = FALSE,
    1465             :         TABMAPCoordBlock **ppoCoordBlock = nullptr) override;
    1466             :     virtual int
    1467             :     WriteGeometryToMAPFile(TABMAPFile *poMapFile, TABMAPObjHdr *,
    1468             :                            GBool bCoordDataOnly = FALSE,
    1469             :                            TABMAPCoordBlock **ppoCoordBlock = nullptr) override;
    1470             : 
    1471             :     virtual int ReadGeometryFromMIFFile(MIDDATAFile *fp) override;
    1472             :     virtual int WriteGeometryToMIFFile(MIDDATAFile *fp) override;
    1473             : 
    1474             :     virtual const char *
    1475             :     GetSymbolStyleString(double dfAngle = 0.0) const override;
    1476             :     virtual const char *GetStyleString() const override;
    1477             :     virtual void SetSymbolFromStyle(OGRStyleSymbol *poSymbolStyle) override;
    1478             : 
    1479             :     GBool QueryFontStyle(TABFontStyle eStyleToQuery);
    1480             :     void ToggleFontStyle(TABFontStyle eStyleToToggle, GBool bStatus);
    1481             : 
    1482             :     int GetFontStyleMIFValue();
    1483             :     void SetFontStyleMIFValue(int nStyle);
    1484             : 
    1485           0 :     int GetFontStyleTABValue()
    1486             :     {
    1487           0 :         return m_nFontStyle;
    1488             :     }
    1489             : 
    1490           0 :     void SetFontStyleTABValue(int nStyle)
    1491             :     {
    1492           0 :         m_nFontStyle = static_cast<GInt16>(nStyle);
    1493           0 :     }
    1494             : 
    1495             :     // GetSymbolAngle(): Return angle in degrees counterclockwise
    1496           7 :     double GetSymbolAngle() const
    1497             :     {
    1498           7 :         return m_dAngle;
    1499             :     }
    1500             : 
    1501             :     void SetSymbolAngle(double dAngle);
    1502             : };
    1503             : 
    1504             : /*---------------------------------------------------------------------
    1505             :  *                      class TABCustomPoint
    1506             :  *
    1507             :  * Feature class to handle MapInfo Custom Point Symbol (Bitmap) types:
    1508             :  *
    1509             :  *     TAB_GEOM_CUSTOMSYMBOL_C  0x2b
    1510             :  *     TAB_GEOM_CUSTOMSYMBOL    0x2c
    1511             :  *
    1512             :  * Feature geometry will be a OGRPoint
    1513             :  *
    1514             :  * The symbol name is the name of a BMP file stored in the "CustSymb"
    1515             :  * directory (e.g. "arrow.BMP").  The symbol number has no meaning for
    1516             :  * this symbol type.
    1517             :  *--------------------------------------------------------------------*/
    1518             : class TABCustomPoint final : public TABPoint, public ITABFeatureFont
    1519             : {
    1520             :   protected:
    1521             :     GByte m_nCustomStyle;  // Show BG/Apply Color
    1522             : 
    1523             :   public:
    1524             :     GByte m_nUnknown_;
    1525             : 
    1526             :   public:
    1527             :     explicit TABCustomPoint(OGRFeatureDefn *poDefnIn);
    1528             :     virtual ~TABCustomPoint();
    1529             : 
    1530         680 :     virtual TABFeatureClass GetFeatureClass() override
    1531             :     {
    1532         680 :         return TABFCCustomPoint;
    1533             :     }
    1534             : 
    1535             :     virtual TABFeature *
    1536             :     CloneTABFeature(OGRFeatureDefn *poNewDefn = nullptr) override;
    1537             : 
    1538             :     virtual int ReadGeometryFromMAPFile(
    1539             :         TABMAPFile *poMapFile, TABMAPObjHdr *, GBool bCoordDataOnly = FALSE,
    1540             :         TABMAPCoordBlock **ppoCoordBlock = nullptr) override;
    1541             :     virtual int
    1542             :     WriteGeometryToMAPFile(TABMAPFile *poMapFile, TABMAPObjHdr *,
    1543             :                            GBool bCoordDataOnly = FALSE,
    1544             :                            TABMAPCoordBlock **ppoCoordBlock = nullptr) override;
    1545             : 
    1546             :     virtual int ReadGeometryFromMIFFile(MIDDATAFile *fp) override;
    1547             :     virtual int WriteGeometryToMIFFile(MIDDATAFile *fp) override;
    1548             : 
    1549             :     virtual const char *
    1550             :     GetSymbolStyleString(double dfAngle = 0.0) const override;
    1551             :     virtual const char *GetStyleString() const override;
    1552             :     virtual void SetSymbolFromStyle(OGRStyleSymbol *poSymbolStyle) override;
    1553             : 
    1554          21 :     const char *GetSymbolNameRef() const
    1555             :     {
    1556          21 :         return GetFontNameRef();
    1557             :     }
    1558             : 
    1559           2 :     void SetSymbolName(const char *pszName)
    1560             :     {
    1561           2 :         SetFontName(pszName);
    1562           2 :     }
    1563             : 
    1564           0 :     GByte GetCustomSymbolStyle()
    1565             :     {
    1566           0 :         return m_nCustomStyle;
    1567             :     }
    1568             : 
    1569           2 :     void SetCustomSymbolStyle(GByte nStyle)
    1570             :     {
    1571           2 :         m_nCustomStyle = nStyle;
    1572           2 :     }
    1573             : };
    1574             : 
    1575             : /*---------------------------------------------------------------------
    1576             :  *                      class TABPolyline
    1577             :  *
    1578             :  * Feature class to handle the various MapInfo line types:
    1579             :  *
    1580             :  *     TAB_GEOM_LINE_C         0x04
    1581             :  *     TAB_GEOM_LINE           0x05
    1582             :  *     TAB_GEOM_PLINE_C        0x07
    1583             :  *     TAB_GEOM_PLINE          0x08
    1584             :  *     TAB_GEOM_MULTIPLINE_C   0x25
    1585             :  *     TAB_GEOM_MULTIPLINE     0x26
    1586             :  *     TAB_GEOM_V450_MULTIPLINE_C 0x31
    1587             :  *     TAB_GEOM_V450_MULTIPLINE   0x32
    1588             :  *
    1589             :  * Feature geometry can be either a OGRLineString or a OGRMultiLineString
    1590             :  *--------------------------------------------------------------------*/
    1591             : class TABPolyline final : public TABFeature, public ITABFeaturePen
    1592             : {
    1593             :   private:
    1594             :     GBool m_bCenterIsSet;
    1595             :     double m_dCenterX;
    1596             :     double m_dCenterY;
    1597             :     GBool m_bWriteTwoPointLineAsPolyline;
    1598             : 
    1599             :   public:
    1600             :     explicit TABPolyline(OGRFeatureDefn *poDefnIn);
    1601             :     virtual ~TABPolyline();
    1602             : 
    1603        2310 :     virtual TABFeatureClass GetFeatureClass() override
    1604             :     {
    1605        2310 :         return TABFCPolyline;
    1606             :     }
    1607             : 
    1608             :     virtual TABGeomType
    1609             :     ValidateMapInfoType(TABMAPFile *poMapFile = nullptr) override;
    1610             : 
    1611             :     virtual TABFeature *
    1612             :     CloneTABFeature(OGRFeatureDefn *poNewDefn = nullptr) override;
    1613             : 
    1614             :     /* 2 methods to simplify access to rings in a multiple polyline
    1615             :      */
    1616             :     int GetNumParts();
    1617             :     OGRLineString *GetPartRef(int nPartIndex);
    1618             : 
    1619             :     GBool TwoPointLineAsPolyline();
    1620             :     void TwoPointLineAsPolyline(GBool bTwoPointLineAsPolyline);
    1621             : 
    1622             :     virtual int ReadGeometryFromMAPFile(
    1623             :         TABMAPFile *poMapFile, TABMAPObjHdr *, GBool bCoordDataOnly = FALSE,
    1624             :         TABMAPCoordBlock **ppoCoordBlock = nullptr) override;
    1625             :     virtual int
    1626             :     WriteGeometryToMAPFile(TABMAPFile *poMapFile, TABMAPObjHdr *,
    1627             :                            GBool bCoordDataOnly = FALSE,
    1628             :                            TABMAPCoordBlock **ppoCoordBlock = nullptr) override;
    1629             : 
    1630             :     virtual int ReadGeometryFromMIFFile(MIDDATAFile *fp) override;
    1631             :     virtual int WriteGeometryToMIFFile(MIDDATAFile *fp) override;
    1632             : 
    1633             :     virtual const char *GetStyleString() const override;
    1634             : 
    1635             :     virtual void DumpMIF(FILE *fpOut = nullptr) override;
    1636             : 
    1637             :     int GetCenter(double &dX, double &dY);
    1638             :     void SetCenter(double dX, double dY);
    1639             : 
    1640             :     // MapInfo-specific attributes... made available through public vars
    1641             :     // for now.
    1642             :     GBool m_bSmooth;
    1643             : };
    1644             : 
    1645             : /*---------------------------------------------------------------------
    1646             :  *                      class TABRegion
    1647             :  *
    1648             :  * Feature class to handle the MapInfo region types:
    1649             :  *
    1650             :  *     TAB_GEOM_REGION_C         0x0d
    1651             :  *     TAB_GEOM_REGION           0x0e
    1652             :  *     TAB_GEOM_V450_REGION_C    0x2e
    1653             :  *     TAB_GEOM_V450_REGION      0x2f
    1654             :  *
    1655             :  * Feature geometry will be returned as OGRPolygon (with a single ring)
    1656             :  * or OGRMultiPolygon (for multiple rings).
    1657             :  *
    1658             :  * REGIONs with multiple rings are returned as OGRMultiPolygon instead of
    1659             :  * as OGRPolygons since OGRPolygons require that the first ring be the
    1660             :  * outer ring, and the other all be inner rings, but this is not guaranteed
    1661             :  * inside MapInfo files.  However, when writing features, OGRPolygons with
    1662             :  * multiple rings will be accepted without problem.
    1663             :  *--------------------------------------------------------------------*/
    1664             : class TABRegion final : public TABFeature,
    1665             :                         public ITABFeaturePen,
    1666             :                         public ITABFeatureBrush
    1667             : {
    1668             :   private:
    1669             :     GBool m_bSmooth;
    1670             :     GBool m_bCenterIsSet;
    1671             :     double m_dCenterX;
    1672             :     double m_dCenterY;
    1673             : 
    1674             :     int ComputeNumRings(TABMAPCoordSecHdr **ppasSecHdrs, TABMAPFile *poMAPFile);
    1675             :     static int AppendSecHdrs(OGRPolygon *poPolygon,
    1676             :                              TABMAPCoordSecHdr *&pasSecHdrs,
    1677             :                              TABMAPFile *poMAPFile, int &iLastRing);
    1678             : 
    1679             :   public:
    1680             :     explicit TABRegion(OGRFeatureDefn *poDefnIn);
    1681             :     virtual ~TABRegion();
    1682             : 
    1683         426 :     virtual TABFeatureClass GetFeatureClass() override
    1684             :     {
    1685         426 :         return TABFCRegion;
    1686             :     }
    1687             : 
    1688             :     virtual TABGeomType
    1689             :     ValidateMapInfoType(TABMAPFile *poMapFile = nullptr) override;
    1690             : 
    1691             :     virtual TABFeature *
    1692             :     CloneTABFeature(OGRFeatureDefn *poNewDefn = nullptr) override;
    1693             : 
    1694             :     /* 2 methods to make the REGION's geometry look like a single collection
    1695             :      * of OGRLinearRings
    1696             :      */
    1697             :     int GetNumRings();
    1698             :     OGRLinearRing *GetRingRef(int nRequestedRingIndex);
    1699             :     GBool IsInteriorRing(int nRequestedRingIndex);
    1700             : 
    1701             :     virtual int ReadGeometryFromMAPFile(
    1702             :         TABMAPFile *poMapFile, TABMAPObjHdr *, GBool bCoordDataOnly = FALSE,
    1703             :         TABMAPCoordBlock **ppoCoordBlock = nullptr) override;
    1704             :     virtual int
    1705             :     WriteGeometryToMAPFile(TABMAPFile *poMapFile, TABMAPObjHdr *,
    1706             :                            GBool bCoordDataOnly = FALSE,
    1707             :                            TABMAPCoordBlock **ppoCoordBlock = nullptr) override;
    1708             : 
    1709             :     virtual int ReadGeometryFromMIFFile(MIDDATAFile *fp) override;
    1710             :     virtual int WriteGeometryToMIFFile(MIDDATAFile *fp) override;
    1711             : 
    1712             :     virtual const char *GetStyleString() const override;
    1713             : 
    1714             :     virtual void DumpMIF(FILE *fpOut = nullptr) override;
    1715             : 
    1716             :     int GetCenter(double &dX, double &dY);
    1717             :     void SetCenter(double dX, double dY);
    1718             : };
    1719             : 
    1720             : /*---------------------------------------------------------------------
    1721             :  *                      class TABRectangle
    1722             :  *
    1723             :  * Feature class to handle the MapInfo rectangle types:
    1724             :  *
    1725             :  *     TAB_GEOM_RECT_C         0x13
    1726             :  *     TAB_GEOM_RECT           0x14
    1727             :  *     TAB_GEOM_ROUNDRECT_C    0x16
    1728             :  *     TAB_GEOM_ROUNDRECT      0x17
    1729             :  *
    1730             :  * A rectangle is defined by the coords of its 2 opposite corners (the MBR)
    1731             :  * Its corners can optionally be rounded, in which case a X and Y rounding
    1732             :  * radius will be defined.
    1733             :  *
    1734             :  * Feature geometry will be OGRPolygon
    1735             :  *--------------------------------------------------------------------*/
    1736             : class TABRectangle final : public TABFeature,
    1737             :                            public ITABFeaturePen,
    1738             :                            public ITABFeatureBrush
    1739             : {
    1740             :   private:
    1741             :     virtual int UpdateMBR(TABMAPFile *poMapFile = nullptr) override;
    1742             : 
    1743             :   public:
    1744             :     explicit TABRectangle(OGRFeatureDefn *poDefnIn);
    1745             :     virtual ~TABRectangle();
    1746             : 
    1747         921 :     virtual TABFeatureClass GetFeatureClass() override
    1748             :     {
    1749         921 :         return TABFCRectangle;
    1750             :     }
    1751             : 
    1752             :     virtual TABGeomType
    1753             :     ValidateMapInfoType(TABMAPFile *poMapFile = nullptr) override;
    1754             : 
    1755             :     virtual TABFeature *
    1756             :     CloneTABFeature(OGRFeatureDefn *poNewDefn = nullptr) override;
    1757             : 
    1758             :     virtual int ReadGeometryFromMAPFile(
    1759             :         TABMAPFile *poMapFile, TABMAPObjHdr *, GBool bCoordDataOnly = FALSE,
    1760             :         TABMAPCoordBlock **ppoCoordBlock = nullptr) override;
    1761             :     virtual int
    1762             :     WriteGeometryToMAPFile(TABMAPFile *poMapFile, TABMAPObjHdr *,
    1763             :                            GBool bCoordDataOnly = FALSE,
    1764             :                            TABMAPCoordBlock **ppoCoordBlock = nullptr) override;
    1765             : 
    1766             :     virtual int ReadGeometryFromMIFFile(MIDDATAFile *fp) override;
    1767             :     virtual int WriteGeometryToMIFFile(MIDDATAFile *fp) override;
    1768             : 
    1769             :     virtual const char *GetStyleString() const override;
    1770             : 
    1771             :     virtual void DumpMIF(FILE *fpOut = nullptr) override;
    1772             : 
    1773             :     // MapInfo-specific attributes... made available through public vars
    1774             :     // for now.
    1775             :     GBool m_bRoundCorners;
    1776             :     double m_dRoundXRadius;
    1777             :     double m_dRoundYRadius;
    1778             : };
    1779             : 
    1780             : /*---------------------------------------------------------------------
    1781             :  *                      class TABEllipse
    1782             :  *
    1783             :  * Feature class to handle the MapInfo ellipse types:
    1784             :  *
    1785             :  *     TAB_GEOM_ELLIPSE_C      0x19
    1786             :  *     TAB_GEOM_ELLIPSE        0x1a
    1787             :  *
    1788             :  * An ellipse is defined by the coords of its 2 opposite corners (the MBR)
    1789             :  *
    1790             :  * Feature geometry can be either an OGRPoint defining the center of the
    1791             :  * ellipse, or an OGRPolygon defining the ellipse itself.
    1792             :  *
    1793             :  * When an ellipse is read, the returned geometry is a OGRPolygon representing
    1794             :  * the ellipse with 2 degrees line segments.
    1795             :  *
    1796             :  * In the case of the OGRPoint, then the X/Y Radius MUST be set, but.
    1797             :  * However with an OGRPolygon, if the X/Y radius are not set (== 0) then
    1798             :  * the MBR of the polygon will be used to define the ellipse parameters
    1799             :  * and the center of the MBR is used as the center of the ellipse...
    1800             :  * (i.e. the polygon vertices themselves will be ignored).
    1801             :  *--------------------------------------------------------------------*/
    1802             : class TABEllipse final : public TABFeature,
    1803             :                          public ITABFeaturePen,
    1804             :                          public ITABFeatureBrush
    1805             : {
    1806             :   private:
    1807             :     virtual int UpdateMBR(TABMAPFile *poMapFile = nullptr) override;
    1808             : 
    1809             :   public:
    1810             :     explicit TABEllipse(OGRFeatureDefn *poDefnIn);
    1811             :     virtual ~TABEllipse();
    1812             : 
    1813         387 :     virtual TABFeatureClass GetFeatureClass() override
    1814             :     {
    1815         387 :         return TABFCEllipse;
    1816             :     }
    1817             : 
    1818             :     virtual TABGeomType
    1819             :     ValidateMapInfoType(TABMAPFile *poMapFile = nullptr) override;
    1820             : 
    1821             :     virtual TABFeature *
    1822             :     CloneTABFeature(OGRFeatureDefn *poNewDefn = nullptr) override;
    1823             : 
    1824             :     virtual int ReadGeometryFromMAPFile(
    1825             :         TABMAPFile *poMapFile, TABMAPObjHdr *, GBool bCoordDataOnly = FALSE,
    1826             :         TABMAPCoordBlock **ppoCoordBlock = nullptr) override;
    1827             :     virtual int
    1828             :     WriteGeometryToMAPFile(TABMAPFile *poMapFile, TABMAPObjHdr *,
    1829             :                            GBool bCoordDataOnly = FALSE,
    1830             :                            TABMAPCoordBlock **ppoCoordBlock = nullptr) override;
    1831             : 
    1832             :     virtual int ReadGeometryFromMIFFile(MIDDATAFile *fp) override;
    1833             :     virtual int WriteGeometryToMIFFile(MIDDATAFile *fp) override;
    1834             : 
    1835             :     virtual const char *GetStyleString() const override;
    1836             : 
    1837             :     virtual void DumpMIF(FILE *fpOut = nullptr) override;
    1838             : 
    1839             :     // MapInfo-specific attributes... made available through public vars
    1840             :     // for now.
    1841             :     double m_dCenterX;
    1842             :     double m_dCenterY;
    1843             :     double m_dXRadius;
    1844             :     double m_dYRadius;
    1845             : };
    1846             : 
    1847             : /*---------------------------------------------------------------------
    1848             :  *                      class TABArc
    1849             :  *
    1850             :  * Feature class to handle the MapInfo arc types:
    1851             :  *
    1852             :  *     TAB_GEOM_ARC_C      0x0a
    1853             :  *     TAB_GEOM_ARC        0x0b
    1854             :  *
    1855             :  * In MapInfo, an arc is defined by the coords of the MBR corners of its
    1856             :  * defining ellipse, which in this case is different from the arc's MBR,
    1857             :  * and a start and end angle in degrees.
    1858             :  *
    1859             :  * Feature geometry can be either an OGRLineString or an OGRPoint.
    1860             :  *
    1861             :  * In any case, X/Y radius X/Y center, and start/end angle (in degrees
    1862             :  * counterclockwise) MUST be set.
    1863             :  *
    1864             :  * When an arc is read, the returned geometry is an OGRLineString
    1865             :  * representing the arc with 2 degrees line segments.
    1866             :  *--------------------------------------------------------------------*/
    1867             : class TABArc final : public TABFeature, public ITABFeaturePen
    1868             : {
    1869             :   private:
    1870             :     double m_dStartAngle;  // In degrees, counterclockwise,
    1871             :     double m_dEndAngle;    // starting at 3 o'clock
    1872             : 
    1873             :     virtual int UpdateMBR(TABMAPFile *poMapFile = nullptr) override;
    1874             : 
    1875             :   public:
    1876             :     explicit TABArc(OGRFeatureDefn *poDefnIn);
    1877             :     virtual ~TABArc();
    1878             : 
    1879         642 :     virtual TABFeatureClass GetFeatureClass() override
    1880             :     {
    1881         642 :         return TABFCArc;
    1882             :     }
    1883             : 
    1884             :     virtual TABGeomType
    1885             :     ValidateMapInfoType(TABMAPFile *poMapFile = nullptr) override;
    1886             : 
    1887             :     virtual TABFeature *
    1888             :     CloneTABFeature(OGRFeatureDefn *poNewDefn = nullptr) override;
    1889             : 
    1890             :     virtual int ReadGeometryFromMAPFile(
    1891             :         TABMAPFile *poMapFile, TABMAPObjHdr *, GBool bCoordDataOnly = FALSE,
    1892             :         TABMAPCoordBlock **ppoCoordBlock = nullptr) override;
    1893             :     virtual int
    1894             :     WriteGeometryToMAPFile(TABMAPFile *poMapFile, TABMAPObjHdr *,
    1895             :                            GBool bCoordDataOnly = FALSE,
    1896             :                            TABMAPCoordBlock **ppoCoordBlock = nullptr) override;
    1897             : 
    1898             :     virtual int ReadGeometryFromMIFFile(MIDDATAFile *fp) override;
    1899             :     virtual int WriteGeometryToMIFFile(MIDDATAFile *fp) override;
    1900             : 
    1901             :     virtual const char *GetStyleString() const override;
    1902             : 
    1903             :     virtual void DumpMIF(FILE *fpOut = nullptr) override;
    1904             : 
    1905           0 :     double GetStartAngle()
    1906             :     {
    1907           0 :         return m_dStartAngle;
    1908             :     }
    1909             : 
    1910           0 :     double GetEndAngle()
    1911             :     {
    1912           0 :         return m_dEndAngle;
    1913             :     }
    1914             : 
    1915             :     void SetStartAngle(double dAngle);
    1916             :     void SetEndAngle(double dAngle);
    1917             : 
    1918             :     // MapInfo-specific attributes... made available through public vars
    1919             :     // for now.
    1920             :     double m_dCenterX;
    1921             :     double m_dCenterY;
    1922             :     double m_dXRadius;
    1923             :     double m_dYRadius;
    1924             : };
    1925             : 
    1926             : /*---------------------------------------------------------------------
    1927             :  *                      class TABText
    1928             :  *
    1929             :  * Feature class to handle the MapInfo text types:
    1930             :  *
    1931             :  *     TAB_GEOM_TEXT_C         0x10
    1932             :  *     TAB_GEOM_TEXT           0x11
    1933             :  *
    1934             :  * Feature geometry is an OGRPoint corresponding to the lower-left
    1935             :  * corner of the text MBR BEFORE ROTATION.
    1936             :  *
    1937             :  * Text string, and box height/width (box before rotation is applied)
    1938             :  * are required in a valid text feature and MUST be set.
    1939             :  * Text angle and other styles are optional.
    1940             :  *--------------------------------------------------------------------*/
    1941             : class TABText final : public TABFeature,
    1942             :                       public ITABFeatureFont,
    1943             :                       public ITABFeaturePen
    1944             : {
    1945             :     CPL_DISALLOW_COPY_ASSIGN(TABText)
    1946             : 
    1947             :   protected:
    1948             :     char *m_pszString;
    1949             : 
    1950             :     double m_dAngle;
    1951             :     double m_dHeight;
    1952             :     mutable double m_dWidth;
    1953             :     double m_dfLineEndX;
    1954             :     double m_dfLineEndY;
    1955             :     GBool m_bLineEndSet;
    1956             :     void UpdateTextMBR();
    1957             : 
    1958             :     GInt32 m_rgbForeground;
    1959             :     GInt32 m_rgbBackground;
    1960             :     GInt32 m_rgbOutline;
    1961             :     GInt32 m_rgbShadow;
    1962             : 
    1963             :     GInt16 m_nTextAlignment;  // Justification/Vert.Spacing/arrow
    1964             :     GInt16 m_nFontStyle;      // Bold/italic/underlined/shadow/...
    1965             : 
    1966             :     const char *GetLabelStyleString() const;
    1967             : 
    1968             :     virtual int UpdateMBR(TABMAPFile *poMapFile = nullptr) override;
    1969             : 
    1970             :   public:
    1971             :     explicit TABText(OGRFeatureDefn *poDefnIn);
    1972             :     virtual ~TABText();
    1973             : 
    1974         280 :     virtual TABFeatureClass GetFeatureClass() override
    1975             :     {
    1976         280 :         return TABFCText;
    1977             :     }
    1978             : 
    1979             :     virtual TABGeomType
    1980             :     ValidateMapInfoType(TABMAPFile *poMapFile = nullptr) override;
    1981             : 
    1982             :     virtual TABFeature *
    1983             :     CloneTABFeature(OGRFeatureDefn *poNewDefn = nullptr) override;
    1984             : 
    1985             :     virtual int ReadGeometryFromMAPFile(
    1986             :         TABMAPFile *poMapFile, TABMAPObjHdr *, GBool bCoordDataOnly = FALSE,
    1987             :         TABMAPCoordBlock **ppoCoordBlock = nullptr) override;
    1988             :     virtual int
    1989             :     WriteGeometryToMAPFile(TABMAPFile *poMapFile, TABMAPObjHdr *,
    1990             :                            GBool bCoordDataOnly = FALSE,
    1991             :                            TABMAPCoordBlock **ppoCoordBlock = nullptr) override;
    1992             : 
    1993             :     virtual int ReadGeometryFromMIFFile(MIDDATAFile *fp) override;
    1994             :     virtual int WriteGeometryToMIFFile(MIDDATAFile *fp) override;
    1995             : 
    1996             :     virtual const char *GetStyleString() const override;
    1997             : 
    1998             :     virtual void DumpMIF(FILE *fpOut = nullptr) override;
    1999             : 
    2000             :     void SetLabelFromStyleString(const char *pszStyleString);
    2001             : 
    2002             :     const char *GetTextString() const;
    2003             :     double GetTextAngle() const;
    2004             :     double GetTextBoxHeight() const;
    2005             :     double GetTextBoxWidth() const;
    2006             :     GInt32 GetFontFGColor() const;
    2007             :     GInt32 GetFontBGColor() const;
    2008             :     GInt32 GetFontOColor() const;
    2009             :     GInt32 GetFontSColor() const;
    2010             :     void GetTextLineEndPoint(double &dX, double &dY);
    2011             : 
    2012             :     TABTextJust GetTextJustification() const;
    2013             :     TABTextSpacing GetTextSpacing() const;
    2014             :     TABTextLineType GetTextLineType() const;
    2015             :     GBool QueryFontStyle(TABFontStyle eStyleToQuery) const;
    2016             : 
    2017             :     void SetTextString(const char *pszStr);
    2018             :     void SetTextAngle(double dAngle);
    2019             :     void SetTextBoxHeight(double dHeight);
    2020             :     void SetTextBoxWidth(double dWidth);
    2021             :     void SetFontFGColor(GInt32 rgbColor);
    2022             :     void SetFontBGColor(GInt32 rgbColor);
    2023             :     void SetFontOColor(GInt32 rgbColor);
    2024             :     void SetFontSColor(GInt32 rgbColor);
    2025             :     void SetTextLineEndPoint(double dX, double dY);
    2026             : 
    2027             :     void SetTextJustification(TABTextJust eJust);
    2028             :     void SetTextSpacing(TABTextSpacing eSpacing);
    2029             :     void SetTextLineType(TABTextLineType eLineType);
    2030             :     void ToggleFontStyle(TABFontStyle eStyleToToggle, GBool bStatus);
    2031             : 
    2032             :     int GetFontStyleMIFValue() const;
    2033             :     void SetFontStyleMIFValue(int nStyle, GBool bBGColorSet = FALSE);
    2034             :     GBool IsFontBGColorUsed() const;
    2035             :     GBool IsFontOColorUsed() const;
    2036             :     GBool IsFontSColorUsed() const;
    2037             :     GBool IsFontBold() const;
    2038             :     GBool IsFontItalic() const;
    2039             :     GBool IsFontUnderline() const;
    2040             : 
    2041           0 :     int GetFontStyleTABValue() const
    2042             :     {
    2043           0 :         return m_nFontStyle;
    2044             :     }
    2045             : 
    2046           0 :     void SetFontStyleTABValue(int nStyle)
    2047             :     {
    2048           0 :         m_nFontStyle = static_cast<GInt16>(nStyle);
    2049           0 :     }
    2050             : };
    2051             : 
    2052             : /*---------------------------------------------------------------------
    2053             :  *                      class TABMultiPoint
    2054             :  *
    2055             :  * Feature class to handle MapInfo Multipoint features:
    2056             :  *
    2057             :  *     TAB_GEOM_MULTIPOINT_C        0x34
    2058             :  *     TAB_GEOM_MULTIPOINT          0x35
    2059             :  *
    2060             :  * Feature geometry will be a OGRMultiPoint
    2061             :  *
    2062             :  * The symbol number is in the range [31..67], with 31=None and corresponds
    2063             :  * to one of the 35 predefined "Old MapInfo Symbols"
    2064             :  *--------------------------------------------------------------------*/
    2065             : class TABMultiPoint final : public TABFeature, public ITABFeatureSymbol
    2066             : {
    2067             :   private:
    2068             :     // We call it center, but it is more like a label point
    2069             :     // Its value default to be the location of the first point
    2070             :     GBool m_bCenterIsSet;
    2071             :     double m_dCenterX;
    2072             :     double m_dCenterY;
    2073             : 
    2074             :   public:
    2075             :     explicit TABMultiPoint(OGRFeatureDefn *poDefnIn);
    2076             :     virtual ~TABMultiPoint();
    2077             : 
    2078         149 :     virtual TABFeatureClass GetFeatureClass() override
    2079             :     {
    2080         149 :         return TABFCMultiPoint;
    2081             :     }
    2082             : 
    2083             :     virtual TABGeomType
    2084             :     ValidateMapInfoType(TABMAPFile *poMapFile = nullptr) override;
    2085             : 
    2086             :     virtual TABFeature *
    2087             :     CloneTABFeature(OGRFeatureDefn *poNewDefn = nullptr) override;
    2088             : 
    2089             :     int GetXY(int i, double &dX, double &dY);
    2090             :     int GetNumPoints();
    2091             : 
    2092             :     int GetCenter(double &dX, double &dY);
    2093             :     void SetCenter(double dX, double dY);
    2094             : 
    2095             :     virtual int ReadGeometryFromMAPFile(
    2096             :         TABMAPFile *poMapFile, TABMAPObjHdr *, GBool bCoordDataOnly = FALSE,
    2097             :         TABMAPCoordBlock **ppoCoordBlock = nullptr) override;
    2098             :     virtual int
    2099             :     WriteGeometryToMAPFile(TABMAPFile *poMapFile, TABMAPObjHdr *,
    2100             :                            GBool bCoordDataOnly = FALSE,
    2101             :                            TABMAPCoordBlock **ppoCoordBlock = nullptr) override;
    2102             : 
    2103             :     virtual int ReadGeometryFromMIFFile(MIDDATAFile *fp) override;
    2104             :     virtual int WriteGeometryToMIFFile(MIDDATAFile *fp) override;
    2105             : 
    2106             :     virtual const char *GetStyleString() const override;
    2107             : 
    2108             :     virtual void DumpMIF(FILE *fpOut = nullptr) override;
    2109             : };
    2110             : 
    2111             : /*---------------------------------------------------------------------
    2112             :  *
    2113             :  *                      class TABCollection
    2114             :  *
    2115             :  * Feature class to handle MapInfo Collection features:
    2116             :  *
    2117             :  *     TAB_GEOM_COLLECTION_C        0x37
    2118             :  *     TAB_GEOM_COLLECTION          0x38
    2119             :  *
    2120             :  * Feature geometry will be a OGRCollection
    2121             :  *
    2122             :  * **** IMPORTANT NOTE: ****
    2123             :  *
    2124             :  * The current implementation does not allow setting the Geometry via
    2125             :  * OGRFeature::SetGeometry*(). The geometries must be set via the
    2126             :  * TABCollection::SetRegion/Pline/MpointDirectly() methods which will take
    2127             :  * care of keeping the OGRFeature's geometry in sync.
    2128             :  *
    2129             :  * If we ever want to support creating collections via the OGR interface then
    2130             :  * something should be added in TABCollection::WriteGeometryToMapFile(), or
    2131             :  * perhaps in ValidateMapInfoType(), or even better in a custom
    2132             :  * TABCollection::SetGeometry*()... but then this last option may not work
    2133             :  * unless OGRFeature::SetGeometry*() are made virtual in OGR.
    2134             :  *
    2135             :  *--------------------------------------------------------------------*/
    2136             : class TABCollection final : public TABFeature, public ITABFeatureSymbol
    2137             : {
    2138             :     CPL_DISALLOW_COPY_ASSIGN(TABCollection)
    2139             : 
    2140             :   private:
    2141             :     TABRegion *m_poRegion;
    2142             :     TABPolyline *m_poPline;
    2143             :     TABMultiPoint *m_poMpoint;
    2144             : 
    2145             :     void EmptyCollection();
    2146             :     static int ReadLabelAndMBR(TABMAPCoordBlock *poCoordBlock,
    2147             :                                GBool bComprCoord, GInt32 nComprOrgX,
    2148             :                                GInt32 nComprOrgY, GInt32 &pnMinX,
    2149             :                                GInt32 &pnMinY, GInt32 &pnMaxX, GInt32 &pnMaxY,
    2150             :                                GInt32 &pnLabelX, GInt32 &pnLabelY);
    2151             :     static int WriteLabelAndMBR(TABMAPCoordBlock *poCoordBlock,
    2152             :                                 GBool bComprCoord, GInt32 nMinX, GInt32 nMinY,
    2153             :                                 GInt32 nMaxX, GInt32 nMaxY, GInt32 nLabelX,
    2154             :                                 GInt32 nLabelY);
    2155             :     int SyncOGRGeometryCollection(GBool bSyncRegion, GBool bSyncPline,
    2156             :                                   GBool bSyncMpoint);
    2157             : 
    2158             :   public:
    2159             :     explicit TABCollection(OGRFeatureDefn *poDefnIn);
    2160             :     virtual ~TABCollection();
    2161             : 
    2162           2 :     virtual TABFeatureClass GetFeatureClass() override
    2163             :     {
    2164           2 :         return TABFCCollection;
    2165             :     }
    2166             : 
    2167             :     virtual TABGeomType
    2168             :     ValidateMapInfoType(TABMAPFile *poMapFile = nullptr) override;
    2169             : 
    2170             :     virtual TABFeature *
    2171             :     CloneTABFeature(OGRFeatureDefn *poNewDefn = nullptr) override;
    2172             : 
    2173             :     virtual int ReadGeometryFromMAPFile(
    2174             :         TABMAPFile *poMapFile, TABMAPObjHdr *, GBool bCoordDataOnly = FALSE,
    2175             :         TABMAPCoordBlock **ppoCoordBlock = nullptr) override;
    2176             :     virtual int
    2177             :     WriteGeometryToMAPFile(TABMAPFile *poMapFile, TABMAPObjHdr *,
    2178             :                            GBool bCoordDataOnly = FALSE,
    2179             :                            TABMAPCoordBlock **ppoCoordBlock = nullptr) override;
    2180             : 
    2181             :     virtual int ReadGeometryFromMIFFile(MIDDATAFile *fp) override;
    2182             :     virtual int WriteGeometryToMIFFile(MIDDATAFile *fp) override;
    2183             : 
    2184             :     virtual const char *GetStyleString() const override;
    2185             : 
    2186             :     virtual void DumpMIF(FILE *fpOut = nullptr) override;
    2187             : 
    2188             :     TABRegion *GetRegionRef()
    2189             :     {
    2190             :         return m_poRegion;
    2191             :     }
    2192             : 
    2193             :     TABPolyline *GetPolylineRef()
    2194             :     {
    2195             :         return m_poPline;
    2196             :     }
    2197             : 
    2198             :     TABMultiPoint *GetMultiPointRef()
    2199             :     {
    2200             :         return m_poMpoint;
    2201             :     }
    2202             : 
    2203             :     int SetRegionDirectly(TABRegion *poRegion);
    2204             :     int SetPolylineDirectly(TABPolyline *poPline);
    2205             :     int SetMultiPointDirectly(TABMultiPoint *poMpoint);
    2206             : };
    2207             : 
    2208             : /*---------------------------------------------------------------------
    2209             :  *                      class TABDebugFeature
    2210             :  *
    2211             :  * Feature class to use for testing purposes... this one does not
    2212             :  * correspond to any MapInfo type... it is just used to dump info about
    2213             :  * feature types that are not implemented yet.
    2214             :  *--------------------------------------------------------------------*/
    2215             : class TABDebugFeature final : public TABFeature
    2216             : {
    2217             :   private:
    2218             :     GByte m_abyBuf[512];
    2219             :     int m_nSize;
    2220             :     int m_nCoordDataPtr;  // -1 if none
    2221             :     int m_nCoordDataSize;
    2222             : 
    2223             :   public:
    2224             :     explicit TABDebugFeature(OGRFeatureDefn *poDefnIn);
    2225             :     virtual ~TABDebugFeature();
    2226             : 
    2227           0 :     virtual TABFeatureClass GetFeatureClass() override
    2228             :     {
    2229           0 :         return TABFCDebugFeature;
    2230             :     }
    2231             : 
    2232             :     virtual int ReadGeometryFromMAPFile(
    2233             :         TABMAPFile *poMapFile, TABMAPObjHdr *, GBool bCoordDataOnly = FALSE,
    2234             :         TABMAPCoordBlock **ppoCoordBlock = nullptr) override;
    2235             :     virtual int
    2236             :     WriteGeometryToMAPFile(TABMAPFile *poMapFile, TABMAPObjHdr *,
    2237             :                            GBool bCoordDataOnly = FALSE,
    2238             :                            TABMAPCoordBlock **ppoCoordBlock = nullptr) override;
    2239             : 
    2240             :     virtual int ReadGeometryFromMIFFile(MIDDATAFile *fp) override;
    2241             :     virtual int WriteGeometryToMIFFile(MIDDATAFile *fp) override;
    2242             : 
    2243             :     virtual void DumpMIF(FILE *fpOut = nullptr) override;
    2244             : };
    2245             : 
    2246             : /* -------------------------------------------------------------------- */
    2247             : /*      Some stuff related to spatial reference system handling.        */
    2248             : /*                                                                      */
    2249             : /*      In GDAL we make use of the coordsys transformation from         */
    2250             : /*      other places (sometimes even from plugins), so we               */
    2251             : /*      deliberately export these two functions from the DLL.           */
    2252             : /* -------------------------------------------------------------------- */
    2253             : 
    2254             : char CPL_DLL *MITABSpatialRef2CoordSys(const OGRSpatialReference *);
    2255             : OGRSpatialReference CPL_DLL *MITABCoordSys2SpatialRef(const char *);
    2256             : 
    2257             : bool MITABExtractCoordSysBounds(const char *pszCoordSys, double &dXMin,
    2258             :                                 double &dYMin, double &dXMax, double &dYMax);
    2259             : int MITABCoordSys2TABProjInfo(const char *pszCoordSys, TABProjInfo *psProj);
    2260             : 
    2261             : typedef struct
    2262             : {
    2263             :     int nDatumEPSGCode;
    2264             :     int nMapInfoDatumID;
    2265             :     const char *pszOGCDatumName;
    2266             :     int nEllipsoid;
    2267             :     double dfShiftX;
    2268             :     double dfShiftY;
    2269             :     double dfShiftZ;
    2270             :     double dfDatumParm0; /* RotX */
    2271             :     double dfDatumParm1; /* RotY */
    2272             :     double dfDatumParm2; /* RotZ */
    2273             :     double dfDatumParm3; /* Scale Factor */
    2274             :     double dfDatumParm4; /* Prime Meridian */
    2275             : } MapInfoDatumInfo;
    2276             : 
    2277             : typedef struct
    2278             : {
    2279             :     int nMapInfoId;
    2280             :     const char *pszMapinfoName;
    2281             :     double dfA;             /* semi major axis in meters */
    2282             :     double dfInvFlattening; /* Inverse flattening */
    2283             : } MapInfoSpheroidInfo;
    2284             : 
    2285             : /*---------------------------------------------------------------------
    2286             :  * The following are used for coordsys bounds lookup
    2287             :  *--------------------------------------------------------------------*/
    2288             : 
    2289             : bool MITABLookupCoordSysBounds(TABProjInfo *psCS, double &dXMin, double &dYMin,
    2290             :                                double &dXMax, double &dYMax,
    2291             :                                bool bOnlyUserTable = false);
    2292             : int MITABLoadCoordSysTable(const char *pszFname);
    2293             : void MITABFreeCoordSysTable();
    2294             : bool MITABCoordSysTableLoaded();  // TODO(schwehr): Unused?
    2295             : 
    2296             : #endif /* MITAB_H_INCLUDED_ */

Generated by: LCOV version 1.14