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