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