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