1 /****************************************************************************** 2 * $Id: ntf.h 842d122d2f23aaebb28362e083b52d6bc7dbcde2 2019-08-11 17:42:34 +0200 Even Rouault $ 3 * 4 * Project: NTF Translator 5 * Purpose: Main declarations for NTF translator. 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 NTF_H_INCLUDED 31 #define NTF_H_INCLUDED 32 33 #include "cpl_conv.h" 34 #include "cpl_vsi.h" 35 #include "ogrsf_frmts.h" 36 37 /* -------------------------------------------------------------------- */ 38 /* Record types. */ 39 /* -------------------------------------------------------------------- */ 40 #define NRT_VHR 1 /* Volume Header Record */ 41 #define NRT_DHR 2 /* Database Header Record */ 42 #define NRT_FCR 5 /* Feature Classification Record */ 43 #define NRT_SHR 7 /* Section Header Record */ 44 #define NRT_NAMEREC 11 /* Name Record */ 45 #define NRT_NAMEPOSTN 12 /* Name Position */ 46 #define NRT_ATTREC 14 /* Attribute Record */ 47 #define NRT_POINTREC 15 /* Point Record */ 48 #define NRT_NODEREC 16 /* Node Record */ 49 #define NRT_GEOMETRY 21 /* Geometry Record */ 50 #define NRT_GEOMETRY3D 22 /* 3D Geometry Record */ 51 #define NRT_LINEREC 23 /* Line Record */ 52 #define NRT_CHAIN 24 /* Chain */ 53 #define NRT_POLYGON 31 /* Polygon */ 54 #define NRT_CPOLY 33 /* Complex Polygon */ 55 #define NRT_COLLECT 34 /* Collection of features */ 56 #define NRT_ADR 40 /* Attribute Description Record */ 57 #define NRT_CODELIST 42 /* Codelist Record (i.e. BL2000) */ 58 #define NRT_TEXTREC 43 /* Text */ 59 #define NRT_TEXTPOS 44 /* Text position */ 60 #define NRT_TEXTREP 45 /* Text representation */ 61 #define NRT_GRIDHREC 50 /* Grid Header Record */ 62 #define NRT_GRIDREC 51 /* Grid Data Record */ 63 #define NRT_COMMENT 90 /* Comment record */ 64 #define NRT_VTR 99 /* Volume Termination Record */ 65 66 /* -------------------------------------------------------------------- */ 67 /* Product names (DBNAME) and codes. */ 68 /* -------------------------------------------------------------------- */ 69 70 #define NPC_UNKNOWN 0 71 72 #define NPC_LANDLINE 1 73 #define NPC_LANDLINE99 2 74 #define NTF_LANDLINE "LAND-LINE.93" 75 #define NTF_LANDLINE_PLUS "LAND-LINE.93+" 76 77 #define NPC_STRATEGI 3 78 #define NTF_STRATEGI "Strategi_02.96" 79 80 #define NPC_MERIDIAN 4 81 #define NTF_MERIDIAN "Meridian_01.95" 82 83 #define NPC_BOUNDARYLINE 5 84 #define NTF_BOUNDARYLINE "Boundary-Line" 85 86 #define NPC_BASEDATA 6 87 #define NTF_BASEDATA "BaseData.GB_01.96" 88 89 #define NPC_OSCAR_ASSET 7 90 #define NPC_OSCAR_TRAFFIC 8 91 #define NPC_OSCAR_ROUTE 9 92 #define NPC_OSCAR_NETWORK 10 93 94 #define NPC_ADDRESS_POINT 11 95 96 #define NPC_CODE_POINT 12 97 #define NPC_CODE_POINT_PLUS 13 98 99 #define NPC_LANDFORM_PROFILE_CONT 14 100 101 #define NPC_LANDRANGER_CONT 15 102 #define NTF_LANDRANGER_CONT "OS_LANDRANGER_CONT" 103 104 #define NPC_LANDRANGER_DTM 16 105 #define NPC_LANDFORM_PROFILE_DTM 17 106 107 #define NPC_BL2000 18 108 109 #define NPC_MERIDIAN2 19 110 #define NTF_MERIDIAN2 "Meridian_02.01" 111 112 /************************************************************************/ 113 /* NTFRecord */ 114 /************************************************************************/ 115 116 class NTFRecord 117 { 118 int nType; 119 int nLength; 120 char *pszData; 121 122 static int ReadPhysicalLine( VSILFILE *fp, char *pszLine ); 123 124 public: 125 explicit NTFRecord( VSILFILE * ); 126 ~NTFRecord(); 127 GetType()128 int GetType() { return nType; } GetLength()129 int GetLength() { return nLength; } GetData()130 const char *GetData() { return pszData; } 131 132 const char *GetField( int, int ); 133 }; 134 135 /************************************************************************/ 136 /* NTFGenericClass */ 137 /************************************************************************/ 138 139 class NTFGenericClass 140 { 141 public: 142 int nFeatureCount; 143 144 int b3D; 145 int nAttrCount; 146 char **papszAttrNames; 147 char **papszAttrFormats; 148 int *panAttrMaxWidth; 149 int *pabAttrMultiple; 150 151 NTFGenericClass(); 152 ~NTFGenericClass(); 153 154 void CheckAddAttr( const char *, const char *, int ); 155 void SetMultiple( const char * ); 156 }; 157 158 /************************************************************************/ 159 /* NTFCodeList */ 160 /************************************************************************/ 161 162 class NTFCodeList 163 { 164 public: 165 explicit NTFCodeList( NTFRecord * ); 166 ~NTFCodeList(); 167 168 const char *Lookup( const char * ); 169 170 char szValType[3]; /* attribute code for list, i.e. AC */ 171 char szFInter[6]; /* format of code values */ 172 173 int nNumCode; 174 char **papszCodeVal; /* Short code value */ 175 char **papszCodeDes; /* Long description of code */ 176 }; 177 178 /************************************************************************/ 179 /* NTFAttDesc */ 180 /************************************************************************/ 181 typedef struct 182 { 183 char val_type [ 2 +1]; 184 char fwidth [ 3 +1]; 185 char finter [ 5 +1]; 186 char att_name [ 100 ]; 187 188 NTFCodeList *poCodeList; 189 190 } NTFAttDesc; 191 192 class OGRNTFLayer; 193 class OGRNTFRasterLayer; 194 class OGRNTFDataSource; 195 class NTFFileReader; 196 197 #define MAX_REC_GROUP 100 198 typedef OGRFeature *(*NTFFeatureTranslator)(NTFFileReader *, 199 OGRNTFLayer *, 200 NTFRecord **); 201 typedef int (*NTFRecordGrouper)(NTFFileReader *, NTFRecord **, NTFRecord *); 202 203 /************************************************************************/ 204 /* NTFFileReader */ 205 /************************************************************************/ 206 207 class NTFFileReader 208 { 209 char *pszFilename; 210 OGRNTFDataSource *poDS; 211 212 VSILFILE *fp; 213 214 // feature class list. 215 int nFCCount; 216 char **papszFCNum; 217 char **papszFCName; 218 219 // attribute definitions 220 int nAttCount; 221 NTFAttDesc *pasAttDesc; 222 223 char *pszTileName; 224 int nCoordWidth; 225 int nZWidth; 226 int nNTFLevel; 227 228 double dfXYMult; 229 double dfZMult; 230 231 double dfXOrigin; 232 double dfYOrigin; 233 234 double dfTileXSize; 235 double dfTileYSize; 236 237 double dfScale; 238 double dfPaperToGround; 239 240 vsi_l_offset nStartPos; 241 vsi_l_offset nPreSavedPos; 242 vsi_l_offset nPostSavedPos; 243 NTFRecord *poSavedRecord; 244 245 long nSavedFeatureId; 246 long nBaseFeatureId; 247 long nFeatureCount; 248 249 NTFRecord *apoCGroup[MAX_REC_GROUP+1]; 250 251 char *pszProduct; 252 char *pszPVName; 253 int nProduct; 254 255 void EstablishLayers(); 256 257 void ClearCGroup(); 258 void ClearDefs(); 259 260 OGRNTFLayer *apoTypeTranslation[100]; 261 262 NTFRecordGrouper pfnRecordGrouper; 263 264 int anIndexSize[100]; 265 NTFRecord **apapoRecordIndex[100]; 266 int bIndexBuilt; 267 int bIndexNeeded; 268 269 void EstablishRasterAccess(); 270 int nRasterXSize; 271 int nRasterYSize; 272 int nRasterDataType; 273 double adfGeoTransform[6]; 274 275 OGRNTFRasterLayer *poRasterLayer; 276 277 vsi_l_offset *panColumnOffset; 278 279 int bCacheLines; 280 int nLineCacheSize; 281 OGRGeometry **papoLineCache; 282 283 void AddToIndexGroup( NTFRecord * poRecord ); 284 285 public: 286 explicit NTFFileReader( OGRNTFDataSource * ); 287 ~NTFFileReader(); 288 289 int Open( const char * pszFilename = nullptr ); 290 void Close(); GetFP()291 VSILFILE *GetFP() { return fp; } 292 void GetFPPos( vsi_l_offset *pnPos, long * pnFeatureId); 293 int SetFPPos( vsi_l_offset nPos, long nFeatureId ); 294 void Reset(); 295 void SetBaseFID( long nFeatureId ); 296 297 OGRGeometry *ProcessGeometry( NTFRecord *, int * = nullptr ); 298 OGRGeometry *ProcessGeometry3D( NTFRecord *, int * = nullptr ); 299 static int ProcessAttDesc( NTFRecord *, NTFAttDesc * ); 300 int ProcessAttRec( NTFRecord *, int *, char ***, char ***); 301 int ProcessAttRecGroup( NTFRecord **, char ***, char ***); 302 303 NTFAttDesc *GetAttDesc( const char * ); 304 305 void ApplyAttributeValues( OGRFeature *, NTFRecord **, ... ); 306 307 int ApplyAttributeValue( OGRFeature *, int, const char *, 308 char **, char ** ); 309 310 int ProcessAttValue( const char *pszValType, 311 const char *pszRawValue, 312 const char **ppszAttName, 313 const char **ppszAttValue, 314 const char **ppszCodeDesc ); 315 316 int TestForLayer( OGRNTFLayer * ); 317 OGRFeature *ReadOGRFeature( OGRNTFLayer * = nullptr ); 318 NTFRecord **ReadRecordGroup(); 319 NTFRecord *ReadRecord(); 320 void SaveRecord( NTFRecord * ); 321 322 void DumpReadable( FILE * ); 323 GetXYLen()324 int GetXYLen() { return nCoordWidth; } GetXYMult()325 double GetXYMult() { return dfXYMult; } GetXOrigin()326 double GetXOrigin() { return dfXOrigin; } GetYOrigin()327 double GetYOrigin() { return dfYOrigin; } GetZMult()328 double GetZMult() { return dfZMult; } GetTileName()329 const char *GetTileName() { return pszTileName; } GetFilename()330 const char *GetFilename() { return pszFilename; } GetNTFLevel()331 int GetNTFLevel() { return nNTFLevel; } GetProduct()332 const char *GetProduct() { return pszProduct; } GetPVName()333 const char *GetPVName() { return pszPVName; } GetProductId()334 int GetProductId() { return nProduct; } GetScale()335 double GetScale() { return dfScale; } GetPaperToGround()336 double GetPaperToGround() { return dfPaperToGround; } 337 GetFCCount()338 int GetFCCount() { return nFCCount; } 339 int GetFeatureClass( int, char **, char ** ); 340 341 void OverrideTileName( const char * ); 342 343 // Generic file index 344 void IndexFile(); 345 void FreshenIndex(); 346 void DestroyIndex(); 347 NTFRecord *GetIndexedRecord( int, int ); 348 NTFRecord **GetNextIndexedRecordGroup( NTFRecord ** ); 349 350 // Line geometry cache 351 OGRGeometry *CacheGetByGeomId( int ); 352 void CacheAddByGeomId( int, OGRGeometry * ); 353 void CacheClean(); 354 void CacheLineGeometryInGroup( NTFRecord ** ); 355 356 int FormPolygonFromCache( OGRFeature * ); 357 358 // just for use of OGRNTFDatasource 359 void EstablishLayer( const char *, OGRwkbGeometryType, 360 NTFFeatureTranslator, int, 361 NTFGenericClass *, ... ); 362 363 // Raster related 364 int IsRasterProduct(); GetRasterXSize()365 int GetRasterXSize() { return nRasterXSize; } GetRasterYSize()366 int GetRasterYSize() { return nRasterYSize; } GetRasterDataType()367 int GetRasterDataType() { return nRasterDataType; } GetGeoTransform()368 double *GetGeoTransform() { return adfGeoTransform; } 369 CPLErr ReadRasterColumn( int, float * ); 370 371 }; 372 373 /************************************************************************/ 374 /* OGRNTFLayer */ 375 /************************************************************************/ 376 377 class OGRNTFLayer final: public OGRLayer 378 { 379 OGRFeatureDefn *poFeatureDefn; 380 NTFFeatureTranslator pfnTranslator; 381 382 OGRNTFDataSource *poDS; 383 384 int iCurrentReader; 385 vsi_l_offset nCurrentPos; 386 long nCurrentFID; 387 388 public: 389 OGRNTFLayer( OGRNTFDataSource * poDS, 390 OGRFeatureDefn * poFeatureDefine, 391 NTFFeatureTranslator pfnTranslator ); 392 393 ~OGRNTFLayer(); 394 395 void ResetReading() override; 396 OGRFeature * GetNextFeature() override; 397 398 #ifdef notdef 399 OGRFeature *GetFeature( GIntBig nFeatureId ); 400 OGRErr ISetFeature( OGRFeature *poFeature ); 401 OGRErr ICreateFeature( OGRFeature *poFeature ); 402 #endif 403 GetLayerDefn()404 OGRFeatureDefn * GetLayerDefn() override { return poFeatureDefn; } 405 406 #ifdef notdef 407 GIntBig GetFeatureCount( int ); 408 #endif 409 410 int TestCapability( const char * ) override; 411 412 // special to NTF 413 OGRFeature *FeatureTranslate( NTFFileReader *, NTFRecord ** ); 414 }; 415 416 /************************************************************************/ 417 /* OGRNTFFeatureClassLayer */ 418 /************************************************************************/ 419 420 class OGRNTFFeatureClassLayer final: public OGRLayer 421 { 422 OGRFeatureDefn *poFeatureDefn; 423 OGRGeometry *poFilterGeom; 424 425 OGRNTFDataSource *poDS; 426 427 GIntBig iCurrentFC; 428 429 public: 430 explicit OGRNTFFeatureClassLayer( OGRNTFDataSource * poDS ); 431 ~OGRNTFFeatureClassLayer(); 432 GetSpatialFilter()433 OGRGeometry * GetSpatialFilter() override { return poFilterGeom; } 434 void SetSpatialFilter( OGRGeometry * ) override; SetSpatialFilter(int iGeomField,OGRGeometry * poGeom)435 virtual void SetSpatialFilter( int iGeomField, OGRGeometry *poGeom ) override 436 { OGRLayer::SetSpatialFilter(iGeomField, poGeom); } 437 438 void ResetReading() override; 439 OGRFeature * GetNextFeature() override; 440 441 OGRFeature *GetFeature( GIntBig nFeatureId ) override; 442 GetLayerDefn()443 OGRFeatureDefn * GetLayerDefn() override { return poFeatureDefn; } 444 445 GIntBig GetFeatureCount( int = TRUE ) override; 446 447 int TestCapability( const char * ) override; 448 }; 449 450 /************************************************************************/ 451 /* OGRNTFRasterLayer */ 452 /************************************************************************/ 453 454 class OGRNTFRasterLayer final: public OGRLayer 455 { 456 OGRFeatureDefn *poFeatureDefn; 457 OGRGeometry *poFilterGeom; 458 459 NTFFileReader *poReader; 460 461 float *pafColumn; 462 int iColumnOffset; 463 464 GIntBig iCurrentFC; 465 466 int nDEMSample; 467 GIntBig nFeatureCount; 468 469 public: 470 OGRNTFRasterLayer( OGRNTFDataSource * poDS, 471 NTFFileReader * poReaderIn ); 472 virtual ~OGRNTFRasterLayer(); 473 GetSpatialFilter()474 OGRGeometry * GetSpatialFilter() override { return poFilterGeom; } 475 void SetSpatialFilter( OGRGeometry * ) override; SetSpatialFilter(int iGeomField,OGRGeometry * poGeom)476 virtual void SetSpatialFilter( int iGeomField, OGRGeometry *poGeom ) override 477 { OGRLayer::SetSpatialFilter(iGeomField, poGeom); } 478 479 void ResetReading() override; 480 OGRFeature * GetNextFeature() override; 481 482 OGRFeature *GetFeature( GIntBig nFeatureId ) override; 483 GetLayerDefn()484 OGRFeatureDefn * GetLayerDefn() override { return poFeatureDefn; } 485 486 GIntBig GetFeatureCount( int = TRUE ) override; 487 488 int TestCapability( const char * ) override; 489 }; 490 491 /************************************************************************/ 492 /* OGRNTFDataSource */ 493 /************************************************************************/ 494 495 class OGRNTFDataSource final: public OGRDataSource 496 { 497 char *pszName; 498 499 int nLayers; 500 OGRLayer **papoLayers; 501 502 OGRNTFFeatureClassLayer *poFCLayer; 503 504 int iCurrentFC; 505 int iCurrentReader; 506 vsi_l_offset nCurrentPos; 507 long nCurrentFID; 508 509 int nNTFFileCount; 510 NTFFileReader **papoNTFFileReader; 511 512 int nFCCount; 513 char **papszFCNum; 514 char **papszFCName; 515 516 OGRSpatialReference *poSpatialRef; 517 518 NTFGenericClass aoGenericClass[100]; 519 520 char **papszOptions; 521 522 void EnsureTileNameUnique( NTFFileReader * ); 523 524 CPL_DISALLOW_COPY_ASSIGN(OGRNTFDataSource) 525 526 public: 527 OGRNTFDataSource(); 528 ~OGRNTFDataSource(); 529 530 void SetOptionList( char ** ); 531 const char *GetOption( const char * ); 532 533 int Open( const char * pszName, int bTestOpen = FALSE, 534 char ** papszFileList = nullptr ); 535 GetName()536 const char *GetName() override { return pszName; } 537 int GetLayerCount() override; 538 OGRLayer *GetLayer( int ) override; 539 int TestCapability( const char * ) override; 540 541 // Note: these are specific to NTF for now, but eventually might 542 // might be available as part of a more object oriented approach to 543 // features like that in FME or SFCORBA. 544 virtual void ResetReading() override; 545 virtual OGRFeature* GetNextFeature( OGRLayer** ppoBelongingLayer, 546 double* pdfProgressPct, 547 GDALProgressFunc pfnProgress, 548 void* pProgressData ) override; 549 550 // these are only for the use of the NTFFileReader class. 551 OGRNTFLayer *GetNamedLayer( const char * ); 552 void AddLayer( OGRLayer * ); 553 554 // Mainly for OGRNTFLayer class GetFileCount()555 int GetFileCount() { return nNTFFileCount; } GetFileReader(int i)556 NTFFileReader *GetFileReader(int i) { return papoNTFFileReader[i]; } 557 GetFCCount()558 int GetFCCount() { return nFCCount; } 559 int GetFeatureClass( int, char **, char ** ); 560 DSGetSpatialRef()561 OGRSpatialReference *DSGetSpatialRef() { return poSpatialRef; } 562 GetGClass(int i)563 NTFGenericClass *GetGClass( int i ) { return aoGenericClass + i; } 564 void WorkupGeneric( NTFFileReader * ); 565 void EstablishGenericLayers(); 566 }; 567 568 /************************************************************************/ 569 /* Support functions. */ 570 /************************************************************************/ 571 int NTFArcCenterFromEdgePoints( double x_c0, double y_c0, 572 double x_c1, double y_c1, 573 double x_c2, double y_c2, 574 double *x_center, double *y_center ); 575 OGRGeometry * 576 NTFStrokeArcToOGRGeometry_Points( double dfStartX, double dfStartY, 577 double dfAlongX, double dfAlongY, 578 double dfEndX, double dfEndY, 579 int nVertexCount ); 580 OGRGeometry * 581 NTFStrokeArcToOGRGeometry_Angles( double dfCenterX, double dfCenterY, 582 double dfRadius, 583 double dfStartAngle, double dfEndAngle, 584 int nVertexCount ); 585 586 #endif /* ndef NTF_H_INCLUDED */ 587