1 /****************************************************************************** 2 * $Id: s57.h 342855360b69569556916db63ea417dd3514f258 2020-06-14 15:44:48 +0200 Even Rouault $ 3 * 4 * Project: S-57 Translator 5 * Purpose: Declarations for S-57 translator not including the 6 * binding onto OGRLayer/DataSource/Driver which are found in 7 * ogr_s57.h. 8 * Author: Frank Warmerdam, warmerdam@pobox.com 9 * 10 ****************************************************************************** 11 * Copyright (c) 1999, Frank Warmerdam 12 * Copyright (c) 2013, Even Rouault <even dot 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 25 * OR 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 #ifndef S57_H_INCLUDED 34 #define S57_H_INCLUDED 35 36 #include <string> 37 #include <vector> 38 #include "ogr_feature.h" 39 #include "iso8211.h" 40 41 class S57Reader; 42 43 char **S57FileCollector( const char * pszDataset ); 44 45 #define EMPTY_NUMBER_MARKER 2147483641 /* MAXINT-6 */ 46 47 /* -------------------------------------------------------------------- */ 48 /* Various option strings. */ 49 /* -------------------------------------------------------------------- */ 50 #define S57O_UPDATES "UPDATES" 51 #define S57O_LNAM_REFS "LNAM_REFS" 52 #define S57O_SPLIT_MULTIPOINT "SPLIT_MULTIPOINT" 53 #define S57O_ADD_SOUNDG_DEPTH "ADD_SOUNDG_DEPTH" 54 #define S57O_PRESERVE_EMPTY_NUMBERS "PRESERVE_EMPTY_NUMBERS" 55 #define S57O_RETURN_PRIMITIVES "RETURN_PRIMITIVES" 56 #define S57O_RETURN_LINKAGES "RETURN_LINKAGES" 57 #define S57O_RETURN_DSID "RETURN_DSID" 58 #define S57O_RECODE_BY_DSSI "RECODE_BY_DSSI" 59 #define S57O_LIST_AS_STRING "LIST_AS_STRING" 60 61 #define S57M_UPDATES 0x01 62 #define S57M_LNAM_REFS 0x02 63 #define S57M_SPLIT_MULTIPOINT 0x04 64 #define S57M_ADD_SOUNDG_DEPTH 0x08 65 #define S57M_PRESERVE_EMPTY_NUMBERS 0x10 66 #define S57M_RETURN_PRIMITIVES 0x20 67 #define S57M_RETURN_LINKAGES 0x40 68 #define S57M_RETURN_DSID 0x80 69 #define S57M_RECODE_BY_DSSI 0x100 70 #define S57M_LIST_AS_STRING 0x200 71 72 /* -------------------------------------------------------------------- */ 73 /* RCNM values. */ 74 /* -------------------------------------------------------------------- */ 75 76 #define RCNM_FE 100 /* Feature record */ 77 78 #define RCNM_VI 110 /* Isolated Node */ 79 #define RCNM_VC 120 /* Connected Node */ 80 #define RCNM_VE 130 /* Edge */ 81 #define RCNM_VF 140 /* Face */ 82 83 #define RCNM_DSID 10 84 85 #define OGRN_VI "IsolatedNode" 86 #define OGRN_VC "ConnectedNode" 87 #define OGRN_VE "Edge" 88 #define OGRN_VF "Face" 89 90 /* -------------------------------------------------------------------- */ 91 /* FRID PRIM values. */ 92 /* -------------------------------------------------------------------- */ 93 #define PRIM_P 1 /* point feature */ 94 #define PRIM_L 2 /* line feature */ 95 #define PRIM_A 3 /* area feature */ 96 #define PRIM_N 4 /* non-spatial feature */ 97 98 /************************************************************************/ 99 /* S57ClassRegistrar */ 100 /************************************************************************/ 101 102 class S57ClassContentExplorer; 103 104 class CPL_DLL S57AttrInfo 105 { 106 public: 107 CPLString osName; 108 CPLString osAcronym; 109 char chType; 110 char chClass; 111 }; 112 113 class CPL_DLL S57ClassRegistrar 114 { 115 friend class S57ClassContentExplorer; 116 117 // Class information: 118 int nClasses; 119 CPLStringList apszClassesInfo; 120 121 // Attribute Information: 122 int nAttrCount; 123 std::vector<S57AttrInfo*> aoAttrInfos; 124 std::vector<int> anAttrIndex; // sorted by acronym. 125 126 static bool FindFile( const char *pszTarget, const char *pszDirectory, 127 bool bReportErr, VSILFILE **fp ); 128 129 const char *ReadLine( VSILFILE * fp ); 130 char **papszNextLine; 131 132 public: 133 S57ClassRegistrar(); 134 ~S57ClassRegistrar(); 135 136 bool LoadInfo( const char *, const char *, bool ); 137 138 // attribute table methods. 139 //int GetMaxAttrIndex() { return nAttrMax; } 140 const S57AttrInfo *GetAttrInfo( int i ); GetAttrName(int i)141 const char *GetAttrName( int i ) 142 { return GetAttrInfo(i) == nullptr ? nullptr : aoAttrInfos[i]->osName.c_str(); } GetAttrAcronym(int i)143 const char *GetAttrAcronym( int i ) 144 { return GetAttrInfo(i) == nullptr ? nullptr : aoAttrInfos[i]->osAcronym.c_str(); } GetAttrType(int i)145 char GetAttrType( int i ) 146 { return GetAttrInfo(i) == nullptr ? '\0' : aoAttrInfos[i]->chType; } 147 #define SAT_ENUM 'E' 148 #define SAT_LIST 'L' 149 #define SAT_FLOAT 'F' 150 #define SAT_INT 'I' 151 #define SAT_CODE_STRING 'A' 152 #define SAT_FREE_TEXT 'S' 153 GetAttrClass(int i)154 char GetAttrClass( int i ) 155 { return GetAttrInfo(i) == nullptr ? '\0' : aoAttrInfos[i]->chClass; } 156 int FindAttrByAcronym( const char * ); 157 }; 158 159 /************************************************************************/ 160 /* S57ClassContentExplorer */ 161 /************************************************************************/ 162 163 class S57ClassContentExplorer 164 { 165 S57ClassRegistrar* poRegistrar; 166 167 char ***papapszClassesFields; 168 169 int iCurrentClass; 170 171 char **papszCurrentFields; 172 173 char **papszTempResult; 174 175 public: 176 explicit S57ClassContentExplorer(S57ClassRegistrar* poRegistrar); 177 ~S57ClassContentExplorer(); 178 179 bool SelectClassByIndex( int ); 180 bool SelectClass( int ); 181 bool SelectClass( const char * ); 182 Rewind()183 bool Rewind() { return SelectClassByIndex(0); } NextClass()184 bool NextClass() { return SelectClassByIndex(iCurrentClass+1); } 185 186 int GetOBJL(); 187 const char *GetDescription() const; 188 const char *GetAcronym() const; 189 190 char **GetAttributeList( const char * = nullptr ); 191 192 char GetClassCode() const; 193 char **GetPrimitives(); 194 }; 195 196 /************************************************************************/ 197 /* DDFRecordIndex */ 198 /* */ 199 /* Maintain an index of DDF records based on an integer key. */ 200 /************************************************************************/ 201 202 typedef struct 203 { 204 int nKey; 205 DDFRecord *poRecord; 206 void *pClientData; 207 } DDFIndexedRecord; 208 209 class CPL_DLL DDFRecordIndex 210 { 211 bool bSorted; 212 213 int nRecordCount; 214 int nRecordMax; 215 216 int nLastObjlPos; // Added for FindRecordByObjl(). 217 int nLastObjl; // Added for FindRecordByObjl(). 218 219 DDFIndexedRecord *pasRecords; 220 221 void Sort(); 222 223 public: 224 DDFRecordIndex(); 225 ~DDFRecordIndex(); 226 227 void AddRecord( int nKey, DDFRecord * ); 228 bool RemoveRecord( int nKey ); 229 230 DDFRecord *FindRecord( int nKey ); 231 232 DDFRecord *FindRecordByObjl( int nObjl ); // Added for FindRecordByObjl(). 233 234 void Clear(); 235 GetCount()236 int GetCount() { return nRecordCount; } 237 238 DDFRecord *GetByIndex( int i ); 239 void *GetClientInfoByIndex( int i ); 240 void SetClientInfoByIndex( int i, void *pClientInfo ); 241 }; 242 243 /************************************************************************/ 244 /* S57Reader */ 245 /************************************************************************/ 246 247 class CPL_DLL S57Reader 248 { 249 S57ClassRegistrar *poRegistrar; 250 S57ClassContentExplorer* poClassContentExplorer; 251 252 int nFDefnCount; 253 OGRFeatureDefn **papoFDefnList; 254 255 std::vector<OGRFeatureDefn*> apoFDefnByOBJL; 256 257 char *pszModuleName; 258 char *pszDSNM; 259 260 DDFModule *poModule; 261 262 int nCOMF; /* Coordinate multiplier */ 263 int nSOMF; /* Vertical (sounding) multiplier */ 264 265 bool bFileIngested; 266 DDFRecordIndex oVI_Index; 267 DDFRecordIndex oVC_Index; 268 DDFRecordIndex oVE_Index; 269 DDFRecordIndex oVF_Index; 270 271 int nNextVIIndex; 272 int nNextVCIndex; 273 int nNextVEIndex; 274 int nNextVFIndex; 275 276 int nNextFEIndex; 277 DDFRecordIndex oFE_Index; 278 279 int nNextDSIDIndex; 280 DDFRecord *poDSIDRecord; 281 DDFRecord *poDSPMRecord; 282 std::string m_osEDTNUpdate; 283 std::string m_osUPDNUpdate; 284 std::string m_osISDTUpdate; 285 286 char **papszOptions; 287 288 int nOptionFlags; 289 290 int iPointOffset; 291 OGRFeature *poMultiPoint; 292 293 int Aall; // see RecodeByDSSI() function 294 int Nall; // see RecodeByDSSI() function 295 bool needAallNallSetup; // see RecodeByDSSI() function 296 297 void ClearPendingMultiPoint(); 298 OGRFeature *NextPendingMultiPoint(); 299 300 OGRFeature *AssembleFeature( DDFRecord *, OGRFeatureDefn * ); 301 302 void ApplyObjectClassAttributes( DDFRecord *, OGRFeature *); 303 // cppcheck-suppress functionStatic 304 void GenerateLNAMAndRefs( DDFRecord *, OGRFeature * ); 305 void GenerateFSPTAttributes( DDFRecord *, OGRFeature * ); 306 307 void AssembleSoundingGeometry( DDFRecord *, OGRFeature * ); 308 // cppcheck-suppress functionStatic 309 void AssemblePointGeometry( DDFRecord *, OGRFeature * ); 310 void AssembleLineGeometry( DDFRecord *, OGRFeature * ); 311 void AssembleAreaGeometry( DDFRecord *, OGRFeature * ); 312 313 bool FetchPoint( int, int, 314 double *, double *, double * = nullptr ); 315 bool FetchLine( DDFRecord *, int, int, OGRLineString * ); 316 317 OGRFeatureDefn *FindFDefn( DDFRecord * ); 318 int ParseName( DDFField *, int = 0, int * = nullptr ); 319 320 // cppcheck-suppress functionStatic 321 bool ApplyRecordUpdate( DDFRecord *, DDFRecord * ); 322 323 bool bMissingWarningIssued; 324 bool bAttrWarningIssued; 325 326 public: 327 explicit S57Reader( const char * ); 328 ~S57Reader(); 329 330 void SetClassBased( S57ClassRegistrar *, S57ClassContentExplorer* ); 331 bool SetOptions( char ** ); GetOptionFlags()332 int GetOptionFlags() { return nOptionFlags; } 333 334 int Open( int bTestOpen ); 335 void Close(); GetModule()336 DDFModule *GetModule() { return poModule; } GetDSNM()337 const char *GetDSNM() { return pszDSNM; } 338 339 bool Ingest(); 340 bool ApplyUpdates( DDFModule * ); 341 bool FindAndApplyUpdates( const char *pszPath=nullptr ); 342 343 void Rewind(); 344 OGRFeature *ReadNextFeature( OGRFeatureDefn * = nullptr ); 345 OGRFeature *ReadFeature( int nFID, OGRFeatureDefn * = nullptr ); 346 OGRFeature *ReadVector( int nFID, int nRCNM ); 347 OGRFeature *ReadDSID(); 348 349 int GetNextFEIndex( int nRCNM = 100 ); 350 void SetNextFEIndex( int nNewIndex, int nRCNM = 100 ); 351 352 void AddFeatureDefn( OGRFeatureDefn * ); 353 354 bool CollectClassList(std::vector<int> &anClassCount); 355 356 OGRErr GetExtent( OGREnvelope *psExtent, int bForce ); 357 358 char *RecodeByDSSI(const char *SourceString, bool LookAtAALL_NALL); 359 }; 360 361 /************************************************************************/ 362 /* S57Writer */ 363 /************************************************************************/ 364 365 class CPL_DLL S57Writer 366 { 367 public: 368 static const int nDEFAULT_EXPP = 1; 369 static const int nDEFAULT_INTU = 4; 370 static const int nDEFAULT_AGEN = 540; 371 372 static const int nDEFAULT_HDAT = 2; 373 static const int nDEFAULT_VDAT = 7; 374 static const int nDEFAULT_SDAT = 23; 375 static const int nDEFAULT_CSCL = 52000; 376 static const int nDEFAULT_COMF = 10000000; 377 static const int nDEFAULT_SOMF = 10; 378 379 S57Writer(); 380 ~S57Writer(); 381 382 void SetClassBased( S57ClassRegistrar *, S57ClassContentExplorer* ); 383 bool CreateS57File( const char *pszFilename ); 384 bool Close(); 385 386 bool WriteGeometry( DDFRecord *, int, double *, double *, 387 double * ); 388 bool WriteATTF( DDFRecord *, OGRFeature * ); 389 bool WritePrimitive( OGRFeature *poFeature ); 390 bool WriteCompleteFeature( OGRFeature *poFeature ); 391 bool WriteDSID( int nEXPP = nDEFAULT_EXPP, 392 int nINTU = nDEFAULT_INTU, 393 const char *pszDSNM = nullptr, 394 const char *pszEDTN = nullptr, 395 const char *pszUPDN = nullptr, 396 const char *pszUADT = nullptr, 397 const char *pszISDT = nullptr, 398 const char *pszSTED = nullptr, 399 int nAGEN = nDEFAULT_AGEN, 400 const char *pszCOMT = nullptr, 401 int nAALL = 0, 402 int nNALL = 0, 403 int nNOMR = 0, int nNOGR = 0, 404 int nNOLR = 0, int nNOIN = 0, 405 int nNOCN = 0, int nNOED = 0 ); 406 bool WriteDSPM( int nHDAT = nDEFAULT_HDAT, 407 int nVDAT = nDEFAULT_VDAT, 408 int nSDAT = nDEFAULT_SDAT, 409 int nCSCL = nDEFAULT_CSCL, 410 int nCOMF = nDEFAULT_COMF, 411 int nSOMF = nDEFAULT_SOMF); 412 413 // semi-private - for sophisticated writers. 414 DDFRecord *MakeRecord(); 415 DDFModule *poModule; 416 417 private: 418 int nNext0001Index; 419 S57ClassRegistrar *poRegistrar; 420 S57ClassContentExplorer* poClassContentExplorer; 421 422 int m_nCOMF; /* Coordinate multiplier */ 423 int m_nSOMF; /* Vertical (sounding) multiplier */ 424 }; 425 426 /* -------------------------------------------------------------------- */ 427 /* Functions to create OGRFeatureDefns. */ 428 /* -------------------------------------------------------------------- */ 429 void CPL_DLL S57GenerateStandardAttributes( OGRFeatureDefn *, int ); 430 OGRFeatureDefn CPL_DLL *S57GenerateGeomFeatureDefn( OGRwkbGeometryType, int ); 431 OGRFeatureDefn CPL_DLL *S57GenerateObjectClassDefn( S57ClassRegistrar *, 432 S57ClassContentExplorer* poClassContentExplorer, 433 int, int ); 434 OGRFeatureDefn CPL_DLL *S57GenerateVectorPrimitiveFeatureDefn( int, int ); 435 OGRFeatureDefn CPL_DLL *S57GenerateDSIDFeatureDefn( void ); 436 437 #endif /* ndef S57_H_INCLUDED */ 438