1 /****************************************************************************** 2 * $Id: sdts_al.h 2ace03ec48c36dae8ba74089d85617c095643428 2018-11-02 18:02:33 +0100 Even Rouault $ 3 * 4 * Project: SDTS Translator 5 * Purpose: Include file for entire SDTS Abstraction Layer functions. 6 * Author: Frank Warmerdam, warmerdam@pobox.com 7 * 8 ****************************************************************************** 9 * Copyright (c) 1999, Frank Warmerdam 10 * 11 * Permission is hereby granted, free of charge, to any person obtaining a 12 * copy of this software and associated documentation files (the "Software"), 13 * to deal in the Software without restriction, including without limitation 14 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 15 * and/or sell copies of the Software, and to permit persons to whom the 16 * Software is furnished to do so, subject to the following conditions: 17 * 18 * The above copyright notice and this permission notice shall be included 19 * in all copies or substantial portions of the Software. 20 * 21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 22 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 24 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 26 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 27 * DEALINGS IN THE SOFTWARE. 28 ****************************************************************************/ 29 30 #ifndef SDTS_AL_H_INCLUDED 31 #define SDTS_AL_H_INCLUDED 32 33 #include "cpl_conv.h" 34 #include "iso8211.h" 35 36 class SDTS_IREF; 37 class SDTSModId; 38 class SDTSTransfer; 39 40 #define SDTS_SIZEOF_SADR 8 41 42 char **SDTSScanModuleReferences( DDFModule *, const char * ); 43 44 /************************************************************************/ 45 /* SDTS_IREF */ 46 /************************************************************************/ 47 48 /** 49 Class holding SDTS IREF (internal reference) information, internal 50 coordinate system format, scaling and resolution. This object isn't 51 normally needed by applications. 52 */ 53 class SDTS_IREF 54 { 55 int nDefaultSADRFormat; 56 57 public: 58 SDTS_IREF(); 59 ~SDTS_IREF(); 60 61 int Read( const char *pszFilename ); 62 63 char *pszXAxisName; /* XLBL */ 64 char *pszYAxisName; /* YLBL */ 65 66 double dfXScale; /* SFAX */ 67 double dfYScale; /* SFAY */ 68 69 double dfXOffset; /* XORG */ 70 double dfYOffset; /* YORG */ 71 72 double dfXRes; /* XHRS */ 73 double dfYRes; /* YHRS */ 74 75 char *pszCoordinateFormat; /* HFMT */ 76 77 int GetSADRCount( DDFField * ) const; 78 int GetSADR( DDFField *, int, double *, double *, double * ); 79 }; 80 81 /************************************************************************/ 82 /* SDTS_XREF */ 83 /************************************************************************/ 84 85 /** 86 Class for reading the XREF (external reference) module containing the 87 data projection definition. 88 */ 89 90 class SDTS_XREF 91 { 92 public: 93 SDTS_XREF(); 94 ~SDTS_XREF(); 95 96 int Read( const char *pszFilename ); 97 98 /** Projection system name, from the RSNM field. One of GEO, SPCS, UTM, 99 UPS, OTHR, UNSP. */ 100 char *pszSystemName; 101 102 /** Horizontal datum name, from the HDAT field. One of NAS, NAX, WGA, 103 WGB, WGC, WGE. */ 104 char *pszDatum; 105 106 /** Zone number for UTM and SPCS projections, from the ZONE field. */ 107 int nZone; 108 }; 109 110 /************************************************************************/ 111 /* SDTS_CATD */ 112 /************************************************************************/ 113 class SDTS_CATDEntry; 114 115 /** 116 List of feature layer types. See SDTSTransfer::GetLayerType(). 117 */ 118 119 typedef enum { 120 SLTUnknown, 121 SLTPoint, 122 SLTLine, 123 SLTAttr, 124 SLTPoly, 125 SLTRaster 126 } SDTSLayerType; 127 128 /** 129 Class for accessing the CATD (Catalog Directory) file containing a list of 130 all other files (modules) in the transfer. 131 */ 132 class SDTS_CATD 133 { 134 char *pszPrefixPath; 135 136 int nEntries; 137 SDTS_CATDEntry **papoEntries; 138 139 public: 140 SDTS_CATD(); 141 ~SDTS_CATD(); 142 143 int Read( const char * pszFilename ); 144 145 const char *GetModuleFilePath( const char * pszModule ) const; 146 GetEntryCount()147 int GetEntryCount() const { return nEntries; } 148 const char * GetEntryModule(int) const; 149 const char * GetEntryTypeDesc(int) const; 150 const char * GetEntryFilePath(int) const; 151 SDTSLayerType GetEntryType(int) const; 152 void SetEntryTypeUnknown(int); 153 }; 154 155 /************************************************************************/ 156 /* SDTSModId */ 157 /************************************************************************/ 158 159 /** 160 Object representing a unique module/record identifier within an SDTS 161 transfer. 162 */ 163 class SDTSModId 164 { 165 public: SDTSModId()166 SDTSModId() { szModule[0] = '\0'; 167 nRecord = -1; 168 szOBRP[0] = '\0'; 169 szName[0] = '\0'; } 170 171 int Set( DDFField * ); 172 173 const char *GetName(); 174 175 /** The module name, such as PC01, containing the indicated record. */ 176 char szModule[8]; 177 178 /** The record within the module referred to. This is -1 for unused 179 SDTSModIds. */ 180 int nRecord; 181 182 /** The "role" of this record within the module. This is normally empty 183 for references, but set in the oModId member of a feature. */ 184 char szOBRP[8]; 185 186 /** String "szModule:nRecord" */ 187 char szName[20]; 188 }; 189 190 /************************************************************************/ 191 /* SDTSFeature */ 192 /************************************************************************/ 193 194 /** 195 Base class for various SDTS features classes, providing a generic 196 module identifier, and list of attribute references. 197 */ 198 class SDTSFeature 199 { 200 public: 201 202 SDTSFeature(); 203 virtual ~SDTSFeature(); 204 205 /** Unique identifier for this record/feature within transfer. */ 206 SDTSModId oModId; 207 208 /** Number of attribute links (aoATID[]) on this feature. */ 209 int nAttributes; 210 211 /** List of nAttributes attribute record identifiers related to this 212 feature. */ 213 SDTSModId *paoATID; 214 215 void ApplyATID( DDFField * ); 216 217 /** Dump readable description of feature to indicated stream. */ 218 virtual void Dump( FILE * ) = 0; 219 }; 220 221 /************************************************************************/ 222 /* SDTSIndexedReader */ 223 /************************************************************************/ 224 225 /** 226 Base class for all the SDTSFeature type readers. Provides feature 227 caching semantics and fetching based on a record number. 228 */ 229 230 class SDTSIndexedReader 231 { 232 int nIndexSize; 233 SDTSFeature **papoFeatures; 234 235 int iCurrentFeature; 236 237 protected: 238 DDFModule oDDFModule; 239 240 public: 241 SDTSIndexedReader(); 242 virtual ~SDTSIndexedReader(); 243 244 virtual SDTSFeature *GetNextRawFeature() = 0; 245 246 SDTSFeature *GetNextFeature(); 247 248 virtual void Rewind(); 249 250 void FillIndex(); 251 void ClearIndex(); 252 int IsIndexed() const; 253 254 SDTSFeature *GetIndexedFeatureRef( int ); 255 char ** ScanModuleReferences( const char * = "ATID" ); 256 GetModule()257 DDFModule *GetModule() { return &oDDFModule; } 258 }; 259 260 /************************************************************************/ 261 /* SDTSRawLine */ 262 /************************************************************************/ 263 264 /** SDTS line feature, as read from LE* modules by SDTSLineReader. */ 265 266 class SDTSRawLine : public SDTSFeature 267 { 268 public: 269 SDTSRawLine(); 270 virtual ~SDTSRawLine(); 271 272 int Read( SDTS_IREF *, DDFRecord * ); 273 274 /** Number of vertices in the padfX, padfY and padfZ arrays. */ 275 int nVertices; 276 277 /** List of nVertices X coordinates. */ 278 double *padfX; 279 /** List of nVertices Y coordinates. */ 280 double *padfY; 281 /** List of nVertices Z coordinates - currently always zero. */ 282 double *padfZ; 283 284 /** Identifier of polygon to left of this line. This is the SDTS PIDL 285 subfield. */ 286 SDTSModId oLeftPoly; 287 288 /** Identifier of polygon to right of this line. This is the SDTS PIDR 289 subfield. */ 290 SDTSModId oRightPoly; 291 292 /** Identifier for the start node of this line. This is the SDTS SNID 293 subfield. */ 294 SDTSModId oStartNode; /* SNID */ 295 296 /** Identifier for the end node of this line. This is the SDTS ENID 297 subfield. */ 298 SDTSModId oEndNode; /* ENID */ 299 300 void Dump( FILE * ) override; 301 }; 302 303 /************************************************************************/ 304 /* SDTSLineReader */ 305 /* */ 306 /* Class for reading any of the files lines. */ 307 /************************************************************************/ 308 309 /** 310 Reader for SDTS line modules. 311 312 Returns SDTSRawLine features. Normally readers are instantiated with 313 the SDTSTransfer::GetIndexedReader() method. 314 315 */ 316 317 class SDTSLineReader : public SDTSIndexedReader 318 { 319 SDTS_IREF *poIREF; 320 321 public: 322 explicit SDTSLineReader( SDTS_IREF * ); 323 ~SDTSLineReader(); 324 325 int Open( const char * ); 326 SDTSRawLine *GetNextLine(); 327 void Close(); 328 GetNextRawFeature()329 SDTSFeature *GetNextRawFeature() override { return GetNextLine(); } 330 331 void AttachToPolygons( SDTSTransfer *, int iPolyLayer ); 332 }; 333 334 /************************************************************************/ 335 /* SDTSAttrRecord */ 336 /************************************************************************/ 337 338 /** 339 SDTS attribute record feature, as read from A* modules by 340 SDTSAttrReader. 341 342 Note that even though SDTSAttrRecord is derived from SDTSFeature, there 343 are never any attribute records associated with attribute records using 344 the aoATID[] mechanism. SDTSFeature::nAttributes will always be zero. 345 */ 346 347 class SDTSAttrRecord : public SDTSFeature 348 { 349 public: 350 SDTSAttrRecord(); 351 virtual ~SDTSAttrRecord(); 352 353 /** The entire DDFRecord read from the file. */ 354 DDFRecord *poWholeRecord; 355 356 /** The ATTR DDFField with the user attribute. Each subfield is a 357 attribute value. */ 358 359 DDFField *poATTR; 360 361 virtual void Dump( FILE * ) override; 362 }; 363 364 /************************************************************************/ 365 /* SDTSAttrReader */ 366 /************************************************************************/ 367 368 /** 369 Class for reading SDTSAttrRecord features from a primary or secondary 370 attribute module. 371 */ 372 373 class SDTSAttrReader : public SDTSIndexedReader 374 { 375 int bIsSecondary; 376 377 public: 378 SDTSAttrReader(); 379 virtual ~SDTSAttrReader(); 380 381 int Open( const char * ); 382 DDFField *GetNextRecord( SDTSModId * = nullptr, 383 DDFRecord ** = nullptr, 384 int bDuplicate = FALSE ); 385 SDTSAttrRecord *GetNextAttrRecord(); 386 void Close(); 387 388 /** 389 Returns TRUE if this is a Attribute Secondary layer rather than 390 an Attribute Primary layer. 391 */ IsSecondary()392 int IsSecondary() const { return bIsSecondary; } 393 GetNextRawFeature()394 SDTSFeature *GetNextRawFeature() override { return GetNextAttrRecord(); } 395 }; 396 397 /************************************************************************/ 398 /* SDTSRawPoint */ 399 /************************************************************************/ 400 401 /** 402 Object containing a point feature (type NA, NO or NP). 403 */ 404 class SDTSRawPoint : public SDTSFeature 405 { 406 public: 407 SDTSRawPoint(); 408 virtual ~SDTSRawPoint(); 409 410 int Read( SDTS_IREF *, DDFRecord * ); 411 412 /** X coordinate of point. */ 413 double dfX; 414 /** Y coordinate of point. */ 415 double dfY; 416 /** Z coordinate of point. */ 417 double dfZ; 418 419 /** Optional identifier of area marked by this point (i.e. PC01:27). */ 420 SDTSModId oAreaId; /* ARID */ 421 422 virtual void Dump( FILE * ) override; 423 }; 424 425 /************************************************************************/ 426 /* SDTSPointReader */ 427 /************************************************************************/ 428 429 /** 430 Class for reading SDTSRawPoint features from a point module (type NA, NO 431 or NP). 432 */ 433 434 class SDTSPointReader : public SDTSIndexedReader 435 { 436 SDTS_IREF *poIREF; 437 438 public: 439 explicit SDTSPointReader( SDTS_IREF * ); 440 virtual ~SDTSPointReader(); 441 442 int Open( const char * ); 443 SDTSRawPoint *GetNextPoint(); 444 void Close(); 445 GetNextRawFeature()446 SDTSFeature *GetNextRawFeature() override { return GetNextPoint(); } 447 }; 448 449 /************************************************************************/ 450 /* SDTSRawPolygon */ 451 /************************************************************************/ 452 453 /** 454 Class for holding information about a polygon feature. 455 456 When directly read from a polygon module, the polygon has no concept 457 of its geometry. Just its ID, and references to attribute records. 458 However, if the SDTSLineReader::AttachToPolygons() method is called on 459 the module containing the lines forming the polygon boundaries, then the 460 nEdges/papoEdges information on the SDTSRawPolygon will be filled in. 461 462 Once this is complete the AssembleRings() method can be used to fill in the 463 nRings/nVertices/panRingStart/padfX/padfY/padfZ information defining the 464 ring geometry. 465 466 Note that the rings may not appear in any particular order, nor with any 467 meaningful direction (clockwise or counterclockwise). 468 */ 469 470 class SDTSRawPolygon : public SDTSFeature 471 { 472 void AddEdgeToRing( int, double *, double *, double *, int, int ); 473 474 public: 475 SDTSRawPolygon(); 476 virtual ~SDTSRawPolygon(); 477 478 int Read( DDFRecord * ); 479 480 int nEdges; 481 SDTSRawLine **papoEdges; 482 483 void AddEdge( SDTSRawLine * ); 484 485 /** This method will assemble the edges associated with a polygon into 486 rings, returning FALSE if problems are encountered during assembly. */ 487 int AssembleRings(); 488 489 /** Number of rings in assembled polygon. */ 490 int nRings; 491 /** Total number of vertices in all rings of assembled polygon. */ 492 int nVertices; 493 /** Offsets into padfX/padfY/padfZ for the beginning of each ring in the 494 polygon. This array is nRings long. */ 495 int *panRingStart; 496 497 /** List of nVertices X coordinates for the polygon (split over multiple 498 rings via panRingStart. */ 499 double *padfX; 500 /** List of nVertices Y coordinates for the polygon (split over multiple 501 rings via panRingStart. */ 502 double *padfY; 503 /** List of nVertices Z coordinates for the polygon (split over multiple 504 rings via panRingStart. The values are almost always zero. */ 505 double *padfZ; 506 507 virtual void Dump( FILE * ) override; 508 }; 509 510 /************************************************************************/ 511 /* SDTSPolygonReader */ 512 /************************************************************************/ 513 514 /** Class for reading SDTSRawPolygon features from a polygon (PC*) module. */ 515 516 class SDTSPolygonReader : public SDTSIndexedReader 517 { 518 int bRingsAssembled; 519 520 public: 521 SDTSPolygonReader(); 522 virtual ~SDTSPolygonReader(); 523 524 int Open( const char * ); 525 SDTSRawPolygon *GetNextPolygon(); 526 void Close(); 527 GetNextRawFeature()528 SDTSFeature *GetNextRawFeature() override { return GetNextPolygon(); } 529 530 void AssembleRings( SDTSTransfer *, int iPolyLayer ); 531 }; 532 533 /************************************************************************/ 534 /* SDTSRasterReader */ 535 /************************************************************************/ 536 537 /** 538 Class for reading raster data from a raster layer. 539 540 This class is somewhat unique among the reader classes in that it isn't 541 derived from SDTSIndexedFeature, and it doesn't return "features". Instead 542 it is used to read raster blocks, in the natural block size of the dataset. 543 */ 544 545 class SDTSRasterReader 546 { 547 DDFModule oDDFModule; 548 549 char szModule[20]; 550 551 int nXSize; 552 int nYSize; 553 int nXBlockSize; 554 int nYBlockSize; 555 556 int nXStart; /* SOCI */ 557 int nYStart; /* SORI */ 558 559 double adfTransform[6]; 560 561 public: 562 char szINTR[4]; /* CE is center, TL is top left */ 563 char szFMT[32]; 564 char szUNITS[64]; 565 char szLabel[64]; 566 567 SDTSRasterReader(); 568 ~SDTSRasterReader(); 569 570 int Open( SDTS_CATD * poCATD, SDTS_IREF *, 571 const char * pszModule ); 572 void Close(); 573 574 int GetRasterType(); /* 1 = int16, see GDAL types */ 575 #define SDTS_RT_INT16 1 576 #define SDTS_RT_FLOAT32 6 577 578 int GetTransform( double * ); 579 580 int GetMinMax( double * pdfMin, double * pdfMax, 581 double dfNoData ); 582 583 /** 584 Fetch the raster width. 585 586 @return the width in pixels. 587 */ GetXSize()588 int GetXSize() const { return nXSize; } 589 /** 590 Fetch the raster height. 591 592 @return the height in pixels. 593 */ GetYSize()594 int GetYSize() const { return nYSize; } 595 596 /** Fetch the width of a source block (usually same as raster width). */ GetBlockXSize()597 int GetBlockXSize() const { return nXBlockSize; } 598 /** Fetch the height of a source block (usually one). */ GetBlockYSize()599 int GetBlockYSize() const { return nYBlockSize; } 600 601 int GetBlock( int nXOffset, int nYOffset, void * pData ); 602 }; 603 604 /************************************************************************/ 605 /* SDTSTransfer */ 606 /************************************************************************/ 607 608 /** 609 Master class representing an entire SDTS transfer. 610 611 This class is used to open the transfer, to get a list of available 612 feature layers, and to instantiate readers for those layers. 613 614 */ 615 616 class SDTSTransfer 617 { 618 public: 619 SDTSTransfer(); 620 ~SDTSTransfer(); 621 622 int Open( const char * ); 623 void Close(); 624 625 int FindLayer( const char * ); GetLayerCount()626 int GetLayerCount() const { return nLayers; } 627 SDTSLayerType GetLayerType( int ) const; 628 int GetLayerCATDEntry( int ) const; 629 630 SDTSLineReader *GetLayerLineReader( int ); 631 SDTSPointReader *GetLayerPointReader( int ); 632 SDTSPolygonReader *GetLayerPolygonReader( int ); 633 SDTSAttrReader *GetLayerAttrReader( int ); 634 SDTSRasterReader *GetLayerRasterReader( int ); 635 DDFModule *GetLayerModuleReader( int ); 636 637 SDTSIndexedReader *GetLayerIndexedReader( int ); 638 639 /** 640 Fetch the catalog object for this transfer. 641 642 @return pointer to the internally managed SDTS_CATD for the transfer. 643 */ GetCATD()644 SDTS_CATD *GetCATD() { return &oCATD ; } 645 GetIREF()646 SDTS_IREF *GetIREF() { return &oIREF; } 647 648 /** 649 Fetch the external reference object for this transfer. 650 651 @return pointer to the internally managed SDTS_XREF for the transfer. 652 */ GetXREF()653 SDTS_XREF *GetXREF() { return &oXREF; } 654 655 SDTSFeature *GetIndexedFeatureRef( SDTSModId *, 656 SDTSLayerType *peType = nullptr); 657 658 DDFField *GetAttr( SDTSModId * ); 659 660 int GetBounds( double *pdfMinX, double *pdfMinY, 661 double *pdfMaxX, double *pdfMaxY ); 662 663 private: 664 665 SDTS_CATD oCATD; 666 SDTS_IREF oIREF; 667 SDTS_XREF oXREF; 668 669 int nLayers; 670 int *panLayerCATDEntry; 671 SDTSIndexedReader **papoLayerReader; 672 }; 673 674 #endif /* ifndef SDTS_AL_H_INCLUDED */ 675