1 : /**********************************************************************
2 : * $Id: mitab_priv.h,v 1.55 2010-01-07 20:39:12 aboudreault Exp $
3 : *
4 : * Name: mitab_priv.h
5 : * Project: MapInfo TAB Read/Write library
6 : * Language: C++
7 : * Purpose: Header file containing private definitions for the library.
8 : * Author: Daniel Morissette, dmorissette@dmsolutions.ca
9 : *
10 : **********************************************************************
11 : * Copyright (c) 1999-2003, Daniel Morissette
12 : *
13 : * Permission is hereby granted, free of charge, to any person obtaining a
14 : * copy of this software and associated documentation files (the "Software"),
15 : * to deal in the Software without restriction, including without limitation
16 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
17 : * and/or sell copies of the Software, and to permit persons to whom the
18 : * Software is furnished to do so, subject to the following conditions:
19 : *
20 : * The above copyright notice and this permission notice shall be included
21 : * in all copies or substantial portions of the Software.
22 : *
23 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24 : * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29 : * DEALINGS IN THE SOFTWARE.
30 : **********************************************************************
31 : *
32 : * $Log: mitab_priv.h,v $
33 : * Revision 1.55 2010-01-07 20:39:12 aboudreault
34 : * Added support to handle duplicate field names, Added validation to check if a field name start with a number (bug 2141)
35 : *
36 : * Revision 1.54 2008-11-27 20:50:23 aboudreault
37 : * Improved support for OGR date/time types. New Read/Write methods (bug 1948)
38 : * Added support of OGR date/time types for MIF features.
39 : *
40 : * Revision 1.53 2008/03/05 20:35:39 dmorissette
41 : * Replace MITAB 1.x SetFeature() with a CreateFeature() for V2.x (bug 1859)
42 : *
43 : * Revision 1.52 2008/02/20 21:35:30 dmorissette
44 : * Added support for V800 COLLECTION of large objects (bug 1496)
45 : *
46 : * Revision 1.51 2008/02/05 22:22:48 dmorissette
47 : * Added support for TAB_GEOM_V800_MULTIPOINT (bug 1496)
48 : *
49 : * Revision 1.50 2008/02/01 19:36:31 dmorissette
50 : * Initial support for V800 REGION and MULTIPLINE (bug 1496)
51 : *
52 : * Revision 1.49 2008/01/29 20:46:32 dmorissette
53 : * Added support for v9 Time and DateTime fields (byg 1754)
54 : *
55 : * Revision 1.48 2007/10/09 17:43:16 fwarmerdam
56 : * Remove static variables that interfere with reentrancy. (GDAL #1883)
57 : *
58 : * Revision 1.47 2007/06/12 12:50:39 dmorissette
59 : * Use Quick Spatial Index by default until bug 1732 is fixed (broken files
60 : * produced by current coord block splitting technique).
61 : *
62 : * Revision 1.46 2007/06/11 14:52:31 dmorissette
63 : * Return a valid m_nCoordDatasize value for Collection objects to prevent
64 : * trashing of collection data during object splitting (bug 1728)
65 : *
66 : * Revision 1.45 2007/03/21 21:15:56 dmorissette
67 : * Added SetQuickSpatialIndexMode() which generates a non-optimal spatial
68 : * index but results in faster write time (bug 1669)
69 : *
70 : * Revision 1.44 2007/02/22 18:35:53 dmorissette
71 : * Fixed problem writing collections where MITAB was sometimes trying to
72 : * read past EOF in write mode (bug 1657).
73 : *
74 : * Revision 1.43 2006/11/28 18:49:08 dmorissette
75 : * Completed changes to split TABMAPObjectBlocks properly and produce an
76 : * optimal spatial index (bug 1585)
77 : *
78 : * Revision 1.42 2006/11/20 20:05:58 dmorissette
79 : * First pass at improving generation of spatial index in .map file (bug 1585)
80 : * New methods for insertion and splittung in the spatial index are done.
81 : * Also implemented a method to dump the spatial index to .mif/.mid
82 : * Still need to implement splitting of TABMapObjectBlock to get optimal
83 : * results.
84 : *
85 : * Revision 1.41 2006/09/05 23:05:08 dmorissette
86 : * Added TABMAPFile::DumpSpatialIndex() (bug 1585)
87 : *
88 : * Revision 1.40 2005/10/06 19:15:31 dmorissette
89 : * Collections: added support for reading/writing pen/brush/symbol ids and
90 : * for writing collection objects to .TAB/.MAP (bug 1126)
91 : *
92 : * Revision 1.39 2005/10/04 15:44:31 dmorissette
93 : * First round of support for Collection objects. Currently supports reading
94 : * from .TAB/.MAP and writing to .MIF. Still lacks symbol support and write
95 : * support. (Based in part on patch and docs from Jim Hope, bug 1126)
96 : *
97 : * Revision 1.38 2005/03/22 23:24:54 dmorissette
98 : * Added support for datum id in .MAP header (bug 910)
99 : *
100 : * Revision 1.37 2004/06/30 20:29:04 dmorissette
101 : * Fixed refs to old address danmo@videotron.ca
102 : *
103 : * Revision 1.36 2003/08/12 23:17:21 dmorissette
104 : * Added reading of v500+ coordsys affine params (Anthony D. - Encom)
105 : *
106 : * Revision 1.35 2003/01/18 20:25:44 daniel
107 : * Increased MIDMAXCHAR value to 10000
108 : *
109 : * Revision 1.34 2002/04/25 16:05:24 julien
110 : * Disabled the overflow warning in SetCoordFilter() by adding bIgnoreOverflow
111 : * variable in Coordsys2Int of the TABMAPFile class and TABMAPHeaderBlock class
112 : *
113 : * Revision 1.33 2002/04/22 13:49:09 julien
114 : * Add EOF validation in MIDDATAFile::GetLastLine() (Bug 819)
115 : *
116 : * Revision 1.32 2002/03/26 19:27:43 daniel
117 : * Got rid of tabs in source
118 : *
119 : * Revision 1.31 2002/03/26 01:48:40 daniel
120 : * Added Multipoint object type (V650)
121 : *
122 : * Revision 1.30 2002/02/22 20:44:51 julien
123 : * Prevent infinite loop with TABRelation by suppress the m_poCurFeature object
124 : * from the class and setting it in the calling function and add GetFeature in
125 : * the class. (bug 706)
126 : *
127 : * Revision 1.29 2001/11/19 15:07:54 daniel
128 : * Added TABMAPObjNone to handle the case of TAB_GEOM_NONE
129 : *
130 : * Revision 1.28 2001/11/17 21:54:06 daniel
131 : * Made several changes in order to support writing objects in 16 bits
132 : * coordinate format. New TABMAPObjHdr-derived classes are used to hold
133 : * object info in mem until block is full.
134 : *
135 : * Revision 1.27 2001/09/18 20:33:52 warmerda
136 : * fixed case of spatial search on file with just one object block
137 : *
138 : * Revision 1.26 2001/09/14 03:23:55 warmerda
139 : * Substantial upgrade to support spatial queries using spatial indexes
140 : *
141 : * Revision 1.25 2001/05/01 18:28:10 daniel
142 : * Fixed default BRUSH, should be BRUSH(1,0,16777215).
143 : *
144 : * Revision 1.24 2001/05/01 03:39:51 daniel
145 : * Added SetLastPtr() to TABBinBlockManager.
146 : *
147 : * Revision 1.23 2001/03/15 03:57:51 daniel
148 : * Added implementation for new OGRLayer::GetExtent(), returning data MBR.
149 : *
150 : * Revision 1.22 2000/11/23 21:11:07 daniel
151 : * OOpps... VC++ didn't like the way TABPenDef, etc. were initialized
152 : *
153 : * Revision 1.21 2000/11/23 20:47:46 daniel
154 : * Use MI defaults for Pen, Brush, Font, Symbol instead of all zeros
155 : *
156 : * Revision 1.20 2000/11/15 04:13:50 daniel
157 : * Fixed writing of TABMAPToolBlock to allocate a new block when full
158 : *
159 : * Revision 1.19 2000/11/13 22:19:30 daniel
160 : * Added TABINDNode::UpdateCurChildEntry()
161 : *
162 : * Revision 1.18 2000/05/19 06:45:25 daniel
163 : * Modified generation of spatial index to split index nodes and produce a
164 : * more balanced tree.
165 : *
166 : * Revision 1.17 2000/03/01 00:30:03 daniel
167 : * Completed support for joined tables
168 : *
169 : * Revision 1.16 2000/02/28 16:53:23 daniel
170 : * Added support for indexed, unique, and for new V450 object types
171 : *
172 : * ...
173 : *
174 : * Revision 1.1 1999/07/12 04:18:25 daniel
175 : * Initial checkin
176 : *
177 : **********************************************************************/
178 :
179 : #ifndef _MITAB_PRIV_H_INCLUDED_
180 : #define _MITAB_PRIV_H_INCLUDED_
181 :
182 : #include "cpl_conv.h"
183 : #include "cpl_string.h"
184 : #include "ogr_feature.h"
185 :
186 : class TABFile;
187 : class TABFeature;
188 : class TABMAPToolBlock;
189 : class TABMAPIndexBlock;
190 :
191 : /*---------------------------------------------------------------------
192 : * Access mode: Read or Write
193 : *--------------------------------------------------------------------*/
194 : typedef enum
195 : {
196 : TABRead,
197 : TABWrite,
198 : TABReadWrite /* ReadWrite not implemented yet */
199 : } TABAccess;
200 :
201 : /*---------------------------------------------------------------------
202 : * Supported .MAP block types (the first byte at the beginning of a block)
203 : *--------------------------------------------------------------------*/
204 : #define TAB_RAWBIN_BLOCK -1
205 : #define TABMAP_HEADER_BLOCK 0
206 : #define TABMAP_INDEX_BLOCK 1
207 : #define TABMAP_OBJECT_BLOCK 2
208 : #define TABMAP_COORD_BLOCK 3
209 : #define TABMAP_GARB_BLOCK 4
210 : #define TABMAP_TOOL_BLOCK 5
211 : #define TABMAP_LAST_VALID_BLOCK_TYPE 5
212 :
213 : /*---------------------------------------------------------------------
214 : * Drawing Tool types
215 : *--------------------------------------------------------------------*/
216 : #define TABMAP_TOOL_PEN 1
217 : #define TABMAP_TOOL_BRUSH 2
218 : #define TABMAP_TOOL_FONT 3
219 : #define TABMAP_TOOL_SYMBOL 4
220 :
221 : /*---------------------------------------------------------------------
222 : * Limits related to .TAB version number. If we pass any of those limits
223 : * then we have to use larger object types
224 : *--------------------------------------------------------------------*/
225 : #define TAB_REGION_PLINE_300_MAX_VERTICES 32767
226 :
227 : #define TAB_REGION_PLINE_450_MAX_SEGMENTS 32767
228 : #define TAB_REGION_PLINE_450_MAX_VERTICES 1048575
229 :
230 : #define TAB_MULTIPOINT_650_MAX_VERTICES 1048576
231 :
232 : /* Use this macro to test whether the number of segments and vertices
233 : * in this object exceeds the V450/650 limits and requires a V800 object
234 : */
235 : #define TAB_REGION_PLINE_REQUIRES_V800(numSegments, numVerticesTotal) \
236 : ((numSegments) > TAB_REGION_PLINE_450_MAX_SEGMENTS || \
237 : ((numSegments)*3 + numVerticesTotal) > TAB_REGION_PLINE_450_MAX_VERTICES )
238 :
239 :
240 : /*---------------------------------------------------------------------
241 : * struct TABMAPIndexEntry - Entries found in type 1 blocks of .MAP files
242 : *
243 : * We will use this struct to rebuild the geographic index in memory
244 : *--------------------------------------------------------------------*/
245 : typedef struct TABMAPIndexEntry_t
246 : {
247 : // These members refer to the info we find in the file
248 : GInt32 XMin;
249 : GInt32 YMin;
250 : GInt32 XMax;
251 : GInt32 YMax;
252 : GInt32 nBlockPtr;
253 : }TABMAPIndexEntry;
254 :
255 : #define TAB_MAX_ENTRIES_INDEX_BLOCK ((512-4)/20)
256 :
257 :
258 : /*---------------------------------------------------------------------
259 : * TABVertex
260 : *--------------------------------------------------------------------*/
261 : typedef struct TABVertex_t
262 : {
263 : double x;
264 : double y;
265 : } TABVertex;
266 :
267 : /*---------------------------------------------------------------------
268 : * TABTableType - Attribute table format
269 : *--------------------------------------------------------------------*/
270 : typedef enum
271 : {
272 : TABTableNative, // The default
273 : TABTableDBF,
274 : TABTableAccess
275 : } TABTableType;
276 :
277 : /*---------------------------------------------------------------------
278 : * TABFieldType - Native MapInfo attribute field types
279 : *--------------------------------------------------------------------*/
280 : typedef enum
281 : {
282 : TABFUnknown = 0,
283 : TABFChar,
284 : TABFInteger,
285 : TABFSmallInt,
286 : TABFDecimal,
287 : TABFFloat,
288 : TABFDate,
289 : TABFLogical,
290 : TABFTime,
291 : TABFDateTime
292 : } TABFieldType;
293 :
294 : #define TABFIELDTYPE_2_STRING(type) \
295 : (type == TABFChar ? "Char" : \
296 : type == TABFInteger ? "Integer" : \
297 : type == TABFSmallInt ? "SmallInt" : \
298 : type == TABFDecimal ? "Decimal" : \
299 : type == TABFFloat ? "Float" : \
300 : type == TABFDate ? "Date" : \
301 : type == TABFLogical ? "Logical" : \
302 : type == TABFTime ? "Time" : \
303 : type == TABFDateTime ? "DateTime" : \
304 : "Unknown field type" )
305 :
306 : /*---------------------------------------------------------------------
307 : * TABDATFieldDef
308 : *--------------------------------------------------------------------*/
309 : typedef struct TABDATFieldDef_t
310 : {
311 : char szName[11];
312 : char cType;
313 : GByte byLength;
314 : GByte byDecimals;
315 :
316 : TABFieldType eTABType;
317 : } TABDATFieldDef;
318 :
319 : /*---------------------------------------------------------------------
320 : * TABMAPCoordSecHdr
321 : * struct used in the TABMAPCoordBlock to store info about the coordinates
322 : * for a section of a PLINE MULTIPLE or a REGION.
323 : *--------------------------------------------------------------------*/
324 : typedef struct TABMAPCoordSecHdr_t
325 : {
326 : GInt32 numVertices;
327 : GInt32 numHoles;
328 : GInt32 nXMin;
329 : GInt32 nYMin;
330 : GInt32 nXMax;
331 : GInt32 nYMax;
332 :
333 : GInt32 nDataOffset;
334 : int nVertexOffset;
335 : } TABMAPCoordSecHdr;
336 :
337 : /*---------------------------------------------------------------------
338 : * TABProjInfo
339 : * struct used to store the projection parameters from the .MAP header
340 : *--------------------------------------------------------------------*/
341 : typedef struct TABProjInfo_t
342 : {
343 : GByte nProjId; // See MapInfo Ref. Manual, App. F and G
344 : GByte nEllipsoidId;
345 : GByte nUnitsId;
346 : double adProjParams[6]; // params in same order as in .MIF COORDSYS
347 :
348 : GInt16 nDatumId; // Datum Id added in MapInfo 7.8+ (.map V500)
349 : double dDatumShiftX; // Before that, we had to always lookup datum
350 : double dDatumShiftY; // parameters to establish datum id
351 : double dDatumShiftZ;
352 : double adDatumParams[5];
353 :
354 : // Affine parameters only in .map version 500 and up
355 : GByte nAffineFlag; // 0=No affine param, 1=Affine params
356 : GByte nAffineUnits;
357 : double dAffineParamA; // Affine params
358 : double dAffineParamB;
359 : double dAffineParamC;
360 : double dAffineParamD;
361 : double dAffineParamE;
362 : double dAffineParamF;
363 :
364 : } TABProjInfo;
365 :
366 :
367 : /*---------------------------------------------------------------------
368 : * TABPenDef - Pen definition information
369 : *--------------------------------------------------------------------*/
370 : typedef struct TABPenDef_t
371 : {
372 : GInt32 nRefCount;
373 : GByte nPixelWidth;
374 : GByte nLinePattern;
375 : int nPointWidth;
376 : GInt32 rgbColor;
377 : } TABPenDef;
378 :
379 : /* MI Default = PEN(1,2,0) */
380 : #define MITAB_PEN_DEFAULT {0, 1, 2, 0, 0x000000}
381 :
382 : /*---------------------------------------------------------------------
383 : * TABBrushDef - Brush definition information
384 : *--------------------------------------------------------------------*/
385 : typedef struct TABBrushDef_t
386 : {
387 : GInt32 nRefCount;
388 : GByte nFillPattern;
389 : GByte bTransparentFill; // 1 = Transparent
390 : GInt32 rgbFGColor;
391 : GInt32 rgbBGColor;
392 : } TABBrushDef;
393 :
394 : /* MI Default = BRUSH(1,0,16777215) */
395 : #define MITAB_BRUSH_DEFAULT {0, 1, 0, 0, 0xffffff}
396 :
397 : /*---------------------------------------------------------------------
398 : * TABFontDef - Font Name information
399 : *--------------------------------------------------------------------*/
400 : typedef struct TABFontDef_t
401 : {
402 : GInt32 nRefCount;
403 : char szFontName[33];
404 : } TABFontDef;
405 :
406 : /* MI Default = FONT("Arial",0,0,0) */
407 : #define MITAB_FONT_DEFAULT {0, "Arial"}
408 :
409 : /*---------------------------------------------------------------------
410 : * TABSymbolDef - Symbol definition information
411 : *--------------------------------------------------------------------*/
412 : typedef struct TABSymbolDef_t
413 : {
414 : GInt32 nRefCount;
415 : GInt16 nSymbolNo;
416 : GInt16 nPointSize;
417 : GByte _nUnknownValue_;// Style???
418 : GInt32 rgbColor;
419 : } TABSymbolDef;
420 :
421 : /* MI Default = SYMBOL(35,0,12) */
422 : #define MITAB_SYMBOL_DEFAULT {0, 35, 12, 0, 0x000000}
423 :
424 : /*---------------------------------------------------------------------
425 : * class TABToolDefTable
426 : *
427 : * Class to handle the list of Drawing Tool Definitions for a dataset
428 : *
429 : * This class also contains methods to read tool defs from the file and
430 : * write them to the file.
431 : *--------------------------------------------------------------------*/
432 :
433 : class TABToolDefTable
434 : {
435 : protected:
436 : TABPenDef **m_papsPen;
437 : int m_numPen;
438 : int m_numAllocatedPen;
439 : TABBrushDef **m_papsBrush;
440 : int m_numBrushes;
441 : int m_numAllocatedBrushes;
442 : TABFontDef **m_papsFont;
443 : int m_numFonts;
444 : int m_numAllocatedFonts;
445 : TABSymbolDef **m_papsSymbol;
446 : int m_numSymbols;
447 : int m_numAllocatedSymbols;
448 :
449 : public:
450 : TABToolDefTable();
451 : ~TABToolDefTable();
452 :
453 : int ReadAllToolDefs(TABMAPToolBlock *poToolBlock);
454 : int WriteAllToolDefs(TABMAPToolBlock *poToolBlock);
455 :
456 : TABPenDef *GetPenDefRef(int nIndex);
457 : int AddPenDefRef(TABPenDef *poPenDef);
458 : int GetNumPen();
459 :
460 : TABBrushDef *GetBrushDefRef(int nIndex);
461 : int AddBrushDefRef(TABBrushDef *poBrushDef);
462 : int GetNumBrushes();
463 :
464 : TABFontDef *GetFontDefRef(int nIndex);
465 : int AddFontDefRef(TABFontDef *poFontDef);
466 : int GetNumFonts();
467 :
468 : TABSymbolDef *GetSymbolDefRef(int nIndex);
469 : int AddSymbolDefRef(TABSymbolDef *poSymbolDef);
470 : int GetNumSymbols();
471 :
472 : int GetMinVersionNumber();
473 : };
474 :
475 : /*=====================================================================
476 : Classes to handle Object Headers inside TABMAPObjectBlocks
477 : =====================================================================*/
478 :
479 : class TABMAPObjectBlock;
480 : class TABMAPHeaderBlock;
481 :
482 : class TABMAPObjHdr
483 : {
484 : public:
485 : GByte m_nType;
486 : GInt32 m_nId;
487 : GInt32 m_nMinX; /* Object MBR */
488 : GInt32 m_nMinY;
489 : GInt32 m_nMaxX;
490 : GInt32 m_nMaxY;
491 :
492 134 : TABMAPObjHdr() {};
493 134 : virtual ~TABMAPObjHdr() {};
494 :
495 : static TABMAPObjHdr *NewObj(GByte nNewObjType, GInt32 nId=0);
496 : static TABMAPObjHdr *ReadNextObj(TABMAPObjectBlock *poObjBlock,
497 : TABMAPHeaderBlock *poHeader);
498 :
499 : GBool IsCompressedType();
500 : int WriteObjTypeAndId(TABMAPObjectBlock *);
501 : void SetMBR(GInt32 nMinX, GInt32 nMinY, GInt32 nMaxX, GInt32 mMaxY);
502 :
503 0 : virtual int WriteObj(TABMAPObjectBlock *) {return -1;};
504 :
505 : // protected:
506 0 : virtual int ReadObj(TABMAPObjectBlock *) {return -1;};
507 : };
508 :
509 : class TABMAPObjHdrWithCoord: public TABMAPObjHdr
510 248 : {
511 : public:
512 : GInt32 m_nCoordBlockPtr;
513 : GInt32 m_nCoordDataSize;
514 :
515 : /* Eventually this class may have methods to help maintaining refs to
516 : * coord. blocks when splitting object blocks.
517 : */
518 : };
519 :
520 :
521 : class TABMAPObjNone: public TABMAPObjHdr
522 : {
523 : public:
524 :
525 6 : TABMAPObjNone() {};
526 6 : virtual ~TABMAPObjNone() {};
527 :
528 0 : virtual int WriteObj(TABMAPObjectBlock *) {return 0;};
529 :
530 : // protected:
531 2 : virtual int ReadObj(TABMAPObjectBlock *) {return 0;};
532 : };
533 :
534 :
535 : class TABMAPObjPoint: public TABMAPObjHdr
536 : {
537 : public:
538 : GInt32 m_nX;
539 : GInt32 m_nY;
540 : GByte m_nSymbolId;
541 :
542 0 : TABMAPObjPoint() {};
543 0 : virtual ~TABMAPObjPoint() {};
544 :
545 : virtual int WriteObj(TABMAPObjectBlock *);
546 :
547 : // protected:
548 : virtual int ReadObj(TABMAPObjectBlock *);
549 : };
550 :
551 : class TABMAPObjFontPoint: public TABMAPObjPoint
552 : {
553 : public:
554 : GByte m_nPointSize;
555 : GInt16 m_nFontStyle;
556 : GByte m_nR;
557 : GByte m_nG;
558 : GByte m_nB;
559 : GInt16 m_nAngle; /* In tenths of degree */
560 : GByte m_nFontId;
561 :
562 0 : TABMAPObjFontPoint() {};
563 0 : virtual ~TABMAPObjFontPoint() {};
564 :
565 : virtual int WriteObj(TABMAPObjectBlock *);
566 :
567 : // protected:
568 : virtual int ReadObj(TABMAPObjectBlock *);
569 : };
570 :
571 : class TABMAPObjCustomPoint: public TABMAPObjPoint
572 : {
573 : public:
574 : GByte m_nUnknown_;
575 : GByte m_nCustomStyle;
576 : GByte m_nFontId;
577 :
578 0 : TABMAPObjCustomPoint() {};
579 0 : virtual ~TABMAPObjCustomPoint() {};
580 :
581 : virtual int WriteObj(TABMAPObjectBlock *);
582 :
583 : // protected:
584 : virtual int ReadObj(TABMAPObjectBlock *);
585 : };
586 :
587 :
588 : class TABMAPObjLine: public TABMAPObjHdr
589 : {
590 : public:
591 : GInt32 m_nX1;
592 : GInt32 m_nY1;
593 : GInt32 m_nX2;
594 : GInt32 m_nY2;
595 : GByte m_nPenId;
596 :
597 4 : TABMAPObjLine() {};
598 4 : virtual ~TABMAPObjLine() {};
599 :
600 : virtual int WriteObj(TABMAPObjectBlock *);
601 :
602 : // protected:
603 : virtual int ReadObj(TABMAPObjectBlock *);
604 : };
605 :
606 : class TABMAPObjPLine: public TABMAPObjHdrWithCoord
607 : {
608 : public:
609 : GInt32 m_numLineSections; /* MULTIPLINE/REGION only. Not in PLINE */
610 : GInt32 m_nLabelX; /* Centroid/label location */
611 : GInt32 m_nLabelY;
612 : GInt32 m_nComprOrgX; /* Present only in compressed coord. case */
613 : GInt32 m_nComprOrgY;
614 : GByte m_nPenId;
615 : GByte m_nBrushId;
616 : GBool m_bSmooth; /* TRUE if (m_nCoordDataSize & 0x80000000) */
617 :
618 124 : TABMAPObjPLine() {};
619 124 : virtual ~TABMAPObjPLine() {};
620 :
621 : virtual int WriteObj(TABMAPObjectBlock *);
622 :
623 : // protected:
624 : virtual int ReadObj(TABMAPObjectBlock *);
625 : };
626 :
627 : class TABMAPObjRectEllipse: public TABMAPObjHdr
628 : {
629 : public:
630 : GInt32 m_nCornerWidth; /* For rounded rect only */
631 : GInt32 m_nCornerHeight;
632 : GByte m_nPenId;
633 : GByte m_nBrushId;
634 :
635 0 : TABMAPObjRectEllipse() {};
636 0 : virtual ~TABMAPObjRectEllipse() {};
637 :
638 : virtual int WriteObj(TABMAPObjectBlock *);
639 :
640 : // protected:
641 : virtual int ReadObj(TABMAPObjectBlock *);
642 : };
643 :
644 : class TABMAPObjArc: public TABMAPObjHdr
645 : {
646 : public:
647 : GInt32 m_nStartAngle;
648 : GInt32 m_nEndAngle;
649 : GInt32 m_nArcEllipseMinX; /* MBR of the arc defining ellipse */
650 : GInt32 m_nArcEllipseMinY; /* Only present in arcs */
651 : GInt32 m_nArcEllipseMaxX;
652 : GInt32 m_nArcEllipseMaxY;
653 : GByte m_nPenId;
654 :
655 0 : TABMAPObjArc() {};
656 0 : virtual ~TABMAPObjArc() {};
657 :
658 : virtual int WriteObj(TABMAPObjectBlock *);
659 :
660 : // protected:
661 : virtual int ReadObj(TABMAPObjectBlock *);
662 : };
663 :
664 :
665 : class TABMAPObjText: public TABMAPObjHdrWithCoord
666 : {
667 : public:
668 : /* String and its len stored in the nCoordPtr and nCoordSize */
669 :
670 : GInt16 m_nTextAlignment;
671 : GInt32 m_nAngle;
672 : GInt16 m_nFontStyle;
673 :
674 : GByte m_nFGColorR;
675 : GByte m_nFGColorG;
676 : GByte m_nFGColorB;
677 : GByte m_nBGColorR;
678 : GByte m_nBGColorG;
679 : GByte m_nBGColorB;
680 :
681 : GInt32 m_nLineEndX;
682 : GInt32 m_nLineEndY;
683 :
684 : GInt32 m_nHeight;
685 : GByte m_nFontId;
686 :
687 : GByte m_nPenId;
688 :
689 0 : TABMAPObjText() {};
690 0 : virtual ~TABMAPObjText() {};
691 :
692 : virtual int WriteObj(TABMAPObjectBlock *);
693 :
694 : // protected:
695 : virtual int ReadObj(TABMAPObjectBlock *);
696 : };
697 :
698 :
699 : class TABMAPObjMultiPoint: public TABMAPObjHdrWithCoord
700 : {
701 : public:
702 : GInt32 m_nNumPoints;
703 : GInt32 m_nComprOrgX; /* Present only in compressed coord. case */
704 : GInt32 m_nComprOrgY;
705 : GByte m_nSymbolId;
706 : GInt32 m_nLabelX; /* Not sure if it's a label point, but */
707 : GInt32 m_nLabelY; /* it's similar to what we find in PLINE */
708 :
709 0 : TABMAPObjMultiPoint() {};
710 0 : virtual ~TABMAPObjMultiPoint() {};
711 :
712 : virtual int WriteObj(TABMAPObjectBlock *);
713 :
714 : // protected:
715 : virtual int ReadObj(TABMAPObjectBlock *);
716 : };
717 :
718 : class TABMAPObjCollection: public TABMAPObjHdrWithCoord
719 : {
720 : public:
721 : GInt32 m_nRegionDataSize;
722 : GInt32 m_nPolylineDataSize;
723 : GInt32 m_nMPointDataSize;
724 : GInt32 m_nComprOrgX; /* Present only in compressed coord. case */
725 : GInt32 m_nComprOrgY;
726 : GInt32 m_nNumMultiPoints;
727 : GInt32 m_nNumRegSections;
728 : GInt32 m_nNumPLineSections;
729 :
730 : GByte m_nMultiPointSymbolId;
731 : GByte m_nRegionPenId;
732 : GByte m_nRegionBrushId;
733 : GByte m_nPolylinePenId;
734 :
735 0 : TABMAPObjCollection() {};
736 0 : virtual ~TABMAPObjCollection()
737 0 : {}
738 :
739 : virtual int WriteObj(TABMAPObjectBlock *);
740 :
741 : // protected:
742 : virtual int ReadObj(TABMAPObjectBlock *);
743 :
744 : private:
745 : // private copy ctor and assignment operator to prevent shallow copying
746 : TABMAPObjCollection& operator=(const TABMAPObjCollection& rhs);
747 : TABMAPObjCollection(const TABMAPObjCollection& rhs);
748 : };
749 :
750 : /*=====================================================================
751 : Classes to handle .MAP files low-level blocks
752 : =====================================================================*/
753 :
754 : typedef struct TABBlockRef_t
755 : {
756 : GInt32 nBlockPtr;
757 : struct TABBlockRef_t *psNext;
758 : } TABBlockRef;
759 :
760 : /*---------------------------------------------------------------------
761 : * class TABBinBlockManager
762 : *
763 : * This class is used to keep track of allocated blocks and is used
764 : * by various classes that need to allocate a new block in a .MAP file.
765 : *--------------------------------------------------------------------*/
766 : class TABBinBlockManager
767 : {
768 : protected:
769 : int m_nBlockSize;
770 : GInt32 m_nLastAllocatedBlock;
771 : TABBlockRef *m_psGarbageBlocks;
772 :
773 : public:
774 : TABBinBlockManager(int nBlockSize=512);
775 : ~TABBinBlockManager();
776 :
777 : GInt32 AllocNewBlock();
778 : void Reset();
779 8 : void SetLastPtr(int nBlockPtr) {m_nLastAllocatedBlock=nBlockPtr; };
780 :
781 : void PushGarbageBlock(GInt32 nBlockPtr);
782 : GInt32 GetFirstGarbageBlock();
783 : GInt32 PopGarbageBlock();
784 : };
785 :
786 : /*---------------------------------------------------------------------
787 : * class TABRawBinBlock
788 : *
789 : * This is the base class used for all other data block types... it
790 : * contains all the base functions to handle binary data.
791 : *--------------------------------------------------------------------*/
792 :
793 : class TABRawBinBlock
794 : {
795 : protected:
796 : FILE *m_fp; /* Associated file handle */
797 : TABAccess m_eAccess; /* Read/Write access mode */
798 :
799 : int m_nBlockType;
800 :
801 : GByte *m_pabyBuf; /* Buffer to contain the block's data */
802 : int m_nBlockSize; /* Size of current block (and buffer) */
803 : int m_nSizeUsed; /* Number of bytes used in buffer */
804 : GBool m_bHardBlockSize;/* TRUE=Blocks MUST always be nSize bytes */
805 : /* FALSE=last block may be less than nSize */
806 : int m_nFileOffset; /* Location of current block in the file */
807 : int m_nCurPos; /* Next byte to read from m_pabyBuf[] */
808 : int m_nFirstBlockPtr;/* Size of file header when different from */
809 : /* block size (used by GotoByteInFile()) */
810 :
811 : int m_bModified; /* Used only to detect changes */
812 :
813 : public:
814 : TABRawBinBlock(TABAccess eAccessMode = TABRead,
815 : GBool bHardBlockSize = TRUE);
816 : virtual ~TABRawBinBlock();
817 :
818 : virtual int ReadFromFile(FILE *fpSrc, int nOffset, int nSize = 512);
819 : virtual int CommitToFile();
820 : int CommitAsDeleted(GInt32 nNextBlockPtr);
821 :
822 : virtual int InitBlockFromData(GByte *pabyBuf,
823 : int nBlockSize, int nSizeUsed,
824 : GBool bMakeCopy = TRUE,
825 : FILE *fpSrc = NULL, int nOffset = 0);
826 : virtual int InitNewBlock(FILE *fpSrc, int nBlockSize, int nFileOffset=0);
827 :
828 : int GetBlockType();
829 0 : virtual int GetBlockClass() { return TAB_RAWBIN_BLOCK; };
830 :
831 64 : GInt32 GetStartAddress() {return m_nFileOffset;};
832 : #ifdef DEBUG
833 : virtual void Dump(FILE *fpOut = NULL);
834 : #endif
835 : void DumpBytes(GInt32 nValue, int nOffset=0, FILE *fpOut=NULL);
836 :
837 : int GotoByteRel(int nOffset);
838 : int GotoByteInBlock(int nOffset);
839 : int GotoByteInFile(int nOffset,
840 : GBool bForceReadFromFile = FALSE,
841 : GBool bOffsetIsEndOfData = FALSE);
842 : void SetFirstBlockPtr(int nOffset);
843 :
844 : int GetNumUnusedBytes();
845 : int GetFirstUnusedByteOffset();
846 : int GetCurAddress();
847 :
848 : virtual int ReadBytes(int numBytes, GByte *pabyDstBuf);
849 : GByte ReadByte();
850 : GInt16 ReadInt16();
851 : GInt32 ReadInt32();
852 : float ReadFloat();
853 : double ReadDouble();
854 :
855 : virtual int WriteBytes(int nBytesToWrite, GByte *pBuf);
856 : int WriteByte(GByte byValue);
857 : int WriteInt16(GInt16 n16Value);
858 : int WriteInt32(GInt32 n32Value);
859 : int WriteFloat(float fValue);
860 : int WriteDouble(double dValue);
861 : int WriteZeros(int nBytesToWrite);
862 : int WritePaddedString(int nFieldSize, const char *pszString);
863 :
864 : void SetModifiedFlag(GBool bModified) {m_bModified=bModified;};
865 :
866 : // This semi-private method gives a direct access to the internal
867 : // buffer... to be used with extreme care!!!!!!!!!
868 2878 : GByte * GetCurDataPtr() { return (m_pabyBuf + m_nCurPos); } ;
869 : };
870 :
871 :
872 : /*---------------------------------------------------------------------
873 : * class TABMAPHeaderBlock
874 : *
875 : * Class to handle Read/Write operation on .MAP Header Blocks
876 : *--------------------------------------------------------------------*/
877 :
878 : class TABMAPHeaderBlock: public TABRawBinBlock
879 : {
880 : protected:
881 : TABProjInfo m_sProj;
882 :
883 : public:
884 : TABMAPHeaderBlock(TABAccess eAccessMode = TABRead);
885 : ~TABMAPHeaderBlock();
886 :
887 : virtual int CommitToFile();
888 :
889 : virtual int InitBlockFromData(GByte *pabyBuf,
890 : int nBlockSize, int nSizeUsed,
891 : GBool bMakeCopy = TRUE,
892 : FILE *fpSrc = NULL, int nOffset = 0);
893 : virtual int InitNewBlock(FILE *fpSrc, int nBlockSize, int nFileOffset=0);
894 :
895 12 : virtual int GetBlockClass() { return TABMAP_HEADER_BLOCK; };
896 :
897 : int Int2Coordsys(GInt32 nX, GInt32 nY, double &dX, double &dY);
898 : int Coordsys2Int(double dX, double dY, GInt32 &nX, GInt32 &nY,
899 : GBool bIgnoreOverflow=FALSE);
900 : int ComprInt2Coordsys(GInt32 nCenterX, GInt32 nCenterY,
901 : int nDeltaX, int nDeltaY,
902 : double &dX, double &dY);
903 : int Int2CoordsysDist(GInt32 nX, GInt32 nY, double &dX, double &dY);
904 : int Coordsys2IntDist(double dX, double dY, GInt32 &nX, GInt32 &nY);
905 : int SetCoordsysBounds(double dXMin, double dYMin,
906 : double dXMax, double dYMax);
907 :
908 : int GetMapObjectSize(int nObjType);
909 : GBool MapObjectUsesCoordBlock(int nObjType);
910 :
911 : int GetProjInfo(TABProjInfo *psProjInfo);
912 : int SetProjInfo(TABProjInfo *psProjInfo);
913 :
914 : #ifdef DEBUG
915 : virtual void Dump(FILE *fpOut = NULL);
916 : #endif
917 :
918 : // Instead of having over 30 get/set methods, we'll make all data
919 : // members public and we will initialize them in the overloaded
920 : // LoadFromFile(). For this reason, this class should be used with care.
921 :
922 : GInt16 m_nMAPVersionNumber;
923 : GInt16 m_nBlockSize;
924 :
925 : double m_dCoordsys2DistUnits;
926 : GInt32 m_nXMin;
927 : GInt32 m_nYMin;
928 : GInt32 m_nXMax;
929 : GInt32 m_nYMax;
930 : GBool m_bIntBoundsOverflow; // Set to TRUE if coordinates
931 : // outside of bounds were written
932 :
933 : GInt32 m_nFirstIndexBlock;
934 : GInt32 m_nFirstGarbageBlock;
935 : GInt32 m_nFirstToolBlock;
936 : GInt32 m_numPointObjects;
937 : GInt32 m_numLineObjects;
938 : GInt32 m_numRegionObjects;
939 : GInt32 m_numTextObjects;
940 : GInt32 m_nMaxCoordBufSize;
941 :
942 : GByte m_nDistUnitsCode; // See Appendix F
943 : GByte m_nMaxSpIndexDepth;
944 : GByte m_nCoordPrecision; // Num. decimal places on coord.
945 : GByte m_nCoordOriginQuadrant;
946 : GByte m_nReflectXAxisCoord;
947 : GByte m_nMaxObjLenArrayId; // See gabyObjLenArray[]
948 : GByte m_numPenDefs;
949 : GByte m_numBrushDefs;
950 : GByte m_numSymbolDefs;
951 : GByte m_numFontDefs;
952 : GInt16 m_numMapToolBlocks;
953 :
954 : double m_XScale;
955 : double m_YScale;
956 : double m_XDispl;
957 : double m_YDispl;
958 :
959 : };
960 :
961 : /*---------------------------------------------------------------------
962 : * class TABMAPIndexBlock
963 : *
964 : * Class to handle Read/Write operation on .MAP Index Blocks (Type 01)
965 : *--------------------------------------------------------------------*/
966 :
967 : class TABMAPIndexBlock: public TABRawBinBlock
968 : {
969 : protected:
970 : int m_numEntries;
971 : TABMAPIndexEntry m_asEntries[TAB_MAX_ENTRIES_INDEX_BLOCK];
972 :
973 : int ReadNextEntry(TABMAPIndexEntry *psEntry);
974 : int WriteNextEntry(TABMAPIndexEntry *psEntry);
975 :
976 : // Use these to keep track of current block's MBR
977 : GInt32 m_nMinX;
978 : GInt32 m_nMinY;
979 : GInt32 m_nMaxX;
980 : GInt32 m_nMaxY;
981 :
982 : TABBinBlockManager *m_poBlockManagerRef;
983 :
984 : // Info about child currently loaded
985 : TABMAPIndexBlock *m_poCurChild;
986 : int m_nCurChildIndex;
987 : // Also need to know about its parent
988 : TABMAPIndexBlock *m_poParentRef;
989 :
990 : int ReadAllEntries();
991 :
992 : public:
993 : TABMAPIndexBlock(TABAccess eAccessMode = TABRead);
994 : ~TABMAPIndexBlock();
995 :
996 : virtual int InitBlockFromData(GByte *pabyBuf,
997 : int nBlockSize, int nSizeUsed,
998 : GBool bMakeCopy = TRUE,
999 : FILE *fpSrc = NULL, int nOffset = 0);
1000 : virtual int InitNewBlock(FILE *fpSrc, int nBlockSize, int nFileOffset=0);
1001 : virtual int CommitToFile();
1002 :
1003 0 : virtual int GetBlockClass() { return TABMAP_INDEX_BLOCK; };
1004 :
1005 : int GetNumFreeEntries();
1006 4 : int GetNumEntries() {return m_numEntries;};
1007 : TABMAPIndexEntry *GetEntry( int iIndex );
1008 : int AddEntry(GInt32 XMin, GInt32 YMin,
1009 : GInt32 XMax, GInt32 YMax,
1010 : GInt32 nBlockPtr,
1011 : GBool bAddInThisNodeOnly=FALSE);
1012 : int GetCurMaxDepth();
1013 : void GetMBR(GInt32 &nXMin, GInt32 &nYMin,
1014 : GInt32 &nXMax, GInt32 &nYMax);
1015 4 : GInt32 GetNodeBlockPtr() { return GetStartAddress();};
1016 :
1017 : void SetMAPBlockManagerRef(TABBinBlockManager *poBlockMgr);
1018 : void SetParentRef(TABMAPIndexBlock *poParent);
1019 : void SetCurChildRef(TABMAPIndexBlock *poChild, int nChildIndex);
1020 :
1021 4 : int GetCurChildIndex() { return m_nCurChildIndex; }
1022 : TABMAPIndexBlock *GetCurChild() { return m_poCurChild; }
1023 2 : TABMAPIndexBlock *GetParentRef() { return m_poParentRef; }
1024 :
1025 : int SplitNode(GInt32 nNewEntryXMin, GInt32 nNewEntryYMin,
1026 : GInt32 nNewEntryXMax, GInt32 nNewEntryYMax);
1027 : int SplitRootNode(GInt32 nNewEntryXMin, GInt32 nNewEntryYMin,
1028 : GInt32 nNewEntryXMax, GInt32 nNewEntryYMax);
1029 : void UpdateCurChildMBR(GInt32 nXMin, GInt32 nYMin,
1030 : GInt32 nXMax, GInt32 nYMax,
1031 : GInt32 nBlockPtr);
1032 : void RecomputeMBR();
1033 : int InsertEntry(GInt32 XMin, GInt32 YMin,
1034 : GInt32 XMax, GInt32 YMax, GInt32 nBlockPtr);
1035 : int ChooseSubEntryForInsert(GInt32 nXMin, GInt32 nYMin,
1036 : GInt32 nXMax, GInt32 nYMax);
1037 : GInt32 ChooseLeafForInsert(GInt32 nXMin, GInt32 nYMin,
1038 : GInt32 nXMax, GInt32 nYMax);
1039 : int UpdateLeafEntry(GInt32 nBlockPtr,
1040 : GInt32 nXMin, GInt32 nYMin,
1041 : GInt32 nXMax, GInt32 nYMax);
1042 : int GetCurLeafEntryMBR(GInt32 nBlockPtr,
1043 : GInt32 &nXMin, GInt32 &nYMin,
1044 : GInt32 &nXMax, GInt32 &nYMax);
1045 :
1046 : // Static utility functions for node splitting, also used by
1047 : // the TABMAPObjectBlock class.
1048 : static double ComputeAreaDiff(GInt32 nNodeXMin, GInt32 nNodeYMin,
1049 : GInt32 nNodeXMax, GInt32 nNodeYMax,
1050 : GInt32 nEntryXMin, GInt32 nEntryYMin,
1051 : GInt32 nEntryXMax, GInt32 nEntryYMax);
1052 : static int PickSeedsForSplit(TABMAPIndexEntry *pasEntries,
1053 : int numEntries,
1054 : int nSrcCurChildIndex,
1055 : GInt32 nNewEntryXMin,
1056 : GInt32 nNewEntryYMin,
1057 : GInt32 nNewEntryXMax,
1058 : GInt32 nNewEntryYMax,
1059 : int &nSeed1, int &nSeed2);
1060 : #ifdef DEBUG
1061 : virtual void Dump(FILE *fpOut = NULL);
1062 : #endif
1063 :
1064 : };
1065 :
1066 : /*---------------------------------------------------------------------
1067 : * class TABMAPObjectBlock
1068 : *
1069 : * Class to handle Read/Write operation on .MAP Object data Blocks (Type 02)
1070 : *--------------------------------------------------------------------*/
1071 :
1072 : class TABMAPObjectBlock: public TABRawBinBlock
1073 : {
1074 : protected:
1075 : int m_numDataBytes; /* Excluding first 4 bytes header */
1076 : GInt32 m_nFirstCoordBlock;
1077 : GInt32 m_nLastCoordBlock;
1078 : GInt32 m_nCenterX;
1079 : GInt32 m_nCenterY;
1080 :
1081 : // In order to compute block center, we need to keep track of MBR
1082 : GInt32 m_nMinX;
1083 : GInt32 m_nMinY;
1084 : GInt32 m_nMaxX;
1085 : GInt32 m_nMaxY;
1086 :
1087 : // Keep track of current object either in read or read/write mode
1088 : int m_nCurObjectOffset; // -1 if there is no current object.
1089 : int m_nCurObjectId; // -1 if there is no current object.
1090 : int m_nCurObjectType; // -1 if there is no current object.
1091 :
1092 : public:
1093 : TABMAPObjectBlock(TABAccess eAccessMode = TABRead);
1094 : ~TABMAPObjectBlock();
1095 :
1096 : virtual int CommitToFile();
1097 : virtual int InitBlockFromData(GByte *pabyBuf,
1098 : int nBlockSize, int nSizeUsed,
1099 : GBool bMakeCopy = TRUE,
1100 : FILE *fpSrc = NULL, int nOffset = 0);
1101 : virtual int InitNewBlock(FILE *fpSrc, int nBlockSize, int nFileOffset=0);
1102 :
1103 0 : virtual int GetBlockClass() { return TABMAP_OBJECT_BLOCK; };
1104 :
1105 : virtual int ReadIntCoord(GBool bCompressed, GInt32 &nX, GInt32 &nY);
1106 : int WriteIntCoord(GInt32 nX, GInt32 nY, GBool bCompressed);
1107 : int WriteIntMBRCoord(GInt32 nXMin, GInt32 nYMin,
1108 : GInt32 nXMax, GInt32 nYMax,
1109 : GBool bCompressed);
1110 : int UpdateMBR(GInt32 nX, GInt32 nY);
1111 :
1112 : int PrepareNewObject(TABMAPObjHdr *poObjHdr);
1113 : int CommitNewObject(TABMAPObjHdr *poObjHdr);
1114 :
1115 : void AddCoordBlockRef(GInt32 nCoordBlockAddress);
1116 0 : GInt32 GetFirstCoordBlockAddress() { return m_nFirstCoordBlock; }
1117 0 : GInt32 GetLastCoordBlockAddress() { return m_nLastCoordBlock; }
1118 :
1119 : void GetMBR(GInt32 &nXMin, GInt32 &nYMin,
1120 : GInt32 &nXMax, GInt32 &nYMax);
1121 : void SetMBR(GInt32 nXMin, GInt32 nYMin,
1122 : GInt32 nXMax, GInt32 nYMax);
1123 :
1124 : void Rewind();
1125 : int AdvanceToNextObject( TABMAPHeaderBlock * );
1126 20 : int GetCurObjectOffset() { return m_nCurObjectOffset; }
1127 20 : int GetCurObjectId() { return m_nCurObjectId; }
1128 20 : int GetCurObjectType() { return m_nCurObjectType; }
1129 :
1130 : #ifdef DEBUG
1131 0 : virtual void Dump(FILE *fpOut = NULL) { Dump(fpOut, FALSE); };
1132 : void Dump(FILE *fpOut, GBool bDetails);
1133 : #endif
1134 :
1135 : };
1136 :
1137 : /*---------------------------------------------------------------------
1138 : * class TABMAPCoordBlock
1139 : *
1140 : * Class to handle Read/Write operation on .MAP Coordinate Blocks (Type 03)
1141 : *--------------------------------------------------------------------*/
1142 :
1143 : class TABMAPCoordBlock: public TABRawBinBlock
1144 : {
1145 : protected:
1146 : int m_numDataBytes; /* Excluding first 8 bytes header */
1147 : GInt32 m_nNextCoordBlock;
1148 : int m_numBlocksInChain;
1149 :
1150 : GInt32 m_nComprOrgX;
1151 : GInt32 m_nComprOrgY;
1152 :
1153 : // In order to compute block center, we need to keep track of MBR
1154 : GInt32 m_nMinX;
1155 : GInt32 m_nMinY;
1156 : GInt32 m_nMaxX;
1157 : GInt32 m_nMaxY;
1158 :
1159 : TABBinBlockManager *m_poBlockManagerRef;
1160 :
1161 : int m_nTotalDataSize; // Num bytes in whole chain of blocks
1162 : int m_nFeatureDataSize; // Num bytes for current feature coords
1163 :
1164 : GInt32 m_nFeatureXMin; // Used to keep track of current
1165 : GInt32 m_nFeatureYMin; // feature MBR.
1166 : GInt32 m_nFeatureXMax;
1167 : GInt32 m_nFeatureYMax;
1168 :
1169 : public:
1170 : TABMAPCoordBlock(TABAccess eAccessMode = TABRead);
1171 : ~TABMAPCoordBlock();
1172 :
1173 : virtual int InitBlockFromData(GByte *pabyBuf,
1174 : int nBlockSize, int nSizeUsed,
1175 : GBool bMakeCopy = TRUE,
1176 : FILE *fpSrc = NULL, int nOffset = 0);
1177 : virtual int InitNewBlock(FILE *fpSrc, int nBlockSize, int nFileOffset=0);
1178 : virtual int CommitToFile();
1179 :
1180 0 : virtual int GetBlockClass() { return TABMAP_COORD_BLOCK; };
1181 :
1182 : void SetMAPBlockManagerRef(TABBinBlockManager *poBlockManager);
1183 : virtual int ReadBytes(int numBytes, GByte *pabyDstBuf);
1184 : virtual int WriteBytes(int nBytesToWrite, GByte *pBuf);
1185 : void SetComprCoordOrigin(GInt32 nX, GInt32 nY);
1186 : int ReadIntCoord(GBool bCompressed, GInt32 &nX, GInt32 &nY);
1187 : int ReadIntCoords(GBool bCompressed, int numCoords, GInt32 *panXY);
1188 : int ReadCoordSecHdrs(GBool bCompressed, int nVersion,
1189 : int numSections, TABMAPCoordSecHdr *pasHdrs,
1190 : GInt32 &numVerticesTotal);
1191 : int WriteCoordSecHdrs(int nVersion, int numSections,
1192 : TABMAPCoordSecHdr *pasHdrs,
1193 : GBool bCompressed);
1194 :
1195 : void SetNextCoordBlock(GInt32 nNextCoordBlockAddress);
1196 0 : GInt32 GetNextCoordBlock() { return m_nNextCoordBlock; };
1197 :
1198 : int WriteIntCoord(GInt32 nX, GInt32 nY, GBool bCompressed);
1199 :
1200 4 : int GetNumBlocksInChain() { return m_numBlocksInChain; };
1201 :
1202 : void ResetTotalDataSize() {m_nTotalDataSize = 0;};
1203 : int GetTotalDataSize() {return m_nTotalDataSize;};
1204 :
1205 : void SeekEnd();
1206 : void StartNewFeature();
1207 22 : int GetFeatureDataSize() {return m_nFeatureDataSize;};
1208 : //__TODO__ Can we flush GetFeatureMBR() and all MBR tracking in this class???
1209 : void GetFeatureMBR(GInt32 &nXMin, GInt32 &nYMin,
1210 : GInt32 &nXMax, GInt32 &nYMax);
1211 :
1212 : #ifdef DEBUG
1213 : virtual void Dump(FILE *fpOut = NULL);
1214 : #endif
1215 :
1216 : };
1217 :
1218 : /*---------------------------------------------------------------------
1219 : * class TABMAPToolBlock
1220 : *
1221 : * Class to handle Read/Write operation on .MAP Drawing Tool Blocks (Type 05)
1222 : *
1223 : * In addition to handling the I/O, this class also maintains the list
1224 : * of Tool definitions in memory.
1225 : *--------------------------------------------------------------------*/
1226 :
1227 : class TABMAPToolBlock: public TABRawBinBlock
1228 : {
1229 : protected:
1230 : int m_numDataBytes; /* Excluding first 8 bytes header */
1231 : GInt32 m_nNextToolBlock;
1232 : int m_numBlocksInChain;
1233 :
1234 : TABBinBlockManager *m_poBlockManagerRef;
1235 :
1236 : public:
1237 : TABMAPToolBlock(TABAccess eAccessMode = TABRead);
1238 : ~TABMAPToolBlock();
1239 :
1240 : virtual int InitBlockFromData(GByte *pabyBuf,
1241 : int nBlockSize, int nSizeUsed,
1242 : GBool bMakeCopy = TRUE,
1243 : FILE *fpSrc = NULL, int nOffset = 0);
1244 : virtual int InitNewBlock(FILE *fpSrc, int nBlockSize, int nFileOffset=0);
1245 : virtual int CommitToFile();
1246 :
1247 0 : virtual int GetBlockClass() { return TABMAP_TOOL_BLOCK; };
1248 :
1249 : void SetMAPBlockManagerRef(TABBinBlockManager *poBlockManager);
1250 : virtual int ReadBytes(int numBytes, GByte *pabyDstBuf);
1251 : virtual int WriteBytes(int nBytesToWrite, GByte *pBuf);
1252 :
1253 : void SetNextToolBlock(GInt32 nNextCoordBlockAddress);
1254 :
1255 : GBool EndOfChain();
1256 4 : int GetNumBlocksInChain() { return m_numBlocksInChain; };
1257 :
1258 : int CheckAvailableSpace(int nToolType);
1259 :
1260 : #ifdef DEBUG
1261 : virtual void Dump(FILE *fpOut = NULL);
1262 : #endif
1263 :
1264 : };
1265 :
1266 :
1267 : /*=====================================================================
1268 : Classes to deal with .MAP files at the MapInfo object level
1269 : =====================================================================*/
1270 :
1271 : /*---------------------------------------------------------------------
1272 : * class TABIDFile
1273 : *
1274 : * Class to handle Read/Write operation on .ID files... the .ID file
1275 : * contains an index to the objects in the .MAP file by object id.
1276 : *--------------------------------------------------------------------*/
1277 :
1278 : class TABIDFile
1279 : {
1280 : private:
1281 : char *m_pszFname;
1282 : FILE *m_fp;
1283 : TABAccess m_eAccessMode;
1284 :
1285 : TABRawBinBlock *m_poIDBlock;
1286 : int m_nBlockSize;
1287 : GInt32 m_nMaxId;
1288 :
1289 : public:
1290 : TABIDFile();
1291 : ~TABIDFile();
1292 :
1293 : int Open(const char *pszFname, const char *pszAccess);
1294 : int Close();
1295 :
1296 : GInt32 GetObjPtr(GInt32 nObjId);
1297 : int SetObjPtr(GInt32 nObjId, GInt32 nObjPtr);
1298 : GInt32 GetMaxObjId();
1299 :
1300 : #ifdef DEBUG
1301 : void Dump(FILE *fpOut = NULL);
1302 : #endif
1303 :
1304 : };
1305 :
1306 : /*---------------------------------------------------------------------
1307 : * class TABMAPFile
1308 : *
1309 : * Class to handle Read/Write operation on .MAP files... this class hides
1310 : * all the dealings with blocks, indexes, etc.
1311 : * Use this class to deal with MapInfo objects directly.
1312 : *--------------------------------------------------------------------*/
1313 :
1314 : class TABMAPFile
1315 : {
1316 : private:
1317 : int m_nMinTABVersion;
1318 : char *m_pszFname;
1319 : FILE *m_fp;
1320 : TABAccess m_eAccessMode;
1321 :
1322 : TABBinBlockManager m_oBlockManager;
1323 :
1324 : TABMAPHeaderBlock *m_poHeader;
1325 :
1326 : // Members used to access objects using the spatial index
1327 : TABMAPIndexBlock *m_poSpIndex;
1328 :
1329 : // Defaults to FALSE, i.e. optimized spatial index
1330 : GBool m_bQuickSpatialIndexMode;
1331 :
1332 : // Member used to access objects using the object ids (.ID file)
1333 : TABIDFile *m_poIdIndex;
1334 :
1335 : // Current object data block.
1336 : TABMAPObjectBlock *m_poCurObjBlock;
1337 : int m_nCurObjPtr;
1338 : int m_nCurObjType;
1339 : int m_nCurObjId;
1340 : TABMAPCoordBlock *m_poCurCoordBlock;
1341 :
1342 : // Drawing Tool Def. table (takes care of all drawing tools in memory)
1343 : TABToolDefTable *m_poToolDefTable;
1344 :
1345 : // Coordinates filter... default is MBR of the whole file
1346 : TABVertex m_sMinFilter;
1347 : TABVertex m_sMaxFilter;
1348 : GInt32 m_XMinFilter;
1349 : GInt32 m_YMinFilter;
1350 : GInt32 m_XMaxFilter;
1351 : GInt32 m_YMaxFilter;
1352 :
1353 : int CommitObjAndCoordBlocks(GBool bDeleteObjects =FALSE);
1354 : int LoadObjAndCoordBlocks(GInt32 nBlockPtr);
1355 : TABMAPObjectBlock *SplitObjBlock(TABMAPObjHdr *poObjHdrToAdd,
1356 : int nSizeOfObjToAdd);
1357 : int MoveObjToBlock(TABMAPObjHdr *poObjHdr,
1358 : TABMAPCoordBlock *poSrcCoordBlock,
1359 : TABMAPObjectBlock *poDstObjBlock,
1360 : TABMAPCoordBlock **ppoDstCoordBlock);
1361 : int PrepareCoordBlock(int nObjType,
1362 : TABMAPObjectBlock *poObjBlock,
1363 : TABMAPCoordBlock **ppoCoordBlock);
1364 :
1365 : int InitDrawingTools();
1366 : int CommitDrawingTools();
1367 :
1368 : int CommitSpatialIndex();
1369 :
1370 : // Stuff related to traversing spatial index.
1371 : TABMAPIndexBlock *m_poSpIndexLeaf;
1372 :
1373 : int LoadNextMatchingObjectBlock(int bFirstObject);
1374 : TABRawBinBlock *PushBlock( int nFileOffset );
1375 :
1376 : public:
1377 : TABMAPFile();
1378 : ~TABMAPFile();
1379 :
1380 : int Open(const char *pszFname, const char *pszAccess,
1381 : GBool bNoErrorMsg = FALSE );
1382 : int Close();
1383 :
1384 : int SetQuickSpatialIndexMode(GBool bQuickSpatialIndexMode = TRUE);
1385 :
1386 : int Int2Coordsys(GInt32 nX, GInt32 nY, double &dX, double &dY);
1387 : int Coordsys2Int(double dX, double dY, GInt32 &nX, GInt32 &nY,
1388 : GBool bIgnoreOveflow=FALSE);
1389 : int Int2CoordsysDist(GInt32 nX, GInt32 nY, double &dX, double &dY);
1390 : int Coordsys2IntDist(double dX, double dY, GInt32 &nX, GInt32 &nY);
1391 : void SetCoordFilter(TABVertex sMin, TABVertex sMax);
1392 : void GetCoordFilter(TABVertex &sMin, TABVertex &sMax);
1393 : void ResetCoordFilter();
1394 : int SetCoordsysBounds(double dXMin, double dYMin,
1395 : double dXMax, double dYMax);
1396 :
1397 : GInt32 GetMaxObjId();
1398 : int MoveToObjId(int nObjId);
1399 : void UpdateMapHeaderInfo(GByte nObjType);
1400 : int PrepareNewObj(TABMAPObjHdr *poObjHdr);
1401 : int PrepareNewObjViaSpatialIndex(TABMAPObjHdr *poObjHdr);
1402 : int PrepareNewObjViaObjBlock(TABMAPObjHdr *poObjHdr);
1403 : int CommitNewObj(TABMAPObjHdr *poObjHdr);
1404 :
1405 : void ResetReading();
1406 : int GetNextFeatureId( int nPrevId );
1407 :
1408 : int GetCurObjType();
1409 : int GetCurObjId();
1410 : TABMAPObjectBlock *GetCurObjBlock();
1411 : TABMAPCoordBlock *GetCurCoordBlock();
1412 : TABMAPCoordBlock *GetCoordBlock(int nFileOffset);
1413 : TABMAPHeaderBlock *GetHeaderBlock();
1414 : TABIDFile *GetIDFileRef();
1415 : TABRawBinBlock *GetIndexObjectBlock(int nFileOffset);
1416 :
1417 : int ReadPenDef(int nPenIndex, TABPenDef *psDef);
1418 : int ReadBrushDef(int nBrushIndex, TABBrushDef *psDef);
1419 : int ReadFontDef(int nFontIndex, TABFontDef *psDef);
1420 : int ReadSymbolDef(int nSymbolIndex, TABSymbolDef *psDef);
1421 : int WritePenDef(TABPenDef *psDef);
1422 : int WriteBrushDef(TABBrushDef *psDef);
1423 : int WriteFontDef(TABFontDef *psDef);
1424 : int WriteSymbolDef(TABSymbolDef *psDef);
1425 :
1426 : int GetMinTABFileVersion();
1427 :
1428 : #ifdef DEBUG
1429 : void Dump(FILE *fpOut = NULL);
1430 : void DumpSpatialIndexToMIF(TABMAPIndexBlock *poNode,
1431 : FILE *fpMIF, FILE *fpMID,
1432 : int nIndexInNode=-1,
1433 : int nParentId=-1,
1434 : int nCurDepth=0,
1435 : int nMaxDepth=-1);
1436 : #endif
1437 :
1438 : };
1439 :
1440 :
1441 :
1442 : /*---------------------------------------------------------------------
1443 : * class TABINDNode
1444 : *
1445 : * An index node in a .IND file.
1446 : *
1447 : * This class takes care of reading child nodes as necessary when looking
1448 : * for a given key value in the index tree.
1449 : *--------------------------------------------------------------------*/
1450 :
1451 : class TABINDNode
1452 : {
1453 : private:
1454 : FILE *m_fp;
1455 : TABAccess m_eAccessMode;
1456 : TABINDNode *m_poCurChildNode;
1457 : TABINDNode *m_poParentNodeRef;
1458 :
1459 : TABBinBlockManager *m_poBlockManagerRef;
1460 :
1461 : int m_nSubTreeDepth;
1462 : int m_nKeyLength;
1463 : TABFieldType m_eFieldType;
1464 : GBool m_bUnique;
1465 :
1466 : GInt32 m_nCurDataBlockPtr;
1467 : int m_nCurIndexEntry;
1468 : TABRawBinBlock *m_poDataBlock;
1469 : int m_numEntriesInNode;
1470 : GInt32 m_nPrevNodePtr;
1471 : GInt32 m_nNextNodePtr;
1472 :
1473 : int GotoNodePtr(GInt32 nNewNodePtr);
1474 : GInt32 ReadIndexEntry(int nEntryNo, GByte *pKeyValue);
1475 : int IndexKeyCmp(GByte *pKeyValue, int nEntryNo);
1476 :
1477 : int InsertEntry(GByte *pKeyValue, GInt32 nRecordNo,
1478 : GBool bInsertAfterCurChild=FALSE,
1479 : GBool bMakeNewEntryCurChild=FALSE);
1480 : int SetNodeBufferDirectly(int numEntries, GByte *pBuf,
1481 : int nCurIndexEntry=0,
1482 : TABINDNode *poCurChild=NULL);
1483 :
1484 : public:
1485 : TABINDNode(TABAccess eAccessMode = TABRead);
1486 : ~TABINDNode();
1487 :
1488 : int InitNode(FILE *fp, int nBlockPtr,
1489 : int nKeyLength, int nSubTreeDepth, GBool bUnique,
1490 : TABBinBlockManager *poBlockMgr=NULL,
1491 : TABINDNode *poParentNode=NULL,
1492 : int nPrevNodePtr=0, int nNextNodePtr=0);
1493 :
1494 : int SetFieldType(TABFieldType eType);
1495 : TABFieldType GetFieldType() {return m_eFieldType;};
1496 :
1497 0 : void SetUnique(GBool bUnique){m_bUnique = bUnique;};
1498 : GBool IsUnique() {return m_bUnique;};
1499 :
1500 268 : int GetKeyLength() {return m_nKeyLength;};
1501 48 : int GetSubTreeDepth() {return m_nSubTreeDepth;};
1502 24 : GInt32 GetNodeBlockPtr() {return m_nCurDataBlockPtr;};
1503 368 : int GetNumEntries() {return m_numEntriesInNode;};
1504 392 : int GetMaxNumEntries() {return (512-12)/(m_nKeyLength+4);};
1505 :
1506 : GInt32 FindFirst(GByte *pKeyValue);
1507 : GInt32 FindNext(GByte *pKeyValue);
1508 :
1509 : int CommitToFile();
1510 :
1511 : int AddEntry(GByte *pKeyValue, GInt32 nRecordNo,
1512 : GBool bAddInThisNodeOnly=FALSE,
1513 : GBool bInsertAfterCurChild=FALSE,
1514 : GBool bMakeNewEntryCurChild=FALSE);
1515 : int SplitNode();
1516 : int SplitRootNode();
1517 : GByte* GetNodeKey();
1518 : int UpdateCurChildEntry(GByte *pKeyValue, GInt32 nRecordNo);
1519 : int UpdateSplitChild(GByte *pKeyValue1, GInt32 nRecordNo1,
1520 : GByte *pKeyValue2, GInt32 nRecordNo2,
1521 : int nNewCurChildNo /* 1 or 2 */);
1522 :
1523 : int SetNodeBlockPtr(GInt32 nThisNodePtr);
1524 : int SetPrevNodePtr(GInt32 nPrevNodePtr);
1525 : int SetNextNodePtr(GInt32 nNextNodePtr);
1526 :
1527 : #ifdef DEBUG
1528 : void Dump(FILE *fpOut = NULL);
1529 : #endif
1530 :
1531 : };
1532 :
1533 :
1534 : /*---------------------------------------------------------------------
1535 : * class TABINDFile
1536 : *
1537 : * Class to handle table field index (.IND) files... we use this
1538 : * class as the main entry point to open and search the table field indexes.
1539 : * Note that .IND files are supported for read access only.
1540 : *--------------------------------------------------------------------*/
1541 :
1542 : class TABINDFile
1543 : {
1544 : private:
1545 : char *m_pszFname;
1546 : FILE *m_fp;
1547 : TABAccess m_eAccessMode;
1548 :
1549 : TABBinBlockManager m_oBlockManager;
1550 :
1551 : int m_numIndexes;
1552 : TABINDNode **m_papoIndexRootNodes;
1553 : GByte **m_papbyKeyBuffers;
1554 :
1555 : int ValidateIndexNo(int nIndexNumber);
1556 : int ReadHeader();
1557 : int WriteHeader();
1558 :
1559 : public:
1560 : TABINDFile();
1561 : ~TABINDFile();
1562 :
1563 : int Open(const char *pszFname, const char *pszAccess,
1564 : GBool bTestOpenNoError=FALSE);
1565 : int Close();
1566 :
1567 : int GetNumIndexes() {return m_numIndexes;};
1568 : int SetIndexFieldType(int nIndexNumber, TABFieldType eType);
1569 : int SetIndexUnique(int nIndexNumber, GBool bUnique=TRUE);
1570 : GByte *BuildKey(int nIndexNumber, GInt32 nValue);
1571 : GByte *BuildKey(int nIndexNumber, const char *pszStr);
1572 : GByte *BuildKey(int nIndexNumber, double dValue);
1573 : GInt32 FindFirst(int nIndexNumber, GByte *pKeyValue);
1574 : GInt32 FindNext(int nIndexNumber, GByte *pKeyValue);
1575 :
1576 : int CreateIndex(TABFieldType eType, int nFieldSize);
1577 : int AddEntry(int nIndexNumber, GByte *pKeyValue, GInt32 nRecordNo);
1578 :
1579 : #ifdef DEBUG
1580 : void Dump(FILE *fpOut = NULL);
1581 : #endif
1582 :
1583 : };
1584 :
1585 :
1586 : /*---------------------------------------------------------------------
1587 : * class TABDATFile
1588 : *
1589 : * Class to handle Read/Write operation on .DAT files... the .DAT file
1590 : * contains the table of attribute field values.
1591 : *--------------------------------------------------------------------*/
1592 :
1593 : class TABDATFile
1594 : {
1595 : private:
1596 : char *m_pszFname;
1597 : FILE *m_fp;
1598 : TABAccess m_eAccessMode;
1599 : TABTableType m_eTableType;
1600 :
1601 : TABRawBinBlock *m_poHeaderBlock;
1602 : int m_numFields;
1603 : TABDATFieldDef *m_pasFieldDef;
1604 :
1605 : TABRawBinBlock *m_poRecordBlock;
1606 : int m_nBlockSize;
1607 : int m_nRecordSize;
1608 : int m_nCurRecordId;
1609 : GBool m_bCurRecordDeletedFlag;
1610 :
1611 : GInt32 m_numRecords;
1612 : GInt32 m_nFirstRecordPtr;
1613 : GBool m_bWriteHeaderInitialized;
1614 :
1615 : int InitWriteHeader();
1616 : int WriteHeader();
1617 :
1618 : // We know that character strings are limited to 254 chars in MapInfo
1619 : // Using a buffer pr. class instance to avoid threading issues with the library
1620 : char m_szBuffer[256];
1621 :
1622 : public:
1623 : TABDATFile();
1624 : ~TABDATFile();
1625 :
1626 : int Open(const char *pszFname, const char *pszAccess,
1627 : TABTableType eTableType =TABTableNative);
1628 : int Close();
1629 :
1630 : int GetNumFields();
1631 : TABFieldType GetFieldType(int nFieldId);
1632 : int GetFieldWidth(int nFieldId);
1633 : int GetFieldPrecision(int nFieldId);
1634 : int ValidateFieldInfoFromTAB(int iField, const char *pszName,
1635 : TABFieldType eType,
1636 : int nWidth, int nPrecision);
1637 :
1638 : int AddField(const char *pszName, TABFieldType eType,
1639 : int nWidth, int nPrecision=0);
1640 :
1641 : GInt32 GetNumRecords();
1642 : TABRawBinBlock *GetRecordBlock(int nRecordId);
1643 108 : GBool IsCurrentRecordDeleted() { return m_bCurRecordDeletedFlag;};
1644 : int CommitRecordToFile();
1645 :
1646 : const char *ReadCharField(int nWidth);
1647 : GInt32 ReadIntegerField(int nWidth);
1648 : GInt16 ReadSmallIntField(int nWidth);
1649 : double ReadFloatField(int nWidth);
1650 : double ReadDecimalField(int nWidth);
1651 : const char *ReadLogicalField(int nWidth);
1652 : const char *ReadDateField(int nWidth);
1653 : int ReadDateField(int nWidth, int *nYear, int *nMonth, int *nDay);
1654 : const char *ReadTimeField(int nWidth);
1655 : int ReadTimeField(int nWidth, int *nHour, int *nMinute,
1656 : int *nSecond, int *nMS);
1657 : const char *ReadDateTimeField(int nWidth);
1658 : int ReadDateTimeField(int nWidth, int *nYear, int *nMonth, int *nDay,
1659 : int *nHour, int *nMinute, int *nSecond, int *nMS);
1660 :
1661 : int WriteCharField(const char *pszValue, int nWidth,
1662 : TABINDFile *poINDFile, int nIndexNo);
1663 : int WriteIntegerField(GInt32 nValue,
1664 : TABINDFile *poINDFile, int nIndexNo);
1665 : int WriteSmallIntField(GInt16 nValue,
1666 : TABINDFile *poINDFile, int nIndexNo);
1667 : int WriteFloatField(double dValue,
1668 : TABINDFile *poINDFile, int nIndexNo);
1669 : int WriteDecimalField(double dValue, int nWidth, int nPrecision,
1670 : TABINDFile *poINDFile, int nIndexNo);
1671 : int WriteLogicalField(const char *pszValue,
1672 : TABINDFile *poINDFile, int nIndexNo);
1673 : int WriteDateField(const char *pszValue,
1674 : TABINDFile *poINDFile, int nIndexNo);
1675 : int WriteDateField(int nYear, int nMonth, int nDay,
1676 : TABINDFile *poINDFile, int nIndexNo);
1677 : int WriteTimeField(const char *pszValue,
1678 : TABINDFile *poINDFile, int nIndexNo);
1679 : int WriteTimeField(int nHour, int nMinute, int nSecond, int nMS,
1680 : TABINDFile *poINDFile, int nIndexNo);
1681 : int WriteDateTimeField(const char *pszValue,
1682 : TABINDFile *poINDFile, int nIndexNo);
1683 : int WriteDateTimeField(int nYear, int nMonth, int nDay,
1684 : int nHour, int nMinute, int nSecond, int nMS,
1685 : TABINDFile *poINDFile, int nIndexNo);
1686 :
1687 : #ifdef DEBUG
1688 : void Dump(FILE *fpOut = NULL);
1689 : #endif
1690 :
1691 : };
1692 :
1693 :
1694 : /*---------------------------------------------------------------------
1695 : * class TABRelation
1696 : *
1697 : * Class that maintains a relation between 2 tables through a field
1698 : * in each table (the SQL "where table1.field1=table2.field2" found in
1699 : * TABView datasets).
1700 : *
1701 : * An instance of this class is used to read data records from the
1702 : * combined tables as if they were a single one.
1703 : *--------------------------------------------------------------------*/
1704 :
1705 : class TABRelation
1706 : {
1707 : private:
1708 : /* Information about the main table.
1709 : */
1710 : TABFile *m_poMainTable;
1711 : char *m_pszMainFieldName;
1712 : int m_nMainFieldNo;
1713 :
1714 : /* Information about the related table.
1715 : * NOTE: The related field MUST be indexed.
1716 : */
1717 : TABFile *m_poRelTable;
1718 : char *m_pszRelFieldName;
1719 : int m_nRelFieldNo;
1720 :
1721 : TABINDFile *m_poRelINDFileRef;
1722 : int m_nRelFieldIndexNo;
1723 :
1724 : int m_nUniqueRecordNo;
1725 :
1726 : /* Main and Rel table field map:
1727 : * For each field in the source tables, -1 means that the field is not
1728 : * selected, and a value >=0 is the index of this field in the combined
1729 : * FeatureDefn
1730 : */
1731 : int *m_panMainTableFieldMap;
1732 : int *m_panRelTableFieldMap;
1733 :
1734 : OGRFeatureDefn *m_poDefn;
1735 :
1736 : void ResetAllMembers();
1737 : GByte *BuildFieldKey(TABFeature *poFeature, int nFieldNo,
1738 : TABFieldType eType, int nIndexNo);
1739 :
1740 : public:
1741 : TABRelation();
1742 : ~TABRelation();
1743 :
1744 : int Init(const char *pszViewName,
1745 : TABFile *poMainTable, TABFile *poRelTable,
1746 : const char *pszMainFieldName,
1747 : const char *pszRelFieldName,
1748 : char **papszSelectedFields);
1749 : int CreateRelFields();
1750 :
1751 0 : OGRFeatureDefn *GetFeatureDefn() {return m_poDefn;};
1752 : TABFieldType GetNativeFieldType(int nFieldId);
1753 : TABFeature *GetFeature(int nFeatureId);
1754 :
1755 : int WriteFeature(TABFeature *poFeature, int nFeatureId=-1);
1756 :
1757 : int SetFeatureDefn(OGRFeatureDefn *poFeatureDefn,
1758 : TABFieldType *paeMapInfoNativeFieldTypes=NULL);
1759 : int AddFieldNative(const char *pszName, TABFieldType eMapInfoType,
1760 : int nWidth=0, int nPrecision=0,
1761 : GBool bIndexed=FALSE, GBool bUnique=FALSE, int bApproxOK=TRUE);
1762 :
1763 : int SetFieldIndexed(int nFieldId);
1764 : GBool IsFieldIndexed(int nFieldId);
1765 : GBool IsFieldUnique(int nFieldId);
1766 :
1767 0 : const char *GetMainFieldName() {return m_pszMainFieldName;};
1768 0 : const char *GetRelFieldName() {return m_pszRelFieldName;};
1769 : };
1770 :
1771 :
1772 : /*---------------------------------------------------------------------
1773 : * class MIDDATAFile
1774 : *
1775 : * Class to handle a file pointer with a copy of the latest readed line
1776 : *
1777 : *--------------------------------------------------------------------*/
1778 :
1779 : class MIDDATAFile
1780 : {
1781 : public:
1782 : MIDDATAFile();
1783 : ~MIDDATAFile();
1784 :
1785 : int Open(const char *pszFname, const char *pszAccess);
1786 : int Close();
1787 :
1788 : const char *GetLine();
1789 : const char *GetLastLine();
1790 : int Rewind();
1791 : void SaveLine(const char *pszLine);
1792 : const char *GetSavedLine();
1793 : void WriteLine(const char*, ...);
1794 : GBool IsValidFeature(const char *pszString);
1795 :
1796 : // Translation information
1797 : void SetTranslation(double, double, double, double);
1798 : double GetXTrans(double);
1799 : double GetYTrans(double);
1800 0 : double GetXMultiplier(){return m_dfXMultiplier;}
1801 130 : const char *GetDelimiter(){return m_pszDelimiter;}
1802 80 : void SetDelimiter(const char *pszDelimiter){m_pszDelimiter=pszDelimiter;}
1803 :
1804 : void SetEof(GBool bEof);
1805 : GBool GetEof();
1806 :
1807 : private:
1808 : FILE *m_fp;
1809 : const char *m_pszDelimiter;
1810 :
1811 : // Set limit for the length of a line
1812 : #define MIDMAXCHAR 10000
1813 : char m_szLastRead[MIDMAXCHAR];
1814 : char m_szSavedLine[MIDMAXCHAR];
1815 :
1816 : char *m_pszFname;
1817 : TABAccess m_eAccessMode;
1818 : double m_dfXMultiplier;
1819 : double m_dfYMultiplier;
1820 : double m_dfXDisplacement;
1821 : double m_dfYDisplacement;
1822 : GBool m_bEof;
1823 : };
1824 :
1825 :
1826 :
1827 : /*=====================================================================
1828 : Function prototypes
1829 : =====================================================================*/
1830 :
1831 : TABRawBinBlock *TABCreateMAPBlockFromFile(FILE *fpSrc, int nOffset,
1832 : int nSize = 512,
1833 : GBool bHardBlockSize = TRUE,
1834 : TABAccess eAccessMode = TABRead);
1835 :
1836 :
1837 : #endif /* _MITAB_PRIV_H_INCLUDED_ */
1838 :
|