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