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