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