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