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