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