Ignore:
Timestamp:
2016-06-24T03:48:12+02:00 (9 years ago)
Author:
donvip
Message:

checkstyle

Location:
applications/editors/josm/plugins/seachart/src/s57
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • applications/editors/josm/plugins/seachart/src/s57/S57att.java

    r32393 r32394  
    1010package s57;
    1111
    12 import java.util.*;
    13 
    14 import s57.S57obj.*;
     12import java.util.EnumMap;
     13import java.util.HashMap;
     14
     15import s57.S57obj.Obj;
    1516
    1617public class S57att { // S57 Attribute lookup tables & methods
    17  
    18  public enum Att {
    19    UNKATT, AGENCY, BCNSHP, BUISHP, BOYSHP, BURDEP, CALSGN, CATAIR, CATACH, CATBRG, CATBUA, CATCBL, CATCAN, CATCAM, CATCHP, CATCOA, CATCTR, CATCON, CATCRN, CATDAM,
    20    CATDIS, CATDOC, CATDPG, CATFNC, CATFRY, CATFIF, CATFOG, CATFOR, CATGAT, CATHAF, CATHLK, CATICE, CATINB, CATLND, CATLMK, CATLAM, CATLIT, CATMFA, CATMPA, CATMOR,
    21    CATNAV, CATOBS, CATOFP, CATOLB, CATPLE, CATPIL, CATPIP, CATPRA, CATPYL, CATRAS, CATRTB, CATROS, CATTRK, CATRSC, CATREA, CATROD, CATRUN, CATSEA, CATSLC, CATSIT,
    22    CATSIW, CATSIL, CATSLO, CATSCF, CATSPM, CATTSS, CATVEG, CATWAT, CATWED, CATWRK, COLOUR, COLPAT, COMCHA, CPDATE, CSCALE, CONDTN, CONRAD, CONVIS, CURVEL, DATEND,
    23    DATSTA, DRVAL1, DRVAL2, ELEVAT, ESTRNG, EXCLIT, EXPSOU, FUNCTN, HEIGHT, HORACC, HORCLR, HORLEN, HORWID, ICEFAC, INFORM, JRSDTN, LIFCAP, LITCHR, LITVIS, MARSYS,
    24    MLTYLT, NATION, NATCON, NATSUR, NATQUA, NMDATE, OBJNAM, ORIENT, PEREND, PERSTA, PICREP, PILDST, PRCTRY, PRODCT, PUBREF, QUASOU, RADWAL, RADIUS, RYRMGV, RESTRN,
    25    SCAMIN, SCVAL1, SCVAL2, SECTR1, SECTR2, SHIPAM, SIGFRQ, SIGGEN, SIGGRP, SIGPER, SIGSEQ, SOUACC, SDISMX, SDISMN, SORDAT, SORIND, STATUS, SURATH, SUREND, SURSTA,
    26    SURTYP, TECSOU, TXTDSC, TS_TSP, TS_TSV, T_ACWL, T_HWLW, T_MTOD, T_THDF, T_TINT, T_TSVL, T_VAHC, TIMEND, TIMSTA, TOPSHP, TRAFIC, VALACM, VALDCO, VALLMA, VALMAG,
    27    VALMXR, VALNMR, VALSOU, VERACC, VERCLR, VERCCL, VERCOP, VERCSA, VERDAT, VERLEN, WATLEV, CAT_TS, NINFOM, NOBJNM, NPLDST, NTXTDS, HORDAT, POSACC, QUAPOS, CLSDNG,
    28    DIRIMP, DISBK1, DISBK2, DISIPU, DISIPD, ELEVA1, ELEVA2, FNCTNM, WTWDIS, BUNVES, BNKWTW, COMCTN, HORCLL, HORCLW, TRSHGD, UNLOCD, HIGWAT, HIGNAM, LOWWAT, LOWNAM,
    29    MEAWAT, MEANAM, OTHWAT, OTHNAM, REFLEV, SDRLEV, VCRLEV, SCHREF, USESHP, CURVHW, CURVLW, CURVMW, CURVOW, APTREF, SHPTYP, UPDMSG, ADDMRK, CATNMK, CATBRT, CATBUN,
    30    CATCCL, CATCOM, CATHBR, CATRFD, CATTML, CATGAG, CATVTR, CATTAB, CATEXS, LG_SPD, LG_SPR, LG_BME, LG_LGS, LG_DRT, LG_WDP, LG_WDU, LG_REL, LG_FNC, LG_DES, LG_PBR,
    31    LC_CSI, LC_CSE, LC_ASI, LC_ASE, LC_CCI, LC_CCE, LC_BM1, LC_BM2, LC_LG1, LC_LG2, LC_DR1, LC_DR2, LC_SP1, LC_SP2, LC_WD1, LC_WD2, LITRAD, CATCVR, HUNITS
    32  }
    33 
    34  private static final EnumMap<Att, Integer> AttS57 = new EnumMap<>(Att.class);
    35  static {
    36   AttS57.put(Att.UNKATT, 0); AttS57.put(Att.AGENCY, 1); AttS57.put(Att.BCNSHP, 2); AttS57.put(Att.BUISHP, 3); AttS57.put(Att.BOYSHP, 4); AttS57.put(Att.BURDEP, 5);
    37   AttS57.put(Att.CALSGN, 6); AttS57.put(Att.CATAIR, 7); AttS57.put(Att.CATACH, 8); AttS57.put(Att.CATBRG, 9); AttS57.put(Att.CATBUA, 10); AttS57.put(Att.CATCBL, 11);
    38   AttS57.put(Att.CATCAN, 12); AttS57.put(Att.CATCAM, 13); AttS57.put(Att.CATCHP, 14); AttS57.put(Att.CATCOA, 15); AttS57.put(Att.CATCTR, 16); AttS57.put(Att.CATCON, 17);
    39   AttS57.put(Att.CATCVR, 18); AttS57.put(Att.CATCRN, 19); AttS57.put(Att.CATDAM, 20); AttS57.put(Att.CATDIS, 21); AttS57.put(Att.CATDOC, 22); AttS57.put(Att.CATDPG, 23);
    40   AttS57.put(Att.CATFNC, 24); AttS57.put(Att.CATFRY, 25); AttS57.put(Att.CATFIF, 26); AttS57.put(Att.CATFOG, 27); AttS57.put(Att.CATFOR, 28); AttS57.put(Att.CATGAT, 29);
    41   AttS57.put(Att.CATHAF, 30); AttS57.put(Att.CATHLK, 31); AttS57.put(Att.CATICE, 32); AttS57.put(Att.CATINB, 33); AttS57.put(Att.CATLND, 34); AttS57.put(Att.CATLMK, 35);
    42   AttS57.put(Att.CATLAM, 36); AttS57.put(Att.CATLIT, 37); AttS57.put(Att.CATMFA, 38); AttS57.put(Att.CATMPA, 39); AttS57.put(Att.CATMOR, 40); AttS57.put(Att.CATNAV, 41);
    43   AttS57.put(Att.CATOBS, 42); AttS57.put(Att.CATOFP, 43); AttS57.put(Att.CATOLB, 44); AttS57.put(Att.CATPLE, 45); AttS57.put(Att.CATPIL, 46); AttS57.put(Att.CATPIP, 47);
    44   AttS57.put(Att.CATPRA, 48); AttS57.put(Att.CATPYL, 49); AttS57.put(Att.CATRAS, 51); AttS57.put(Att.CATRTB, 52); AttS57.put(Att.CATROS, 53); AttS57.put(Att.CATTRK, 54);
    45   AttS57.put(Att.CATRSC, 55); AttS57.put(Att.CATREA, 56); AttS57.put(Att.CATROD, 57); AttS57.put(Att.CATRUN, 58); AttS57.put(Att.CATSEA, 59); AttS57.put(Att.CATSLC, 60);
    46   AttS57.put(Att.CATSIT, 61); AttS57.put(Att.CATSIW, 62); AttS57.put(Att.CATSIL, 63); AttS57.put(Att.CATSLO, 64); AttS57.put(Att.CATSCF, 65); AttS57.put(Att.CATSPM, 66);
    47   AttS57.put(Att.CATTSS, 67); AttS57.put(Att.CATVEG, 68); AttS57.put(Att.CATWAT, 69); AttS57.put(Att.CATWED, 70); AttS57.put(Att.CATWRK, 71); AttS57.put(Att.COLOUR, 75);
    48   AttS57.put(Att.COLPAT, 76); AttS57.put(Att.COMCHA, 77); AttS57.put(Att.CONDTN, 81); AttS57.put(Att.CONRAD, 82); AttS57.put(Att.CONVIS, 83); AttS57.put(Att.CURVEL, 84);
    49   AttS57.put(Att.DATEND, 85); AttS57.put(Att.DATSTA, 86); AttS57.put(Att.DRVAL1, 87); AttS57.put(Att.DRVAL2, 88); AttS57.put(Att.ELEVAT, 90); AttS57.put(Att.ESTRNG, 91);
    50   AttS57.put(Att.EXCLIT, 92); AttS57.put(Att.EXPSOU, 93); AttS57.put(Att.FUNCTN, 94); AttS57.put(Att.HEIGHT, 95); AttS57.put(Att.HUNITS, 96); AttS57.put(Att.HORACC, 97);
    51   AttS57.put(Att.HORCLR, 98); AttS57.put(Att.HORLEN, 99); AttS57.put(Att.HORWID, 100); AttS57.put(Att.ICEFAC, 101); AttS57.put(Att.INFORM, 102); AttS57.put(Att.JRSDTN, 103);
    52   AttS57.put(Att.LIFCAP, 106); AttS57.put(Att.LITCHR, 107); AttS57.put(Att.LITVIS, 108); AttS57.put(Att.MARSYS, 109); AttS57.put(Att.MLTYLT, 110); AttS57.put(Att.NATION, 111);
    53   AttS57.put(Att.NATCON, 112); AttS57.put(Att.NATSUR, 113); AttS57.put(Att.NATQUA, 114); AttS57.put(Att.NMDATE, 115); AttS57.put(Att.OBJNAM, 116); AttS57.put(Att.ORIENT, 117);
    54   AttS57.put(Att.PEREND, 118); AttS57.put(Att.PERSTA, 119); AttS57.put(Att.PICREP, 120); AttS57.put(Att.PILDST, 121); AttS57.put(Att.PRCTRY, 122); AttS57.put(Att.PRODCT, 123);
    55   AttS57.put(Att.PUBREF, 124); AttS57.put(Att.QUASOU, 125); AttS57.put(Att.RADWAL, 126); AttS57.put(Att.RADIUS, 127); AttS57.put(Att.RYRMGV, 130); AttS57.put(Att.RESTRN, 131);
    56   AttS57.put(Att.SCAMIN, 133); AttS57.put(Att.SCVAL1, 134); AttS57.put(Att.SCVAL2, 135); AttS57.put(Att.SECTR1, 136); AttS57.put(Att.SECTR2, 137); AttS57.put(Att.SHIPAM, 138);
    57   AttS57.put(Att.SIGFRQ, 139); AttS57.put(Att.SIGGEN, 140); AttS57.put(Att.SIGGRP, 141); AttS57.put(Att.SIGPER, 142); AttS57.put(Att.SIGSEQ, 143); AttS57.put(Att.SOUACC, 144);
    58   AttS57.put(Att.SDISMX, 145); AttS57.put(Att.SDISMN, 146); AttS57.put(Att.SORDAT, 147); AttS57.put(Att.SORIND, 148); AttS57.put(Att.STATUS, 149); AttS57.put(Att.SURATH, 150);
    59   AttS57.put(Att.SUREND, 151); AttS57.put(Att.SURSTA, 152); AttS57.put(Att.SURTYP, 153); AttS57.put(Att.TECSOU, 156); AttS57.put(Att.TXTDSC, 158); AttS57.put(Att.TIMEND, 168);
    60   AttS57.put(Att.TIMSTA, 169); AttS57.put(Att.TOPSHP, 171); AttS57.put(Att.TRAFIC, 172); AttS57.put(Att.VALACM, 173); AttS57.put(Att.VALDCO, 174); AttS57.put(Att.VALLMA, 175);
    61   AttS57.put(Att.VALMAG, 176); AttS57.put(Att.VALMXR, 177); AttS57.put(Att.VALNMR, 178); AttS57.put(Att.VALSOU, 179); AttS57.put(Att.VERACC, 180); AttS57.put(Att.VERCLR, 181);
    62   AttS57.put(Att.VERCCL, 182); AttS57.put(Att.VERCOP, 183); AttS57.put(Att.VERCSA, 184); AttS57.put(Att.VERDAT, 185); AttS57.put(Att.VERLEN, 186); AttS57.put(Att.WATLEV, 187);
    63   AttS57.put(Att.CAT_TS, 188); AttS57.put(Att.NINFOM, 300); AttS57.put(Att.NOBJNM, 301); AttS57.put(Att.NPLDST, 302); AttS57.put(Att.NTXTDS, 304); AttS57.put(Att.HORDAT, 400);
    64   AttS57.put(Att.POSACC, 401); AttS57.put(Att.QUAPOS, 402);
    65  }
    66 
    67  private static final EnumMap<Att, Integer> AttIENC = new EnumMap<>(Att.class);
    68  static {
    69   AttIENC.put(Att.CATACH, 17000); AttIENC.put(Att.CATDIS, 17001); AttIENC.put(Att.CATSIT, 17002); AttIENC.put(Att.CATSIW, 17003); AttIENC.put(Att.RESTRN, 17004);
    70   AttIENC.put(Att.VERDAT, 17005); AttIENC.put(Att.CATBRG, 17006); AttIENC.put(Att.CATFRY, 17007); AttIENC.put(Att.CATHAF, 17008); AttIENC.put(Att.MARSYS, 17009);
    71   AttIENC.put(Att.CATCHP, 17010); AttIENC.put(Att.CATLAM, 17011); AttIENC.put(Att.CATSLC, 17012); AttIENC.put(Att.ADDMRK, 17050); AttIENC.put(Att.CATNMK, 17052);
    72   AttIENC.put(Att.CLSDNG, 17055); AttIENC.put(Att.DIRIMP, 17056); AttIENC.put(Att.DISBK1, 17057); AttIENC.put(Att.DISBK2, 17058); AttIENC.put(Att.DISIPU, 17059);
    73   AttIENC.put(Att.DISIPD, 17060); AttIENC.put(Att.ELEVA1, 17061); AttIENC.put(Att.ELEVA2, 17062); AttIENC.put(Att.FNCTNM, 17063); AttIENC.put(Att.WTWDIS, 17064);
    74   AttIENC.put(Att.BUNVES, 17065); AttIENC.put(Att.CATBRT, 17066); AttIENC.put(Att.CATBUN, 17067); AttIENC.put(Att.CATCCL, 17069); AttIENC.put(Att.CATHBR, 17070);
    75   AttIENC.put(Att.CATRFD, 17071); AttIENC.put(Att.CATTML, 17072); AttIENC.put(Att.COMCTN, 17073); AttIENC.put(Att.HORCLL, 17074); AttIENC.put(Att.HORCLW, 17075);
    76   AttIENC.put(Att.TRSHGD, 17076); AttIENC.put(Att.UNLOCD, 17077); AttIENC.put(Att.CATGAG, 17078); AttIENC.put(Att.HIGWAT, 17080); AttIENC.put(Att.HIGNAM, 17081);
    77   AttIENC.put(Att.LOWWAT, 17082); AttIENC.put(Att.LOWNAM, 17083); AttIENC.put(Att.MEAWAT, 17084); AttIENC.put(Att.MEANAM, 17085); AttIENC.put(Att.OTHWAT, 17086);
    78   AttIENC.put(Att.OTHNAM, 17087); AttIENC.put(Att.REFLEV, 17088); AttIENC.put(Att.SDRLEV, 17089); AttIENC.put(Att.VCRLEV, 17090); AttIENC.put(Att.CATVTR, 17091);
    79   AttIENC.put(Att.CATTAB, 17092); AttIENC.put(Att.SCHREF, 17093); AttIENC.put(Att.USESHP, 17094); AttIENC.put(Att.CURVHW, 17095); AttIENC.put(Att.CURVLW, 17096);
    80   AttIENC.put(Att.CURVMW, 17097); AttIENC.put(Att.CURVOW, 17098); AttIENC.put(Att.APTREF, 17099); AttIENC.put(Att.CATEXS, 17100); AttIENC.put(Att.CATCBL, 17101);
    81   AttIENC.put(Att.CATHLK, 17102); AttIENC.put(Att.HUNITS, 17103); AttIENC.put(Att.WATLEV, 17104); AttIENC.put(Att.LG_SPD, 18001); AttIENC.put(Att.LG_SPR, 18002);
    82   AttIENC.put(Att.LG_BME, 18003); AttIENC.put(Att.LG_LGS, 18004); AttIENC.put(Att.LG_DRT, 18005); AttIENC.put(Att.LG_WDP, 18006); AttIENC.put(Att.LG_WDU, 18007);
    83   AttIENC.put(Att.LG_REL, 18008); AttIENC.put(Att.LG_FNC, 18009); AttIENC.put(Att.LG_DES, 18010); AttIENC.put(Att.LG_PBR, 18011); AttIENC.put(Att.LC_CSI, 18012);
    84   AttIENC.put(Att.LC_CSE, 18013); AttIENC.put(Att.LC_ASI, 18014); AttIENC.put(Att.LC_ASE, 18015); AttIENC.put(Att.LC_CCI, 18016); AttIENC.put(Att.LC_CCE, 18017);
    85   AttIENC.put(Att.LC_BM1, 18018); AttIENC.put(Att.LC_BM2, 18019); AttIENC.put(Att.LC_LG1, 18020); AttIENC.put(Att.LC_LG2, 18021); AttIENC.put(Att.LC_DR1, 18022);
    86   AttIENC.put(Att.LC_DR2, 18023); AttIENC.put(Att.LC_SP1, 18024); AttIENC.put(Att.LC_SP2, 18025); AttIENC.put(Att.LC_WD1, 18026); AttIENC.put(Att.LC_WD2, 18027);
    87   AttIENC.put(Att.SHPTYP, 33066); AttIENC.put(Att.UPDMSG, 40000); AttIENC.put(Att.BNKWTW, 17999);
    88  }
    89  
    90  private static final EnumMap<Att, String> AttStr = new EnumMap<>(Att.class);
    91  static {
    92   AttStr.put(Att.UNKATT, ""); AttStr.put(Att.AGENCY, "agency"); AttStr.put(Att.BCNSHP, "shape"); AttStr.put(Att.BUISHP, "shape"); AttStr.put(Att.BOYSHP, "shape");
    93   AttStr.put(Att.BURDEP, "depth_buried"); AttStr.put(Att.CALSGN, "callsign"); AttStr.put(Att.CATAIR, "category"); AttStr.put(Att.CATACH, "category");
    94   AttStr.put(Att.CATBRG, "category"); AttStr.put(Att.CATBUA, "category"); AttStr.put(Att.CATCBL, "category"); AttStr.put(Att.CATCAN, "category");
    95   AttStr.put(Att.CATCAM, "category"); AttStr.put(Att.CATCHP, "category"); AttStr.put(Att.CATCOA, "category"); AttStr.put(Att.CATCTR, "category");
    96   AttStr.put(Att.CATCON, "category"); AttStr.put(Att.CATCRN, "category"); AttStr.put(Att.CATDAM, "category"); AttStr.put(Att.CATDIS, "category");
    97   AttStr.put(Att.CATDOC, "category"); AttStr.put(Att.CATDPG, "category"); AttStr.put(Att.CATFNC, "category"); AttStr.put(Att.CATFRY, "category");
    98   AttStr.put(Att.CATFIF, "category"); AttStr.put(Att.CATFOG, "category"); AttStr.put(Att.CATFOR, "category"); AttStr.put(Att.CATGAT, "category");
    99   AttStr.put(Att.CATHAF, "category"); AttStr.put(Att.CATHLK, "category"); AttStr.put(Att.CATICE, "category"); AttStr.put(Att.CATINB, "category");
    100   AttStr.put(Att.CATLND, "category"); AttStr.put(Att.CATLMK, "category"); AttStr.put(Att.CATLAM, "category"); AttStr.put(Att.CATLIT, "category");
    101   AttStr.put(Att.CATMFA, "category"); AttStr.put(Att.CATMPA, "category"); AttStr.put(Att.CATMOR, "category"); AttStr.put(Att.CATNAV, "category");
    102   AttStr.put(Att.CATOBS, "category"); AttStr.put(Att.CATOFP, "category"); AttStr.put(Att.CATOLB, "category"); AttStr.put(Att.CATPLE, "category");
    103   AttStr.put(Att.CATPIL, "category"); AttStr.put(Att.CATPIP, "category"); AttStr.put(Att.CATPRA, "category"); AttStr.put(Att.CATPYL, "category");
    104   AttStr.put(Att.CATRAS, "category"); AttStr.put(Att.CATRTB, "category"); AttStr.put(Att.CATROS, "category"); AttStr.put(Att.CATTRK, "category");
    105   AttStr.put(Att.CATRSC, "category"); AttStr.put(Att.CATREA, "category"); AttStr.put(Att.CATROD, "category"); AttStr.put(Att.CATRUN, "category");
    106   AttStr.put(Att.CATSEA, "category"); AttStr.put(Att.CATSLC, "category"); AttStr.put(Att.CATSIT, "category"); AttStr.put(Att.CATSIW, "category");
    107   AttStr.put(Att.CATSIL, "category"); AttStr.put(Att.CATSLO, "category"); AttStr.put(Att.CATSCF, "category"); AttStr.put(Att.CATSPM, "category");
    108   AttStr.put(Att.CATTSS, "category"); AttStr.put(Att.CATVEG, "category"); AttStr.put(Att.CATWAT, "category"); AttStr.put(Att.CATWED, "category");
    109   AttStr.put(Att.CATWRK, "category"); AttStr.put(Att.COLOUR, "colour"); AttStr.put(Att.COLPAT, "colour_pattern"); AttStr.put(Att.COMCHA, "channel");
    110   AttStr.put(Att.CONDTN, "condition"); AttStr.put(Att.CONRAD, "reflectivity"); AttStr.put(Att.CONVIS, "conspicuity"); AttStr.put(Att.CURVEL, "velocity");
    111   AttStr.put(Att.DATEND, "end_date"); AttStr.put(Att.DATSTA, "start_date"); AttStr.put(Att.DRVAL1, "minimum_depth"); AttStr.put(Att.DRVAL2, "maximum_depth");
    112   AttStr.put(Att.ELEVAT, "elevation"); AttStr.put(Att.ESTRNG, "estimated_range"); AttStr.put(Att.EXCLIT, "exhibition"); AttStr.put(Att.EXPSOU, "exposition");
    113   AttStr.put(Att.FUNCTN, "function"); AttStr.put(Att.HEIGHT, "height"); AttStr.put(Att.HUNITS, "units"); AttStr.put(Att.HORACC, "accuracy");
    114   AttStr.put(Att.HORCLR, "clearance_width"); AttStr.put(Att.HORLEN, "length"); AttStr.put(Att.HORWID, "width"); AttStr.put(Att.ICEFAC, "factor");
    115   AttStr.put(Att.INFORM, "information"); AttStr.put(Att.JRSDTN, "jurisdiction"); AttStr.put(Att.LIFCAP, "maximum_load"); AttStr.put(Att.LITCHR, "character");
    116   AttStr.put(Att.LITVIS, "visibility"); AttStr.put(Att.MARSYS, "system"); AttStr.put(Att.MLTYLT, "multiple"); AttStr.put(Att.NATION, "nationality");
    117   AttStr.put(Att.NATCON, "construction"); AttStr.put(Att.NATSUR, "surface"); AttStr.put(Att.NATQUA, "surface_qualification"); AttStr.put(Att.NMDATE, "nm_date");
    118   AttStr.put(Att.OBJNAM, "name"); AttStr.put(Att.ORIENT, "orientation"); AttStr.put(Att.PEREND, "period_end"); AttStr.put(Att.PERSTA, "period_start");
    119   AttStr.put(Att.PICREP, "picture"); AttStr.put(Att.PILDST, "pilot_district"); AttStr.put(Att.PRCTRY, "producing_country"); AttStr.put(Att.PRODCT, "product");
    120   AttStr.put(Att.PUBREF, "reference"); AttStr.put(Att.QUASOU, "quality"); AttStr.put(Att.RADWAL, "wavelength"); AttStr.put(Att.RADIUS, "radius");
    121   AttStr.put(Att.RYRMGV, "year"); AttStr.put(Att.RESTRN, "restriction"); AttStr.put(Att.SECTR1, "sector_start"); AttStr.put(Att.SECTR2, "sector_end");
    122   AttStr.put(Att.SHIPAM, "shift"); AttStr.put(Att.SIGFRQ, "frequency"); AttStr.put(Att.SIGGEN, "generation"); AttStr.put(Att.SIGGRP, "group");
    123   AttStr.put(Att.SIGPER, "period"); AttStr.put(Att.SIGSEQ, "sequence"); AttStr.put(Att.SOUACC, "sounding_accuracy"); AttStr.put(Att.SDISMX, "maximum_sounding");
    124   AttStr.put(Att.SDISMN, "minimum_sounding"); AttStr.put(Att.SORDAT, "source_date"); AttStr.put(Att.SORIND, "source"); AttStr.put(Att.STATUS, "status");
    125   AttStr.put(Att.SURATH, "authority"); AttStr.put(Att.SUREND, "survey_end"); AttStr.put(Att.SURSTA, "survey_start"); AttStr.put(Att.SURTYP, "survey");
    126   AttStr.put(Att.TECSOU, "technique"); AttStr.put(Att.TXTDSC, "document"); AttStr.put(Att.TIMEND, "end_time"); AttStr.put(Att.TIMSTA, "start_time");
    127   AttStr.put(Att.TOPSHP, "shape"); AttStr.put(Att.TRAFIC, "traffic_flow"); AttStr.put(Att.VALACM, "variation_change"); AttStr.put(Att.VALDCO, "depth");
    128   AttStr.put(Att.VALLMA, "anomaly"); AttStr.put(Att.VALMAG, "variation"); AttStr.put(Att.VALMXR, "maximum_range"); AttStr.put(Att.VALNMR, "range");
    129   AttStr.put(Att.VALSOU, "depth"); AttStr.put(Att.VERACC, "vertical_accuracy"); AttStr.put(Att.VERCLR, "clearance_height");
    130   AttStr.put(Att.VERCCL, "clearance_height_closed"); AttStr.put(Att.VERCOP, "clearance_height_open"); AttStr.put(Att.VERCSA, "clearance_height_safe");
    131   AttStr.put(Att.VERDAT, "vertical_datum"); AttStr.put(Att.VERLEN, "vertical_length"); AttStr.put(Att.WATLEV, "water_level"); AttStr.put(Att.CAT_TS, "category");
    132   AttStr.put(Att.NINFOM, "national_information"); AttStr.put(Att.NOBJNM, "national_name"); AttStr.put(Att.NPLDST, "national_pilot_district");
    133   AttStr.put(Att.NTXTDS, "national_description"); AttStr.put(Att.HORDAT, "horizontal_datum"); AttStr.put(Att.POSACC, "positional_accuracy");
    134   AttStr.put(Att.QUAPOS, "position_quality"); AttStr.put(Att.ADDMRK, "addition"); AttStr.put(Att.BNKWTW, "bank"); AttStr.put(Att.CATNMK, "category");
    135   AttStr.put(Att.CLSDNG, "danger_class"); AttStr.put(Att.DIRIMP, "impact"); AttStr.put(Att.DISBK1, "distance_start"); AttStr.put(Att.DISBK2, "distance_end");
    136   AttStr.put(Att.DISIPU, "distance_up"); AttStr.put(Att.DISIPD, "distance_down"); AttStr.put(Att.ELEVA1, "minimum_elevation");
    137   AttStr.put(Att.ELEVA2, "maximum_elevation"); AttStr.put(Att.FNCTNM, "function"); AttStr.put(Att.WTWDIS, "distance"); AttStr.put(Att.BUNVES, "availability");
    138   AttStr.put(Att.CATBRT, "category"); AttStr.put(Att.CATBUN, "category"); AttStr.put(Att.CATCCL, "category"); AttStr.put(Att.CATHBR, "category");
    139   AttStr.put(Att.CATRFD, "category"); AttStr.put(Att.CATTML, "category"); AttStr.put(Att.COMCTN, "communication"); AttStr.put(Att.HORCLL, "horizontal_clearance_length");
    140   AttStr.put(Att.HORCLW, "horizontal_clearance_width"); AttStr.put(Att.TRSHGD, "goods"); AttStr.put(Att.UNLOCD, ""); AttStr.put(Att.CATGAG, "category");
    141   AttStr.put(Att.HIGWAT, "high_value"); AttStr.put(Att.HIGNAM, "high_name"); AttStr.put(Att.LOWWAT, "low_value"); AttStr.put(Att.LOWNAM, "low_name");
    142   AttStr.put(Att.MEAWAT, "mean_value"); AttStr.put(Att.MEANAM, "mean_name"); AttStr.put(Att.OTHWAT, "local_value"); AttStr.put(Att.OTHNAM, "local_name");
    143   AttStr.put(Att.REFLEV, "gravity_reference"); AttStr.put(Att.SDRLEV, "sounding_name"); AttStr.put(Att.VCRLEV, "vertical_name"); AttStr.put(Att.CATVTR, "category");
    144   AttStr.put(Att.CATTAB, "operation"); AttStr.put(Att.SCHREF, "schedule"); AttStr.put(Att.USESHP, "use"); AttStr.put(Att.CURVHW, "high_velocity");
    145   AttStr.put(Att.CURVLW, "low_velocity"); AttStr.put(Att.CURVMW, "mean_velocity"); AttStr.put(Att.CURVOW, "other_velocity"); AttStr.put(Att.APTREF, "passing_time");
    146   AttStr.put(Att.CATCOM, "category"); AttStr.put(Att.CATCVR, "category"); AttStr.put(Att.CATEXS, "category"); AttStr.put(Att.SHPTYP, "ship");
    147   AttStr.put(Att.UPDMSG, "message"); AttStr.put(Att.LITRAD, "radius");
    148  }
    149  private static final EnumMap<Obj, Att> Accuracy = new EnumMap<>(Obj.class); static { Accuracy.put(Obj.UNKOBJ, Att.HORACC); }
    150  private static final EnumMap<Obj, Att> Addition = new EnumMap<>(Obj.class); static { Addition.put(Obj.UNKOBJ, Att.ADDMRK); }
    151  private static final EnumMap<Obj, Att> Agency = new EnumMap<>(Obj.class); static { Agency.put(Obj.UNKOBJ, Att.AGENCY); }
    152  private static final EnumMap<Obj, Att> Anomaly = new EnumMap<>(Obj.class); static { Anomaly.put(Obj.UNKOBJ, Att.VALLMA); }
    153  private static final EnumMap<Obj, Att> Authority = new EnumMap<>(Obj.class); static { Authority.put(Obj.UNKOBJ, Att.SURATH); }
    154  private static final EnumMap<Obj, Att> Availability = new EnumMap<>(Obj.class); static { Availability.put(Obj.UNKOBJ, Att.BUNVES); }
    155  private static final EnumMap<Obj, Att> Bank = new EnumMap<>(Obj.class); static { Bank.put(Obj.UNKOBJ, Att.BNKWTW); }
    156  private static final EnumMap<Obj, Att> Callsign = new EnumMap<>(Obj.class); static { Callsign.put(Obj.UNKOBJ, Att.CALSGN); }
    157  private static final EnumMap<Obj, Att> Category = new EnumMap<>(Obj.class); static {
    158   Category.put(Obj.ACHARE, Att.CATACH); Category.put(Obj.ACHBRT, Att.CATACH); Category.put(Obj.AIRARE, Att.CATAIR); Category.put(Obj.BCNCAR, Att.CATCAM); Category.put(Obj.BCNLAT, Att.CATLAM);
    159   Category.put(Obj.BCNSPP, Att.CATSPM); Category.put(Obj.BOYLAT, Att.CATLAM); Category.put(Obj.BOYINB, Att.CATINB); Category.put(Obj.BOYSPP, Att.CATSPM); Category.put(Obj.DAYMAR, Att.CATSPM);
    160   Category.put(Obj.BRIDGE, Att.CATBRG); Category.put(Obj.BUAARE, Att.CATBUA); Category.put(Obj.BUNSTA, Att.CATBUN); Category.put(Obj.CANALS, Att.CATCAN);
    161   Category.put(Obj.CBLARE, Att.CATCBL); Category.put(Obj.CBLOHD, Att.CATCBL); Category.put(Obj.CBLSUB, Att.CATCBL); Category.put(Obj.CHKPNT, Att.CATCHP); Category.put(Obj.COMARE, Att.CATCOM);
    162   Category.put(Obj.COALNE, Att.CATCOA); Category.put(Obj.CONVYR, Att.CATCON); Category.put(Obj.CRANES, Att.CATCRN); Category.put(Obj.CTRPNT, Att.CATCTR); Category.put(Obj.DAMCON, Att.CATDAM);
    163   Category.put(Obj.DISMAR, Att.CATDIS); Category.put(Obj.DMPGRD, Att.CATDPG); Category.put(Obj.DOCARE, Att.CATDOC); Category.put(Obj.EXCNST, Att.CATEXS); Category.put(Obj.FERYRT, Att.CATFRY);
    164   Category.put(Obj.FNCLNE, Att.CATFNC); Category.put(Obj.FOGSIG, Att.CATFOG); Category.put(Obj.FORSTC, Att.CATFOR); Category.put(Obj.FSHFAC, Att.CATFIF); Category.put(Obj.GATCON, Att.CATGAT);
    165   Category.put(Obj.HRBFAC, Att.CATHAF); Category.put(Obj.HRBARE, Att.CATHBR); Category.put(Obj.HRBBSN, Att.CATHBR); Category.put(Obj.HULKES, Att.CATHLK); Category.put(Obj.ICEARE, Att.CATICE);
    166   Category.put(Obj.LNDRGN, Att.CATLND); Category.put(Obj.LNDMRK, Att.CATLMK); Category.put(Obj.LIGHTS, Att.CATLIT); Category.put(Obj.M_COVR, Att.CATCVR); Category.put(Obj.MARCUL, Att.CATMFA);
    167   Category.put(Obj.MIPARE, Att.CATMPA); Category.put(Obj.MORFAC, Att.CATMOR); Category.put(Obj.NAVLNE, Att.CATNAV); Category.put(Obj.NOTMRK, Att.CATNMK); Category.put(Obj.OBSTRN, Att.CATOBS);
    168   Category.put(Obj.OFSPLF, Att.CATOFP); Category.put(Obj.OILBAR, Att.CATOLB); Category.put(Obj.OSPARE, Att.CATPRA); Category.put(Obj.PILPNT, Att.CATPLE); Category.put(Obj.PILBOP, Att.CATPIL);
    169   Category.put(Obj.PIPARE, Att.CATPIP); Category.put(Obj.PIPOHD, Att.CATPIP); Category.put(Obj.PIPSOL, Att.CATPIP); Category.put(Obj.PRDARE, Att.CATPRA); Category.put(Obj.PYLONS, Att.CATPYL);
    170   Category.put(Obj.RADSTA, Att.CATRAS); Category.put(Obj.RCRTCL, Att.CATTRK); Category.put(Obj.RCTLPT, Att.CATTRK); Category.put(Obj.RDOSTA, Att.CATROS); Category.put(Obj.RDOCAL, Att.CATCOM);
    171   Category.put(Obj.RECTRC, Att.CATTRK); Category.put(Obj.REFDMP, Att.CATRFD); Category.put(Obj.RESARE, Att.CATREA); Category.put(Obj.RSCSTA, Att.CATRSC);
    172   Category.put(Obj.RTPBCN, Att.CATRTB); Category.put(Obj.ROADWY, Att.CATROD); Category.put(Obj.RUNWAY, Att.CATRUN); Category.put(Obj.SEAARE, Att.CATSEA); Category.put(Obj.SILTNK, Att.CATSIL);
    173   Category.put(Obj.SISTAT, Att.CATSIT); Category.put(Obj.SISTAW, Att.CATSIW); Category.put(Obj.SLCONS, Att.CATSLC); Category.put(Obj.SLOTOP, Att.CATSLO); Category.put(Obj.SLOGRD, Att.CATSLO);
    174   Category.put(Obj.SMCFAC, Att.CATSCF); Category.put(Obj.TERMNL, Att.CATTML); Category.put(Obj.TS_FEB, Att.CAT_TS); Category.put(Obj.TSELNE, Att.CATTSS); Category.put(Obj.TSEZNE, Att.CATTSS);
    175   Category.put(Obj.TSSBND, Att.CATTSS); Category.put(Obj.TSSCRS, Att.CATTSS); Category.put(Obj.TSSLPT, Att.CATTSS); Category.put(Obj.TSSRON, Att.CATTSS); Category.put(Obj.TWRTPT, Att.CATTRK);
    176   Category.put(Obj.VEGATN, Att.CATVEG); Category.put(Obj.VEHTRF, Att.CATVTR); Category.put(Obj.WATTUR, Att.CATWAT); Category.put(Obj.WEDKLP, Att.CATWED); Category.put(Obj.WRECKS, Att.CATWRK);
    177   Category.put(Obj.WTWAXS, Att.CATCCL); Category.put(Obj.WTWARE, Att.CATCCL); Category.put(Obj.WTWGAG, Att.CATGAG); Category.put(Obj.BERTHS, Att.CATBRT);
    178  }
    179  
    180  private static final EnumMap<Obj, Att> Channel = new EnumMap<>(Obj.class); static { Channel.put(Obj.UNKOBJ, Att.COMCHA); }
    181  private static final EnumMap<Obj, Att> Character = new EnumMap<>(Obj.class); static { Character.put(Obj.UNKOBJ, Att.LITCHR); }
    182  private static final EnumMap<Obj, Att> Clearance_height = new EnumMap<>(Obj.class); static { Clearance_height.put(Obj.UNKOBJ, Att.VERCLR); }
    183  private static final EnumMap<Obj, Att> Clearance_height_closed = new EnumMap<>(Obj.class); static { Clearance_height_closed.put(Obj.UNKOBJ, Att.VERCCL); }
    184  private static final EnumMap<Obj, Att> Clearance_height_open = new EnumMap<>(Obj.class); static { Clearance_height_open.put(Obj.UNKOBJ, Att.VERCOP); }
    185  private static final EnumMap<Obj, Att> Clearance_height_safe = new EnumMap<>(Obj.class); static { Clearance_height_safe.put(Obj.UNKOBJ, Att.VERCSA); }
    186  private static final EnumMap<Obj, Att> Clearance_width = new EnumMap<>(Obj.class); static { Clearance_width.put(Obj.UNKOBJ, Att.HORCLR); }
    187  private static final EnumMap<Obj, Att> Colour = new EnumMap<>(Obj.class); static { Colour.put(Obj.UNKOBJ, Att.COLOUR); }
    188  private static final EnumMap<Obj, Att> Colour_pattern = new EnumMap<>(Obj.class); static { Colour_pattern.put(Obj.UNKOBJ, Att.COLPAT); }
    189  private static final EnumMap<Obj, Att> Communication = new EnumMap<>(Obj.class); static { Communication.put(Obj.UNKOBJ, Att.COMCTN); }
    190  private static final EnumMap<Obj, Att> Condition = new EnumMap<>(Obj.class); static { Condition.put(Obj.UNKOBJ, Att.CONDTN); }
    191  private static final EnumMap<Obj, Att> Conspicuity = new EnumMap<>(Obj.class); static { Conspicuity.put(Obj.UNKOBJ, Att.CONVIS); }
    192  private static final EnumMap<Obj, Att> Construction = new EnumMap<>(Obj.class); static { Construction.put(Obj.UNKOBJ, Att.NATCON); }
    193  private static final EnumMap<Obj, Att> Danger_class = new EnumMap<>(Obj.class); static { Danger_class.put(Obj.UNKOBJ, Att.CLSDNG); }
    194  private static final EnumMap<Obj, Att> Depth = new EnumMap<>(Obj.class); static { Depth.put(Obj.UNKOBJ, Att.VALDCO); Depth.put(Obj.SOUNDG, Att.VALSOU); }
    195  private static final EnumMap<Obj, Att> Depth_buried = new EnumMap<>(Obj.class); static { Depth_buried.put(Obj.UNKOBJ, Att.BURDEP); }
    196  private static final EnumMap<Obj, Att> Description = new EnumMap<>(Obj.class); static { Description.put(Obj.UNKOBJ, Att.TXTDSC); }
    197  private static final EnumMap<Obj, Att> Distance = new EnumMap<>(Obj.class); static { Distance.put(Obj.UNKOBJ, Att.WTWDIS); }
    198  private static final EnumMap<Obj, Att> Distance_down = new EnumMap<>(Obj.class); static { Distance_down.put(Obj.UNKOBJ, Att.DISIPD); }
    199  private static final EnumMap<Obj, Att> Distance_end = new EnumMap<>(Obj.class); static { Distance_end.put(Obj.UNKOBJ, Att.DISBK2); }
    200  private static final EnumMap<Obj, Att> Distance_start = new EnumMap<>(Obj.class); static { Distance_start.put(Obj.UNKOBJ, Att.DISBK1); }
    201  private static final EnumMap<Obj, Att> Distance_up = new EnumMap<>(Obj.class); static { Distance_up.put(Obj.UNKOBJ, Att.DISIPU); }
    202  private static final EnumMap<Obj, Att> Elevation = new EnumMap<>(Obj.class); static { Elevation.put(Obj.UNKOBJ, Att.ELEVAT); }
    203  private static final EnumMap<Obj, Att> End_date = new EnumMap<>(Obj.class); static { End_date.put(Obj.UNKOBJ, Att.DATEND); }
    204  private static final EnumMap<Obj, Att> End_time = new EnumMap<>(Obj.class); static { End_time.put(Obj.UNKOBJ, Att.TIMEND); }
    205  private static final EnumMap<Obj, Att> Estimated_range = new EnumMap<>(Obj.class); static { Estimated_range.put(Obj.UNKOBJ, Att.ESTRNG); }
    206  private static final EnumMap<Obj, Att> Exhibition = new EnumMap<>(Obj.class); static { Exhibition.put(Obj.UNKOBJ, Att.EXCLIT); }
    207  private static final EnumMap<Obj, Att> Exposition = new EnumMap<>(Obj.class); static { Exposition.put(Obj.UNKOBJ, Att.EXPSOU); }
    208  private static final EnumMap<Obj, Att> Factor = new EnumMap<>(Obj.class); static { Factor.put(Obj.UNKOBJ, Att.ICEFAC); }
    209  private static final EnumMap<Obj, Att> Frequency = new EnumMap<>(Obj.class); static { Frequency.put(Obj.UNKOBJ, Att.SIGFRQ); }
    210  private static final EnumMap<Obj, Att> Function = new EnumMap<>(Obj.class); static { Function.put(Obj.BUISGL, Att.FUNCTN); Function.put(Obj.LNDMRK, Att.FUNCTN); Function.put(Obj.NOTMRK, Att.FNCTNM); }
    211  private static final EnumMap<Obj, Att> Generation = new EnumMap<>(Obj.class); static { Generation.put(Obj.UNKOBJ, Att.SIGGEN); }
    212  private static final EnumMap<Obj, Att> Goods = new EnumMap<>(Obj.class); static { Goods.put(Obj.UNKOBJ, Att.TRSHGD); }
    213  private static final EnumMap<Obj, Att> Gravity_reference = new EnumMap<>(Obj.class); static { Gravity_reference.put(Obj.UNKOBJ, Att.REFLEV); }
    214  private static final EnumMap<Obj, Att> Group = new EnumMap<>(Obj.class); static { Group.put(Obj.UNKOBJ, Att.SIGGRP); }
    215  private static final EnumMap<Obj, Att> Height = new EnumMap<>(Obj.class); static { Height.put(Obj.UNKOBJ, Att.HEIGHT); }
    216  private static final EnumMap<Obj, Att> High_name = new EnumMap<>(Obj.class); static { High_name.put(Obj.UNKOBJ, Att.HIGNAM); }
    217  private static final EnumMap<Obj, Att> High_value = new EnumMap<>(Obj.class); static { High_value.put(Obj.UNKOBJ, Att.HIGWAT); }
    218  private static final EnumMap<Obj, Att> High_velocity = new EnumMap<>(Obj.class); static { High_velocity.put(Obj.UNKOBJ, Att.CURVHW); }
    219  private static final EnumMap<Obj, Att> Horizontal_clearance_length = new EnumMap<>(Obj.class); static { Horizontal_clearance_length.put(Obj.UNKOBJ, Att.HORCLL); }
    220  private static final EnumMap<Obj, Att> Horizontal_clearance_width = new EnumMap<>(Obj.class); static { Horizontal_clearance_width.put(Obj.UNKOBJ, Att.HORCLW); }
    221  private static final EnumMap<Obj, Att> Horizontal_datum = new EnumMap<>(Obj.class); static { Horizontal_datum.put(Obj.UNKOBJ, Att.HORDAT); }
    222  private static final EnumMap<Obj, Att> Impact = new EnumMap<>(Obj.class); static { Impact.put(Obj.UNKOBJ, Att.DIRIMP); }
    223  private static final EnumMap<Obj, Att> Information = new EnumMap<>(Obj.class); static { Information.put(Obj.UNKOBJ, Att.INFORM); }
    224  private static final EnumMap<Obj, Att> Jurisdiction = new EnumMap<>(Obj.class); static { Jurisdiction.put(Obj.UNKOBJ, Att.JRSDTN); }
    225  private static final EnumMap<Obj, Att> Length = new EnumMap<>(Obj.class); static { Length.put(Obj.UNKOBJ, Att.HORLEN); }
    226  private static final EnumMap<Obj, Att> Local_name = new EnumMap<>(Obj.class); static { Local_name.put(Obj.UNKOBJ, Att.OTHNAM); }
    227  private static final EnumMap<Obj, Att> Local_value = new EnumMap<>(Obj.class); static { Local_value.put(Obj.UNKOBJ, Att.OTHWAT); }
    228  private static final EnumMap<Obj, Att> Low_name = new EnumMap<>(Obj.class); static { Low_name.put(Obj.UNKOBJ, Att.LOWNAM); }
    229  private static final EnumMap<Obj, Att> Low_value = new EnumMap<>(Obj.class); static { Low_value.put(Obj.UNKOBJ, Att.LOWWAT); }
    230  private static final EnumMap<Obj, Att> Low_velocity = new EnumMap<>(Obj.class); static { Low_velocity.put(Obj.UNKOBJ, Att.CURVLW); }
    231  private static final EnumMap<Obj, Att> Maximum_depth = new EnumMap<>(Obj.class); static { Maximum_depth.put(Obj.UNKOBJ, Att.DRVAL2); }
    232  private static final EnumMap<Obj, Att> Maximum_elevation = new EnumMap<>(Obj.class); static { Maximum_elevation.put(Obj.UNKOBJ, Att.ELEVA2); }
    233  private static final EnumMap<Obj, Att> Maximum_load = new EnumMap<>(Obj.class); static { Maximum_load.put(Obj.UNKOBJ, Att.LIFCAP); }
    234  private static final EnumMap<Obj, Att> Maximum_range = new EnumMap<>(Obj.class); static { Maximum_range.put(Obj.UNKOBJ, Att.VALMXR); }
    235  private static final EnumMap<Obj, Att> Maximum_sounding = new EnumMap<>(Obj.class); static { Maximum_sounding.put(Obj.UNKOBJ, Att.SDISMX); }
    236  private static final EnumMap<Obj, Att> Mean_name = new EnumMap<>(Obj.class); static { Mean_name.put(Obj.UNKOBJ, Att.MEANAM); }
    237  private static final EnumMap<Obj, Att> Mean_value = new EnumMap<>(Obj.class); static { Mean_value.put(Obj.UNKOBJ, Att.MEAWAT); }
    238  private static final EnumMap<Obj, Att> Mean_velocity = new EnumMap<>(Obj.class); static { Mean_velocity.put(Obj.UNKOBJ, Att.CURVMW); }
    239  private static final EnumMap<Obj, Att> Message = new EnumMap<>(Obj.class); static { Message.put(Obj.UNKOBJ, Att.UPDMSG); }
    240  private static final EnumMap<Obj, Att> Minimum_depth = new EnumMap<>(Obj.class); static { Minimum_depth.put(Obj.UNKOBJ, Att.DRVAL1); }
    241  private static final EnumMap<Obj, Att> Minimum_elevation = new EnumMap<>(Obj.class); static { Minimum_elevation.put(Obj.UNKOBJ, Att.ELEVA1); }
    242  private static final EnumMap<Obj, Att> Minimum_sounding = new EnumMap<>(Obj.class); static { Minimum_sounding.put(Obj.UNKOBJ, Att.SDISMN); }
    243  private static final EnumMap<Obj, Att> Multiple = new EnumMap<>(Obj.class); static { Multiple.put(Obj.UNKOBJ, Att.MLTYLT); }
    244  private static final EnumMap<Obj, Att> Name = new EnumMap<>(Obj.class); static { Name.put(Obj.UNKOBJ, Att.OBJNAM); }
    245  private static final EnumMap<Obj, Att> National_information = new EnumMap<>(Obj.class); static { National_information.put(Obj.UNKOBJ, Att.NINFOM); }
    246  private static final EnumMap<Obj, Att> Nationality = new EnumMap<>(Obj.class); static { Nationality.put(Obj.UNKOBJ, Att.NATION); }
    247  private static final EnumMap<Obj, Att> National_description = new EnumMap<>(Obj.class); static { National_description.put(Obj.UNKOBJ, Att.NTXTDS); }
    248  private static final EnumMap<Obj, Att> National_name = new EnumMap<>(Obj.class); static { National_name.put(Obj.UNKOBJ, Att.NOBJNM); }
    249  private static final EnumMap<Obj, Att> National_pilot_district = new EnumMap<>(Obj.class); static { National_pilot_district.put(Obj.UNKOBJ, Att.NPLDST); }
    250  private static final EnumMap<Obj, Att> Nm_date = new EnumMap<>(Obj.class); static { Nm_date.put(Obj.UNKOBJ, Att.NMDATE); }
    251  private static final EnumMap<Obj, Att> Other_velocity = new EnumMap<>(Obj.class); static { Other_velocity.put(Obj.UNKOBJ, Att.CURVOW); }
    252  private static final EnumMap<Obj, Att> Operation = new EnumMap<>(Obj.class); static { Operation.put(Obj.UNKOBJ, Att.CATTAB); }
    253  private static final EnumMap<Obj, Att> Orientation = new EnumMap<>(Obj.class); static { Orientation.put(Obj.UNKOBJ, Att.ORIENT); }
    254  private static final EnumMap<Obj, Att> Passing_time = new EnumMap<>(Obj.class); static { Passing_time.put(Obj.UNKOBJ, Att.APTREF); }
    255  private static final EnumMap<Obj, Att> Period = new EnumMap<>(Obj.class); static { Period.put(Obj.UNKOBJ, Att.SIGPER); }
    256  private static final EnumMap<Obj, Att> Period_end = new EnumMap<>(Obj.class); static { Period_end.put(Obj.UNKOBJ, Att.PEREND); }
    257  private static final EnumMap<Obj, Att> Period_start = new EnumMap<>(Obj.class); static { Period_start.put(Obj.UNKOBJ, Att.PERSTA); }
    258  private static final EnumMap<Obj, Att> Pilot_district = new EnumMap<>(Obj.class); static { Pilot_district.put(Obj.UNKOBJ, Att.PILDST); }
    259  private static final EnumMap<Obj, Att> Position_quality = new EnumMap<>(Obj.class); static { Position_quality.put(Obj.UNKOBJ, Att.QUAPOS); }
    260  private static final EnumMap<Obj, Att> Positional_accuracy = new EnumMap<>(Obj.class); static { Positional_accuracy.put(Obj.UNKOBJ, Att.POSACC); }
    261  private static final EnumMap<Obj, Att> Producing_country = new EnumMap<>(Obj.class); static { Producing_country.put(Obj.UNKOBJ, Att.PRCTRY); }
    262  private static final EnumMap<Obj, Att> Product = new EnumMap<>(Obj.class); static { Product.put(Obj.UNKOBJ, Att.PRODCT); }
    263  private static final EnumMap<Obj, Att> Quality = new EnumMap<>(Obj.class); static { Quality.put(Obj.UNKOBJ, Att.QUASOU); }
    264  private static final EnumMap<Obj, Att> Radius = new EnumMap<>(Obj.class); static { Radius.put(Obj.UNKOBJ, Att.RADIUS); Radius.put(Obj.LIGHTS, Att.LITRAD); }
    265  private static final EnumMap<Obj, Att> Range = new EnumMap<>(Obj.class); static { Range.put(Obj.UNKOBJ, Att.VALNMR); }
    266  private static final EnumMap<Obj, Att> Reference = new EnumMap<>(Obj.class); static { Reference.put(Obj.UNKOBJ, Att.PUBREF); }
    267  private static final EnumMap<Obj, Att> Reflectivity = new EnumMap<>(Obj.class); static { Reflectivity.put(Obj.UNKOBJ, Att.CONRAD); }
    268  private static final EnumMap<Obj, Att> Restriction = new EnumMap<>(Obj.class); static { Restriction.put(Obj.UNKOBJ, Att.RESTRN); }
    269  private static final EnumMap<Obj, Att> Schedule = new EnumMap<>(Obj.class); static { Schedule.put(Obj.UNKOBJ, Att.SCHREF); }
    270  private static final EnumMap<Obj, Att> Shape = new EnumMap<>(Obj.class); static { Shape.put(Obj.BCNCAR, Att.BCNSHP); Shape.put(Obj.BCNISD, Att.BCNSHP);
    271   Shape.put(Obj.BCNLAT, Att.BCNSHP); Shape.put(Obj.BCNSAW, Att.BCNSHP); Shape.put(Obj.BCNSPP, Att.BCNSHP); Shape.put(Obj.BUISGL, Att.BUISHP);
    272   Shape.put(Obj.BOYCAR, Att.BOYSHP); Shape.put(Obj.BOYISD, Att.BOYSHP); Shape.put(Obj.BOYLAT, Att.BOYSHP); Shape.put(Obj.BOYSAW, Att.BOYSHP); Shape.put(Obj.BOYSPP, Att.BOYSHP);
    273   Shape.put(Obj.BOYINB, Att.BOYSHP); Shape.put(Obj.DAYMAR, Att.TOPSHP); Shape.put(Obj.TOPMAR, Att.TOPSHP); Shape.put(Obj.MORFAC, Att.BOYSHP);
    274   Shape.put(Obj.SILTNK, Att.BUISHP);
    275  }
    276  private static final EnumMap<Obj, Att> Sector_end = new EnumMap<>(Obj.class); static { Sector_end.put(Obj.UNKOBJ, Att.SECTR2); }
    277  private static final EnumMap<Obj, Att> Sector_start = new EnumMap<>(Obj.class); static { Sector_start.put(Obj.UNKOBJ, Att.SECTR1); }
    278  private static final EnumMap<Obj, Att> Sequence = new EnumMap<>(Obj.class); static { Sequence.put(Obj.UNKOBJ, Att.SIGSEQ); }
    279  private static final EnumMap<Obj, Att> Shift = new EnumMap<>(Obj.class); static { Shift.put(Obj.UNKOBJ, Att.SHIPAM); }
    280  private static final EnumMap<Obj, Att> Ship = new EnumMap<>(Obj.class); static { Ship.put(Obj.UNKOBJ, Att.SHPTYP); }
    281  private static final EnumMap<Obj, Att> Sounding_accuracy = new EnumMap<>(Obj.class); static { Sounding_accuracy.put(Obj.UNKOBJ, Att.SOUACC); }
    282  private static final EnumMap<Obj, Att> Sounding_name = new EnumMap<>(Obj.class); static { Sounding_name.put(Obj.UNKOBJ, Att.SDRLEV); }
    283  private static final EnumMap<Obj, Att> Start_date = new EnumMap<>(Obj.class); static { Start_date.put(Obj.UNKOBJ, Att.DATSTA); }
    284  private static final EnumMap<Obj, Att> Start_time = new EnumMap<>(Obj.class); static { Start_time.put(Obj.UNKOBJ, Att.TIMSTA); }
    285  private static final EnumMap<Obj, Att> Status = new EnumMap<>(Obj.class); static { Status.put(Obj.UNKOBJ, Att.STATUS); }
    286  private static final EnumMap<Obj, Att> Surface = new EnumMap<>(Obj.class); static { Surface.put(Obj.UNKOBJ, Att.NATSUR); }
    287  private static final EnumMap<Obj, Att> Surface_qualification = new EnumMap<>(Obj.class); static { Surface_qualification.put(Obj.UNKOBJ, Att.NATQUA); }
    288  private static final EnumMap<Obj, Att> Survey = new EnumMap<>(Obj.class); static { Survey.put(Obj.UNKOBJ, Att.SURTYP); }
    289  private static final EnumMap<Obj, Att> Survey_end = new EnumMap<>(Obj.class); static { Survey_end.put(Obj.UNKOBJ, Att.SUREND); }
    290  private static final EnumMap<Obj, Att> Survey_start = new EnumMap<>(Obj.class); static { Survey_start.put(Obj.UNKOBJ, Att.SURSTA); }
    291  private static final EnumMap<Obj, Att> System = new EnumMap<>(Obj.class); static { System.put(Obj.UNKOBJ, Att.MARSYS); }
    292  private static final EnumMap<Obj, Att> Technique = new EnumMap<>(Obj.class); static { Technique.put(Obj.UNKOBJ, Att.TECSOU); }
    293  private static final EnumMap<Obj, Att> Traffic_flow = new EnumMap<>(Obj.class); static { Traffic_flow.put(Obj.UNKOBJ, Att.TRAFIC); }
    294  private static final EnumMap<Obj, Att> Units = new EnumMap<>(Obj.class); static { Units.put(Obj.UNKOBJ, Att.HUNITS); }
    295  private static final EnumMap<Obj, Att> Use = new EnumMap<>(Obj.class); static { Use.put(Obj.UNKOBJ, Att.USESHP); }
    296  private static final EnumMap<Obj, Att> Variation = new EnumMap<>(Obj.class); static { Variation.put(Obj.UNKOBJ, Att.VALMAG); }
    297  private static final EnumMap<Obj, Att> Variation_change = new EnumMap<>(Obj.class); static { Variation_change.put(Obj.UNKOBJ, Att.VALACM); }
    298  private static final EnumMap<Obj, Att> Velocity = new EnumMap<>(Obj.class); static { Velocity.put(Obj.UNKOBJ, Att.CURVEL); }
    299  private static final EnumMap<Obj, Att> Vertical_accuracy = new EnumMap<>(Obj.class); static { Vertical_accuracy.put(Obj.UNKOBJ, Att.VERACC); }
    300  private static final EnumMap<Obj, Att> Vertical_datum = new EnumMap<>(Obj.class); static { Vertical_datum.put(Obj.UNKOBJ, Att.VERDAT); }
    301  private static final EnumMap<Obj, Att> Vertical_length = new EnumMap<>(Obj.class); static { Vertical_length.put(Obj.UNKOBJ, Att.VERLEN); }
    302  private static final EnumMap<Obj, Att> Vertical_name = new EnumMap<>(Obj.class); static { Vertical_name.put(Obj.UNKOBJ, Att.VCRLEV); }
    303  private static final EnumMap<Obj, Att> Visibility = new EnumMap<>(Obj.class); static { Visibility.put(Obj.UNKOBJ, Att.LITVIS); }
    304  private static final EnumMap<Obj, Att> Water_level = new EnumMap<>(Obj.class); static { Water_level.put(Obj.UNKOBJ, Att.WATLEV); }
    305  private static final EnumMap<Obj, Att> Wavelength = new EnumMap<>(Obj.class); static { Wavelength.put(Obj.UNKOBJ, Att.RADWAL); }
    306  private static final EnumMap<Obj, Att> Width = new EnumMap<>(Obj.class); static { Width.put(Obj.UNKOBJ, Att.HORWID); }
    307  private static final EnumMap<Obj, Att> Year = new EnumMap<>(Obj.class); static { Year.put(Obj.UNKOBJ, Att.RYRMGV); }
    308  
    309  private static final HashMap<String, EnumMap<Obj, Att>> StrAtt = new HashMap<>();
    310  static {
    311   StrAtt.put("accuracy", Accuracy); StrAtt.put("addition", Addition); StrAtt.put("agency", Agency); StrAtt.put("anomaly", Anomaly); StrAtt.put("authority", Authority);
    312   StrAtt.put("availability", Availability); StrAtt.put("bank", Bank); StrAtt.put("callsign", Callsign); StrAtt.put("category", Category); StrAtt.put("channel", Channel);
    313   StrAtt.put("character", Character); StrAtt.put("clearance_height", Clearance_height); StrAtt.put("clearance_height_closed", Clearance_height_closed);
    314   StrAtt.put("clearance_height_open", Clearance_height_open); StrAtt.put("clearance_height_safe", Clearance_height_safe); StrAtt.put("clearance_width", Clearance_width);
    315   StrAtt.put("colour", Colour); StrAtt.put("colour_pattern", Colour_pattern); StrAtt.put("communication", Communication); StrAtt.put("condition", Condition);
    316   StrAtt.put("conspicuity", Conspicuity); StrAtt.put("construction", Construction); StrAtt.put("danger_class", Danger_class); StrAtt.put("depth", Depth);
    317   StrAtt.put("depth_buried", Depth_buried); StrAtt.put("description", Description); StrAtt.put("distance", Distance); StrAtt.put("distance_down", Distance_down);
    318   StrAtt.put("distance_end", Distance_end); StrAtt.put("distance_start", Distance_start); StrAtt.put("distance_up", Distance_up); StrAtt.put("elevation", Elevation);
    319   StrAtt.put("end_date", End_date); StrAtt.put("end_time", End_time); StrAtt.put("estimated_range", Estimated_range); StrAtt.put("exhibition", Exhibition);
    320   StrAtt.put("exposition", Exposition); StrAtt.put("factor", Factor); StrAtt.put("frequency", Frequency); StrAtt.put("function", Function);
    321   StrAtt.put("generation", Generation); StrAtt.put("goods", Goods); StrAtt.put("gravity_reference", Gravity_reference); StrAtt.put("group", Group);
    322   StrAtt.put("height", Height); StrAtt.put("high_name", High_name); StrAtt.put("high_value", High_value); StrAtt.put("high_velocity", High_velocity);
    323   StrAtt.put("horizontal_clearance_length", Horizontal_clearance_length); StrAtt.put("horizontal_clearance_width", Horizontal_clearance_width);
    324   StrAtt.put("horizontal_datum", Horizontal_datum); StrAtt.put("impact", Impact); StrAtt.put("information", Information); StrAtt.put("jurisdiction", Jurisdiction);
    325   StrAtt.put("length", Length); StrAtt.put("local_name", Local_name); StrAtt.put("local_value", Local_value); StrAtt.put("low_name", Low_name);
    326   StrAtt.put("low_value", Low_value); StrAtt.put("low_velocity", Low_velocity); StrAtt.put("maximum_depth", Maximum_depth); StrAtt.put("maximum_elevation", Maximum_elevation);
    327   StrAtt.put("maximum_load", Maximum_load); StrAtt.put("maximum_range", Maximum_range); StrAtt.put("maximum_sounding", Maximum_sounding); StrAtt.put("mean_name", Mean_name);
    328   StrAtt.put("mean_value", Mean_value); StrAtt.put("mean_velocity", Mean_velocity); StrAtt.put("message", Message); StrAtt.put("minimum_depth", Minimum_depth);
    329   StrAtt.put("minimum_elevation", Minimum_elevation); StrAtt.put("minimum_sounding", Minimum_sounding); StrAtt.put("multiple", Multiple); StrAtt.put("name", Name);
    330   StrAtt.put("national_information", National_information); StrAtt.put("nationality", Nationality); StrAtt.put("national_description", National_description);
    331   StrAtt.put("national_name", National_name); StrAtt.put("national_pilot_district", National_pilot_district); StrAtt.put("nm_date", Nm_date); StrAtt.put("other_velocity", Other_velocity);
    332   StrAtt.put("operation", Operation); StrAtt.put("orientation", Orientation); StrAtt.put("passing_time", Passing_time); StrAtt.put("period", Period); StrAtt.put("period_end", Period_end);
    333   StrAtt.put("period_start", Period_start); StrAtt.put("pilot_district", Pilot_district); StrAtt.put("position_quality", Position_quality); StrAtt.put("positional_accuracy", Positional_accuracy);
    334   StrAtt.put("producing_country", Producing_country); StrAtt.put("product", Product); StrAtt.put("quality", Quality); StrAtt.put("radius", Radius); StrAtt.put("range", Range);
    335   StrAtt.put("reference", Reference); StrAtt.put("reflectivity", Reflectivity); StrAtt.put("restriction", Restriction); StrAtt.put("schedule", Schedule); StrAtt.put("shape", Shape);
    336   StrAtt.put("sector_end", Sector_end); StrAtt.put("sector_start", Sector_start); StrAtt.put("sequence", Sequence); StrAtt.put("shift", Shift); StrAtt.put("ship", Ship);
    337   StrAtt.put("sounding_accuracy", Sounding_accuracy); StrAtt.put("sounding_name", Sounding_name); StrAtt.put("start_date", Start_date); StrAtt.put("start_time", Start_time);
    338   StrAtt.put("status", Status); StrAtt.put("surface", Surface); StrAtt.put("surface_qualification", Surface_qualification); StrAtt.put("survey", Survey);
    339   StrAtt.put("survey_end", Survey_end); StrAtt.put("survey_start", Survey_start); StrAtt.put("system", System); StrAtt.put("technique", Technique); StrAtt.put("traffic_flow", Traffic_flow);
    340   StrAtt.put("units", Units); StrAtt.put("use", Use); StrAtt.put("variation", Variation); StrAtt.put("variation_change", Variation_change); StrAtt.put("velocity", Velocity);
    341   StrAtt.put("vertical_accuracy", Vertical_accuracy); StrAtt.put("vertical_datum", Vertical_datum); StrAtt.put("vertical_length", Vertical_length); StrAtt.put("vertical_name", Vertical_name);
    342   StrAtt.put("visibility", Visibility); StrAtt.put("water_level", Water_level); StrAtt.put("wavelength", Wavelength); StrAtt.put("width", Width); StrAtt.put("year", Year);
    343  }
    344 
    345  public static Att decodeAttribute(long attl) { // Convert S57 attribute code to SCM attribute enumeration
    346                 for (Att att : AttS57.keySet()) {
    347                         if (AttS57.get(att) == attl) return att;
    348                 }
    349                 for (Att att : AttIENC.keySet()) {
    350                         if (AttIENC.get(att) == attl) return att;
    351                 }
    352   return Att.UNKATT;
    353  }
    354  
    355  public static Integer encodeAttribute(String attribute) { // Convert SCM attribute enumeration to S57 attribute code
    356   if (AttS57.containsKey(attribute))
    357    return AttS57.get(attribute);
    358   else if (AttIENC.containsKey(attribute))
    359    return AttIENC.get(attribute);
    360   return 0;
    361  }
    362 
    363  public static Integer encodeAttribute(Att attribute) { // Convert SCM attribute enumeration to S57 attribute code
    364    return AttS57.get(attribute) != 0 ? AttS57.get(attribute) : AttIENC.get(attribute);
    365  }
    366 
    367  public static String stringAttribute(Att attribute) { // Convert SCM enumeration to OSM attribute string
    368   String str = AttStr.get(attribute);
    369   return str != null ? str : "";
    370  }
    371  
    372  public static Att enumAttribute(String attribute, Obj obj) { // Convert OSM attribute string to SCM enumeration
    373    if ((attribute != null) && !attribute.isEmpty()) {
    374    EnumMap<Obj, Att> map = StrAtt.get(attribute);
    375    if (map != null) {
    376     if (map.containsKey(obj)) {
    377      return map.get(obj);
    378     } else if (map.containsKey(Obj.UNKOBJ)) {
    379      return map.get(Obj.UNKOBJ);
    380     } else {
    381      return Att.UNKATT;
    382     }
    383    }
    384    }
    385   return Att.UNKATT;
    386  }
    387 
     18    // CHECKSTYLE.OFF: LineLength
     19
     20    public enum Att {
     21        UNKATT, AGENCY, BCNSHP, BUISHP, BOYSHP, BURDEP, CALSGN, CATAIR, CATACH, CATBRG, CATBUA, CATCBL, CATCAN, CATCAM, CATCHP, CATCOA, CATCTR, CATCON, CATCRN, CATDAM,
     22        CATDIS, CATDOC, CATDPG, CATFNC, CATFRY, CATFIF, CATFOG, CATFOR, CATGAT, CATHAF, CATHLK, CATICE, CATINB, CATLND, CATLMK, CATLAM, CATLIT, CATMFA, CATMPA, CATMOR,
     23        CATNAV, CATOBS, CATOFP, CATOLB, CATPLE, CATPIL, CATPIP, CATPRA, CATPYL, CATRAS, CATRTB, CATROS, CATTRK, CATRSC, CATREA, CATROD, CATRUN, CATSEA, CATSLC, CATSIT,
     24        CATSIW, CATSIL, CATSLO, CATSCF, CATSPM, CATTSS, CATVEG, CATWAT, CATWED, CATWRK, COLOUR, COLPAT, COMCHA, CPDATE, CSCALE, CONDTN, CONRAD, CONVIS, CURVEL, DATEND,
     25        DATSTA, DRVAL1, DRVAL2, ELEVAT, ESTRNG, EXCLIT, EXPSOU, FUNCTN, HEIGHT, HORACC, HORCLR, HORLEN, HORWID, ICEFAC, INFORM, JRSDTN, LIFCAP, LITCHR, LITVIS, MARSYS,
     26        MLTYLT, NATION, NATCON, NATSUR, NATQUA, NMDATE, OBJNAM, ORIENT, PEREND, PERSTA, PICREP, PILDST, PRCTRY, PRODCT, PUBREF, QUASOU, RADWAL, RADIUS, RYRMGV, RESTRN,
     27        SCAMIN, SCVAL1, SCVAL2, SECTR1, SECTR2, SHIPAM, SIGFRQ, SIGGEN, SIGGRP, SIGPER, SIGSEQ, SOUACC, SDISMX, SDISMN, SORDAT, SORIND, STATUS, SURATH, SUREND, SURSTA,
     28        SURTYP, TECSOU, TXTDSC, TS_TSP, TS_TSV, T_ACWL, T_HWLW, T_MTOD, T_THDF, T_TINT, T_TSVL, T_VAHC, TIMEND, TIMSTA, TOPSHP, TRAFIC, VALACM, VALDCO, VALLMA, VALMAG,
     29        VALMXR, VALNMR, VALSOU, VERACC, VERCLR, VERCCL, VERCOP, VERCSA, VERDAT, VERLEN, WATLEV, CAT_TS, NINFOM, NOBJNM, NPLDST, NTXTDS, HORDAT, POSACC, QUAPOS, CLSDNG,
     30        DIRIMP, DISBK1, DISBK2, DISIPU, DISIPD, ELEVA1, ELEVA2, FNCTNM, WTWDIS, BUNVES, BNKWTW, COMCTN, HORCLL, HORCLW, TRSHGD, UNLOCD, HIGWAT, HIGNAM, LOWWAT, LOWNAM,
     31        MEAWAT, MEANAM, OTHWAT, OTHNAM, REFLEV, SDRLEV, VCRLEV, SCHREF, USESHP, CURVHW, CURVLW, CURVMW, CURVOW, APTREF, SHPTYP, UPDMSG, ADDMRK, CATNMK, CATBRT, CATBUN,
     32        CATCCL, CATCOM, CATHBR, CATRFD, CATTML, CATGAG, CATVTR, CATTAB, CATEXS, LG_SPD, LG_SPR, LG_BME, LG_LGS, LG_DRT, LG_WDP, LG_WDU, LG_REL, LG_FNC, LG_DES, LG_PBR,
     33        LC_CSI, LC_CSE, LC_ASI, LC_ASE, LC_CCI, LC_CCE, LC_BM1, LC_BM2, LC_LG1, LC_LG2, LC_DR1, LC_DR2, LC_SP1, LC_SP2, LC_WD1, LC_WD2, LITRAD, CATCVR, HUNITS
     34    }
     35
     36    private static final EnumMap<Att, Integer> AttS57 = new EnumMap<>(Att.class);
     37    static {
     38        AttS57.put(Att.UNKATT, 0); AttS57.put(Att.AGENCY, 1); AttS57.put(Att.BCNSHP, 2); AttS57.put(Att.BUISHP, 3); AttS57.put(Att.BOYSHP, 4); AttS57.put(Att.BURDEP, 5);
     39        AttS57.put(Att.CALSGN, 6); AttS57.put(Att.CATAIR, 7); AttS57.put(Att.CATACH, 8); AttS57.put(Att.CATBRG, 9); AttS57.put(Att.CATBUA, 10); AttS57.put(Att.CATCBL, 11);
     40        AttS57.put(Att.CATCAN, 12); AttS57.put(Att.CATCAM, 13); AttS57.put(Att.CATCHP, 14); AttS57.put(Att.CATCOA, 15); AttS57.put(Att.CATCTR, 16); AttS57.put(Att.CATCON, 17);
     41        AttS57.put(Att.CATCVR, 18); AttS57.put(Att.CATCRN, 19); AttS57.put(Att.CATDAM, 20); AttS57.put(Att.CATDIS, 21); AttS57.put(Att.CATDOC, 22); AttS57.put(Att.CATDPG, 23);
     42        AttS57.put(Att.CATFNC, 24); AttS57.put(Att.CATFRY, 25); AttS57.put(Att.CATFIF, 26); AttS57.put(Att.CATFOG, 27); AttS57.put(Att.CATFOR, 28); AttS57.put(Att.CATGAT, 29);
     43        AttS57.put(Att.CATHAF, 30); AttS57.put(Att.CATHLK, 31); AttS57.put(Att.CATICE, 32); AttS57.put(Att.CATINB, 33); AttS57.put(Att.CATLND, 34); AttS57.put(Att.CATLMK, 35);
     44        AttS57.put(Att.CATLAM, 36); AttS57.put(Att.CATLIT, 37); AttS57.put(Att.CATMFA, 38); AttS57.put(Att.CATMPA, 39); AttS57.put(Att.CATMOR, 40); AttS57.put(Att.CATNAV, 41);
     45        AttS57.put(Att.CATOBS, 42); AttS57.put(Att.CATOFP, 43); AttS57.put(Att.CATOLB, 44); AttS57.put(Att.CATPLE, 45); AttS57.put(Att.CATPIL, 46); AttS57.put(Att.CATPIP, 47);
     46        AttS57.put(Att.CATPRA, 48); AttS57.put(Att.CATPYL, 49); AttS57.put(Att.CATRAS, 51); AttS57.put(Att.CATRTB, 52); AttS57.put(Att.CATROS, 53); AttS57.put(Att.CATTRK, 54);
     47        AttS57.put(Att.CATRSC, 55); AttS57.put(Att.CATREA, 56); AttS57.put(Att.CATROD, 57); AttS57.put(Att.CATRUN, 58); AttS57.put(Att.CATSEA, 59); AttS57.put(Att.CATSLC, 60);
     48        AttS57.put(Att.CATSIT, 61); AttS57.put(Att.CATSIW, 62); AttS57.put(Att.CATSIL, 63); AttS57.put(Att.CATSLO, 64); AttS57.put(Att.CATSCF, 65); AttS57.put(Att.CATSPM, 66);
     49        AttS57.put(Att.CATTSS, 67); AttS57.put(Att.CATVEG, 68); AttS57.put(Att.CATWAT, 69); AttS57.put(Att.CATWED, 70); AttS57.put(Att.CATWRK, 71); AttS57.put(Att.COLOUR, 75);
     50        AttS57.put(Att.COLPAT, 76); AttS57.put(Att.COMCHA, 77); AttS57.put(Att.CONDTN, 81); AttS57.put(Att.CONRAD, 82); AttS57.put(Att.CONVIS, 83); AttS57.put(Att.CURVEL, 84);
     51        AttS57.put(Att.DATEND, 85); AttS57.put(Att.DATSTA, 86); AttS57.put(Att.DRVAL1, 87); AttS57.put(Att.DRVAL2, 88); AttS57.put(Att.ELEVAT, 90); AttS57.put(Att.ESTRNG, 91);
     52        AttS57.put(Att.EXCLIT, 92); AttS57.put(Att.EXPSOU, 93); AttS57.put(Att.FUNCTN, 94); AttS57.put(Att.HEIGHT, 95); AttS57.put(Att.HUNITS, 96); AttS57.put(Att.HORACC, 97);
     53        AttS57.put(Att.HORCLR, 98); AttS57.put(Att.HORLEN, 99); AttS57.put(Att.HORWID, 100); AttS57.put(Att.ICEFAC, 101); AttS57.put(Att.INFORM, 102); AttS57.put(Att.JRSDTN, 103);
     54        AttS57.put(Att.LIFCAP, 106); AttS57.put(Att.LITCHR, 107); AttS57.put(Att.LITVIS, 108); AttS57.put(Att.MARSYS, 109); AttS57.put(Att.MLTYLT, 110); AttS57.put(Att.NATION, 111);
     55        AttS57.put(Att.NATCON, 112); AttS57.put(Att.NATSUR, 113); AttS57.put(Att.NATQUA, 114); AttS57.put(Att.NMDATE, 115); AttS57.put(Att.OBJNAM, 116); AttS57.put(Att.ORIENT, 117);
     56        AttS57.put(Att.PEREND, 118); AttS57.put(Att.PERSTA, 119); AttS57.put(Att.PICREP, 120); AttS57.put(Att.PILDST, 121); AttS57.put(Att.PRCTRY, 122); AttS57.put(Att.PRODCT, 123);
     57        AttS57.put(Att.PUBREF, 124); AttS57.put(Att.QUASOU, 125); AttS57.put(Att.RADWAL, 126); AttS57.put(Att.RADIUS, 127); AttS57.put(Att.RYRMGV, 130); AttS57.put(Att.RESTRN, 131);
     58        AttS57.put(Att.SCAMIN, 133); AttS57.put(Att.SCVAL1, 134); AttS57.put(Att.SCVAL2, 135); AttS57.put(Att.SECTR1, 136); AttS57.put(Att.SECTR2, 137); AttS57.put(Att.SHIPAM, 138);
     59        AttS57.put(Att.SIGFRQ, 139); AttS57.put(Att.SIGGEN, 140); AttS57.put(Att.SIGGRP, 141); AttS57.put(Att.SIGPER, 142); AttS57.put(Att.SIGSEQ, 143); AttS57.put(Att.SOUACC, 144);
     60        AttS57.put(Att.SDISMX, 145); AttS57.put(Att.SDISMN, 146); AttS57.put(Att.SORDAT, 147); AttS57.put(Att.SORIND, 148); AttS57.put(Att.STATUS, 149); AttS57.put(Att.SURATH, 150);
     61        AttS57.put(Att.SUREND, 151); AttS57.put(Att.SURSTA, 152); AttS57.put(Att.SURTYP, 153); AttS57.put(Att.TECSOU, 156); AttS57.put(Att.TXTDSC, 158); AttS57.put(Att.TIMEND, 168);
     62        AttS57.put(Att.TIMSTA, 169); AttS57.put(Att.TOPSHP, 171); AttS57.put(Att.TRAFIC, 172); AttS57.put(Att.VALACM, 173); AttS57.put(Att.VALDCO, 174); AttS57.put(Att.VALLMA, 175);
     63        AttS57.put(Att.VALMAG, 176); AttS57.put(Att.VALMXR, 177); AttS57.put(Att.VALNMR, 178); AttS57.put(Att.VALSOU, 179); AttS57.put(Att.VERACC, 180); AttS57.put(Att.VERCLR, 181);
     64        AttS57.put(Att.VERCCL, 182); AttS57.put(Att.VERCOP, 183); AttS57.put(Att.VERCSA, 184); AttS57.put(Att.VERDAT, 185); AttS57.put(Att.VERLEN, 186); AttS57.put(Att.WATLEV, 187);
     65        AttS57.put(Att.CAT_TS, 188); AttS57.put(Att.NINFOM, 300); AttS57.put(Att.NOBJNM, 301); AttS57.put(Att.NPLDST, 302); AttS57.put(Att.NTXTDS, 304); AttS57.put(Att.HORDAT, 400);
     66        AttS57.put(Att.POSACC, 401); AttS57.put(Att.QUAPOS, 402);
     67    }
     68
     69    private static final EnumMap<Att, Integer> AttIENC = new EnumMap<>(Att.class);
     70    static {
     71        AttIENC.put(Att.CATACH, 17000); AttIENC.put(Att.CATDIS, 17001); AttIENC.put(Att.CATSIT, 17002); AttIENC.put(Att.CATSIW, 17003); AttIENC.put(Att.RESTRN, 17004);
     72        AttIENC.put(Att.VERDAT, 17005); AttIENC.put(Att.CATBRG, 17006); AttIENC.put(Att.CATFRY, 17007); AttIENC.put(Att.CATHAF, 17008); AttIENC.put(Att.MARSYS, 17009);
     73        AttIENC.put(Att.CATCHP, 17010); AttIENC.put(Att.CATLAM, 17011); AttIENC.put(Att.CATSLC, 17012); AttIENC.put(Att.ADDMRK, 17050); AttIENC.put(Att.CATNMK, 17052);
     74        AttIENC.put(Att.CLSDNG, 17055); AttIENC.put(Att.DIRIMP, 17056); AttIENC.put(Att.DISBK1, 17057); AttIENC.put(Att.DISBK2, 17058); AttIENC.put(Att.DISIPU, 17059);
     75        AttIENC.put(Att.DISIPD, 17060); AttIENC.put(Att.ELEVA1, 17061); AttIENC.put(Att.ELEVA2, 17062); AttIENC.put(Att.FNCTNM, 17063); AttIENC.put(Att.WTWDIS, 17064);
     76        AttIENC.put(Att.BUNVES, 17065); AttIENC.put(Att.CATBRT, 17066); AttIENC.put(Att.CATBUN, 17067); AttIENC.put(Att.CATCCL, 17069); AttIENC.put(Att.CATHBR, 17070);
     77        AttIENC.put(Att.CATRFD, 17071); AttIENC.put(Att.CATTML, 17072); AttIENC.put(Att.COMCTN, 17073); AttIENC.put(Att.HORCLL, 17074); AttIENC.put(Att.HORCLW, 17075);
     78        AttIENC.put(Att.TRSHGD, 17076); AttIENC.put(Att.UNLOCD, 17077); AttIENC.put(Att.CATGAG, 17078); AttIENC.put(Att.HIGWAT, 17080); AttIENC.put(Att.HIGNAM, 17081);
     79        AttIENC.put(Att.LOWWAT, 17082); AttIENC.put(Att.LOWNAM, 17083); AttIENC.put(Att.MEAWAT, 17084); AttIENC.put(Att.MEANAM, 17085); AttIENC.put(Att.OTHWAT, 17086);
     80        AttIENC.put(Att.OTHNAM, 17087); AttIENC.put(Att.REFLEV, 17088); AttIENC.put(Att.SDRLEV, 17089); AttIENC.put(Att.VCRLEV, 17090); AttIENC.put(Att.CATVTR, 17091);
     81        AttIENC.put(Att.CATTAB, 17092); AttIENC.put(Att.SCHREF, 17093); AttIENC.put(Att.USESHP, 17094); AttIENC.put(Att.CURVHW, 17095); AttIENC.put(Att.CURVLW, 17096);
     82        AttIENC.put(Att.CURVMW, 17097); AttIENC.put(Att.CURVOW, 17098); AttIENC.put(Att.APTREF, 17099); AttIENC.put(Att.CATEXS, 17100); AttIENC.put(Att.CATCBL, 17101);
     83        AttIENC.put(Att.CATHLK, 17102); AttIENC.put(Att.HUNITS, 17103); AttIENC.put(Att.WATLEV, 17104); AttIENC.put(Att.LG_SPD, 18001); AttIENC.put(Att.LG_SPR, 18002);
     84        AttIENC.put(Att.LG_BME, 18003); AttIENC.put(Att.LG_LGS, 18004); AttIENC.put(Att.LG_DRT, 18005); AttIENC.put(Att.LG_WDP, 18006); AttIENC.put(Att.LG_WDU, 18007);
     85        AttIENC.put(Att.LG_REL, 18008); AttIENC.put(Att.LG_FNC, 18009); AttIENC.put(Att.LG_DES, 18010); AttIENC.put(Att.LG_PBR, 18011); AttIENC.put(Att.LC_CSI, 18012);
     86        AttIENC.put(Att.LC_CSE, 18013); AttIENC.put(Att.LC_ASI, 18014); AttIENC.put(Att.LC_ASE, 18015); AttIENC.put(Att.LC_CCI, 18016); AttIENC.put(Att.LC_CCE, 18017);
     87        AttIENC.put(Att.LC_BM1, 18018); AttIENC.put(Att.LC_BM2, 18019); AttIENC.put(Att.LC_LG1, 18020); AttIENC.put(Att.LC_LG2, 18021); AttIENC.put(Att.LC_DR1, 18022);
     88        AttIENC.put(Att.LC_DR2, 18023); AttIENC.put(Att.LC_SP1, 18024); AttIENC.put(Att.LC_SP2, 18025); AttIENC.put(Att.LC_WD1, 18026); AttIENC.put(Att.LC_WD2, 18027);
     89        AttIENC.put(Att.SHPTYP, 33066); AttIENC.put(Att.UPDMSG, 40000); AttIENC.put(Att.BNKWTW, 17999);
     90    }
     91
     92    private static final EnumMap<Att, String> AttStr = new EnumMap<>(Att.class);
     93    static {
     94        AttStr.put(Att.UNKATT, ""); AttStr.put(Att.AGENCY, "agency"); AttStr.put(Att.BCNSHP, "shape"); AttStr.put(Att.BUISHP, "shape"); AttStr.put(Att.BOYSHP, "shape");
     95        AttStr.put(Att.BURDEP, "depth_buried"); AttStr.put(Att.CALSGN, "callsign"); AttStr.put(Att.CATAIR, "category"); AttStr.put(Att.CATACH, "category");
     96        AttStr.put(Att.CATBRG, "category"); AttStr.put(Att.CATBUA, "category"); AttStr.put(Att.CATCBL, "category"); AttStr.put(Att.CATCAN, "category");
     97        AttStr.put(Att.CATCAM, "category"); AttStr.put(Att.CATCHP, "category"); AttStr.put(Att.CATCOA, "category"); AttStr.put(Att.CATCTR, "category");
     98        AttStr.put(Att.CATCON, "category"); AttStr.put(Att.CATCRN, "category"); AttStr.put(Att.CATDAM, "category"); AttStr.put(Att.CATDIS, "category");
     99        AttStr.put(Att.CATDOC, "category"); AttStr.put(Att.CATDPG, "category"); AttStr.put(Att.CATFNC, "category"); AttStr.put(Att.CATFRY, "category");
     100        AttStr.put(Att.CATFIF, "category"); AttStr.put(Att.CATFOG, "category"); AttStr.put(Att.CATFOR, "category"); AttStr.put(Att.CATGAT, "category");
     101        AttStr.put(Att.CATHAF, "category"); AttStr.put(Att.CATHLK, "category"); AttStr.put(Att.CATICE, "category"); AttStr.put(Att.CATINB, "category");
     102        AttStr.put(Att.CATLND, "category"); AttStr.put(Att.CATLMK, "category"); AttStr.put(Att.CATLAM, "category"); AttStr.put(Att.CATLIT, "category");
     103        AttStr.put(Att.CATMFA, "category"); AttStr.put(Att.CATMPA, "category"); AttStr.put(Att.CATMOR, "category"); AttStr.put(Att.CATNAV, "category");
     104        AttStr.put(Att.CATOBS, "category"); AttStr.put(Att.CATOFP, "category"); AttStr.put(Att.CATOLB, "category"); AttStr.put(Att.CATPLE, "category");
     105        AttStr.put(Att.CATPIL, "category"); AttStr.put(Att.CATPIP, "category"); AttStr.put(Att.CATPRA, "category"); AttStr.put(Att.CATPYL, "category");
     106        AttStr.put(Att.CATRAS, "category"); AttStr.put(Att.CATRTB, "category"); AttStr.put(Att.CATROS, "category"); AttStr.put(Att.CATTRK, "category");
     107        AttStr.put(Att.CATRSC, "category"); AttStr.put(Att.CATREA, "category"); AttStr.put(Att.CATROD, "category"); AttStr.put(Att.CATRUN, "category");
     108        AttStr.put(Att.CATSEA, "category"); AttStr.put(Att.CATSLC, "category"); AttStr.put(Att.CATSIT, "category"); AttStr.put(Att.CATSIW, "category");
     109        AttStr.put(Att.CATSIL, "category"); AttStr.put(Att.CATSLO, "category"); AttStr.put(Att.CATSCF, "category"); AttStr.put(Att.CATSPM, "category");
     110        AttStr.put(Att.CATTSS, "category"); AttStr.put(Att.CATVEG, "category"); AttStr.put(Att.CATWAT, "category"); AttStr.put(Att.CATWED, "category");
     111        AttStr.put(Att.CATWRK, "category"); AttStr.put(Att.COLOUR, "colour"); AttStr.put(Att.COLPAT, "colour_pattern"); AttStr.put(Att.COMCHA, "channel");
     112        AttStr.put(Att.CONDTN, "condition"); AttStr.put(Att.CONRAD, "reflectivity"); AttStr.put(Att.CONVIS, "conspicuity"); AttStr.put(Att.CURVEL, "velocity");
     113        AttStr.put(Att.DATEND, "end_date"); AttStr.put(Att.DATSTA, "start_date"); AttStr.put(Att.DRVAL1, "minimum_depth"); AttStr.put(Att.DRVAL2, "maximum_depth");
     114        AttStr.put(Att.ELEVAT, "elevation"); AttStr.put(Att.ESTRNG, "estimated_range"); AttStr.put(Att.EXCLIT, "exhibition"); AttStr.put(Att.EXPSOU, "exposition");
     115        AttStr.put(Att.FUNCTN, "function"); AttStr.put(Att.HEIGHT, "height"); AttStr.put(Att.HUNITS, "units"); AttStr.put(Att.HORACC, "accuracy");
     116        AttStr.put(Att.HORCLR, "clearance_width"); AttStr.put(Att.HORLEN, "length"); AttStr.put(Att.HORWID, "width"); AttStr.put(Att.ICEFAC, "factor");
     117        AttStr.put(Att.INFORM, "information"); AttStr.put(Att.JRSDTN, "jurisdiction"); AttStr.put(Att.LIFCAP, "maximum_load"); AttStr.put(Att.LITCHR, "character");
     118        AttStr.put(Att.LITVIS, "visibility"); AttStr.put(Att.MARSYS, "system"); AttStr.put(Att.MLTYLT, "multiple"); AttStr.put(Att.NATION, "nationality");
     119        AttStr.put(Att.NATCON, "construction"); AttStr.put(Att.NATSUR, "surface"); AttStr.put(Att.NATQUA, "surface_qualification"); AttStr.put(Att.NMDATE, "nm_date");
     120        AttStr.put(Att.OBJNAM, "name"); AttStr.put(Att.ORIENT, "orientation"); AttStr.put(Att.PEREND, "period_end"); AttStr.put(Att.PERSTA, "period_start");
     121        AttStr.put(Att.PICREP, "picture"); AttStr.put(Att.PILDST, "pilot_district"); AttStr.put(Att.PRCTRY, "producing_country"); AttStr.put(Att.PRODCT, "product");
     122        AttStr.put(Att.PUBREF, "reference"); AttStr.put(Att.QUASOU, "quality"); AttStr.put(Att.RADWAL, "wavelength"); AttStr.put(Att.RADIUS, "radius");
     123        AttStr.put(Att.RYRMGV, "year"); AttStr.put(Att.RESTRN, "restriction"); AttStr.put(Att.SECTR1, "sector_start"); AttStr.put(Att.SECTR2, "sector_end");
     124        AttStr.put(Att.SHIPAM, "shift"); AttStr.put(Att.SIGFRQ, "frequency"); AttStr.put(Att.SIGGEN, "generation"); AttStr.put(Att.SIGGRP, "group");
     125        AttStr.put(Att.SIGPER, "period"); AttStr.put(Att.SIGSEQ, "sequence"); AttStr.put(Att.SOUACC, "sounding_accuracy"); AttStr.put(Att.SDISMX, "maximum_sounding");
     126        AttStr.put(Att.SDISMN, "minimum_sounding"); AttStr.put(Att.SORDAT, "source_date"); AttStr.put(Att.SORIND, "source"); AttStr.put(Att.STATUS, "status");
     127        AttStr.put(Att.SURATH, "authority"); AttStr.put(Att.SUREND, "survey_end"); AttStr.put(Att.SURSTA, "survey_start"); AttStr.put(Att.SURTYP, "survey");
     128        AttStr.put(Att.TECSOU, "technique"); AttStr.put(Att.TXTDSC, "document"); AttStr.put(Att.TIMEND, "end_time"); AttStr.put(Att.TIMSTA, "start_time");
     129        AttStr.put(Att.TOPSHP, "shape"); AttStr.put(Att.TRAFIC, "traffic_flow"); AttStr.put(Att.VALACM, "variation_change"); AttStr.put(Att.VALDCO, "depth");
     130        AttStr.put(Att.VALLMA, "anomaly"); AttStr.put(Att.VALMAG, "variation"); AttStr.put(Att.VALMXR, "maximum_range"); AttStr.put(Att.VALNMR, "range");
     131        AttStr.put(Att.VALSOU, "depth"); AttStr.put(Att.VERACC, "vertical_accuracy"); AttStr.put(Att.VERCLR, "clearance_height");
     132        AttStr.put(Att.VERCCL, "clearance_height_closed"); AttStr.put(Att.VERCOP, "clearance_height_open"); AttStr.put(Att.VERCSA, "clearance_height_safe");
     133        AttStr.put(Att.VERDAT, "vertical_datum"); AttStr.put(Att.VERLEN, "vertical_length"); AttStr.put(Att.WATLEV, "water_level"); AttStr.put(Att.CAT_TS, "category");
     134        AttStr.put(Att.NINFOM, "national_information"); AttStr.put(Att.NOBJNM, "national_name"); AttStr.put(Att.NPLDST, "national_pilot_district");
     135        AttStr.put(Att.NTXTDS, "national_description"); AttStr.put(Att.HORDAT, "horizontal_datum"); AttStr.put(Att.POSACC, "positional_accuracy");
     136        AttStr.put(Att.QUAPOS, "position_quality"); AttStr.put(Att.ADDMRK, "addition"); AttStr.put(Att.BNKWTW, "bank"); AttStr.put(Att.CATNMK, "category");
     137        AttStr.put(Att.CLSDNG, "danger_class"); AttStr.put(Att.DIRIMP, "impact"); AttStr.put(Att.DISBK1, "distance_start"); AttStr.put(Att.DISBK2, "distance_end");
     138        AttStr.put(Att.DISIPU, "distance_up"); AttStr.put(Att.DISIPD, "distance_down"); AttStr.put(Att.ELEVA1, "minimum_elevation");
     139        AttStr.put(Att.ELEVA2, "maximum_elevation"); AttStr.put(Att.FNCTNM, "function"); AttStr.put(Att.WTWDIS, "distance"); AttStr.put(Att.BUNVES, "availability");
     140        AttStr.put(Att.CATBRT, "category"); AttStr.put(Att.CATBUN, "category"); AttStr.put(Att.CATCCL, "category"); AttStr.put(Att.CATHBR, "category");
     141        AttStr.put(Att.CATRFD, "category"); AttStr.put(Att.CATTML, "category"); AttStr.put(Att.COMCTN, "communication"); AttStr.put(Att.HORCLL, "horizontal_clearance_length");
     142        AttStr.put(Att.HORCLW, "horizontal_clearance_width"); AttStr.put(Att.TRSHGD, "goods"); AttStr.put(Att.UNLOCD, ""); AttStr.put(Att.CATGAG, "category");
     143        AttStr.put(Att.HIGWAT, "high_value"); AttStr.put(Att.HIGNAM, "high_name"); AttStr.put(Att.LOWWAT, "low_value"); AttStr.put(Att.LOWNAM, "low_name");
     144        AttStr.put(Att.MEAWAT, "mean_value"); AttStr.put(Att.MEANAM, "mean_name"); AttStr.put(Att.OTHWAT, "local_value"); AttStr.put(Att.OTHNAM, "local_name");
     145        AttStr.put(Att.REFLEV, "gravity_reference"); AttStr.put(Att.SDRLEV, "sounding_name"); AttStr.put(Att.VCRLEV, "vertical_name"); AttStr.put(Att.CATVTR, "category");
     146        AttStr.put(Att.CATTAB, "operation"); AttStr.put(Att.SCHREF, "schedule"); AttStr.put(Att.USESHP, "use"); AttStr.put(Att.CURVHW, "high_velocity");
     147        AttStr.put(Att.CURVLW, "low_velocity"); AttStr.put(Att.CURVMW, "mean_velocity"); AttStr.put(Att.CURVOW, "other_velocity"); AttStr.put(Att.APTREF, "passing_time");
     148        AttStr.put(Att.CATCOM, "category"); AttStr.put(Att.CATCVR, "category"); AttStr.put(Att.CATEXS, "category"); AttStr.put(Att.SHPTYP, "ship");
     149        AttStr.put(Att.UPDMSG, "message"); AttStr.put(Att.LITRAD, "radius");
     150    }
     151
     152    private static final EnumMap<Obj, Att> Accuracy = new EnumMap<>(Obj.class); static {
     153        Accuracy.put(Obj.UNKOBJ, Att.HORACC); }
     154
     155    private static final EnumMap<Obj, Att> Addition = new EnumMap<>(Obj.class); static {
     156        Addition.put(Obj.UNKOBJ, Att.ADDMRK); }
     157
     158    private static final EnumMap<Obj, Att> Agency = new EnumMap<>(Obj.class); static {
     159        Agency.put(Obj.UNKOBJ, Att.AGENCY); }
     160
     161    private static final EnumMap<Obj, Att> Anomaly = new EnumMap<>(Obj.class); static {
     162        Anomaly.put(Obj.UNKOBJ, Att.VALLMA); }
     163
     164    private static final EnumMap<Obj, Att> Authority = new EnumMap<>(Obj.class); static {
     165        Authority.put(Obj.UNKOBJ, Att.SURATH); }
     166
     167    private static final EnumMap<Obj, Att> Availability = new EnumMap<>(Obj.class); static {
     168        Availability.put(Obj.UNKOBJ, Att.BUNVES); }
     169
     170    private static final EnumMap<Obj, Att> Bank = new EnumMap<>(Obj.class); static {
     171        Bank.put(Obj.UNKOBJ, Att.BNKWTW); }
     172
     173    private static final EnumMap<Obj, Att> Callsign = new EnumMap<>(Obj.class); static {
     174        Callsign.put(Obj.UNKOBJ, Att.CALSGN); }
     175
     176    private static final EnumMap<Obj, Att> Category = new EnumMap<>(Obj.class);
     177    static {
     178        Category.put(Obj.ACHARE, Att.CATACH); Category.put(Obj.ACHBRT, Att.CATACH); Category.put(Obj.AIRARE, Att.CATAIR); Category.put(Obj.BCNCAR, Att.CATCAM); Category.put(Obj.BCNLAT, Att.CATLAM);
     179        Category.put(Obj.BCNSPP, Att.CATSPM); Category.put(Obj.BOYLAT, Att.CATLAM); Category.put(Obj.BOYINB, Att.CATINB); Category.put(Obj.BOYSPP, Att.CATSPM); Category.put(Obj.DAYMAR, Att.CATSPM);
     180        Category.put(Obj.BRIDGE, Att.CATBRG); Category.put(Obj.BUAARE, Att.CATBUA); Category.put(Obj.BUNSTA, Att.CATBUN); Category.put(Obj.CANALS, Att.CATCAN);
     181        Category.put(Obj.CBLARE, Att.CATCBL); Category.put(Obj.CBLOHD, Att.CATCBL); Category.put(Obj.CBLSUB, Att.CATCBL); Category.put(Obj.CHKPNT, Att.CATCHP); Category.put(Obj.COMARE, Att.CATCOM);
     182        Category.put(Obj.COALNE, Att.CATCOA); Category.put(Obj.CONVYR, Att.CATCON); Category.put(Obj.CRANES, Att.CATCRN); Category.put(Obj.CTRPNT, Att.CATCTR); Category.put(Obj.DAMCON, Att.CATDAM);
     183        Category.put(Obj.DISMAR, Att.CATDIS); Category.put(Obj.DMPGRD, Att.CATDPG); Category.put(Obj.DOCARE, Att.CATDOC); Category.put(Obj.EXCNST, Att.CATEXS); Category.put(Obj.FERYRT, Att.CATFRY);
     184        Category.put(Obj.FNCLNE, Att.CATFNC); Category.put(Obj.FOGSIG, Att.CATFOG); Category.put(Obj.FORSTC, Att.CATFOR); Category.put(Obj.FSHFAC, Att.CATFIF); Category.put(Obj.GATCON, Att.CATGAT);
     185        Category.put(Obj.HRBFAC, Att.CATHAF); Category.put(Obj.HRBARE, Att.CATHBR); Category.put(Obj.HRBBSN, Att.CATHBR); Category.put(Obj.HULKES, Att.CATHLK); Category.put(Obj.ICEARE, Att.CATICE);
     186        Category.put(Obj.LNDRGN, Att.CATLND); Category.put(Obj.LNDMRK, Att.CATLMK); Category.put(Obj.LIGHTS, Att.CATLIT); Category.put(Obj.M_COVR, Att.CATCVR); Category.put(Obj.MARCUL, Att.CATMFA);
     187        Category.put(Obj.MIPARE, Att.CATMPA); Category.put(Obj.MORFAC, Att.CATMOR); Category.put(Obj.NAVLNE, Att.CATNAV); Category.put(Obj.NOTMRK, Att.CATNMK); Category.put(Obj.OBSTRN, Att.CATOBS);
     188        Category.put(Obj.OFSPLF, Att.CATOFP); Category.put(Obj.OILBAR, Att.CATOLB); Category.put(Obj.OSPARE, Att.CATPRA); Category.put(Obj.PILPNT, Att.CATPLE); Category.put(Obj.PILBOP, Att.CATPIL);
     189        Category.put(Obj.PIPARE, Att.CATPIP); Category.put(Obj.PIPOHD, Att.CATPIP); Category.put(Obj.PIPSOL, Att.CATPIP); Category.put(Obj.PRDARE, Att.CATPRA); Category.put(Obj.PYLONS, Att.CATPYL);
     190        Category.put(Obj.RADSTA, Att.CATRAS); Category.put(Obj.RCRTCL, Att.CATTRK); Category.put(Obj.RCTLPT, Att.CATTRK); Category.put(Obj.RDOSTA, Att.CATROS); Category.put(Obj.RDOCAL, Att.CATCOM);
     191        Category.put(Obj.RECTRC, Att.CATTRK); Category.put(Obj.REFDMP, Att.CATRFD); Category.put(Obj.RESARE, Att.CATREA); Category.put(Obj.RSCSTA, Att.CATRSC);
     192        Category.put(Obj.RTPBCN, Att.CATRTB); Category.put(Obj.ROADWY, Att.CATROD); Category.put(Obj.RUNWAY, Att.CATRUN); Category.put(Obj.SEAARE, Att.CATSEA); Category.put(Obj.SILTNK, Att.CATSIL);
     193        Category.put(Obj.SISTAT, Att.CATSIT); Category.put(Obj.SISTAW, Att.CATSIW); Category.put(Obj.SLCONS, Att.CATSLC); Category.put(Obj.SLOTOP, Att.CATSLO); Category.put(Obj.SLOGRD, Att.CATSLO);
     194        Category.put(Obj.SMCFAC, Att.CATSCF); Category.put(Obj.TERMNL, Att.CATTML); Category.put(Obj.TS_FEB, Att.CAT_TS); Category.put(Obj.TSELNE, Att.CATTSS); Category.put(Obj.TSEZNE, Att.CATTSS);
     195        Category.put(Obj.TSSBND, Att.CATTSS); Category.put(Obj.TSSCRS, Att.CATTSS); Category.put(Obj.TSSLPT, Att.CATTSS); Category.put(Obj.TSSRON, Att.CATTSS); Category.put(Obj.TWRTPT, Att.CATTRK);
     196        Category.put(Obj.VEGATN, Att.CATVEG); Category.put(Obj.VEHTRF, Att.CATVTR); Category.put(Obj.WATTUR, Att.CATWAT); Category.put(Obj.WEDKLP, Att.CATWED); Category.put(Obj.WRECKS, Att.CATWRK);
     197        Category.put(Obj.WTWAXS, Att.CATCCL); Category.put(Obj.WTWARE, Att.CATCCL); Category.put(Obj.WTWGAG, Att.CATGAG); Category.put(Obj.BERTHS, Att.CATBRT);
     198    }
     199
     200    private static final EnumMap<Obj, Att> Channel = new EnumMap<>(Obj.class); static {
     201        Channel.put(Obj.UNKOBJ, Att.COMCHA); }
     202
     203    private static final EnumMap<Obj, Att> Character = new EnumMap<>(Obj.class); static {
     204        Character.put(Obj.UNKOBJ, Att.LITCHR); }
     205
     206    private static final EnumMap<Obj, Att> Clearance_height = new EnumMap<>(Obj.class); static {
     207        Clearance_height.put(Obj.UNKOBJ, Att.VERCLR); }
     208
     209    private static final EnumMap<Obj, Att> Clearance_height_closed = new EnumMap<>(Obj.class); static {
     210        Clearance_height_closed.put(Obj.UNKOBJ, Att.VERCCL); }
     211
     212    private static final EnumMap<Obj, Att> Clearance_height_open = new EnumMap<>(Obj.class); static {
     213        Clearance_height_open.put(Obj.UNKOBJ, Att.VERCOP); }
     214
     215    private static final EnumMap<Obj, Att> Clearance_height_safe = new EnumMap<>(Obj.class); static {
     216        Clearance_height_safe.put(Obj.UNKOBJ, Att.VERCSA); }
     217
     218    private static final EnumMap<Obj, Att> Clearance_width = new EnumMap<>(Obj.class); static {
     219        Clearance_width.put(Obj.UNKOBJ, Att.HORCLR); }
     220
     221    private static final EnumMap<Obj, Att> Colour = new EnumMap<>(Obj.class); static {
     222        Colour.put(Obj.UNKOBJ, Att.COLOUR); }
     223
     224    private static final EnumMap<Obj, Att> Colour_pattern = new EnumMap<>(Obj.class); static {
     225        Colour_pattern.put(Obj.UNKOBJ, Att.COLPAT); }
     226
     227    private static final EnumMap<Obj, Att> Communication = new EnumMap<>(Obj.class); static {
     228        Communication.put(Obj.UNKOBJ, Att.COMCTN); }
     229
     230    private static final EnumMap<Obj, Att> Condition = new EnumMap<>(Obj.class); static {
     231        Condition.put(Obj.UNKOBJ, Att.CONDTN); }
     232
     233    private static final EnumMap<Obj, Att> Conspicuity = new EnumMap<>(Obj.class); static {
     234        Conspicuity.put(Obj.UNKOBJ, Att.CONVIS); }
     235
     236    private static final EnumMap<Obj, Att> Construction = new EnumMap<>(Obj.class); static {
     237        Construction.put(Obj.UNKOBJ, Att.NATCON); }
     238
     239    private static final EnumMap<Obj, Att> Danger_class = new EnumMap<>(Obj.class); static {
     240        Danger_class.put(Obj.UNKOBJ, Att.CLSDNG); }
     241
     242    private static final EnumMap<Obj, Att> Depth = new EnumMap<>(Obj.class); static {
     243        Depth.put(Obj.UNKOBJ, Att.VALDCO); Depth.put(Obj.SOUNDG, Att.VALSOU); }
     244
     245    private static final EnumMap<Obj, Att> Depth_buried = new EnumMap<>(Obj.class); static {
     246        Depth_buried.put(Obj.UNKOBJ, Att.BURDEP); }
     247
     248    private static final EnumMap<Obj, Att> Description = new EnumMap<>(Obj.class); static {
     249        Description.put(Obj.UNKOBJ, Att.TXTDSC); }
     250
     251    private static final EnumMap<Obj, Att> Distance = new EnumMap<>(Obj.class); static {
     252        Distance.put(Obj.UNKOBJ, Att.WTWDIS); }
     253
     254    private static final EnumMap<Obj, Att> Distance_down = new EnumMap<>(Obj.class); static {
     255        Distance_down.put(Obj.UNKOBJ, Att.DISIPD); }
     256
     257    private static final EnumMap<Obj, Att> Distance_end = new EnumMap<>(Obj.class); static {
     258        Distance_end.put(Obj.UNKOBJ, Att.DISBK2); }
     259
     260    private static final EnumMap<Obj, Att> Distance_start = new EnumMap<>(Obj.class); static {
     261        Distance_start.put(Obj.UNKOBJ, Att.DISBK1); }
     262
     263    private static final EnumMap<Obj, Att> Distance_up = new EnumMap<>(Obj.class); static {
     264        Distance_up.put(Obj.UNKOBJ, Att.DISIPU); }
     265
     266    private static final EnumMap<Obj, Att> Elevation = new EnumMap<>(Obj.class); static {
     267        Elevation.put(Obj.UNKOBJ, Att.ELEVAT); }
     268
     269    private static final EnumMap<Obj, Att> End_date = new EnumMap<>(Obj.class); static {
     270        End_date.put(Obj.UNKOBJ, Att.DATEND); }
     271
     272    private static final EnumMap<Obj, Att> End_time = new EnumMap<>(Obj.class); static {
     273        End_time.put(Obj.UNKOBJ, Att.TIMEND); }
     274
     275    private static final EnumMap<Obj, Att> Estimated_range = new EnumMap<>(Obj.class); static {
     276        Estimated_range.put(Obj.UNKOBJ, Att.ESTRNG); }
     277
     278    private static final EnumMap<Obj, Att> Exhibition = new EnumMap<>(Obj.class); static {
     279        Exhibition.put(Obj.UNKOBJ, Att.EXCLIT); }
     280
     281    private static final EnumMap<Obj, Att> Exposition = new EnumMap<>(Obj.class); static {
     282        Exposition.put(Obj.UNKOBJ, Att.EXPSOU); }
     283
     284    private static final EnumMap<Obj, Att> Factor = new EnumMap<>(Obj.class); static {
     285        Factor.put(Obj.UNKOBJ, Att.ICEFAC); }
     286
     287    private static final EnumMap<Obj, Att> Frequency = new EnumMap<>(Obj.class); static {
     288        Frequency.put(Obj.UNKOBJ, Att.SIGFRQ); }
     289
     290    private static final EnumMap<Obj, Att> Function = new EnumMap<>(Obj.class); static {
     291        Function.put(Obj.BUISGL, Att.FUNCTN); Function.put(Obj.LNDMRK, Att.FUNCTN); Function.put(Obj.NOTMRK, Att.FNCTNM); }
     292
     293    private static final EnumMap<Obj, Att> Generation = new EnumMap<>(Obj.class); static {
     294        Generation.put(Obj.UNKOBJ, Att.SIGGEN); }
     295
     296    private static final EnumMap<Obj, Att> Goods = new EnumMap<>(Obj.class); static {
     297        Goods.put(Obj.UNKOBJ, Att.TRSHGD); }
     298
     299    private static final EnumMap<Obj, Att> Gravity_reference = new EnumMap<>(Obj.class); static {
     300        Gravity_reference.put(Obj.UNKOBJ, Att.REFLEV); }
     301
     302    private static final EnumMap<Obj, Att> Group = new EnumMap<>(Obj.class); static {
     303        Group.put(Obj.UNKOBJ, Att.SIGGRP); }
     304
     305    private static final EnumMap<Obj, Att> Height = new EnumMap<>(Obj.class); static {
     306        Height.put(Obj.UNKOBJ, Att.HEIGHT); }
     307
     308    private static final EnumMap<Obj, Att> High_name = new EnumMap<>(Obj.class); static {
     309        High_name.put(Obj.UNKOBJ, Att.HIGNAM); }
     310
     311    private static final EnumMap<Obj, Att> High_value = new EnumMap<>(Obj.class); static {
     312        High_value.put(Obj.UNKOBJ, Att.HIGWAT); }
     313
     314    private static final EnumMap<Obj, Att> High_velocity = new EnumMap<>(Obj.class); static {
     315        High_velocity.put(Obj.UNKOBJ, Att.CURVHW); }
     316
     317    private static final EnumMap<Obj, Att> Horizontal_clearance_length = new EnumMap<>(Obj.class); static {
     318        Horizontal_clearance_length.put(Obj.UNKOBJ, Att.HORCLL); }
     319
     320    private static final EnumMap<Obj, Att> Horizontal_clearance_width = new EnumMap<>(Obj.class); static {
     321        Horizontal_clearance_width.put(Obj.UNKOBJ, Att.HORCLW); }
     322
     323    private static final EnumMap<Obj, Att> Horizontal_datum = new EnumMap<>(Obj.class); static {
     324        Horizontal_datum.put(Obj.UNKOBJ, Att.HORDAT); }
     325
     326    private static final EnumMap<Obj, Att> Impact = new EnumMap<>(Obj.class); static {
     327        Impact.put(Obj.UNKOBJ, Att.DIRIMP); }
     328
     329    private static final EnumMap<Obj, Att> Information = new EnumMap<>(Obj.class); static {
     330        Information.put(Obj.UNKOBJ, Att.INFORM); }
     331
     332    private static final EnumMap<Obj, Att> Jurisdiction = new EnumMap<>(Obj.class); static {
     333        Jurisdiction.put(Obj.UNKOBJ, Att.JRSDTN); }
     334
     335    private static final EnumMap<Obj, Att> Length = new EnumMap<>(Obj.class); static {
     336        Length.put(Obj.UNKOBJ, Att.HORLEN); }
     337
     338    private static final EnumMap<Obj, Att> Local_name = new EnumMap<>(Obj.class); static {
     339        Local_name.put(Obj.UNKOBJ, Att.OTHNAM); }
     340
     341    private static final EnumMap<Obj, Att> Local_value = new EnumMap<>(Obj.class); static {
     342        Local_value.put(Obj.UNKOBJ, Att.OTHWAT); }
     343
     344    private static final EnumMap<Obj, Att> Low_name = new EnumMap<>(Obj.class); static {
     345        Low_name.put(Obj.UNKOBJ, Att.LOWNAM); }
     346
     347    private static final EnumMap<Obj, Att> Low_value = new EnumMap<>(Obj.class); static {
     348        Low_value.put(Obj.UNKOBJ, Att.LOWWAT); }
     349
     350    private static final EnumMap<Obj, Att> Low_velocity = new EnumMap<>(Obj.class); static {
     351        Low_velocity.put(Obj.UNKOBJ, Att.CURVLW); }
     352
     353    private static final EnumMap<Obj, Att> Maximum_depth = new EnumMap<>(Obj.class); static {
     354        Maximum_depth.put(Obj.UNKOBJ, Att.DRVAL2); }
     355
     356    private static final EnumMap<Obj, Att> Maximum_elevation = new EnumMap<>(Obj.class); static {
     357        Maximum_elevation.put(Obj.UNKOBJ, Att.ELEVA2); }
     358
     359    private static final EnumMap<Obj, Att> Maximum_load = new EnumMap<>(Obj.class); static {
     360        Maximum_load.put(Obj.UNKOBJ, Att.LIFCAP); }
     361
     362    private static final EnumMap<Obj, Att> Maximum_range = new EnumMap<>(Obj.class); static {
     363        Maximum_range.put(Obj.UNKOBJ, Att.VALMXR); }
     364
     365    private static final EnumMap<Obj, Att> Maximum_sounding = new EnumMap<>(Obj.class); static {
     366        Maximum_sounding.put(Obj.UNKOBJ, Att.SDISMX); }
     367
     368    private static final EnumMap<Obj, Att> Mean_name = new EnumMap<>(Obj.class); static {
     369        Mean_name.put(Obj.UNKOBJ, Att.MEANAM); }
     370
     371    private static final EnumMap<Obj, Att> Mean_value = new EnumMap<>(Obj.class); static {
     372        Mean_value.put(Obj.UNKOBJ, Att.MEAWAT); }
     373
     374    private static final EnumMap<Obj, Att> Mean_velocity = new EnumMap<>(Obj.class); static {
     375        Mean_velocity.put(Obj.UNKOBJ, Att.CURVMW); }
     376
     377    private static final EnumMap<Obj, Att> Message = new EnumMap<>(Obj.class); static {
     378        Message.put(Obj.UNKOBJ, Att.UPDMSG); }
     379
     380    private static final EnumMap<Obj, Att> Minimum_depth = new EnumMap<>(Obj.class); static {
     381        Minimum_depth.put(Obj.UNKOBJ, Att.DRVAL1); }
     382
     383    private static final EnumMap<Obj, Att> Minimum_elevation = new EnumMap<>(Obj.class); static {
     384        Minimum_elevation.put(Obj.UNKOBJ, Att.ELEVA1); }
     385
     386    private static final EnumMap<Obj, Att> Minimum_sounding = new EnumMap<>(Obj.class); static {
     387        Minimum_sounding.put(Obj.UNKOBJ, Att.SDISMN); }
     388
     389    private static final EnumMap<Obj, Att> Multiple = new EnumMap<>(Obj.class); static {
     390        Multiple.put(Obj.UNKOBJ, Att.MLTYLT); }
     391
     392    private static final EnumMap<Obj, Att> Name = new EnumMap<>(Obj.class); static {
     393        Name.put(Obj.UNKOBJ, Att.OBJNAM); }
     394
     395    private static final EnumMap<Obj, Att> National_information = new EnumMap<>(Obj.class); static {
     396        National_information.put(Obj.UNKOBJ, Att.NINFOM); }
     397
     398    private static final EnumMap<Obj, Att> Nationality = new EnumMap<>(Obj.class); static {
     399        Nationality.put(Obj.UNKOBJ, Att.NATION); }
     400
     401    private static final EnumMap<Obj, Att> National_description = new EnumMap<>(Obj.class); static {
     402        National_description.put(Obj.UNKOBJ, Att.NTXTDS); }
     403
     404    private static final EnumMap<Obj, Att> National_name = new EnumMap<>(Obj.class); static {
     405        National_name.put(Obj.UNKOBJ, Att.NOBJNM); }
     406
     407    private static final EnumMap<Obj, Att> National_pilot_district = new EnumMap<>(Obj.class); static {
     408        National_pilot_district.put(Obj.UNKOBJ, Att.NPLDST); }
     409
     410    private static final EnumMap<Obj, Att> Nm_date = new EnumMap<>(Obj.class); static {
     411        Nm_date.put(Obj.UNKOBJ, Att.NMDATE); }
     412
     413    private static final EnumMap<Obj, Att> Other_velocity = new EnumMap<>(Obj.class); static {
     414        Other_velocity.put(Obj.UNKOBJ, Att.CURVOW); }
     415
     416    private static final EnumMap<Obj, Att> Operation = new EnumMap<>(Obj.class); static {
     417        Operation.put(Obj.UNKOBJ, Att.CATTAB); }
     418
     419    private static final EnumMap<Obj, Att> Orientation = new EnumMap<>(Obj.class); static {
     420        Orientation.put(Obj.UNKOBJ, Att.ORIENT); }
     421
     422    private static final EnumMap<Obj, Att> Passing_time = new EnumMap<>(Obj.class); static {
     423        Passing_time.put(Obj.UNKOBJ, Att.APTREF); }
     424
     425    private static final EnumMap<Obj, Att> Period = new EnumMap<>(Obj.class); static {
     426        Period.put(Obj.UNKOBJ, Att.SIGPER); }
     427
     428    private static final EnumMap<Obj, Att> Period_end = new EnumMap<>(Obj.class); static {
     429        Period_end.put(Obj.UNKOBJ, Att.PEREND); }
     430
     431    private static final EnumMap<Obj, Att> Period_start = new EnumMap<>(Obj.class); static {
     432        Period_start.put(Obj.UNKOBJ, Att.PERSTA); }
     433
     434    private static final EnumMap<Obj, Att> Pilot_district = new EnumMap<>(Obj.class); static {
     435        Pilot_district.put(Obj.UNKOBJ, Att.PILDST); }
     436
     437    private static final EnumMap<Obj, Att> Position_quality = new EnumMap<>(Obj.class); static {
     438        Position_quality.put(Obj.UNKOBJ, Att.QUAPOS); }
     439
     440    private static final EnumMap<Obj, Att> Positional_accuracy = new EnumMap<>(Obj.class); static {
     441        Positional_accuracy.put(Obj.UNKOBJ, Att.POSACC); }
     442
     443    private static final EnumMap<Obj, Att> Producing_country = new EnumMap<>(Obj.class); static {
     444        Producing_country.put(Obj.UNKOBJ, Att.PRCTRY); }
     445
     446    private static final EnumMap<Obj, Att> Product = new EnumMap<>(Obj.class); static {
     447        Product.put(Obj.UNKOBJ, Att.PRODCT); }
     448
     449    private static final EnumMap<Obj, Att> Quality = new EnumMap<>(Obj.class); static {
     450        Quality.put(Obj.UNKOBJ, Att.QUASOU); }
     451
     452    private static final EnumMap<Obj, Att> Radius = new EnumMap<>(Obj.class); static {
     453        Radius.put(Obj.UNKOBJ, Att.RADIUS); Radius.put(Obj.LIGHTS, Att.LITRAD); }
     454
     455    private static final EnumMap<Obj, Att> Range = new EnumMap<>(Obj.class); static {
     456        Range.put(Obj.UNKOBJ, Att.VALNMR); }
     457
     458    private static final EnumMap<Obj, Att> Reference = new EnumMap<>(Obj.class); static {
     459        Reference.put(Obj.UNKOBJ, Att.PUBREF); }
     460
     461    private static final EnumMap<Obj, Att> Reflectivity = new EnumMap<>(Obj.class); static {
     462        Reflectivity.put(Obj.UNKOBJ, Att.CONRAD); }
     463
     464    private static final EnumMap<Obj, Att> Restriction = new EnumMap<>(Obj.class); static {
     465        Restriction.put(Obj.UNKOBJ, Att.RESTRN); }
     466
     467    private static final EnumMap<Obj, Att> Schedule = new EnumMap<>(Obj.class); static {
     468        Schedule.put(Obj.UNKOBJ, Att.SCHREF); }
     469
     470    private static final EnumMap<Obj, Att> Shape = new EnumMap<>(Obj.class); static {
     471        Shape.put(Obj.BCNCAR, Att.BCNSHP); Shape.put(Obj.BCNISD, Att.BCNSHP);
     472        Shape.put(Obj.BCNLAT, Att.BCNSHP); Shape.put(Obj.BCNSAW, Att.BCNSHP); Shape.put(Obj.BCNSPP, Att.BCNSHP); Shape.put(Obj.BUISGL, Att.BUISHP);
     473        Shape.put(Obj.BOYCAR, Att.BOYSHP); Shape.put(Obj.BOYISD, Att.BOYSHP); Shape.put(Obj.BOYLAT, Att.BOYSHP); Shape.put(Obj.BOYSAW, Att.BOYSHP); Shape.put(Obj.BOYSPP, Att.BOYSHP);
     474        Shape.put(Obj.BOYINB, Att.BOYSHP); Shape.put(Obj.DAYMAR, Att.TOPSHP); Shape.put(Obj.TOPMAR, Att.TOPSHP); Shape.put(Obj.MORFAC, Att.BOYSHP);
     475        Shape.put(Obj.SILTNK, Att.BUISHP);
     476    }
     477
     478    private static final EnumMap<Obj, Att> Sector_end = new EnumMap<>(Obj.class); static {
     479        Sector_end.put(Obj.UNKOBJ, Att.SECTR2); }
     480
     481    private static final EnumMap<Obj, Att> Sector_start = new EnumMap<>(Obj.class); static {
     482        Sector_start.put(Obj.UNKOBJ, Att.SECTR1); }
     483
     484    private static final EnumMap<Obj, Att> Sequence = new EnumMap<>(Obj.class); static {
     485        Sequence.put(Obj.UNKOBJ, Att.SIGSEQ); }
     486
     487    private static final EnumMap<Obj, Att> Shift = new EnumMap<>(Obj.class); static {
     488        Shift.put(Obj.UNKOBJ, Att.SHIPAM); }
     489
     490    private static final EnumMap<Obj, Att> Ship = new EnumMap<>(Obj.class); static {
     491        Ship.put(Obj.UNKOBJ, Att.SHPTYP); }
     492
     493    private static final EnumMap<Obj, Att> Sounding_accuracy = new EnumMap<>(Obj.class); static {
     494        Sounding_accuracy.put(Obj.UNKOBJ, Att.SOUACC); }
     495
     496    private static final EnumMap<Obj, Att> Sounding_name = new EnumMap<>(Obj.class); static {
     497        Sounding_name.put(Obj.UNKOBJ, Att.SDRLEV); }
     498
     499    private static final EnumMap<Obj, Att> Start_date = new EnumMap<>(Obj.class); static {
     500        Start_date.put(Obj.UNKOBJ, Att.DATSTA); }
     501
     502    private static final EnumMap<Obj, Att> Start_time = new EnumMap<>(Obj.class); static {
     503        Start_time.put(Obj.UNKOBJ, Att.TIMSTA); }
     504
     505    private static final EnumMap<Obj, Att> Status = new EnumMap<>(Obj.class); static {
     506        Status.put(Obj.UNKOBJ, Att.STATUS); }
     507
     508    private static final EnumMap<Obj, Att> Surface = new EnumMap<>(Obj.class); static {
     509        Surface.put(Obj.UNKOBJ, Att.NATSUR); }
     510
     511    private static final EnumMap<Obj, Att> Surface_qualification = new EnumMap<>(Obj.class); static {
     512        Surface_qualification.put(Obj.UNKOBJ, Att.NATQUA); }
     513
     514    private static final EnumMap<Obj, Att> Survey = new EnumMap<>(Obj.class); static {
     515        Survey.put(Obj.UNKOBJ, Att.SURTYP); }
     516
     517    private static final EnumMap<Obj, Att> Survey_end = new EnumMap<>(Obj.class); static {
     518        Survey_end.put(Obj.UNKOBJ, Att.SUREND); }
     519
     520    private static final EnumMap<Obj, Att> Survey_start = new EnumMap<>(Obj.class); static {
     521        Survey_start.put(Obj.UNKOBJ, Att.SURSTA); }
     522
     523    private static final EnumMap<Obj, Att> System = new EnumMap<>(Obj.class); static {
     524        System.put(Obj.UNKOBJ, Att.MARSYS); }
     525
     526    private static final EnumMap<Obj, Att> Technique = new EnumMap<>(Obj.class); static {
     527        Technique.put(Obj.UNKOBJ, Att.TECSOU); }
     528
     529    private static final EnumMap<Obj, Att> Traffic_flow = new EnumMap<>(Obj.class); static {
     530        Traffic_flow.put(Obj.UNKOBJ, Att.TRAFIC); }
     531
     532    private static final EnumMap<Obj, Att> Units = new EnumMap<>(Obj.class); static {
     533        Units.put(Obj.UNKOBJ, Att.HUNITS); }
     534
     535    private static final EnumMap<Obj, Att> Use = new EnumMap<>(Obj.class); static {
     536        Use.put(Obj.UNKOBJ, Att.USESHP); }
     537
     538    private static final EnumMap<Obj, Att> Variation = new EnumMap<>(Obj.class); static {
     539        Variation.put(Obj.UNKOBJ, Att.VALMAG); }
     540
     541    private static final EnumMap<Obj, Att> Variation_change = new EnumMap<>(Obj.class); static {
     542        Variation_change.put(Obj.UNKOBJ, Att.VALACM); }
     543
     544    private static final EnumMap<Obj, Att> Velocity = new EnumMap<>(Obj.class); static {
     545        Velocity.put(Obj.UNKOBJ, Att.CURVEL); }
     546
     547    private static final EnumMap<Obj, Att> Vertical_accuracy = new EnumMap<>(Obj.class); static {
     548        Vertical_accuracy.put(Obj.UNKOBJ, Att.VERACC); }
     549
     550    private static final EnumMap<Obj, Att> Vertical_datum = new EnumMap<>(Obj.class); static {
     551        Vertical_datum.put(Obj.UNKOBJ, Att.VERDAT); }
     552
     553    private static final EnumMap<Obj, Att> Vertical_length = new EnumMap<>(Obj.class); static {
     554        Vertical_length.put(Obj.UNKOBJ, Att.VERLEN); }
     555
     556    private static final EnumMap<Obj, Att> Vertical_name = new EnumMap<>(Obj.class); static {
     557        Vertical_name.put(Obj.UNKOBJ, Att.VCRLEV); }
     558
     559    private static final EnumMap<Obj, Att> Visibility = new EnumMap<>(Obj.class); static {
     560        Visibility.put(Obj.UNKOBJ, Att.LITVIS); }
     561
     562    private static final EnumMap<Obj, Att> Water_level = new EnumMap<>(Obj.class); static {
     563        Water_level.put(Obj.UNKOBJ, Att.WATLEV); }
     564
     565    private static final EnumMap<Obj, Att> Wavelength = new EnumMap<>(Obj.class); static {
     566        Wavelength.put(Obj.UNKOBJ, Att.RADWAL); }
     567
     568    private static final EnumMap<Obj, Att> Width = new EnumMap<>(Obj.class); static {
     569        Width.put(Obj.UNKOBJ, Att.HORWID); }
     570
     571    private static final EnumMap<Obj, Att> Year = new EnumMap<>(Obj.class); static {
     572        Year.put(Obj.UNKOBJ, Att.RYRMGV); }
     573
     574    private static final HashMap<String, EnumMap<Obj, Att>> StrAtt = new HashMap<>();
     575    static {
     576        StrAtt.put("accuracy", Accuracy); StrAtt.put("addition", Addition); StrAtt.put("agency", Agency); StrAtt.put("anomaly", Anomaly); StrAtt.put("authority", Authority);
     577        StrAtt.put("availability", Availability); StrAtt.put("bank", Bank); StrAtt.put("callsign", Callsign); StrAtt.put("category", Category); StrAtt.put("channel", Channel);
     578        StrAtt.put("character", Character); StrAtt.put("clearance_height", Clearance_height); StrAtt.put("clearance_height_closed", Clearance_height_closed);
     579        StrAtt.put("clearance_height_open", Clearance_height_open); StrAtt.put("clearance_height_safe", Clearance_height_safe); StrAtt.put("clearance_width", Clearance_width);
     580        StrAtt.put("colour", Colour); StrAtt.put("colour_pattern", Colour_pattern); StrAtt.put("communication", Communication); StrAtt.put("condition", Condition);
     581        StrAtt.put("conspicuity", Conspicuity); StrAtt.put("construction", Construction); StrAtt.put("danger_class", Danger_class); StrAtt.put("depth", Depth);
     582        StrAtt.put("depth_buried", Depth_buried); StrAtt.put("description", Description); StrAtt.put("distance", Distance); StrAtt.put("distance_down", Distance_down);
     583        StrAtt.put("distance_end", Distance_end); StrAtt.put("distance_start", Distance_start); StrAtt.put("distance_up", Distance_up); StrAtt.put("elevation", Elevation);
     584        StrAtt.put("end_date", End_date); StrAtt.put("end_time", End_time); StrAtt.put("estimated_range", Estimated_range); StrAtt.put("exhibition", Exhibition);
     585        StrAtt.put("exposition", Exposition); StrAtt.put("factor", Factor); StrAtt.put("frequency", Frequency); StrAtt.put("function", Function);
     586        StrAtt.put("generation", Generation); StrAtt.put("goods", Goods); StrAtt.put("gravity_reference", Gravity_reference); StrAtt.put("group", Group);
     587        StrAtt.put("height", Height); StrAtt.put("high_name", High_name); StrAtt.put("high_value", High_value); StrAtt.put("high_velocity", High_velocity);
     588        StrAtt.put("horizontal_clearance_length", Horizontal_clearance_length); StrAtt.put("horizontal_clearance_width", Horizontal_clearance_width);
     589        StrAtt.put("horizontal_datum", Horizontal_datum); StrAtt.put("impact", Impact); StrAtt.put("information", Information); StrAtt.put("jurisdiction", Jurisdiction);
     590        StrAtt.put("length", Length); StrAtt.put("local_name", Local_name); StrAtt.put("local_value", Local_value); StrAtt.put("low_name", Low_name);
     591        StrAtt.put("low_value", Low_value); StrAtt.put("low_velocity", Low_velocity); StrAtt.put("maximum_depth", Maximum_depth); StrAtt.put("maximum_elevation", Maximum_elevation);
     592        StrAtt.put("maximum_load", Maximum_load); StrAtt.put("maximum_range", Maximum_range); StrAtt.put("maximum_sounding", Maximum_sounding); StrAtt.put("mean_name", Mean_name);
     593        StrAtt.put("mean_value", Mean_value); StrAtt.put("mean_velocity", Mean_velocity); StrAtt.put("message", Message); StrAtt.put("minimum_depth", Minimum_depth);
     594        StrAtt.put("minimum_elevation", Minimum_elevation); StrAtt.put("minimum_sounding", Minimum_sounding); StrAtt.put("multiple", Multiple); StrAtt.put("name", Name);
     595        StrAtt.put("national_information", National_information); StrAtt.put("nationality", Nationality); StrAtt.put("national_description", National_description);
     596        StrAtt.put("national_name", National_name); StrAtt.put("national_pilot_district", National_pilot_district); StrAtt.put("nm_date", Nm_date); StrAtt.put("other_velocity", Other_velocity);
     597        StrAtt.put("operation", Operation); StrAtt.put("orientation", Orientation); StrAtt.put("passing_time", Passing_time); StrAtt.put("period", Period); StrAtt.put("period_end", Period_end);
     598        StrAtt.put("period_start", Period_start); StrAtt.put("pilot_district", Pilot_district); StrAtt.put("position_quality", Position_quality); StrAtt.put("positional_accuracy", Positional_accuracy);
     599        StrAtt.put("producing_country", Producing_country); StrAtt.put("product", Product); StrAtt.put("quality", Quality); StrAtt.put("radius", Radius); StrAtt.put("range", Range);
     600        StrAtt.put("reference", Reference); StrAtt.put("reflectivity", Reflectivity); StrAtt.put("restriction", Restriction); StrAtt.put("schedule", Schedule); StrAtt.put("shape", Shape);
     601        StrAtt.put("sector_end", Sector_end); StrAtt.put("sector_start", Sector_start); StrAtt.put("sequence", Sequence); StrAtt.put("shift", Shift); StrAtt.put("ship", Ship);
     602        StrAtt.put("sounding_accuracy", Sounding_accuracy); StrAtt.put("sounding_name", Sounding_name); StrAtt.put("start_date", Start_date); StrAtt.put("start_time", Start_time);
     603        StrAtt.put("status", Status); StrAtt.put("surface", Surface); StrAtt.put("surface_qualification", Surface_qualification); StrAtt.put("survey", Survey);
     604        StrAtt.put("survey_end", Survey_end); StrAtt.put("survey_start", Survey_start); StrAtt.put("system", System); StrAtt.put("technique", Technique); StrAtt.put("traffic_flow", Traffic_flow);
     605        StrAtt.put("units", Units); StrAtt.put("use", Use); StrAtt.put("variation", Variation); StrAtt.put("variation_change", Variation_change); StrAtt.put("velocity", Velocity);
     606        StrAtt.put("vertical_accuracy", Vertical_accuracy); StrAtt.put("vertical_datum", Vertical_datum); StrAtt.put("vertical_length", Vertical_length); StrAtt.put("vertical_name", Vertical_name);
     607        StrAtt.put("visibility", Visibility); StrAtt.put("water_level", Water_level); StrAtt.put("wavelength", Wavelength); StrAtt.put("width", Width); StrAtt.put("year", Year);
     608    }
     609
     610    public static Att decodeAttribute(long attl) { // Convert S57 attribute code to SCM attribute enumeration
     611        for (Att att : AttS57.keySet()) {
     612            if (AttS57.get(att) == attl) return att;
     613        }
     614        for (Att att : AttIENC.keySet()) {
     615            if (AttIENC.get(att) == attl) return att;
     616        }
     617        return Att.UNKATT;
     618    }
     619
     620    public static Integer encodeAttribute(String attribute) { // Convert SCM attribute enumeration to S57 attribute code
     621        if (AttS57.containsKey(attribute))
     622            return AttS57.get(attribute);
     623        else if (AttIENC.containsKey(attribute))
     624            return AttIENC.get(attribute);
     625        return 0;
     626    }
     627
     628    public static Integer encodeAttribute(Att attribute) { // Convert SCM attribute enumeration to S57 attribute code
     629        return AttS57.get(attribute) != 0 ? AttS57.get(attribute) : AttIENC.get(attribute);
     630    }
     631
     632    public static String stringAttribute(Att attribute) { // Convert SCM enumeration to OSM attribute string
     633        String str = AttStr.get(attribute);
     634        return str != null ? str : "";
     635    }
     636
     637    public static Att enumAttribute(String attribute, Obj obj) { // Convert OSM attribute string to SCM enumeration
     638        if ((attribute != null) && !attribute.isEmpty()) {
     639            EnumMap<Obj, Att> map = StrAtt.get(attribute);
     640            if (map != null) {
     641                if (map.containsKey(obj)) {
     642                    return map.get(obj);
     643                } else if (map.containsKey(Obj.UNKOBJ)) {
     644                    return map.get(Obj.UNKOBJ);
     645                } else {
     646                    return Att.UNKATT;
     647                }
     648            }
     649        }
     650        return Att.UNKATT;
     651    }
    388652}
  • applications/editors/josm/plugins/seachart/src/s57/S57box.java

    r32082 r32394  
    1212import java.util.ArrayList;
    1313
    14 import s57.S57map.*;
    15 import s57.S57obj.*;
     14import s57.S57map.Edge;
     15import s57.S57map.Feature;
     16import s57.S57map.Pflag;
     17import s57.S57map.Rflag;
     18import s57.S57map.Snode;
     19import s57.S57obj.Obj;
    1620
    1721public class S57box { //S57 bounding box truncation
    18        
    19         enum Ext {I, N, W, S, E }
    20        
    21         static Ext getExt(S57map map, double lat, double lon) {
    22                 if ((lat >= map.bounds.maxlat) && (lon < map.bounds.maxlon)) {
    23                         return Ext.N;
    24                 } else if (lon <= map.bounds.minlon) {
    25                         return Ext.W;
    26                 } else if (lat <= map.bounds.minlat) {
    27                         return Ext.S;
    28                 } else if (lon >= map.bounds.maxlon) {
    29                         return Ext.E;
    30                 }               return Ext.I;
    31         }
    32        
    33         public static void bBox(S57map map) {
    34                 /* Truncations
    35                  * Points: delete point features outside BB
    36                  * Lines: Truncate edges at BB boundaries
    37                  * Areas: Truncate edges of outers & inners and add new border edges. Merge inners to outer where necessary
    38                  * Remove nodes outside BB
    39                  * Remove edges that are completely outside BB
    40                  */
    41                 class Land {
    42                         long first;
    43                         Snode start;
    44                         Ext sbound;
    45                         long last;
    46                         Snode end;
    47                         Ext ebound;
    48                         Feature land;
     22    // CHECKSTYLE.OFF: LineLength
    4923
    50                         Land(Feature l) {
    51                                 land = l;
    52                                 first = last = 0;
    53                                 start = end = null;
    54                                 sbound = ebound = Ext.I;
    55                         }
    56                 }
    57                 if (map.features.get(Obj.COALNE) != null) {
    58                         ArrayList<Feature> coasts = new ArrayList<>();
    59                         ArrayList<Land> lands = new ArrayList<>();
    60                         if (map.features.get(Obj.LNDARE) == null) {
    61                                 map.features.put(Obj.LNDARE, new ArrayList<Feature>());
    62                         }
    63                         for (Feature feature : map.features.get(Obj.COALNE)) {
    64                                 Feature land = map.new Feature();
    65                                 land.id = ++map.xref;
    66                                 land.type = Obj.LNDARE;
    67                                 land.reln = Rflag.MASTER;
    68                                 land.objs.put(Obj.LNDARE, map.new ObjTab());
    69                                 land.objs.get(Obj.LNDARE).put(0, map.new AttMap());
    70                                 if (feature.geom.prim == Pflag.AREA) {
    71                                         land.geom = feature.geom;
    72                                         map.features.get(Obj.LNDARE).add(land);
    73                                 } else if (feature.geom.prim == Pflag.LINE) {
    74                                         land.geom.prim = Pflag.LINE;
    75                                         land.geom.elems.addAll(feature.geom.elems);
    76                                         coasts.add(land);
    77                                 }
    78                         }
    79                         while (coasts.size() > 0) {
    80                                 Feature land = coasts.remove(0);
    81                                 Edge fedge = map.edges.get(land.geom.elems.get(0).id);
    82                                 long first = fedge.first;
    83                                 long last = map.edges.get(land.geom.elems.get(land.geom.elems.size() - 1).id).last;
    84                                 if (coasts.size() > 0) {
    85                                         boolean added = true;
    86                                         while (added) {
    87                                                 added = false;
    88                                                 for (int i = 0; i < coasts.size(); i++) {
    89                                                         Feature coast = coasts.get(i);
    90                                                         Edge edge = map.edges.get(coast.geom.elems.get(0).id);
    91                                                         if (edge.first == last) {
    92                                                                 land.geom.elems.add(coast.geom.elems.get(0));
    93                                                                 last = edge.last;
    94                                                                 coasts.remove(i--);
    95                                                                 added = true;
    96                                                         } else if (edge.last == first) {
    97                                                                 land.geom.elems.add(0, coast.geom.elems.get(0));
    98                                                                 first = edge.first;
    99                                                                 coasts.remove(i--);
    100                                                                 added = true;
    101                                                         }
    102                                                 }
    103                                         }
    104                                 }
    105                                 lands.add(new Land(land));
    106                         }
    107                         ArrayList<Land> islands = new ArrayList<>();
    108                         for (Land land : lands) {
    109                                 map.sortGeom(land.land);
    110                                 if (land.land.geom.prim == Pflag.AREA) {
    111                                         islands.add(land);
    112                                         map.features.get(Obj.LNDARE).add(land.land);
    113                                 }
    114                         }
    115                         for (Land island : islands) {
    116                                 lands.remove(island);
    117                         }
    118                         for (Land land : lands) {
    119                                 land.first = map.edges.get(land.land.geom.elems.get(0).id).first;
    120                                 land.start = map.nodes.get(land.first);
    121                                 land.sbound = getExt(map, land.start.lat, land.start.lon);
    122                                 land.last = map.edges.get(land.land.geom.elems.get(land.land.geom.comps.get(0).size - 1).id).last;
    123                                 land.end = map.nodes.get(land.last);
    124                                 land.ebound = getExt(map, land.end.lat, land.end.lon);
    125                         }
    126                         islands = new ArrayList<>();
    127                         for (Land land : lands) {
    128                                 if ((land.sbound == Ext.I) || (land.ebound == Ext.I)) {
    129                                         islands.add(land);
    130                                 }
    131                         }
    132                         for (Land island : islands) {
    133                                 lands.remove(island);
    134                         }
    135                         for (Land land : lands) {
    136                                 Edge nedge = map.new Edge();
    137                                 nedge.first = land.last;
    138                                 nedge.last = land.first;
    139                                 Ext bound = land.ebound;
    140                                 while (bound != land.sbound) {
    141                                         switch (bound) {
    142                                         case N:
    143                                                 nedge.nodes.add(1l);
    144                                                 bound = Ext.W;
    145                                                 break;
    146                                         case W:
    147                                                 nedge.nodes.add(2l);
    148                                                 bound = Ext.S;
    149                                                 break;
    150                                         case S:
    151                                                 nedge.nodes.add(3l);
    152                                                 bound = Ext.E;
    153                                                 break;
    154                                         case E:
    155                                                 nedge.nodes.add(4l);
    156                                                 bound = Ext.N;
    157                                                 break;
    158                                         default:
    159                                                 continue;
    160                                         }
    161                                 }
    162                                 map.edges.put(++map.xref, nedge);
    163                                 land.land.geom.elems.add(map.new Prim(map.xref));
    164                                 land.land.geom.comps.get(0).size++;
    165                                 land.land.geom.prim = Pflag.AREA;
    166                                 map.features.get(Obj.LNDARE).add(land.land);
    167                         }
    168                 }
    169                 return;
     24    enum Ext { I, N, W, S, E }
    17025
    171         }
     26    static Ext getExt(S57map map, double lat, double lon) {
     27        if ((lat >= map.bounds.maxlat) && (lon < map.bounds.maxlon)) {
     28            return Ext.N;
     29        } else if (lon <= map.bounds.minlon) {
     30            return Ext.W;
     31        } else if (lat <= map.bounds.minlat) {
     32            return Ext.S;
     33        } else if (lon >= map.bounds.maxlon) {
     34            return Ext.E;
     35        }
     36        return Ext.I;
     37    }
     38
     39    public static void bBox(S57map map) {
     40        /* Truncations
     41         * Points: delete point features outside BB
     42         * Lines: Truncate edges at BB boundaries
     43         * Areas: Truncate edges of outers & inners and add new border edges. Merge inners to outer where necessary
     44         * Remove nodes outside BB
     45         * Remove edges that are completely outside BB
     46         */
     47        class Land {
     48            long first;
     49            Snode start;
     50            Ext sbound;
     51            long last;
     52            Snode end;
     53            Ext ebound;
     54            Feature land;
     55
     56            Land(Feature l) {
     57                land = l;
     58                first = last = 0;
     59                start = end = null;
     60                sbound = ebound = Ext.I;
     61            }
     62        }
     63
     64        if (map.features.get(Obj.COALNE) != null) {
     65            ArrayList<Feature> coasts = new ArrayList<>();
     66            ArrayList<Land> lands = new ArrayList<>();
     67            if (map.features.get(Obj.LNDARE) == null) {
     68                map.features.put(Obj.LNDARE, new ArrayList<Feature>());
     69            }
     70            for (Feature feature : map.features.get(Obj.COALNE)) {
     71                Feature land = map.new Feature();
     72                land.id = ++map.xref;
     73                land.type = Obj.LNDARE;
     74                land.reln = Rflag.MASTER;
     75                land.objs.put(Obj.LNDARE, map.new ObjTab());
     76                land.objs.get(Obj.LNDARE).put(0, map.new AttMap());
     77                if (feature.geom.prim == Pflag.AREA) {
     78                    land.geom = feature.geom;
     79                    map.features.get(Obj.LNDARE).add(land);
     80                } else if (feature.geom.prim == Pflag.LINE) {
     81                    land.geom.prim = Pflag.LINE;
     82                    land.geom.elems.addAll(feature.geom.elems);
     83                    coasts.add(land);
     84                }
     85            }
     86            while (coasts.size() > 0) {
     87                Feature land = coasts.remove(0);
     88                Edge fedge = map.edges.get(land.geom.elems.get(0).id);
     89                long first = fedge.first;
     90                long last = map.edges.get(land.geom.elems.get(land.geom.elems.size() - 1).id).last;
     91                if (coasts.size() > 0) {
     92                    boolean added = true;
     93                    while (added) {
     94                        added = false;
     95                        for (int i = 0; i < coasts.size(); i++) {
     96                            Feature coast = coasts.get(i);
     97                            Edge edge = map.edges.get(coast.geom.elems.get(0).id);
     98                            if (edge.first == last) {
     99                                land.geom.elems.add(coast.geom.elems.get(0));
     100                                last = edge.last;
     101                                coasts.remove(i--);
     102                                added = true;
     103                            } else if (edge.last == first) {
     104                                land.geom.elems.add(0, coast.geom.elems.get(0));
     105                                first = edge.first;
     106                                coasts.remove(i--);
     107                                added = true;
     108                            }
     109                        }
     110                    }
     111                }
     112                lands.add(new Land(land));
     113            }
     114            ArrayList<Land> islands = new ArrayList<>();
     115            for (Land land : lands) {
     116                map.sortGeom(land.land);
     117                if (land.land.geom.prim == Pflag.AREA) {
     118                    islands.add(land);
     119                    map.features.get(Obj.LNDARE).add(land.land);
     120                }
     121            }
     122            for (Land island : islands) {
     123                lands.remove(island);
     124            }
     125            for (Land land : lands) {
     126                land.first = map.edges.get(land.land.geom.elems.get(0).id).first;
     127                land.start = map.nodes.get(land.first);
     128                land.sbound = getExt(map, land.start.lat, land.start.lon);
     129                land.last = map.edges.get(land.land.geom.elems.get(land.land.geom.comps.get(0).size - 1).id).last;
     130                land.end = map.nodes.get(land.last);
     131                land.ebound = getExt(map, land.end.lat, land.end.lon);
     132            }
     133            islands = new ArrayList<>();
     134            for (Land land : lands) {
     135                if ((land.sbound == Ext.I) || (land.ebound == Ext.I)) {
     136                    islands.add(land);
     137                }
     138            }
     139            for (Land island : islands) {
     140                lands.remove(island);
     141            }
     142            for (Land land : lands) {
     143                Edge nedge = map.new Edge();
     144                nedge.first = land.last;
     145                nedge.last = land.first;
     146                Ext bound = land.ebound;
     147                while (bound != land.sbound) {
     148                    switch (bound) {
     149                    case N:
     150                        nedge.nodes.add(1L);
     151                        bound = Ext.W;
     152                        break;
     153                    case W:
     154                        nedge.nodes.add(2L);
     155                        bound = Ext.S;
     156                        break;
     157                    case S:
     158                        nedge.nodes.add(3L);
     159                        bound = Ext.E;
     160                        break;
     161                    case E:
     162                        nedge.nodes.add(4L);
     163                        bound = Ext.N;
     164                        break;
     165                    default:
     166                        continue;
     167                    }
     168                }
     169                map.edges.put(++map.xref, nedge);
     170                land.land.geom.elems.add(map.new Prim(map.xref));
     171                land.land.geom.comps.get(0).size++;
     172                land.land.geom.prim = Pflag.AREA;
     173                map.features.get(Obj.LNDARE).add(land.land);
     174            }
     175        }
     176        return;
     177
     178    }
    172179
    173180}
  • applications/editors/josm/plugins/seachart/src/s57/S57dat.java

    r32380 r32394  
    1111
    1212import java.io.UnsupportedEncodingException;
    13 import java.util.*;
    14 
    15 import s57.S57map.*;
    16 import s57.S57obj.*;
     13import java.util.ArrayList;
     14import java.util.Arrays;
     15import java.util.EnumMap;
     16
     17import s57.S57map.Feature;
     18import s57.S57map.Pflag;
     19import s57.S57obj.Obj;
    1720
    1821public class S57dat { // S57 ENC file fields lookup tables & methods
    19        
    20         public static class S57conv {
    21                 int asc;        // 0=A(), 1+=A(n)
    22                 int bin;        // 0=ASCII, +ve=b1n(unsigned LE), -ve=b2n(signed LE), n>8=b1(n/8)(unsigned BE)
    23                 S57conv(int a, int b) {
    24                         asc = a; bin = b;
    25                 }
    26         }
    27        
    28         public enum S57subf { I8RN, RCNM, RCID, EXPP, INTU, DSNM, EDTN, UPDN, UADT, ISDT, STED, PRSP, PSDN, PRED, PROF, AGEN, COMT, DSTR, AALL, NALL, NOMR, NOCR, NOGR, NOLR, NOIN, NOCN,
    29                 NOED, NOFA, HDAT, VDAT, SDAT, CSCL, DUNI, HUNI, PUNI, COUN, COMF, SOMF, PROJ, PRP1, PRP2, PRP3, PRP4, FEAS, FNOR, FPMF, RPID, RYCO, RXCO, CURP, RXVL, RYVL, PRCO, ESDT,
    30                 LSDT, DCRT, CODT, PACC, HACC, SACC, FILE, LFIL, VOLM, IMPL, SLAT, WLON, NLAT, ELON, CRCS, NAM1, NAM2, OORA, OAAC, OACO, OALL, OATY, DEFN, AUTH, RFTP, RFVL, ATLB, ATDO,
    31                 ADMU, ADFT, RAVA, DVAL, DVSD, OBLB, ASET, PRIM, GRUP, OBJL, RVER, RUIN, FIDN, FIDS, ATTL, ATVL, FFUI, FFIX, NFPT, LNAM, RIND, FSUI, FSIX, NSPT, NAME, ORNT, USAG, MASK,
    32                 VPUI, VPIX, NVPT, TOPI, CCUI, CCIX, CCNC, YCOO, XCOO, VE3D, ATYP, SURF, ORDR, RESO, STPT, CTPT, ENPT, CDPM, CDPR }
    33 
    34         private static final EnumMap<S57subf, S57conv> convs = new EnumMap<>(S57subf.class);
    35         static {
    36                 convs.put(S57subf.I8RN, new S57conv(5,2));
    37                 convs.put(S57subf.RCNM, new S57conv(2,1)); convs.put(S57subf.RCID, new S57conv(10,4)); convs.put(S57subf.EXPP, new S57conv(1,1));
    38                 convs.put(S57subf.INTU, new S57conv(1,1)); convs.put(S57subf.DSNM, new S57conv(0,0)); convs.put(S57subf.EDTN, new S57conv(0,0));
    39                 convs.put(S57subf.UPDN, new S57conv(0,0)); convs.put(S57subf.UADT, new S57conv(8,0)); convs.put(S57subf.ISDT, new S57conv(8,0));
    40                 convs.put(S57subf.STED, new S57conv(4,0)); convs.put(S57subf.PRSP, new S57conv(3,1)); convs.put(S57subf.PSDN, new S57conv(0,0));
    41                 convs.put(S57subf.PRED, new S57conv(0,0)); convs.put(S57subf.PROF, new S57conv(2,1)); convs.put(S57subf.AGEN, new S57conv(2,2));
    42                 convs.put(S57subf.COMT, new S57conv(0,0)); convs.put(S57subf.DSTR, new S57conv(2,1)); convs.put(S57subf.AALL, new S57conv(1,1));
    43                 convs.put(S57subf.NALL, new S57conv(1,1)); convs.put(S57subf.NOMR, new S57conv(0,4)); convs.put(S57subf.NOCR, new S57conv(0,4));
    44                 convs.put(S57subf.NOGR, new S57conv(0,4)); convs.put(S57subf.NOLR, new S57conv(0,4)); convs.put(S57subf.NOIN, new S57conv(0,4));
    45                 convs.put(S57subf.NOCN, new S57conv(0,4)); convs.put(S57subf.NOED, new S57conv(0,4)); convs.put(S57subf.NOFA, new S57conv(0,4));
    46                 convs.put(S57subf.HDAT, new S57conv(3,1)); convs.put(S57subf.VDAT, new S57conv(2,1)); convs.put(S57subf.SDAT, new S57conv(2,1));
    47                 convs.put(S57subf.CSCL, new S57conv(0,4)); convs.put(S57subf.DUNI, new S57conv(2,1)); convs.put(S57subf.HUNI, new S57conv(2,1));
    48                 convs.put(S57subf.PUNI, new S57conv(2,1)); convs.put(S57subf.COUN, new S57conv(2,1)); convs.put(S57subf.COMF, new S57conv(0,4));
    49                 convs.put(S57subf.SOMF, new S57conv(0,4)); convs.put(S57subf.PROJ, new S57conv(3,1)); convs.put(S57subf.PRP1, new S57conv(0,-4));
    50                 convs.put(S57subf.PRP2, new S57conv(0,-4)); convs.put(S57subf.PRP3, new S57conv(0,-4)); convs.put(S57subf.PRP4, new S57conv(0,-4));
    51                 convs.put(S57subf.FEAS, new S57conv(0,-4)); convs.put(S57subf.FNOR, new S57conv(0,-4)); convs.put(S57subf.FPMF, new S57conv(0,4));
    52                 convs.put(S57subf.RPID, new S57conv(1,1)); convs.put(S57subf.RYCO, new S57conv(0,-4)); convs.put(S57subf.RXCO, new S57conv(0,-4));
    53                 convs.put(S57subf.CURP, new S57conv(2,1)); convs.put(S57subf.RXVL, new S57conv(0,-4)); convs.put(S57subf.RYVL, new S57conv(0,-4));
    54                 convs.put(S57subf.PRCO, new S57conv(2,2)); convs.put(S57subf.ESDT, new S57conv(8,0)); convs.put(S57subf.LSDT, new S57conv(8,0));
    55                 convs.put(S57subf.DCRT, new S57conv(0,0)); convs.put(S57subf.CODT, new S57conv(8,0)); convs.put(S57subf.PACC, new S57conv(0,4));
    56                 convs.put(S57subf.HACC, new S57conv(0,4)); convs.put(S57subf.SACC, new S57conv(0,4)); convs.put(S57subf.FILE, new S57conv(0,0));
    57                 convs.put(S57subf.LFIL, new S57conv(0,0)); convs.put(S57subf.VOLM, new S57conv(0,0)); convs.put(S57subf.IMPL, new S57conv(3,0));
    58                 convs.put(S57subf.SLAT, new S57conv(0,0)); convs.put(S57subf.WLON, new S57conv(0,0)); convs.put(S57subf.NLAT, new S57conv(0,0));
    59                 convs.put(S57subf.ELON, new S57conv(0,0)); convs.put(S57subf.CRCS, new S57conv(0,0)); convs.put(S57subf.NAM1, new S57conv(12,5));
    60                 convs.put(S57subf.NAM2, new S57conv(12,5)); convs.put(S57subf.OORA, new S57conv(1,1)); convs.put(S57subf.OAAC, new S57conv(6,0));
    61                 convs.put(S57subf.OACO, new S57conv(5,2)); convs.put(S57subf.OALL, new S57conv(0,0)); convs.put(S57subf.OATY, new S57conv(1,1));
    62                 convs.put(S57subf.DEFN, new S57conv(0,0)); convs.put(S57subf.AUTH, new S57conv(2,2)); convs.put(S57subf.RFTP, new S57conv(2,1));
    63                 convs.put(S57subf.RFVL, new S57conv(0,0)); convs.put(S57subf.ATLB, new S57conv(5,2)); convs.put(S57subf.ATDO, new S57conv(1,1));
    64                 convs.put(S57subf.ADMU, new S57conv(0,0)); convs.put(S57subf.ADFT, new S57conv(0,0)); convs.put(S57subf.RAVA, new S57conv(1,1));
    65                 convs.put(S57subf.DVAL, new S57conv(0,0)); convs.put(S57subf.DVSD, new S57conv(0,0)); convs.put(S57subf.OBLB, new S57conv(5,2));
    66                 convs.put(S57subf.ASET, new S57conv(1,1)); convs.put(S57subf.PRIM, new S57conv(1,1)); convs.put(S57subf.GRUP, new S57conv(3,1));
    67                 convs.put(S57subf.OBJL, new S57conv(5,2)); convs.put(S57subf.RVER, new S57conv(3,2)); convs.put(S57subf.RUIN, new S57conv(1,1));
    68                 convs.put(S57subf.FIDN, new S57conv(10,4)); convs.put(S57subf.FIDS, new S57conv(5,2)); convs.put(S57subf.ATTL, new S57conv(5,2));
    69                 convs.put(S57subf.ATVL, new S57conv(0,0)); convs.put(S57subf.FFUI, new S57conv(1,1)); convs.put(S57subf.FFIX, new S57conv(0,2));
    70                 convs.put(S57subf.NFPT, new S57conv(0,2)); convs.put(S57subf.LNAM, new S57conv(17,8)); convs.put(S57subf.RIND, new S57conv(0,1));
    71                 convs.put(S57subf.FSUI, new S57conv(1,1)); convs.put(S57subf.FSIX, new S57conv(0,2)); convs.put(S57subf.NSPT, new S57conv(0,2));
    72                 convs.put(S57subf.NAME, new S57conv(12,5)); convs.put(S57subf.ORNT, new S57conv(1,1)); convs.put(S57subf.USAG, new S57conv(1,1));
    73                 convs.put(S57subf.MASK, new S57conv(1,1)); convs.put(S57subf.VPUI, new S57conv(1,1)); convs.put(S57subf.VPIX, new S57conv(0,2));
    74                 convs.put(S57subf.NVPT, new S57conv(0,2)); convs.put(S57subf.TOPI, new S57conv(1,1)); convs.put(S57subf.CCUI, new S57conv(1,1));
    75                 convs.put(S57subf.CCIX, new S57conv(0,2)); convs.put(S57subf.CCNC, new S57conv(0,2)); convs.put(S57subf.YCOO, new S57conv(0,-4));
    76                 convs.put(S57subf.XCOO, new S57conv(0,-4)); convs.put(S57subf.VE3D, new S57conv(0,-4)); convs.put(S57subf.ATYP, new S57conv(1,1));
    77                 convs.put(S57subf.SURF, new S57conv(1,1)); convs.put(S57subf.ORDR, new S57conv(1,1)); convs.put(S57subf.RESO, new S57conv(0,4));
    78                 convs.put(S57subf.STPT, new S57conv(0,0)); convs.put(S57subf.CTPT, new S57conv(0,0)); convs.put(S57subf.ENPT, new S57conv(0,0));
    79                 convs.put(S57subf.CDPM, new S57conv(0,0)); convs.put(S57subf.CDPR, new S57conv(0,0));
    80         }
    81        
    82         public enum S57field { I8RI, DSID, DSSI, DSPM, DSPR, DSRC, DSHT, DSAC, CATD, CATX, DDDF, DDDR, DDDI, DDOM, DDRF, DDSI, DDSC,
    83                 FRID, FOID, LNAM, ATTF, NATF, FFPC, FFPT, FSPC, FSPT, VRID, ATTV, VRPC, VRPT, SGCC, SG2D, SG3D, ARCC, AR2D, EL2D, CT2D }
    84        
    85         private static ArrayList<S57subf> S57i8ri = new ArrayList<>(Arrays.asList(S57subf.I8RN));
    86         private static ArrayList<S57subf> S57dsid = new ArrayList<>(Arrays.asList(S57subf.RCNM, S57subf.RCID, S57subf.EXPP, S57subf.INTU, S57subf.DSNM, S57subf.EDTN, S57subf.UPDN,
    87                         S57subf.UADT, S57subf.ISDT, S57subf.STED, S57subf.PRSP, S57subf.PSDN, S57subf.PRED, S57subf.PROF, S57subf.AGEN, S57subf.COMT));
    88         private static ArrayList<S57subf> S57dssi = new ArrayList<>(Arrays.asList(S57subf.DSTR, S57subf.AALL, S57subf.NALL, S57subf.NOMR, S57subf.NOCR, S57subf.NOGR, S57subf.NOLR,
    89                         S57subf.NOIN, S57subf.NOCN, S57subf.NOED, S57subf.NOFA ));
    90         private static ArrayList<S57subf> S57dspm = new ArrayList<>(Arrays.asList(S57subf.RCNM, S57subf.RCID, S57subf.HDAT, S57subf.VDAT, S57subf.SDAT, S57subf.CSCL, S57subf.DUNI,
    91                         S57subf.HUNI, S57subf.PUNI, S57subf.COUN, S57subf.COMF, S57subf.SOMF, S57subf.COMT ));
    92         private static ArrayList<S57subf> S57dspr = new ArrayList<>(Arrays.asList(S57subf.PROJ, S57subf.PRP1, S57subf.PRP2, S57subf.PRP3, S57subf.PRP4, S57subf.FEAS, S57subf.FNOR,
    93                         S57subf.FPMF, S57subf.COMT ));
    94         private static ArrayList<S57subf> S57dsrc = new ArrayList<>(Arrays.asList(S57subf.RPID, S57subf.RYCO, S57subf.RXCO, S57subf.CURP, S57subf.FPMF, S57subf.RXVL, S57subf.RYVL,
    95                         S57subf.COMT ));
    96         private static ArrayList<S57subf> S57dsht = new ArrayList<>(Arrays.asList(S57subf.RCNM, S57subf.RCID, S57subf.PRCO, S57subf.ESDT, S57subf.LSDT, S57subf.DCRT, S57subf.CODT, S57subf.COMT ));
    97         private static ArrayList<S57subf> S57dsac = new ArrayList<>(Arrays.asList(S57subf.RCNM, S57subf.RCID, S57subf.PACC, S57subf.HACC, S57subf.SACC, S57subf.FPMF, S57subf.COMT ));
    98         private static ArrayList<S57subf> S57catd = new ArrayList<>(Arrays.asList(S57subf.RCNM, S57subf.RCID, S57subf.FILE, S57subf.LFIL, S57subf.VOLM, S57subf.IMPL, S57subf.SLAT,
    99                         S57subf.WLON, S57subf.NLAT, S57subf.ELON, S57subf.CRCS, S57subf.COMT ));
    100         private static ArrayList<S57subf> S57catx = new ArrayList<>(Arrays.asList(S57subf.RCNM, S57subf.RCID, S57subf.NAM1, S57subf.NAM2, S57subf.COMT ));
    101         private static ArrayList<S57subf> S57dddf = new ArrayList<>(Arrays.asList(S57subf.RCNM, S57subf.RCID, S57subf.OORA, S57subf.OAAC, S57subf.OACO, S57subf.OALL, S57subf.OATY,
    102                         S57subf.DEFN, S57subf.AUTH, S57subf.COMT ));
    103         private static ArrayList<S57subf> S57dddr = new ArrayList<>(Arrays.asList(S57subf.RFTP, S57subf.RFVL ));
    104         private static ArrayList<S57subf> S57dddi = new ArrayList<>(Arrays.asList(S57subf.RCNM, S57subf.RCID, S57subf.ATLB, S57subf.ATDO, S57subf.ADMU, S57subf.ADFT, S57subf.AUTH, S57subf.COMT ));
    105         private static ArrayList<S57subf> S57ddom = new ArrayList<>(Arrays.asList(S57subf.RAVA, S57subf.DVAL, S57subf.DVSD, S57subf.DEFN, S57subf.AUTH ));
    106         private static ArrayList<S57subf> S57ddrf = new ArrayList<>(Arrays.asList(S57subf.RFTP, S57subf.RFVL ));
    107         private static ArrayList<S57subf> S57ddsi = new ArrayList<>(Arrays.asList(S57subf.RCNM, S57subf.RCID, S57subf.OBLB ));
    108         private static ArrayList<S57subf> S57ddsc = new ArrayList<>(Arrays.asList(S57subf.ATLB, S57subf.ASET, S57subf.AUTH ));
    109         private static ArrayList<S57subf> S57frid = new ArrayList<>(Arrays.asList(S57subf.RCNM, S57subf.RCID, S57subf.PRIM, S57subf.GRUP, S57subf.OBJL, S57subf.RVER, S57subf.RUIN ));
    110         private static ArrayList<S57subf> S57foid = new ArrayList<>(Arrays.asList(S57subf.AGEN, S57subf.FIDN, S57subf.FIDS ));
    111         private static ArrayList<S57subf> S57lnam = new ArrayList<>(Arrays.asList(S57subf.LNAM));
    112         private static ArrayList<S57subf> S57attf = new ArrayList<>(Arrays.asList(S57subf.ATTL, S57subf.ATVL ));
    113         private static ArrayList<S57subf> S57natf = new ArrayList<>(Arrays.asList(S57subf.ATTL, S57subf.ATVL ));
    114         private static ArrayList<S57subf> S57ffpc = new ArrayList<>(Arrays.asList(S57subf.FFUI, S57subf.FFIX, S57subf.NFPT ));
    115         private static ArrayList<S57subf> S57ffpt = new ArrayList<>(Arrays.asList(S57subf.LNAM, S57subf.RIND, S57subf.COMT ));
    116         private static ArrayList<S57subf> S57fspc = new ArrayList<>(Arrays.asList(S57subf.FSUI, S57subf.FSIX, S57subf.NSPT ));
    117         private static ArrayList<S57subf> S57fspt = new ArrayList<>(Arrays.asList(S57subf.NAME, S57subf.ORNT, S57subf.USAG, S57subf.MASK ));
    118         private static ArrayList<S57subf> S57vrid = new ArrayList<>(Arrays.asList(S57subf.RCNM, S57subf.RCID, S57subf.RVER, S57subf.RUIN ));
    119         private static ArrayList<S57subf> S57attv = new ArrayList<>(Arrays.asList(S57subf.ATTL, S57subf.ATVL ));
    120         private static ArrayList<S57subf> S57vrpc = new ArrayList<>(Arrays.asList(S57subf.VPUI, S57subf.VPIX, S57subf.NVPT ));
    121         private static ArrayList<S57subf> S57vrpt = new ArrayList<>(Arrays.asList(S57subf.NAME, S57subf.ORNT, S57subf.USAG, S57subf.TOPI, S57subf.MASK ));
    122         private static ArrayList<S57subf> S57sgcc = new ArrayList<>(Arrays.asList(S57subf.CCUI, S57subf.CCIX, S57subf.CCNC ));
    123         private static ArrayList<S57subf> S57sg2d = new ArrayList<>(Arrays.asList(S57subf.YCOO, S57subf.XCOO ));
    124         private static ArrayList<S57subf> S57sg3d = new ArrayList<>(Arrays.asList(S57subf.YCOO, S57subf.XCOO, S57subf.VE3D ));
    125         private static ArrayList<S57subf> S57arcc = new ArrayList<>(Arrays.asList(S57subf.ATYP, S57subf.SURF, S57subf.ORDR, S57subf.RESO, S57subf.FPMF ));
    126         private static ArrayList<S57subf> S57ar2d = new ArrayList<>(Arrays.asList(S57subf.STPT, S57subf.CTPT, S57subf.ENPT, S57subf.YCOO, S57subf.XCOO ));
    127         private static ArrayList<S57subf> S57el2d = new ArrayList<>(Arrays.asList(S57subf.STPT, S57subf.CTPT, S57subf.ENPT, S57subf.CDPM, S57subf.CDPR, S57subf.YCOO, S57subf.XCOO ));
    128         private static ArrayList<S57subf> S57ct2d = new ArrayList<>(Arrays.asList(S57subf.YCOO, S57subf.XCOO ));
    129        
    130         private static final EnumMap<S57field, ArrayList<S57subf>> fields = new EnumMap<>(S57field.class);
    131         static {
    132                 fields.put(S57field.I8RI, S57i8ri);
    133                 fields.put(S57field.DSID, S57dsid); fields.put(S57field.DSSI, S57dssi); fields.put(S57field.DSPM, S57dspm); fields.put(S57field.DSPR, S57dspr);
    134                 fields.put(S57field.DSRC, S57dsrc); fields.put(S57field.DSHT, S57dsht); fields.put(S57field.DSAC, S57dsac); fields.put(S57field.CATD, S57catd);
    135                 fields.put(S57field.CATX, S57catx); fields.put(S57field.DDDF, S57dddf); fields.put(S57field.DDDR, S57dddr); fields.put(S57field.DDDI, S57dddi);
    136                 fields.put(S57field.DDOM, S57ddom); fields.put(S57field.DDRF, S57ddrf); fields.put(S57field.DDSI, S57ddsi); fields.put(S57field.DDSC, S57ddsc);
    137                 fields.put(S57field.FRID, S57frid); fields.put(S57field.FOID, S57foid); fields.put(S57field.LNAM, S57lnam); fields.put(S57field.ATTF, S57attf);
    138                 fields.put(S57field.NATF, S57natf); fields.put(S57field.FFPC, S57ffpc); fields.put(S57field.FFPT, S57ffpt); fields.put(S57field.FFPC, S57fspc);
    139                 fields.put(S57field.FSPT, S57fspt); fields.put(S57field.VRID, S57vrid); fields.put(S57field.ATTV, S57attv); fields.put(S57field.VRPC, S57vrpc);
    140                 fields.put(S57field.VRPT, S57vrpt); fields.put(S57field.SGCC, S57sgcc); fields.put(S57field.SG2D, S57sg2d); fields.put(S57field.SG3D, S57sg3d);
    141                 fields.put(S57field.ARCC, S57arcc); fields.put(S57field.AR2D, S57ar2d); fields.put(S57field.EL2D, S57el2d); fields.put(S57field.CT2D, S57ct2d);
    142         }
    143        
    144         private static byte[] leader = {'0', '0', '0', '0', '0', ' ', 'D', ' ', ' ', ' ', ' ', ' ', '0', '0', '0', '0', '0', ' ', ' ', ' ', '0', '0', '0', '4'};
    145         private static byte[] buffer;
    146         private static int offset;
    147         private static int maxoff;
    148         private static int index;
    149         private static S57field field;
    150         private static String aall = "US-ASCII";
    151         private static String nall = "US-ASCII";
    152         public static int rnum;
    153        
    154         private static S57conv findSubf(S57subf subf) {
    155                 ArrayList<S57subf> subs = fields.get(field);
    156                 boolean wrap = false;
    157                 while (true) {
    158                         if (index == subs.size()) {
    159                                 if (!wrap) {
    160                                         index = 0;
    161                                         wrap = true;
    162                                 } else {
    163                                         System.out.println("ERROR: Subfield not found " + subf.name() + " in " + field.name() + " in record " + rnum);
    164                                         System.exit(-1);
    165                                 }
    166                         }
    167                         S57subf sub = subs.get(index++);
    168                         S57conv conv = convs.get(sub);
    169                         if (sub == subf) {
    170                                 return conv;
    171                         } else {
    172                                 offset += (conv.bin != 0) ? ((conv.bin < 8) ? Math.abs(conv.bin) : conv.bin / 8) : conv.asc;
    173                         }
    174                 }
    175         }
    176        
    177         public static void setField(byte[] buf, int off, S57field fld, int len) {
    178                 buffer = buf;
    179                 offset = off;
    180                 maxoff = off + len - 1;
    181                 field = fld;
    182                 index = 0;
    183         }
    184        
    185         public static boolean more() {
    186                 return (offset < maxoff);
    187         }
    188        
    189         public static Object decSubf(byte[] buf, int off, S57field fld, S57subf subf) {
    190                 buffer = buf;
    191                 offset = off;
    192                 index = 0;
    193                 return decSubf(fld, subf);
    194         }
    195        
    196         public static Object decSubf(S57field fld, S57subf subf) {
    197                 field = fld;
    198                 index = 0;
    199                 return decSubf(subf);
    200         }
    201 
    202         public static Object decSubf(S57subf subf) {
    203                 S57conv conv = findSubf(subf);
    204                 if (conv.bin == 0) {
    205                         String str = "";
    206                         int i = 0;
    207                         if (conv.asc == 0) {
    208                                 for (i=0; buffer[offset+i] != 0x1f; i++) {}
    209                                 try {
    210                                         String charset = "";
    211                                         if (field == S57field.ATTF) charset = aall;
    212                                         else if (field == S57field.NATF) charset = nall;
    213                                         else charset = "US-ASCII";
    214                                         str = new String(buffer, offset, i, charset);
    215                                 } catch (UnsupportedEncodingException e) {
    216                                         e.printStackTrace();
    217                                 }
    218                                 offset += i + 1;
    219                         } else {
    220                                 str = new String(buffer, offset, conv.asc);
    221                                 offset += conv.asc;
    222                         }
    223                         return str;
    224                 } else {
    225                         int f = Math.abs(conv.bin);
    226                         if (f < 5) {
    227                                 long val = buffer[offset + --f];
    228                                 if (conv.bin > 0)
    229                                         val &= 0xff;
    230                                 while (f > 0) {
    231                                         val = (val << 8) + (buffer[offset + --f] & 0xff);
    232                                 }
    233                                 offset += Math.abs(conv.bin);
    234                                 if ((subf == S57subf.AALL) || (subf == S57subf.NALL)) {
    235                                         String charset = "";
    236                                         switch ((int)val) {
    237                                         case 0:
    238                                                 charset = "US-ASCII";
    239                                                 break;
    240                                         case 1:
    241                                                 charset = "ISO-8859-1";
    242                                                 break;
    243                                         case 2:
    244                                                 charset = "UTF-16LE";
    245                                                 break;
    246                                         }
    247                                         if (subf == S57subf.NALL) {
    248                                                 nall = charset;
    249                                         } else {
    250                                                 aall = charset;
    251                                         }
    252                                 }
    253                                 return val;
    254                         } else {
    255                                 if (f == 5) {
    256                                         long val = buffer[offset++] & 0xff;
    257                                         f--;
    258                                         while (f > 0) {
    259                                                 val = (val << 8) + (buffer[offset + --f] & 0xff);
    260                                         }
    261                                         offset += 4;
    262                                         return val;
    263                                 } else {
    264                                         long val = buffer[offset++] & 0xff;
    265                                         val = (val << 8) + (buffer[offset++] & 0xff);
    266                                         f = 4;
    267                                         while (f > 0) {
    268                                                 val = (val << 8) + (buffer[offset + --f] & 0xff);
    269                                         }
    270                                         offset += 4;
    271                                         f = 2;
    272                                         while (f > 0) {
    273                                                 val = (val << 8) + (buffer[offset + --f] & 0xff);
    274                                         }
    275                                         offset += 2;
    276                                         return val;
    277                                 }
    278                         }
    279                 }
    280         }
    281 
    282         public static byte[] encSubf(S57subf subf, Object val) {
    283                 S57conv conv = convs.get(subf);
    284                 if ((conv.bin == 0) || asc) {
    285                         String sval = "";
    286                         if (val instanceof String) {
    287                                 sval = (String) val;
    288                         } else if (val instanceof Integer) {
    289                                 sval = ((Integer)val).toString();
    290                         } else if (val instanceof Long) {
    291                                 sval = ((Long)val).toString();
    292                         } else if (val instanceof Double) {
    293                                 sval = ((Double)val).toString();
    294                         }
    295                         index = sval.length();
    296                         try {
    297                                 buffer = ((String) sval + " ").getBytes("ISO-8859-1");
    298                         } catch (Exception e) {
    299                                 System.err.println(e.getMessage());
    300                                 System.exit(-1);
    301                         }
    302                         if (conv.asc == 0) {
    303                                 buffer[index] = 0x01f;
    304                         } else {
    305                                 buffer = Arrays.copyOf(buffer, conv.asc);
    306                                 while (index < buffer.length) {
    307                                         buffer[index++] = ' ';
    308                                 }
    309                         }
    310                 } else {
    311                         int f = Math.abs(conv.bin);
    312                         long lval;
    313                         if (val instanceof String) {
    314                                 lval = Long.parseLong((String)val);
    315                         } else  if (val instanceof Double) {
    316                                 double dval = (double) val;
    317                                 lval = (long) dval;
    318                         } else  if (val instanceof Integer) {
    319                                 lval = (int) val;
    320                         } else {
    321                                 lval = (long) val;
    322                         }
    323                         buffer = new byte[f];
    324                         for (int i = 0; i < f; i++) {
    325                                 buffer[i] = (byte) (lval & 0xff);
    326                                 lval >>= 8;
    327                         }
    328                 }
    329                 return buffer;
    330         }
    331 
    332         static class Index {
    333                 byte[] field;
    334                 int length;
    335                 int offset;
    336                 Index (byte[] id, int l, int o) {
    337                         field = id;
    338                         length = l;
    339                         offset = o;
    340                 }
    341         }
    342        
    343         public static class Fparams {
    344                 public S57field field;
    345                 public Object[] params;
    346                 public Fparams(S57field f, Object[] p) {
    347                         field = f;
    348                         params = p;
    349                 }
    350         };
    351 
    352         static boolean asc = false;
    353        
    354         public static byte[] encRecord(String i8rn, ArrayList<Fparams> fparams) {
    355                 asc = true;
    356                 return encRecord(Integer.parseInt(i8rn), fparams);
    357         }
    358        
    359         public static byte[] encRecord(int i8rn, ArrayList<Fparams> fparams) {
    360                 ArrayList<Index> index = new ArrayList<>();
    361                 int offset = 3;
    362                 int maxlen = 3;
    363                 byte[] buf = encSubf(S57subf.I8RN, i8rn);
    364                 buf = Arrays.copyOf(buf, 3);
    365                 buf[2] = 0x1e;
    366                 index.add(new Index("0001".getBytes(), 3, 0));
    367                 for (Fparams sfparams : fparams) {
    368                         for (int ip = 0; ip < sfparams.params.length; ) {
    369                                 for (S57subf subf : fields.get(sfparams.field)) {
    370                                         byte[] next = encSubf(subf, sfparams.params[ip++]);
    371                                         buf = Arrays.copyOf(buf, (buf.length + next.length));
    372                                         System.arraycopy(next, 0, buf, (buf.length - next.length), next.length);
    373                                 }
    374                         }
    375                         buf = Arrays.copyOf(buf, (buf.length + 1));
    376                         buf[buf.length-1] = 0x1e;
    377                         int flen = buf.length - offset;
    378                         index.add(new Index(sfparams.field.toString().getBytes(), flen, offset));
    379                         maxlen = (flen > maxlen) ? flen : maxlen;
    380                         offset += flen;
    381                 }
    382                 int mlen = String.valueOf(maxlen).length();
    383                 String ffmt = "%0" + mlen + "d";
    384                 int olen = String.valueOf(offset).length();
    385                 String ofmt = "%0" + olen + "d";
    386                 int ilen = 4 + mlen + olen;
    387                 int isiz = (ilen * index.size()) + 1;
    388                 byte[] ibuf = new byte[isiz];
    389                 int i = 0;
    390                 for (Index item : index) {
    391                         for (byte ch : item.field) {
    392                                 ibuf[i++] = ch;
    393                         }
    394                         byte[] digits = String.format(ffmt, item.length).getBytes();
    395                         for (byte ch : digits) {
    396                                 ibuf[i++] = ch;
    397                         }
    398                         digits = String.format(ofmt, item.offset).getBytes();
    399                         for (byte ch : digits) {
    400                                 ibuf[i++] = ch;
    401                         }
    402                 }
    403                 ibuf[i] = 0x1e;
    404                 byte[] fbuf = Arrays.copyOf(leader, (leader.length + ibuf.length + buf.length));
    405                 System.arraycopy(ibuf, 0, fbuf, leader.length, ibuf.length);
    406                 System.arraycopy(buf, 0, fbuf, (leader.length + ibuf.length), buf.length);
    407                 fbuf[20] = (byte)(mlen + 0x30);
    408                 fbuf[21] = (byte)(olen + 0x30);
    409                 System.arraycopy(String.format("%05d", fbuf.length).getBytes(), 0, fbuf, 0, 5);
    410                 System.arraycopy(String.format("%05d", (leader.length + ibuf.length)).getBytes(), 0, fbuf, 12, 5);
    411                 asc = false;
    412                 return fbuf;
    413         }
    414 
    415         enum Prims { N, P, L, A, PA, PL, LA, PLA }
    416         private static final EnumMap<Obj, Prims> S57prims = new EnumMap<>(Obj.class);
    417         static {
    418                 S57prims.put(Obj.UNKOBJ, Prims.PLA); S57prims.put(Obj.M_COVR, Prims.A); S57prims.put(Obj.M_NSYS, Prims.A); S57prims.put(Obj.AIRARE, Prims.PA);
    419                 S57prims.put(Obj.ACHBRT, Prims.PA); S57prims.put(Obj.ACHARE, Prims.PA); S57prims.put(Obj.BCNCAR, Prims.P); S57prims.put(Obj.BCNISD, Prims.P);
    420                 S57prims.put(Obj.BCNLAT, Prims.P); S57prims.put(Obj.BCNSAW, Prims.P); S57prims.put(Obj.BCNSPP, Prims.P); S57prims.put(Obj.BERTHS, Prims.PLA);
    421                 S57prims.put(Obj.BRIDGE, Prims.PLA); S57prims.put(Obj.BUISGL, Prims.PA); S57prims.put(Obj.BUAARE, Prims.PA); S57prims.put(Obj.BOYCAR, Prims.P);
    422                 S57prims.put(Obj.BOYINB, Prims.P); S57prims.put(Obj.BOYISD, Prims.P); S57prims.put(Obj.BOYLAT, Prims.P); S57prims.put(Obj.BOYSAW, Prims.P);
    423                 S57prims.put(Obj.BOYSPP, Prims.P); S57prims.put(Obj.CBLARE, Prims.A); S57prims.put(Obj.CBLOHD, Prims.L); S57prims.put(Obj.CBLSUB, Prims.L);
    424                 S57prims.put(Obj.CANALS, Prims.A); S57prims.put(Obj.CTSARE, Prims.PA); S57prims.put(Obj.CAUSWY, Prims.LA); S57prims.put(Obj.CTNARE, Prims.PA);
    425                 S57prims.put(Obj.CHKPNT, Prims.PA); S57prims.put(Obj.CGUSTA, Prims.P); S57prims.put(Obj.COALNE, Prims.L); S57prims.put(Obj.CONZNE, Prims.A);
    426                 S57prims.put(Obj.COSARE, Prims.A); S57prims.put(Obj.CTRPNT, Prims.P); S57prims.put(Obj.CONVYR, Prims.LA); S57prims.put(Obj.CRANES, Prims.PA);
    427                 S57prims.put(Obj.CURENT, Prims.P); S57prims.put(Obj.CUSZNE, Prims.A); S57prims.put(Obj.DAMCON, Prims.LA); S57prims.put(Obj.DAYMAR, Prims.P);
    428                 S57prims.put(Obj.DWRTCL, Prims.L); S57prims.put(Obj.DWRTPT, Prims.A); S57prims.put(Obj.DEPARE, Prims.A); S57prims.put(Obj.DEPCNT, Prims.L);
    429                 S57prims.put(Obj.DISMAR, Prims.P); S57prims.put(Obj.DOCARE, Prims.A); S57prims.put(Obj.DRGARE, Prims.A); S57prims.put(Obj.DRYDOC, Prims.A);
    430                 S57prims.put(Obj.DMPGRD, Prims.PA); S57prims.put(Obj.DYKCON, Prims.L); S57prims.put(Obj.EXEZNE, Prims.A); S57prims.put(Obj.FAIRWY, Prims.A);
    431                 S57prims.put(Obj.FNCLNE, Prims.L); S57prims.put(Obj.FERYRT, Prims.LA); S57prims.put(Obj.FSHZNE, Prims.A); S57prims.put(Obj.FSHFAC, Prims.PLA);
    432                 S57prims.put(Obj.FSHGRD, Prims.A); S57prims.put(Obj.FLODOC, Prims.A); S57prims.put(Obj.FOGSIG, Prims.P); S57prims.put(Obj.FORSTC, Prims.PLA);
    433                 S57prims.put(Obj.FRPARE, Prims.A); S57prims.put(Obj.GATCON, Prims.PLA); S57prims.put(Obj.GRIDRN, Prims.PA); S57prims.put(Obj.HRBARE, Prims.A);
    434                 S57prims.put(Obj.HRBFAC, Prims.PA); S57prims.put(Obj.HULKES, Prims.PA); S57prims.put(Obj.ICEARE, Prims.A); S57prims.put(Obj.ICNARE, Prims.PA);
    435                 S57prims.put(Obj.ISTZNE, Prims.A); S57prims.put(Obj.LAKARE, Prims.A); S57prims.put(Obj.LNDARE, Prims.PLA); S57prims.put(Obj.LNDELV, Prims.PL);
    436                 S57prims.put(Obj.LNDRGN, Prims.PA); S57prims.put(Obj.LNDMRK, Prims.PLA); S57prims.put(Obj.LIGHTS, Prims.P); S57prims.put(Obj.LITFLT, Prims.P);
    437                 S57prims.put(Obj.LITVES, Prims.P); S57prims.put(Obj.LOCMAG, Prims.PLA); S57prims.put(Obj.LOKBSN, Prims.A); S57prims.put(Obj.LOGPON, Prims.PA);
    438                 S57prims.put(Obj.MAGVAR, Prims.PLA); S57prims.put(Obj.MARCUL, Prims.PLA); S57prims.put(Obj.MIPARE, Prims.PA); S57prims.put(Obj.MORFAC, Prims.PLA);
    439                 S57prims.put(Obj.MPAARE, Prims.PA); S57prims.put(Obj.NAVLNE, Prims.L); S57prims.put(Obj.OBSTRN, Prims.PLA); S57prims.put(Obj.OFSPLF, Prims.PA);
    440                 S57prims.put(Obj.OSPARE, Prims.A); S57prims.put(Obj.OILBAR, Prims.L); S57prims.put(Obj.PILPNT, Prims.P); S57prims.put(Obj.PILBOP, Prims.PA);
    441                 S57prims.put(Obj.PIPARE, Prims.PA); S57prims.put(Obj.PIPOHD, Prims.L); S57prims.put(Obj.PIPSOL, Prims.PL); S57prims.put(Obj.PONTON, Prims.LA);
    442                 S57prims.put(Obj.PRCARE, Prims.PA); S57prims.put(Obj.PRDARE, Prims.PA); S57prims.put(Obj.PYLONS, Prims.PA); S57prims.put(Obj.RADLNE, Prims.L);
    443                 S57prims.put(Obj.RADRNG, Prims.A); S57prims.put(Obj.RADRFL, Prims.P); S57prims.put(Obj.RADSTA, Prims.P); S57prims.put(Obj.RTPBCN, Prims.P);
    444                 S57prims.put(Obj.RDOCAL, Prims.PL); S57prims.put(Obj.RDOSTA, Prims.P); S57prims.put(Obj.RAILWY, Prims.L); S57prims.put(Obj.RAPIDS, Prims.PLA);
    445                 S57prims.put(Obj.RCRTCL, Prims.L); S57prims.put(Obj.RECTRC, Prims.LA); S57prims.put(Obj.RCTLPT, Prims.PA); S57prims.put(Obj.RSCSTA, Prims.P);
    446                 S57prims.put(Obj.RESARE, Prims.A); S57prims.put(Obj.RETRFL, Prims.P); S57prims.put(Obj.RIVERS, Prims.LA); S57prims.put(Obj.ROADWY, Prims.PLA);
    447                 S57prims.put(Obj.RUNWAY, Prims.PLA); S57prims.put(Obj.SNDWAV, Prims.PLA); S57prims.put(Obj.SEAARE, Prims.PA); S57prims.put(Obj.SPLARE, Prims.PA);
    448                 S57prims.put(Obj.SBDARE, Prims.PLA); S57prims.put(Obj.SLCONS, Prims.PLA); S57prims.put(Obj.SISTAT, Prims.P); S57prims.put(Obj.SISTAW, Prims.P);
    449                 S57prims.put(Obj.SILTNK, Prims.PA); S57prims.put(Obj.SLOTOP, Prims.L); S57prims.put(Obj.SLOGRD, Prims.PA); S57prims.put(Obj.SMCFAC, Prims.PA);
    450                 S57prims.put(Obj.SOUNDG, Prims.P); S57prims.put(Obj.SPRING, Prims.P); S57prims.put(Obj.STSLNE, Prims.L); S57prims.put(Obj.SUBTLN, Prims.A);
    451                 S57prims.put(Obj.SWPARE, Prims.A); S57prims.put(Obj.TESARE, Prims.A); S57prims.put(Obj.TS_PRH, Prims.PA); S57prims.put(Obj.TS_PNH, Prims.PA);
    452                 S57prims.put(Obj.TS_PAD, Prims.PA); S57prims.put(Obj.TS_TIS, Prims.PA); S57prims.put(Obj.T_HMON, Prims.PA); S57prims.put(Obj.T_NHMN, Prims.PA);
    453                 S57prims.put(Obj.T_TIMS, Prims.PA); S57prims.put(Obj.TIDEWY, Prims.LA); S57prims.put(Obj.TOPMAR, Prims.P); S57prims.put(Obj.TSELNE, Prims.LA);
    454                 S57prims.put(Obj.TSSBND, Prims.L); S57prims.put(Obj.TSSCRS, Prims.A); S57prims.put(Obj.TSSLPT, Prims.A); S57prims.put(Obj.TSSRON, Prims.A);
    455                 S57prims.put(Obj.TSEZNE, Prims.A); S57prims.put(Obj.TUNNEL, Prims.LA); S57prims.put(Obj.TWRTPT, Prims.A); S57prims.put(Obj.UWTROC, Prims.P);
    456                 S57prims.put(Obj.UNSARE, Prims.A); S57prims.put(Obj.VEGATN, Prims.PLA); S57prims.put(Obj.WATTUR, Prims.PLA); S57prims.put(Obj.WATFAL, Prims.PL);
    457                 S57prims.put(Obj.WEDKLP, Prims.PA); S57prims.put(Obj.WRECKS, Prims.PA); S57prims.put(Obj.TS_FEB, Prims.PA);
    458                 S57prims.put(Obj.NOTMRK, Prims.P); S57prims.put(Obj.WTWAXS, Prims.L); S57prims.put(Obj.WTWPRF, Prims.L); S57prims.put(Obj.BUNSTA, Prims.PA);
    459                 S57prims.put(Obj.COMARE, Prims.A); S57prims.put(Obj.HRBBSN, Prims.A); S57prims.put(Obj.LKBSPT, Prims.A); S57prims.put(Obj.PRTARE, Prims.A);
    460                 S57prims.put(Obj.REFDMP, Prims.P); S57prims.put(Obj.TERMNL, Prims.PA); S57prims.put(Obj.TRNBSN, Prims.PA); S57prims.put(Obj.WTWARE, Prims.A);
    461                 S57prims.put(Obj.WTWGAG, Prims.PA); S57prims.put(Obj.TISDGE, Prims.N); S57prims.put(Obj.VEHTRF, Prims.PA); S57prims.put(Obj.EXCNST, Prims.PA);
    462                 S57prims.put(Obj.LG_SDM, Prims.A); S57prims.put(Obj.LG_VSP, Prims.A); S57prims.put(Obj.LITMAJ, Prims.P);  S57prims.put(Obj.LITMIN, Prims.P);
    463         }
    464 
    465         public static void S57geoms(S57map map) {
    466                 for (ArrayList<Feature> list : map.features.values()) {
    467                         for (Feature feature : list) {
    468                                 switch (S57prims.get(feature.type)) {
    469                                 case N:
    470                                         break;
    471                                 case P:
    472                                         if (feature.geom.prim != Pflag.POINT) {
    473 //                                              Snode node = feature.geom.centre;
    474 //                                              node.flg = Nflag.ISOL;
    475 //                                              map.nodes.put(++map.xref, node);
    476 //                                              feature.geom = map.new Geom(Pflag.POINT);
    477 //                                              feature.geom.centre = node;
    478 //                                              feature.geom.elems.add(map.new Prim(map.xref));
    479                                         }
    480                                         break;
    481                                 case L:
    482                                         break;
    483                                 case A:
    484                                         break;
    485                                 case PA:
    486                                         break;
    487                                 case PL:
    488                                         break;
    489                                 case LA:
    490                                         if (feature.geom.prim == Pflag.POINT) {
    491 //                                              list.remove(feature);
    492                                         }
    493                                         break;
    494                                 case PLA:
    495                                         // No changes needed
    496                                         break;
    497                                 }
    498                         }
    499                 }
    500         }
     22    // CHECKSTYLE.OFF: LineLength
     23
     24    public static class S57conv {
     25        int asc;    // 0=A(), 1+=A(n)
     26        int bin;    // 0=ASCII, +ve=b1n(unsigned LE), -ve=b2n(signed LE), n>8=b1(n/8)(unsigned BE)
     27        S57conv(int a, int b) {
     28            asc = a; bin = b;
     29        }
     30    }
     31
     32    public enum S57subf { I8RN, RCNM, RCID, EXPP, INTU, DSNM, EDTN, UPDN, UADT, ISDT, STED, PRSP, PSDN, PRED, PROF, AGEN, COMT, DSTR, AALL, NALL, NOMR, NOCR, NOGR, NOLR, NOIN, NOCN,
     33        NOED, NOFA, HDAT, VDAT, SDAT, CSCL, DUNI, HUNI, PUNI, COUN, COMF, SOMF, PROJ, PRP1, PRP2, PRP3, PRP4, FEAS, FNOR, FPMF, RPID, RYCO, RXCO, CURP, RXVL, RYVL, PRCO, ESDT,
     34        LSDT, DCRT, CODT, PACC, HACC, SACC, FILE, LFIL, VOLM, IMPL, SLAT, WLON, NLAT, ELON, CRCS, NAM1, NAM2, OORA, OAAC, OACO, OALL, OATY, DEFN, AUTH, RFTP, RFVL, ATLB, ATDO,
     35        ADMU, ADFT, RAVA, DVAL, DVSD, OBLB, ASET, PRIM, GRUP, OBJL, RVER, RUIN, FIDN, FIDS, ATTL, ATVL, FFUI, FFIX, NFPT, LNAM, RIND, FSUI, FSIX, NSPT, NAME, ORNT, USAG, MASK,
     36        VPUI, VPIX, NVPT, TOPI, CCUI, CCIX, CCNC, YCOO, XCOO, VE3D, ATYP, SURF, ORDR, RESO, STPT, CTPT, ENPT, CDPM, CDPR }
     37
     38    private static final EnumMap<S57subf, S57conv> convs = new EnumMap<>(S57subf.class);
     39    static {
     40        convs.put(S57subf.I8RN, new S57conv(5, 2));
     41        convs.put(S57subf.RCNM, new S57conv(2, 1)); convs.put(S57subf.RCID, new S57conv(10, 4)); convs.put(S57subf.EXPP, new S57conv(1, 1));
     42        convs.put(S57subf.INTU, new S57conv(1, 1)); convs.put(S57subf.DSNM, new S57conv(0, 0)); convs.put(S57subf.EDTN, new S57conv(0, 0));
     43        convs.put(S57subf.UPDN, new S57conv(0, 0)); convs.put(S57subf.UADT, new S57conv(8, 0)); convs.put(S57subf.ISDT, new S57conv(8, 0));
     44        convs.put(S57subf.STED, new S57conv(4, 0)); convs.put(S57subf.PRSP, new S57conv(3, 1)); convs.put(S57subf.PSDN, new S57conv(0, 0));
     45        convs.put(S57subf.PRED, new S57conv(0, 0)); convs.put(S57subf.PROF, new S57conv(2, 1)); convs.put(S57subf.AGEN, new S57conv(2, 2));
     46        convs.put(S57subf.COMT, new S57conv(0, 0)); convs.put(S57subf.DSTR, new S57conv(2, 1)); convs.put(S57subf.AALL, new S57conv(1, 1));
     47        convs.put(S57subf.NALL, new S57conv(1, 1)); convs.put(S57subf.NOMR, new S57conv(0, 4)); convs.put(S57subf.NOCR, new S57conv(0, 4));
     48        convs.put(S57subf.NOGR, new S57conv(0, 4)); convs.put(S57subf.NOLR, new S57conv(0, 4)); convs.put(S57subf.NOIN, new S57conv(0, 4));
     49        convs.put(S57subf.NOCN, new S57conv(0, 4)); convs.put(S57subf.NOED, new S57conv(0, 4)); convs.put(S57subf.NOFA, new S57conv(0, 4));
     50        convs.put(S57subf.HDAT, new S57conv(3, 1)); convs.put(S57subf.VDAT, new S57conv(2, 1)); convs.put(S57subf.SDAT, new S57conv(2, 1));
     51        convs.put(S57subf.CSCL, new S57conv(0, 4)); convs.put(S57subf.DUNI, new S57conv(2, 1)); convs.put(S57subf.HUNI, new S57conv(2, 1));
     52        convs.put(S57subf.PUNI, new S57conv(2, 1)); convs.put(S57subf.COUN, new S57conv(2, 1)); convs.put(S57subf.COMF, new S57conv(0, 4));
     53        convs.put(S57subf.SOMF, new S57conv(0, 4)); convs.put(S57subf.PROJ, new S57conv(3, 1)); convs.put(S57subf.PRP1, new S57conv(0, -4));
     54        convs.put(S57subf.PRP2, new S57conv(0, -4)); convs.put(S57subf.PRP3, new S57conv(0, -4)); convs.put(S57subf.PRP4, new S57conv(0, -4));
     55        convs.put(S57subf.FEAS, new S57conv(0, -4)); convs.put(S57subf.FNOR, new S57conv(0, -4)); convs.put(S57subf.FPMF, new S57conv(0, 4));
     56        convs.put(S57subf.RPID, new S57conv(1, 1)); convs.put(S57subf.RYCO, new S57conv(0, -4)); convs.put(S57subf.RXCO, new S57conv(0, -4));
     57        convs.put(S57subf.CURP, new S57conv(2, 1)); convs.put(S57subf.RXVL, new S57conv(0, -4)); convs.put(S57subf.RYVL, new S57conv(0, -4));
     58        convs.put(S57subf.PRCO, new S57conv(2, 2)); convs.put(S57subf.ESDT, new S57conv(8, 0)); convs.put(S57subf.LSDT, new S57conv(8, 0));
     59        convs.put(S57subf.DCRT, new S57conv(0, 0)); convs.put(S57subf.CODT, new S57conv(8, 0)); convs.put(S57subf.PACC, new S57conv(0, 4));
     60        convs.put(S57subf.HACC, new S57conv(0, 4)); convs.put(S57subf.SACC, new S57conv(0, 4)); convs.put(S57subf.FILE, new S57conv(0, 0));
     61        convs.put(S57subf.LFIL, new S57conv(0, 0)); convs.put(S57subf.VOLM, new S57conv(0, 0)); convs.put(S57subf.IMPL, new S57conv(3, 0));
     62        convs.put(S57subf.SLAT, new S57conv(0, 0)); convs.put(S57subf.WLON, new S57conv(0, 0)); convs.put(S57subf.NLAT, new S57conv(0, 0));
     63        convs.put(S57subf.ELON, new S57conv(0, 0)); convs.put(S57subf.CRCS, new S57conv(0, 0)); convs.put(S57subf.NAM1, new S57conv(12, 5));
     64        convs.put(S57subf.NAM2, new S57conv(12, 5)); convs.put(S57subf.OORA, new S57conv(1, 1)); convs.put(S57subf.OAAC, new S57conv(6, 0));
     65        convs.put(S57subf.OACO, new S57conv(5, 2)); convs.put(S57subf.OALL, new S57conv(0, 0)); convs.put(S57subf.OATY, new S57conv(1, 1));
     66        convs.put(S57subf.DEFN, new S57conv(0, 0)); convs.put(S57subf.AUTH, new S57conv(2, 2)); convs.put(S57subf.RFTP, new S57conv(2, 1));
     67        convs.put(S57subf.RFVL, new S57conv(0, 0)); convs.put(S57subf.ATLB, new S57conv(5, 2)); convs.put(S57subf.ATDO, new S57conv(1, 1));
     68        convs.put(S57subf.ADMU, new S57conv(0, 0)); convs.put(S57subf.ADFT, new S57conv(0, 0)); convs.put(S57subf.RAVA, new S57conv(1, 1));
     69        convs.put(S57subf.DVAL, new S57conv(0, 0)); convs.put(S57subf.DVSD, new S57conv(0, 0)); convs.put(S57subf.OBLB, new S57conv(5, 2));
     70        convs.put(S57subf.ASET, new S57conv(1, 1)); convs.put(S57subf.PRIM, new S57conv(1, 1)); convs.put(S57subf.GRUP, new S57conv(3, 1));
     71        convs.put(S57subf.OBJL, new S57conv(5, 2)); convs.put(S57subf.RVER, new S57conv(3, 2)); convs.put(S57subf.RUIN, new S57conv(1, 1));
     72        convs.put(S57subf.FIDN, new S57conv(10, 4)); convs.put(S57subf.FIDS, new S57conv(5, 2)); convs.put(S57subf.ATTL, new S57conv(5, 2));
     73        convs.put(S57subf.ATVL, new S57conv(0, 0)); convs.put(S57subf.FFUI, new S57conv(1, 1)); convs.put(S57subf.FFIX, new S57conv(0, 2));
     74        convs.put(S57subf.NFPT, new S57conv(0, 2)); convs.put(S57subf.LNAM, new S57conv(17, 8)); convs.put(S57subf.RIND, new S57conv(0, 1));
     75        convs.put(S57subf.FSUI, new S57conv(1, 1)); convs.put(S57subf.FSIX, new S57conv(0, 2)); convs.put(S57subf.NSPT, new S57conv(0, 2));
     76        convs.put(S57subf.NAME, new S57conv(12, 5)); convs.put(S57subf.ORNT, new S57conv(1, 1)); convs.put(S57subf.USAG, new S57conv(1, 1));
     77        convs.put(S57subf.MASK, new S57conv(1, 1)); convs.put(S57subf.VPUI, new S57conv(1, 1)); convs.put(S57subf.VPIX, new S57conv(0, 2));
     78        convs.put(S57subf.NVPT, new S57conv(0, 2)); convs.put(S57subf.TOPI, new S57conv(1, 1)); convs.put(S57subf.CCUI, new S57conv(1, 1));
     79        convs.put(S57subf.CCIX, new S57conv(0, 2)); convs.put(S57subf.CCNC, new S57conv(0, 2)); convs.put(S57subf.YCOO, new S57conv(0, -4));
     80        convs.put(S57subf.XCOO, new S57conv(0, -4)); convs.put(S57subf.VE3D, new S57conv(0, -4)); convs.put(S57subf.ATYP, new S57conv(1, 1));
     81        convs.put(S57subf.SURF, new S57conv(1, 1)); convs.put(S57subf.ORDR, new S57conv(1, 1)); convs.put(S57subf.RESO, new S57conv(0, 4));
     82        convs.put(S57subf.STPT, new S57conv(0, 0)); convs.put(S57subf.CTPT, new S57conv(0, 0)); convs.put(S57subf.ENPT, new S57conv(0, 0));
     83        convs.put(S57subf.CDPM, new S57conv(0, 0)); convs.put(S57subf.CDPR, new S57conv(0, 0));
     84    }
     85
     86    public enum S57field { I8RI, DSID, DSSI, DSPM, DSPR, DSRC, DSHT, DSAC, CATD, CATX, DDDF, DDDR, DDDI, DDOM, DDRF, DDSI, DDSC,
     87        FRID, FOID, LNAM, ATTF, NATF, FFPC, FFPT, FSPC, FSPT, VRID, ATTV, VRPC, VRPT, SGCC, SG2D, SG3D, ARCC, AR2D, EL2D, CT2D }
     88
     89    private static ArrayList<S57subf> S57i8ri = new ArrayList<>(Arrays.asList(S57subf.I8RN));
     90    private static ArrayList<S57subf> S57dsid = new ArrayList<>(Arrays.asList(S57subf.RCNM, S57subf.RCID, S57subf.EXPP, S57subf.INTU, S57subf.DSNM, S57subf.EDTN, S57subf.UPDN,
     91            S57subf.UADT, S57subf.ISDT, S57subf.STED, S57subf.PRSP, S57subf.PSDN, S57subf.PRED, S57subf.PROF, S57subf.AGEN, S57subf.COMT));
     92    private static ArrayList<S57subf> S57dssi = new ArrayList<>(Arrays.asList(S57subf.DSTR, S57subf.AALL, S57subf.NALL, S57subf.NOMR, S57subf.NOCR, S57subf.NOGR, S57subf.NOLR,
     93            S57subf.NOIN, S57subf.NOCN, S57subf.NOED, S57subf.NOFA));
     94    private static ArrayList<S57subf> S57dspm = new ArrayList<>(Arrays.asList(S57subf.RCNM, S57subf.RCID, S57subf.HDAT, S57subf.VDAT, S57subf.SDAT, S57subf.CSCL, S57subf.DUNI,
     95            S57subf.HUNI, S57subf.PUNI, S57subf.COUN, S57subf.COMF, S57subf.SOMF, S57subf.COMT));
     96    private static ArrayList<S57subf> S57dspr = new ArrayList<>(Arrays.asList(S57subf.PROJ, S57subf.PRP1, S57subf.PRP2, S57subf.PRP3, S57subf.PRP4, S57subf.FEAS, S57subf.FNOR,
     97            S57subf.FPMF, S57subf.COMT));
     98    private static ArrayList<S57subf> S57dsrc = new ArrayList<>(Arrays.asList(S57subf.RPID, S57subf.RYCO, S57subf.RXCO, S57subf.CURP, S57subf.FPMF, S57subf.RXVL, S57subf.RYVL,
     99            S57subf.COMT));
     100    private static ArrayList<S57subf> S57dsht = new ArrayList<>(Arrays.asList(S57subf.RCNM, S57subf.RCID, S57subf.PRCO, S57subf.ESDT, S57subf.LSDT, S57subf.DCRT, S57subf.CODT, S57subf.COMT));
     101    private static ArrayList<S57subf> S57dsac = new ArrayList<>(Arrays.asList(S57subf.RCNM, S57subf.RCID, S57subf.PACC, S57subf.HACC, S57subf.SACC, S57subf.FPMF, S57subf.COMT));
     102    private static ArrayList<S57subf> S57catd = new ArrayList<>(Arrays.asList(S57subf.RCNM, S57subf.RCID, S57subf.FILE, S57subf.LFIL, S57subf.VOLM, S57subf.IMPL, S57subf.SLAT,
     103            S57subf.WLON, S57subf.NLAT, S57subf.ELON, S57subf.CRCS, S57subf.COMT));
     104    private static ArrayList<S57subf> S57catx = new ArrayList<>(Arrays.asList(S57subf.RCNM, S57subf.RCID, S57subf.NAM1, S57subf.NAM2, S57subf.COMT));
     105    private static ArrayList<S57subf> S57dddf = new ArrayList<>(Arrays.asList(S57subf.RCNM, S57subf.RCID, S57subf.OORA, S57subf.OAAC, S57subf.OACO, S57subf.OALL, S57subf.OATY,
     106            S57subf.DEFN, S57subf.AUTH, S57subf.COMT));
     107    private static ArrayList<S57subf> S57dddr = new ArrayList<>(Arrays.asList(S57subf.RFTP, S57subf.RFVL));
     108    private static ArrayList<S57subf> S57dddi = new ArrayList<>(Arrays.asList(S57subf.RCNM, S57subf.RCID, S57subf.ATLB, S57subf.ATDO, S57subf.ADMU, S57subf.ADFT, S57subf.AUTH, S57subf.COMT));
     109    private static ArrayList<S57subf> S57ddom = new ArrayList<>(Arrays.asList(S57subf.RAVA, S57subf.DVAL, S57subf.DVSD, S57subf.DEFN, S57subf.AUTH));
     110    private static ArrayList<S57subf> S57ddrf = new ArrayList<>(Arrays.asList(S57subf.RFTP, S57subf.RFVL));
     111    private static ArrayList<S57subf> S57ddsi = new ArrayList<>(Arrays.asList(S57subf.RCNM, S57subf.RCID, S57subf.OBLB));
     112    private static ArrayList<S57subf> S57ddsc = new ArrayList<>(Arrays.asList(S57subf.ATLB, S57subf.ASET, S57subf.AUTH));
     113    private static ArrayList<S57subf> S57frid = new ArrayList<>(Arrays.asList(S57subf.RCNM, S57subf.RCID, S57subf.PRIM, S57subf.GRUP, S57subf.OBJL, S57subf.RVER, S57subf.RUIN));
     114    private static ArrayList<S57subf> S57foid = new ArrayList<>(Arrays.asList(S57subf.AGEN, S57subf.FIDN, S57subf.FIDS));
     115    private static ArrayList<S57subf> S57lnam = new ArrayList<>(Arrays.asList(S57subf.LNAM));
     116    private static ArrayList<S57subf> S57attf = new ArrayList<>(Arrays.asList(S57subf.ATTL, S57subf.ATVL));
     117    private static ArrayList<S57subf> S57natf = new ArrayList<>(Arrays.asList(S57subf.ATTL, S57subf.ATVL));
     118    private static ArrayList<S57subf> S57ffpc = new ArrayList<>(Arrays.asList(S57subf.FFUI, S57subf.FFIX, S57subf.NFPT));
     119    private static ArrayList<S57subf> S57ffpt = new ArrayList<>(Arrays.asList(S57subf.LNAM, S57subf.RIND, S57subf.COMT));
     120    private static ArrayList<S57subf> S57fspc = new ArrayList<>(Arrays.asList(S57subf.FSUI, S57subf.FSIX, S57subf.NSPT));
     121    private static ArrayList<S57subf> S57fspt = new ArrayList<>(Arrays.asList(S57subf.NAME, S57subf.ORNT, S57subf.USAG, S57subf.MASK));
     122    private static ArrayList<S57subf> S57vrid = new ArrayList<>(Arrays.asList(S57subf.RCNM, S57subf.RCID, S57subf.RVER, S57subf.RUIN));
     123    private static ArrayList<S57subf> S57attv = new ArrayList<>(Arrays.asList(S57subf.ATTL, S57subf.ATVL));
     124    private static ArrayList<S57subf> S57vrpc = new ArrayList<>(Arrays.asList(S57subf.VPUI, S57subf.VPIX, S57subf.NVPT));
     125    private static ArrayList<S57subf> S57vrpt = new ArrayList<>(Arrays.asList(S57subf.NAME, S57subf.ORNT, S57subf.USAG, S57subf.TOPI, S57subf.MASK));
     126    private static ArrayList<S57subf> S57sgcc = new ArrayList<>(Arrays.asList(S57subf.CCUI, S57subf.CCIX, S57subf.CCNC));
     127    private static ArrayList<S57subf> S57sg2d = new ArrayList<>(Arrays.asList(S57subf.YCOO, S57subf.XCOO));
     128    private static ArrayList<S57subf> S57sg3d = new ArrayList<>(Arrays.asList(S57subf.YCOO, S57subf.XCOO, S57subf.VE3D));
     129    private static ArrayList<S57subf> S57arcc = new ArrayList<>(Arrays.asList(S57subf.ATYP, S57subf.SURF, S57subf.ORDR, S57subf.RESO, S57subf.FPMF));
     130    private static ArrayList<S57subf> S57ar2d = new ArrayList<>(Arrays.asList(S57subf.STPT, S57subf.CTPT, S57subf.ENPT, S57subf.YCOO, S57subf.XCOO));
     131    private static ArrayList<S57subf> S57el2d = new ArrayList<>(Arrays.asList(S57subf.STPT, S57subf.CTPT, S57subf.ENPT, S57subf.CDPM, S57subf.CDPR, S57subf.YCOO, S57subf.XCOO));
     132    private static ArrayList<S57subf> S57ct2d = new ArrayList<>(Arrays.asList(S57subf.YCOO, S57subf.XCOO));
     133
     134    private static final EnumMap<S57field, ArrayList<S57subf>> fields = new EnumMap<>(S57field.class);
     135    static {
     136        fields.put(S57field.I8RI, S57i8ri);
     137        fields.put(S57field.DSID, S57dsid); fields.put(S57field.DSSI, S57dssi); fields.put(S57field.DSPM, S57dspm); fields.put(S57field.DSPR, S57dspr);
     138        fields.put(S57field.DSRC, S57dsrc); fields.put(S57field.DSHT, S57dsht); fields.put(S57field.DSAC, S57dsac); fields.put(S57field.CATD, S57catd);
     139        fields.put(S57field.CATX, S57catx); fields.put(S57field.DDDF, S57dddf); fields.put(S57field.DDDR, S57dddr); fields.put(S57field.DDDI, S57dddi);
     140        fields.put(S57field.DDOM, S57ddom); fields.put(S57field.DDRF, S57ddrf); fields.put(S57field.DDSI, S57ddsi); fields.put(S57field.DDSC, S57ddsc);
     141        fields.put(S57field.FRID, S57frid); fields.put(S57field.FOID, S57foid); fields.put(S57field.LNAM, S57lnam); fields.put(S57field.ATTF, S57attf);
     142        fields.put(S57field.NATF, S57natf); fields.put(S57field.FFPC, S57ffpc); fields.put(S57field.FFPT, S57ffpt); fields.put(S57field.FFPC, S57fspc);
     143        fields.put(S57field.FSPT, S57fspt); fields.put(S57field.VRID, S57vrid); fields.put(S57field.ATTV, S57attv); fields.put(S57field.VRPC, S57vrpc);
     144        fields.put(S57field.VRPT, S57vrpt); fields.put(S57field.SGCC, S57sgcc); fields.put(S57field.SG2D, S57sg2d); fields.put(S57field.SG3D, S57sg3d);
     145        fields.put(S57field.ARCC, S57arcc); fields.put(S57field.AR2D, S57ar2d); fields.put(S57field.EL2D, S57el2d); fields.put(S57field.CT2D, S57ct2d);
     146    }
     147
     148    private static byte[] leader = {'0', '0', '0', '0', '0', ' ', 'D', ' ', ' ', ' ', ' ', ' ', '0', '0', '0', '0', '0', ' ', ' ', ' ', '0', '0', '0', '4'};
     149    private static byte[] buffer;
     150    private static int offset;
     151    private static int maxoff;
     152    private static int index;
     153    private static S57field field;
     154    private static String aall = "US-ASCII";
     155    private static String nall = "US-ASCII";
     156    public static int rnum;
     157
     158    private static S57conv findSubf(S57subf subf) {
     159        ArrayList<S57subf> subs = fields.get(field);
     160        boolean wrap = false;
     161        while (true) {
     162            if (index == subs.size()) {
     163                if (!wrap) {
     164                    index = 0;
     165                    wrap = true;
     166                } else {
     167                    System.out.println("ERROR: Subfield not found " + subf.name() + " in " + field.name() + " in record " + rnum);
     168                    System.exit(-1);
     169                }
     170            }
     171            S57subf sub = subs.get(index++);
     172            S57conv conv = convs.get(sub);
     173            if (sub == subf) {
     174                return conv;
     175            } else {
     176                offset += (conv.bin != 0) ? ((conv.bin < 8) ? Math.abs(conv.bin) : conv.bin / 8) : conv.asc;
     177            }
     178        }
     179    }
     180
     181    public static void setField(byte[] buf, int off, S57field fld, int len) {
     182        buffer = buf;
     183        offset = off;
     184        maxoff = off + len - 1;
     185        field = fld;
     186        index = 0;
     187    }
     188
     189    public static boolean more() {
     190        return (offset < maxoff);
     191    }
     192
     193    public static Object decSubf(byte[] buf, int off, S57field fld, S57subf subf) {
     194        buffer = buf;
     195        offset = off;
     196        index = 0;
     197        return decSubf(fld, subf);
     198    }
     199
     200    public static Object decSubf(S57field fld, S57subf subf) {
     201        field = fld;
     202        index = 0;
     203        return decSubf(subf);
     204    }
     205
     206    public static Object decSubf(S57subf subf) {
     207        S57conv conv = findSubf(subf);
     208        if (conv.bin == 0) {
     209            String str = "";
     210            int i = 0;
     211            if (conv.asc == 0) {
     212                for (i = 0; buffer[offset+i] != 0x1f; i++) { }
     213                try {
     214                    String charset = "";
     215                    if (field == S57field.ATTF) charset = aall;
     216                    else if (field == S57field.NATF) charset = nall;
     217                    else charset = "US-ASCII";
     218                    str = new String(buffer, offset, i, charset);
     219                } catch (UnsupportedEncodingException e) {
     220                    e.printStackTrace();
     221                }
     222                offset += i + 1;
     223            } else {
     224                str = new String(buffer, offset, conv.asc);
     225                offset += conv.asc;
     226            }
     227            return str;
     228        } else {
     229            int f = Math.abs(conv.bin);
     230            if (f < 5) {
     231                long val = buffer[offset + --f];
     232                if (conv.bin > 0)
     233                    val &= 0xff;
     234                while (f > 0) {
     235                    val = (val << 8) + (buffer[offset + --f] & 0xff);
     236                }
     237                offset += Math.abs(conv.bin);
     238                if ((subf == S57subf.AALL) || (subf == S57subf.NALL)) {
     239                    String charset = "";
     240                    switch ((int) val) {
     241                    case 0:
     242                        charset = "US-ASCII";
     243                        break;
     244                    case 1:
     245                        charset = "ISO-8859-1";
     246                        break;
     247                    case 2:
     248                        charset = "UTF-16LE";
     249                        break;
     250                    }
     251                    if (subf == S57subf.NALL) {
     252                        nall = charset;
     253                    } else {
     254                        aall = charset;
     255                    }
     256                }
     257                return val;
     258            } else {
     259                if (f == 5) {
     260                    long val = buffer[offset++] & 0xff;
     261                    f--;
     262                    while (f > 0) {
     263                        val = (val << 8) + (buffer[offset + --f] & 0xff);
     264                    }
     265                    offset += 4;
     266                    return val;
     267                } else {
     268                    long val = buffer[offset++] & 0xff;
     269                    val = (val << 8) + (buffer[offset++] & 0xff);
     270                    f = 4;
     271                    while (f > 0) {
     272                        val = (val << 8) + (buffer[offset + --f] & 0xff);
     273                    }
     274                    offset += 4;
     275                    f = 2;
     276                    while (f > 0) {
     277                        val = (val << 8) + (buffer[offset + --f] & 0xff);
     278                    }
     279                    offset += 2;
     280                    return val;
     281                }
     282            }
     283        }
     284    }
     285
     286    public static byte[] encSubf(S57subf subf, Object val) {
     287        S57conv conv = convs.get(subf);
     288        if ((conv.bin == 0) || asc) {
     289            String sval = "";
     290            if (val instanceof String) {
     291                sval = (String) val;
     292            } else if (val instanceof Integer) {
     293                sval = ((Integer) val).toString();
     294            } else if (val instanceof Long) {
     295                sval = ((Long) val).toString();
     296            } else if (val instanceof Double) {
     297                sval = ((Double) val).toString();
     298            }
     299            index = sval.length();
     300            try {
     301                buffer = (sval + " ").getBytes("ISO-8859-1");
     302            } catch (Exception e) {
     303                System.err.println(e.getMessage());
     304                System.exit(-1);
     305            }
     306            if (conv.asc == 0) {
     307                buffer[index] = 0x01f;
     308            } else {
     309                buffer = Arrays.copyOf(buffer, conv.asc);
     310                while (index < buffer.length) {
     311                    buffer[index++] = ' ';
     312                }
     313            }
     314        } else {
     315            int f = Math.abs(conv.bin);
     316            long lval;
     317            if (val instanceof String) {
     318                lval = Long.parseLong((String) val);
     319            } else if (val instanceof Double) {
     320                double dval = (double) val;
     321                lval = (long) dval;
     322            } else if (val instanceof Integer) {
     323                lval = (int) val;
     324            } else {
     325                lval = (long) val;
     326            }
     327            buffer = new byte[f];
     328            for (int i = 0; i < f; i++) {
     329                buffer[i] = (byte) (lval & 0xff);
     330                lval >>= 8;
     331            }
     332        }
     333        return buffer;
     334    }
     335
     336    static class Index {
     337        byte[] field;
     338        int length;
     339        int offset;
     340        Index(byte[] id, int l, int o) {
     341            field = id;
     342            length = l;
     343            offset = o;
     344        }
     345    }
     346
     347    public static class Fparams {
     348        public S57field field;
     349        public Object[] params;
     350        public Fparams(S57field f, Object[] p) {
     351            field = f;
     352            params = p;
     353        }
     354    }
     355
     356    static boolean asc = false;
     357
     358    public static byte[] encRecord(String i8rn, ArrayList<Fparams> fparams) {
     359        asc = true;
     360        return encRecord(Integer.parseInt(i8rn), fparams);
     361    }
     362
     363    public static byte[] encRecord(int i8rn, ArrayList<Fparams> fparams) {
     364        ArrayList<Index> index = new ArrayList<>();
     365        int offset = 3;
     366        int maxlen = 3;
     367        byte[] buf = encSubf(S57subf.I8RN, i8rn);
     368        buf = Arrays.copyOf(buf, 3);
     369        buf[2] = 0x1e;
     370        index.add(new Index("0001".getBytes(), 3, 0));
     371        for (Fparams sfparams : fparams) {
     372            for (int ip = 0; ip < sfparams.params.length;) {
     373                for (S57subf subf : fields.get(sfparams.field)) {
     374                    byte[] next = encSubf(subf, sfparams.params[ip++]);
     375                    buf = Arrays.copyOf(buf, (buf.length + next.length));
     376                    System.arraycopy(next, 0, buf, (buf.length - next.length), next.length);
     377                }
     378            }
     379            buf = Arrays.copyOf(buf, (buf.length + 1));
     380            buf[buf.length-1] = 0x1e;
     381            int flen = buf.length - offset;
     382            index.add(new Index(sfparams.field.toString().getBytes(), flen, offset));
     383            maxlen = (flen > maxlen) ? flen : maxlen;
     384            offset += flen;
     385        }
     386        int mlen = String.valueOf(maxlen).length();
     387        String ffmt = "%0" + mlen + "d";
     388        int olen = String.valueOf(offset).length();
     389        String ofmt = "%0" + olen + "d";
     390        int ilen = 4 + mlen + olen;
     391        int isiz = (ilen * index.size()) + 1;
     392        byte[] ibuf = new byte[isiz];
     393        int i = 0;
     394        for (Index item : index) {
     395            for (byte ch : item.field) {
     396                ibuf[i++] = ch;
     397            }
     398            byte[] digits = String.format(ffmt, item.length).getBytes();
     399            for (byte ch : digits) {
     400                ibuf[i++] = ch;
     401            }
     402            digits = String.format(ofmt, item.offset).getBytes();
     403            for (byte ch : digits) {
     404                ibuf[i++] = ch;
     405            }
     406        }
     407        ibuf[i] = 0x1e;
     408        byte[] fbuf = Arrays.copyOf(leader, (leader.length + ibuf.length + buf.length));
     409        System.arraycopy(ibuf, 0, fbuf, leader.length, ibuf.length);
     410        System.arraycopy(buf, 0, fbuf, (leader.length + ibuf.length), buf.length);
     411        fbuf[20] = (byte) (mlen + 0x30);
     412        fbuf[21] = (byte) (olen + 0x30);
     413        System.arraycopy(String.format("%05d", fbuf.length).getBytes(), 0, fbuf, 0, 5);
     414        System.arraycopy(String.format("%05d", (leader.length + ibuf.length)).getBytes(), 0, fbuf, 12, 5);
     415        asc = false;
     416        return fbuf;
     417    }
     418
     419    enum Prims { N, P, L, A, PA, PL, LA, PLA }
     420
     421    private static final EnumMap<Obj, Prims> S57prims = new EnumMap<>(Obj.class);
     422    static {
     423        S57prims.put(Obj.UNKOBJ, Prims.PLA); S57prims.put(Obj.M_COVR, Prims.A); S57prims.put(Obj.M_NSYS, Prims.A); S57prims.put(Obj.AIRARE, Prims.PA);
     424        S57prims.put(Obj.ACHBRT, Prims.PA); S57prims.put(Obj.ACHARE, Prims.PA); S57prims.put(Obj.BCNCAR, Prims.P); S57prims.put(Obj.BCNISD, Prims.P);
     425        S57prims.put(Obj.BCNLAT, Prims.P); S57prims.put(Obj.BCNSAW, Prims.P); S57prims.put(Obj.BCNSPP, Prims.P); S57prims.put(Obj.BERTHS, Prims.PLA);
     426        S57prims.put(Obj.BRIDGE, Prims.PLA); S57prims.put(Obj.BUISGL, Prims.PA); S57prims.put(Obj.BUAARE, Prims.PA); S57prims.put(Obj.BOYCAR, Prims.P);
     427        S57prims.put(Obj.BOYINB, Prims.P); S57prims.put(Obj.BOYISD, Prims.P); S57prims.put(Obj.BOYLAT, Prims.P); S57prims.put(Obj.BOYSAW, Prims.P);
     428        S57prims.put(Obj.BOYSPP, Prims.P); S57prims.put(Obj.CBLARE, Prims.A); S57prims.put(Obj.CBLOHD, Prims.L); S57prims.put(Obj.CBLSUB, Prims.L);
     429        S57prims.put(Obj.CANALS, Prims.A); S57prims.put(Obj.CTSARE, Prims.PA); S57prims.put(Obj.CAUSWY, Prims.LA); S57prims.put(Obj.CTNARE, Prims.PA);
     430        S57prims.put(Obj.CHKPNT, Prims.PA); S57prims.put(Obj.CGUSTA, Prims.P); S57prims.put(Obj.COALNE, Prims.L); S57prims.put(Obj.CONZNE, Prims.A);
     431        S57prims.put(Obj.COSARE, Prims.A); S57prims.put(Obj.CTRPNT, Prims.P); S57prims.put(Obj.CONVYR, Prims.LA); S57prims.put(Obj.CRANES, Prims.PA);
     432        S57prims.put(Obj.CURENT, Prims.P); S57prims.put(Obj.CUSZNE, Prims.A); S57prims.put(Obj.DAMCON, Prims.LA); S57prims.put(Obj.DAYMAR, Prims.P);
     433        S57prims.put(Obj.DWRTCL, Prims.L); S57prims.put(Obj.DWRTPT, Prims.A); S57prims.put(Obj.DEPARE, Prims.A); S57prims.put(Obj.DEPCNT, Prims.L);
     434        S57prims.put(Obj.DISMAR, Prims.P); S57prims.put(Obj.DOCARE, Prims.A); S57prims.put(Obj.DRGARE, Prims.A); S57prims.put(Obj.DRYDOC, Prims.A);
     435        S57prims.put(Obj.DMPGRD, Prims.PA); S57prims.put(Obj.DYKCON, Prims.L); S57prims.put(Obj.EXEZNE, Prims.A); S57prims.put(Obj.FAIRWY, Prims.A);
     436        S57prims.put(Obj.FNCLNE, Prims.L); S57prims.put(Obj.FERYRT, Prims.LA); S57prims.put(Obj.FSHZNE, Prims.A); S57prims.put(Obj.FSHFAC, Prims.PLA);
     437        S57prims.put(Obj.FSHGRD, Prims.A); S57prims.put(Obj.FLODOC, Prims.A); S57prims.put(Obj.FOGSIG, Prims.P); S57prims.put(Obj.FORSTC, Prims.PLA);
     438        S57prims.put(Obj.FRPARE, Prims.A); S57prims.put(Obj.GATCON, Prims.PLA); S57prims.put(Obj.GRIDRN, Prims.PA); S57prims.put(Obj.HRBARE, Prims.A);
     439        S57prims.put(Obj.HRBFAC, Prims.PA); S57prims.put(Obj.HULKES, Prims.PA); S57prims.put(Obj.ICEARE, Prims.A); S57prims.put(Obj.ICNARE, Prims.PA);
     440        S57prims.put(Obj.ISTZNE, Prims.A); S57prims.put(Obj.LAKARE, Prims.A); S57prims.put(Obj.LNDARE, Prims.PLA); S57prims.put(Obj.LNDELV, Prims.PL);
     441        S57prims.put(Obj.LNDRGN, Prims.PA); S57prims.put(Obj.LNDMRK, Prims.PLA); S57prims.put(Obj.LIGHTS, Prims.P); S57prims.put(Obj.LITFLT, Prims.P);
     442        S57prims.put(Obj.LITVES, Prims.P); S57prims.put(Obj.LOCMAG, Prims.PLA); S57prims.put(Obj.LOKBSN, Prims.A); S57prims.put(Obj.LOGPON, Prims.PA);
     443        S57prims.put(Obj.MAGVAR, Prims.PLA); S57prims.put(Obj.MARCUL, Prims.PLA); S57prims.put(Obj.MIPARE, Prims.PA); S57prims.put(Obj.MORFAC, Prims.PLA);
     444        S57prims.put(Obj.MPAARE, Prims.PA); S57prims.put(Obj.NAVLNE, Prims.L); S57prims.put(Obj.OBSTRN, Prims.PLA); S57prims.put(Obj.OFSPLF, Prims.PA);
     445        S57prims.put(Obj.OSPARE, Prims.A); S57prims.put(Obj.OILBAR, Prims.L); S57prims.put(Obj.PILPNT, Prims.P); S57prims.put(Obj.PILBOP, Prims.PA);
     446        S57prims.put(Obj.PIPARE, Prims.PA); S57prims.put(Obj.PIPOHD, Prims.L); S57prims.put(Obj.PIPSOL, Prims.PL); S57prims.put(Obj.PONTON, Prims.LA);
     447        S57prims.put(Obj.PRCARE, Prims.PA); S57prims.put(Obj.PRDARE, Prims.PA); S57prims.put(Obj.PYLONS, Prims.PA); S57prims.put(Obj.RADLNE, Prims.L);
     448        S57prims.put(Obj.RADRNG, Prims.A); S57prims.put(Obj.RADRFL, Prims.P); S57prims.put(Obj.RADSTA, Prims.P); S57prims.put(Obj.RTPBCN, Prims.P);
     449        S57prims.put(Obj.RDOCAL, Prims.PL); S57prims.put(Obj.RDOSTA, Prims.P); S57prims.put(Obj.RAILWY, Prims.L); S57prims.put(Obj.RAPIDS, Prims.PLA);
     450        S57prims.put(Obj.RCRTCL, Prims.L); S57prims.put(Obj.RECTRC, Prims.LA); S57prims.put(Obj.RCTLPT, Prims.PA); S57prims.put(Obj.RSCSTA, Prims.P);
     451        S57prims.put(Obj.RESARE, Prims.A); S57prims.put(Obj.RETRFL, Prims.P); S57prims.put(Obj.RIVERS, Prims.LA); S57prims.put(Obj.ROADWY, Prims.PLA);
     452        S57prims.put(Obj.RUNWAY, Prims.PLA); S57prims.put(Obj.SNDWAV, Prims.PLA); S57prims.put(Obj.SEAARE, Prims.PA); S57prims.put(Obj.SPLARE, Prims.PA);
     453        S57prims.put(Obj.SBDARE, Prims.PLA); S57prims.put(Obj.SLCONS, Prims.PLA); S57prims.put(Obj.SISTAT, Prims.P); S57prims.put(Obj.SISTAW, Prims.P);
     454        S57prims.put(Obj.SILTNK, Prims.PA); S57prims.put(Obj.SLOTOP, Prims.L); S57prims.put(Obj.SLOGRD, Prims.PA); S57prims.put(Obj.SMCFAC, Prims.PA);
     455        S57prims.put(Obj.SOUNDG, Prims.P); S57prims.put(Obj.SPRING, Prims.P); S57prims.put(Obj.STSLNE, Prims.L); S57prims.put(Obj.SUBTLN, Prims.A);
     456        S57prims.put(Obj.SWPARE, Prims.A); S57prims.put(Obj.TESARE, Prims.A); S57prims.put(Obj.TS_PRH, Prims.PA); S57prims.put(Obj.TS_PNH, Prims.PA);
     457        S57prims.put(Obj.TS_PAD, Prims.PA); S57prims.put(Obj.TS_TIS, Prims.PA); S57prims.put(Obj.T_HMON, Prims.PA); S57prims.put(Obj.T_NHMN, Prims.PA);
     458        S57prims.put(Obj.T_TIMS, Prims.PA); S57prims.put(Obj.TIDEWY, Prims.LA); S57prims.put(Obj.TOPMAR, Prims.P); S57prims.put(Obj.TSELNE, Prims.LA);
     459        S57prims.put(Obj.TSSBND, Prims.L); S57prims.put(Obj.TSSCRS, Prims.A); S57prims.put(Obj.TSSLPT, Prims.A); S57prims.put(Obj.TSSRON, Prims.A);
     460        S57prims.put(Obj.TSEZNE, Prims.A); S57prims.put(Obj.TUNNEL, Prims.LA); S57prims.put(Obj.TWRTPT, Prims.A); S57prims.put(Obj.UWTROC, Prims.P);
     461        S57prims.put(Obj.UNSARE, Prims.A); S57prims.put(Obj.VEGATN, Prims.PLA); S57prims.put(Obj.WATTUR, Prims.PLA); S57prims.put(Obj.WATFAL, Prims.PL);
     462        S57prims.put(Obj.WEDKLP, Prims.PA); S57prims.put(Obj.WRECKS, Prims.PA); S57prims.put(Obj.TS_FEB, Prims.PA);
     463        S57prims.put(Obj.NOTMRK, Prims.P); S57prims.put(Obj.WTWAXS, Prims.L); S57prims.put(Obj.WTWPRF, Prims.L); S57prims.put(Obj.BUNSTA, Prims.PA);
     464        S57prims.put(Obj.COMARE, Prims.A); S57prims.put(Obj.HRBBSN, Prims.A); S57prims.put(Obj.LKBSPT, Prims.A); S57prims.put(Obj.PRTARE, Prims.A);
     465        S57prims.put(Obj.REFDMP, Prims.P); S57prims.put(Obj.TERMNL, Prims.PA); S57prims.put(Obj.TRNBSN, Prims.PA); S57prims.put(Obj.WTWARE, Prims.A);
     466        S57prims.put(Obj.WTWGAG, Prims.PA); S57prims.put(Obj.TISDGE, Prims.N); S57prims.put(Obj.VEHTRF, Prims.PA); S57prims.put(Obj.EXCNST, Prims.PA);
     467        S57prims.put(Obj.LG_SDM, Prims.A); S57prims.put(Obj.LG_VSP, Prims.A); S57prims.put(Obj.LITMAJ, Prims.P); S57prims.put(Obj.LITMIN, Prims.P);
     468    }
     469
     470    public static void S57geoms(S57map map) {
     471        for (ArrayList<Feature> list : map.features.values()) {
     472            for (Feature feature : list) {
     473                switch (S57prims.get(feature.type)) {
     474                case N:
     475                    break;
     476                case P:
     477                    if (feature.geom.prim != Pflag.POINT) {
     478                        //                        Snode node = feature.geom.centre;
     479                        //                        node.flg = Nflag.ISOL;
     480                        //                        map.nodes.put(++map.xref, node);
     481                        //                        feature.geom = map.new Geom(Pflag.POINT);
     482                        //                        feature.geom.centre = node;
     483                        //                        feature.geom.elems.add(map.new Prim(map.xref));
     484                    }
     485                    break;
     486                case L:
     487                    break;
     488                case A:
     489                    break;
     490                case PA:
     491                    break;
     492                case PL:
     493                    break;
     494                case LA:
     495                    if (feature.geom.prim == Pflag.POINT) {
     496                        //                        list.remove(feature);
     497                    }
     498                    break;
     499                case PLA:
     500                    // No changes needed
     501                    break;
     502                }
     503            }
     504        }
     505    }
    501506}
  • applications/editors/josm/plugins/seachart/src/s57/S57dec.java

    r32380 r32394  
    1313import java.io.IOException;
    1414
    15 import s57.S57dat.*;
    16 import s57.S57map.*;
     15import s57.S57dat.S57field;
     16import s57.S57dat.S57subf;
     17import s57.S57map.Nflag;
    1718
    1819public class S57dec { // S57 ENC file input & map conversion
    19 
    20         public static void decodeChart(FileInputStream in, S57map map) throws IOException {
    21                 S57dat.rnum = 0;
    22                 byte[] leader = new byte[24];
    23                 byte[] record = new byte[0];
    24                 boolean ddr = false;
    25                 int length = 0;
    26                 int fields = 0;;
    27                 int mapfl, mapfp, mapts, entry;
    28                 String tag;
    29                 int len;
    30                 int pos;
    31                 boolean inFeature = false;
    32 
    33                 double comf = 1;
    34                 double somf = 1;
    35                 long name = 0;
    36                 S57map.Nflag nflag = Nflag.ANON;
    37                 S57map.Pflag pflag = S57map.Pflag.NOSP;
    38                 long objl = 0;
    39                
    40                 while (in.read(leader) == 24) {
    41                         try {
    42                         length = Integer.parseInt(new String(leader, 0, 5)) - 24;
    43                         record = new byte[length];
    44                         ddr = (leader[6] == 'L');
    45                         fields = Integer.parseInt(new String(leader, 12, 5)) - 24;
    46                         } catch (Exception e) {
    47                                 System.err.println("Invalid file format - Encrypted/compressed ENC file?");
    48                                 System.exit(-1);
    49                         }
    50                         mapfl = leader[20] - '0';
    51                         mapfp = leader[21] - '0';
    52                         mapts = leader[23] - '0';
    53                         entry = mapfl + mapfp + mapts;
    54                         if (in.read(record) != length)
    55                                 break;
    56                         for (int idx = 0; idx < fields-1; idx += entry) {
    57                                 tag = new String(record, idx, mapts);
    58                                 len = Integer.parseInt(new String(record, idx+mapts, mapfl));
    59                                 pos = Integer.parseInt(new String(record, idx+mapts+mapfl, mapfp));
    60                                 if (!ddr) {
    61                                         switch (tag.toString()) {
    62                                         case "0001":
    63                                                 int i8rn = ((Long) S57dat.decSubf(record, fields + pos, S57field.I8RI, S57subf.I8RN)).intValue();
    64 //                                              if (i8rn != ++S57dat.rnum) {
    65 //                                                      System.err.println("Out of order record ID");
    66 //                                                      in.close();
    67 //                                                      System.exit(-1);
    68 //                                              }
    69                                                 break;
    70                                         case "DSSI":
    71                                                 S57dat.decSubf(record, fields + pos, S57field.DSSI, S57subf.AALL);
    72                                                 S57dat.decSubf(S57subf.NALL);
    73                                                 break;
    74                                         case "DSPM":
    75                                                 comf = (double) (Long) S57dat.decSubf(record, fields + pos, S57field.DSPM, S57subf.COMF);
    76                                                 somf = (double) (Long) S57dat.decSubf(S57subf.SOMF);
    77                                                 break;
    78                                         case "FRID":
    79                                                 inFeature = true;
    80                                                 switch (((Long)S57dat.decSubf(record, fields + pos, S57field.FRID, S57subf.PRIM)).intValue()) {
    81                                                 case 1:
    82                                                         pflag = S57map.Pflag.POINT;
    83                                                         break;
    84                                                 case 2:
    85                                                         pflag = S57map.Pflag.LINE;
    86                                                         break;
    87                                                 case 3:
    88                                                         pflag = S57map.Pflag.AREA;
    89                                                         break;
    90                                                 default:
    91                                                         pflag = S57map.Pflag.NOSP;
    92                                                 }
    93                                                 objl = (Long)S57dat.decSubf(S57subf.OBJL);
    94                                                 break;
    95                                         case "FOID":
    96                                                 name = (long) S57dat.decSubf(record, fields + pos, S57field.LNAM, S57subf.LNAM);
    97                                                 map.newFeature(name, pflag, objl);
    98                                                 break;
    99                                         case "ATTF":
    100                                                 S57dat.setField(record, fields + pos, S57field.ATTF, len);
    101                                                 do {
    102                                                         long attl = (Long) S57dat.decSubf(S57subf.ATTL);
    103                                                         String atvl = ((String) S57dat.decSubf(S57subf.ATVL)).trim();
    104                                                         if (!atvl.isEmpty()) {
    105                                                                 map.newAtt(attl, atvl);
    106                                                         }
    107                                                 } while (S57dat.more());
    108                                                 break;
    109                                         case "FFPT":
    110                                                 S57dat.setField(record, fields + pos, S57field.FFPT, len);
    111                                                 do {
    112                                                         name = (long) S57dat.decSubf(S57subf.LNAM);
    113                                                         int rind = ((Long) S57dat.decSubf(S57subf.RIND)).intValue();
    114                                                         S57dat.decSubf(S57subf.COMT);
    115                                                         map.refObj(name, rind);
    116                                                 } while (S57dat.more());
    117                                                 break;
    118                                         case "FSPT":
    119                                                 S57dat.setField(record, fields + pos, S57field.FSPT, len);
    120                                                 do {
    121                                                         name = (long) S57dat.decSubf(S57subf.NAME) << 16;
    122                                                         map.newPrim(name, (Long) S57dat.decSubf(S57subf.ORNT), (Long) S57dat.decSubf(S57subf.USAG));
    123                                                         S57dat.decSubf(S57subf.MASK);
    124                                                 } while (S57dat.more());
    125                                                 break;
    126                                         case "VRID":
    127                                                 inFeature = false;
    128                                                 name = (long) (Long)S57dat.decSubf(record, fields + pos, S57field.VRID, S57subf.RCNM);
    129                                                 switch ((int) name) {
    130                                                 case 110:
    131                                                         nflag = Nflag.ISOL;
    132                                                         break;
    133                                                 case 120:
    134                                                         nflag = Nflag.CONN;
    135                                                         break;
    136                                                 default:
    137                                                         nflag = Nflag.ANON;
    138                                                         break;
    139                                                 }
    140                                                 name <<= 32;
    141                                                 name += (long) S57dat.decSubf(S57subf.RCID);
    142                                                 name <<= 16;
    143                                                 if (nflag == Nflag.ANON) {
    144                                                         map.newEdge(name);
    145                                                 }
    146                                                 break;
    147                                         case "VRPT":
    148                                                 S57dat.setField(record, fields + pos, S57field.VRPT, len);
    149                                                 do {
    150                                                         long conn = (Long) S57dat.decSubf(S57subf.NAME) << 16;
    151                                                         int topi = ((Long) S57dat.decSubf(S57subf.TOPI)).intValue();
    152                                                         map.addConn(conn, topi);
    153                                                         S57dat.decSubf(S57subf.MASK);
    154                                                 } while (S57dat.more());
    155                                                 break;
    156                                         case "SG2D":
    157                                                 S57dat.setField(record, fields + pos, S57field.SG2D, len);
    158                                                 do {
    159                                                         double lat = (double) ((Long) S57dat.decSubf(S57subf.YCOO)) / comf;
    160                                                         double lon = (double) ((Long) S57dat.decSubf(S57subf.XCOO)) / comf;
    161                                                         if (nflag == Nflag.ANON) {
    162                                                                 map.newNode(++name, lat, lon, nflag);
    163                                                         } else {
    164                                                                 map.newNode(name, lat, lon, nflag);
    165                                                         }
    166                                                         lat = Math.toRadians(lat);
    167                                                         lon = Math.toRadians(lon);
    168                                                         if (lat < map.bounds.minlat)
    169                                                                 map.bounds.minlat = lat;
    170                                                         if (lat > map.bounds.maxlat)
    171                                                                 map.bounds.maxlat = lat;
    172                                                         if (lon < map.bounds.minlon)
    173                                                                 map.bounds.minlon = lon;
    174                                                         if (lon > map.bounds.maxlon)
    175                                                                 map.bounds.maxlon = lon;
    176                                                 } while (S57dat.more());
    177                                                 break;
    178                                         case "SG3D":
    179                                                 S57dat.setField(record, fields + pos, S57field.SG3D, len);
    180                                                 do {
    181                                                         double lat = (double) ((Long) S57dat.decSubf(S57subf.YCOO)) / comf;
    182                                                         double lon = (double) ((Long) S57dat.decSubf(S57subf.XCOO)) / comf;
    183                                                         double depth = (double) ((Long) S57dat.decSubf(S57subf.VE3D)) / somf;
    184                                                         map.newNode(name++, lat, lon, depth);
    185                                                         lat = Math.toRadians(lat);
    186                                                         lon = Math.toRadians(lon);
    187                                                         if (lat < map.bounds.minlat)
    188                                                                 map.bounds.minlat = lat;
    189                                                         if (lat > map.bounds.maxlat)
    190                                                                 map.bounds.maxlat = lat;
    191                                                         if (lon < map.bounds.minlon)
    192                                                                 map.bounds.minlon = lon;
    193                                                         if (lon > map.bounds.maxlon)
    194                                                                 map.bounds.maxlon = lon;
    195                                                 } while (S57dat.more());
    196                                                 break;
    197                                         default:
    198                                                 break;
    199                                         }
    200                                 }
    201                                 if (inFeature) {
    202                                         map.endFeature();
    203                                         inFeature = false;
    204                                 }
    205                         }
    206                 }
    207                 map.endFile();
    208                 in.close();
    209                
    210                 return;
    211         }
    212        
     20    // CHECKSTYLE.OFF: LineLength
     21
     22    public static void decodeChart(FileInputStream in, S57map map) throws IOException {
     23        S57dat.rnum = 0;
     24        byte[] leader = new byte[24];
     25        byte[] record = new byte[0];
     26        boolean ddr = false;
     27        int length = 0;
     28        int fields = 0;;
     29        int mapfl, mapfp, mapts, entry;
     30        String tag;
     31        int len;
     32        int pos;
     33        boolean inFeature = false;
     34
     35        double comf = 1;
     36        double somf = 1;
     37        long name = 0;
     38        S57map.Nflag nflag = Nflag.ANON;
     39        S57map.Pflag pflag = S57map.Pflag.NOSP;
     40        long objl = 0;
     41
     42        while (in.read(leader) == 24) {
     43            try {
     44                length = Integer.parseInt(new String(leader, 0, 5)) - 24;
     45                record = new byte[length];
     46                ddr = (leader[6] == 'L');
     47                fields = Integer.parseInt(new String(leader, 12, 5)) - 24;
     48            } catch (Exception e) {
     49                System.err.println("Invalid file format - Encrypted/compressed ENC file?");
     50                System.exit(-1);
     51            }
     52            mapfl = leader[20] - '0';
     53            mapfp = leader[21] - '0';
     54            mapts = leader[23] - '0';
     55            entry = mapfl + mapfp + mapts;
     56            if (in.read(record) != length)
     57                break;
     58            for (int idx = 0; idx < fields-1; idx += entry) {
     59                tag = new String(record, idx, mapts);
     60                len = Integer.parseInt(new String(record, idx+mapts, mapfl));
     61                pos = Integer.parseInt(new String(record, idx+mapts+mapfl, mapfp));
     62                if (!ddr) {
     63                    switch (tag.toString()) {
     64                    case "0001":
     65                        int i8rn = ((Long) S57dat.decSubf(record, fields + pos, S57field.I8RI, S57subf.I8RN)).intValue();
     66                        //                        if (i8rn != ++S57dat.rnum) {
     67                        //                            System.err.println("Out of order record ID");
     68                        //                            in.close();
     69                        //                            System.exit(-1);
     70                        //                        }
     71                        break;
     72                    case "DSSI":
     73                        S57dat.decSubf(record, fields + pos, S57field.DSSI, S57subf.AALL);
     74                        S57dat.decSubf(S57subf.NALL);
     75                        break;
     76                    case "DSPM":
     77                        comf = (Long) S57dat.decSubf(record, fields + pos, S57field.DSPM, S57subf.COMF);
     78                        somf = (Long) S57dat.decSubf(S57subf.SOMF);
     79                        break;
     80                    case "FRID":
     81                        inFeature = true;
     82                        switch (((Long) S57dat.decSubf(record, fields + pos, S57field.FRID, S57subf.PRIM)).intValue()) {
     83                        case 1:
     84                            pflag = S57map.Pflag.POINT;
     85                            break;
     86                        case 2:
     87                            pflag = S57map.Pflag.LINE;
     88                            break;
     89                        case 3:
     90                            pflag = S57map.Pflag.AREA;
     91                            break;
     92                        default:
     93                            pflag = S57map.Pflag.NOSP;
     94                        }
     95                        objl = (Long) S57dat.decSubf(S57subf.OBJL);
     96                        break;
     97                    case "FOID":
     98                        name = (long) S57dat.decSubf(record, fields + pos, S57field.LNAM, S57subf.LNAM);
     99                        map.newFeature(name, pflag, objl);
     100                        break;
     101                    case "ATTF":
     102                        S57dat.setField(record, fields + pos, S57field.ATTF, len);
     103                        do {
     104                            long attl = (Long) S57dat.decSubf(S57subf.ATTL);
     105                            String atvl = ((String) S57dat.decSubf(S57subf.ATVL)).trim();
     106                            if (!atvl.isEmpty()) {
     107                                map.newAtt(attl, atvl);
     108                            }
     109                        } while (S57dat.more());
     110                        break;
     111                    case "FFPT":
     112                        S57dat.setField(record, fields + pos, S57field.FFPT, len);
     113                        do {
     114                            name = (long) S57dat.decSubf(S57subf.LNAM);
     115                            int rind = ((Long) S57dat.decSubf(S57subf.RIND)).intValue();
     116                            S57dat.decSubf(S57subf.COMT);
     117                            map.refObj(name, rind);
     118                        } while (S57dat.more());
     119                        break;
     120                    case "FSPT":
     121                        S57dat.setField(record, fields + pos, S57field.FSPT, len);
     122                        do {
     123                            name = (long) S57dat.decSubf(S57subf.NAME) << 16;
     124                            map.newPrim(name, (Long) S57dat.decSubf(S57subf.ORNT), (Long) S57dat.decSubf(S57subf.USAG));
     125                            S57dat.decSubf(S57subf.MASK);
     126                        } while (S57dat.more());
     127                        break;
     128                    case "VRID":
     129                        inFeature = false;
     130                        name = (Long) S57dat.decSubf(record, fields + pos, S57field.VRID, S57subf.RCNM);
     131                        switch ((int) name) {
     132                        case 110:
     133                            nflag = Nflag.ISOL;
     134                            break;
     135                        case 120:
     136                            nflag = Nflag.CONN;
     137                            break;
     138                        default:
     139                            nflag = Nflag.ANON;
     140                            break;
     141                        }
     142                        name <<= 32;
     143                        name += (long) S57dat.decSubf(S57subf.RCID);
     144                        name <<= 16;
     145                        if (nflag == Nflag.ANON) {
     146                            map.newEdge(name);
     147                        }
     148                        break;
     149                    case "VRPT":
     150                        S57dat.setField(record, fields + pos, S57field.VRPT, len);
     151                        do {
     152                            long conn = (Long) S57dat.decSubf(S57subf.NAME) << 16;
     153                            int topi = ((Long) S57dat.decSubf(S57subf.TOPI)).intValue();
     154                            map.addConn(conn, topi);
     155                            S57dat.decSubf(S57subf.MASK);
     156                        } while (S57dat.more());
     157                        break;
     158                    case "SG2D":
     159                        S57dat.setField(record, fields + pos, S57field.SG2D, len);
     160                        do {
     161                            double lat = (double) ((Long) S57dat.decSubf(S57subf.YCOO)) / comf;
     162                            double lon = (double) ((Long) S57dat.decSubf(S57subf.XCOO)) / comf;
     163                            if (nflag == Nflag.ANON) {
     164                                map.newNode(++name, lat, lon, nflag);
     165                            } else {
     166                                map.newNode(name, lat, lon, nflag);
     167                            }
     168                            lat = Math.toRadians(lat);
     169                            lon = Math.toRadians(lon);
     170                            if (lat < map.bounds.minlat)
     171                                map.bounds.minlat = lat;
     172                            if (lat > map.bounds.maxlat)
     173                                map.bounds.maxlat = lat;
     174                            if (lon < map.bounds.minlon)
     175                                map.bounds.minlon = lon;
     176                            if (lon > map.bounds.maxlon)
     177                                map.bounds.maxlon = lon;
     178                        } while (S57dat.more());
     179                        break;
     180                    case "SG3D":
     181                        S57dat.setField(record, fields + pos, S57field.SG3D, len);
     182                        do {
     183                            double lat = (double) ((Long) S57dat.decSubf(S57subf.YCOO)) / comf;
     184                            double lon = (double) ((Long) S57dat.decSubf(S57subf.XCOO)) / comf;
     185                            double depth = (double) ((Long) S57dat.decSubf(S57subf.VE3D)) / somf;
     186                            map.newNode(name++, lat, lon, depth);
     187                            lat = Math.toRadians(lat);
     188                            lon = Math.toRadians(lon);
     189                            if (lat < map.bounds.minlat)
     190                                map.bounds.minlat = lat;
     191                            if (lat > map.bounds.maxlat)
     192                                map.bounds.maxlat = lat;
     193                            if (lon < map.bounds.minlon)
     194                                map.bounds.minlon = lon;
     195                            if (lon > map.bounds.maxlon)
     196                                map.bounds.maxlon = lon;
     197                        } while (S57dat.more());
     198                        break;
     199                    default:
     200                        break;
     201                    }
     202                }
     203                if (inFeature) {
     204                    map.endFeature();
     205                    inFeature = false;
     206                }
     207            }
     208        }
     209        map.endFile();
     210        in.close();
     211
     212        return;
     213    }
     214
    213215}
  • applications/editors/josm/plugins/seachart/src/s57/S57enc.java

    r31846 r32394  
    2121import java.util.zip.CRC32;
    2222
    23 import s57.S57obj.*;
     23import s57.S57att.Att;
     24import s57.S57dat.Fparams;
     25import s57.S57dat.S57field;
     26import s57.S57map.AttMap;
     27import s57.S57map.Feature;
     28import s57.S57map.Nflag;
     29import s57.S57map.ObjTab;
     30import s57.S57map.Pflag;
     31import s57.S57map.Prim;
     32import s57.S57obj.Obj;
    2433import s57.S57val.AttVal;
    25 import s57.S57att.Att;
    26 import s57.S57dat.*;
    27 import s57.S57map.*;
    2834
    2935public class S57enc { // S57 ENC file generation
    30 
    31         private static final byte[] header = {
    32                
    33                 '0', '1', '5', '7', '6', '3', 'L', 'E', '1', ' ', '0', '9', '0', '0', '2', '0', '1', ' ', '!', ' ', '3', '4', '0', '4', // Leader
    34                 '0', '0', '0', '0', '1', '2', '3', '0', '0', '0', '0', '0', '0', '0', '1', '0', '4', '7', '0', '1', '2', '3',
    35                 'D', 'S', 'I', 'D', '1', '5', '9', '0', '1', '7', '0', 'D', 'S', 'S', 'I', '1', '1', '3', '0', '3', '2', '9',
    36                 'D', 'S', 'P', 'M', '1', '3', '0', '0', '4', '4', '2', 'F', 'R', 'I', 'D', '1', '0', '0', '0', '5', '7', '2',
    37                 'F', 'O', 'I', 'D', '0', '7', '0', '0', '6', '7', '2', 'A', 'T', 'T', 'F', '0', '5', '9', '0', '7', '4', '2',
    38                 'N', 'A', 'T', 'F', '0', '6', '8', '0', '8', '0', '1', 'F', 'F', 'P', 'T', '0', '8', '6', '0', '8', '6', '9',
    39                 'F', 'S', 'P', 'T', '0', '9', '0', '0', '9', '5', '5', 'V', 'R', 'I', 'D', '0', '7', '8', '1', '0', '4', '5',
    40                 'A', 'T', 'T', 'V', '0', '5', '8', '1', '1', '2', '3', 'V', 'R', 'P', 'T', '0', '7', '6', '1', '1', '8', '1',
    41                 'S', 'G', '2', 'D', '0', '4', '8', '1', '2', '5', '7', 'S', 'G', '3', 'D', '0', '7', '0', '1', '3', '0', '5', 0x1e,
    42                 // File control field
    43                 '0', '0', '0', '0', ';', '&', ' ', ' ', ' ', 0x1f,
    44                 '0', '0', '0', '1', 'D', 'S', 'I', 'D', 'D', 'S', 'I', 'D', 'D', 'S', 'S', 'I', '0', '0', '0', '1', 'D', 'S', 'P', 'M',
    45                 '0', '0', '0', '1', 'F', 'R', 'I', 'D', 'F', 'R', 'I', 'D', 'F', 'O', 'I', 'D', 'F', 'R', 'I', 'D', 'A', 'T', 'T', 'F',
    46                 'F', 'R', 'I', 'D', 'N', 'A', 'T', 'F', 'F', 'R', 'I', 'D', 'F', 'F', 'P', 'T', 'F', 'R', 'I', 'D', 'F', 'S', 'P', 'T',
    47                 '0', '0', '0', '1', 'V', 'R', 'I', 'D', 'V', 'R', 'I', 'D', 'A', 'T', 'T', 'V', 'V', 'R', 'I', 'D', 'V', 'R', 'P', 'T',
    48                 'V', 'R', 'I', 'D', 'S', 'G', '2', 'D', 'V', 'R', 'I', 'D', 'S', 'G', '3', 'D', 0x1e,
    49                 // Record identifier fields
    50                 '0', '5', '0', '0', ';', '&', ' ', ' ', ' ', 'I', 'S', 'O', '/', 'I', 'E', 'C', ' ', '8', '2', '1', '1', ' ',
    51                 'R', 'e', 'c', 'o', 'r', 'd', ' ', 'I', 'd', 'e', 'n', 't', 'i', 'f', 'i', 'e', 'r', 0x1f, 0x1f, '(', 'b', '1', '2', ')', 0x1e,
    52                 '1', '6', '0', '0', ';', '&', ' ', ' ', ' ', 'D', 'a', 't', 'a', ' ', 'S', 'e', 't', ' ', 'I', 'd', 'e', 'n', 't', 'i',
    53                 'f', 'i', 'c', 'a', 't', 'i', 'o', 'n', 0x1f, 'R', 'C', 'N', 'M', '!', 'R', 'C', 'I', 'D', '!', 'E', 'X', 'P', 'P', '!',
    54                 'I', 'N', 'T', 'U', '!', 'D', 'S', 'N', 'M', '!', 'E', 'D', 'T', 'N', '!', 'U', 'P', 'D', 'N', '!', 'U', 'A', 'D', 'T',
    55                 '!', 'I', 'S', 'D', 'T', '!', 'S', 'T', 'E', 'D', '!', 'P', 'R', 'S', 'P', '!', 'P', 'S', 'D', 'N', '!', 'P', 'R', 'E',
    56                 'D', '!', 'P', 'R', 'O', 'F', '!', 'A', 'G', 'E', 'N', '!', 'C', 'O', 'M', 'T', 0x1f, '(', 'b', '1', '1', ',', 'b', '1',
    57                 '4', ',', '2', 'b', '1', '1', ',', '3', 'A', ',', '2', 'A', '(', '8', ')', ',', 'R', '(', '4', ')', ',', 'b', '1', '1',
    58                 ',', '2', 'A', ',', 'b', '1', '1', ',', 'b', '1', '2', ',', 'A', ')', 0x1e,
    59                 '1', '6', '0', '0', ';', '&', ' ', ' ', ' ', 'D', 'a', 't', 'a', ' ', 's', 'e', 't', ' ', 's', 't', 'r', 'u', 'c', 't',
    60                 'u', 'r', 'e', ' ', 'i', 'n', 'f', 'o', 'r', 'm', 'a', 't', 'i', 'o', 'n', ' ', 'f', 'i', 'e', 'l', 'd', 0x1f,
    61                 'D', 'S', 'T', 'R', '!', 'A', 'A', 'L', 'L', '!', 'N', 'A', 'L', 'L', '!', 'N', 'O', 'M', 'R', '!', 'N', 'O', 'C', 'R',
    62                 '!', 'N', 'O', 'G', 'R', '!', 'N', 'O', 'L', 'R', '!', 'N', 'O', 'I', 'N', '!', 'N', 'O', 'C', 'N', '!', 'N', 'O', 'E',
    63                 'D', '!', 'N', 'O', 'F', 'A', 0x1f, '(', '3', 'b', '1', '1', ',', '8', 'b', '1', '4', ')', 0x1e,
    64                 '1', '6', '0', '0', ';', '&', ' ', ' ', ' ', 'D', 'a', 't', 'a', ' ', 's', 'e', 't', ' ', 'p', 'a', 'r', 'a', 'm', 'e',
    65                 't', 'e', 'r', ' ', 'f', 'i', 'e', 'l', 'd', 0x1f, 'R', 'C', 'N', 'M', '!', 'R', 'C', 'I', 'D', '!', 'H', 'D', 'A', 'T',
    66                 '!', 'V', 'D', 'A', 'T', '!', 'S', 'D', 'A', 'T', '!', 'C', 'S', 'C', 'L', '!', 'D', 'U', 'N', 'I', '!', 'H', 'U', 'N',
    67                 'I', '!', 'P', 'U', 'N', 'I', '!', 'C', 'O', 'U', 'N', '!', 'C', 'O', 'M', 'F', '!', 'S', 'O', 'M', 'F', '!', 'C', 'O',
    68                 'M', 'T', 0x1f, '(', 'b', '1', '1', ',', 'b', '1', '4', ',', '3', 'b', '1', '1', ',', 'b', '1', '4', ',', '4', 'b', '1',
    69                 '1', ',', '2', 'b', '1', '4', ',', 'A', ')', 0x1e,
    70                 '1', '6', '0', '0', ';', '&', ' ', ' ', ' ', 'F', 'e', 'a', 't', 'u', 'r', 'e', ' ', 'r', 'e', 'c', 'o', 'r', 'd', ' ', 'i',
    71                 'd', 'e', 'n', 't', 'i', 'f', 'i', 'e', 'r', ' ', 'f', 'i', 'e', 'l', 'd', 0x1f, 'R', 'C', 'N', 'M', '!', 'R', 'C', 'I', 'D',
    72                 '!', 'P', 'R', 'I', 'M', '!', 'G', 'R', 'U', 'P', '!', 'O', 'B', 'J', 'L', '!', 'R', 'V', 'E', 'R', '!', 'R', 'U', 'I', 'N', 0x1f,
    73                 '(', 'b', '1', '1', ',', 'b', '1', '4', ',', '2', 'b', '1', '1', ',', '2', 'b', '1', '2', ',', 'b', '1', '1', ')', 0x1e,
    74                 '1', '6', '0', '0', ';', '&', ' ', ' ', ' ', 'F', 'e', 'a', 't', 'u', 'r', 'e', ' ', 'o', 'b', 'j', 'e', 'c', 't', ' ', 'i',
    75                 'd', 'e', 'n', 't', 'i', 'f', 'i', 'e', 'r', ' ', 'f', 'i', 'e', 'l', 'd', 0x1f, 'A', 'G', 'E', 'N', '!', 'F', 'I', 'D', 'N',
    76                 '!', 'F', 'I', 'D', 'S', 0x1f, '(', 'b', '1', '2', ',', 'b', '1', '4', ',', 'b', '1', '2', ')', 0x1e,
    77                 '2', '6', '0', '0', ';', '&', '-', 'A', ' ', 'F', 'e', 'a', 't', 'u', 'r', 'e', ' ', 'r', 'e', 'c', 'o', 'r', 'd', ' ', 'a',
    78                 't', 't', 'r', 'i', 'b', 'u', 't', 'e', ' ', 'f', 'i', 'e', 'l', 'd', 0x1f, '*', 'A', 'T', 'T', 'L', '!', 'A', 'T', 'V', 'L', 0x1f,
    79                 '(', 'b', '1', '2', ',', 'A', ')', 0x1e,
    80                 '2', '6', '0', '0', ';', '&', '-', 'A', ' ', 'F', 'e', 'a', 't', 'u', 'r', 'e', ' ', 'r', 'e', 'c', 'o', 'r', 'd', ' ', 'n', 'a',
    81                 't', 'i', 'o', 'n', 'a', 'l', ' ', 'a', 't', 't', 'r', 'i', 'b', 'u', 't', 'e', ' ', 'f', 'i', 'e', 'l', 'd', 0x1f, '*', 'A', 'T',
    82                 'T', 'L', '!', 'A', 'T', 'V', 'L', 0x1f, '(', 'b', '1', '2', ',', 'A', ')', 0x1e,
    83                 '2', '6', '0', '0', ';', '&', ' ', ' ', ' ', 'F', 'e', 'a', 't', 'u', 'r', 'e', ' ', 'r', 'e', 'c', 'o', 'r', 'd', ' ', 't', 'o',
    84                 ' ', 'f', 'e', 'a', 't', 'u', 'r', 'e', ' ', 'o', 'b', 'j', 'e', 'c', 't', ' ', 'p', 'o', 'i', 'n', 't', 'e', 'r', ' ', 'f', 'i',
    85                 'e', 'l', 'd', 0x1f, '*', 'L', 'N', 'A', 'M', '!', 'R', 'I', 'N', 'D', '!', 'C', 'O', 'M', 'T', 0x1f, '(', 'B', '(', '6', '4',
    86                 ')', ',', 'b', '1', '1', ',', 'A', ')', 0x1e,
    87                 '2', '6', '0', '0', ';', '&', ' ', ' ', ' ', 'F', 'e', 'a', 't', 'u', 'r', 'e', ' ', 'r', 'e', 'c', 'o', 'r', 'd', ' ', 't', 'o',
    88                 ' ', 's', 'p', 'a', 't', 'i', 'a', 'l', ' ', 'r', 'e', 'c', 'o', 'r', 'd', ' ', 'p', 'o', 'i', 'n', 't', 'e', 'r', ' ', 'f', 'i',
    89                 'e', 'l', 'd', 0x1f, '*', 'N', 'A', 'M', 'E', '!', 'O', 'R', 'N', 'T', '!', 'U', 'S', 'A', 'G', '!', 'M', 'A', 'S', 'K', 0x1f,
    90                 '(', 'B', '(', '4', '0', ')', ',', '3', 'b', '1', '1', ')', 0x1e,
    91                 '1', '6', '0', '0', ';', '&', ' ', ' ', ' ', 'V', 'e', 'c', 't', 'o', 'r', ' ', 'r', 'e', 'c', 'o', 'r', 'd', ' ', 'i', 'd', 'e',
    92                 'n', 't', 'i', 'f', 'i', 'e', 'r', ' ', 'f', 'i', 'e', 'l', 'd', 0x1f, 'R', 'C', 'N', 'M', '!', 'R', 'C', 'I', 'D', '!', 'R', 'V',
    93                 'E', 'R', '!', 'R', 'U', 'I', 'N', 0x1f, '(', 'b', '1', '1', ',', 'b', '1', '4', ',', 'b', '1', '2', ',', 'b', '1', '1', ')', 0x1e,
    94                 '2', '6', '0', '0', ';', '&', ' ', ' ', ' ', 'V', 'e', 'c', 't', 'o', 'r', ' ', 'r', 'e', 'c', 'o', 'r', 'd', ' ', 'a', 't', 't',
    95                 'r', 'i', 'b', 'u', 't', 'e', ' ', 'f', 'i', 'e', 'l', 'd', 0x1f, '*', 'A', 'T', 'T', 'L', '!', 'A', 'T', 'V', 'L', 0x1f, '(', 'b',
    96                 '1', '2', ',', 'A', ')', 0x1e,
    97                 '2', '6', '0', '0', ';', '&', ' ', ' ', ' ', 'V', 'e', 'c', 't', 'o', 'r', ' ', 'r', 'e', 'c', 'o', 'r', 'd', ' ', 'p', 'o', 'i',
    98                 'n', 't', 'e', 'r', ' ', 'f', 'i', 'e', 'l', 'd', 0x1f, '*', 'N', 'A', 'M', 'E', '!', 'O', 'R', 'N', 'T', '!', 'U', 'S', 'A', 'G',
    99                 '!', 'T', 'O', 'P', 'I', '!', 'M', 'A', 'S', 'K', 0x1f, '(', 'B', '(', '4', '0', ')', ',', '4', 'b', '1', '1', ')', 0x1e,
    100                 '2', '6', '0', '0', ';', '&', ' ', ' ', ' ', '2', '-', 'D', ' ', 'c', 'o', 'o', 'r', 'd', 'i', 'n', 'a', 't', 'e', ' ', 'f', 'i',
    101                 'e', 'l', 'd', 0x1f, '*', 'Y', 'C', 'O', 'O', '!', 'X', 'C', 'O', 'O', 0x1f, '(', '2', 'b', '2', '4', ')', 0x1e,
    102                 '2', '6', '0', '0', ';', '&', ' ', ' ', ' ', '3', '-', 'D', ' ', 'c', 'o', 'o', 'r', 'd', 'i', 'n', 'a', 't', 'e', ' ', '(', 's',
    103                 'o', 'u', 'n', 'd', 'i', 'n', 'g', ' ', 'a', 'r', 'r', 'a', 'y', ')', ' ', 'f', 'i', 'e', 'l', 'd', 0x1f, '*', 'Y', 'C', 'O', 'O',
    104                 '!', 'X', 'C', 'O', 'O', '!', 'V', 'E', '3', 'D', 0x1f, '(', '3', 'b', '2', '4', ')', 0x1e
    105         };
    106        
    107         static final double COMF=10000000;
    108         static final double SOMF=10;
    109        
    110         static String file = "0S000000.000";
    111         static int intu = 0;
    112         static String code = "0S";
    113         static int agen = 3878;
    114         static int cscl = 10000;
    115         static int vdat = 23;
    116         static int duni = 1;
    117         static int huni = 1;
    118        
    119         static int idx;
    120         static int recs;
    121        
    122         static int isols;
    123         static int conns;
    124         static int metas;
    125         static int geos;
    126         static int edges;
    127        
    128         static long hash(long val) {
    129                 byte[] bval = ByteBuffer.allocate(Long.SIZE).putLong(val).array();
    130                 CRC32 crc = new CRC32();
    131                 crc.update(bval);
    132                 return crc.getValue();
    133         }
    134 
    135         public static int encodeChart(S57map map, HashMap<String, String> meta, byte[] buf) throws IndexOutOfBoundsException, UnsupportedEncodingException {
    136                
    137                 for (Entry<String, String> entry : meta.entrySet()) {
    138                         try {
    139                                 switch (entry.getKey()) {
    140                                 case "FILE":
    141                                         file = entry.getValue();
    142                                         break;
    143                                 case "INTU":
    144                                         intu = Integer.parseInt(entry.getValue());
    145                                         break;
    146                                 case "AGEN":
    147                                         String[] tokens = entry.getValue().split("/");
    148                                         code = tokens[0];
    149                                         agen = Integer.parseInt(tokens[1]);
    150                                         break;
    151                                 case "VDAT":
    152                                         vdat = Integer.parseInt(entry.getValue());
    153                                         break;
    154                                 case "CSCL":
    155                                         cscl = Integer.parseInt(entry.getValue());
    156                                         break;
    157                                 case "DUNI":
    158                                         duni = Integer.parseInt(entry.getValue());
    159                                         break;
    160                                 case "HUNI":
    161                                         huni = Integer.parseInt(entry.getValue());
    162                                         break;
    163                                 }
    164                         } catch (Exception e) {
    165                                 System.err.println("Meta data (" + entry.getKey() + "=" + entry.getValue() + "):" + e.getMessage());
    166                                 System.exit(-1);
    167                         }
    168                 }
    169                
    170                 //M_COVR & MNSYS in BB if not in map
    171                 if (!map.features.containsKey(Obj.M_COVR)) {
    172                         S57osm.OSMmeta(map);
    173                 }
    174                
    175                 S57dat.S57geoms(map);
    176 
    177                 byte[] record;
    178                 ArrayList<Fparams> fields;
    179 
    180                 isols = conns = metas = geos = edges = 0;
    181                 String date = new SimpleDateFormat("yyyyMMdd").format(Calendar.getInstance().getTime());
    182                 ArrayList<Fparams> ds = new ArrayList<>();
    183                 ds.add(new Fparams(S57field.DSID, new Object[] { 10, 1, 1, intu, file, "1", "0", date, date, "03.1", 1, "ENC", "2.0", 1, agen, "Generated by OpenSeaMap.org" }));
    184                 ds.add(new Fparams(S57field.DSSI, new Object[] { 2, 1, 2, metas, 0, geos, 0, isols, conns, edges, 0 }));
    185                 ArrayList<Fparams> dp = new ArrayList<>();
    186                 dp.add(new Fparams(S57field.DSPM, new Object[] { 20, 2, 2, vdat, vdat, cscl, duni, huni, 1, 1, 10000000, 10, "" }));
    187 
    188                 System.arraycopy(header, 0, buf, 0, header.length);
    189                 idx = header.length;
    190                 record = S57dat.encRecord(1, ds);
    191                 System.arraycopy(record, 0, buf, idx, record.length);
    192                 idx += record.length;
    193                 record = S57dat.encRecord(2, dp);
    194                 System.arraycopy(record, 0, buf, idx, record.length);
    195                 idx += record.length;
    196                 recs = 3;
    197 
    198                 // Depths
    199                 Object[] depths = new Object[0];
    200                 for (Map.Entry<Long, S57map.Snode> entry : map.nodes.entrySet()) {
    201                         S57map.Snode node = entry.getValue();
    202                         if (node.flg == Nflag.DPTH) {
    203                                 Object[] dval = new Object[] { (Math.toDegrees(node.lat) * COMF), (Math.toDegrees(node.lon) * COMF), (node.val * SOMF) };
    204                                 depths = Arrays.copyOf(depths, (depths.length + dval.length));
    205                                 System.arraycopy(dval, 0, depths, (depths.length - dval.length), dval.length);
    206                         }
    207                 }
    208                 if (depths.length > 0) {
    209                         fields = new ArrayList<>();
    210                         fields.add(new Fparams(S57field.VRID, new Object[] { 110, -2, 1, 1 }));
    211                         fields.add(new Fparams(S57field.SG3D, depths));
    212                         record = S57dat.encRecord(recs++, fields);
    213                         System.arraycopy(record, 0, buf, idx, record.length);
    214                         idx += record.length;
    215                         isols++;
    216                 }
    217 
    218                 // Isolated nodes
    219                 for (Map.Entry<Long, S57map.Snode> entry : map.nodes.entrySet()) {
    220                         S57map.Snode node = entry.getValue();
    221                         if (node.flg == Nflag.ISOL) {
    222                                 fields = new ArrayList<>();
    223                                 fields.add(new Fparams(S57field.VRID, new Object[] { 110, hash(entry.getKey()), 1, 1 }));
    224                                 fields.add(new Fparams(S57field.SG2D, new Object[] { (Math.toDegrees(node.lat) * COMF), (Math.toDegrees(node.lon) * COMF) }));
    225                                 record = S57dat.encRecord(recs++, fields);
    226                                 System.arraycopy(record, 0, buf, idx, record.length);
    227                                 idx += record.length;
    228                                 isols++;
    229                         }
    230                 }
    231 
    232                 // Connected nodes
    233                 for (Map.Entry<Long, S57map.Snode> entry : map.nodes.entrySet()) {
    234                         S57map.Snode node = entry.getValue();
    235                         if (node.flg == Nflag.CONN) {
    236                                 fields = new ArrayList<>();
    237                                 fields.add(new Fparams(S57field.VRID, new Object[] { 120, hash(entry.getKey()), 1, 1 }));
    238                                 fields.add(new Fparams(S57field.SG2D, new Object[] { (Math.toDegrees(node.lat) * COMF), (Math.toDegrees(node.lon) * COMF) }));
    239                                 record = S57dat.encRecord(recs++, fields);
    240                                 System.arraycopy(record, 0, buf, idx, record.length);
    241                                 idx += record.length;
    242                                 conns++;
    243                         }
    244                 }
    245 
    246                 // Edges
    247                 for (Map.Entry<Long, S57map.Edge> entry : map.edges.entrySet()) {
    248                         S57map.Edge edge = entry.getValue();
    249                         fields = new ArrayList<>();
    250                         fields.add(new Fparams(S57field.VRID, new Object[] { 130, hash(entry.getKey()), 1, 1 }));
    251                         fields.add(new Fparams(S57field.VRPT, new Object[] { (((hash(edge.first) & 0xffffffff) << 8) + 120l), 255, 255, 1, 255, (((hash(edge.last) & 0xffffffff) << 8) + 120l), 255, 255, 2, 255 }));
    252                         Object[] nodes = new Object[0];
    253                         for (long ref : edge.nodes) {
    254                                 Object[] nval = new Object[] { (Math.toDegrees(map.nodes.get(ref).lat) * COMF), (Math.toDegrees(map.nodes.get(ref).lon) * COMF) };
    255                                 nodes = Arrays.copyOf(nodes, (nodes.length + nval.length));
    256                                 System.arraycopy(nval, 0, nodes, (nodes.length - nval.length), nval.length);
    257                         }
    258                         if (nodes.length > 0) {
    259                                 fields.add(new Fparams(S57field.SG2D, nodes));
    260                         }
    261                         record = S57dat.encRecord(recs++, fields);
    262                         System.arraycopy(record, 0, buf, idx, record.length);
    263                         idx += record.length;
    264                         edges++;
    265                 }
    266 
    267                 // Meta & Geo objects
    268                 boolean soundings = false;
    269                 for (Entry<Obj, ArrayList<Feature>> entry : map.features.entrySet()) {
    270                         Obj obj = entry.getKey();
    271                         for (Feature feature : entry.getValue()) {
    272                                 if (obj == Obj.SOUNDG) {
    273                                         if (soundings) {
    274                                                 continue;
    275                                         } else {
    276                                                 soundings = true;
    277                                         }
    278                                 }
    279                                 int prim = feature.geom.prim.ordinal();
    280                                 prim = (prim == 0) ? 255 : prim;
    281                                 int grup = ((obj == Obj.DEPARE) || (obj == Obj.DRGARE) || (obj == Obj.FLODOC) || (obj == Obj.HULKES) || (obj == Obj.LNDARE) || (obj == Obj.PONTON) || (obj == Obj.UNSARE)) ? 1 : 2;
    282 
    283                                 ArrayList<Fparams> geom = new ArrayList<>();
    284                                 int outers = 0;
    285                                 outers = (feature.geom.prim == Pflag.POINT) ? 1 : feature.geom.comps.get(0).size;
    286                                 for (Prim elem : feature.geom.elems) {
    287                                         if (feature.geom.prim == Pflag.POINT) {
    288                                                 if (obj == Obj.SOUNDG) {
    289                                                         geom.add(new Fparams(S57field.FSPT, new Object[] { ((-2 << 8) + 110l), 255, 255, 255 }));
    290                                                 } else {
    291                                                         geom.add(new Fparams(S57field.FSPT, new Object[] { ((hash(elem.id) << 8) + ((map.nodes.get(elem.id).flg == Nflag.CONN) ? 120l : 110l)), 255, 255, 255 }));
    292                                                 }
    293                                         } else {
    294                                                 geom.add(new Fparams(S57field.FSPT, new Object[] { ((hash(elem.id) << 8) + 130l), (elem.forward ? 1 : 2), ((outers-- > 0) ? 1 : 2), 2 }));
    295                                         }
    296                                 }
    297 
    298                                 ArrayList<ArrayList<Fparams>> objects = new ArrayList<>();
    299                                 ArrayList<Long> slaves = new ArrayList<>();
    300                                 long slaveid = feature.id + 0x0100000000000000l;
    301                                 for (Entry<Obj, ObjTab> objs : feature.objs.entrySet()) {
    302                                         Obj objobj = objs.getKey();
    303                                         boolean master = true;
    304                                         for (Entry<Integer, AttMap> object : objs.getValue().entrySet()) {
    305                                                 ArrayList<Fparams> objatts = new ArrayList<>();
    306                                                 master = (feature.type == objobj) && ((object.getKey() == 0) || (object.getKey() == 1));
    307                                                 long id = hash(master ? feature.id : slaveid);
    308                                                 objatts.add(new Fparams(S57field.FRID, new Object[] { 100, id, prim, grup, S57obj.encodeType(objobj), 1, 1 }));
    309                                                 objatts.add(new Fparams(S57field.FOID, new Object[] { agen, id, 1 }));
    310                                                 Object[] attf = new Object[0];
    311                                                 Object[] natf = new Object[0];
    312                                                 AttMap atts = map.new AttMap();
    313                                                 atts.putAll(object.getValue());
    314                                                 if (master) {
    315                                                         atts.putAll(feature.atts);
    316                                                 }
    317                                                 for (Entry<Att, AttVal<?>> att : atts.entrySet()) {
    318                                                         if (!((obj == Obj.SOUNDG) && (att.getKey() == Att.VALSOU))) {
    319                                                                 long attl = S57att.encodeAttribute(att.getKey());
    320                                                                 Object[] next = new Object[] { attl, S57val.encodeValue(att.getValue(), att.getKey()) };
    321                                                                 if ((attl < 300) || (attl > 304)) {
    322                                                                         attf = Arrays.copyOf(attf, (attf.length + next.length));
    323                                                                         System.arraycopy(next, 0, attf, (attf.length - next.length), next.length);
    324                                                                 } else {
    325                                                                         natf = Arrays.copyOf(natf, (natf.length + next.length));
    326                                                                         System.arraycopy(next, 0, natf, (natf.length - next.length), next.length);
    327                                                                 }
    328                                                         }
    329                                                 }
    330                                                 if (attf.length > 0) {
    331                                                         objatts.add(new Fparams(S57field.ATTF, attf));
    332                                                 }
    333                                                 if (natf.length > 0) {
    334                                                         objatts.add(new Fparams(S57field.NATF, attf));
    335                                                 }
    336                                                 if (master) {
    337                                                         objects.add(objatts);
    338                                                 } else {
    339                                                         slaves.add(id);
    340                                                         objects.add(0, objatts);
    341                                                         slaveid += 0x0100000000000000l;
    342                                                 }
    343                                         }
    344                                 }
    345 
    346                                 if (!slaves.isEmpty()) {
    347                                         ArrayList<Fparams> refs = new ArrayList<>();
    348                                         Object[] params = new Object[0];
    349                                         while (!slaves.isEmpty()) {
    350                                                 long id = slaves.remove(0);
    351                                                 Object[] next = new Object[] { (long) ((((id & 0xffffffff) + 0x100000000l) << 16) + (agen & 0xffff)), 2, "" };
    352                                                 params = Arrays.copyOf(params, (params.length + next.length));
    353                                                 System.arraycopy(next, 0, params, (params.length - next.length), next.length);
    354                                         }
    355                                         refs.add(new Fparams(S57field.FFPT, params));
    356                                         objects.get(objects.size() - 1).addAll(refs);
    357                                 }
    358 
    359                                 for (ArrayList<Fparams> object : objects) {
    360                                         object.addAll(geom);
    361                                         record = S57dat.encRecord(recs++, object);
    362                                         System.arraycopy(record, 0, buf, idx, record.length);
    363                                         idx += record.length;
    364                                         if ((obj == Obj.M_COVR) || (obj == Obj.M_NSYS)) {
    365                                                 metas++;
    366                                         } else {
    367                                                 geos++;
    368                                         }
    369                                 }
    370                         }
    371                 }
    372 
    373                 // Re-write DSID/DSSI with final totals
    374                 ds = new ArrayList<>();
    375                 ds.add(new Fparams(S57field.DSID, new Object[] { 10, 1, 1, intu, file, "1", "0", date, date, "03.1", 1, "ENC", "2.0", 1, agen, "Generated by OpenSeaMap.org" }));
    376                 ds.add(new Fparams(S57field.DSSI, new Object[] { 2, 1, 2, metas, 0, geos, 0, isols, conns, edges, 0 }));
    377                 record = S57dat.encRecord(1, ds);
    378                 System.arraycopy(record, 0, buf, header.length, record.length);
    379 
    380                 return idx;
    381         }
     36    // CHECKSTYLE.OFF: LineLength
     37
     38    private static final byte[] header = {
     39
     40            '0', '1', '5', '7', '6', '3', 'L', 'E', '1', ' ', '0', '9', '0', '0', '2', '0', '1', ' ', '!', ' ', '3', '4', '0', '4', // Leader
     41            '0', '0', '0', '0', '1', '2', '3', '0', '0', '0', '0', '0', '0', '0', '1', '0', '4', '7', '0', '1', '2', '3',
     42            'D', 'S', 'I', 'D', '1', '5', '9', '0', '1', '7', '0', 'D', 'S', 'S', 'I', '1', '1', '3', '0', '3', '2', '9',
     43            'D', 'S', 'P', 'M', '1', '3', '0', '0', '4', '4', '2', 'F', 'R', 'I', 'D', '1', '0', '0', '0', '5', '7', '2',
     44            'F', 'O', 'I', 'D', '0', '7', '0', '0', '6', '7', '2', 'A', 'T', 'T', 'F', '0', '5', '9', '0', '7', '4', '2',
     45            'N', 'A', 'T', 'F', '0', '6', '8', '0', '8', '0', '1', 'F', 'F', 'P', 'T', '0', '8', '6', '0', '8', '6', '9',
     46            'F', 'S', 'P', 'T', '0', '9', '0', '0', '9', '5', '5', 'V', 'R', 'I', 'D', '0', '7', '8', '1', '0', '4', '5',
     47            'A', 'T', 'T', 'V', '0', '5', '8', '1', '1', '2', '3', 'V', 'R', 'P', 'T', '0', '7', '6', '1', '1', '8', '1',
     48            'S', 'G', '2', 'D', '0', '4', '8', '1', '2', '5', '7', 'S', 'G', '3', 'D', '0', '7', '0', '1', '3', '0', '5', 0x1e,
     49            // File control field
     50            '0', '0', '0', '0', ';', '&', ' ', ' ', ' ', 0x1f,
     51            '0', '0', '0', '1', 'D', 'S', 'I', 'D', 'D', 'S', 'I', 'D', 'D', 'S', 'S', 'I', '0', '0', '0', '1', 'D', 'S', 'P', 'M',
     52            '0', '0', '0', '1', 'F', 'R', 'I', 'D', 'F', 'R', 'I', 'D', 'F', 'O', 'I', 'D', 'F', 'R', 'I', 'D', 'A', 'T', 'T', 'F',
     53            'F', 'R', 'I', 'D', 'N', 'A', 'T', 'F', 'F', 'R', 'I', 'D', 'F', 'F', 'P', 'T', 'F', 'R', 'I', 'D', 'F', 'S', 'P', 'T',
     54            '0', '0', '0', '1', 'V', 'R', 'I', 'D', 'V', 'R', 'I', 'D', 'A', 'T', 'T', 'V', 'V', 'R', 'I', 'D', 'V', 'R', 'P', 'T',
     55            'V', 'R', 'I', 'D', 'S', 'G', '2', 'D', 'V', 'R', 'I', 'D', 'S', 'G', '3', 'D', 0x1e,
     56            // Record identifier fields
     57            '0', '5', '0', '0', ';', '&', ' ', ' ', ' ', 'I', 'S', 'O', '/', 'I', 'E', 'C', ' ', '8', '2', '1', '1', ' ',
     58            'R', 'e', 'c', 'o', 'r', 'd', ' ', 'I', 'd', 'e', 'n', 't', 'i', 'f', 'i', 'e', 'r', 0x1f, 0x1f, '(', 'b', '1', '2', ')', 0x1e,
     59            '1', '6', '0', '0', ';', '&', ' ', ' ', ' ', 'D', 'a', 't', 'a', ' ', 'S', 'e', 't', ' ', 'I', 'd', 'e', 'n', 't', 'i',
     60            'f', 'i', 'c', 'a', 't', 'i', 'o', 'n', 0x1f, 'R', 'C', 'N', 'M', '!', 'R', 'C', 'I', 'D', '!', 'E', 'X', 'P', 'P', '!',
     61            'I', 'N', 'T', 'U', '!', 'D', 'S', 'N', 'M', '!', 'E', 'D', 'T', 'N', '!', 'U', 'P', 'D', 'N', '!', 'U', 'A', 'D', 'T',
     62            '!', 'I', 'S', 'D', 'T', '!', 'S', 'T', 'E', 'D', '!', 'P', 'R', 'S', 'P', '!', 'P', 'S', 'D', 'N', '!', 'P', 'R', 'E',
     63            'D', '!', 'P', 'R', 'O', 'F', '!', 'A', 'G', 'E', 'N', '!', 'C', 'O', 'M', 'T', 0x1f, '(', 'b', '1', '1', ',', 'b', '1',
     64            '4', ',', '2', 'b', '1', '1', ',', '3', 'A', ',', '2', 'A', '(', '8', ')', ',', 'R', '(', '4', ')', ',', 'b', '1', '1',
     65            ',', '2', 'A', ',', 'b', '1', '1', ',', 'b', '1', '2', ',', 'A', ')', 0x1e,
     66            '1', '6', '0', '0', ';', '&', ' ', ' ', ' ', 'D', 'a', 't', 'a', ' ', 's', 'e', 't', ' ', 's', 't', 'r', 'u', 'c', 't',
     67            'u', 'r', 'e', ' ', 'i', 'n', 'f', 'o', 'r', 'm', 'a', 't', 'i', 'o', 'n', ' ', 'f', 'i', 'e', 'l', 'd', 0x1f,
     68            'D', 'S', 'T', 'R', '!', 'A', 'A', 'L', 'L', '!', 'N', 'A', 'L', 'L', '!', 'N', 'O', 'M', 'R', '!', 'N', 'O', 'C', 'R',
     69            '!', 'N', 'O', 'G', 'R', '!', 'N', 'O', 'L', 'R', '!', 'N', 'O', 'I', 'N', '!', 'N', 'O', 'C', 'N', '!', 'N', 'O', 'E',
     70            'D', '!', 'N', 'O', 'F', 'A', 0x1f, '(', '3', 'b', '1', '1', ',', '8', 'b', '1', '4', ')', 0x1e,
     71            '1', '6', '0', '0', ';', '&', ' ', ' ', ' ', 'D', 'a', 't', 'a', ' ', 's', 'e', 't', ' ', 'p', 'a', 'r', 'a', 'm', 'e',
     72            't', 'e', 'r', ' ', 'f', 'i', 'e', 'l', 'd', 0x1f, 'R', 'C', 'N', 'M', '!', 'R', 'C', 'I', 'D', '!', 'H', 'D', 'A', 'T',
     73            '!', 'V', 'D', 'A', 'T', '!', 'S', 'D', 'A', 'T', '!', 'C', 'S', 'C', 'L', '!', 'D', 'U', 'N', 'I', '!', 'H', 'U', 'N',
     74            'I', '!', 'P', 'U', 'N', 'I', '!', 'C', 'O', 'U', 'N', '!', 'C', 'O', 'M', 'F', '!', 'S', 'O', 'M', 'F', '!', 'C', 'O',
     75            'M', 'T', 0x1f, '(', 'b', '1', '1', ',', 'b', '1', '4', ',', '3', 'b', '1', '1', ',', 'b', '1', '4', ',', '4', 'b', '1',
     76            '1', ',', '2', 'b', '1', '4', ',', 'A', ')', 0x1e,
     77            '1', '6', '0', '0', ';', '&', ' ', ' ', ' ', 'F', 'e', 'a', 't', 'u', 'r', 'e', ' ', 'r', 'e', 'c', 'o', 'r', 'd', ' ', 'i',
     78            'd', 'e', 'n', 't', 'i', 'f', 'i', 'e', 'r', ' ', 'f', 'i', 'e', 'l', 'd', 0x1f, 'R', 'C', 'N', 'M', '!', 'R', 'C', 'I', 'D',
     79            '!', 'P', 'R', 'I', 'M', '!', 'G', 'R', 'U', 'P', '!', 'O', 'B', 'J', 'L', '!', 'R', 'V', 'E', 'R', '!', 'R', 'U', 'I', 'N', 0x1f,
     80            '(', 'b', '1', '1', ',', 'b', '1', '4', ',', '2', 'b', '1', '1', ',', '2', 'b', '1', '2', ',', 'b', '1', '1', ')', 0x1e,
     81            '1', '6', '0', '0', ';', '&', ' ', ' ', ' ', 'F', 'e', 'a', 't', 'u', 'r', 'e', ' ', 'o', 'b', 'j', 'e', 'c', 't', ' ', 'i',
     82            'd', 'e', 'n', 't', 'i', 'f', 'i', 'e', 'r', ' ', 'f', 'i', 'e', 'l', 'd', 0x1f, 'A', 'G', 'E', 'N', '!', 'F', 'I', 'D', 'N',
     83            '!', 'F', 'I', 'D', 'S', 0x1f, '(', 'b', '1', '2', ',', 'b', '1', '4', ',', 'b', '1', '2', ')', 0x1e,
     84            '2', '6', '0', '0', ';', '&', '-', 'A', ' ', 'F', 'e', 'a', 't', 'u', 'r', 'e', ' ', 'r', 'e', 'c', 'o', 'r', 'd', ' ', 'a',
     85            't', 't', 'r', 'i', 'b', 'u', 't', 'e', ' ', 'f', 'i', 'e', 'l', 'd', 0x1f, '*', 'A', 'T', 'T', 'L', '!', 'A', 'T', 'V', 'L', 0x1f,
     86            '(', 'b', '1', '2', ',', 'A', ')', 0x1e,
     87            '2', '6', '0', '0', ';', '&', '-', 'A', ' ', 'F', 'e', 'a', 't', 'u', 'r', 'e', ' ', 'r', 'e', 'c', 'o', 'r', 'd', ' ', 'n', 'a',
     88            't', 'i', 'o', 'n', 'a', 'l', ' ', 'a', 't', 't', 'r', 'i', 'b', 'u', 't', 'e', ' ', 'f', 'i', 'e', 'l', 'd', 0x1f, '*', 'A', 'T',
     89            'T', 'L', '!', 'A', 'T', 'V', 'L', 0x1f, '(', 'b', '1', '2', ',', 'A', ')', 0x1e,
     90            '2', '6', '0', '0', ';', '&', ' ', ' ', ' ', 'F', 'e', 'a', 't', 'u', 'r', 'e', ' ', 'r', 'e', 'c', 'o', 'r', 'd', ' ', 't', 'o',
     91            ' ', 'f', 'e', 'a', 't', 'u', 'r', 'e', ' ', 'o', 'b', 'j', 'e', 'c', 't', ' ', 'p', 'o', 'i', 'n', 't', 'e', 'r', ' ', 'f', 'i',
     92            'e', 'l', 'd', 0x1f, '*', 'L', 'N', 'A', 'M', '!', 'R', 'I', 'N', 'D', '!', 'C', 'O', 'M', 'T', 0x1f, '(', 'B', '(', '6', '4',
     93            ')', ',', 'b', '1', '1', ',', 'A', ')', 0x1e,
     94            '2', '6', '0', '0', ';', '&', ' ', ' ', ' ', 'F', 'e', 'a', 't', 'u', 'r', 'e', ' ', 'r', 'e', 'c', 'o', 'r', 'd', ' ', 't', 'o',
     95            ' ', 's', 'p', 'a', 't', 'i', 'a', 'l', ' ', 'r', 'e', 'c', 'o', 'r', 'd', ' ', 'p', 'o', 'i', 'n', 't', 'e', 'r', ' ', 'f', 'i',
     96            'e', 'l', 'd', 0x1f, '*', 'N', 'A', 'M', 'E', '!', 'O', 'R', 'N', 'T', '!', 'U', 'S', 'A', 'G', '!', 'M', 'A', 'S', 'K', 0x1f,
     97            '(', 'B', '(', '4', '0', ')', ',', '3', 'b', '1', '1', ')', 0x1e,
     98            '1', '6', '0', '0', ';', '&', ' ', ' ', ' ', 'V', 'e', 'c', 't', 'o', 'r', ' ', 'r', 'e', 'c', 'o', 'r', 'd', ' ', 'i', 'd', 'e',
     99            'n', 't', 'i', 'f', 'i', 'e', 'r', ' ', 'f', 'i', 'e', 'l', 'd', 0x1f, 'R', 'C', 'N', 'M', '!', 'R', 'C', 'I', 'D', '!', 'R', 'V',
     100            'E', 'R', '!', 'R', 'U', 'I', 'N', 0x1f, '(', 'b', '1', '1', ',', 'b', '1', '4', ',', 'b', '1', '2', ',', 'b', '1', '1', ')', 0x1e,
     101            '2', '6', '0', '0', ';', '&', ' ', ' ', ' ', 'V', 'e', 'c', 't', 'o', 'r', ' ', 'r', 'e', 'c', 'o', 'r', 'd', ' ', 'a', 't', 't',
     102            'r', 'i', 'b', 'u', 't', 'e', ' ', 'f', 'i', 'e', 'l', 'd', 0x1f, '*', 'A', 'T', 'T', 'L', '!', 'A', 'T', 'V', 'L', 0x1f, '(', 'b',
     103            '1', '2', ',', 'A', ')', 0x1e,
     104            '2', '6', '0', '0', ';', '&', ' ', ' ', ' ', 'V', 'e', 'c', 't', 'o', 'r', ' ', 'r', 'e', 'c', 'o', 'r', 'd', ' ', 'p', 'o', 'i',
     105            'n', 't', 'e', 'r', ' ', 'f', 'i', 'e', 'l', 'd', 0x1f, '*', 'N', 'A', 'M', 'E', '!', 'O', 'R', 'N', 'T', '!', 'U', 'S', 'A', 'G',
     106            '!', 'T', 'O', 'P', 'I', '!', 'M', 'A', 'S', 'K', 0x1f, '(', 'B', '(', '4', '0', ')', ',', '4', 'b', '1', '1', ')', 0x1e,
     107            '2', '6', '0', '0', ';', '&', ' ', ' ', ' ', '2', '-', 'D', ' ', 'c', 'o', 'o', 'r', 'd', 'i', 'n', 'a', 't', 'e', ' ', 'f', 'i',
     108            'e', 'l', 'd', 0x1f, '*', 'Y', 'C', 'O', 'O', '!', 'X', 'C', 'O', 'O', 0x1f, '(', '2', 'b', '2', '4', ')', 0x1e,
     109            '2', '6', '0', '0', ';', '&', ' ', ' ', ' ', '3', '-', 'D', ' ', 'c', 'o', 'o', 'r', 'd', 'i', 'n', 'a', 't', 'e', ' ', '(', 's',
     110            'o', 'u', 'n', 'd', 'i', 'n', 'g', ' ', 'a', 'r', 'r', 'a', 'y', ')', ' ', 'f', 'i', 'e', 'l', 'd', 0x1f, '*', 'Y', 'C', 'O', 'O',
     111            '!', 'X', 'C', 'O', 'O', '!', 'V', 'E', '3', 'D', 0x1f, '(', '3', 'b', '2', '4', ')', 0x1e
     112    };
     113
     114    static final double COMF = 10000000;
     115    static final double SOMF = 10;
     116
     117    static String file = "0S000000.000";
     118    static int intu = 0;
     119    static String code = "0S";
     120    static int agen = 3878;
     121    static int cscl = 10000;
     122    static int vdat = 23;
     123    static int duni = 1;
     124    static int huni = 1;
     125
     126    static int idx;
     127    static int recs;
     128
     129    static int isols;
     130    static int conns;
     131    static int metas;
     132    static int geos;
     133    static int edges;
     134
     135    static long hash(long val) {
     136        byte[] bval = ByteBuffer.allocate(Long.SIZE).putLong(val).array();
     137        CRC32 crc = new CRC32();
     138        crc.update(bval);
     139        return crc.getValue();
     140    }
     141
     142    public static int encodeChart(S57map map, HashMap<String, String> meta, byte[] buf) throws IndexOutOfBoundsException, UnsupportedEncodingException {
     143
     144        for (Entry<String, String> entry : meta.entrySet()) {
     145            try {
     146                switch (entry.getKey()) {
     147                case "FILE":
     148                    file = entry.getValue();
     149                    break;
     150                case "INTU":
     151                    intu = Integer.parseInt(entry.getValue());
     152                    break;
     153                case "AGEN":
     154                    String[] tokens = entry.getValue().split("/");
     155                    code = tokens[0];
     156                    agen = Integer.parseInt(tokens[1]);
     157                    break;
     158                case "VDAT":
     159                    vdat = Integer.parseInt(entry.getValue());
     160                    break;
     161                case "CSCL":
     162                    cscl = Integer.parseInt(entry.getValue());
     163                    break;
     164                case "DUNI":
     165                    duni = Integer.parseInt(entry.getValue());
     166                    break;
     167                case "HUNI":
     168                    huni = Integer.parseInt(entry.getValue());
     169                    break;
     170                }
     171            } catch (Exception e) {
     172                System.err.println("Meta data (" + entry.getKey() + "=" + entry.getValue() + "):" + e.getMessage());
     173                System.exit(-1);
     174            }
     175        }
     176
     177        //M_COVR & MNSYS in BB if not in map
     178        if (!map.features.containsKey(Obj.M_COVR)) {
     179            S57osm.OSMmeta(map);
     180        }
     181
     182        S57dat.S57geoms(map);
     183
     184        byte[] record;
     185        ArrayList<Fparams> fields;
     186
     187        isols = conns = metas = geos = edges = 0;
     188        String date = new SimpleDateFormat("yyyyMMdd").format(Calendar.getInstance().getTime());
     189        ArrayList<Fparams> ds = new ArrayList<>();
     190        ds.add(new Fparams(S57field.DSID, new Object[] {10, 1, 1, intu, file, "1", "0", date, date, "03.1", 1, "ENC", "2.0", 1, agen, "Generated by OpenSeaMap.org" }));
     191        ds.add(new Fparams(S57field.DSSI, new Object[] {2, 1, 2, metas, 0, geos, 0, isols, conns, edges, 0 }));
     192        ArrayList<Fparams> dp = new ArrayList<>();
     193        dp.add(new Fparams(S57field.DSPM, new Object[] {20, 2, 2, vdat, vdat, cscl, duni, huni, 1, 1, 10000000, 10, "" }));
     194
     195        System.arraycopy(header, 0, buf, 0, header.length);
     196        idx = header.length;
     197        record = S57dat.encRecord(1, ds);
     198        System.arraycopy(record, 0, buf, idx, record.length);
     199        idx += record.length;
     200        record = S57dat.encRecord(2, dp);
     201        System.arraycopy(record, 0, buf, idx, record.length);
     202        idx += record.length;
     203        recs = 3;
     204
     205        // Depths
     206        Object[] depths = new Object[0];
     207        for (Map.Entry<Long, S57map.Snode> entry : map.nodes.entrySet()) {
     208            S57map.Snode node = entry.getValue();
     209            if (node.flg == Nflag.DPTH) {
     210                Object[] dval = new Object[] {(Math.toDegrees(node.lat) * COMF), (Math.toDegrees(node.lon) * COMF), (node.val * SOMF) };
     211                depths = Arrays.copyOf(depths, (depths.length + dval.length));
     212                System.arraycopy(dval, 0, depths, (depths.length - dval.length), dval.length);
     213            }
     214        }
     215        if (depths.length > 0) {
     216            fields = new ArrayList<>();
     217            fields.add(new Fparams(S57field.VRID, new Object[] {110, -2, 1, 1 }));
     218            fields.add(new Fparams(S57field.SG3D, depths));
     219            record = S57dat.encRecord(recs++, fields);
     220            System.arraycopy(record, 0, buf, idx, record.length);
     221            idx += record.length;
     222            isols++;
     223        }
     224
     225        // Isolated nodes
     226        for (Map.Entry<Long, S57map.Snode> entry : map.nodes.entrySet()) {
     227            S57map.Snode node = entry.getValue();
     228            if (node.flg == Nflag.ISOL) {
     229                fields = new ArrayList<>();
     230                fields.add(new Fparams(S57field.VRID, new Object[] {110, hash(entry.getKey()), 1, 1 }));
     231                fields.add(new Fparams(S57field.SG2D, new Object[] {(Math.toDegrees(node.lat) * COMF), (Math.toDegrees(node.lon) * COMF) }));
     232                record = S57dat.encRecord(recs++, fields);
     233                System.arraycopy(record, 0, buf, idx, record.length);
     234                idx += record.length;
     235                isols++;
     236            }
     237        }
     238
     239        // Connected nodes
     240        for (Map.Entry<Long, S57map.Snode> entry : map.nodes.entrySet()) {
     241            S57map.Snode node = entry.getValue();
     242            if (node.flg == Nflag.CONN) {
     243                fields = new ArrayList<>();
     244                fields.add(new Fparams(S57field.VRID, new Object[] {120, hash(entry.getKey()), 1, 1 }));
     245                fields.add(new Fparams(S57field.SG2D, new Object[] {(Math.toDegrees(node.lat) * COMF), (Math.toDegrees(node.lon) * COMF) }));
     246                record = S57dat.encRecord(recs++, fields);
     247                System.arraycopy(record, 0, buf, idx, record.length);
     248                idx += record.length;
     249                conns++;
     250            }
     251        }
     252
     253        // Edges
     254        for (Map.Entry<Long, S57map.Edge> entry : map.edges.entrySet()) {
     255            S57map.Edge edge = entry.getValue();
     256            fields = new ArrayList<>();
     257            fields.add(new Fparams(S57field.VRID, new Object[] {130, hash(entry.getKey()), 1, 1}));
     258            fields.add(new Fparams(S57field.VRPT, new Object[] {(((hash(edge.first) & 0xffffffff) << 8) + 120L), 255, 255, 1, 255, (((hash(edge.last) & 0xffffffff) << 8) + 120L), 255, 255, 2, 255 }));
     259            Object[] nodes = new Object[0];
     260            for (long ref : edge.nodes) {
     261                Object[] nval = new Object[] {(Math.toDegrees(map.nodes.get(ref).lat) * COMF), (Math.toDegrees(map.nodes.get(ref).lon) * COMF) };
     262                nodes = Arrays.copyOf(nodes, (nodes.length + nval.length));
     263                System.arraycopy(nval, 0, nodes, (nodes.length - nval.length), nval.length);
     264            }
     265            if (nodes.length > 0) {
     266                fields.add(new Fparams(S57field.SG2D, nodes));
     267            }
     268            record = S57dat.encRecord(recs++, fields);
     269            System.arraycopy(record, 0, buf, idx, record.length);
     270            idx += record.length;
     271            edges++;
     272        }
     273
     274        // Meta & Geo objects
     275        boolean soundings = false;
     276        for (Entry<Obj, ArrayList<Feature>> entry : map.features.entrySet()) {
     277            Obj obj = entry.getKey();
     278            for (Feature feature : entry.getValue()) {
     279                if (obj == Obj.SOUNDG) {
     280                    if (soundings) {
     281                        continue;
     282                    } else {
     283                        soundings = true;
     284                    }
     285                }
     286                int prim = feature.geom.prim.ordinal();
     287                prim = (prim == 0) ? 255 : prim;
     288                int grup = ((obj == Obj.DEPARE) || (obj == Obj.DRGARE) || (obj == Obj.FLODOC) || (obj == Obj.HULKES) || (obj == Obj.LNDARE) || (obj == Obj.PONTON) || (obj == Obj.UNSARE)) ? 1 : 2;
     289
     290                ArrayList<Fparams> geom = new ArrayList<>();
     291                int outers = 0;
     292                outers = (feature.geom.prim == Pflag.POINT) ? 1 : feature.geom.comps.get(0).size;
     293                for (Prim elem : feature.geom.elems) {
     294                    if (feature.geom.prim == Pflag.POINT) {
     295                        if (obj == Obj.SOUNDG) {
     296                            geom.add(new Fparams(S57field.FSPT, new Object[] {((-2 << 8) + 110L), 255, 255, 255 }));
     297                        } else {
     298                            geom.add(new Fparams(S57field.FSPT, new Object[] {((hash(elem.id) << 8) + ((map.nodes.get(elem.id).flg == Nflag.CONN) ? 120L : 110L)), 255, 255, 255 }));
     299                        }
     300                    } else {
     301                        geom.add(new Fparams(S57field.FSPT, new Object[] {((hash(elem.id) << 8) + 130L), (elem.forward ? 1 : 2), ((outers-- > 0) ? 1 : 2), 2 }));
     302                    }
     303                }
     304
     305                ArrayList<ArrayList<Fparams>> objects = new ArrayList<>();
     306                ArrayList<Long> slaves = new ArrayList<>();
     307                long slaveid = feature.id + 0x0100000000000000L;
     308                for (Entry<Obj, ObjTab> objs : feature.objs.entrySet()) {
     309                    Obj objobj = objs.getKey();
     310                    boolean master = true;
     311                    for (Entry<Integer, AttMap> object : objs.getValue().entrySet()) {
     312                        ArrayList<Fparams> objatts = new ArrayList<>();
     313                        master = (feature.type == objobj) && ((object.getKey() == 0) || (object.getKey() == 1));
     314                        long id = hash(master ? feature.id : slaveid);
     315                        objatts.add(new Fparams(S57field.FRID, new Object[] {100, id, prim, grup, S57obj.encodeType(objobj), 1, 1}));
     316                        objatts.add(new Fparams(S57field.FOID, new Object[] {agen, id, 1}));
     317                        Object[] attf = new Object[0];
     318                        Object[] natf = new Object[0];
     319                        AttMap atts = map.new AttMap();
     320                        atts.putAll(object.getValue());
     321                        if (master) {
     322                            atts.putAll(feature.atts);
     323                        }
     324                        for (Entry<Att, AttVal<?>> att : atts.entrySet()) {
     325                            if (!((obj == Obj.SOUNDG) && (att.getKey() == Att.VALSOU))) {
     326                                long attl = S57att.encodeAttribute(att.getKey());
     327                                Object[] next = new Object[] {attl, S57val.encodeValue(att.getValue(), att.getKey())};
     328                                if ((attl < 300) || (attl > 304)) {
     329                                    attf = Arrays.copyOf(attf, (attf.length + next.length));
     330                                    System.arraycopy(next, 0, attf, (attf.length - next.length), next.length);
     331                                } else {
     332                                    natf = Arrays.copyOf(natf, (natf.length + next.length));
     333                                    System.arraycopy(next, 0, natf, (natf.length - next.length), next.length);
     334                                }
     335                            }
     336                        }
     337                        if (attf.length > 0) {
     338                            objatts.add(new Fparams(S57field.ATTF, attf));
     339                        }
     340                        if (natf.length > 0) {
     341                            objatts.add(new Fparams(S57field.NATF, attf));
     342                        }
     343                        if (master) {
     344                            objects.add(objatts);
     345                        } else {
     346                            slaves.add(id);
     347                            objects.add(0, objatts);
     348                            slaveid += 0x0100000000000000L;
     349                        }
     350                    }
     351                }
     352
     353                if (!slaves.isEmpty()) {
     354                    ArrayList<Fparams> refs = new ArrayList<>();
     355                    Object[] params = new Object[0];
     356                    while (!slaves.isEmpty()) {
     357                        long id = slaves.remove(0);
     358                        Object[] next = new Object[] {(long) ((((id & 0xffffffff) + 0x100000000L) << 16) + (agen & 0xffff)), 2, "" };
     359                        params = Arrays.copyOf(params, (params.length + next.length));
     360                        System.arraycopy(next, 0, params, (params.length - next.length), next.length);
     361                    }
     362                    refs.add(new Fparams(S57field.FFPT, params));
     363                    objects.get(objects.size() - 1).addAll(refs);
     364                }
     365
     366                for (ArrayList<Fparams> object : objects) {
     367                    object.addAll(geom);
     368                    record = S57dat.encRecord(recs++, object);
     369                    System.arraycopy(record, 0, buf, idx, record.length);
     370                    idx += record.length;
     371                    if ((obj == Obj.M_COVR) || (obj == Obj.M_NSYS)) {
     372                        metas++;
     373                    } else {
     374                        geos++;
     375                    }
     376                }
     377            }
     378        }
     379
     380        // Re-write DSID/DSSI with final totals
     381        ds = new ArrayList<>();
     382        ds.add(new Fparams(S57field.DSID, new Object[] {10, 1, 1, intu, file, "1", "0", date, date, "03.1", 1, "ENC", "2.0", 1, agen, "Generated by OpenSeaMap.org" }));
     383        ds.add(new Fparams(S57field.DSSI, new Object[] {2, 1, 2, metas, 0, geos, 0, isols, conns, edges, 0 }));
     384        record = S57dat.encRecord(1, ds);
     385        System.arraycopy(record, 0, buf, header.length, record.length);
     386
     387        return idx;
     388    }
    382389
    383390}
  • applications/editors/josm/plugins/seachart/src/s57/S57map.java

    r32393 r32394  
    1010package s57;
    1111
    12 import java.util.*;
    13 
    14 import s57.S57obj;
    15 import s57.S57obj.*;
    16 import s57.S57att;
    17 import s57.S57att.*;
    18 import s57.S57val;
    19 import s57.S57val.*;
    20 import s57.S57osm;
    21 import s57.S57osm.*;
     12import java.util.ArrayList;
     13import java.util.EnumMap;
     14import java.util.HashMap;
     15import java.util.ListIterator;
     16
     17import s57.S57att.Att;
     18import s57.S57obj.Obj;
     19import s57.S57osm.KeyVal;
     20import s57.S57val.AttVal;
    2221
    2322public class S57map { // S57/OSM map generation methods
    24        
    25         public class MapBounds {
    26                 public double minlat;
    27                 public double minlon;
    28                 public double maxlat;
    29                 public double maxlon;
    30                 public MapBounds() {
    31                         minlat = Math.toRadians(90);
    32                         minlon = Math.toRadians(180);
    33                         maxlat = Math.toRadians(-90);
    34                         maxlon = Math.toRadians(-180);
    35                 }
    36         }
    37 
    38         public enum Nflag {
    39                 ANON,   // Edge inner nodes
    40                 ISOL,   // Node not part of Edge
    41                 CONN,   // Edge first and last nodes
    42                 TRNK, // Edge truncated polygon nodes
    43                 DPTH    // Sounding nodes
    44         }
    45 
    46         public class Snode {    // All coordinates in map
    47                 public double lat;      // Latitude in radians
    48                 public double lon;      // Longitude in radians
    49                 public Nflag flg;               // Role of node
    50                 public double val;      // Optional value
    51 
    52                 public Snode() {
    53                         flg = Nflag.ANON;
    54                         lat = 0;
    55                         lon = 0;
    56                         val = 0;
    57                 }
    58                 public Snode(double ilat, double ilon) {
    59                         flg = Nflag.ANON;
    60                         lat = ilat;
    61                         lon = ilon;
    62                         val = 0;
    63                 }
    64                 public Snode(double ilat, double ilon, Nflag iflg) {
    65                         lat = ilat;
    66                         lon = ilon;
    67                         flg = iflg;
    68                         val = 0;
    69                 }
    70                 public Snode(double ilat, double ilon, double ival) {
    71                         flg = Nflag.DPTH;
    72                         lat = ilat;
    73                         lon = ilon;
    74                         val = ival;
    75                 }
    76         }
    77 
    78         public class Edge {             // A polyline segment
    79                 public long first;      // First CONN node
    80                 public long last;               // Last CONN node
    81                 public ArrayList<Long> nodes; // Inner ANON nodes
    82 
    83                 public Edge() {
    84                         first = 0;
    85                         last = 0;
    86                         nodes = new ArrayList<>();
    87                 }
    88         }
    89        
    90         public enum Rflag {
    91                 UNKN, MASTER, SLAVE
    92         }
    93        
    94         public class Reln {
    95                 public long id;
    96                 public Rflag reln;
    97                 public Reln(long i, Rflag r) {
    98                         id = i;
    99                         reln = r;
    100                 }
    101         }
    102 
    103         public class RelTab extends ArrayList<Reln> {
    104                 public RelTab() {
    105                         super();
    106                 }
    107         }
    108 
    109         public class ObjTab extends HashMap<Integer, AttMap> {
    110                 public ObjTab() {
    111                         super();
    112                 }
    113         }
    114 
    115         public class ObjMap extends EnumMap<Obj, ObjTab> {
    116                 public ObjMap() {
    117                         super(Obj.class);
    118                 }
    119         }
    120 
    121         public class AttMap extends HashMap<Att, AttVal<?>> {
    122                 public AttMap() {
    123                         super();
    124                 }
    125         }
    126 
    127         public class NodeTab extends HashMap<Long, Snode> {
    128                 public NodeTab() {
    129                         super();
    130                 }
    131         }
    132 
    133         public class EdgeTab extends HashMap<Long, Edge> {
    134                 public EdgeTab() {
    135                         super();
    136                 }
    137         }
    138 
    139         public class FtrMap extends EnumMap<Obj, ArrayList<Feature>> {
    140                 public FtrMap() {
    141                         super(Obj.class);
    142                 }
    143         }
    144 
    145         public class FtrTab extends HashMap<Long, Feature> {
    146                 public FtrTab() {
    147                         super();
    148                 }
    149         }
    150 
    151         public class Prim {                             // Spatial element
    152                 public long id;                                 // Snode ID for POINTs, Edge ID for LINEs & AREAs)
    153                 public boolean forward; // Direction of vector used (LINEs & AREAs)
    154                 public boolean outer;           // Exterior/Interior boundary (AREAs)
    155                 public boolean trunc;           // Cell limit truncation
    156                 public Prim() {
    157                         id = 0; forward = true; outer = true; trunc = false;
    158                 }
    159                 public Prim(long i) {
    160                         id = i; forward = true; outer = true; trunc = false;
    161                 }
    162                 public Prim(long i, boolean o) {
    163                         id = i; forward = true; outer = o; trunc = false;
    164                 }
    165                 public Prim(long i, boolean f, boolean o) {
    166                         id = i; forward = f; outer = o; trunc = false;
    167                 }
    168                 public Prim(long i, boolean f, boolean o, boolean t) {
    169                         id = i; forward = f; outer = o; trunc = t;
    170                 }
    171         }
    172        
    173         public class Comp {                     // Composite spatial element
    174                 public long ref;                        // ID of Comp
    175                 public int size;                        // Number of Prims in this Comp
    176                 public Comp(long r, int s) {
    177                         ref = r;
    178                         size = s;
    179                 }
    180         }
    181        
    182         public enum Pflag {
    183                 NOSP, POINT, LINE, AREA
    184         }
    185        
    186         public class Geom {                                                     // Geometric structure of feature
    187                 public Pflag prim;                                              // Geometry type
    188                 public ArrayList<Prim> elems;   // Ordered list of elements
    189                 public int outers;                                              // Number of outers
    190                 public int inners;                                              // Number of inners
    191                 public ArrayList<Comp> comps;   // Ordered list of compounds
    192                 public double area;                                             // Area of feature
    193                 public double length;                                   // Length of feature
    194                 public Snode centre;                                    // Centre of feature
    195                 public Geom(Pflag p) {
    196                         prim = p;
    197                         elems = new ArrayList<>();
    198                         outers = inners = 0;
    199                         comps = new ArrayList<>();
    200                         area = 0;
    201                         length = 0;
    202                         centre = new Snode();
    203                 }
    204         }
    205        
    206         public class Feature {
    207                 public long id;                         // Ref for this feature
    208                 public Rflag reln;              // Relationship status
    209                 public Geom geom;                       // Geometry data
    210                 public Obj type;                        // Feature type
    211                 public AttMap atts;             // Feature attributes
    212                 public RelTab rels;             // Related objects
    213                 public ObjMap objs;             // Slave object attributes
    214 
    215                 Feature() {
    216                         id = 0;
    217                         reln = Rflag.UNKN;
    218                         geom = new Geom(Pflag.NOSP);
    219                         type = Obj.UNKOBJ;
    220                         atts = new AttMap();
    221                         rels = new RelTab();
    222                         objs = new ObjMap();
    223                 }
    224         }
    225        
    226         public MapBounds bounds;
    227         public NodeTab nodes;
    228         public EdgeTab edges;
    229         public FtrMap features;
    230         public FtrTab index;
    231         public long xref;
    232 
    233         private long cref;
    234         private Feature feature;
    235         private Edge edge;
    236         private ArrayList<KeyVal<?>> osm;
    237         private boolean sea;
    238 
    239         public S57map(boolean s) {
    240                 sea = s;
    241                 nodes = new NodeTab();          // All nodes in map
    242                 edges = new EdgeTab();          // All edges in map
    243                 feature = new Feature();        // Current feature being built
    244                 features = new FtrMap();        // All features in map, grouped by type
    245                 index = new FtrTab();                   // Feature look-up table
    246                 bounds = new MapBounds();
    247                 cref = 0x0000ffffffff0000L;// Compound reference generator
    248                 xref = 0x0fff000000000000L;// Extras reference generator
    249         }
    250 
    251         // S57 map building methods
    252        
    253         public void newNode(long id, double lat, double lon, Nflag flag) {
    254                 nodes.put(id, new Snode(Math.toRadians(lat), Math.toRadians(lon), flag));
    255                 if (flag == Nflag.ANON) {
    256                         edge.nodes.add(id);
    257                 }
    258         }
    259 
    260         public void newNode(long id, double lat, double lon, double depth) {
    261                 nodes.put(id, new Snode(Math.toRadians(lat), Math.toRadians(lon), depth));
    262         }
    263 
    264         public void newFeature(long id, Pflag p, long objl) {
    265                 feature = new Feature();
    266                 Obj obj = S57obj.decodeType(objl);
    267                 feature.geom = new Geom(p);
    268                 feature.type = obj;
    269                 if (obj != Obj.UNKOBJ) {
    270                         index.put(id, feature);
    271                         feature.id = id;
    272                 }
    273         }
    274        
    275         public void refObj(long id, int rind) {
    276                 Rflag r = Rflag.UNKN;
    277                 switch (rind) {
    278                 case 1:
    279                         r = Rflag.MASTER;
    280                         break;
    281                 case 2:
    282                         r = Rflag.SLAVE;
    283                         break;
    284                 case 3:
    285                         r = Rflag.UNKN;
    286                         break;
    287                 }
    288                 feature.rels.add(new Reln(id, r));
    289         }
    290        
    291         public void endFeature() {
    292                
    293         }
    294        
    295         public void newAtt(long attl, String atvl) {
    296                 Att att = S57att.decodeAttribute(attl);
    297                 AttVal<?> val = S57val.decodeValue(atvl, att);
    298                 feature.atts.put(att, val);
    299         }
    300 
    301         public void newPrim(long id, long ornt, long usag) {
    302                 feature.geom.elems.add(new Prim(id, (ornt != 2), (usag != 2)));
    303         }
    304 
    305         public void addConn(long id, int topi) {
    306                 if (topi == 1) {
    307                         edge.first = id;
    308                 } else {
    309                         edge.last = id;
    310                 }
    311         }
    312 
    313         public void newEdge(long id) {
    314                 edge = new Edge();
    315                 edges.put(id, edge);
    316         }
    317 
    318         public void endFile() {
    319                 for (long id : index.keySet()) {
    320                         Feature feature = index.get(id);
    321                         sortGeom(feature);
    322                         for (Reln reln : feature.rels) {
    323                                 Feature rel = index.get(reln.id);
    324                                 if (cmpGeoms(feature.geom, rel.geom)) {
    325                                         switch (reln.reln) {
    326                                         case SLAVE:
    327                                                 feature.reln = Rflag.MASTER;
    328                                                 break;
    329                                         default:
    330                                                 feature.reln = Rflag.UNKN;
    331                                                 break;
    332                                         }
    333                                         rel.reln = reln.reln;
    334                                 } else {
    335                                         reln.reln = Rflag.UNKN;
    336                                 }
    337                         }
    338                 }
    339                 for (long id : index.keySet()) {
    340                         Feature feature = index.get(id);
    341                         if (feature.reln == Rflag.UNKN) {
    342                                 feature.reln = Rflag.MASTER;
    343                         }
    344                         if ((feature.type != Obj.UNKOBJ) && (feature.reln == Rflag.MASTER)) {
    345                                 if (features.get(feature.type) == null) {
    346                                         features.put(feature.type, new ArrayList<Feature>());
    347                                 }
    348                                 features.get(feature.type).add(feature);
    349                         }
    350                 }
    351                 for (long id : index.keySet()) {
    352                         Feature feature = index.get(id);
    353                         for (Reln reln : feature.rels) {
    354                                 Feature rel = index.get(reln.id);
    355                                 if (rel.reln == Rflag.SLAVE) {
    356                                         if (feature.objs.get(rel.type) == null) {
    357                                                 feature.objs.put(rel.type, new ObjTab());
    358                                         }
    359                                         ObjTab tab = feature.objs.get(rel.type);
    360                                         int ix = tab.size();
    361                                         tab.put(ix, rel.atts);
    362                                 }
    363                         }
    364                 }
    365         }
    366 
    367         // OSM map building methods
    368 
    369         public void addNode(long id, double lat, double lon) {
    370                 nodes.put(id, new Snode(Math.toRadians(lat), Math.toRadians(lon)));
    371                 feature = new Feature();
    372                 feature.id = id;
    373                 feature.reln = Rflag.UNKN;
    374                 feature.geom.prim = Pflag.POINT;
    375                 feature.geom.elems.add(new Prim(id));
    376                 edge = null;
    377                 osm =  new ArrayList<>();
    378         }
    379 
    380         public void addEdge(long id) {
    381                 feature = new Feature();
    382                 feature.id = id;
    383                 feature.reln = Rflag.UNKN;
    384                 feature.geom.prim = Pflag.LINE;
    385                 feature.geom.elems.add(new Prim(id));
    386                 edge = new Edge();
    387                 osm = new ArrayList<>();
    388         }
    389 
    390         public void addToEdge(long node) {
    391                 if (edge.first == 0) {
    392                         edge.first = node;
    393                         nodes.get(node).flg = Nflag.CONN;
    394                 } else {
    395                         if (edge.last != 0) {
    396                                 edge.nodes.add(edge.last);
    397                         }
    398                         edge.last = node;
    399                 }
    400         }
    401 
    402         public void addArea(long id) {
    403                 feature = new Feature();
    404                 feature.id = id;
    405                 feature.reln = Rflag.UNKN;
    406                 feature.geom.prim = Pflag.AREA;
    407                 edge = null;
    408                 osm = new ArrayList<>();
    409         }
    410 
    411         public void addToArea(long id, boolean outer) {
    412                 feature.geom.elems.add(new Prim(id, outer));
    413         }
    414 
    415         public void addTag(String key, String val) {
    416                 feature.reln = Rflag.MASTER;
    417                 String subkeys[] = key.split(":");
    418                 if ((subkeys.length > 1) && subkeys[0].equals("seamark")) {
    419                         Obj obj = S57obj.enumType(subkeys[1]);
    420                         if ((subkeys.length > 2) && (obj != Obj.UNKOBJ)) {
    421                                 int idx = 0;
    422                                 Att att = Att.UNKATT;
    423                                 try {
    424                                         idx = Integer.parseInt(subkeys[2]);
    425                                         if (subkeys.length == 4) {
    426                                                 att = s57.S57att.enumAttribute(subkeys[3], obj);
    427                                         }
    428                                 } catch (Exception e) {
    429                                         att = S57att.enumAttribute(subkeys[2], obj);
    430                                 }
    431                                 ObjTab objs = feature.objs.get(obj);
    432                                 if (objs == null) {
    433                                         objs = new ObjTab();
    434                                         feature.objs.put(obj, objs);
    435                                 }
    436                                 AttMap atts = objs.get(idx);
    437                                 if (atts == null) {
    438                                         atts = new AttMap();
    439                                         objs.put(idx, atts);
    440                                 }
    441                                 AttVal<?> attval = S57val.convertValue(val, att);
    442                                 if (attval.val != null) {
    443                                         if (att == Att.VALSOU) {
    444                                                 Snode node = nodes.get(feature.geom.elems.get(0).id);
    445                                                 node.val = (Double) attval.val;
    446                                         }
    447                                         atts.put(att, attval);
    448                                 }
    449                         } else {
    450                                 if (subkeys[1].equals("type")) {
    451                                         obj = S57obj.enumType(val);
    452                                         feature.type = obj;
    453                                         ObjTab objs = feature.objs.get(obj);
    454                                         if (objs == null) {
    455                                                 objs = new ObjTab();
    456                                                 feature.objs.put(obj, objs);
    457                                         }
    458                                         AttMap atts = objs.get(0);
    459                                         if (atts == null) {
    460                                                 atts = new AttMap();
    461                                                 objs.put(0, atts);
    462                                         }
    463                                         if ((obj == Obj.SOUNDG) && (feature.geom.prim == Pflag.POINT)) {
    464                                                 Snode node = nodes.get(feature.geom.elems.get(0).id);
    465                                                 node.flg = Nflag.DPTH;
    466                                         }
    467                                 } else {
    468                                         if (obj != Obj.UNKOBJ) {
    469                                                 if (val.equals("yes")) {
    470                                                         ObjTab objs = feature.objs.get(obj);
    471                                                         if (objs == null) {
    472                                                                 objs = new ObjTab();
    473                                                                 feature.objs.put(obj, objs);
    474                                                         }
    475                                                 }
    476                                         } else {
    477                                                 Att att = S57att.enumAttribute(subkeys[1], Obj.UNKOBJ);
    478                                                 if (att != Att.UNKATT) {
    479                                                         AttVal<?> attval = S57val.convertValue(val, att);
    480                                                         if (attval.val != null)
    481                                                                 feature.atts.put(att, attval);
    482                                                 }
    483                                         }
    484                                 }
    485                         }
    486                 } else if (!sea) {
    487                         S57osm.OSMtag(osm, key, val);
    488                 }
    489         }
    490 
    491         public void tagsDone(long id) {
    492                 switch (feature.geom.prim) {
    493                 case POINT:
    494                         Snode node = nodes.get(id);
    495                         if ((node.flg != Nflag.CONN) && (node.flg != Nflag.DPTH) && (!feature.objs.isEmpty() || !osm.isEmpty())) {
    496                                 node.flg = Nflag.ISOL;
    497                         }
    498                         break;
    499                 case LINE:
    500                         edges.put(id, edge);
    501                         nodes.get(edge.first).flg = Nflag.CONN;
    502                         nodes.get(edge.last).flg = Nflag.CONN;
    503                         if (edge.first == edge.last) {
    504                                 feature.geom.prim = Pflag.AREA;
    505                         }
    506                         break;
    507                 case AREA:
    508                         break;
    509                 default:
    510                         break;
    511                 }
    512                 if (sortGeom(feature) && !((edge != null) && (edge.last == 0))) {
    513                         if (feature.type != Obj.UNKOBJ) {
    514                                 index.put(id, feature);
    515                                 if (features.get(feature.type) == null) {
    516                                         features.put(feature.type, new ArrayList<Feature>());
    517                                 }
    518                                 features.get(feature.type).add(feature);
    519                         }
    520                         for (KeyVal<?> kvx : osm) {
    521                                 Feature base = new Feature();
    522                                 base.reln = Rflag.MASTER;
    523                                 base.geom = feature.geom;
    524                                 base.type = kvx.obj;
    525                                 ObjTab objs = new ObjTab();
    526                                 base.objs.put(kvx.obj, objs);
    527                                 AttMap atts = new AttMap();
    528                                 objs.put(0, atts);
    529                                 if (kvx.att != Att.UNKATT) {
    530                                         atts.put(kvx.att, new AttVal<>(kvx.conv, kvx.val));
    531                                 }
    532                                 index.put(++xref, base);
    533                                 if (features.get(kvx.obj) == null) {
    534                                         features.put(kvx.obj, new ArrayList<Feature>());
    535                                 }
    536                                 features.get(kvx.obj).add(base);
    537                         }
    538 /*                      if (!osm.isEmpty()) {
    539                                 if (feature.type == Obj.UNKOBJ) {
    540                                         feature.type = osm.obj;
    541                                         ObjTab objs = feature.objs.get(osm.obj);
    542                                         if (objs == null) {
    543                                                 objs = new ObjTab();
    544                                                 feature.objs.put(osm.obj, objs);
    545                                         }
    546                                         AttMap atts = objs.get(0);
    547                                         if (atts == null) {
    548                                                 atts = new AttMap();
    549                                                 objs.put(0, atts);
    550                                         }
    551                                         if (osm.att != Att.UNKATT) {
    552                                                 atts.put(osm.att, new AttVal<>(osm.conv, osm.val));
    553                                         }
    554                                 } else {
    555                                         Feature base = new Feature();
    556                                         base.reln = Rflag.MASTER;
    557                                         base.geom = feature.geom;
    558                                         base.type = osm.obj;
    559                                         ObjTab objs = new ObjTab();
    560                                         base.objs.put(osm.obj, objs);
    561                                         AttMap atts = new AttMap();
    562                                         objs.put(0, atts);
    563                                         if (osm.att != Att.UNKATT) {
    564                                                 atts.put(osm.att, new AttVal<>(osm.conv, osm.val));
    565                                         }
    566                                         index.put(++xref, base);
    567                                         if (features.get(osm.obj) == null) {
    568                                                 features.put(osm.obj, new ArrayList<Feature>());
    569                                         }
    570                                         features.get(osm.obj).add(base);
    571                                 }
    572                         }*/
    573                 }
    574         }
    575        
    576         public void mapDone() {
    577                 if (!sea) {
    578                         S57box.bBox(this);
    579                 }
    580         }
    581        
    582         // Utility methods
    583 
    584         public boolean sortGeom(Feature feature) {
    585                 try {
    586                         Geom sort = new Geom(feature.geom.prim);
    587                         long first = 0;
    588                         long last = 0;
    589                         Comp comp = null;
    590                         boolean next = true;
    591                         feature.geom.length = 0;
    592                         feature.geom.area = 0;
    593                         if (feature.geom.elems.isEmpty()) {
    594                                 return false;
    595                         }
    596                         if (feature.geom.prim == Pflag.POINT) {
    597                                 feature.geom.centre = nodes.get(feature.geom.elems.get(0).id);
    598                                 return true;
    599                         }
    600                         Geom outer = new Geom(feature.geom.prim);
    601                         Geom inner = new Geom(feature.geom.prim);
    602                         for (Prim prim : feature.geom.elems) {
    603                                 if (prim.outer) {
    604                                         outer.elems.add(prim);
    605                                 } else {
    606                                         inner.elems.add(prim);
    607                                 }
    608                         }
    609                         boolean outin = true;
    610                         int sweep = outer.elems.size();
    611                         if (sweep == 0) {
    612                                 return false;
    613                         }
    614                         int prev = sweep;
    615                         int top = 0;
    616                         while (!outer.elems.isEmpty()) {
    617                                 Prim prim = outer.elems.remove(0);
    618                                 Edge edge = edges.get(prim.id);
    619                                 if (edge == null) {
    620                                         return false;
    621                                 }
    622                                 if (next == true) {
    623                                         next = false;
    624                                         first = edge.first;
    625                                         last = edge.last;
    626                                         prim.forward = true;
    627                                         sort.elems.add(prim);
    628                                         if (prim.outer) {
    629                                                 sort.outers++;
    630                                         } else {
    631                                                 sort.inners++;
    632                                         }
    633                                         comp = new Comp(cref++, 1);
    634                                         sort.comps.add(comp);
    635                                 } else {
    636                                         if (edge.first == last) {
    637                                                 sort.elems.add(prim);
    638                                                 last = edge.last;
    639                                                 prim.forward = true;
    640                                                 comp.size++;
    641                                         } else if (edge.last == first) {
    642                                                 sort.elems.add(top, prim);
    643                                                 first = edge.first;
    644                                                 prim.forward = true;
    645                                                 comp.size++;
    646                                         } else if (edge.last == last) {
    647                                                 sort.elems.add(prim);
    648                                                 last = edge.first;
    649                                                 prim.forward = false;
    650                                                 comp.size++;
    651                                         } else if (edge.first == first) {
    652                                                 sort.elems.add(top, prim);
    653                                                 first = edge.last;
    654                                                 prim.forward = false;
    655                                                 comp.size++;
    656                                         } else {
    657                                                 outer.elems.add(prim);
    658                                         }
    659                                 }
    660                                 if (--sweep == 0) {
    661                                         sweep = outer.elems.size();
    662                                         if ((sweep == 0) || (sweep == prev)) {
    663                                                 if ((sort.prim == Pflag.AREA) && (first != last)) {
    664                                                         return false;
    665                                                 }
    666                                                 if (outin) {
    667                                                         if (sweep != 0) {
    668                                                                 return false;
    669                                                         }
    670                                                         outer = inner;
    671                                                         outin = false;
    672                                                         sweep = outer.elems.size();
    673                                                 }
    674                                                 next = true;
    675                                                 top = sort.elems.size();
    676                                         }
    677                                         prev = sweep;
    678                                 }
    679                         }
    680                         if ((sort.prim == Pflag.LINE) && (sort.outers == 1) && (sort.inners == 0) && (first == last)) {
    681                                 sort.prim = Pflag.AREA;
    682                         }
    683                         feature.geom = sort;
    684                         if (feature.geom.prim == Pflag.AREA) {
    685                                 int ie = 0;
    686                                 int ic = 0;
    687                                 while (ie < feature.geom.elems.size()) {
    688                                         double area = calcArea(feature.geom, ic);
    689                                         if (ie == 0)
    690                                                 feature.geom.area = Math.abs(area) * 3444 * 3444;
    691                                         if (((ie == 0) && (area < 0.0)) || ((ie > 0) && (area >= 0.0))) {
    692                                                 ArrayList<Prim> tmp = new ArrayList<>();
    693                                                 for (int i = 0; i < feature.geom.comps.get(ic).size; i++) {
    694                                                         Prim p = feature.geom.elems.remove(ie);
    695                                                         p.forward = !p.forward;
    696                                                         tmp.add(0, p);
    697                                                 }
    698                                                 feature.geom.elems.addAll(ie, tmp);
    699                                         }
    700                                         ie += feature.geom.comps.get(ic).size;
    701                                         ic++;
    702                                 }
    703                         }
    704                         feature.geom.length = calcLength(feature.geom);
    705                         feature.geom.centre = calcCentroid(feature);
    706                         return true;
    707                 } catch (Exception e) {
    708                         return false;
    709                 }
    710         }
    711        
    712         public boolean cmpGeoms (Geom g1, Geom g2) {
    713                 return ((g1.prim == g2.prim) && (g1.outers == g2.outers) && (g1.inners == g2.inners) && (g1.elems.size() == g2.elems.size()));
    714         }
    715        
    716         public class EdgeIterator {
    717                 Edge edge;
    718                 boolean forward;
    719                 ListIterator<Long> it;
    720 
    721                 public EdgeIterator(Edge e, boolean dir) {
    722                         edge = e;
    723                         forward = dir;
    724                         it = null;
    725                 }
    726 
    727                 public boolean hasNext() {
    728                         return (edge != null);
    729                 }
    730 
    731                 public long nextRef() {
    732                         long ref = 0;
    733                         if (forward) {
    734                                 if (it == null) {
    735                                         ref = edge.first;
    736                                         it = edge.nodes.listIterator();
    737                                 } else {
    738                                         if (it.hasNext()) {
    739                                                 ref = it.next();
    740                                         } else {
    741                                                 ref = edge.last;
    742                                                 edge = null;
    743                                         }
    744                                 }
    745                         } else {
    746                                 if (it == null) {
    747                                         ref = edge.last;
    748                                         it = edge.nodes.listIterator(edge.nodes.size());
    749                                 } else {
    750                                         if (it.hasPrevious()) {
    751                                                 ref = it.previous();
    752                                         } else {
    753                                                 ref = edge.first;
    754                                                 edge = null;
    755                                         }
    756                                 }
    757                         }
    758                         return ref;
    759                 }
    760                
    761                 public Snode next() {
    762                         return nodes.get(nextRef());
    763                 }
    764         }
    765 
    766         public class GeomIterator {
    767                 Geom geom;
    768                 Prim prim;
    769                 EdgeIterator eit;
    770                 ListIterator<S57map.Prim> ite;
    771                 ListIterator<Comp> itc;
    772                 Comp comp;
    773                 int ec;
    774                 long lastref;
    775 
    776                 public GeomIterator(Geom g) {
    777                         geom = g;
    778                         lastref = 0;
    779                         ite = geom.elems.listIterator();
    780                         itc = geom.comps.listIterator();
    781                 }
    782                
    783                 public boolean hasComp() {
    784                         return (itc.hasNext());
    785                 }
    786                
    787                 public long nextComp() {
    788                         comp = itc.next();
    789                         ec = comp.size;
    790                         lastref = 0;
    791                         return comp.ref;
    792                 }
    793                
    794                 public boolean hasEdge() {
    795                         return (ec > 0) && ite.hasNext();
    796                 }
    797                
    798                 public long nextEdge() {
    799                         prim = ite.next();
    800                         eit = new EdgeIterator(edges.get(prim.id), prim.forward);
    801                         ec--;
    802                         return prim.id;
    803                 }
    804                
    805                 public boolean hasNode() {
    806                         return (eit.hasNext());
    807                 }
    808                
    809                 public long nextRef(boolean all) {
    810                         long ref = eit.nextRef();
    811                         if (!all && (ref == lastref)) {
    812                                 ref = eit.nextRef();
    813                         }
    814                         lastref = ref;
    815                         return ref;
    816                 }
    817                
    818                 public long nextRef() {
    819                         return nextRef(false);
    820                 }
    821                
    822                 public Snode next() {
    823                         return nodes.get(nextRef());
    824                 }
    825         }
    826        
    827         double calcArea(Geom geom, int comp) {
    828                 Snode node;
    829                 double lat, lon, llon, llat;
    830                 lat = lon = llon = llat = 0;
    831                 double sigma = 0;
    832                 GeomIterator git = new GeomIterator(geom);
    833                 for (int i = 0; i <= comp; i++) {
    834                         if (git.hasComp()) {
    835                                 git.nextComp();
    836                                 while (git.hasEdge()) {
    837                                         git.nextEdge();
    838                                         while (git.hasNode()) {
    839                                                 node = git.next();
    840                                                 if (node == null)
    841                                                         continue;
    842                                                 llon = lon;
    843                                                 llat = lat;
    844                                                 lat = node.lat;
    845                                                 lon = node.lon;
    846                                                 sigma += (lon * Math.sin(llat)) - (llon * Math.sin(lat));
    847                                         }
    848                                 }
    849                                 if (i != comp)
    850                                         sigma = lat = lon = llon = llat = 0;
    851                         }
    852                 }
    853                 return sigma / 2.0;
    854         }
    855 
    856         double calcLength(Geom geom) {
    857                 Snode node;
    858                 double lat, lon, llon, llat;
    859                 lat = lon = llon = llat = 0;
    860                 double sigma = 0;
    861                 boolean first = true;
    862                 GeomIterator git = new GeomIterator(geom);
    863                 while (git.hasComp()) {
    864                         git.nextComp();
    865                         while (git.hasEdge()) {
    866                                 git.nextEdge();
    867                                 while (git.hasNode()) {
    868                                         node = git.next();
    869                                         if (first) {
    870                                                 first = false;
    871                                                 lat = node.lat;
    872                                                 lon = node.lon;
    873                                         } else if (node != null) {
    874                                                 llat = lat;
    875                                                 llon = lon;
    876                                                 lat = node.lat;
    877                                                 lon = node.lon;
    878                                                 sigma += Math.acos(Math.sin(lat) * Math.sin(llat) + Math.cos(lat) * Math.cos(llat) * Math.cos(llon - lon));
    879                                         }
    880                                 }
    881                         }
    882                 }
    883                 return sigma * 3444;
    884         }
    885 
    886         Snode calcCentroid(Feature feature) {
    887                 double lat, lon, slat, slon, llat, llon;
    888                 llat = llon = lat = lon = slat = slon = 0;
    889                 double sarc = 0;
    890                 boolean first = true;
    891                 switch (feature.geom.prim) {
    892                 case POINT:
    893                         return nodes.get(feature.geom.elems.get(0).id);
    894                 case LINE:
    895                         GeomIterator git = new GeomIterator(feature.geom);
    896                         while (git.hasComp()) {
    897                                 git.nextComp();
    898                                 while (git.hasEdge()) {
    899                                         git.nextEdge();
    900                                         while (git.hasNode()) {
    901                                                 Snode node = git.next();
    902                                                 if (node == null) continue;
    903                                                 lat = node.lat;
    904                                                 lon = node.lon;
    905                                                 if (first) {
    906                                                         first = false;
    907                                                 } else {
    908                                                         sarc += (Math.acos(Math.cos(lon - llon) * Math.cos(lat - llat)));
    909                                                 }
    910                                                 llat = lat;
    911                                                 llon = lon;
    912                                         }
    913                                 }
    914                         }
    915                         double harc = sarc / 2;
    916                         sarc = 0;
    917                         first = true;
    918                         git = new GeomIterator(feature.geom);
    919                         while (git.hasComp()) {
    920                                 git.nextComp();
    921                                 while (git.hasEdge()) {
    922                                         git.nextEdge();
    923                                         while (git.hasNode()) {
    924                                                 Snode node = git.next();
    925                                                 if (node == null) continue;
    926                                                 lat = node.lat;
    927                                                 lon = node.lon;
    928                                                 if (first) {
    929                                                         first = false;
    930                                                 } else {
    931                                                         sarc = (Math.acos(Math.cos(lon - llon) * Math.cos(lat - llat)));
    932                                                         if (sarc > harc)
    933                                                                 break;
    934                                                 }
    935                                                 harc -= sarc;
    936                                                 llat = lat;
    937                                                 llon = lon;
    938                                         }
    939                                 }
    940                         }
    941                         return new Snode(llat + ((lat - llat) * harc / sarc), llon + ((lon - llon) * harc / sarc));
    942                 case AREA:
    943                         git = new GeomIterator(feature.geom);
    944                         while (git.hasComp()) {
    945                                 git.nextComp();
    946                                 while (git.hasEdge()) {
    947                                         git.nextEdge();
    948                                         while (git.hasNode()) {
    949                                                 Snode node = git.next();
    950                                                 lat = node.lat;
    951                                                 lon = node.lon;
    952                                                 if (first) {
    953                                                         first = false;
    954                                                 } else {
    955                                                         double arc = (Math.acos(Math.cos(lon - llon) * Math.cos(lat - llat)));
    956                                                         slat += ((lat + llat) / 2 * arc);
    957                                                         slon += ((lon + llon) / 2 * arc);
    958                                                         sarc += arc;
    959                                                 }
    960                                                 llon = lon;
    961                                                 llat = lat;
    962                                         }
    963                                 }
    964                         }
    965                         return new Snode((sarc > 0.0 ? slat / sarc : 0.0), (sarc > 0.0 ? slon / sarc : 0.0));
    966                 default:
    967                 }
    968                 return null;
    969         }
     23    // CHECKSTYLE.OFF: LineLength
     24
     25    public class MapBounds {
     26        public double minlat;
     27        public double minlon;
     28        public double maxlat;
     29        public double maxlon;
     30        public MapBounds() {
     31            minlat = Math.toRadians(90);
     32            minlon = Math.toRadians(180);
     33            maxlat = Math.toRadians(-90);
     34            maxlon = Math.toRadians(-180);
     35        }
     36    }
     37
     38    public enum Nflag {
     39        ANON,    // Edge inner nodes
     40        ISOL,    // Node not part of Edge
     41        CONN,    // Edge first and last nodes
     42        TRNK, // Edge truncated polygon nodes
     43        DPTH    // Sounding nodes
     44    }
     45
     46    public class Snode {    // All coordinates in map
     47        public double lat;    // Latitude in radians
     48        public double lon;    // Longitude in radians
     49        public Nflag flg;        // Role of node
     50        public double val;    // Optional value
     51
     52        public Snode() {
     53            flg = Nflag.ANON;
     54            lat = 0;
     55            lon = 0;
     56            val = 0;
     57        }
     58
     59        public Snode(double ilat, double ilon) {
     60            flg = Nflag.ANON;
     61            lat = ilat;
     62            lon = ilon;
     63            val = 0;
     64        }
     65
     66        public Snode(double ilat, double ilon, Nflag iflg) {
     67            lat = ilat;
     68            lon = ilon;
     69            flg = iflg;
     70            val = 0;
     71        }
     72
     73        public Snode(double ilat, double ilon, double ival) {
     74            flg = Nflag.DPTH;
     75            lat = ilat;
     76            lon = ilon;
     77            val = ival;
     78        }
     79    }
     80
     81    public class Edge {        // A polyline segment
     82        public long first;    // First CONN node
     83        public long last;        // Last CONN node
     84        public ArrayList<Long> nodes; // Inner ANON nodes
     85
     86        public Edge() {
     87            first = 0;
     88            last = 0;
     89            nodes = new ArrayList<>();
     90        }
     91    }
     92
     93    public enum Rflag {
     94        UNKN, MASTER, SLAVE
     95    }
     96
     97    public class Reln {
     98        public long id;
     99        public Rflag reln;
     100        public Reln(long i, Rflag r) {
     101            id = i;
     102            reln = r;
     103        }
     104    }
     105
     106    public class RelTab extends ArrayList<Reln> {
     107        public RelTab() {
     108            super();
     109        }
     110    }
     111
     112    public class ObjTab extends HashMap<Integer, AttMap> {
     113        public ObjTab() {
     114            super();
     115        }
     116    }
     117
     118    public class ObjMap extends EnumMap<Obj, ObjTab> {
     119        public ObjMap() {
     120            super(Obj.class);
     121        }
     122    }
     123
     124    public class AttMap extends HashMap<Att, AttVal<?>> {
     125        public AttMap() {
     126            super();
     127        }
     128    }
     129
     130    public class NodeTab extends HashMap<Long, Snode> {
     131        public NodeTab() {
     132            super();
     133        }
     134    }
     135
     136    public class EdgeTab extends HashMap<Long, Edge> {
     137        public EdgeTab() {
     138            super();
     139        }
     140    }
     141
     142    public class FtrMap extends EnumMap<Obj, ArrayList<Feature>> {
     143        public FtrMap() {
     144            super(Obj.class);
     145        }
     146    }
     147
     148    public class FtrTab extends HashMap<Long, Feature> {
     149        public FtrTab() {
     150            super();
     151        }
     152    }
     153
     154    public class Prim {                // Spatial element
     155        public long id;                    // Snode ID for POINTs, Edge ID for LINEs & AREAs)
     156        public boolean forward;    // Direction of vector used (LINEs & AREAs)
     157        public boolean outer;        // Exterior/Interior boundary (AREAs)
     158        public boolean trunc;        // Cell limit truncation
     159        public Prim() {
     160            id = 0; forward = true; outer = true; trunc = false;
     161        }
     162
     163        public Prim(long i) {
     164            id = i; forward = true; outer = true; trunc = false;
     165        }
     166
     167        public Prim(long i, boolean o) {
     168            id = i; forward = true; outer = o; trunc = false;
     169        }
     170
     171        public Prim(long i, boolean f, boolean o) {
     172            id = i; forward = f; outer = o; trunc = false;
     173        }
     174
     175        public Prim(long i, boolean f, boolean o, boolean t) {
     176            id = i; forward = f; outer = o; trunc = t;
     177        }
     178    }
     179
     180    public class Comp {            // Composite spatial element
     181        public long ref;            // ID of Comp
     182        public int size;            // Number of Prims in this Comp
     183        public Comp(long r, int s) {
     184            ref = r;
     185            size = s;
     186        }
     187    }
     188
     189    public enum Pflag {
     190        NOSP, POINT, LINE, AREA
     191    }
     192
     193    public class Geom {                            // Geometric structure of feature
     194        public Pflag prim;                        // Geometry type
     195        public ArrayList<Prim> elems;    // Ordered list of elements
     196        public int outers;                        // Number of outers
     197        public int inners;                        // Number of inners
     198        public ArrayList<Comp> comps;    // Ordered list of compounds
     199        public double area;                        // Area of feature
     200        public double length;                    // Length of feature
     201        public Snode centre;                    // Centre of feature
     202        public Geom(Pflag p) {
     203            prim = p;
     204            elems = new ArrayList<>();
     205            outers = inners = 0;
     206            comps = new ArrayList<>();
     207            area = 0;
     208            length = 0;
     209            centre = new Snode();
     210        }
     211    }
     212
     213    public class Feature {
     214        public long id;                // Ref for this feature
     215        public Rflag reln;        // Relationship status
     216        public Geom geom;            // Geometry data
     217        public Obj type;            // Feature type
     218        public AttMap atts;        // Feature attributes
     219        public RelTab rels;        // Related objects
     220        public ObjMap objs;        // Slave object attributes
     221
     222        Feature() {
     223            id = 0;
     224            reln = Rflag.UNKN;
     225            geom = new Geom(Pflag.NOSP);
     226            type = Obj.UNKOBJ;
     227            atts = new AttMap();
     228            rels = new RelTab();
     229            objs = new ObjMap();
     230        }
     231    }
     232
     233    public MapBounds bounds;
     234    public NodeTab nodes;
     235    public EdgeTab edges;
     236    public FtrMap features;
     237    public FtrTab index;
     238    public long xref;
     239
     240    private long cref;
     241    private Feature feature;
     242    private Edge edge;
     243    private ArrayList<KeyVal<?>> osm;
     244    private boolean sea;
     245
     246    public S57map(boolean s) {
     247        sea = s;
     248        nodes = new NodeTab();      // All nodes in map
     249        edges = new EdgeTab();      // All edges in map
     250        feature = new Feature();    // Current feature being built
     251        features = new FtrMap();    // All features in map, grouped by type
     252        index = new FtrTab();       // Feature look-up table
     253        bounds = new MapBounds();
     254        cref = 0x0000ffffffff0000L; // Compound reference generator
     255        xref = 0x0fff000000000000L; // Extras reference generator
     256    }
     257
     258    // S57 map building methods
     259
     260    public void newNode(long id, double lat, double lon, Nflag flag) {
     261        nodes.put(id, new Snode(Math.toRadians(lat), Math.toRadians(lon), flag));
     262        if (flag == Nflag.ANON) {
     263            edge.nodes.add(id);
     264        }
     265    }
     266
     267    public void newNode(long id, double lat, double lon, double depth) {
     268        nodes.put(id, new Snode(Math.toRadians(lat), Math.toRadians(lon), depth));
     269    }
     270
     271    public void newFeature(long id, Pflag p, long objl) {
     272        feature = new Feature();
     273        Obj obj = S57obj.decodeType(objl);
     274        feature.geom = new Geom(p);
     275        feature.type = obj;
     276        if (obj != Obj.UNKOBJ) {
     277            index.put(id, feature);
     278            feature.id = id;
     279        }
     280    }
     281
     282    public void refObj(long id, int rind) {
     283        Rflag r = Rflag.UNKN;
     284        switch (rind) {
     285        case 1:
     286            r = Rflag.MASTER;
     287            break;
     288        case 2:
     289            r = Rflag.SLAVE;
     290            break;
     291        case 3:
     292            r = Rflag.UNKN;
     293            break;
     294        }
     295        feature.rels.add(new Reln(id, r));
     296    }
     297
     298    public void endFeature() {
     299
     300    }
     301
     302    public void newAtt(long attl, String atvl) {
     303        Att att = S57att.decodeAttribute(attl);
     304        AttVal<?> val = S57val.decodeValue(atvl, att);
     305        feature.atts.put(att, val);
     306    }
     307
     308    public void newPrim(long id, long ornt, long usag) {
     309        feature.geom.elems.add(new Prim(id, (ornt != 2), (usag != 2)));
     310    }
     311
     312    public void addConn(long id, int topi) {
     313        if (topi == 1) {
     314            edge.first = id;
     315        } else {
     316            edge.last = id;
     317        }
     318    }
     319
     320    public void newEdge(long id) {
     321        edge = new Edge();
     322        edges.put(id, edge);
     323    }
     324
     325    public void endFile() {
     326        for (long id : index.keySet()) {
     327            Feature feature = index.get(id);
     328            sortGeom(feature);
     329            for (Reln reln : feature.rels) {
     330                Feature rel = index.get(reln.id);
     331                if (cmpGeoms(feature.geom, rel.geom)) {
     332                    switch (reln.reln) {
     333                    case SLAVE:
     334                        feature.reln = Rflag.MASTER;
     335                        break;
     336                    default:
     337                        feature.reln = Rflag.UNKN;
     338                        break;
     339                    }
     340                    rel.reln = reln.reln;
     341                } else {
     342                    reln.reln = Rflag.UNKN;
     343                }
     344            }
     345        }
     346        for (long id : index.keySet()) {
     347            Feature feature = index.get(id);
     348            if (feature.reln == Rflag.UNKN) {
     349                feature.reln = Rflag.MASTER;
     350            }
     351            if ((feature.type != Obj.UNKOBJ) && (feature.reln == Rflag.MASTER)) {
     352                if (features.get(feature.type) == null) {
     353                    features.put(feature.type, new ArrayList<Feature>());
     354                }
     355                features.get(feature.type).add(feature);
     356            }
     357        }
     358        for (long id : index.keySet()) {
     359            Feature feature = index.get(id);
     360            for (Reln reln : feature.rels) {
     361                Feature rel = index.get(reln.id);
     362                if (rel.reln == Rflag.SLAVE) {
     363                    if (feature.objs.get(rel.type) == null) {
     364                        feature.objs.put(rel.type, new ObjTab());
     365                    }
     366                    ObjTab tab = feature.objs.get(rel.type);
     367                    int ix = tab.size();
     368                    tab.put(ix, rel.atts);
     369                }
     370            }
     371        }
     372    }
     373
     374    // OSM map building methods
     375
     376    public void addNode(long id, double lat, double lon) {
     377        nodes.put(id, new Snode(Math.toRadians(lat), Math.toRadians(lon)));
     378        feature = new Feature();
     379        feature.id = id;
     380        feature.reln = Rflag.UNKN;
     381        feature.geom.prim = Pflag.POINT;
     382        feature.geom.elems.add(new Prim(id));
     383        edge = null;
     384        osm = new ArrayList<>();
     385    }
     386
     387    public void addEdge(long id) {
     388        feature = new Feature();
     389        feature.id = id;
     390        feature.reln = Rflag.UNKN;
     391        feature.geom.prim = Pflag.LINE;
     392        feature.geom.elems.add(new Prim(id));
     393        edge = new Edge();
     394        osm = new ArrayList<>();
     395    }
     396
     397    public void addToEdge(long node) {
     398        if (edge.first == 0) {
     399            edge.first = node;
     400            nodes.get(node).flg = Nflag.CONN;
     401        } else {
     402            if (edge.last != 0) {
     403                edge.nodes.add(edge.last);
     404            }
     405            edge.last = node;
     406        }
     407    }
     408
     409    public void addArea(long id) {
     410        feature = new Feature();
     411        feature.id = id;
     412        feature.reln = Rflag.UNKN;
     413        feature.geom.prim = Pflag.AREA;
     414        edge = null;
     415        osm = new ArrayList<>();
     416    }
     417
     418    public void addToArea(long id, boolean outer) {
     419        feature.geom.elems.add(new Prim(id, outer));
     420    }
     421
     422    public void addTag(String key, String val) {
     423        feature.reln = Rflag.MASTER;
     424        String[] subkeys = key.split(":");
     425        if ((subkeys.length > 1) && subkeys[0].equals("seamark")) {
     426            Obj obj = S57obj.enumType(subkeys[1]);
     427            if ((subkeys.length > 2) && (obj != Obj.UNKOBJ)) {
     428                int idx = 0;
     429                Att att = Att.UNKATT;
     430                try {
     431                    idx = Integer.parseInt(subkeys[2]);
     432                    if (subkeys.length == 4) {
     433                        att = s57.S57att.enumAttribute(subkeys[3], obj);
     434                    }
     435                } catch (Exception e) {
     436                    att = S57att.enumAttribute(subkeys[2], obj);
     437                }
     438                ObjTab objs = feature.objs.get(obj);
     439                if (objs == null) {
     440                    objs = new ObjTab();
     441                    feature.objs.put(obj, objs);
     442                }
     443                AttMap atts = objs.get(idx);
     444                if (atts == null) {
     445                    atts = new AttMap();
     446                    objs.put(idx, atts);
     447                }
     448                AttVal<?> attval = S57val.convertValue(val, att);
     449                if (attval.val != null) {
     450                    if (att == Att.VALSOU) {
     451                        Snode node = nodes.get(feature.geom.elems.get(0).id);
     452                        node.val = (Double) attval.val;
     453                    }
     454                    atts.put(att, attval);
     455                }
     456            } else {
     457                if (subkeys[1].equals("type")) {
     458                    obj = S57obj.enumType(val);
     459                    feature.type = obj;
     460                    ObjTab objs = feature.objs.get(obj);
     461                    if (objs == null) {
     462                        objs = new ObjTab();
     463                        feature.objs.put(obj, objs);
     464                    }
     465                    AttMap atts = objs.get(0);
     466                    if (atts == null) {
     467                        atts = new AttMap();
     468                        objs.put(0, atts);
     469                    }
     470                    if ((obj == Obj.SOUNDG) && (feature.geom.prim == Pflag.POINT)) {
     471                        Snode node = nodes.get(feature.geom.elems.get(0).id);
     472                        node.flg = Nflag.DPTH;
     473                    }
     474                } else {
     475                    if (obj != Obj.UNKOBJ) {
     476                        if (val.equals("yes")) {
     477                            ObjTab objs = feature.objs.get(obj);
     478                            if (objs == null) {
     479                                objs = new ObjTab();
     480                                feature.objs.put(obj, objs);
     481                            }
     482                        }
     483                    } else {
     484                        Att att = S57att.enumAttribute(subkeys[1], Obj.UNKOBJ);
     485                        if (att != Att.UNKATT) {
     486                            AttVal<?> attval = S57val.convertValue(val, att);
     487                            if (attval.val != null)
     488                                feature.atts.put(att, attval);
     489                        }
     490                    }
     491                }
     492            }
     493        } else if (!sea) {
     494            S57osm.OSMtag(osm, key, val);
     495        }
     496    }
     497
     498    public void tagsDone(long id) {
     499        switch (feature.geom.prim) {
     500        case POINT:
     501            Snode node = nodes.get(id);
     502            if ((node.flg != Nflag.CONN) && (node.flg != Nflag.DPTH) && (!feature.objs.isEmpty() || !osm.isEmpty())) {
     503                node.flg = Nflag.ISOL;
     504            }
     505            break;
     506        case LINE:
     507            edges.put(id, edge);
     508            nodes.get(edge.first).flg = Nflag.CONN;
     509            nodes.get(edge.last).flg = Nflag.CONN;
     510            if (edge.first == edge.last) {
     511                feature.geom.prim = Pflag.AREA;
     512            }
     513            break;
     514        case AREA:
     515            break;
     516        default:
     517            break;
     518        }
     519        if (sortGeom(feature) && !((edge != null) && (edge.last == 0))) {
     520            if (feature.type != Obj.UNKOBJ) {
     521                index.put(id, feature);
     522                if (features.get(feature.type) == null) {
     523                    features.put(feature.type, new ArrayList<Feature>());
     524                }
     525                features.get(feature.type).add(feature);
     526            }
     527            for (KeyVal<?> kvx : osm) {
     528                Feature base = new Feature();
     529                base.reln = Rflag.MASTER;
     530                base.geom = feature.geom;
     531                base.type = kvx.obj;
     532                ObjTab objs = new ObjTab();
     533                base.objs.put(kvx.obj, objs);
     534                AttMap atts = new AttMap();
     535                objs.put(0, atts);
     536                if (kvx.att != Att.UNKATT) {
     537                    atts.put(kvx.att, new AttVal<>(kvx.conv, kvx.val));
     538                }
     539                index.put(++xref, base);
     540                if (features.get(kvx.obj) == null) {
     541                    features.put(kvx.obj, new ArrayList<Feature>());
     542                }
     543                features.get(kvx.obj).add(base);
     544            }
     545            /*            if (!osm.isEmpty()) {
     546                if (feature.type == Obj.UNKOBJ) {
     547                    feature.type = osm.obj;
     548                    ObjTab objs = feature.objs.get(osm.obj);
     549                    if (objs == null) {
     550                        objs = new ObjTab();
     551                        feature.objs.put(osm.obj, objs);
     552                    }
     553                    AttMap atts = objs.get(0);
     554                    if (atts == null) {
     555                        atts = new AttMap();
     556                        objs.put(0, atts);
     557                    }
     558                    if (osm.att != Att.UNKATT) {
     559                        atts.put(osm.att, new AttVal<>(osm.conv, osm.val));
     560                    }
     561                } else {
     562                    Feature base = new Feature();
     563                    base.reln = Rflag.MASTER;
     564                    base.geom = feature.geom;
     565                    base.type = osm.obj;
     566                    ObjTab objs = new ObjTab();
     567                    base.objs.put(osm.obj, objs);
     568                    AttMap atts = new AttMap();
     569                    objs.put(0, atts);
     570                    if (osm.att != Att.UNKATT) {
     571                        atts.put(osm.att, new AttVal<>(osm.conv, osm.val));
     572                    }
     573                    index.put(++xref, base);
     574                    if (features.get(osm.obj) == null) {
     575                        features.put(osm.obj, new ArrayList<Feature>());
     576                    }
     577                    features.get(osm.obj).add(base);
     578                }
     579            }*/
     580        }
     581    }
     582
     583    public void mapDone() {
     584        if (!sea) {
     585            S57box.bBox(this);
     586        }
     587    }
     588
     589    // Utility methods
     590
     591    public boolean sortGeom(Feature feature) {
     592        try {
     593            Geom sort = new Geom(feature.geom.prim);
     594            long first = 0;
     595            long last = 0;
     596            Comp comp = null;
     597            boolean next = true;
     598            feature.geom.length = 0;
     599            feature.geom.area = 0;
     600            if (feature.geom.elems.isEmpty()) {
     601                return false;
     602            }
     603            if (feature.geom.prim == Pflag.POINT) {
     604                feature.geom.centre = nodes.get(feature.geom.elems.get(0).id);
     605                return true;
     606            }
     607            Geom outer = new Geom(feature.geom.prim);
     608            Geom inner = new Geom(feature.geom.prim);
     609            for (Prim prim : feature.geom.elems) {
     610                if (prim.outer) {
     611                    outer.elems.add(prim);
     612                } else {
     613                    inner.elems.add(prim);
     614                }
     615            }
     616            boolean outin = true;
     617            int sweep = outer.elems.size();
     618            if (sweep == 0) {
     619                return false;
     620            }
     621            int prev = sweep;
     622            int top = 0;
     623            while (!outer.elems.isEmpty()) {
     624                Prim prim = outer.elems.remove(0);
     625                Edge edge = edges.get(prim.id);
     626                if (edge == null) {
     627                    return false;
     628                }
     629                if (next == true) {
     630                    next = false;
     631                    first = edge.first;
     632                    last = edge.last;
     633                    prim.forward = true;
     634                    sort.elems.add(prim);
     635                    if (prim.outer) {
     636                        sort.outers++;
     637                    } else {
     638                        sort.inners++;
     639                    }
     640                    comp = new Comp(cref++, 1);
     641                    sort.comps.add(comp);
     642                } else {
     643                    if (edge.first == last) {
     644                        sort.elems.add(prim);
     645                        last = edge.last;
     646                        prim.forward = true;
     647                        comp.size++;
     648                    } else if (edge.last == first) {
     649                        sort.elems.add(top, prim);
     650                        first = edge.first;
     651                        prim.forward = true;
     652                        comp.size++;
     653                    } else if (edge.last == last) {
     654                        sort.elems.add(prim);
     655                        last = edge.first;
     656                        prim.forward = false;
     657                        comp.size++;
     658                    } else if (edge.first == first) {
     659                        sort.elems.add(top, prim);
     660                        first = edge.last;
     661                        prim.forward = false;
     662                        comp.size++;
     663                    } else {
     664                        outer.elems.add(prim);
     665                    }
     666                }
     667                if (--sweep == 0) {
     668                    sweep = outer.elems.size();
     669                    if ((sweep == 0) || (sweep == prev)) {
     670                        if ((sort.prim == Pflag.AREA) && (first != last)) {
     671                            return false;
     672                        }
     673                        if (outin) {
     674                            if (sweep != 0) {
     675                                return false;
     676                            }
     677                            outer = inner;
     678                            outin = false;
     679                            sweep = outer.elems.size();
     680                        }
     681                        next = true;
     682                        top = sort.elems.size();
     683                    }
     684                    prev = sweep;
     685                }
     686            }
     687            if ((sort.prim == Pflag.LINE) && (sort.outers == 1) && (sort.inners == 0) && (first == last)) {
     688                sort.prim = Pflag.AREA;
     689            }
     690            feature.geom = sort;
     691            if (feature.geom.prim == Pflag.AREA) {
     692                int ie = 0;
     693                int ic = 0;
     694                while (ie < feature.geom.elems.size()) {
     695                    double area = calcArea(feature.geom, ic);
     696                    if (ie == 0)
     697                        feature.geom.area = Math.abs(area) * 3444 * 3444;
     698                    if (((ie == 0) && (area < 0.0)) || ((ie > 0) && (area >= 0.0))) {
     699                        ArrayList<Prim> tmp = new ArrayList<>();
     700                        for (int i = 0; i < feature.geom.comps.get(ic).size; i++) {
     701                            Prim p = feature.geom.elems.remove(ie);
     702                            p.forward = !p.forward;
     703                            tmp.add(0, p);
     704                        }
     705                        feature.geom.elems.addAll(ie, tmp);
     706                    }
     707                    ie += feature.geom.comps.get(ic).size;
     708                    ic++;
     709                }
     710            }
     711            feature.geom.length = calcLength(feature.geom);
     712            feature.geom.centre = calcCentroid(feature);
     713            return true;
     714        } catch (Exception e) {
     715            return false;
     716        }
     717    }
     718
     719    public boolean cmpGeoms(Geom g1, Geom g2) {
     720        return ((g1.prim == g2.prim) && (g1.outers == g2.outers) && (g1.inners == g2.inners) && (g1.elems.size() == g2.elems.size()));
     721    }
     722
     723    public class EdgeIterator {
     724        Edge edge;
     725        boolean forward;
     726        ListIterator<Long> it;
     727
     728        public EdgeIterator(Edge e, boolean dir) {
     729            edge = e;
     730            forward = dir;
     731            it = null;
     732        }
     733
     734        public boolean hasNext() {
     735            return (edge != null);
     736        }
     737
     738        public long nextRef() {
     739            long ref = 0;
     740            if (forward) {
     741                if (it == null) {
     742                    ref = edge.first;
     743                    it = edge.nodes.listIterator();
     744                } else {
     745                    if (it.hasNext()) {
     746                        ref = it.next();
     747                    } else {
     748                        ref = edge.last;
     749                        edge = null;
     750                    }
     751                }
     752            } else {
     753                if (it == null) {
     754                    ref = edge.last;
     755                    it = edge.nodes.listIterator(edge.nodes.size());
     756                } else {
     757                    if (it.hasPrevious()) {
     758                        ref = it.previous();
     759                    } else {
     760                        ref = edge.first;
     761                        edge = null;
     762                    }
     763                }
     764            }
     765            return ref;
     766        }
     767
     768        public Snode next() {
     769            return nodes.get(nextRef());
     770        }
     771    }
     772
     773    public class GeomIterator {
     774        Geom geom;
     775        Prim prim;
     776        EdgeIterator eit;
     777        ListIterator<S57map.Prim> ite;
     778        ListIterator<Comp> itc;
     779        Comp comp;
     780        int ec;
     781        long lastref;
     782
     783        public GeomIterator(Geom g) {
     784            geom = g;
     785            lastref = 0;
     786            ite = geom.elems.listIterator();
     787            itc = geom.comps.listIterator();
     788        }
     789
     790        public boolean hasComp() {
     791            return (itc.hasNext());
     792        }
     793
     794        public long nextComp() {
     795            comp = itc.next();
     796            ec = comp.size;
     797            lastref = 0;
     798            return comp.ref;
     799        }
     800
     801        public boolean hasEdge() {
     802            return (ec > 0) && ite.hasNext();
     803        }
     804
     805        public long nextEdge() {
     806            prim = ite.next();
     807            eit = new EdgeIterator(edges.get(prim.id), prim.forward);
     808            ec--;
     809            return prim.id;
     810        }
     811
     812        public boolean hasNode() {
     813            return (eit.hasNext());
     814        }
     815
     816        public long nextRef(boolean all) {
     817            long ref = eit.nextRef();
     818            if (!all && (ref == lastref)) {
     819                ref = eit.nextRef();
     820            }
     821            lastref = ref;
     822            return ref;
     823        }
     824
     825        public long nextRef() {
     826            return nextRef(false);
     827        }
     828
     829        public Snode next() {
     830            return nodes.get(nextRef());
     831        }
     832    }
     833
     834    double calcArea(Geom geom, int comp) {
     835        Snode node;
     836        double lat, lon, llon, llat;
     837        lat = lon = llon = llat = 0;
     838        double sigma = 0;
     839        GeomIterator git = new GeomIterator(geom);
     840        for (int i = 0; i <= comp; i++) {
     841            if (git.hasComp()) {
     842                git.nextComp();
     843                while (git.hasEdge()) {
     844                    git.nextEdge();
     845                    while (git.hasNode()) {
     846                        node = git.next();
     847                        if (node == null)
     848                            continue;
     849                        llon = lon;
     850                        llat = lat;
     851                        lat = node.lat;
     852                        lon = node.lon;
     853                        sigma += (lon * Math.sin(llat)) - (llon * Math.sin(lat));
     854                    }
     855                }
     856                if (i != comp)
     857                    sigma = lat = lon = llon = llat = 0;
     858            }
     859        }
     860        return sigma / 2.0;
     861    }
     862
     863    double calcLength(Geom geom) {
     864        Snode node;
     865        double lat, lon, llon, llat;
     866        lat = lon = llon = llat = 0;
     867        double sigma = 0;
     868        boolean first = true;
     869        GeomIterator git = new GeomIterator(geom);
     870        while (git.hasComp()) {
     871            git.nextComp();
     872            while (git.hasEdge()) {
     873                git.nextEdge();
     874                while (git.hasNode()) {
     875                    node = git.next();
     876                    if (first) {
     877                        first = false;
     878                        lat = node.lat;
     879                        lon = node.lon;
     880                    } else if (node != null) {
     881                        llat = lat;
     882                        llon = lon;
     883                        lat = node.lat;
     884                        lon = node.lon;
     885                        sigma += Math.acos(Math.sin(lat) * Math.sin(llat) + Math.cos(lat) * Math.cos(llat) * Math.cos(llon - lon));
     886                    }
     887                }
     888            }
     889        }
     890        return sigma * 3444;
     891    }
     892
     893    Snode calcCentroid(Feature feature) {
     894        double lat, lon, slat, slon, llat, llon;
     895        llat = llon = lat = lon = slat = slon = 0;
     896        double sarc = 0;
     897        boolean first = true;
     898        switch (feature.geom.prim) {
     899        case POINT:
     900            return nodes.get(feature.geom.elems.get(0).id);
     901        case LINE:
     902            GeomIterator git = new GeomIterator(feature.geom);
     903            while (git.hasComp()) {
     904                git.nextComp();
     905                while (git.hasEdge()) {
     906                    git.nextEdge();
     907                    while (git.hasNode()) {
     908                        Snode node = git.next();
     909                        if (node == null) continue;
     910                        lat = node.lat;
     911                        lon = node.lon;
     912                        if (first) {
     913                            first = false;
     914                        } else {
     915                            sarc += (Math.acos(Math.cos(lon - llon) * Math.cos(lat - llat)));
     916                        }
     917                        llat = lat;
     918                        llon = lon;
     919                    }
     920                }
     921            }
     922            double harc = sarc / 2;
     923            sarc = 0;
     924            first = true;
     925            git = new GeomIterator(feature.geom);
     926            while (git.hasComp()) {
     927                git.nextComp();
     928                while (git.hasEdge()) {
     929                    git.nextEdge();
     930                    while (git.hasNode()) {
     931                        Snode node = git.next();
     932                        if (node == null) continue;
     933                        lat = node.lat;
     934                        lon = node.lon;
     935                        if (first) {
     936                            first = false;
     937                        } else {
     938                            sarc = (Math.acos(Math.cos(lon - llon) * Math.cos(lat - llat)));
     939                            if (sarc > harc)
     940                                break;
     941                        }
     942                        harc -= sarc;
     943                        llat = lat;
     944                        llon = lon;
     945                    }
     946                }
     947            }
     948            return new Snode(llat + ((lat - llat) * harc / sarc), llon + ((lon - llon) * harc / sarc));
     949        case AREA:
     950            git = new GeomIterator(feature.geom);
     951            while (git.hasComp()) {
     952                git.nextComp();
     953                while (git.hasEdge()) {
     954                    git.nextEdge();
     955                    while (git.hasNode()) {
     956                        Snode node = git.next();
     957                        lat = node.lat;
     958                        lon = node.lon;
     959                        if (first) {
     960                            first = false;
     961                        } else {
     962                            double arc = (Math.acos(Math.cos(lon - llon) * Math.cos(lat - llat)));
     963                            slat += ((lat + llat) / 2 * arc);
     964                            slon += ((lon + llon) / 2 * arc);
     965                            sarc += arc;
     966                        }
     967                        llon = lon;
     968                        llat = lat;
     969                    }
     970                }
     971            }
     972            return new Snode((sarc > 0.0 ? slat / sarc : 0.0), (sarc > 0.0 ? slon / sarc : 0.0));
     973        default:
     974        }
     975        return null;
     976    }
    970977
    971978}
  • applications/editors/josm/plugins/seachart/src/s57/S57obj.java

    r31846 r32394  
    1010package s57;
    1111
    12 import java.util.*;
     12import java.util.EnumMap;
     13import java.util.HashMap;
     14import java.util.Map;
    1315
    1416public class S57obj { // S57 Object lookup tables & methods
    15        
    16         public enum Obj {
    17                 UNKOBJ, M_COVR, M_NSYS, AIRARE, ACHBRT, ACHARE, BCNCAR, BCNISD, BCNLAT, BCNSAW, BCNSPP, BERTHS, BRIDGE, BUISGL, BUAARE, BOYCAR,
    18                 BOYINB, BOYISD, BOYLAT, BOYSAW, BOYSPP, CBLARE, CBLOHD, CBLSUB, CANALS, CTSARE, CAUSWY, CTNARE, CHKPNT, CGUSTA, COALNE, CONZNE,
    19                 COSARE, CTRPNT, CONVYR, CRANES, CURENT, CUSZNE, DAMCON, DAYMAR, DWRTCL, DWRTPT, DEPARE, DEPCNT, DISMAR, DOCARE, DRGARE, DRYDOC,
    20                 DMPGRD, DYKCON, EXEZNE, FAIRWY, FNCLNE, FERYRT, FSHZNE, FSHFAC, FSHGRD, FLODOC, FOGSIG, FORSTC, FRPARE, GATCON, GRIDRN, HRBARE,
    21                 HRBFAC, HULKES, ICEARE, ICNARE, ISTZNE, LAKARE, LNDARE, LNDELV, LNDRGN, LNDMRK, LIGHTS, LITFLT, LITVES, LOCMAG, LOKBSN, LOGPON,
    22                 MAGVAR, MARCUL, MIPARE, MORFAC, MPAARE, NAVLNE, OBSTRN, OFSPLF, OSPARE, OILBAR, PILPNT, PILBOP, PIPARE, PIPOHD, PIPSOL, PONTON,
    23                 PRCARE, PRDARE, PYLONS, RADLNE, RADRNG, RADRFL, RADSTA, RTPBCN, RDOCAL, RDOSTA, RAILWY, RAPIDS, RCRTCL, RECTRC, RCTLPT, RSCSTA,
    24                 RESARE, RETRFL, RIVERS, ROADWY, RUNWAY, SNDWAV, SEAARE, SPLARE, SBDARE, SLCONS, SISTAT, SISTAW, SILTNK, SLOTOP, SLOGRD, SMCFAC,
    25                 SOUNDG, SPRING, STSLNE, SUBTLN, SWPARE, TESARE, TS_PRH, TS_PNH, TS_PAD, TS_TIS, T_HMON, T_NHMN, T_TIMS, TIDEWY, TOPMAR, TSELNE,
    26                 TSSBND, TSSCRS, TSSLPT, TSSRON, TSEZNE, TUNNEL, TWRTPT, UWTROC, UNSARE, VEGATN, WATTUR, WATFAL, WEDKLP, WRECKS, TS_FEB, NOTMRK,
    27                 WTWAXS, WTWPRF, BUNSTA, COMARE, HRBBSN, LOKARE, LKBSPT, PRTARE, REFDMP, TERMNL, TRNBSN, WTWARE, WTWGAG, TISDGE, VEHTRF, EXCNST,
    28                 LG_SDM, LG_VSP, LITMIN, LITMAJ
    29         }
     17    // CHECKSTYLE.OFF: LineLength
    3018
    31         private static final EnumMap<Obj, Integer> ObjS57 = new EnumMap<>(Obj.class);
    32         static {
    33                 ObjS57.put(Obj.UNKOBJ,0);
    34                 ObjS57.put(Obj.AIRARE,2); ObjS57.put(Obj.ACHBRT,3); ObjS57.put(Obj.ACHARE,4); ObjS57.put(Obj.BCNCAR,5); ObjS57.put(Obj.BCNISD,6);
    35                 ObjS57.put(Obj.BCNLAT,7); ObjS57.put(Obj.BCNSAW,8); ObjS57.put(Obj.BCNSPP,9); ObjS57.put(Obj.BERTHS,10); ObjS57.put(Obj.BRIDGE,11);
    36                 ObjS57.put(Obj.BUISGL,12); ObjS57.put(Obj.BUAARE,13); ObjS57.put(Obj.BOYCAR,14); ObjS57.put(Obj.BOYINB,15); ObjS57.put(Obj.BOYISD,16);
    37                 ObjS57.put(Obj.BOYLAT,17); ObjS57.put(Obj.BOYSAW,18); ObjS57.put(Obj.BOYSPP,19); ObjS57.put(Obj.CBLARE,20); ObjS57.put(Obj.CBLOHD,21);
    38                 ObjS57.put(Obj.CBLSUB,22); ObjS57.put(Obj.CANALS,23); ObjS57.put(Obj.CTSARE,25); ObjS57.put(Obj.CAUSWY,26); ObjS57.put(Obj.CTNARE,27);
    39                 ObjS57.put(Obj.CHKPNT,28); ObjS57.put(Obj.CGUSTA,29); ObjS57.put(Obj.COALNE,30); ObjS57.put(Obj.CONZNE,31); ObjS57.put(Obj.COSARE,32);
    40                 ObjS57.put(Obj.CTRPNT,33); ObjS57.put(Obj.CONVYR,34); ObjS57.put(Obj.CRANES,35); ObjS57.put(Obj.CURENT,36); ObjS57.put(Obj.CUSZNE,37);
    41                 ObjS57.put(Obj.DAMCON,38); ObjS57.put(Obj.DAYMAR,39); ObjS57.put(Obj.DWRTCL,40); ObjS57.put(Obj.DWRTPT,41); ObjS57.put(Obj.DEPARE,42);
    42                 ObjS57.put(Obj.DEPCNT,43); ObjS57.put(Obj.DISMAR,44); ObjS57.put(Obj.DOCARE,45); ObjS57.put(Obj.DRGARE,46); ObjS57.put(Obj.DRYDOC,47);
    43                 ObjS57.put(Obj.DMPGRD,48); ObjS57.put(Obj.DYKCON,49); ObjS57.put(Obj.EXEZNE,50); ObjS57.put(Obj.FAIRWY,51); ObjS57.put(Obj.FNCLNE,52);
    44                 ObjS57.put(Obj.FERYRT,53); ObjS57.put(Obj.FSHZNE,54); ObjS57.put(Obj.FSHFAC,55); ObjS57.put(Obj.FSHGRD,56); ObjS57.put(Obj.FLODOC,57);
    45                 ObjS57.put(Obj.FOGSIG,58); ObjS57.put(Obj.FORSTC,59); ObjS57.put(Obj.FRPARE,60); ObjS57.put(Obj.GATCON,61); ObjS57.put(Obj.GRIDRN,62);
    46                 ObjS57.put(Obj.HRBARE,63); ObjS57.put(Obj.HRBFAC,64); ObjS57.put(Obj.HULKES,65); ObjS57.put(Obj.ICEARE,66); ObjS57.put(Obj.ICNARE,67);
    47                 ObjS57.put(Obj.ISTZNE,68); ObjS57.put(Obj.LAKARE,69); ObjS57.put(Obj.LNDARE,71); ObjS57.put(Obj.LNDELV,72); ObjS57.put(Obj.LNDRGN,73);
    48                 ObjS57.put(Obj.LNDMRK,74); ObjS57.put(Obj.LIGHTS,75); ObjS57.put(Obj.LITFLT,76); ObjS57.put(Obj.LITVES,77); ObjS57.put(Obj.LOCMAG,78);
    49                 ObjS57.put(Obj.LOKBSN,79); ObjS57.put(Obj.LOGPON,80); ObjS57.put(Obj.MAGVAR,81); ObjS57.put(Obj.MARCUL,82); ObjS57.put(Obj.MIPARE,83);
    50                 ObjS57.put(Obj.MORFAC,84); ObjS57.put(Obj.NAVLNE,85); ObjS57.put(Obj.OBSTRN,86); ObjS57.put(Obj.OFSPLF,87); ObjS57.put(Obj.OSPARE,88);
    51                 ObjS57.put(Obj.OILBAR,89); ObjS57.put(Obj.PILPNT,90); ObjS57.put(Obj.PILBOP,91); ObjS57.put(Obj.PIPARE,92); ObjS57.put(Obj.PIPOHD,93);
    52                 ObjS57.put(Obj.PIPSOL,94); ObjS57.put(Obj.PONTON,95); ObjS57.put(Obj.PRCARE,96); ObjS57.put(Obj.PRDARE,97); ObjS57.put(Obj.PYLONS,98);
    53                 ObjS57.put(Obj.RADLNE,99); ObjS57.put(Obj.RADRNG,100); ObjS57.put(Obj.RADRFL,101); ObjS57.put(Obj.RADSTA,102); ObjS57.put(Obj.RTPBCN,103);
    54                 ObjS57.put(Obj.RDOCAL,104); ObjS57.put(Obj.RDOSTA,105); ObjS57.put(Obj.RAILWY,106);     ObjS57.put(Obj.RAPIDS,107);     ObjS57.put(Obj.RCRTCL,108);
    55                 ObjS57.put(Obj.RECTRC,109); ObjS57.put(Obj.RCTLPT,110); ObjS57.put(Obj.RSCSTA,111);     ObjS57.put(Obj.RESARE,112);     ObjS57.put(Obj.RETRFL,113);
    56                 ObjS57.put(Obj.RIVERS,114); ObjS57.put(Obj.ROADWY,116); ObjS57.put(Obj.RUNWAY,117);     ObjS57.put(Obj.SNDWAV,118);     ObjS57.put(Obj.SEAARE,119);
    57                 ObjS57.put(Obj.SPLARE,120); ObjS57.put(Obj.SBDARE,121); ObjS57.put(Obj.SLCONS,122);     ObjS57.put(Obj.SISTAT,123);     ObjS57.put(Obj.SISTAW,124);
    58                 ObjS57.put(Obj.SILTNK,125); ObjS57.put(Obj.SLOTOP,126); ObjS57.put(Obj.SLOGRD,127);     ObjS57.put(Obj.SMCFAC,128);     ObjS57.put(Obj.SOUNDG,129);
    59                 ObjS57.put(Obj.SPRING,130); ObjS57.put(Obj.STSLNE,132); ObjS57.put(Obj.SUBTLN,133);     ObjS57.put(Obj.SWPARE,134); ObjS57.put(Obj.TESARE,135);
    60                 ObjS57.put(Obj.TS_PRH,136);     ObjS57.put(Obj.TS_PNH,137); ObjS57.put(Obj.TS_PAD,138); ObjS57.put(Obj.TS_TIS,139); ObjS57.put(Obj.T_HMON,140);
    61                 ObjS57.put(Obj.T_NHMN,141);     ObjS57.put(Obj.T_TIMS,142);     ObjS57.put(Obj.TIDEWY,143);     ObjS57.put(Obj.TOPMAR,144); ObjS57.put(Obj.TSELNE,145);
    62                 ObjS57.put(Obj.TSSBND,146);     ObjS57.put(Obj.TSSCRS,147);     ObjS57.put(Obj.TSSLPT,148);     ObjS57.put(Obj.TSSRON,149); ObjS57.put(Obj.TSEZNE,150);
    63                 ObjS57.put(Obj.TUNNEL,151);     ObjS57.put(Obj.TWRTPT,152);     ObjS57.put(Obj.UWTROC,153);     ObjS57.put(Obj.UNSARE,154); ObjS57.put(Obj.VEGATN,155);
    64                 ObjS57.put(Obj.WATTUR,156);     ObjS57.put(Obj.WATFAL,157);     ObjS57.put(Obj.WEDKLP,158);     ObjS57.put(Obj.WRECKS,159); ObjS57.put(Obj.TS_FEB,160);
    65                 ObjS57.put(Obj.MPAARE,199); ObjS57.put(Obj.M_COVR,302); ObjS57.put(Obj.M_NSYS,306); ObjS57.put(Obj.LITMAJ,74); ObjS57.put(Obj.LITMIN,90);
    66         }
     19    public enum Obj {
     20        UNKOBJ, M_COVR, M_NSYS, AIRARE, ACHBRT, ACHARE, BCNCAR, BCNISD, BCNLAT, BCNSAW, BCNSPP, BERTHS, BRIDGE, BUISGL, BUAARE, BOYCAR,
     21        BOYINB, BOYISD, BOYLAT, BOYSAW, BOYSPP, CBLARE, CBLOHD, CBLSUB, CANALS, CTSARE, CAUSWY, CTNARE, CHKPNT, CGUSTA, COALNE, CONZNE,
     22        COSARE, CTRPNT, CONVYR, CRANES, CURENT, CUSZNE, DAMCON, DAYMAR, DWRTCL, DWRTPT, DEPARE, DEPCNT, DISMAR, DOCARE, DRGARE, DRYDOC,
     23        DMPGRD, DYKCON, EXEZNE, FAIRWY, FNCLNE, FERYRT, FSHZNE, FSHFAC, FSHGRD, FLODOC, FOGSIG, FORSTC, FRPARE, GATCON, GRIDRN, HRBARE,
     24        HRBFAC, HULKES, ICEARE, ICNARE, ISTZNE, LAKARE, LNDARE, LNDELV, LNDRGN, LNDMRK, LIGHTS, LITFLT, LITVES, LOCMAG, LOKBSN, LOGPON,
     25        MAGVAR, MARCUL, MIPARE, MORFAC, MPAARE, NAVLNE, OBSTRN, OFSPLF, OSPARE, OILBAR, PILPNT, PILBOP, PIPARE, PIPOHD, PIPSOL, PONTON,
     26        PRCARE, PRDARE, PYLONS, RADLNE, RADRNG, RADRFL, RADSTA, RTPBCN, RDOCAL, RDOSTA, RAILWY, RAPIDS, RCRTCL, RECTRC, RCTLPT, RSCSTA,
     27        RESARE, RETRFL, RIVERS, ROADWY, RUNWAY, SNDWAV, SEAARE, SPLARE, SBDARE, SLCONS, SISTAT, SISTAW, SILTNK, SLOTOP, SLOGRD, SMCFAC,
     28        SOUNDG, SPRING, STSLNE, SUBTLN, SWPARE, TESARE, TS_PRH, TS_PNH, TS_PAD, TS_TIS, T_HMON, T_NHMN, T_TIMS, TIDEWY, TOPMAR, TSELNE,
     29        TSSBND, TSSCRS, TSSLPT, TSSRON, TSEZNE, TUNNEL, TWRTPT, UWTROC, UNSARE, VEGATN, WATTUR, WATFAL, WEDKLP, WRECKS, TS_FEB, NOTMRK,
     30        WTWAXS, WTWPRF, BUNSTA, COMARE, HRBBSN, LOKARE, LKBSPT, PRTARE, REFDMP, TERMNL, TRNBSN, WTWARE, WTWGAG, TISDGE, VEHTRF, EXCNST,
     31        LG_SDM, LG_VSP, LITMIN, LITMAJ
     32    }
    6733
    68         private static final EnumMap<Obj, Integer> ObjIENC = new EnumMap<>(Obj.class);
    69         static {
    70                 ObjIENC.put(Obj.UNKOBJ, 0);
    71                 ObjIENC.put(Obj.ACHBRT, 17000); ObjIENC.put(Obj.ACHARE, 17001); ObjIENC.put(Obj.DEPARE, 17003); ObjIENC.put(Obj.DISMAR, 17004); ObjIENC.put(Obj.RESARE, 17005);
    72                 ObjIENC.put(Obj.SISTAT, 17007); ObjIENC.put(Obj.SISTAW, 17008); ObjIENC.put(Obj.TOPMAR, 17009); ObjIENC.put(Obj.BERTHS, 17010); ObjIENC.put(Obj.BRIDGE, 17011);
    73                 ObjIENC.put(Obj.CBLOHD, 17012); ObjIENC.put(Obj.FERYRT, 17013); ObjIENC.put(Obj.HRBARE, 17014); ObjIENC.put(Obj.HRBFAC, 17015); ObjIENC.put(Obj.LOKBSN, 17016);
    74                 ObjIENC.put(Obj.RDOCAL, 17017); ObjIENC.put(Obj.CURENT, 17019); ObjIENC.put(Obj.HULKES, 17020); ObjIENC.put(Obj.PONTON, 17021); ObjIENC.put(Obj.PIPOHD, 17024);
    75                 ObjIENC.put(Obj.FLODOC, 17025); ObjIENC.put(Obj.CHKPNT, 17027); ObjIENC.put(Obj.BCNLAT, 17028); ObjIENC.put(Obj.BOYLAT, 17029); ObjIENC.put(Obj.CRANES, 17030);
    76                 ObjIENC.put(Obj.GATCON, 17031); ObjIENC.put(Obj.SLCONS, 17032); ObjIENC.put(Obj.UWTROC, 17033); ObjIENC.put(Obj.CONVYR, 17034); ObjIENC.put(Obj.NOTMRK, 17050);
    77                 ObjIENC.put(Obj.WTWAXS, 17051); ObjIENC.put(Obj.WTWPRF, 17052); ObjIENC.put(Obj.BUNSTA, 17054); ObjIENC.put(Obj.COMARE, 17055); ObjIENC.put(Obj.HRBBSN, 17056);
    78                 ObjIENC.put(Obj.LKBSPT, 17058); ObjIENC.put(Obj.PRTARE, 17059); ObjIENC.put(Obj.REFDMP, 17062); ObjIENC.put(Obj.TERMNL, 17064); ObjIENC.put(Obj.TRNBSN, 17065);
    79                 ObjIENC.put(Obj.WTWARE, 17066); ObjIENC.put(Obj.WTWGAG, 17067); ObjIENC.put(Obj.TISDGE, 17068); ObjIENC.put(Obj.VEHTRF, 17069); ObjIENC.put(Obj.EXCNST, 17070);
    80                 ObjIENC.put(Obj.LG_SDM, 18001); ObjIENC.put(Obj.LG_VSP, 18002);
    81         }
     34    private static final EnumMap<Obj, Integer> ObjS57 = new EnumMap<>(Obj.class);
     35    static {
     36        ObjS57.put(Obj.UNKOBJ, 0);
     37        ObjS57.put(Obj.AIRARE, 2); ObjS57.put(Obj.ACHBRT, 3); ObjS57.put(Obj.ACHARE, 4); ObjS57.put(Obj.BCNCAR, 5); ObjS57.put(Obj.BCNISD, 6);
     38        ObjS57.put(Obj.BCNLAT, 7); ObjS57.put(Obj.BCNSAW, 8); ObjS57.put(Obj.BCNSPP, 9); ObjS57.put(Obj.BERTHS, 10); ObjS57.put(Obj.BRIDGE, 11);
     39        ObjS57.put(Obj.BUISGL, 12); ObjS57.put(Obj.BUAARE, 13); ObjS57.put(Obj.BOYCAR, 14); ObjS57.put(Obj.BOYINB, 15); ObjS57.put(Obj.BOYISD, 16);
     40        ObjS57.put(Obj.BOYLAT, 17); ObjS57.put(Obj.BOYSAW, 18); ObjS57.put(Obj.BOYSPP, 19); ObjS57.put(Obj.CBLARE, 20); ObjS57.put(Obj.CBLOHD, 21);
     41        ObjS57.put(Obj.CBLSUB, 22); ObjS57.put(Obj.CANALS, 23); ObjS57.put(Obj.CTSARE, 25); ObjS57.put(Obj.CAUSWY, 26); ObjS57.put(Obj.CTNARE, 27);
     42        ObjS57.put(Obj.CHKPNT, 28); ObjS57.put(Obj.CGUSTA, 29); ObjS57.put(Obj.COALNE, 30); ObjS57.put(Obj.CONZNE, 31); ObjS57.put(Obj.COSARE, 32);
     43        ObjS57.put(Obj.CTRPNT, 33); ObjS57.put(Obj.CONVYR, 34); ObjS57.put(Obj.CRANES, 35); ObjS57.put(Obj.CURENT, 36); ObjS57.put(Obj.CUSZNE, 37);
     44        ObjS57.put(Obj.DAMCON, 38); ObjS57.put(Obj.DAYMAR, 39); ObjS57.put(Obj.DWRTCL, 40); ObjS57.put(Obj.DWRTPT, 41); ObjS57.put(Obj.DEPARE, 42);
     45        ObjS57.put(Obj.DEPCNT, 43); ObjS57.put(Obj.DISMAR, 44); ObjS57.put(Obj.DOCARE, 45); ObjS57.put(Obj.DRGARE, 46); ObjS57.put(Obj.DRYDOC, 47);
     46        ObjS57.put(Obj.DMPGRD, 48); ObjS57.put(Obj.DYKCON, 49); ObjS57.put(Obj.EXEZNE, 50); ObjS57.put(Obj.FAIRWY, 51); ObjS57.put(Obj.FNCLNE, 52);
     47        ObjS57.put(Obj.FERYRT, 53); ObjS57.put(Obj.FSHZNE, 54); ObjS57.put(Obj.FSHFAC, 55); ObjS57.put(Obj.FSHGRD, 56); ObjS57.put(Obj.FLODOC, 57);
     48        ObjS57.put(Obj.FOGSIG, 58); ObjS57.put(Obj.FORSTC, 59); ObjS57.put(Obj.FRPARE, 60); ObjS57.put(Obj.GATCON, 61); ObjS57.put(Obj.GRIDRN, 62);
     49        ObjS57.put(Obj.HRBARE, 63); ObjS57.put(Obj.HRBFAC, 64); ObjS57.put(Obj.HULKES, 65); ObjS57.put(Obj.ICEARE, 66); ObjS57.put(Obj.ICNARE, 67);
     50        ObjS57.put(Obj.ISTZNE, 68); ObjS57.put(Obj.LAKARE, 69); ObjS57.put(Obj.LNDARE, 71); ObjS57.put(Obj.LNDELV, 72); ObjS57.put(Obj.LNDRGN, 73);
     51        ObjS57.put(Obj.LNDMRK, 74); ObjS57.put(Obj.LIGHTS, 75); ObjS57.put(Obj.LITFLT, 76); ObjS57.put(Obj.LITVES, 77); ObjS57.put(Obj.LOCMAG, 78);
     52        ObjS57.put(Obj.LOKBSN, 79); ObjS57.put(Obj.LOGPON, 80); ObjS57.put(Obj.MAGVAR, 81); ObjS57.put(Obj.MARCUL, 82); ObjS57.put(Obj.MIPARE, 83);
     53        ObjS57.put(Obj.MORFAC, 84); ObjS57.put(Obj.NAVLNE, 85); ObjS57.put(Obj.OBSTRN, 86); ObjS57.put(Obj.OFSPLF, 87); ObjS57.put(Obj.OSPARE, 88);
     54        ObjS57.put(Obj.OILBAR, 89); ObjS57.put(Obj.PILPNT, 90); ObjS57.put(Obj.PILBOP, 91); ObjS57.put(Obj.PIPARE, 92); ObjS57.put(Obj.PIPOHD, 93);
     55        ObjS57.put(Obj.PIPSOL, 94); ObjS57.put(Obj.PONTON, 95); ObjS57.put(Obj.PRCARE, 96); ObjS57.put(Obj.PRDARE, 97); ObjS57.put(Obj.PYLONS, 98);
     56        ObjS57.put(Obj.RADLNE, 99); ObjS57.put(Obj.RADRNG, 100); ObjS57.put(Obj.RADRFL, 101); ObjS57.put(Obj.RADSTA, 102); ObjS57.put(Obj.RTPBCN, 103);
     57        ObjS57.put(Obj.RDOCAL, 104); ObjS57.put(Obj.RDOSTA, 105); ObjS57.put(Obj.RAILWY, 106); ObjS57.put(Obj.RAPIDS, 107); ObjS57.put(Obj.RCRTCL, 108);
     58        ObjS57.put(Obj.RECTRC, 109); ObjS57.put(Obj.RCTLPT, 110); ObjS57.put(Obj.RSCSTA, 111); ObjS57.put(Obj.RESARE, 112); ObjS57.put(Obj.RETRFL, 113);
     59        ObjS57.put(Obj.RIVERS, 114); ObjS57.put(Obj.ROADWY, 116); ObjS57.put(Obj.RUNWAY, 117); ObjS57.put(Obj.SNDWAV, 118); ObjS57.put(Obj.SEAARE, 119);
     60        ObjS57.put(Obj.SPLARE, 120); ObjS57.put(Obj.SBDARE, 121); ObjS57.put(Obj.SLCONS, 122); ObjS57.put(Obj.SISTAT, 123); ObjS57.put(Obj.SISTAW, 124);
     61        ObjS57.put(Obj.SILTNK, 125); ObjS57.put(Obj.SLOTOP, 126); ObjS57.put(Obj.SLOGRD, 127); ObjS57.put(Obj.SMCFAC, 128); ObjS57.put(Obj.SOUNDG, 129);
     62        ObjS57.put(Obj.SPRING, 130); ObjS57.put(Obj.STSLNE, 132); ObjS57.put(Obj.SUBTLN, 133); ObjS57.put(Obj.SWPARE, 134); ObjS57.put(Obj.TESARE, 135);
     63        ObjS57.put(Obj.TS_PRH, 136); ObjS57.put(Obj.TS_PNH, 137); ObjS57.put(Obj.TS_PAD, 138); ObjS57.put(Obj.TS_TIS, 139); ObjS57.put(Obj.T_HMON, 140);
     64        ObjS57.put(Obj.T_NHMN, 141); ObjS57.put(Obj.T_TIMS, 142); ObjS57.put(Obj.TIDEWY, 143); ObjS57.put(Obj.TOPMAR, 144); ObjS57.put(Obj.TSELNE, 145);
     65        ObjS57.put(Obj.TSSBND, 146); ObjS57.put(Obj.TSSCRS, 147); ObjS57.put(Obj.TSSLPT, 148); ObjS57.put(Obj.TSSRON, 149); ObjS57.put(Obj.TSEZNE, 150);
     66        ObjS57.put(Obj.TUNNEL, 151); ObjS57.put(Obj.TWRTPT, 152); ObjS57.put(Obj.UWTROC, 153); ObjS57.put(Obj.UNSARE, 154); ObjS57.put(Obj.VEGATN, 155);
     67        ObjS57.put(Obj.WATTUR, 156); ObjS57.put(Obj.WATFAL, 157); ObjS57.put(Obj.WEDKLP, 158); ObjS57.put(Obj.WRECKS, 159); ObjS57.put(Obj.TS_FEB, 160);
     68        ObjS57.put(Obj.MPAARE, 199); ObjS57.put(Obj.M_COVR, 302); ObjS57.put(Obj.M_NSYS, 306); ObjS57.put(Obj.LITMAJ, 74); ObjS57.put(Obj.LITMIN, 90);
     69    }
    8270
    83         private static final EnumMap<Obj, String> ObjStr = new EnumMap<>(Obj.class);
    84         static {
    85                 ObjStr.put(Obj.UNKOBJ, "");     ObjStr.put(Obj.AIRARE, "airfield");     ObjStr.put(Obj.ACHBRT, "anchor_berth"); ObjStr.put(Obj.ACHARE, "anchorage");
    86                 ObjStr.put(Obj.BCNCAR, "beacon_cardinal");      ObjStr.put(Obj.BCNISD, "beacon_isolated_danger"); ObjStr.put(Obj.BCNLAT, "beacon_lateral");
    87                 ObjStr.put(Obj.BCNSAW, "beacon_safe_water"); ObjStr.put(Obj.BCNSPP, "beacon_special_purpose"); ObjStr.put(Obj.BERTHS, "berth"); ObjStr.put(Obj.BRIDGE, "bridge");
    88                 ObjStr.put(Obj.BUISGL, "building"); ObjStr.put(Obj.BUAARE, "built-up_area"); ObjStr.put(Obj.BOYCAR, "buoy_cardinal"); ObjStr.put(Obj.BOYINB, "buoy_installation");
    89                 ObjStr.put(Obj.BOYISD, "buoy_isolated_danger"); ObjStr.put(Obj.BOYLAT, "buoy_lateral"); ObjStr.put(Obj.BOYSAW, "buoy_safe_water");
    90                 ObjStr.put(Obj.BOYSPP, "buoy_special_purpose"); ObjStr.put(Obj.CBLARE, "cable_area");   ObjStr.put(Obj.CBLOHD, "cable_overhead");
    91                 ObjStr.put(Obj.CBLSUB, "cable_submarine"); ObjStr.put(Obj.CANALS, "canal"); ObjStr.put(Obj.CTSARE, "cargo_area");       ObjStr.put(Obj.CAUSWY, "causeway");
    92                 ObjStr.put(Obj.CTNARE, "caution_area"); ObjStr.put(Obj.CHKPNT, "checkpoint"); ObjStr.put(Obj.CGUSTA, "coastguard_station");     ObjStr.put(Obj.COALNE, "coastline");
    93                 ObjStr.put(Obj.CONZNE, "contiguous_zone"); ObjStr.put(Obj.COSARE, "continental_shelf"); ObjStr.put(Obj.CTRPNT, "control_point");
    94                 ObjStr.put(Obj.CONVYR, "conveyor");     ObjStr.put(Obj.CRANES, "crane"); ObjStr.put(Obj.CURENT, "current"); ObjStr.put(Obj.CUSZNE, "custom_zone");
    95                 ObjStr.put(Obj.DAMCON, "dam"); ObjStr.put(Obj.DAYMAR, "daymark"); ObjStr.put(Obj.DWRTCL, "deep_water_route_centreline"); ObjStr.put(Obj.DWRTPT, "deep_water_route");
    96                 ObjStr.put(Obj.DEPARE, "depth_area"); ObjStr.put(Obj.DEPCNT, "depth_contour"); ObjStr.put(Obj.DISMAR, "distance_mark"); ObjStr.put(Obj.DOCARE, "dock");
    97                 ObjStr.put(Obj.DRGARE, "dredged_area"); ObjStr.put(Obj.DRYDOC, "dry_dock");     ObjStr.put(Obj.DMPGRD, "dumping_ground");       ObjStr.put(Obj.DYKCON, "dyke");
    98                 ObjStr.put(Obj.EXEZNE, "exclusive_economic_zone"); ObjStr.put(Obj.FAIRWY, "fairway"); ObjStr.put(Obj.FNCLNE, "wall"); ObjStr.put(Obj.FERYRT, "ferry_route");
    99                 ObjStr.put(Obj.FSHZNE, "fishery_zone"); ObjStr.put(Obj.FSHFAC, "fishing_facility");     ObjStr.put(Obj.FSHGRD, "fishing_ground");       ObjStr.put(Obj.FLODOC, "floating_dock");
    100                 ObjStr.put(Obj.FOGSIG, "fog_signal"); ObjStr.put(Obj.FORSTC, "fortified_structure"); ObjStr.put(Obj.FRPARE, "free_port_area"); ObjStr.put(Obj.GATCON, "gate");
    101                 ObjStr.put(Obj.GRIDRN, "gridiron"); ObjStr.put(Obj.HRBARE, "harbour_area");     ObjStr.put(Obj.HRBFAC, "harbour"); ObjStr.put(Obj.HULKES, "hulk");
    102                 ObjStr.put(Obj.ICEARE, "ice_area"); ObjStr.put(Obj.ICNARE, "incineration_zone"); ObjStr.put(Obj.ISTZNE, "inshore_traffic_zone"); ObjStr.put(Obj.LAKARE, "lake");
    103                 ObjStr.put(Obj.LNDARE, "land_area"); ObjStr.put(Obj.LNDELV, "land_elevation"); ObjStr.put(Obj.LNDRGN, "land_region");   ObjStr.put(Obj.LNDMRK, "landmark");
    104                 ObjStr.put(Obj.LIGHTS, "light"); ObjStr.put(Obj.LITFLT, "light_float"); ObjStr.put(Obj.LITVES, "light_vessel"); ObjStr.put(Obj.LOCMAG, "local_magnetic_anomaly");
    105                 ObjStr.put(Obj.LOKBSN, "lock_basin");   ObjStr.put(Obj.LOGPON, "log_pond");     ObjStr.put(Obj.MAGVAR, "magnetic_variation");   ObjStr.put(Obj.MARCUL, "marine_farm");
    106                 ObjStr.put(Obj.MIPARE, "military_area"); ObjStr.put(Obj.MORFAC, "mooring");     ObjStr.put(Obj.NAVLNE, "navigation_line"); ObjStr.put(Obj.OBSTRN, "obstruction");
    107                 ObjStr.put(Obj.OFSPLF, "platform");     ObjStr.put(Obj.OSPARE, "production_area"); ObjStr.put(Obj.OILBAR, "oil_barrier");       ObjStr.put(Obj.PILPNT, "pile");
    108                 ObjStr.put(Obj.PILBOP, "pilot_boarding");       ObjStr.put(Obj.PIPARE, "pipeline_area"); ObjStr.put(Obj.PIPOHD, "pipeline_overhead");   ObjStr.put(Obj.PIPSOL, "pipeline_submarine");
    109                 ObjStr.put(Obj.PONTON, "pontoon"); ObjStr.put(Obj.PRCARE, "precautionary_area"); ObjStr.put(Obj.PRDARE, "land_production_area");ObjStr.put(Obj.PYLONS, "pylon");
    110                 ObjStr.put(Obj.RADLNE, "radar_line");   ObjStr.put(Obj.RADRNG, "radar_range"); ObjStr.put(Obj.RADRFL, "radar_reflector");       ObjStr.put(Obj.RADSTA, "radar_station");
    111                 ObjStr.put(Obj.RTPBCN, "radar_transponder"); ObjStr.put(Obj.RDOCAL, "calling-in_point"); ObjStr.put(Obj.RDOSTA, "radio_station");       ObjStr.put(Obj.RAILWY, "railway");
    112                 ObjStr.put(Obj.RAPIDS, "rapids");       ObjStr.put(Obj.RCRTCL, "recommended_route_centreline"); ObjStr.put(Obj.RECTRC, "recommended_track");
    113                 ObjStr.put(Obj.RCTLPT, "recommended_traffic_lane");     ObjStr.put(Obj.RSCSTA, "rescue_station");       ObjStr.put(Obj.RESARE, "restricted_area");
    114                 ObjStr.put(Obj.RETRFL, "retro_reflector"); ObjStr.put(Obj.RIVERS, "river");     ObjStr.put(Obj.ROADWY, "road"); ObjStr.put(Obj.RUNWAY, "runway");
    115                 ObjStr.put(Obj.SNDWAV, "sand_waves");   ObjStr.put(Obj.SEAARE, "sea_area");     ObjStr.put(Obj.SPLARE, "seaplane_landing_area"); ObjStr.put(Obj.SBDARE, "seabed_area");
    116                 ObjStr.put(Obj.SLCONS, "shoreline_construction"); ObjStr.put(Obj.SISTAT, "signal_station_traffic"); ObjStr.put(Obj.SISTAW, "signal_station_warning");
    117                 ObjStr.put(Obj.SILTNK, "tank"); ObjStr.put(Obj.SLOTOP, "slope_topline"); ObjStr.put(Obj.SLOGRD, "sloping_ground"); ObjStr.put(Obj.SMCFAC, "small_craft_facility");
    118                 ObjStr.put(Obj.SOUNDG, "sounding");     ObjStr.put(Obj.SPRING, "spring"); ObjStr.put(Obj.STSLNE, "territorial_baseline");       ObjStr.put(Obj.SUBTLN, "submarine_transit_lane");
    119                 ObjStr.put(Obj.SWPARE, "swept_area"); ObjStr.put(Obj.TESARE, "territorial_area");       ObjStr.put(Obj.TIDEWY, "tideway"); ObjStr.put(Obj.TOPMAR, "topmark");
    120                 ObjStr.put(Obj.TSELNE, "separation_line"); ObjStr.put(Obj.TSSBND, "separation_boundary");       ObjStr.put(Obj.TSSCRS, "separation_crossing");
    121                 ObjStr.put(Obj.TSSLPT, "separation_lane"); ObjStr.put(Obj.TSSRON, "separation_roundabout");     ObjStr.put(Obj.TSEZNE, "separation_zone"); ObjStr.put(Obj.TUNNEL, "tunnel");
    122                 ObjStr.put(Obj.TWRTPT, "two-way_route"); ObjStr.put(Obj.UWTROC, "rock"); ObjStr.put(Obj.UNSARE, "unsurveyed_area");     ObjStr.put(Obj.VEGATN, "vegetation");
    123                 ObjStr.put(Obj.WATTUR, "water_turbulence");     ObjStr.put(Obj.WATFAL, "waterfall"); ObjStr.put(Obj.WEDKLP, "weed"); ObjStr.put(Obj.WRECKS, "wreck");
    124                 ObjStr.put(Obj.TS_FEB, "tidal_stream"); ObjStr.put(Obj.NOTMRK, "notice");       ObjStr.put(Obj.WTWAXS, "waterway_axis"); ObjStr.put(Obj.WTWPRF, "waterway_profile");
    125                 ObjStr.put(Obj.BUNSTA, "bunker_station");       ObjStr.put(Obj.COMARE, "communication_area");   ObjStr.put(Obj.HRBBSN, "harbour_basin"); ObjStr.put(Obj.LOKARE, "lock_area");
    126                 ObjStr.put(Obj.LKBSPT, "lock_basin_part"); ObjStr.put(Obj.PRTARE, "port_area"); ObjStr.put(Obj.REFDMP, "refuse_dump");
    127                 ObjStr.put(Obj.TERMNL, "terminal"); ObjStr.put(Obj.TRNBSN, "turning_basin"); ObjStr.put(Obj.WTWARE, "waterway_area"); ObjStr.put(Obj.WTWGAG, "waterway_gauge");
    128                 ObjStr.put(Obj.TISDGE, "time_schedule"); ObjStr.put(Obj.VEHTRF, "vehicle_transfer"); ObjStr.put(Obj.EXCNST, "exceptional_structure"); ObjStr.put(Obj.MPAARE, "protected_area");
    129                 ObjStr.put(Obj.LITMAJ, "light_major"); ObjStr.put(Obj.LITMIN, "light_minor"); ObjStr.put(Obj.M_COVR, "coverage"); ObjStr.put(Obj.M_NSYS, "system");
    130         }
    131        
    132         private static final HashMap<String, Obj> StrObj = new HashMap<>();
    133         static {
    134                 for (Map.Entry<Obj, String> entry : ObjStr.entrySet()) {
    135                         if (!entry.getValue().isEmpty())
    136                                 StrObj.put(entry.getValue(), entry.getKey());
    137                 }
    138         }
    139        
    140         public static Obj decodeType(long objl) { // Convert S57 feature code to SCM object enumeration
    141                 for (Obj obj : ObjS57.keySet()) {
    142                         if (ObjS57.get(obj) == objl) return obj;
    143                 }
    144                 for (Obj obj : ObjIENC.keySet()) {
    145                         if (ObjIENC.get(obj) == objl) return obj;
    146                 }
    147                 return Obj.UNKOBJ;
    148         }
     71    private static final EnumMap<Obj, Integer> ObjIENC = new EnumMap<>(Obj.class);
     72    static {
     73        ObjIENC.put(Obj.UNKOBJ, 0);
     74        ObjIENC.put(Obj.ACHBRT, 17000); ObjIENC.put(Obj.ACHARE, 17001); ObjIENC.put(Obj.DEPARE, 17003); ObjIENC.put(Obj.DISMAR, 17004); ObjIENC.put(Obj.RESARE, 17005);
     75        ObjIENC.put(Obj.SISTAT, 17007); ObjIENC.put(Obj.SISTAW, 17008); ObjIENC.put(Obj.TOPMAR, 17009); ObjIENC.put(Obj.BERTHS, 17010); ObjIENC.put(Obj.BRIDGE, 17011);
     76        ObjIENC.put(Obj.CBLOHD, 17012); ObjIENC.put(Obj.FERYRT, 17013); ObjIENC.put(Obj.HRBARE, 17014); ObjIENC.put(Obj.HRBFAC, 17015); ObjIENC.put(Obj.LOKBSN, 17016);
     77        ObjIENC.put(Obj.RDOCAL, 17017); ObjIENC.put(Obj.CURENT, 17019); ObjIENC.put(Obj.HULKES, 17020); ObjIENC.put(Obj.PONTON, 17021); ObjIENC.put(Obj.PIPOHD, 17024);
     78        ObjIENC.put(Obj.FLODOC, 17025); ObjIENC.put(Obj.CHKPNT, 17027); ObjIENC.put(Obj.BCNLAT, 17028); ObjIENC.put(Obj.BOYLAT, 17029); ObjIENC.put(Obj.CRANES, 17030);
     79        ObjIENC.put(Obj.GATCON, 17031); ObjIENC.put(Obj.SLCONS, 17032); ObjIENC.put(Obj.UWTROC, 17033); ObjIENC.put(Obj.CONVYR, 17034); ObjIENC.put(Obj.NOTMRK, 17050);
     80        ObjIENC.put(Obj.WTWAXS, 17051); ObjIENC.put(Obj.WTWPRF, 17052); ObjIENC.put(Obj.BUNSTA, 17054); ObjIENC.put(Obj.COMARE, 17055); ObjIENC.put(Obj.HRBBSN, 17056);
     81        ObjIENC.put(Obj.LKBSPT, 17058); ObjIENC.put(Obj.PRTARE, 17059); ObjIENC.put(Obj.REFDMP, 17062); ObjIENC.put(Obj.TERMNL, 17064); ObjIENC.put(Obj.TRNBSN, 17065);
     82        ObjIENC.put(Obj.WTWARE, 17066); ObjIENC.put(Obj.WTWGAG, 17067); ObjIENC.put(Obj.TISDGE, 17068); ObjIENC.put(Obj.VEHTRF, 17069); ObjIENC.put(Obj.EXCNST, 17070);
     83        ObjIENC.put(Obj.LG_SDM, 18001); ObjIENC.put(Obj.LG_VSP, 18002);
     84    }
    14985
    150         public static long encodeType(Obj type) { // Convert SCM object enumeration to S57 feature code
    151                 if (ObjS57.containsKey(type))
    152                         return ObjS57.get(type);
    153                 else if (ObjIENC.containsKey(type))
    154                         return ObjIENC.get(type);
    155                 return 0;
    156         }
     86    private static final EnumMap<Obj, String> ObjStr = new EnumMap<>(Obj.class);
     87    static {
     88        ObjStr.put(Obj.UNKOBJ, ""); ObjStr.put(Obj.AIRARE, "airfield"); ObjStr.put(Obj.ACHBRT, "anchor_berth"); ObjStr.put(Obj.ACHARE, "anchorage");
     89        ObjStr.put(Obj.BCNCAR, "beacon_cardinal"); ObjStr.put(Obj.BCNISD, "beacon_isolated_danger"); ObjStr.put(Obj.BCNLAT, "beacon_lateral");
     90        ObjStr.put(Obj.BCNSAW, "beacon_safe_water"); ObjStr.put(Obj.BCNSPP, "beacon_special_purpose"); ObjStr.put(Obj.BERTHS, "berth"); ObjStr.put(Obj.BRIDGE, "bridge");
     91        ObjStr.put(Obj.BUISGL, "building"); ObjStr.put(Obj.BUAARE, "built-up_area"); ObjStr.put(Obj.BOYCAR, "buoy_cardinal"); ObjStr.put(Obj.BOYINB, "buoy_installation");
     92        ObjStr.put(Obj.BOYISD, "buoy_isolated_danger"); ObjStr.put(Obj.BOYLAT, "buoy_lateral"); ObjStr.put(Obj.BOYSAW, "buoy_safe_water");
     93        ObjStr.put(Obj.BOYSPP, "buoy_special_purpose"); ObjStr.put(Obj.CBLARE, "cable_area"); ObjStr.put(Obj.CBLOHD, "cable_overhead");
     94        ObjStr.put(Obj.CBLSUB, "cable_submarine"); ObjStr.put(Obj.CANALS, "canal"); ObjStr.put(Obj.CTSARE, "cargo_area"); ObjStr.put(Obj.CAUSWY, "causeway");
     95        ObjStr.put(Obj.CTNARE, "caution_area"); ObjStr.put(Obj.CHKPNT, "checkpoint"); ObjStr.put(Obj.CGUSTA, "coastguard_station"); ObjStr.put(Obj.COALNE, "coastline");
     96        ObjStr.put(Obj.CONZNE, "contiguous_zone"); ObjStr.put(Obj.COSARE, "continental_shelf"); ObjStr.put(Obj.CTRPNT, "control_point");
     97        ObjStr.put(Obj.CONVYR, "conveyor"); ObjStr.put(Obj.CRANES, "crane"); ObjStr.put(Obj.CURENT, "current"); ObjStr.put(Obj.CUSZNE, "custom_zone");
     98        ObjStr.put(Obj.DAMCON, "dam"); ObjStr.put(Obj.DAYMAR, "daymark"); ObjStr.put(Obj.DWRTCL, "deep_water_route_centreline"); ObjStr.put(Obj.DWRTPT, "deep_water_route");
     99        ObjStr.put(Obj.DEPARE, "depth_area"); ObjStr.put(Obj.DEPCNT, "depth_contour"); ObjStr.put(Obj.DISMAR, "distance_mark"); ObjStr.put(Obj.DOCARE, "dock");
     100        ObjStr.put(Obj.DRGARE, "dredged_area"); ObjStr.put(Obj.DRYDOC, "dry_dock"); ObjStr.put(Obj.DMPGRD, "dumping_ground"); ObjStr.put(Obj.DYKCON, "dyke");
     101        ObjStr.put(Obj.EXEZNE, "exclusive_economic_zone"); ObjStr.put(Obj.FAIRWY, "fairway"); ObjStr.put(Obj.FNCLNE, "wall"); ObjStr.put(Obj.FERYRT, "ferry_route");
     102        ObjStr.put(Obj.FSHZNE, "fishery_zone"); ObjStr.put(Obj.FSHFAC, "fishing_facility"); ObjStr.put(Obj.FSHGRD, "fishing_ground"); ObjStr.put(Obj.FLODOC, "floating_dock");
     103        ObjStr.put(Obj.FOGSIG, "fog_signal"); ObjStr.put(Obj.FORSTC, "fortified_structure"); ObjStr.put(Obj.FRPARE, "free_port_area"); ObjStr.put(Obj.GATCON, "gate");
     104        ObjStr.put(Obj.GRIDRN, "gridiron"); ObjStr.put(Obj.HRBARE, "harbour_area"); ObjStr.put(Obj.HRBFAC, "harbour"); ObjStr.put(Obj.HULKES, "hulk");
     105        ObjStr.put(Obj.ICEARE, "ice_area"); ObjStr.put(Obj.ICNARE, "incineration_zone"); ObjStr.put(Obj.ISTZNE, "inshore_traffic_zone"); ObjStr.put(Obj.LAKARE, "lake");
     106        ObjStr.put(Obj.LNDARE, "land_area"); ObjStr.put(Obj.LNDELV, "land_elevation"); ObjStr.put(Obj.LNDRGN, "land_region"); ObjStr.put(Obj.LNDMRK, "landmark");
     107        ObjStr.put(Obj.LIGHTS, "light"); ObjStr.put(Obj.LITFLT, "light_float"); ObjStr.put(Obj.LITVES, "light_vessel"); ObjStr.put(Obj.LOCMAG, "local_magnetic_anomaly");
     108        ObjStr.put(Obj.LOKBSN, "lock_basin"); ObjStr.put(Obj.LOGPON, "log_pond"); ObjStr.put(Obj.MAGVAR, "magnetic_variation"); ObjStr.put(Obj.MARCUL, "marine_farm");
     109        ObjStr.put(Obj.MIPARE, "military_area"); ObjStr.put(Obj.MORFAC, "mooring"); ObjStr.put(Obj.NAVLNE, "navigation_line"); ObjStr.put(Obj.OBSTRN, "obstruction");
     110        ObjStr.put(Obj.OFSPLF, "platform"); ObjStr.put(Obj.OSPARE, "production_area"); ObjStr.put(Obj.OILBAR, "oil_barrier"); ObjStr.put(Obj.PILPNT, "pile");
     111        ObjStr.put(Obj.PILBOP, "pilot_boarding"); ObjStr.put(Obj.PIPARE, "pipeline_area"); ObjStr.put(Obj.PIPOHD, "pipeline_overhead"); ObjStr.put(Obj.PIPSOL, "pipeline_submarine");
     112        ObjStr.put(Obj.PONTON, "pontoon"); ObjStr.put(Obj.PRCARE, "precautionary_area"); ObjStr.put(Obj.PRDARE, "land_production_area"); ObjStr.put(Obj.PYLONS, "pylon");
     113        ObjStr.put(Obj.RADLNE, "radar_line"); ObjStr.put(Obj.RADRNG, "radar_range"); ObjStr.put(Obj.RADRFL, "radar_reflector"); ObjStr.put(Obj.RADSTA, "radar_station");
     114        ObjStr.put(Obj.RTPBCN, "radar_transponder"); ObjStr.put(Obj.RDOCAL, "calling-in_point"); ObjStr.put(Obj.RDOSTA, "radio_station"); ObjStr.put(Obj.RAILWY, "railway");
     115        ObjStr.put(Obj.RAPIDS, "rapids"); ObjStr.put(Obj.RCRTCL, "recommended_route_centreline"); ObjStr.put(Obj.RECTRC, "recommended_track");
     116        ObjStr.put(Obj.RCTLPT, "recommended_traffic_lane"); ObjStr.put(Obj.RSCSTA, "rescue_station"); ObjStr.put(Obj.RESARE, "restricted_area");
     117        ObjStr.put(Obj.RETRFL, "retro_reflector"); ObjStr.put(Obj.RIVERS, "river"); ObjStr.put(Obj.ROADWY, "road"); ObjStr.put(Obj.RUNWAY, "runway");
     118        ObjStr.put(Obj.SNDWAV, "sand_waves"); ObjStr.put(Obj.SEAARE, "sea_area"); ObjStr.put(Obj.SPLARE, "seaplane_landing_area"); ObjStr.put(Obj.SBDARE, "seabed_area");
     119        ObjStr.put(Obj.SLCONS, "shoreline_construction"); ObjStr.put(Obj.SISTAT, "signal_station_traffic"); ObjStr.put(Obj.SISTAW, "signal_station_warning");
     120        ObjStr.put(Obj.SILTNK, "tank"); ObjStr.put(Obj.SLOTOP, "slope_topline"); ObjStr.put(Obj.SLOGRD, "sloping_ground"); ObjStr.put(Obj.SMCFAC, "small_craft_facility");
     121        ObjStr.put(Obj.SOUNDG, "sounding"); ObjStr.put(Obj.SPRING, "spring"); ObjStr.put(Obj.STSLNE, "territorial_baseline"); ObjStr.put(Obj.SUBTLN, "submarine_transit_lane");
     122        ObjStr.put(Obj.SWPARE, "swept_area"); ObjStr.put(Obj.TESARE, "territorial_area"); ObjStr.put(Obj.TIDEWY, "tideway"); ObjStr.put(Obj.TOPMAR, "topmark");
     123        ObjStr.put(Obj.TSELNE, "separation_line"); ObjStr.put(Obj.TSSBND, "separation_boundary"); ObjStr.put(Obj.TSSCRS, "separation_crossing");
     124        ObjStr.put(Obj.TSSLPT, "separation_lane"); ObjStr.put(Obj.TSSRON, "separation_roundabout"); ObjStr.put(Obj.TSEZNE, "separation_zone"); ObjStr.put(Obj.TUNNEL, "tunnel");
     125        ObjStr.put(Obj.TWRTPT, "two-way_route"); ObjStr.put(Obj.UWTROC, "rock"); ObjStr.put(Obj.UNSARE, "unsurveyed_area"); ObjStr.put(Obj.VEGATN, "vegetation");
     126        ObjStr.put(Obj.WATTUR, "water_turbulence"); ObjStr.put(Obj.WATFAL, "waterfall"); ObjStr.put(Obj.WEDKLP, "weed"); ObjStr.put(Obj.WRECKS, "wreck");
     127        ObjStr.put(Obj.TS_FEB, "tidal_stream"); ObjStr.put(Obj.NOTMRK, "notice"); ObjStr.put(Obj.WTWAXS, "waterway_axis"); ObjStr.put(Obj.WTWPRF, "waterway_profile");
     128        ObjStr.put(Obj.BUNSTA, "bunker_station"); ObjStr.put(Obj.COMARE, "communication_area"); ObjStr.put(Obj.HRBBSN, "harbour_basin"); ObjStr.put(Obj.LOKARE, "lock_area");
     129        ObjStr.put(Obj.LKBSPT, "lock_basin_part"); ObjStr.put(Obj.PRTARE, "port_area"); ObjStr.put(Obj.REFDMP, "refuse_dump");
     130        ObjStr.put(Obj.TERMNL, "terminal"); ObjStr.put(Obj.TRNBSN, "turning_basin"); ObjStr.put(Obj.WTWARE, "waterway_area"); ObjStr.put(Obj.WTWGAG, "waterway_gauge");
     131        ObjStr.put(Obj.TISDGE, "time_schedule"); ObjStr.put(Obj.VEHTRF, "vehicle_transfer"); ObjStr.put(Obj.EXCNST, "exceptional_structure"); ObjStr.put(Obj.MPAARE, "protected_area");
     132        ObjStr.put(Obj.LITMAJ, "light_major"); ObjStr.put(Obj.LITMIN, "light_minor"); ObjStr.put(Obj.M_COVR, "coverage"); ObjStr.put(Obj.M_NSYS, "system");
     133    }
    157134
    158         public static String stringType(Obj type) { // Convert SCM object enumeration to OSM object string
    159                 String str = ObjStr.get(type);
    160                         return str != null ? str : "";
    161         }
     135    private static final HashMap<String, Obj> StrObj = new HashMap<>();
     136    static {
     137        for (Map.Entry<Obj, String> entry : ObjStr.entrySet()) {
     138            if (!entry.getValue().isEmpty())
     139                StrObj.put(entry.getValue(), entry.getKey());
     140        }
     141    }
    162142
    163         public static Obj enumType(String type) { // Convert OSM object string to SCM object enumeration
    164                 if ((type != null) && !type.isEmpty() && (StrObj.containsKey(type)))
    165                         return StrObj.get(type);
    166                 else
    167                         return Obj.UNKOBJ;
    168         }
    169        
     143    public static Obj decodeType(long objl) { // Convert S57 feature code to SCM object enumeration
     144        for (Obj obj : ObjS57.keySet()) {
     145            if (ObjS57.get(obj) == objl) return obj;
     146        }
     147        for (Obj obj : ObjIENC.keySet()) {
     148            if (ObjIENC.get(obj) == objl) return obj;
     149        }
     150        return Obj.UNKOBJ;
     151    }
     152
     153    public static long encodeType(Obj type) { // Convert SCM object enumeration to S57 feature code
     154        if (ObjS57.containsKey(type))
     155            return ObjS57.get(type);
     156        else if (ObjIENC.containsKey(type))
     157            return ObjIENC.get(type);
     158        return 0;
     159    }
     160
     161    public static String stringType(Obj type) { // Convert SCM object enumeration to OSM object string
     162        String str = ObjStr.get(type);
     163        return str != null ? str : "";
     164    }
     165
     166    public static Obj enumType(String type) { // Convert OSM object string to SCM object enumeration
     167        if ((type != null) && !type.isEmpty() && (StrObj.containsKey(type)))
     168            return StrObj.get(type);
     169        else
     170            return Obj.UNKOBJ;
     171    }
    170172}
  • applications/editors/josm/plugins/seachart/src/s57/S57osm.java

    r32393 r32394  
    1111
    1212import java.io.BufferedReader;
    13 import java.util.*;
    14 
    15 import s57.S57obj.*;
    16 import s57.S57att.*;
    17 import s57.S57val.*;
     13import java.util.ArrayList;
     14import java.util.HashMap;
     15
     16import s57.S57att.Att;
     17import s57.S57obj.Obj;
     18import s57.S57val.CatBUA;
     19import s57.S57val.CatROD;
     20import s57.S57val.Conv;
    1821
    1922public class S57osm { // OSM to S57 Object/Attribute and Object/Primitive conversions
    20        
    21         static class KeyVal<V> {
    22                 Obj obj;
    23                 Att att;
    24                 Conv conv;
    25                 V val;
    26                 KeyVal(Obj o, Att a, Conv c, V v) {
    27                         obj = o;
    28                         att = a;
    29                         conv = c;
    30                         val = v;
    31                 }
    32         }
    33        
    34         private static final HashMap<String, KeyVal<?>> OSMtags = new HashMap<>();
    35         static {
    36                 OSMtags.put("natural=coastline", new KeyVal<>(Obj.COALNE, Att.UNKATT, null, null)); OSMtags.put("natural=water", new KeyVal<>(Obj.LAKARE, Att.UNKATT, null, null));
    37                 OSMtags.put("water=river", new KeyVal<>(Obj.RIVERS, Att.UNKATT, null, null)); OSMtags.put("water=canal", new KeyVal<>(Obj.CANALS, Att.UNKATT, null, null));
    38                 OSMtags.put("waterway=riverbank", new KeyVal<>(Obj.RIVERS, Att.UNKATT, null, null)); OSMtags.put("waterway=dock", new KeyVal<>(Obj.HRBBSN, Att.UNKATT, null, null));
    39                 OSMtags.put("waterway=lock", new KeyVal<>(Obj.HRBBSN, Att.UNKATT, null, null)); OSMtags.put("landuse=basin", new KeyVal<>(Obj.LAKARE, Att.UNKATT, null, null));
    40                 OSMtags.put("wetland=tidalflat", new KeyVal<>(Obj.DEPARE, Att.DRVAL2, Conv.F, (Double)0.0)); OSMtags.put("tidal=yes", new KeyVal<>(Obj.DEPARE, Att.DRVAL2, Conv.F, (Double)0.0));
    41                 OSMtags.put("natural=mud", new KeyVal<>(Obj.DEPARE, Att.UNKATT, null, null)); OSMtags.put("natural=sand", new KeyVal<>(Obj.DEPARE, Att.UNKATT, null, null));
    42                 OSMtags.put("highway=motorway", new KeyVal<>(Obj.ROADWY, Att.CATROD, Conv.E, CatROD.ROD_MWAY)); OSMtags.put("highway=trunk", new KeyVal<>(Obj.ROADWY, Att.CATROD, Conv.E, CatROD.ROD_MAJR));
    43                 OSMtags.put("highway=primary", new KeyVal<>(Obj.ROADWY, Att.CATROD, Conv.E, CatROD.ROD_MAJR)); OSMtags.put("highway=secondary", new KeyVal<>(Obj.ROADWY, Att.CATROD, Conv.E, CatROD.ROD_MINR));
    44                 OSMtags.put("highway=tertiary", new KeyVal<>(Obj.ROADWY, Att.CATROD, Conv.E, CatROD.ROD_MINR)); OSMtags.put("highway=residential", new KeyVal<>(Obj.ROADWY, Att.UNKATT, null, null));
    45                 OSMtags.put("highway=unclassified", new KeyVal<>(Obj.ROADWY, Att.UNKATT, null, null)); OSMtags.put("railway=rail", new KeyVal<>(Obj.RAILWY, Att.UNKATT, null, null));
    46                 OSMtags.put("man_made=breakwater", new KeyVal<>(Obj.SLCONS, Att.UNKATT, null, null)); OSMtags.put("man_made=groyne", new KeyVal<>(Obj.SLCONS, Att.UNKATT, null, null));
    47                 OSMtags.put("man_made=pier", new KeyVal<>(Obj.SLCONS, Att.UNKATT, null, null)); OSMtags.put("man_made=jetty", new KeyVal<>(Obj.SLCONS, Att.UNKATT, null, null));
    48                 OSMtags.put("landuse=industrial", new KeyVal<>(Obj.BUAARE, Att.UNKATT, null, null)); OSMtags.put("landuse=commercial", new KeyVal<>(Obj.BUAARE, Att.UNKATT, null, null));
    49                 OSMtags.put("landuse=retail", new KeyVal<>(Obj.BUAARE, Att.UNKATT, null, null)); OSMtags.put("landuse=residential", new KeyVal<>(Obj.BUAARE, Att.UNKATT, null, null));
    50                 OSMtags.put("place=city", new KeyVal<>(Obj.BUAARE, Att.CATBUA, Conv.E, CatBUA.BUA_CITY)); OSMtags.put("place=town", new KeyVal<>(Obj.BUAARE, Att.CATBUA, Conv.E, CatBUA.BUA_TOWN));
    51                 OSMtags.put("place=village", new KeyVal<>(Obj.BUAARE, Att.CATBUA, Conv.E, CatBUA.BUA_VLLG));
    52                 }
    53        
    54         public static void OSMtag(ArrayList<KeyVal<?>> osm, String key, String val) {
    55                 KeyVal<?> kv = OSMtags.get(key + "=" + val);
    56                 if (kv != null) {
    57                         if (kv.conv == Conv.E) {
    58                                 ArrayList<Enum<?>> list = new ArrayList<>();
    59                                 list.add((Enum<?>)kv.val);
    60                                 osm.add(new KeyVal<>(kv.obj, kv.att, kv.conv, list));
    61                         } else {
    62                                 osm.add(kv);
    63                         }
    64                 }
    65                 KeyVal<?> kvl = null;
    66                 KeyVal<?> kvd = null;
    67                 boolean rc = false;
    68                 boolean rcl = false;
    69                 for (KeyVal<?> kvx : osm) {
    70                         if (kvx.obj == Obj.LAKARE) {
    71                                 kvl = kvx;
    72                         } else if ((kvx.obj == Obj.RIVERS) || (kvx.obj == Obj.CANALS)) {
    73                                 rc = true;
    74                         }
    75                         if (kvx.obj == Obj.DEPARE) {
    76                                 kvd = kvx;
    77                         } else if ((kvx.obj == Obj.RIVERS) || (kvx.obj == Obj.CANALS) || (kvx.obj == Obj.LAKARE)) {
    78                                 rcl = true;
    79                         }
    80                 }
    81                 if (rc && (kvl != null)) {
    82                         osm.remove(kvl);
    83                 }
    84                 if (rcl && (kvd != null)) {
    85                         osm.remove(kvd);
    86                 }
    87                 return;
    88         }
    89        
    90         public static void OSMmap(BufferedReader in, S57map map, boolean bb) throws Exception {
    91                 String k = "";
    92                 String v = "";
    93 
    94                 double lat = 0;
    95                 double lon = 0;
    96                 long id = 0;
    97 
    98                 boolean inOsm = false;
    99                 boolean inNode = false;
    100                 boolean inWay = false;
    101                 boolean inRel = false;
    102                 map.nodes.put(1l, map.new Snode());
    103                 map.nodes.put(2l, map.new Snode());
    104                 map.nodes.put(3l, map.new Snode());
    105                 map.nodes.put(4l, map.new Snode());
    106 
    107                 String ln;
    108                 while ((ln = in.readLine()) != null) {
    109                         if (inOsm) {
    110                                 if (ln.contains("<bounds") && !bb) {
    111                                         for (String token : ln.split("[ ]+")) {
    112                                                 if (token.matches("^minlat=.+")) {
    113                                                         map.bounds.minlat = Math.toRadians(Double.parseDouble(token.split("[\"\']")[1]));
    114                                                         map.nodes.get(2l).lat = map.bounds.minlat;
    115                                                         map.nodes.get(3l).lat = map.bounds.minlat;
    116                                                 } else if (token.matches("^minlon=.+")) {
    117                                                         map.bounds.minlon = Math.toRadians(Double.parseDouble(token.split("[\"\']")[1]));
    118                                                         map.nodes.get(1l).lon = map.bounds.minlon;
    119                                                         map.nodes.get(2l).lon = map.bounds.minlon;
    120                                                 } else if (token.matches("^maxlat=.+")) {
    121                                                         map.bounds.maxlat = Math.toRadians(Double.parseDouble(token.split("[\"\']")[1]));
    122                                                         map.nodes.get(1l).lat = map.bounds.maxlat;
    123                                                         map.nodes.get(4l).lat = map.bounds.maxlat;
    124                                                 } else if (token.matches("^maxlon=.+")) {
    125                                                         map.bounds.maxlon = Math.toRadians(Double.parseDouble(token.split("[\"\']")[1]));
    126                                                         map.nodes.get(3l).lon = map.bounds.maxlon;
    127                                                         map.nodes.get(4l).lon = map.bounds.maxlon;
    128                                                 }
    129                                         }
    130                                 } else {
    131                                         if ((inNode || inWay || inRel) && (ln.contains("<tag"))) {
    132                                                 k = v = "";
    133                                                 String[] token = ln.split("k=");
    134                                                 k = token[1].split("[\"\']")[1];
    135                                                 token = token[1].split("v=");
    136                                                 v = token[1].split("[\"\']")[1];
    137                                                 if (!k.isEmpty() && !v.isEmpty()) {
    138                                                         map.addTag(k, v);
    139                                                 }
    140                                         }
    141                                         if (inNode) {
    142                                                 if (ln.contains("</node")) {
    143                                                         inNode = false;
    144                                                         map.tagsDone(id);
    145                                                 }
    146                                         } else if (ln.contains("<node")) {
    147                                                 for (String token : ln.split("[ ]+")) {
    148                                                         if (token.matches("^id=.+")) {
    149                                                                 id = Long.parseLong(token.split("[\"\']")[1]);
    150                                                         } else if (token.matches("^lat=.+")) {
    151                                                                 lat = Double.parseDouble(token.split("[\"\']")[1]);
    152                                                         } else if (token.matches("^lon=.+")) {
    153                                                                 lon = Double.parseDouble(token.split("[\"\']")[1]);
    154                                                         }
    155                                                 }
    156                                                 map.addNode(id, lat, lon);
    157                                                 if (ln.contains("/>")) {
    158                                                         map.tagsDone(id);
    159                                                 } else {
    160                                                         inNode = true;
    161                                                 }
    162                                         } else if (inWay) {
    163                                                 if (ln.contains("<nd")) {
    164                                                         long ref = 0;
    165                                                         for (String token : ln.split("[ ]+")) {
    166                                                                 if (token.matches("^ref=.+")) {
    167                                                                         ref = Long.parseLong(token.split("[\"\']")[1]);
    168                                                                 }
    169                                                         }
    170                                                         try {
    171                                                                 map.addToEdge(ref);
    172                                                         } catch (Exception e) {
    173                                                                 inWay = false;
    174                                                         }
    175                                                 }
    176                                                 if (ln.contains("</way")) {
    177                                                         inWay = false;
    178                                                         map.tagsDone(id);
    179                                                 }
    180                                         } else if (ln.contains("<way")) {
    181                                                 for (String token : ln.split("[ ]+")) {
    182                                                         if (token.matches("^id=.+")) {
    183                                                                 id = Long.parseLong(token.split("[\"\']")[1]);
    184                                                         }
    185                                                 }
    186                                                 map.addEdge(id);
    187                                                 if (ln.contains("/>")) {
    188                                                         map.tagsDone(0);
    189                                                 } else {
    190                                                         inWay = true;
    191                                                 }
    192                                         } else if (ln.contains("</osm")) {
    193                                                 map.mapDone();
    194                                                 inOsm = false;
    195                                                 break;
    196                                         } else if (inRel) {
    197                                                 if (ln.contains("<member")) {
    198                                                         String type = "";
    199                                                         String role = "";
    200                                                         long ref = 0;
    201                                                         for (String token : ln.split("[ ]+")) {
    202                                                                 if (token.matches("^ref=.+")) {
    203                                                                         ref = Long.parseLong(token.split("[\"\']")[1]);
    204                                                                 } else if (token.matches("^type=.+")) {
    205                                                                         type = (token.split("[\"\']")[1]);
    206                                                                 } else if (token.matches("^role=.+")) {
    207                                                                         String str[] = token.split("[\"\']");
    208                                                                         if (str.length > 1) {
    209                                                                                 role = (token.split("[\"\']")[1]);
    210                                                                         }
    211                                                                 }
    212                                                         }
    213                                                         if ((role.equals("outer") || role.equals("inner")) && type.equals("way"))
    214                                                                 map.addToArea(ref, role.equals("outer"));
    215                                                 }
    216                                                 if (ln.contains("</relation")) {
    217                                                         inRel = false;
    218                                                         map.tagsDone(id);
    219                                                 }
    220                                         } else if (ln.contains("<relation")) {
    221                                                 for (String token : ln.split("[ ]+")) {
    222                                                         if (token.matches("^id=.+")) {
    223                                                                 id = Long.parseLong(token.split("[\"\']")[1]);
    224                                                         }
    225                                                 }
    226                                                 map.addArea(id);
    227                                                 if (ln.contains("/>")) {
    228                                                         map.tagsDone(id);
    229                                                 } else {
    230                                                         inRel = true;
    231                                                 }
    232                                         }
    233                                 }
    234                         } else if (ln.contains("<osm")) {
    235                                 inOsm = true;
    236                         }
    237                 }
    238                 return;
    239         }
    240        
    241         public static void OSMmeta(S57map map) {
    242                 map.addEdge(++map.xref);
    243                 for (long ref = 0; ref <= 4; ref++) {
    244                         map.addToEdge((ref == 0) ? 4 : ref);
    245                 }
    246                 map.addTag("seamark:type", "coverage");
    247                 map.addTag("seamark:coverage:category", "coverage");
    248                 map.tagsDone(map.xref);
    249         }
    250        
     23    // CHECKSTYLE.OFF: LineLength
     24
     25    static class KeyVal<V> {
     26        Obj obj;
     27        Att att;
     28        Conv conv;
     29        V val;
     30        KeyVal(Obj o, Att a, Conv c, V v) {
     31            obj = o;
     32            att = a;
     33            conv = c;
     34            val = v;
     35        }
     36    }
     37
     38    private static final HashMap<String, KeyVal<?>> OSMtags = new HashMap<>();
     39    static {
     40        OSMtags.put("natural=coastline", new KeyVal<>(Obj.COALNE, Att.UNKATT, null, null)); OSMtags.put("natural=water", new KeyVal<>(Obj.LAKARE, Att.UNKATT, null, null));
     41        OSMtags.put("water=river", new KeyVal<>(Obj.RIVERS, Att.UNKATT, null, null)); OSMtags.put("water=canal", new KeyVal<>(Obj.CANALS, Att.UNKATT, null, null));
     42        OSMtags.put("waterway=riverbank", new KeyVal<>(Obj.RIVERS, Att.UNKATT, null, null)); OSMtags.put("waterway=dock", new KeyVal<>(Obj.HRBBSN, Att.UNKATT, null, null));
     43        OSMtags.put("waterway=lock", new KeyVal<>(Obj.HRBBSN, Att.UNKATT, null, null)); OSMtags.put("landuse=basin", new KeyVal<>(Obj.LAKARE, Att.UNKATT, null, null));
     44        OSMtags.put("wetland=tidalflat", new KeyVal<>(Obj.DEPARE, Att.DRVAL2, Conv.F, 0.0)); OSMtags.put("tidal=yes", new KeyVal<>(Obj.DEPARE, Att.DRVAL2, Conv.F, 0.0));
     45        OSMtags.put("natural=mud", new KeyVal<>(Obj.DEPARE, Att.UNKATT, null, null)); OSMtags.put("natural=sand", new KeyVal<>(Obj.DEPARE, Att.UNKATT, null, null));
     46        OSMtags.put("highway=motorway", new KeyVal<>(Obj.ROADWY, Att.CATROD, Conv.E, CatROD.ROD_MWAY)); OSMtags.put("highway=trunk", new KeyVal<>(Obj.ROADWY, Att.CATROD, Conv.E, CatROD.ROD_MAJR));
     47        OSMtags.put("highway=primary", new KeyVal<>(Obj.ROADWY, Att.CATROD, Conv.E, CatROD.ROD_MAJR)); OSMtags.put("highway=secondary", new KeyVal<>(Obj.ROADWY, Att.CATROD, Conv.E, CatROD.ROD_MINR));
     48        OSMtags.put("highway=tertiary", new KeyVal<>(Obj.ROADWY, Att.CATROD, Conv.E, CatROD.ROD_MINR)); OSMtags.put("highway=residential", new KeyVal<>(Obj.ROADWY, Att.UNKATT, null, null));
     49        OSMtags.put("highway=unclassified", new KeyVal<>(Obj.ROADWY, Att.UNKATT, null, null)); OSMtags.put("railway=rail", new KeyVal<>(Obj.RAILWY, Att.UNKATT, null, null));
     50        OSMtags.put("man_made=breakwater", new KeyVal<>(Obj.SLCONS, Att.UNKATT, null, null)); OSMtags.put("man_made=groyne", new KeyVal<>(Obj.SLCONS, Att.UNKATT, null, null));
     51        OSMtags.put("man_made=pier", new KeyVal<>(Obj.SLCONS, Att.UNKATT, null, null)); OSMtags.put("man_made=jetty", new KeyVal<>(Obj.SLCONS, Att.UNKATT, null, null));
     52        OSMtags.put("landuse=industrial", new KeyVal<>(Obj.BUAARE, Att.UNKATT, null, null)); OSMtags.put("landuse=commercial", new KeyVal<>(Obj.BUAARE, Att.UNKATT, null, null));
     53        OSMtags.put("landuse=retail", new KeyVal<>(Obj.BUAARE, Att.UNKATT, null, null)); OSMtags.put("landuse=residential", new KeyVal<>(Obj.BUAARE, Att.UNKATT, null, null));
     54        OSMtags.put("place=city", new KeyVal<>(Obj.BUAARE, Att.CATBUA, Conv.E, CatBUA.BUA_CITY)); OSMtags.put("place=town", new KeyVal<>(Obj.BUAARE, Att.CATBUA, Conv.E, CatBUA.BUA_TOWN));
     55        OSMtags.put("place=village", new KeyVal<>(Obj.BUAARE, Att.CATBUA, Conv.E, CatBUA.BUA_VLLG));
     56    }
     57
     58    public static void OSMtag(ArrayList<KeyVal<?>> osm, String key, String val) {
     59        KeyVal<?> kv = OSMtags.get(key + "=" + val);
     60        if (kv != null) {
     61            if (kv.conv == Conv.E) {
     62                ArrayList<Enum<?>> list = new ArrayList<>();
     63                list.add((Enum<?>) kv.val);
     64                osm.add(new KeyVal<>(kv.obj, kv.att, kv.conv, list));
     65            } else {
     66                osm.add(kv);
     67            }
     68        }
     69        KeyVal<?> kvl = null;
     70        KeyVal<?> kvd = null;
     71        boolean rc = false;
     72        boolean rcl = false;
     73        for (KeyVal<?> kvx : osm) {
     74            if (kvx.obj == Obj.LAKARE) {
     75                kvl = kvx;
     76            } else if ((kvx.obj == Obj.RIVERS) || (kvx.obj == Obj.CANALS)) {
     77                rc = true;
     78            }
     79            if (kvx.obj == Obj.DEPARE) {
     80                kvd = kvx;
     81            } else if ((kvx.obj == Obj.RIVERS) || (kvx.obj == Obj.CANALS) || (kvx.obj == Obj.LAKARE)) {
     82                rcl = true;
     83            }
     84        }
     85        if (rc && (kvl != null)) {
     86            osm.remove(kvl);
     87        }
     88        if (rcl && (kvd != null)) {
     89            osm.remove(kvd);
     90        }
     91        return;
     92    }
     93
     94    public static void OSMmap(BufferedReader in, S57map map, boolean bb) throws Exception {
     95        String k = "";
     96        String v = "";
     97
     98        double lat = 0;
     99        double lon = 0;
     100        long id = 0;
     101
     102        boolean inOsm = false;
     103        boolean inNode = false;
     104        boolean inWay = false;
     105        boolean inRel = false;
     106        map.nodes.put(1L, map.new Snode());
     107        map.nodes.put(2L, map.new Snode());
     108        map.nodes.put(3L, map.new Snode());
     109        map.nodes.put(4L, map.new Snode());
     110
     111        String ln;
     112        while ((ln = in.readLine()) != null) {
     113            if (inOsm) {
     114                if (ln.contains("<bounds") && !bb) {
     115                    for (String token : ln.split("[ ]+")) {
     116                        if (token.matches("^minlat=.+")) {
     117                            map.bounds.minlat = Math.toRadians(Double.parseDouble(token.split("[\"\']")[1]));
     118                            map.nodes.get(2L).lat = map.bounds.minlat;
     119                            map.nodes.get(3L).lat = map.bounds.minlat;
     120                        } else if (token.matches("^minlon=.+")) {
     121                            map.bounds.minlon = Math.toRadians(Double.parseDouble(token.split("[\"\']")[1]));
     122                            map.nodes.get(1L).lon = map.bounds.minlon;
     123                            map.nodes.get(2L).lon = map.bounds.minlon;
     124                        } else if (token.matches("^maxlat=.+")) {
     125                            map.bounds.maxlat = Math.toRadians(Double.parseDouble(token.split("[\"\']")[1]));
     126                            map.nodes.get(1L).lat = map.bounds.maxlat;
     127                            map.nodes.get(4L).lat = map.bounds.maxlat;
     128                        } else if (token.matches("^maxlon=.+")) {
     129                            map.bounds.maxlon = Math.toRadians(Double.parseDouble(token.split("[\"\']")[1]));
     130                            map.nodes.get(3L).lon = map.bounds.maxlon;
     131                            map.nodes.get(4L).lon = map.bounds.maxlon;
     132                        }
     133                    }
     134                } else {
     135                    if ((inNode || inWay || inRel) && (ln.contains("<tag"))) {
     136                        k = v = "";
     137                        String[] token = ln.split("k=");
     138                        k = token[1].split("[\"\']")[1];
     139                        token = token[1].split("v=");
     140                        v = token[1].split("[\"\']")[1];
     141                        if (!k.isEmpty() && !v.isEmpty()) {
     142                            map.addTag(k, v);
     143                        }
     144                    }
     145                    if (inNode) {
     146                        if (ln.contains("</node")) {
     147                            inNode = false;
     148                            map.tagsDone(id);
     149                        }
     150                    } else if (ln.contains("<node")) {
     151                        for (String token : ln.split("[ ]+")) {
     152                            if (token.matches("^id=.+")) {
     153                                id = Long.parseLong(token.split("[\"\']")[1]);
     154                            } else if (token.matches("^lat=.+")) {
     155                                lat = Double.parseDouble(token.split("[\"\']")[1]);
     156                            } else if (token.matches("^lon=.+")) {
     157                                lon = Double.parseDouble(token.split("[\"\']")[1]);
     158                            }
     159                        }
     160                        map.addNode(id, lat, lon);
     161                        if (ln.contains("/>")) {
     162                            map.tagsDone(id);
     163                        } else {
     164                            inNode = true;
     165                        }
     166                    } else if (inWay) {
     167                        if (ln.contains("<nd")) {
     168                            long ref = 0;
     169                            for (String token : ln.split("[ ]+")) {
     170                                if (token.matches("^ref=.+")) {
     171                                    ref = Long.parseLong(token.split("[\"\']")[1]);
     172                                }
     173                            }
     174                            try {
     175                                map.addToEdge(ref);
     176                            } catch (Exception e) {
     177                                inWay = false;
     178                            }
     179                        }
     180                        if (ln.contains("</way")) {
     181                            inWay = false;
     182                            map.tagsDone(id);
     183                        }
     184                    } else if (ln.contains("<way")) {
     185                        for (String token : ln.split("[ ]+")) {
     186                            if (token.matches("^id=.+")) {
     187                                id = Long.parseLong(token.split("[\"\']")[1]);
     188                            }
     189                        }
     190                        map.addEdge(id);
     191                        if (ln.contains("/>")) {
     192                            map.tagsDone(0);
     193                        } else {
     194                            inWay = true;
     195                        }
     196                    } else if (ln.contains("</osm")) {
     197                        map.mapDone();
     198                        inOsm = false;
     199                        break;
     200                    } else if (inRel) {
     201                        if (ln.contains("<member")) {
     202                            String type = "";
     203                            String role = "";
     204                            long ref = 0;
     205                            for (String token : ln.split("[ ]+")) {
     206                                if (token.matches("^ref=.+")) {
     207                                    ref = Long.parseLong(token.split("[\"\']")[1]);
     208                                } else if (token.matches("^type=.+")) {
     209                                    type = (token.split("[\"\']")[1]);
     210                                } else if (token.matches("^role=.+")) {
     211                                    String[] str = token.split("[\"\']");
     212                                    if (str.length > 1) {
     213                                        role = (token.split("[\"\']")[1]);
     214                                    }
     215                                }
     216                            }
     217                            if ((role.equals("outer") || role.equals("inner")) && type.equals("way"))
     218                                map.addToArea(ref, role.equals("outer"));
     219                        }
     220                        if (ln.contains("</relation")) {
     221                            inRel = false;
     222                            map.tagsDone(id);
     223                        }
     224                    } else if (ln.contains("<relation")) {
     225                        for (String token : ln.split("[ ]+")) {
     226                            if (token.matches("^id=.+")) {
     227                                id = Long.parseLong(token.split("[\"\']")[1]);
     228                            }
     229                        }
     230                        map.addArea(id);
     231                        if (ln.contains("/>")) {
     232                            map.tagsDone(id);
     233                        } else {
     234                            inRel = true;
     235                        }
     236                    }
     237                }
     238            } else if (ln.contains("<osm")) {
     239                inOsm = true;
     240            }
     241        }
     242        return;
     243    }
     244
     245    public static void OSMmeta(S57map map) {
     246        map.addEdge(++map.xref);
     247        for (long ref = 0; ref <= 4; ref++) {
     248            map.addToEdge((ref == 0) ? 4 : ref);
     249        }
     250        map.addTag("seamark:type", "coverage");
     251        map.addTag("seamark:coverage:category", "coverage");
     252        map.tagsDone(map.xref);
     253    }
     254
    251255}
  • applications/editors/josm/plugins/seachart/src/s57/S57val.java

    r32393 r32394  
    1010package s57;
    1111
    12 import java.util.*;
    13 
    14 import s57.S57att.*;
     12import java.util.ArrayList;
     13import java.util.EnumMap;
     14
     15import s57.S57att.Att;
    1516
    1617public class S57val { // S57 Attribute values lookup tables & methods
    17 
    18  static class S57enum {
    19   Integer atvl;
    20   String val;
    21   S57enum(Integer a, String v) {
    22    atvl = a; val = v;
    23   }
    24  }
    25  
    26  public enum Conv { S, A, L, E, F, I }
    27  
    28  static class S57key {
    29   Conv conv;
    30   EnumMap<?, ?> map;
    31   S57key(Conv c, EnumMap<?, S57enum> m) {
    32    conv = c; map = m;
    33   }
    34  }
    35  
    36  public static class AttVal<V> {
    37   public Conv conv;
    38   public V val;
    39   AttVal(Conv c, V v) {
    40    conv = c; val = v;
    41   }
    42  }
    43  
    44  public enum BcnSHP { BCN_UNKN, BCN_STAK, BCN_WTHY, BCN_TOWR, BCN_LATT, BCN_PILE, BCN_CARN, BCN_BUOY, BCN_POLE, BCN_PRCH, BCN_POST }
    45  private static final EnumMap<BcnSHP, S57enum> Bcnshp = new EnumMap<>(BcnSHP.class); static { Bcnshp.put(BcnSHP.BCN_UNKN, new S57enum(0, ""));
    46   Bcnshp.put(BcnSHP.BCN_STAK, new S57enum(1, "stake")); Bcnshp.put(BcnSHP.BCN_WTHY, new S57enum(2, "withy")); Bcnshp.put(BcnSHP.BCN_TOWR, new S57enum(3, "tower"));
    47   Bcnshp.put(BcnSHP.BCN_LATT, new S57enum(4, "lattice")); Bcnshp.put(BcnSHP.BCN_PILE, new S57enum(5, "pile")); Bcnshp.put(BcnSHP.BCN_CARN, new S57enum(6, "cairn"));
    48   Bcnshp.put(BcnSHP.BCN_BUOY, new S57enum(7, "buoyant")); Bcnshp.put(BcnSHP.BCN_POLE, new S57enum(1, "pole")); Bcnshp.put(BcnSHP.BCN_PRCH, new S57enum(1, "perch"));
    49   Bcnshp.put(BcnSHP.BCN_POST, new S57enum(1, "post"));
    50  }
    51  public enum BuiSHP { BUI_UNKN, BUI_HIRS, BUI_PYRD, BUI_CYLR, BUI_SPHR, BUI_CUBE }
    52  private static final EnumMap<BuiSHP, S57enum> Buishp = new EnumMap<>(BuiSHP.class); static { Buishp.put(BuiSHP.BUI_UNKN, new S57enum(0, ""));
    53   Buishp.put(BuiSHP.BUI_HIRS, new S57enum(5, "high-rise")); Buishp.put(BuiSHP.BUI_PYRD, new S57enum(6, "pyramid")); Buishp.put(BuiSHP.BUI_CYLR, new S57enum(7, "cylindrical"));
    54   Buishp.put(BuiSHP.BUI_SPHR, new S57enum(8, "spherical")); Buishp.put(BuiSHP.BUI_CUBE, new S57enum(9, "cubic"));
    55  }
    56  public enum BoySHP { BOY_UNKN, BOY_CONE, BOY_CAN, BOY_SPHR, BOY_PILR, BOY_SPAR, BOY_BARL, BOY_SUPR, BOY_ICE }
    57  private static final EnumMap<BoySHP, S57enum> Boyshp = new EnumMap<>(BoySHP.class); static { Boyshp.put(BoySHP.BOY_UNKN, new S57enum(0, ""));
    58   Boyshp.put(BoySHP.BOY_CONE, new S57enum(1, "conical")); Boyshp.put(BoySHP.BOY_CAN, new S57enum(2, "can")); Boyshp.put(BoySHP.BOY_SPHR, new S57enum(3, "spherical"));
    59   Boyshp.put(BoySHP.BOY_PILR, new S57enum(4, "pillar")); Boyshp.put(BoySHP.BOY_SPAR, new S57enum(5, "spar")); Boyshp.put(BoySHP.BOY_BARL, new S57enum(6, "barrel"));
    60    Boyshp.put(BoySHP.BOY_SUPR, new S57enum(7, "super-buoy")); Boyshp.put(BoySHP.BOY_ICE, new S57enum(8, "ice_buoy"));
    61  }
    62  public enum CatAIR { AIR_UNKN, AIR_MILA, AIR_CIVA, AIR_MILH, AIR_CIVH, AIR_GLDR, AIR_SMLP, AIR_EMRG }
    63  private static final EnumMap<CatAIR, S57enum> Catair = new EnumMap<>(CatAIR.class); static { Catair.put(CatAIR.AIR_UNKN, new S57enum(0, ""));
    64   Catair.put(CatAIR.AIR_MILA, new S57enum(1, "military")); Catair.put(CatAIR.AIR_CIVA, new S57enum(2, "civil")); Catair.put(CatAIR.AIR_MILH, new S57enum(3, "military_heliport"));
    65   Catair.put(CatAIR.AIR_CIVH, new S57enum(4, "civil_heliport")); Catair.put(CatAIR.AIR_GLDR, new S57enum(5, "glider")); Catair.put(CatAIR.AIR_SMLP, new S57enum(6, "small_planes"));
    66   Catair.put(CatAIR.AIR_EMRG, new S57enum(8, "emergency"));
    67  }
    68  public enum CatACH { ACH_UNKN, ACH_UNRD, ACH_DEEP, ACH_TANK, ACH_EXPL, ACH_QUAR, ACH_SEAP, ACH_SMCF, ACH_SMCM, ACH_H24P, ACH_LTPD, ACH_NPSH, ACH_DRYC, ACH_RAFT, ACH_WAIT, ACH_REPT }
    69  private static final EnumMap<CatACH, S57enum> Catach = new EnumMap<>(CatACH.class); static {Catach.put(CatACH.ACH_UNKN, new S57enum(0, ""));
    70   Catach.put(CatACH.ACH_UNRD, new S57enum(1, "unrestricted")); Catach.put(CatACH.ACH_DEEP, new S57enum(2, "deep_water")); Catach.put(CatACH.ACH_TANK, new S57enum(3, "tanker"));
    71   Catach.put(CatACH.ACH_EXPL, new S57enum(4, "explosives")); Catach.put(CatACH.ACH_QUAR, new S57enum(5, "quarantine")); Catach.put(CatACH.ACH_SEAP, new S57enum(6, "seaplane"));
    72   Catach.put(CatACH.ACH_SMCF, new S57enum(7, "small_craft")); Catach.put(CatACH.ACH_SMCM, new S57enum(8, "small_craft_mooring")); Catach.put(CatACH.ACH_H24P, new S57enum(9, "24_hour"));
    73   Catach.put(CatACH.ACH_LTPD, new S57enum(10, "limited_period")); Catach.put(CatACH.ACH_NPSH, new S57enum(11, "non_pushing")); Catach.put(CatACH.ACH_DRYC, new S57enum(12, "dry_cargo"));
    74   Catach.put(CatACH.ACH_RAFT, new S57enum(13, "raft")); Catach.put(CatACH.ACH_WAIT, new S57enum(14, "waiting")); Catach.put(CatACH.ACH_REPT, new S57enum(15, "reported"));
    75  }
    76  public enum CatBRG { BRG_UNKN, BRG_FIXD, BRG_OPEN, BRG_SWNG, BRG_LIFT, BRG_BASC, BRG_PONT, BRG_DRAW, BRG_TRNS, BRG_FOOT, BRG_VIAD, BRG_AQUA, BRG_SUSP }
    77  private static final EnumMap<CatBRG, S57enum> Catbrg = new EnumMap<>(CatBRG.class); static {Catbrg.put(CatBRG.BRG_UNKN, new S57enum(0, ""));
    78   Catbrg.put(CatBRG.BRG_FIXD, new S57enum(1, "fixed")); Catbrg.put(CatBRG.BRG_OPEN, new S57enum(2, "opening")); Catbrg.put(CatBRG.BRG_SWNG, new S57enum(3, "swing"));
    79   Catbrg.put(CatBRG.BRG_LIFT, new S57enum(4, "lifting")); Catbrg.put(CatBRG.BRG_BASC, new S57enum(5, "bascule")); Catbrg.put(CatBRG.BRG_PONT, new S57enum(6, "pontoon"));
    80   Catbrg.put(CatBRG.BRG_DRAW, new S57enum(7, "drawbridge")); Catbrg.put(CatBRG.BRG_TRNS, new S57enum(8, "transporter")); Catbrg.put(CatBRG.BRG_FOOT, new S57enum(9, "footbridge"));
    81   Catbrg.put(CatBRG.BRG_VIAD, new S57enum(10, "viaduct")); Catbrg.put(CatBRG.BRG_AQUA, new S57enum(11, "aqueduct")); Catbrg.put(CatBRG.BRG_SUSP, new S57enum(12, "suspension"));
    82  }
    83  public enum CatBUA { BUA_UNKN, BUA_URBN, BUA_STTL, BUA_VLLG, BUA_TOWN, BUA_CITY, BUA_HOLV }
    84  private static final EnumMap<CatBUA, S57enum> Catbua = new EnumMap<>(CatBUA.class); static { Catbua.put(CatBUA.BUA_UNKN, new S57enum(0, ""));
    85   Catbua.put(CatBUA.BUA_URBN, new S57enum(1, "urban")); Catbua.put(CatBUA.BUA_STTL, new S57enum(2, "settlement")); Catbua.put(CatBUA.BUA_VLLG, new S57enum(3, "village"));
    86   Catbua.put(CatBUA.BUA_TOWN, new S57enum(4, "town")); Catbua.put(CatBUA.BUA_CITY, new S57enum(5, "city")); Catbua.put(CatBUA.BUA_HOLV, new S57enum(6, "holiday_village"));
    87  }
    88  public enum CatCBL { CBL_UNKN, CBL_POWR, CBL_TRNS, CBL_TELE, CBL_TGPH, CBL_MOOR, CBL_OPTC, CBL_FERY }
    89  private static final EnumMap<CatCBL, S57enum> Catcbl = new EnumMap<>(CatCBL.class); static {Catcbl.put(CatCBL.CBL_UNKN, new S57enum(0, ""));
    90   Catcbl.put(CatCBL.CBL_POWR, new S57enum(1, "power")); Catcbl.put(CatCBL.CBL_TRNS, new S57enum(3, "transmission")); Catcbl.put(CatCBL.CBL_TELE, new S57enum(4, "telephone"));
    91   Catcbl.put(CatCBL.CBL_TGPH, new S57enum(5, "telegraph")); Catcbl.put(CatCBL.CBL_MOOR, new S57enum(6, "mooring")); Catcbl.put(CatCBL.CBL_OPTC, new S57enum(7, "optical"));
    92   Catcbl.put(CatCBL.CBL_FERY, new S57enum(8, "ferry"));
    93  }
    94  public enum CatCAN { CAN_UNKN, CAN_TRNS, CAN_DRNG, CAN_IRGN }
    95  private static final EnumMap<CatCAN, S57enum> Catcan = new EnumMap<>(CatCAN.class); static { Catcan.put(CatCAN.CAN_UNKN, new S57enum(0, ""));
    96   Catcan.put(CatCAN.CAN_TRNS, new S57enum(1, "transportation")); Catcan.put(CatCAN.CAN_DRNG, new S57enum(2, "drainage")); Catcan.put(CatCAN.CAN_IRGN, new S57enum(3, "irrigation"));
    97  }
    98  public enum CatCAM { CAM_UNKN, CAM_NORTH, CAM_EAST, CAM_SOUTH, CAM_WEST }
    99  private static final EnumMap<CatCAM, S57enum> Catcam = new EnumMap<>(CatCAM.class); static { Catcam.put(CatCAM.CAM_UNKN, new S57enum(0, ""));
    100   Catcam.put(CatCAM.CAM_NORTH, new S57enum(1, "north")); Catcam.put(CatCAM.CAM_EAST, new S57enum(2, "east"));
    101   Catcam.put(CatCAM.CAM_SOUTH, new S57enum(3, "south")); Catcam.put(CatCAM.CAM_WEST, new S57enum(4, "west"));
    102  }
    103  public enum CatCHP { CHP_UNKN, CHP_CSTM, CHP_BRDR }
    104  private static final EnumMap<CatCHP, S57enum> Catchp = new EnumMap<>(CatCHP.class); static { Catchp.put(CatCHP.CHP_UNKN, new S57enum(0, ""));
    105   Catchp.put(CatCHP.CHP_CSTM, new S57enum(1, "customs")); Catchp.put(CatCHP.CHP_BRDR, new S57enum(2, "border"));
    106  }
    107  public enum CatCOA { COA_UNKN, COA_STEP, COA_FLAT, COA_SAND, COA_STON, COA_SHNG, COA_GLCR, COA_MNGV, COA_MRSH, COA_CRRF, COA_ICE, COA_SHEL }
    108  private static final EnumMap<CatCOA, S57enum> Catcoa = new EnumMap<>(CatCOA.class); static { Catcoa.put(CatCOA.COA_UNKN, new S57enum(0, ""));
    109   Catcoa.put(CatCOA.COA_STEP, new S57enum(1, "steep")); Catcoa.put(CatCOA.COA_FLAT, new S57enum(2, "flat")); Catcoa.put(CatCOA.COA_SAND, new S57enum(3, "sandy"));
    110   Catcoa.put(CatCOA.COA_STON, new S57enum(4, "stony")); Catcoa.put(CatCOA.COA_SHNG, new S57enum(5, "shingly")); Catcoa.put(CatCOA.COA_GLCR, new S57enum(6, "glacier"));
    111   Catcoa.put(CatCOA.COA_MNGV, new S57enum(7, "mangrove")); Catcoa.put(CatCOA.COA_MRSH, new S57enum(8, "marshy")); Catcoa.put(CatCOA.COA_CRRF, new S57enum(9, "coral_reef"));
    112   Catcoa.put(CatCOA.COA_ICE, new S57enum(10, "ice")); Catcoa.put(CatCOA.COA_SHEL, new S57enum(11, "shelly"));
    113  }
    114  public enum CatCTR { CTR_UNKN, CTR_TRGN, CTR_OBSV, CTR_FIXD, CTR_BMRK, CTR_BDRY, CTR_HORM, CTR_HORS }
    115  private static final EnumMap<CatCTR, S57enum> Catctr = new EnumMap<>(CatCTR.class); static { Catctr.put(CatCTR.CTR_UNKN, new S57enum(0, ""));
    116   Catctr.put(CatCTR.CTR_TRGN, new S57enum(1, "triangulation")); Catctr.put(CatCTR.CTR_OBSV, new S57enum(2, "observation")); Catctr.put(CatCTR.CTR_FIXD, new S57enum(3, "fixed"));
    117   Catctr.put(CatCTR.CTR_BMRK, new S57enum(4, "benchmark")); Catctr.put(CatCTR.CTR_BDRY, new S57enum(5, "boundary")); Catctr.put(CatCTR.CTR_HORM, new S57enum(6, "horizontal_main"));
    118   Catctr.put(CatCTR.CTR_HORS, new S57enum(7, "horizontal_secondary"));
    119  }
    120  public enum CatCON { CON_UNKN, CAT_AERL, CAT_BELT }
    121  private static final EnumMap<CatCON, S57enum> Catcon = new EnumMap<>(CatCON.class); static { Catcon.put(CatCON.CON_UNKN, new S57enum(0, ""));
    122   Catcon.put(CatCON.CAT_AERL, new S57enum(1, "aerial")); Catcon.put(CatCON.CAT_BELT, new S57enum(2, "belt"));
    123  }
    124  public enum CatCRN { CRN_UNKN, CRN_NONS, CRN_CONT, CRN_SHRL, CRN_TRAV, CRN_AFRM, CRN_GLTH }
    125  private static final EnumMap<CatCRN, S57enum> Catcrn = new EnumMap<>(CatCRN.class); static { Catcrn.put(CatCRN.CRN_UNKN, new S57enum(0, ""));
    126   Catcrn.put(CatCRN.CRN_NONS, new S57enum(1, "non-specific")); Catcrn.put(CatCRN.CRN_CONT, new S57enum(2, "container")); Catcrn.put(CatCRN.CRN_SHRL, new S57enum(3, "sheerlegs"));
    127   Catcrn.put(CatCRN.CRN_TRAV, new S57enum(4, "travelling")); Catcrn.put(CatCRN.CRN_AFRM , new S57enum(5, "a-frame")); Catcrn.put(CatCRN.CRN_GLTH , new S57enum(6, "goliath"));
    128  }
    129  public enum CatDAM { DAM_UNKN, DAM_WEIR, DAM_DAM, DAM_FLDB }
    130  private static final EnumMap<CatDAM, S57enum> Catdam = new EnumMap<>(CatDAM.class); static { Catdam.put(CatDAM.DAM_UNKN, new S57enum(0, ""));
    131   Catdam.put(CatDAM.DAM_WEIR, new S57enum(1, "weir")); Catdam.put(CatDAM.DAM_DAM, new S57enum(2, "dam")); Catdam.put(CatDAM.DAM_FLDB, new S57enum(3, "flood_barrage"));
    132  }
    133  public enum CatDIS { DIS_UNKN, DIS_NONI, DIS_POLE, DIS_BORD, DIS_UKSH }
    134  private static final EnumMap<CatDIS, S57enum> Catdis = new EnumMap<>(CatDIS.class); static { Catdis.put(CatDIS.DIS_UNKN, new S57enum(0, ""));
    135   Catdis.put(CatDIS.DIS_NONI, new S57enum(1, "not_installed")); Catdis.put(CatDIS.DIS_POLE, new S57enum(2, "pole")); Catdis.put(CatDIS.DIS_BORD, new S57enum(3, "board"));
    136   Catdis.put(CatDIS.DIS_UKSH, new S57enum(4, "unknown_shape"));
    137  }
    138  public enum CatDOC { DOC_UNKN, DOC_TIDL, DOC_NTDL }
    139  private static final EnumMap<CatDOC, S57enum> Catdoc = new EnumMap<>(CatDOC.class); static { Catdoc.put(CatDOC.DOC_UNKN, new S57enum(0, ""));
    140   Catdoc.put(CatDOC.DOC_TIDL, new S57enum(1, "tidal")); Catdoc.put(CatDOC.DOC_NTDL, new S57enum(2, "non-tidal"));
    141  }
    142  public enum CatDPG { DPG_UNKN, DPG_GENL, DPG_CHEM, DPG_NCLR, DPG_EXPL, DPG_SPIL, DPG_VSSL }
    143  private static final EnumMap<CatDPG, S57enum> Catdpg = new EnumMap<>(CatDPG.class); static { Catdpg.put(CatDPG.DPG_UNKN, new S57enum(0, ""));
    144   Catdpg.put(CatDPG.DPG_GENL, new S57enum(1, "general")); Catdpg.put(CatDPG.DPG_CHEM, new S57enum(2, "chemical")); Catdpg.put(CatDPG.DPG_NCLR, new S57enum(3, "nuclear"));
    145   Catdpg.put(CatDPG.DPG_EXPL, new S57enum(4, "explosives")); Catdpg.put(CatDPG.DPG_SPIL, new S57enum(5, "spoil")); Catdpg.put(CatDPG.DPG_VSSL, new S57enum(6, "vessel"));
    146  }
    147  public enum CatFNC { FNC_UNKN, FNC_FENC, FNC_MUIR, FNC_HEDG, FNC_WALL }
    148  private static final EnumMap<CatFNC, S57enum> Catfnc = new EnumMap<>(CatFNC.class); static { Catfnc.put(CatFNC.FNC_UNKN, new S57enum(0, ""));
    149   Catfnc.put(CatFNC.FNC_FENC, new S57enum(1, "fence")); Catfnc.put(CatFNC.FNC_MUIR, new S57enum(2, "muir")); Catfnc.put(CatFNC.FNC_HEDG, new S57enum(3, "hedge"));
    150   Catfnc.put(CatFNC.FNC_WALL, new S57enum(4, "wall"));
    151  }
    152  public enum CatFRY { FRY_UNKN, FRY_FREE, FRY_CABL, FRY_ICE, FRY_SWWR }
    153  private static final EnumMap<CatFRY, S57enum> Catfry = new EnumMap<>(CatFRY.class); static { Catfry.put(CatFRY.FRY_UNKN, new S57enum(0, ""));
    154   Catfry.put(CatFRY.FRY_FREE, new S57enum(1, "free")); Catfry.put(CatFRY.FRY_CABL, new S57enum(2, "cable")); Catfry.put(CatFRY.FRY_ICE, new S57enum(3, "ice"));
    155   Catfry.put(CatFRY.FRY_SWWR, new S57enum(4, "swinging_wire"));
    156  }
    157  public enum CatFIF { FIF_UNKN, FIF_STAK, FIF_TRAP, FIF_WEIR, FIF_TUNY }
    158  private static final EnumMap<CatFIF, S57enum> Catfif = new EnumMap<>(CatFIF.class); static { Catfif.put(CatFIF.FIF_UNKN, new S57enum(0, ""));
    159   Catfif.put(CatFIF.FIF_STAK, new S57enum(1, "stake")); Catfif.put(CatFIF.FIF_TRAP, new S57enum(2, "trap")); Catfif.put(CatFIF.FIF_WEIR, new S57enum(3, "weir"));
    160   Catfif.put(CatFIF.FIF_TUNY, new S57enum(4, "tunny"));
    161  }
    162  public enum CatFOG { FOG_UNKN, FOG_EXPL, FOG_DIA, FOG_SIRN, FOG_NAUT, FOG_REED, FOG_TYPH, FOG_BELL, FOG_WHIS, FOG_GONG, FOG_HORN }
    163  private static final EnumMap<CatFOG, S57enum> Catfog = new EnumMap<>(CatFOG.class); static {Catfog.put(CatFOG.FOG_UNKN, new S57enum(0, ""));
    164   Catfog.put(CatFOG.FOG_EXPL, new S57enum(1, "explosive")); Catfog.put(CatFOG.FOG_DIA, new S57enum(2, "diaphone")); Catfog.put(CatFOG.FOG_SIRN, new S57enum(3, "siren"));
    165   Catfog.put(CatFOG.FOG_NAUT, new S57enum(4, "nautophone")); Catfog.put(CatFOG.FOG_REED, new S57enum(5, "reed"));
    166    Catfog.put(CatFOG.FOG_TYPH, new S57enum(6, "tyfon")); Catfog.put(CatFOG.FOG_BELL, new S57enum(7, "bell")); Catfog.put(CatFOG.FOG_WHIS, new S57enum(8, "whistle"));
    167    Catfog.put(CatFOG.FOG_GONG, new S57enum(9, "gong")); Catfog.put(CatFOG.FOG_HORN, new S57enum(10, "horn"));
    168   }
    169  public enum CatFOR { FOR_UNKN, FOR_CSTL, FOR_FORT, FOR_BTTY, FOR_BKHS, FOR_MTWR, FOR_RDBT }
    170  private static final EnumMap<CatFOR, S57enum> Catfor = new EnumMap<>(CatFOR.class); static { Catfor.put(CatFOR.FOR_UNKN, new S57enum(0, ""));
    171   Catfor.put(CatFOR.FOR_CSTL, new S57enum(1, "castle")); Catfor.put(CatFOR.FOR_FORT, new S57enum(2, "fort")); Catfor.put(CatFOR.FOR_BTTY, new S57enum(3, "battery"));
    172   Catfor.put(CatFOR.FOR_BKHS, new S57enum(4, "blockhouse")); Catfor.put(CatFOR.FOR_MTWR, new S57enum(5, "martello_tower")); Catfor.put(CatFOR.FOR_RDBT, new S57enum(6, "redoubt"));
    173  }
    174  public enum CatGAT { GAT_UNKN, GAT_GNRL, GAT_FLBG, GAT_CSSN, GAT_LOCK, GAT_DYKE, GAT_SLUC }
    175  private static final EnumMap<CatGAT, S57enum> Catgat = new EnumMap<>(CatGAT.class); static { Catgat.put(CatGAT.GAT_UNKN, new S57enum(0, ""));
    176   Catgat.put(CatGAT.GAT_GNRL, new S57enum(1, "general")); Catgat.put(CatGAT.GAT_FLBG, new S57enum(2, "flood_barrage")); Catgat.put(CatGAT.GAT_CSSN, new S57enum(3, "caisson"));
    177   Catgat.put(CatGAT.GAT_LOCK, new S57enum(4, "lock")); Catgat.put(CatGAT.GAT_DYKE, new S57enum(5, "dyke")); Catgat.put(CatGAT.GAT_SLUC, new S57enum(6, "sluice"));
    178  }
    179  public enum CatHAF { HAF_UNKN, HAF_RORO, HAF_TMBR, HAF_FERY, HAF_FISH, HAF_MRNA, HAF_NAVL, HAF_TNKR, HAF_PSGR, HAF_YARD, HAF_CNTR, HAF_BULK, HAF_SYNC, HAF_STCR, HAF_LUVB,
    180   HAF_REPR, HAF_QUAR, HAF_SPLN, HAF_CARG, HAF_OFFS, HAF_SSUP, HAF_MANF }
    181  private static final EnumMap<CatHAF, S57enum> Cathaf = new EnumMap<>(CatHAF.class); static { Cathaf.put(CatHAF.HAF_UNKN, new S57enum(0, ""));
    182   Cathaf.put(CatHAF.HAF_RORO, new S57enum(1, "roro")); Cathaf.put(CatHAF.HAF_FERY, new S57enum(3, "ferry")); Cathaf.put(CatHAF.HAF_FISH, new S57enum(4, "fishing"));
    183   Cathaf.put(CatHAF.HAF_MRNA, new S57enum(5, "marina")); Cathaf.put(CatHAF.HAF_NAVL, new S57enum(6, "naval")); Cathaf.put(CatHAF.HAF_TNKR, new S57enum(7, "tanker"));
    184   Cathaf.put(CatHAF.HAF_PSGR, new S57enum(8, "passenger")); Cathaf.put(CatHAF.HAF_YARD, new S57enum(9, "shipyard")); Cathaf.put(CatHAF.HAF_CNTR, new S57enum(10, "container"));
    185   Cathaf.put(CatHAF.HAF_BULK, new S57enum(11, "bulk")); Cathaf.put(CatHAF.HAF_SYNC, new S57enum(12, "syncrolift")); Cathaf.put(CatHAF.HAF_STCR, new S57enum(13, "straddle_carrier"));
    186   Cathaf.put(CatHAF.HAF_LUVB, new S57enum(14, "lay_up")); Cathaf.put(CatHAF.HAF_TMBR, new S57enum(15, "timber")); Cathaf.put(CatHAF.HAF_REPR, new S57enum(16, "service_repair"));
    187   Cathaf.put(CatHAF.HAF_QUAR, new S57enum(17, "quarantine")); Cathaf.put(CatHAF.HAF_SPLN, new S57enum(18, "seaplane")); Cathaf.put(CatHAF.HAF_CARG, new S57enum(19, "cargo"));
    188   Cathaf.put(CatHAF.HAF_OFFS, new S57enum(20, "offshore_support"));  Cathaf.put(CatHAF.HAF_OFFS, new S57enum(21, "port_support_base"));
    189   Cathaf.put(CatHAF.HAF_MANF, new S57enum(22, "marina_no_facilities"));
    190  }
    191  public enum CatHLK { HLK_UNKN, HLK_REST, HLK_HIST, HLK_MUSM, HLK_ACCM, HLK_BWTR, HLK_CSNO }
    192  private static final EnumMap<CatHLK, S57enum> Cathlk = new EnumMap<>(CatHLK.class); static { Cathlk.put(CatHLK.HLK_UNKN, new S57enum(0, ""));
    193   Cathlk.put(CatHLK.HLK_REST, new S57enum(1, "floating_restaurant")); Cathlk.put(CatHLK.HLK_HIST, new S57enum(2, "historic")); Cathlk.put(CatHLK.HLK_MUSM, new S57enum(3, "museum"));
    194   Cathlk.put(CatHLK.HLK_ACCM, new S57enum(4, "accommodation")); Cathlk.put(CatHLK.HLK_BWTR, new S57enum(5, "floating_breakwater")); Cathlk.put(CatHLK.HLK_CSNO, new S57enum(6, "casino_boat"));
    195  }
    196  public enum CatICE { ICE_UNKN, ICE_FAST, ICE_SEA, ICE_GRLR, ICE_PANK, ICE_GLAS, ICE_PEAK, ICE_PACK, ICE_POLR }
    197  private static final EnumMap<CatICE, S57enum> Catice = new EnumMap<>(CatICE.class); static { Catice.put(CatICE.ICE_UNKN, new S57enum(0, ""));
    198   Catice.put(CatICE.ICE_FAST, new S57enum(1, "fast")); Catice.put(CatICE.ICE_SEA, new S57enum(2, "sea")); Catice.put(CatICE.ICE_GRLR, new S57enum(3, "growler"));
    199   Catice.put(CatICE.ICE_PANK, new S57enum(4, "pancake")); Catice.put(CatICE.ICE_GLAS, new S57enum(5, "glacier")); Catice.put(CatICE.ICE_PEAK, new S57enum(6, "peak"));
    200   Catice.put(CatICE.ICE_PACK, new S57enum(7, "pack")); Catice.put(CatICE.ICE_POLR, new S57enum(8, "polar"));
    201  }
    202  public enum CatINB { INB_UNKN, INB_CALM, INB_SBM }
    203  private static final EnumMap<CatINB, S57enum> Catinb = new EnumMap<>(CatINB.class); static { Catinb.put(CatINB.INB_UNKN, new S57enum(0, ""));
    204   Catinb.put(CatINB.INB_CALM, new S57enum(1, "calm")); Catinb.put(CatINB.INB_SBM, new S57enum(2, "sbm"));
    205  }
    206  public enum CatLND { LND_UNKN, LND_FEN, LND_MRSH, LND_BOG, LND_HTHL, LND_MNTN, LND_LOWL, LND_CNYN, LND_PDDY, LND_AGRI, LND_SVNA, LND_PARK, LND_SWMP, LND_LSLD, LND_LAVA,
    207   LND_SLTP, LND_MORN, LND_CRTR, LND_CAVE, LND_PINCL, LND_CAY }
    208  private static final EnumMap<CatLND, S57enum> Catlnd = new EnumMap<>(CatLND.class); static { Catlnd.put(CatLND.LND_UNKN, new S57enum(0, ""));
    209   Catlnd.put(CatLND.LND_FEN, new S57enum(1, "fen")); Catlnd.put(CatLND.LND_MRSH, new S57enum(2, "marsh")); Catlnd.put(CatLND.LND_BOG, new S57enum(3, "bog"));
    210   Catlnd.put(CatLND.LND_HTHL, new S57enum(4, "heathland")); Catlnd.put(CatLND.LND_MNTN, new S57enum(5, "mountain")); Catlnd.put(CatLND.LND_LOWL, new S57enum(6, "lowlands"));
    211   Catlnd.put(CatLND.LND_CNYN, new S57enum(7, "canyon")); Catlnd.put(CatLND.LND_PDDY, new S57enum(8, "paddy")); Catlnd.put(CatLND.LND_AGRI, new S57enum(9, "agricultural"));
    212   Catlnd.put(CatLND.LND_SVNA, new S57enum(10, "savanna")); Catlnd.put(CatLND.LND_PARK, new S57enum(11, "parkland")); Catlnd.put(CatLND.LND_SWMP, new S57enum(12, "swamp"));
    213   Catlnd.put(CatLND.LND_LSLD, new S57enum(13, "landslide")); Catlnd.put(CatLND.LND_LAVA, new S57enum(14, "lava")); Catlnd.put(CatLND.LND_SLTP, new S57enum(15, "salt_pan"));
    214   Catlnd.put(CatLND.LND_MORN, new S57enum(16, "moraine")); Catlnd.put(CatLND.LND_CRTR, new S57enum(17, "crater")); Catlnd.put(CatLND.LND_CAVE, new S57enum(18, "cave"));
    215   Catlnd.put(CatLND.LND_PINCL, new S57enum(19, "rock_pinnacle")); Catlnd.put(CatLND.LND_CAY, new S57enum(20, "cay"));
    216  }
    217  public enum CatLMK { LMK_UNKN, LMK_CARN, LMK_CMTY, LMK_CHMY, LMK_DISH, LMK_FLAG, LMK_FLAR, LMK_MAST, LMK_WNDS, LMK_MNMT, LMK_CLMN, LMK_MEML, LMK_OBLK, LMK_STAT, LMK_CROS,
    218   LMK_DOME, LMK_RADR, LMK_TOWR, LMK_WNDM, LMK_WNDG, LMK_SPIR, LMK_BLDR, LMK_TRIM, LMK_BNDM, LMK_OBSW, LMK_TORL }
    219  private static final EnumMap<CatLMK, S57enum> Catlmk = new EnumMap<>(CatLMK.class); static {Catlmk.put(CatLMK.LMK_UNKN, new S57enum(0, ""));
    220   Catlmk.put(CatLMK.LMK_CARN, new S57enum(1, "cairn")); Catlmk.put(CatLMK.LMK_CMTY, new S57enum(2, "cemetery")); Catlmk.put(CatLMK.LMK_CHMY, new S57enum(3, "chimney"));
    221   Catlmk.put(CatLMK.LMK_DISH, new S57enum(4, "dish_aerial")); Catlmk.put(CatLMK.LMK_FLAG, new S57enum(5, "flagstaff")); Catlmk.put(CatLMK.LMK_FLAR, new S57enum(6, "flare_stack"));
    222    Catlmk.put(CatLMK.LMK_MAST, new S57enum(7, "mast")); Catlmk.put(CatLMK.LMK_WNDS, new S57enum(8, "windsock")); Catlmk.put(CatLMK.LMK_MNMT, new S57enum(9, "monument"));
    223    Catlmk.put(CatLMK.LMK_CLMN, new S57enum(10, "column")); Catlmk.put(CatLMK.LMK_MEML, new S57enum(11, "memorial")); Catlmk.put(CatLMK.LMK_OBLK, new S57enum(12, "obelisk"));
    224    Catlmk.put(CatLMK.LMK_STAT, new S57enum(13, "statue")); Catlmk.put(CatLMK.LMK_CROS, new S57enum(14, "cross")); Catlmk.put(CatLMK.LMK_DOME, new S57enum(15, "dome"));
    225    Catlmk.put(CatLMK.LMK_RADR, new S57enum(16, "radar_scanner")); Catlmk.put(CatLMK.LMK_TOWR, new S57enum(17, "tower")); Catlmk.put(CatLMK.LMK_WNDM, new S57enum(18, "windmill"));
    226    Catlmk.put(CatLMK.LMK_WNDG, new S57enum(19, "windmotor")); Catlmk.put(CatLMK.LMK_SPIR, new S57enum(20, "spire")); Catlmk.put(CatLMK.LMK_BLDR, new S57enum(21, "boulder"));
    227    Catlmk.put(CatLMK.LMK_TRIM, new S57enum(22, "triangulation_mark")); Catlmk.put(CatLMK.LMK_BNDM, new S57enum(23, "boundary_mark"));
    228    Catlmk.put(CatLMK.LMK_OBSW, new S57enum(24, "observation_wheel")); Catlmk.put(CatLMK.LMK_TORL, new S57enum(25, "toril"));
    229  }
    230  public enum CatLAM { LAM_UNKN, LAM_PORT, LAM_STBD, LAM_PCST, LAM_PCPT, LAM_WWLT, LAM_WWRT, LAM_CHLT, LAM_CHRT, LAM_WWSN, LAM_CHSN, LAM_CHRB, LAM_CHLB, LAM_CRRT, LAM_CRLT,
    231   LAM_DRLT, LAM_DRRT, LAM_TOLT, LAM_TPRT, LAM_JBRT, LAM_JNLT, LAM_HBRT, LAM_HBLT, LAM_BRGP }
    232  private static final EnumMap<CatLAM, S57enum> Catlam = new EnumMap<>(CatLAM.class); static { Catlam.put(CatLAM.LAM_UNKN, new S57enum(0, ""));
    233   Catlam.put(CatLAM.LAM_PORT, new S57enum(1, "port")); Catlam.put(CatLAM.LAM_STBD, new S57enum(2, "starboard")); Catlam.put(CatLAM.LAM_PCST, new S57enum(3, "preferred_channel_starboard"));
    234   Catlam.put(CatLAM.LAM_PCPT, new S57enum(4, "preferred_channel_port")); Catlam.put(CatLAM.LAM_WWRT, new S57enum(5, "waterway_right")); Catlam.put(CatLAM.LAM_WWLT, new S57enum(6, "waterway_left"));
    235   Catlam.put(CatLAM.LAM_CHRT, new S57enum(7, "channel_right")); Catlam.put(CatLAM.LAM_CHLT, new S57enum(8, "channel_left")); Catlam.put(CatLAM.LAM_WWSN, new S57enum(9, "waterway_separation"));
    236   Catlam.put(CatLAM.LAM_CHSN, new S57enum(10, "channel_separation")); Catlam.put(CatLAM.LAM_CHRB, new S57enum(11, "channel_right_bank")); Catlam.put(CatLAM.LAM_CHLB, new S57enum(12, "channel_left_bank"));
    237   Catlam.put(CatLAM.LAM_CRRT, new S57enum(13, "crossover_right")); Catlam.put(CatLAM.LAM_CRLT, new S57enum(14, "crossover_left")); Catlam.put(CatLAM.LAM_DRLT, new S57enum(15, "danger_right"));
    238   Catlam.put(CatLAM.LAM_DRRT, new S57enum(16, "danger_left")); Catlam.put(CatLAM.LAM_TOLT, new S57enum(17, "turnoff_right")); Catlam.put(CatLAM.LAM_TPRT, new S57enum(18, "turnoff_left"));
    239   Catlam.put(CatLAM.LAM_JBRT, new S57enum(19, "junction_right")); Catlam.put(CatLAM.LAM_JNLT, new S57enum(20, "junction_left")); Catlam.put(CatLAM.LAM_HBRT, new S57enum(21, "harbour_right"));
    240   Catlam.put(CatLAM.LAM_HBLT, new S57enum(22, "harbour_left")); Catlam.put(CatLAM.LAM_BRGP, new S57enum(23, "bridge_pier"));
    241  }
    242  public enum CatLIT { LIT_UNKN, LIT_DIR, LIT_LEAD, LIT_AERO, LIT_AIR, LIT_FOG, LIT_FLDL, LIT_STRP, LIT_SUBS, LIT_SPOT, LIT_FRNT, LIT_REAR, LIT_LOWR, LIT_UPPR, LIT_MOIR, LIT_EMRG, LIT_BRNG, LIT_HORI, LIT_VERT }
    243  private static final EnumMap<CatLIT, S57enum> Catlit = new EnumMap<>(CatLIT.class); static { Catlit.put(CatLIT.LIT_UNKN, new S57enum(0, ""));
    244   Catlit.put(CatLIT.LIT_DIR, new S57enum(1, "directional")); Catlit.put(CatLIT.LIT_LEAD, new S57enum(4, "leading")); Catlit.put(CatLIT.LIT_AERO, new S57enum(5, "aero"));
    245   Catlit.put(CatLIT.LIT_AIR, new S57enum(6, "air_obstruction")); Catlit.put(CatLIT.LIT_FOG, new S57enum(7, "fog_detector")); Catlit.put(CatLIT.LIT_FLDL, new S57enum(8, "floodlight"));
    246   Catlit.put(CatLIT.LIT_STRP, new S57enum(9, "strip_light")); Catlit.put(CatLIT.LIT_SUBS, new S57enum(10, "subsidiary")); Catlit.put(CatLIT.LIT_SPOT, new S57enum(11, "spotlight"));
    247   Catlit.put(CatLIT.LIT_FRNT, new S57enum(12, "front")); Catlit.put(CatLIT.LIT_REAR, new S57enum(13, "rear")); Catlit.put(CatLIT.LIT_LOWR, new S57enum(14, "lower"));
    248   Catlit.put(CatLIT.LIT_UPPR, new S57enum(15, "upper")); Catlit.put(CatLIT.LIT_MOIR, new S57enum(16, "moire")); Catlit.put(CatLIT.LIT_EMRG, new S57enum(17, "emergency"));
    249   Catlit.put(CatLIT.LIT_BRNG, new S57enum(18, "bearing")); Catlit.put(CatLIT.LIT_HORI, new S57enum(19, "horizontal")); Catlit.put(CatLIT.LIT_VERT, new S57enum(20, "vertical"));
    250  }
    251  public enum CatMFA { MFA_UNKN, MFA_CRST, MFA_OYMS, MFA_FISH, MFA_SEAW, MFA_PRLC }
    252  private static final EnumMap<CatMFA, S57enum> Catmfa = new EnumMap<>(CatMFA.class); static { Catmfa.put(CatMFA.MFA_UNKN, new S57enum(0, ""));
    253   Catmfa.put(CatMFA.MFA_CRST, new S57enum(1, "crustaceans")); Catmfa.put(CatMFA.MFA_OYMS, new S57enum(2, "oysters_mussels")); Catmfa.put(CatMFA.MFA_FISH, new S57enum(3, "fish"));
    254   Catmfa.put(CatMFA.MFA_SEAW, new S57enum(4, "seaweed")); Catmfa.put(CatMFA.MFA_PRLC, new S57enum(5, "pearl_culture"));
    255  }
    256  public enum CatMPA { MPA_UNKN, MPA_PRCT, MPA_TRPD, MPA_SUBM, MPA_FIRG, MPA_MINL, MPA_SMLA }
    257  private static final EnumMap<CatMPA, S57enum> Catmpa = new EnumMap<>(CatMPA.class); static { Catmpa.put(CatMPA.MPA_UNKN, new S57enum(0, ""));
    258   Catmpa.put(CatMPA.MPA_PRCT, new S57enum(1, "practice")); Catmpa.put(CatMPA.MPA_TRPD, new S57enum(2, "torpedo")); Catmpa.put(CatMPA.MPA_SUBM, new S57enum(3, "submarine"));
    259   Catmpa.put(CatMPA.MPA_FIRG, new S57enum(4, "firing")); Catmpa.put(CatMPA.MPA_MINL, new S57enum(5, "mine-laying")); Catmpa.put(CatMPA.MPA_SMLA, new S57enum(6, "small_arms"));
    260  }
    261  public enum CatMOR { MOR_UNKN, MOR_DLPN, MOR_DDPN, MOR_BLRD, MOR_WALL, MOR_PILE, MOR_CHAN, MOR_BUOY, MOR_SHRP, MOR_AUTO, MOR_POST, MOR_WIRE, MOR_CABL }
    262  private static final EnumMap<CatMOR, S57enum> Catmor = new EnumMap<>(CatMOR.class); static { Catmor.put(CatMOR.MOR_UNKN, new S57enum(0, ""));
    263   Catmor.put(CatMOR.MOR_DLPN, new S57enum(1, "dolphin")); Catmor.put(CatMOR.MOR_DDPN, new S57enum(2, "deviation_dolphin")); Catmor.put(CatMOR.MOR_BLRD, new S57enum(3, "bollard"));
    264   Catmor.put(CatMOR.MOR_WALL, new S57enum(4, "wall")); Catmor.put(CatMOR.MOR_PILE, new S57enum(5, "pile")); Catmor.put(CatMOR.MOR_CHAN, new S57enum(6, "chain"));
    265   Catmor.put(CatMOR.MOR_BUOY, new S57enum(7, "buoy")); Catmor.put(CatMOR.MOR_SHRP, new S57enum(8, "shore_ropes")); Catmor.put(CatMOR.MOR_AUTO, new S57enum(9, "automatic"));
    266   Catmor.put(CatMOR.MOR_POST, new S57enum(10, "post")); Catmor.put(CatMOR.MOR_WIRE, new S57enum(11, "wire")); Catmor.put(CatMOR.MOR_CABL, new S57enum(12, "cable"));
    267  }
    268  public enum CatNAV { NAV_UNKN, NAV_CLRG, NAV_TRST, NAV_LDNG }
    269  private static final EnumMap<CatNAV, S57enum> Catnav = new EnumMap<>(CatNAV.class); static { Catnav.put(CatNAV.NAV_UNKN, new S57enum(0, ""));
    270   Catnav.put(CatNAV.NAV_CLRG, new S57enum(1, "clearing")); Catnav.put(CatNAV.NAV_TRST, new S57enum(2, "transit")); Catnav.put(CatNAV.NAV_LDNG, new S57enum(3, "leading"));
    271  }
    272  public enum CatOBS { OBS_UNKN, OBS_STMP, OBS_WELH, OBS_DIFF, OBS_CRIB, OBS_FHVN, OBS_FLAR, OBS_FLGD, OBS_ICEB, OBS_GTKL, OBS_BOOM, OBS_UWTB, OBS_TPLT, OBS_WEND, OBS_UWAS,
    273          OBS_REEF, OBS_MNFD, OBS_PNGO, OBS_RPLT, OBS_SCII }
    274  private static final EnumMap<CatOBS, S57enum> Catobs = new EnumMap<>(CatOBS.class); static { Catobs.put(CatOBS.OBS_UNKN, new S57enum(0, ""));
    275   Catobs.put(CatOBS.OBS_STMP, new S57enum(1, "stump")); Catobs.put(CatOBS.OBS_WELH, new S57enum(2, "wellhead")); Catobs.put(CatOBS.OBS_DIFF, new S57enum(3, "diffuser"));
    276   Catobs.put(CatOBS.OBS_CRIB, new S57enum(4, "crib")); Catobs.put(CatOBS.OBS_FHVN, new S57enum(5, "fish_haven")); Catobs.put(CatOBS.OBS_FLAR, new S57enum(6, "foul_area"));
    277   Catobs.put(CatOBS.OBS_FLGD, new S57enum(7, "foul_ground")); Catobs.put(CatOBS.OBS_ICEB, new S57enum(8, "ice_boom")); Catobs.put(CatOBS.OBS_GTKL, new S57enum(9, "ground_tackle"));
    278   Catobs.put(CatOBS.OBS_BOOM, new S57enum(10, "boom")); Catobs.put(CatOBS.OBS_UWTB, new S57enum(11, "underwater_turbine")); Catobs.put(CatOBS.OBS_TPLT, new S57enum(12, "template"));
    279   Catobs.put(CatOBS.OBS_WEND, new S57enum(13, "wave_energy_device")); Catobs.put(CatOBS.OBS_UWAS, new S57enum(14, "subsurface_data")); Catobs.put(CatOBS.OBS_REEF, new S57enum(15, "artificial_reef"));
    280   Catobs.put(CatOBS.OBS_MNFD, new S57enum(16, "manifold")); Catobs.put(CatOBS.OBS_PNGO, new S57enum(17, "submerged_pingo")); Catobs.put(CatOBS.OBS_RPLT, new S57enum(18, "platform_remains"));
    281   Catobs.put(CatOBS.OBS_SCII, new S57enum(19, "scientific_instrument"));
    282  }
    283 
    284  public enum CatOFP { OFP_UNKN, OFP_OIL, OFP_PROD, OFP_OBS, OFP_ALP, OFP_SALM, OFP_MOOR, OFP_AISL, OFP_FPSO, OFP_ACCN, OFP_NCCB, OFP_FOTK }
    285  private static final EnumMap<CatOFP, S57enum> Catofp = new EnumMap<>(CatOFP.class); static { Catofp.put(CatOFP.OFP_UNKN, new S57enum(0, ""));
    286   Catofp.put(CatOFP.OFP_OIL, new S57enum(1, "oil")); Catofp.put(CatOFP.OFP_PROD, new S57enum(2, "production")); Catofp.put(CatOFP.OFP_OBS, new S57enum(3, "observation"));
    287   Catofp.put(CatOFP.OFP_ALP, new S57enum(4, "alp")); Catofp.put(CatOFP.OFP_SALM, new S57enum(5, "salm")); Catofp.put(CatOFP.OFP_MOOR, new S57enum(6, "mooring"));
    288   Catofp.put(CatOFP.OFP_AISL, new S57enum(7, "artificial_island")); Catofp.put(CatOFP.OFP_FPSO, new S57enum(8, "fpso")); Catofp.put(CatOFP.OFP_ACCN, new S57enum(9, "accommodation"));
    289   Catofp.put(CatOFP.OFP_NCCB, new S57enum(10, "nccb")); Catofp.put(CatOFP.OFP_FOTK, new S57enum(11, "floating_oil_tank"));
    290  }
    291  public enum CatOLB { OLB_UNKN, OLB_RETN, OLB_FLTG }
    292  private static final EnumMap<CatOLB, S57enum> Catolb = new EnumMap<>(CatOLB.class); static { Catolb.put(CatOLB.OLB_UNKN, new S57enum(0, ""));
    293   Catolb.put(CatOLB.OLB_RETN, new S57enum(1, "retention")); Catolb.put(CatOLB.OLB_FLTG, new S57enum(2, "floating"));
    294  }
    295  public enum CatPLE { PLE_UNKN, PLE_STAK, PLE_POST, PLE_TRIP, PLE_PLNG, PLE_PARE, PLE_PIPE }
    296  private static final EnumMap<CatPLE, S57enum> Catple = new EnumMap<>(CatPLE.class); static { Catple.put(CatPLE.PLE_UNKN, new S57enum(0, ""));
    297   Catple.put(CatPLE.PLE_STAK, new S57enum(1, "stake")); Catple.put(CatPLE.PLE_POST, new S57enum(3, "post")); Catple.put(CatPLE.PLE_TRIP, new S57enum(4, "tripodal"));
    298   Catple.put(CatPLE.PLE_PLNG, new S57enum(5, "piling")); Catple.put(CatPLE.PLE_PARE, new S57enum(6, "pile_area")); Catple.put(CatPLE.PLE_PIPE, new S57enum(7, "pipe"));
    299  }
    300 
    301  public enum CatPIL { PIL_UNKN, PIL_CVSL, PIL_HELI, PIL_SHOR }
    302  private static final EnumMap<CatPIL, S57enum> Catpil = new EnumMap<>(CatPIL.class); static { Catpil.put(CatPIL.PIL_UNKN, new S57enum(0, ""));
    303   Catpil.put(CatPIL.PIL_CVSL, new S57enum(1, "cruising_vessel")); Catpil.put(CatPIL.PIL_HELI, new S57enum(2, "helicopter")); Catpil.put(CatPIL.PIL_SHOR, new S57enum(3, "from_shore"));
    304  }
    305  public enum CatPIP { PIP_UNKN, PIP_OFAL, PIP_ITAK, PIP_SEWR, PIP_BBLR, PIP_SPPL }
    306  private static final EnumMap<CatPIP, S57enum> Catpip = new EnumMap<>(CatPIP.class); static { Catpip.put(CatPIP.PIP_UNKN, new S57enum(0, ""));
    307   Catpip.put(CatPIP.PIP_OFAL, new S57enum(2, "outfall")); Catpip.put(CatPIP.PIP_ITAK, new S57enum(3, "intake")); Catpip.put(CatPIP.PIP_SEWR, new S57enum(4, "sewer"));
    308   Catpip.put(CatPIP.PIP_BBLR, new S57enum(5, "bubbler")); Catpip.put(CatPIP.PIP_SPPL, new S57enum(6, "supply"));
    309  }
    310  public enum CatPRA { PRA_UNKN, PRA_QRRY, PRA_MINE, PRA_STPL, PRA_PSTN, PRA_RFNY, PRA_TYRD, PRA_FACT, PRA_TFRM, PRA_WFRM, PRA_SLAG, PRA_CURF, PRA_OILF, PRA_GASF, PRA_WAVE }
    311  private static final EnumMap<CatPRA, S57enum> Catpra = new EnumMap<>(CatPRA.class); static { Catpra.put(CatPRA.PRA_UNKN, new S57enum(0, ""));
    312   Catpra.put(CatPRA.PRA_QRRY, new S57enum(1, "quarry")); Catpra.put(CatPRA.PRA_MINE, new S57enum(2, "mine")); Catpra.put(CatPRA.PRA_STPL, new S57enum(3, "stockpile"));
    313   Catpra.put(CatPRA.PRA_PSTN, new S57enum(4, "power_station")); Catpra.put(CatPRA.PRA_RFNY, new S57enum(5, "refinery")); Catpra.put(CatPRA.PRA_TYRD, new S57enum(6, "timber_yard"));
    314   Catpra.put(CatPRA.PRA_FACT, new S57enum(7, "factory")); Catpra.put(CatPRA.PRA_TFRM, new S57enum(8, "tank_farm")); Catpra.put(CatPRA.PRA_WFRM, new S57enum(9, "wind_farm"));
    315   Catpra.put(CatPRA.PRA_SLAG, new S57enum(10, "slag_heap")); Catpra.put(CatPRA.PRA_CURF, new S57enum(11, "current_farm")); Catpra.put(CatPRA.PRA_OILF, new S57enum(12, "oil"));
    316   Catpra.put(CatPRA.PRA_GASF, new S57enum(13, "gas")); Catpra.put(CatPRA.PRA_WAVE, new S57enum(14, "wave_energy"));
    317  }
    318  public enum CatPYL { PYL_UNKN, PYL_POWR, PYL_TELE, PYL_AERL, PYL_BRDG, PYL_PIER }
    319  private static final EnumMap<CatPYL, S57enum> Catpyl = new EnumMap<>(CatPYL.class); static { Catpyl.put(CatPYL.PYL_UNKN, new S57enum(0, ""));
    320   Catpyl.put(CatPYL.PYL_POWR, new S57enum(1, "power")); Catpyl.put(CatPYL.PYL_TELE, new S57enum(2, "telecom")); Catpyl.put(CatPYL.PYL_AERL, new S57enum(3, "aerial"));
    321   Catpyl.put(CatPYL.PYL_BRDG, new S57enum(4, "bridge")); Catpyl.put(CatPYL.PYL_PIER, new S57enum(5, "bridge_pier"));
    322  }
    323  public enum CatRAS { RAS_UNKN, RAS_SURV, RAS_COST }
    324  private static final EnumMap<CatRAS, S57enum> Catras = new EnumMap<>(CatRAS.class); static { Catras.put(CatRAS.RAS_UNKN, new S57enum(0, ""));
    325   Catras.put(CatRAS.RAS_SURV, new S57enum(1, "surveillance")); Catras.put(CatRAS.RAS_COST, new S57enum(2, "coast"));
    326  }
    327  public enum CatRTB { RTB_UNKN, RTB_RAMK, RTB_RACN, RTB_LDG }
    328  private static final EnumMap<CatRTB, S57enum> Catrtb = new EnumMap<>(CatRTB.class); static {Catrtb.put(CatRTB.RTB_UNKN, new S57enum(0, ""));
    329   Catrtb.put(CatRTB.RTB_RAMK, new S57enum(1, "ramark")); Catrtb.put(CatRTB.RTB_RACN, new S57enum(2, "racon")); Catrtb.put(CatRTB.RTB_LDG, new S57enum(3, "leading"));
    330  }
    331  public enum CatROS { ROS_UNKN, ROS_OMNI, ROS_DIRL, ROS_ROTP, ROS_CNSL, ROS_RDF, ROS_QTA, ROS_AERO, ROS_DECA, ROS_LORN, ROS_DGPS, ROS_TORN, ROS_OMGA, ROS_SYLD, ROS_CHKA,
    332   ROS_PCOM, ROS_COMB, ROS_FACS, ROS_TIME, ROS_PAIS, ROS_SAIS, ROS_VAIS, ROS_VANC, ROS_VASC, ROS_VAEC, ROS_VAWC, ROS_VAPL, ROS_VASL, ROS_VAID, ROS_VASW, ROS_VASP, ROS_VAWK }
    333  private static final EnumMap<CatROS, S57enum> Catros = new EnumMap<>(CatROS.class); static { Catros.put(CatROS.ROS_UNKN, new S57enum(0, ""));
    334   Catros.put(CatROS.ROS_OMNI, new S57enum(1, "omnidirectional")); Catros.put(CatROS.ROS_DIRL, new S57enum(2, "directional")); Catros.put(CatROS.ROS_ROTP, new S57enum(3, "rotating_pattern"));
    335   Catros.put(CatROS.ROS_CNSL, new S57enum(4, "consol")); Catros.put(CatROS.ROS_RDF, new S57enum(5, "rdf")); Catros.put(CatROS.ROS_QTA, new S57enum(6, "qtg"));
    336   Catros.put(CatROS.ROS_AERO, new S57enum(7, "aeronautical")); Catros.put(CatROS.ROS_DECA, new S57enum(8, "decca")); Catros.put(CatROS.ROS_LORN, new S57enum(9, "loran"));
    337   Catros.put(CatROS.ROS_DGPS, new S57enum(10, "dgps")); Catros.put(CatROS.ROS_TORN, new S57enum(11, "toran")); Catros.put(CatROS.ROS_OMGA, new S57enum(12, "omega"));
    338   Catros.put(CatROS.ROS_SYLD, new S57enum(13, "syledis")); Catros.put(CatROS.ROS_CHKA, new S57enum(14, "chiaka")); Catros.put(CatROS.ROS_PCOM, new S57enum(15, "public_communication"));
    339   Catros.put(CatROS.ROS_COMB, new S57enum(16, "commercial_broadcast")); Catros.put(CatROS.ROS_FACS, new S57enum(17, "facsimile")); Catros.put(CatROS.ROS_TIME, new S57enum(18, "time_signal"));
    340   Catros.put(CatROS.ROS_PAIS, new S57enum(19, "ais")); Catros.put(CatROS.ROS_SAIS, new S57enum(20, "s-ais")); Catros.put(CatROS.ROS_VAIS, new S57enum(21, "v-ais"));
    341   Catros.put(CatROS.ROS_VANC, new S57enum(22, "v-ais_north_cardinal")); Catros.put(CatROS.ROS_VASC, new S57enum(23, "v-ais_south_cardinal"));
    342   Catros.put(CatROS.ROS_VAEC, new S57enum(24, "v-ais_east_cardinal")); Catros.put(CatROS.ROS_VAWC, new S57enum(25, "v-ais_west_cardinal"));
    343   Catros.put(CatROS.ROS_VAPL, new S57enum(26, "v-ais_port_lateral")); Catros.put(CatROS.ROS_VASL, new S57enum(27, "v-ais_starboard_lateral"));
    344   Catros.put(CatROS.ROS_VAID, new S57enum(28, "v-ais_isolated_danger")); Catros.put(CatROS.ROS_VASW, new S57enum(29, "v-ais_safe_water"));
    345   Catros.put(CatROS.ROS_VASP, new S57enum(30, "v-ais_special_purpose")); Catros.put(CatROS.ROS_VAWK, new S57enum(31, "v-ais_wreck"));
    346  }
    347  public enum CatRSC { RSC_UNKN, RSC_LIFB, RSC_ROKT, RSC_LBRK, RSC_RFSW, RSC_RFIT, RSC_LBOM, RSC_RDIO, RSC_FSTA, RSC_SPLN, RSC_ACFT, RSC_STUG }
    348  private static final EnumMap<CatRSC, S57enum> Catrsc = new EnumMap<>(CatRSC.class); static { Catrsc.put(CatRSC.RSC_UNKN, new S57enum(0, ""));
    349   Catrsc.put(CatRSC.RSC_LIFB, new S57enum(1, "lifeboat")); Catrsc.put(CatRSC.RSC_ROKT, new S57enum(2, "rocket")); Catrsc.put(CatRSC.RSC_LBRK, new S57enum(3, "lifeboat_rocket"));
    350   Catrsc.put(CatRSC.RSC_RFSW, new S57enum(4, "refuge_shipwrecked")); Catrsc.put(CatRSC.RSC_RFIT, new S57enum(5, "refuge_intertidal")); Catrsc.put(CatRSC.RSC_LBOM, new S57enum(6, "lifeboat_on_mooring"));
    351   Catrsc.put(CatRSC.RSC_RDIO, new S57enum(7, "radio")); Catrsc.put(CatRSC.RSC_FSTA, new S57enum(8, "first_aid")); Catrsc.put(CatRSC.RSC_SPLN, new S57enum(9, "seaplane"));
    352   Catrsc.put(CatRSC.RSC_ACFT, new S57enum(10, "aircraft")); Catrsc.put(CatRSC.RSC_STUG, new S57enum(12, "tug"));
    353  }
    354  public enum CatREA { REA_UNKN, REA_SFTY, REA_NANC, REA_NFSH, REA_NATR, REA_BRDS, REA_GRSV, REA_SEAL, REA_DEGR, REA_MILY, REA_HIST, REA_INST,
    355   REA_NASF, REA_STRD, REA_MINE, REA_NDIV, REA_TBAV, REA_PROH, REA_SWIM, REA_WAIT, REA_RSCH, REA_DREG, REA_FSNC, REA_ERES, REA_NWAK, REA_SWNG,
    356   REA_WSKI, REA_ESSA, REA_PSSA, REA_DISA, REA_PSAR, REA_CRLS }
    357  private static final EnumMap<CatREA, S57enum> Catrea = new EnumMap<>(CatREA.class); static { Catrea.put(CatREA.REA_UNKN, new S57enum(0, ""));
    358   Catrea.put(CatREA.REA_SFTY, new S57enum(1, "safety")); Catrea.put(CatREA.REA_NANC, new S57enum(2, "no_anchoring")); Catrea.put(CatREA.REA_NFSH, new S57enum(3, "no_fishing"));
    359   Catrea.put(CatREA.REA_NATR, new S57enum(4, "nature_reserve")); Catrea.put(CatREA.REA_BRDS, new S57enum(5, "bird_sanctuary")); Catrea.put(CatREA.REA_GRSV, new S57enum(6, "game_reserve"));
    360   Catrea.put(CatREA.REA_SEAL, new S57enum(7, "seal_sanctuary")); Catrea.put(CatREA.REA_DEGR, new S57enum(8, "degaussing_range")); Catrea.put(CatREA.REA_MILY, new S57enum(9, "military"));
    361    Catrea.put(CatREA.REA_HIST, new S57enum(10, "historic_wreck")); Catrea.put(CatREA.REA_INST, new S57enum(11, "inshore_traffic")); Catrea.put(CatREA.REA_NASF, new S57enum(12, "navigational_aid_safety"));
    362    Catrea.put(CatREA.REA_STRD, new S57enum(13, "stranding_danger")); Catrea.put(CatREA.REA_MINE, new S57enum(14, "minefield")); Catrea.put(CatREA.REA_NDIV, new S57enum(15, "no_diving"));
    363    Catrea.put(CatREA.REA_TBAV, new S57enum(16, "to_be_avoided")); Catrea.put(CatREA.REA_PROH, new S57enum(17, "prohibited")); Catrea.put(CatREA.REA_SWIM, new S57enum(18, "swimming"));
    364    Catrea.put(CatREA.REA_WAIT, new S57enum(19, "waiting")); Catrea.put(CatREA.REA_RSCH, new S57enum(20, "research")); Catrea.put(CatREA.REA_DREG, new S57enum(21, "dredging"));
    365    Catrea.put(CatREA.REA_FSNC, new S57enum(22, "fish_sanctuary")); Catrea.put(CatREA.REA_ERES, new S57enum(23, "ecological_reserve")); Catrea.put(CatREA.REA_NWAK, new S57enum(24, "no_wake"));
    366    Catrea.put(CatREA.REA_SWNG, new S57enum(25, "swinging")); Catrea.put(CatREA.REA_WSKI, new S57enum(26, "water_skiing"));
    367    Catrea.put(CatREA.REA_ESSA, new S57enum(27, "environmentally_sensitive")); Catrea.put(CatREA.REA_PSSA, new S57enum(28, "particularly_sensitive"));
    368    Catrea.put(CatREA.REA_DISA, new S57enum(29, "disengagement")); Catrea.put(CatREA.REA_PSAR, new S57enum(30, "port_security")); Catrea.put(CatREA.REA_CRLS, new S57enum(31, "coral_sactuary"));
    369  }
    370  public enum CatROD { ROD_UNKN, ROD_MWAY, ROD_MAJR, ROD_MINR, ROD_TRAK, ROD_MAJS, ROD_MINS, ROD_CRSG, ROD_PATH }
    371  private static final EnumMap<CatROD, S57enum> Catrod = new EnumMap<>(CatROD.class); static { Catrod.put(CatROD.ROD_UNKN, new S57enum(0, ""));
    372   Catrod.put(CatROD.ROD_MWAY, new S57enum(1, "motorway")); Catrod.put(CatROD.ROD_MAJR, new S57enum(2, "major_road")); Catrod.put(CatROD.ROD_MINR, new S57enum(3, "minor_road"));
    373   Catrod.put(CatROD.ROD_TRAK, new S57enum(4, "track")); Catrod.put(CatROD.ROD_MAJS, new S57enum(5, "major_street")); Catrod.put(CatROD.ROD_MINS, new S57enum(6, "minor_street"));
    374   Catrod.put(CatROD.ROD_CRSG, new S57enum(7, "crossing")); Catrod.put(CatROD.ROD_PATH, new S57enum(8, "path"));
    375  }
    376  public enum CatRUN { RUN_UNKN, RUN_AERP, RUN_HELI }
    377  private static final EnumMap<CatRUN, S57enum> Catrun = new EnumMap<>(CatRUN.class); static { Catrun.put(CatRUN.RUN_UNKN, new S57enum(0, ""));
    378   Catrun.put(CatRUN.RUN_AERP, new S57enum(1, "aeroplane")); Catrun.put(CatRUN.RUN_HELI, new S57enum(2, "helicopter"));
    379  }
    380  public enum CatSEA { SEA_UNKN, SEA_GENL, SEA_GAT, SEA_BANK, SEA_DEEP, SEA_BAY, SEA_TRCH, SEA_BASN, SEA_MDFT, SEA_REEF, SEA_LEDG, SEA_CNYN, SEA_NRRW, SEA_SHOL,
    381   SEA_KNOL, SEA_RIDG, SEA_SMNT, SEA_PNCL, SEA_APLN, SEA_PLTU, SEA_SPUR, SEA_SHLF, SEA_TRGH, SEA_SDDL, SEA_AHLL, SEA_APRN, SEA_AAPN, SEA_BLND, SEA_CMGN, SEA_CRIS,
    382   SEA_ESCT, SEA_FAN, SEA_FZON, SEA_GAP, SEA_GUYT, SEA_HILL, SEA_HOLE, SEA_LEVE, SEA_MVLY, SEA_MOAT, SEA_MTNS, SEA_PEAK, SEA_PVNC, SEA_RISE, SEA_SCNL, SEA_SCHN,
    383   SEA_SEDG, SEA_SILL, SEA_SLOP, SEA_TRRC, SEA_VLLY, SEA_CANL, SEA_LAKE, SEA_RIVR, SEA_RECH }
    384  private static final EnumMap<CatSEA, S57enum> Catsea = new EnumMap<>(CatSEA.class); static { Catsea.put(CatSEA.SEA_UNKN, new S57enum(0, ""));
    385   Catsea.put(CatSEA.SEA_GENL, new S57enum(1, "general")); Catsea.put(CatSEA.SEA_GAT, new S57enum(2, "gat")); Catsea.put(CatSEA.SEA_BANK, new S57enum(3, "bank"));
    386   Catsea.put(CatSEA.SEA_DEEP, new S57enum(4, "deep")); Catsea.put(CatSEA.SEA_BAY, new S57enum(5, "bay")); Catsea.put(CatSEA.SEA_TRCH, new S57enum(6, "trench"));
    387   Catsea.put(CatSEA.SEA_BASN, new S57enum(7, "basin")); Catsea.put(CatSEA.SEA_MDFT, new S57enum(8, "flat")); Catsea.put(CatSEA.SEA_REEF, new S57enum(9, "reef"));
    388   Catsea.put(CatSEA.SEA_LEDG, new S57enum(10, "ledge")); Catsea.put(CatSEA.SEA_CNYN, new S57enum(11, "canyon")); Catsea.put(CatSEA.SEA_NRRW, new S57enum(12, "narrows"));
    389   Catsea.put(CatSEA.SEA_SHOL, new S57enum(13, "shoal")); Catsea.put(CatSEA.SEA_KNOL, new S57enum(14, "knoll")); Catsea.put(CatSEA.SEA_RIDG, new S57enum(15, "ridge"));
    390   Catsea.put(CatSEA.SEA_SMNT, new S57enum(16, "seamount")); Catsea.put(CatSEA.SEA_PNCL, new S57enum(17, "pinnacle")); Catsea.put(CatSEA.SEA_APLN, new S57enum(18, "abyssal_plain"));
    391   Catsea.put(CatSEA.SEA_PLTU, new S57enum(19, "plateau")); Catsea.put(CatSEA.SEA_SPUR, new S57enum(20, "spur")); Catsea.put(CatSEA.SEA_SHLF, new S57enum(21, "shelf"));
    392   Catsea.put(CatSEA.SEA_TRGH, new S57enum(22, "trough")); Catsea.put(CatSEA.SEA_SDDL, new S57enum(23, "saddle")); Catsea.put(CatSEA.SEA_AHLL, new S57enum(24, "abyssal_hills"));
    393   Catsea.put(CatSEA.SEA_APRN, new S57enum(25, "apron")); Catsea.put(CatSEA.SEA_AAPN, new S57enum(26, "archipelagic_apron")); Catsea.put(CatSEA.SEA_BLND, new S57enum(27, "borderland"));
    394   Catsea.put(CatSEA.SEA_CMGN, new S57enum(28, "continental_margin")); Catsea.put(CatSEA.SEA_CRIS, new S57enum(29, "continental_rise")); Catsea.put(CatSEA.SEA_ESCT, new S57enum(30, "escarpment"));
    395   Catsea.put(CatSEA.SEA_FAN, new S57enum(31, "fan")); Catsea.put(CatSEA.SEA_FZON, new S57enum(32, "fracture_zone")); Catsea.put(CatSEA.SEA_GAP, new S57enum(33, "gap"));
    396   Catsea.put(CatSEA.SEA_GUYT, new S57enum(34, "guyot")); Catsea.put(CatSEA.SEA_HILL, new S57enum(35, "hill")); Catsea.put(CatSEA.SEA_HOLE, new S57enum(36, "hole"));
    397   Catsea.put(CatSEA.SEA_LEVE, new S57enum(37, "levee")); Catsea.put(CatSEA.SEA_MVLY, new S57enum(38, "median_valley")); Catsea.put(CatSEA.SEA_MOAT, new S57enum(39, "moat"));
    398   Catsea.put(CatSEA.SEA_MTNS, new S57enum(40, "mountains")); Catsea.put(CatSEA.SEA_PEAK, new S57enum(41, "peak")); Catsea.put(CatSEA.SEA_PVNC, new S57enum(42, "province"));
    399   Catsea.put(CatSEA.SEA_RISE, new S57enum(43, "rise")); Catsea.put(CatSEA.SEA_SCNL, new S57enum(44, "sea_channel")); Catsea.put(CatSEA.SEA_SCHN, new S57enum(45, "seamount_chain"));
    400   Catsea.put(CatSEA.SEA_SEDG, new S57enum(46, "shelf-edge")); Catsea.put(CatSEA.SEA_SILL, new S57enum(47, "sill")); Catsea.put(CatSEA.SEA_SLOP, new S57enum(48, "slope"));
    401   Catsea.put(CatSEA.SEA_TRRC, new S57enum(49, "terrace")); Catsea.put(CatSEA.SEA_VLLY, new S57enum(50, "valley")); Catsea.put(CatSEA.SEA_CANL, new S57enum(51, "canal"));
    402   Catsea.put(CatSEA.SEA_LAKE, new S57enum(52, "lake")); Catsea.put(CatSEA.SEA_RIVR, new S57enum(53, "river")); Catsea.put(CatSEA.SEA_RECH, new S57enum(54, "reach"));
    403  }
    404  public enum CatSLC { SLC_UNKN, SLC_BWTR, SLC_GRYN, SLC_MOLE, SLC_PIER, SLC_PPER, SLC_WHRF, SLC_TWAL, SLC_RPRP, SLC_RVMT, SLC_SWAL, SLC_LSTP,
    405   SLC_RAMP, SLC_SWAY, SLC_FNDR, SLC_SFWF,  SLC_OFWF,  SLC_LRMP,  SLC_LWAL, SLC_ICEB }
    406  private static final EnumMap<CatSLC, S57enum> Catslc = new EnumMap<>(CatSLC.class); static { Catslc.put(CatSLC.SLC_UNKN, new S57enum(0, ""));
    407   Catslc.put(CatSLC.SLC_BWTR, new S57enum(1, "breakwater")); Catslc.put(CatSLC.SLC_GRYN, new S57enum(2, "groyne")); Catslc.put(CatSLC.SLC_MOLE, new S57enum(3, "mole"));
    408   Catslc.put(CatSLC.SLC_PIER, new S57enum(4, "pier")); Catslc.put(CatSLC.SLC_PPER, new S57enum(5, "promenade_pier")); Catslc.put(CatSLC.SLC_WHRF, new S57enum(6, "wharf"));
    409   Catslc.put(CatSLC.SLC_TWAL, new S57enum(7, "training_wall")); Catslc.put(CatSLC.SLC_RPRP, new S57enum(8, "rip_rap")); Catslc.put(CatSLC.SLC_RVMT, new S57enum(9, "revetment"));
    410   Catslc.put(CatSLC.SLC_SWAL, new S57enum(10, "sea_wall")); Catslc.put(CatSLC.SLC_LSTP, new S57enum(11, "landing_steps")); Catslc.put(CatSLC.SLC_RAMP, new S57enum(12, "ramp"));
    411   Catslc.put(CatSLC.SLC_SWAY, new S57enum(13, "slipway")); Catslc.put(CatSLC.SLC_FNDR, new S57enum(14, "fender")); Catslc.put(CatSLC.SLC_SFWF, new S57enum(15, "solid_face_wharf"));
    412   Catslc.put(CatSLC.SLC_OFWF, new S57enum(16, "open_face_wharf")); Catslc.put(CatSLC.SLC_LRMP, new S57enum(17, "log_ramp")); Catslc.put(CatSLC.SLC_LWAL, new S57enum(18, "lock_wall"));
    413   Catslc.put(CatSLC.SLC_ICEB, new S57enum(18, "ice_breaker"));
    414  }
    415  public enum CatSIT { SIT_UNKN, SIT_PRTC, SIT_PRTE, SIT_IPT, SIT_BRTH, SIT_DOCK, SIT_LOCK, SIT_FLDB, SIT_BRDG, SIT_DRDG, SIT_TCLT, SIT_SPCL, SIT_PLTG, SIT_ONCT }
    416  private static final EnumMap<CatSIT, S57enum>  Catsit = new EnumMap<>(CatSIT.class); static {Catsit.put(CatSIT.SIT_UNKN, new S57enum(0, ""));
    417   Catsit.put(CatSIT.SIT_PRTC, new S57enum(1, "port_control")); Catsit.put(CatSIT.SIT_PRTE, new S57enum(2, "port_entry_departure")); Catsit.put(CatSIT.SIT_IPT, new S57enum(3, "ipt"));
    418   Catsit.put(CatSIT.SIT_BRTH, new S57enum(4, "berthing")); Catsit.put(CatSIT.SIT_DOCK, new S57enum(5, "dock")); Catsit.put(CatSIT.SIT_LOCK, new S57enum(6, "lock"));
    419   Catsit.put(CatSIT.SIT_FLDB, new S57enum(7, "flood_barrage")); Catsit.put(CatSIT.SIT_BRDG, new S57enum(8, "bridge_passage")); Catsit.put(CatSIT.SIT_DRDG, new S57enum(9, "dredging"));
    420   Catsit.put(CatSIT.SIT_TCLT, new S57enum(10, "traffic_control")); Catsit.put(CatSIT.SIT_PLTG, new S57enum(11, "pilotage")); Catsit.put(CatSIT.SIT_SPCL, new S57enum(12, "special"));
    421   Catsit.put(CatSIT.SIT_ONCT, new S57enum(13, "oncoming_traffic"));
    422  }
    423  public enum CatSIW { SIW_UNKN, SIW_DNGR, SIW_OBST, SIW_CABL, SIW_MILY, SIW_DSTR, SIW_WTHR, SIW_STRM, SIW_ICE, SIW_TIME, SIW_TIDE, SIW_TSTR,
    424    SIW_TIDG, SIW_TIDS, SIW_DIVE, SIW_WTLG, SIW_VRCL, SIW_HIWM, SIW_DPTH, SIW_CURR }
    425  private static final EnumMap<CatSIW, S57enum>  Catsiw = new EnumMap<>(CatSIW.class); static {Catsiw.put(CatSIW.SIW_UNKN, new S57enum(0, ""));
    426   Catsiw.put(CatSIW.SIW_DNGR, new S57enum(1, "danger")); Catsiw.put(CatSIW.SIW_OBST, new S57enum(2, "maritime_obstruction")); Catsiw.put(CatSIW.SIW_CABL, new S57enum(3, "cable"));
    427   Catsiw.put(CatSIW.SIW_MILY, new S57enum(4, "military")); Catsiw.put(CatSIW.SIW_DSTR, new S57enum(5, "distress")); Catsiw.put(CatSIW.SIW_WTHR, new S57enum(6, "weather"));
    428   Catsiw.put(CatSIW.SIW_STRM, new S57enum(7, "storm")); Catsiw.put(CatSIW.SIW_ICE, new S57enum(8, "ice")); Catsiw.put(CatSIW.SIW_TIME, new S57enum(9, "time"));
    429   Catsiw.put(CatSIW.SIW_TIDE, new S57enum(10, "tide")); Catsiw.put(CatSIW.SIW_TSTR, new S57enum(11, "tidal_stream")); Catsiw.put(CatSIW.SIW_TIDG, new S57enum(12, "tide_gauge"));
    430    Catsiw.put(CatSIW.SIW_TIDS, new S57enum(13, "tide_scale")); Catsiw.put(CatSIW.SIW_DIVE, new S57enum(14, "diving")); Catsiw.put(CatSIW.SIW_WTLG, new S57enum(15, "water_level_gauge"));
    431    Catsiw.put(CatSIW.SIW_VRCL, new S57enum(16, "vertical_clearance")); Catsiw.put(CatSIW.SIW_HIWM, new S57enum(17, "high_water")); Catsiw.put(CatSIW.SIW_DPTH, new S57enum(18, "depth"));
    432    Catsiw.put(CatSIW.SIW_CURR, new S57enum(19, "current"));
    433  }
    434  public enum CatSIL { SIL_UNKN, SIL_SILO, SIL_TANK, SIL_GRNE, SIL_WTRT }
    435  private static final EnumMap<CatSIL, S57enum> Catsil = new EnumMap<>(CatSIL.class); static { Catsil.put(CatSIL.SIL_UNKN, new S57enum(0, ""));
    436   Catsil.put(CatSIL.SIL_SILO, new S57enum(1, "silo")); Catsil.put(CatSIL.SIL_TANK, new S57enum(2, "tank")); Catsil.put(CatSIL.SIL_GRNE, new S57enum(3, "grain_elevator"));
    437   Catsil.put(CatSIL.SIL_WTRT, new S57enum(4, "water_tower"));
    438  }
    439  public enum CatSLO { SLO_UNKN, SLO_CUTG, SLO_EMBK, SLO_DUNE, SLO_HILL, SLO_PINO, SLO_CLIF, SLO_SCRE }
    440  private static final EnumMap<CatSLO, S57enum> Catslo = new EnumMap<>(CatSLO.class); static { Catslo.put(CatSLO.SLO_UNKN, new S57enum(0, ""));
    441   Catslo.put(CatSLO.SLO_CUTG, new S57enum(1, "cutting")); Catslo.put(CatSLO.SLO_EMBK, new S57enum(2, "embankment")); Catslo.put(CatSLO.SLO_DUNE, new S57enum(3, "dune"));
    442   Catslo.put(CatSLO.SLO_HILL, new S57enum(4, "hill")); Catslo.put(CatSLO.SLO_PINO, new S57enum(5, "pingo")); Catslo.put(CatSLO.SLO_CLIF, new S57enum(6, "cliff")); Catslo.put(CatSLO.SLO_SCRE, new S57enum(7, "scree"));
    443  }
    444  public enum CatSCF { SCF_UNKN, SCF_VBTH, SCF_CLUB, SCF_BHST, SCF_SMKR, SCF_BTYD, SCF_INN, SCF_RSRT, SCF_CHDR, SCF_PROV, SCF_DCTR, SCF_PHRM,
    445   SCF_WTRT, SCF_FUEL, SCF_ELEC, SCF_BGAS, SCF_SHWR, SCF_LAUN, SCF_WC, SCF_POST, SCF_TELE, SCF_REFB, SCF_CARP, SCF_BTPK, SCF_CRVN, SCF_CAMP,
    446   SCF_PMPO, SCF_EMRT, SCF_SLPW, SCF_VMOR, SCF_SCRB, SCF_PCNC, SCF_MECH, SCF_SECS }
    447  private static final EnumMap<CatSCF, S57enum> Catscf = new EnumMap<>(CatSCF.class); static { Catscf.put(CatSCF.SCF_UNKN, new S57enum(0, ""));
    448   Catscf.put(CatSCF.SCF_VBTH, new S57enum(1, "visitor_berth")); Catscf.put(CatSCF.SCF_CLUB, new S57enum(2, "nautical_club")); Catscf.put(CatSCF.SCF_BHST, new S57enum(3, "boat_hoist"));
    449   Catscf.put(CatSCF.SCF_SMKR, new S57enum(4, "sailmaker")); Catscf.put(CatSCF.SCF_BTYD, new S57enum(5, "boatyard")); Catscf.put(CatSCF.SCF_INN, new S57enum(6, "public_inn"));
    450   Catscf.put(CatSCF.SCF_RSRT, new S57enum(7, "restaurant")); Catscf.put(CatSCF.SCF_CHDR, new S57enum(8, "chandler")); Catscf.put(CatSCF.SCF_PROV, new S57enum(9, "provisions"));
    451   Catscf.put(CatSCF.SCF_DCTR, new S57enum(10, "doctor")); Catscf.put(CatSCF.SCF_PHRM, new S57enum(11, "pharmacy")); Catscf.put(CatSCF.SCF_WTRT, new S57enum(12, "water_tap"));
    452    Catscf.put(CatSCF.SCF_FUEL, new S57enum(13, "fuel_station")); Catscf.put(CatSCF.SCF_ELEC, new S57enum(14, "electricity")); Catscf.put(CatSCF.SCF_BGAS, new S57enum(15, "bottle_gas"));
    453    Catscf.put(CatSCF.SCF_SHWR, new S57enum(16, "showers")); Catscf.put(CatSCF.SCF_LAUN, new S57enum(17, "laundrette")); Catscf.put(CatSCF.SCF_WC, new S57enum(18, "toilets"));
    454    Catscf.put(CatSCF.SCF_POST, new S57enum(19, "post_box")); Catscf.put(CatSCF.SCF_TELE, new S57enum(20, "telephone")); Catscf.put(CatSCF.SCF_REFB, new S57enum(21, "refuse_bin"));
    455    Catscf.put(CatSCF.SCF_CARP, new S57enum(22, "car_park")); Catscf.put(CatSCF.SCF_BTPK, new S57enum(23, "boat_trailers_park")); Catscf.put(CatSCF.SCF_CRVN, new S57enum(24, "caravan_site"));
    456    Catscf.put(CatSCF.SCF_CAMP, new S57enum(25, "camping_site"));  Catscf.put(CatSCF.SCF_PMPO, new S57enum(26, "pump-out")); Catscf.put(CatSCF.SCF_EMRT, new S57enum(27, "emergency_telephone"));
    457    Catscf.put(CatSCF.SCF_SLPW, new S57enum(28, "slipway")); Catscf.put(CatSCF.SCF_VMOR, new S57enum(29, "visitors_mooring")); Catscf.put(CatSCF.SCF_SCRB, new S57enum(30, "scrubbing_berth"));
    458    Catscf.put(CatSCF.SCF_PCNC, new S57enum(31, "picnic_area")); Catscf.put(CatSCF.SCF_MECH, new S57enum(32, "mechanics_workshop")); Catscf.put(CatSCF.SCF_SECS, new S57enum(33, "security_service"));
    459  }
    460  public enum CatSPM { SPM_UNKN, SPM_FDGA, SPM_TRGT, SPM_MSHP, SPM_DGRG, SPM_BARG, SPM_CABL, SPM_SPLG, SPM_OFAL, SPM_ODAS, SPM_RCDG, SPM_SPLA, SPM_RCZN, SPM_PRVT, SPM_MOOR, SPM_LNBY, SPM_LDNG, SPM_MDST,
    461   SPM_NOTC, SPM_TSS, SPM_NANC, SPM_NBRT, SPM_NOTK, SPM_NTWT, SPM_RWAK, SPM_SPDL, SPM_STOP, SPM_WRNG, SPM_SSSN, SPM_RVCL, SPM_MVDT, SPM_RHCL, SPM_SCNT, SPM_BRTH, SPM_OHPC, SPM_CHEG, SPM_TELE, SPM_FCRS,
    462   SPM_MTRL, SPM_PLIN, SPM_ANCH, SPM_CLRG, SPM_CTRL, SPM_DIVG, SPM_RBCN, SPM_FGND, SPM_YCHT, SPM_HPRT, SPM_GPS, SPM_SLDG, SPM_NENT, SPM_WRKP, SPM_UKPP, SPM_WELH, SPM_CHSP, SPM_MFRM, SPM_AREF }
    463  private static final EnumMap<CatSPM, S57enum> Catspm = new EnumMap<>(CatSPM.class); static { Catspm.put(CatSPM.SPM_UNKN, new S57enum(0, ""));
    464   Catspm.put(CatSPM.SPM_FDGA, new S57enum(1, "firing_danger_area")); Catspm.put(CatSPM.SPM_TRGT, new S57enum(2, "target")); Catspm.put(CatSPM.SPM_MSHP, new S57enum(3, "marker_ship"));
    465   Catspm.put(CatSPM.SPM_DGRG, new S57enum(4, "degaussing_range")); Catspm.put(CatSPM.SPM_BARG, new S57enum(5, "barge")); Catspm.put(CatSPM.SPM_CABL, new S57enum(6, "cable"));
    466   Catspm.put(CatSPM.SPM_SPLG, new S57enum(7, "spoil_ground")); Catspm.put(CatSPM.SPM_OFAL, new S57enum(8, "outfall")); Catspm.put(CatSPM.SPM_ODAS, new S57enum(9, "odas"));
    467   Catspm.put(CatSPM.SPM_RCDG, new S57enum(10, "recording")); Catspm.put(CatSPM.SPM_SPLA, new S57enum(11, "seaplane_anchorage")); Catspm.put(CatSPM.SPM_RCZN, new S57enum(12, "recreation_zone"));
    468   Catspm.put(CatSPM.SPM_PRVT, new S57enum(13, "private")); Catspm.put(CatSPM.SPM_MOOR, new S57enum(14, "mooring")); Catspm.put(CatSPM.SPM_LNBY, new S57enum(15, "lanby"));
    469   Catspm.put(CatSPM.SPM_LDNG, new S57enum(16, "leading")); Catspm.put(CatSPM.SPM_MDST, new S57enum(17, "measured_distance")); Catspm.put(CatSPM.SPM_NOTC, new S57enum(18, "notice"));
    470   Catspm.put(CatSPM.SPM_TSS, new S57enum(19, "tss")); Catspm.put(CatSPM.SPM_NANC, new S57enum(20, "no_anchoring")); Catspm.put(CatSPM.SPM_NBRT, new S57enum(21, "no_berthing"));
    471   Catspm.put(CatSPM.SPM_NOTK, new S57enum(22, "no_overtaking")); Catspm.put(CatSPM.SPM_NTWT, new S57enum(23, "no_two-way_traffic")); Catspm.put(CatSPM.SPM_RWAK, new S57enum(24, "reduced_wake"));
    472   Catspm.put(CatSPM.SPM_SPDL, new S57enum(25, "speed_limit")); Catspm.put(CatSPM.SPM_STOP, new S57enum(26, "stop")); Catspm.put(CatSPM.SPM_WRNG, new S57enum(27, "warning"));
    473   Catspm.put(CatSPM.SPM_SSSN, new S57enum(28, "sound_ship_siren")); Catspm.put(CatSPM.SPM_RVCL, new S57enum(29, "restricted_vertical_clearance"));
    474   Catspm.put(CatSPM.SPM_MVDT, new S57enum(30, "maximum_vessel_draught")); Catspm.put(CatSPM.SPM_RHCL, new S57enum(31, "restricted_horizontal_clearance"));
    475   Catspm.put(CatSPM.SPM_SCNT, new S57enum(32, "strong_current")); Catspm.put(CatSPM.SPM_BRTH, new S57enum(33, "berthing")); Catspm.put(CatSPM.SPM_OHPC, new S57enum(34, "overhead_power_cable"));
    476   Catspm.put(CatSPM.SPM_CHEG, new S57enum(35, "channel_edge_gradient")); Catspm.put(CatSPM.SPM_TELE, new S57enum(36, "telephone")); Catspm.put(CatSPM.SPM_FCRS, new S57enum(37, "ferry_crossing"));
    477   Catspm.put(CatSPM.SPM_MTRL, new S57enum(38, "marine_traffic_lights")); Catspm.put(CatSPM.SPM_PLIN, new S57enum(39, "pipeline")); Catspm.put(CatSPM.SPM_ANCH, new S57enum(40, "anchorage"));
    478   Catspm.put(CatSPM.SPM_CLRG, new S57enum(41, "clearing")); Catspm.put(CatSPM.SPM_CTRL, new S57enum(42, "control")); Catspm.put(CatSPM.SPM_DIVG, new S57enum(43, "diving"));
    479   Catspm.put(CatSPM.SPM_RBCN, new S57enum(44, "refuge_beacon")); Catspm.put(CatSPM.SPM_FGND, new S57enum(45, "foul_ground")); Catspm.put(CatSPM.SPM_YCHT, new S57enum(46, "yachting"));
    480   Catspm.put(CatSPM.SPM_HPRT, new S57enum(47, "heliport")); Catspm.put(CatSPM.SPM_GPS, new S57enum(48, "gps")); Catspm.put(CatSPM.SPM_SLDG, new S57enum(49, "seaplane_landing"));
    481    Catspm.put(CatSPM.SPM_NENT, new S57enum(50, "no_entry")); Catspm.put(CatSPM.SPM_WRKP, new S57enum(51, "work_in_progress")); Catspm.put(CatSPM.SPM_UKPP, new S57enum(52, "unknown_purpose"));
    482    Catspm.put(CatSPM.SPM_WELH, new S57enum(53, "wellhead")); Catspm.put(CatSPM.SPM_CHSP, new S57enum(54, "channel_separation")); Catspm.put(CatSPM.SPM_MFRM, new S57enum(55, "marine_farm"));
    483    Catspm.put(CatSPM.SPM_AREF, new S57enum(56, "artificial_reef"));
    484  }
    485  public enum CatTRK { TRK_UNKN, TRK_FIXM, TRK_NFXM }
    486  private static final EnumMap<CatTRK, S57enum> Cattrk = new EnumMap<>(CatTRK.class); static { Cattrk.put(CatTRK.TRK_UNKN, new S57enum(0, ""));
    487   Cattrk.put(CatTRK.TRK_FIXM, new S57enum(1, "fixed_marks")); Cattrk.put(CatTRK.TRK_NFXM, new S57enum(2, "no_fixed_marks"));
    488  }
    489  public enum CatTSS { TSS_UNKN, TSS_IMOA, TSS_NIMO }
    490  private static final EnumMap<CatTSS, S57enum> Cattss = new EnumMap<>(CatTSS.class); static { Cattss.put(CatTSS.TSS_UNKN, new S57enum(0, ""));
    491   Cattss.put(CatTSS.TSS_IMOA, new S57enum(1, "imo_adopted")); Cattss.put(CatTSS.TSS_NIMO, new S57enum(2, "not_imo_adopted"));
    492  }
    493  public enum CatVEG { VEG_UNKN, VEG_GRAS, VEG_PDDY, VEG_BUSH, VEG_DCDW, VEG_CONW, VEG_WOOD, VEG_MGRV, VEG_PARK, VEG_PKLD, VEG_MCRP, VEG_REED, VEG_MOSS,
    494   VEG_TREE, VEG_EVGT, VEG_CONT, VEG_PLMT, VEG_NPMT, VEG_CSAT, VEG_EUCT, VEG_DCDT, VEG_MRVT, VEG_FLOT }
    495  private static final EnumMap<CatVEG, S57enum> Catveg = new EnumMap<>(CatVEG.class); static { Catveg.put(CatVEG.VEG_UNKN, new S57enum(0, ""));
    496   Catveg.put(CatVEG.VEG_GRAS, new S57enum(1, "grass")); Catveg.put(CatVEG.VEG_PDDY, new S57enum(2, "paddy")); Catveg.put(CatVEG.VEG_BUSH, new S57enum(3, "bush"));
    497   Catveg.put(CatVEG.VEG_DCDW, new S57enum(4, "deciduous_wood")); Catveg.put(CatVEG.VEG_CONW, new S57enum(5, "coniferous_wood")); Catveg.put(CatVEG.VEG_WOOD, new S57enum(6, "wood"));
    498   Catveg.put(CatVEG.VEG_MGRV, new S57enum(7, "mangroves")); Catveg.put(CatVEG.VEG_PARK, new S57enum(8, "park")); Catveg.put(CatVEG.VEG_PKLD, new S57enum(9, "parkland"));
    499   Catveg.put(CatVEG.VEG_MCRP, new S57enum(10, "mixed_crops")); Catveg.put(CatVEG.VEG_REED, new S57enum(11, "reed")); Catveg.put(CatVEG.VEG_MOSS, new S57enum(12, "moss"));
    500   Catveg.put(CatVEG.VEG_TREE, new S57enum(13, "tree")); Catveg.put(CatVEG.VEG_EVGT, new S57enum(14, "evergreen_tree")); Catveg.put(CatVEG.VEG_CONT, new S57enum(15, "coniferous_tree"));
    501   Catveg.put(CatVEG.VEG_PLMT, new S57enum(16, "palm_tree")); Catveg.put(CatVEG.VEG_NPMT, new S57enum(17, "nipa_palm_tree")); Catveg.put(CatVEG.VEG_CSAT, new S57enum(18, "casuarina_tree"));
    502   Catveg.put(CatVEG.VEG_EUCT, new S57enum(19, "eucalypt_tree")); Catveg.put(CatVEG.VEG_DCDT, new S57enum(20, "deciduous_tree")); Catveg.put(CatVEG.VEG_MRVT, new S57enum(21, "mangrove_tree"));
    503   Catveg.put(CatVEG.VEG_FLOT, new S57enum(22, "filao_tree"));
    504  }
    505  public enum CatWAT { WAT_UNKN, WAT_BKRS, WAT_EDDY, WAT_OVFL, WAT_TDRP, WAT_BMBR }
    506  private static final EnumMap<CatWAT, S57enum> Catwat = new EnumMap<>(CatWAT.class); static { Catwat.put(CatWAT.WAT_UNKN, new S57enum(0, ""));
    507   Catwat.put(CatWAT.WAT_BKRS, new S57enum(1, "breakers")); Catwat.put(CatWAT.WAT_EDDY, new S57enum(2, "eddies")); Catwat.put(CatWAT.WAT_OVFL, new S57enum(3, "overfalls"));
    508   Catwat.put(CatWAT.WAT_TDRP, new S57enum(4, "tide_rips")); Catwat.put(CatWAT.WAT_BMBR, new S57enum(5, "bombora"));
    509  }
    510  public enum CatWED { WED_UNKN, WED_KELP, WED_SWED, WED_SGRS, WED_SGSO }
    511  private static final EnumMap<CatWED, S57enum> Catwed = new EnumMap<>(CatWED.class); static { Catwed.put(CatWED.WED_UNKN, new S57enum(0, ""));
    512   Catwed.put(CatWED.WED_KELP, new S57enum(1, "kelp")); Catwed.put(CatWED.WED_SWED, new S57enum(2, "sea_weed")); Catwed.put(CatWED.WED_SGRS, new S57enum(3, "sea_grass"));
    513   Catwed.put(CatWED.WED_SGSO, new S57enum(4, "sargasso"));
    514  }
    515  public enum CatWRK { WRK_UNKN, WRK_NDGR, WRK_DNGR, WRK_DREM, WRK_MSTS, WRK_HULS }
    516  private static final EnumMap<CatWRK, S57enum> Catwrk = new EnumMap<>(CatWRK.class); static { Catwrk.put(CatWRK.WRK_UNKN, new S57enum(0, ""));
    517   Catwrk.put(CatWRK.WRK_NDGR, new S57enum(1, "non-dangerous")); Catwrk.put(CatWRK.WRK_DNGR, new S57enum(2, "dangerous")); Catwrk.put(CatWRK.WRK_DREM, new S57enum(3, "distributed_remains"));
    518   Catwrk.put(CatWRK.WRK_MSTS, new S57enum(4, "mast_showing")); Catwrk.put(CatWRK.WRK_HULS, new S57enum(5, "hull_showing"));
    519  }
    520  public enum CatZOC { ZOC_UNKN, ZOC_A1, ZOC_A2, ZOC_B, ZOC_C, ZOC_D, ZOC_U }
    521  private static final EnumMap<CatZOC, S57enum> Catzoc = new EnumMap<>(CatZOC.class); static { Catzoc.put(CatZOC.ZOC_UNKN, new S57enum(0, ""));
    522   Catzoc.put(CatZOC.ZOC_A1, new S57enum(1, "a1")); Catzoc.put(CatZOC.ZOC_A2, new S57enum(2, "a2")); Catzoc.put(CatZOC.ZOC_B, new S57enum(3, "b"));
    523   Catzoc.put(CatZOC.ZOC_C, new S57enum(4, "c")); Catzoc.put(CatZOC.ZOC_D, new S57enum(5, "d")); Catzoc.put(CatZOC.ZOC_U, new S57enum(6, "u"));
    524  }
    525  public enum ColCOL { COL_UNK, COL_WHT, COL_BLK, COL_RED, COL_GRN, COL_BLU, COL_YEL, COL_GRY, COL_BRN, COL_AMB, COL_VIO, COL_ORG, COL_MAG, COL_PNK }
    526  private static final EnumMap<ColCOL, S57enum> Colour = new EnumMap<>(ColCOL.class); static { Colour.put(ColCOL.COL_UNK, new S57enum(0, ""));
    527   Colour.put(ColCOL.COL_WHT, new S57enum(1, "white")); Colour.put(ColCOL.COL_BLK, new S57enum(2, "black")); Colour.put(ColCOL.COL_RED, new S57enum(3, "red"));
    528   Colour.put(ColCOL.COL_GRN, new S57enum(4, "green")); Colour.put(ColCOL.COL_BLU, new S57enum(5, "blue")); Colour.put(ColCOL.COL_YEL, new S57enum(6, "yellow"));
    529   Colour.put(ColCOL.COL_GRY, new S57enum(7, "grey")); Colour.put(ColCOL.COL_BRN, new S57enum(8, "brown")); Colour.put(ColCOL.COL_AMB, new S57enum(9, "amber"));
    530   Colour.put(ColCOL.COL_VIO, new S57enum(10, "violet")); Colour.put(ColCOL.COL_ORG, new S57enum(11, "orange")); Colour.put(ColCOL.COL_MAG, new S57enum(12, "magenta"));
    531   Colour.put(ColCOL.COL_PNK, new S57enum(13, "pink"));
    532  }
    533  public enum ColPAT { PAT_UNKN, PAT_HORI, PAT_VERT, PAT_DIAG, PAT_SQUR, PAT_STRP, PAT_BRDR, PAT_CROS, PAT_SALT }
    534  private static final EnumMap<ColPAT, S57enum> Colpat = new EnumMap<>(ColPAT.class); static { Colpat.put(ColPAT.PAT_UNKN, new S57enum(0, ""));
    535   Colpat.put(ColPAT.PAT_HORI, new S57enum(1, "horizontal")); Colpat.put(ColPAT.PAT_VERT, new S57enum(2, "vertical")); Colpat.put(ColPAT.PAT_DIAG, new S57enum(3, "diagonal"));
    536   Colpat.put(ColPAT.PAT_SQUR, new S57enum(4, "squared")); Colpat.put(ColPAT.PAT_STRP, new S57enum(5, "stripes")); Colpat.put(ColPAT.PAT_BRDR, new S57enum(6, "border"));
    537   Colpat.put(ColPAT.PAT_CROS, new S57enum(7, "cross")); Colpat.put(ColPAT.PAT_SALT, new S57enum(8, "saltire"));
    538  }
    539  public enum CndCND { CND_UNKN, CND_UCNS, CND_RUIN, CND_URCL, CND_WLES, CND_PCNS }
    540  private static final EnumMap<CndCND, S57enum> Condtn = new EnumMap<>(CndCND.class); static { Condtn.put(CndCND.CND_UNKN, new S57enum(0, ""));
    541   Condtn.put(CndCND.CND_UCNS, new S57enum(1, "under_construction")); Condtn.put(CndCND.CND_RUIN, new S57enum(2, "ruined")); Condtn.put(CndCND.CND_URCL, new S57enum(3, "under_reclamation"));
    542   Condtn.put(CndCND.CND_WLES, new S57enum(4, "wingless")); Condtn.put(CndCND.CND_PCNS, new S57enum(5, "planned_construction"));
    543  }
    544  public enum ConRAD { RAD_UNKN, RAD_CNSP, RAD_NCSP, RAD_REFL }
    545  private static final EnumMap<ConRAD, S57enum> Conrad = new EnumMap<>(ConRAD.class); static { Conrad.put(ConRAD.RAD_UNKN, new S57enum(0, ""));
    546   Conrad.put(ConRAD.RAD_CNSP, new S57enum(1, "conspicuous")); Conrad.put(ConRAD.RAD_NCSP, new S57enum(2, "not_conspicuous")); Conrad.put(ConRAD.RAD_REFL, new S57enum(3, "reflector"));
    547  }
    548  public enum ConVIS { VIS_UNKN, VIS_CNSP, VIS_NCSP }
    549  private static final EnumMap<ConVIS, S57enum> Convis = new EnumMap<>(ConVIS.class); static { Convis.put(ConVIS.VIS_UNKN, new S57enum(0, ""));
    550   Convis.put(ConVIS.VIS_CNSP, new S57enum(1, "conspicuous")); Convis.put(ConVIS.VIS_NCSP, new S57enum(2, "not_conspicuous"));
    551  }
    552  public enum UniDPU { DPU_UNKN, DPU_METR, DPU_FTFT, DPU_FTHM, DPU_FTFR }
    553  private static final EnumMap<UniDPU, S57enum> Dunits = new EnumMap<>(UniDPU.class); static { Dunits.put(UniDPU.DPU_UNKN, new S57enum(0, ""));
    554   Dunits.put(UniDPU.DPU_METR, new S57enum(1, "metres")); Dunits.put(UniDPU.DPU_FTFT, new S57enum(2, "fathoms_feet")); Dunits.put(UniDPU.DPU_FTHM, new S57enum(3, "fathoms"));
    555   Dunits.put(UniDPU.DPU_FTFR, new S57enum(4, "fathoms_fractions"));
    556  }
    557  public enum ExcLIT { EXH_UNKN, EXH_24H, EXH_DAY, EXH_FOG, EXH_NGHT, EXH_WRNG, EXH_STRM }
    558  private static final EnumMap<ExcLIT, S57enum> Exclit = new EnumMap<>(ExcLIT.class); static { Exclit.put(ExcLIT.EXH_UNKN, new S57enum(0, ""));
    559   Exclit.put(ExcLIT.EXH_24H, new S57enum(1, "24h")); Exclit.put(ExcLIT.EXH_DAY, new S57enum(2, "day")); Exclit.put(ExcLIT.EXH_FOG, new S57enum(3, "fog")); Exclit.put(ExcLIT.EXH_NGHT, new S57enum(4, "night"));
    560   Exclit.put(ExcLIT.EXH_WRNG, new S57enum(5, "warning")); Exclit.put(ExcLIT.EXH_STRM, new S57enum(6, "storm"));
    561  }
    562  public enum ExpSOU { EXP_UNKN, EXP_WTHN, EXP_SHLR, EXP_DEPR }
    563  private static final EnumMap<ExpSOU, S57enum> Expsou = new EnumMap<>(ExpSOU.class); static { Expsou.put(ExpSOU.EXP_UNKN, new S57enum(0, ""));
    564   Expsou.put(ExpSOU.EXP_WTHN, new S57enum(1, "within")); Expsou.put(ExpSOU.EXP_SHLR, new S57enum(2, "shoaler")); Expsou.put(ExpSOU.EXP_DEPR, new S57enum(3, "deeper"));
    565  }
    566  public enum FncFNC { FNC_UNKN, FNC_HBRM, FNC_CSTM, FNC_HLTH, FNC_HOSP, FNC_POST, FNC_HOTL, FNC_RAIL, FNC_POLC, FNC_WPOL, FNC_PILO, FNC_PILL, FNC_BANK,
    567   FNC_DIST, FNC_TRNS, FNC_FCTY, FNC_POWR, FNC_ADMIN, FNC_EDUC, FNC_CHCH, FNC_CHPL, FNC_TMPL, FNC_PGDA, FNC_SHSH, FNC_BTMP, FNC_MOSQ, FNC_MRBT,
    568   FNC_LOOK, FNC_COMM, FNC_TV, FNC_RADO, FNC_RADR, FNC_LGHT, FNC_MCWV, FNC_COOL, FNC_OBS, FNC_TMBL, FNC_CLOK, FNC_CTRL, FNC_ASHM, FNC_STAD, FNC_BUSS,
    569   FNC_PTRM, FNC_SRCT, FNC_OBSV, FNC_OREC, FNC_BTHS, FNC_PMPS }
    570  private static final EnumMap<FncFNC, S57enum> Functn = new EnumMap<>(FncFNC.class); static {Functn.put(FncFNC.FNC_UNKN, new S57enum(0, ""));
    571   Functn.put(FncFNC.FNC_HBRM, new S57enum(2, "harbour_master")); Functn.put(FncFNC.FNC_CSTM, new S57enum(3, "customs")); Functn.put(FncFNC.FNC_HLTH, new S57enum(4, "health"));
    572   Functn.put(FncFNC.FNC_HOSP, new S57enum(5, "hospital")); Functn.put(FncFNC.FNC_POST, new S57enum(6, "post_office")); Functn.put(FncFNC.FNC_HOTL, new S57enum(7, "hotel"));
    573    Functn.put(FncFNC.FNC_RAIL, new S57enum(8, "railway_station")); Functn.put(FncFNC.FNC_POLC, new S57enum(9, "police_station")); Functn.put(FncFNC.FNC_WPOL, new S57enum(10, "water-police_station"));
    574    Functn.put(FncFNC.FNC_PILO, new S57enum(11, "pilot_office")); Functn.put(FncFNC.FNC_PILL, new S57enum(12, "pilot_lookout")); Functn.put(FncFNC.FNC_BANK, new S57enum(13, "bank"));
    575    Functn.put(FncFNC.FNC_DIST, new S57enum(14, "district_control")); Functn.put(FncFNC.FNC_TRNS, new S57enum(15, "transit_shed")); Functn.put(FncFNC.FNC_FCTY, new S57enum(16, "factory"));
    576    Functn.put(FncFNC.FNC_POWR, new S57enum(17, "power_station")); Functn.put(FncFNC.FNC_ADMIN, new S57enum(18, "administrative")); Functn.put(FncFNC.FNC_EDUC, new S57enum(19, "educational"));
    577    Functn.put(FncFNC.FNC_CHCH, new S57enum(20, "church")); Functn.put(FncFNC.FNC_CHPL, new S57enum(21, "chapel")); Functn.put(FncFNC.FNC_TMPL, new S57enum(22, "temple"));
    578    Functn.put(FncFNC.FNC_PGDA, new S57enum(23, "pagoda")); Functn.put(FncFNC.FNC_SHSH, new S57enum(24, "shinto_shrine")); Functn.put(FncFNC.FNC_BTMP, new S57enum(25, "buddhist_temple"));
    579    Functn.put(FncFNC.FNC_MOSQ, new S57enum(26, "mosque")); Functn.put(FncFNC.FNC_MRBT, new S57enum(27, "marabout")); Functn.put(FncFNC.FNC_LOOK, new S57enum(28, "lookout"));
    580    Functn.put(FncFNC.FNC_COMM, new S57enum(29, "communication")); Functn.put(FncFNC.FNC_TV, new S57enum(30, "television")); Functn.put(FncFNC.FNC_RADO, new S57enum(31, "radio"));
    581    Functn.put(FncFNC.FNC_RADR, new S57enum(32, "radar")); Functn.put(FncFNC.FNC_LGHT, new S57enum(33, "light_support")); Functn.put(FncFNC.FNC_MCWV, new S57enum(34, "microwave"));
    582    Functn.put(FncFNC.FNC_COOL, new S57enum(35, "cooling")); Functn.put(FncFNC.FNC_OBS, new S57enum(36, "observation")); Functn.put(FncFNC.FNC_TMBL, new S57enum(37, "time_ball"));
    583    Functn.put(FncFNC.FNC_CLOK, new S57enum(38, "clock")); Functn.put(FncFNC.FNC_CTRL, new S57enum(39, "control")); Functn.put(FncFNC.FNC_ASHM, new S57enum(40, "airship_mooring"));
    584    Functn.put(FncFNC.FNC_STAD, new S57enum(41, "stadium")); Functn.put(FncFNC.FNC_BUSS, new S57enum(42, "bus_station")); Functn.put(FncFNC.FNC_PTRM, new S57enum(43, "passenger_terminal"));
    585    Functn.put(FncFNC.FNC_SRCT, new S57enum(44, "sea_rescue_control")); Functn.put(FncFNC.FNC_OBSV, new S57enum(45, "observatory")); Functn.put(FncFNC.FNC_OREC, new S57enum(46, "ore_crusher"));
    586    Functn.put(FncFNC.FNC_BTHS, new S57enum(47, "boathouse")); Functn.put(FncFNC.FNC_PMPS, new S57enum(48, "pumping_station"));
    587  }
    588 
    589  public enum UniHLU { HLU_UNKN, HLU_METR, HLU_FEET, HLU_KMTR, HLU_HMTR, HLU_SMIL, HLU_NMIL }
    590  private static final EnumMap<UniHLU, S57enum> Hunits = new EnumMap<>(UniHLU.class); static { Hunits.put(UniHLU.HLU_UNKN, new S57enum(0, ""));
    591   Hunits.put(UniHLU.HLU_METR, new S57enum(1, "metres")); Hunits.put(UniHLU.HLU_FEET, new S57enum(2, "feet")); Hunits.put(UniHLU.HLU_KMTR, new S57enum(3, "kilometres"));
    592   Hunits.put(UniHLU.HLU_HMTR, new S57enum(4, "hectometres")); Hunits.put(UniHLU.HLU_SMIL, new S57enum(5, "statute_miles")); Hunits.put(UniHLU.HLU_NMIL, new S57enum(6, "nautical_miles"));
    593  }
    594  public enum JrsJRS { JRS_UNKN, JRS_INT, JRS_NAT, JRS_NSD }
    595  private static final EnumMap<JrsJRS, S57enum> Jrsdtn = new EnumMap<>(JrsJRS.class); static { Jrsdtn.put(JrsJRS.JRS_UNKN, new S57enum(0, ""));
    596   Jrsdtn.put(JrsJRS.JRS_INT, new S57enum(1, "international")); Jrsdtn.put(JrsJRS.JRS_NAT, new S57enum(2, "national")); Jrsdtn.put(JrsJRS.JRS_NSD, new S57enum(3, "national_sub-division"));
    597  }
    598  public enum LitCHR { CHR_UNKN, CHR_F, CHR_FL, CHR_LFL, CHR_Q, CHR_VQ, CHR_UQ, CHR_ISO, CHR_OC, CHR_IQ, CHR_IVQ, CHR_IUQ, CHR_MO, CHR_FFL,
    599   CHR_FLLFL, CHR_OCFL, CHR_FLFL, CHR_ALOC, CHR_ALLFL, CHR_ALFL, CHR_ALGR, CHR_QLFL, CHR_VQLFL, CHR_UQLFL, CHR_AL, CHR_ALFFL }
    600  private static final EnumMap<LitCHR, S57enum> Litchr = new EnumMap<>(LitCHR.class); static { Litchr.put(LitCHR.CHR_UNKN, new S57enum(0, ""));
    601   Litchr.put(LitCHR.CHR_F, new S57enum(1, "F")); Litchr.put(LitCHR.CHR_FL, new S57enum(2, "Fl")); Litchr.put(LitCHR.CHR_LFL, new S57enum(3, "LFl")); Litchr.put(LitCHR.CHR_Q, new S57enum(4, "Q"));
    602   Litchr.put(LitCHR.CHR_VQ, new S57enum(5, "VQ")); Litchr.put(LitCHR.CHR_UQ, new S57enum(6, "UQ")); Litchr.put(LitCHR.CHR_ISO, new S57enum(7, "Iso")); Litchr.put(LitCHR.CHR_OC, new S57enum(8, "Oc"));
    603    Litchr.put(LitCHR.CHR_IQ, new S57enum(9, "IQ")); Litchr.put(LitCHR.CHR_IVQ, new S57enum(10, "IVQ")); Litchr.put(LitCHR.CHR_IUQ, new S57enum(11, "IUQ")); Litchr.put(LitCHR.CHR_MO, new S57enum(12, "Mo"));
    604    Litchr.put(LitCHR.CHR_FFL, new S57enum(13, "FFl")); Litchr.put(LitCHR.CHR_FLLFL, new S57enum(14, "FlLFl")); Litchr.put(LitCHR.CHR_OCFL, new S57enum(15, "OcFl"));
    605    Litchr.put(LitCHR.CHR_FLFL, new S57enum(16, "FLFl")); Litchr.put(LitCHR.CHR_ALOC, new S57enum(17, "Al.Oc")); Litchr.put(LitCHR.CHR_ALLFL, new S57enum(18, "Al.LFl"));
    606    Litchr.put(LitCHR.CHR_ALFL, new S57enum(19, "Al.Fl")); Litchr.put(LitCHR.CHR_ALGR, new S57enum(20, "Al.Gr")); Litchr.put(LitCHR.CHR_QLFL, new S57enum(25, "Q+LFl"));
    607    Litchr.put(LitCHR.CHR_VQLFL, new S57enum(26, "VQ+LFl")); Litchr.put(LitCHR.CHR_UQLFL, new S57enum(27, "UQ+LFl")); Litchr.put(LitCHR.CHR_AL, new S57enum(28, "Al"));
    608    Litchr.put(LitCHR.CHR_ALFFL, new S57enum(29, "Al.FFl"));
    609  }
    610  public enum LitVIS { LIT_UNKN, LIT_HIGH, LIT_LOW, LIT_FANT, LIT_INTS, LIT_UINT, LIT_RSTR, LIT_OBSC, LIT_POBS }
    611  private static final EnumMap<LitVIS, S57enum> Litvis = new EnumMap<>(LitVIS.class); static { Litvis.put(LitVIS.LIT_UNKN, new S57enum(0, ""));
    612   Litvis.put(LitVIS.LIT_HIGH, new S57enum(1, "high")); Litvis.put(LitVIS.LIT_LOW, new S57enum(2, "low")); Litvis.put(LitVIS.LIT_FANT, new S57enum(3, "faint"));
    613   Litvis.put(LitVIS.LIT_INTS, new S57enum(4, "intensified")); Litvis.put(LitVIS.LIT_UINT, new S57enum(5, "unintensified")); Litvis.put(LitVIS.LIT_RSTR, new S57enum(6, "restricted"));
    614   Litvis.put(LitVIS.LIT_OBSC, new S57enum(7, "obscured")); Litvis.put(LitVIS.LIT_POBS, new S57enum(8, "part_obscured"));
    615  }
    616  public enum MarSYS { SYS_UNKN, SYS_IALA, SYS_IALB, SYS_NONE, SYS_OTHR, SYS_CEVN, SYS_RIWR, SYS_BWR2, SYS_BNWR, SYS_PPWB }
    617  private static final EnumMap<MarSYS, S57enum> Marsys = new EnumMap<>(MarSYS.class); static { Marsys.put(MarSYS.SYS_UNKN, new S57enum(0, ""));
    618   Marsys.put(MarSYS.SYS_IALA, new S57enum(1, "iala-a")); Marsys.put(MarSYS.SYS_IALB, new S57enum(2, "iala-b")); Marsys.put(MarSYS.SYS_NONE, new S57enum(9, "none"));
    619   Marsys.put(MarSYS.SYS_OTHR, new S57enum(10, "other")); Marsys.put(MarSYS.SYS_CEVN, new S57enum(11, "cevni")); Marsys.put(MarSYS.SYS_RIWR, new S57enum(12, "riwr"));
    620   Marsys.put(MarSYS.SYS_BWR2, new S57enum(13, "bniwr2")); Marsys.put(MarSYS.SYS_BNWR, new S57enum(14, "bniwr")); Marsys.put(MarSYS.SYS_PPWB, new S57enum(15, "ppwbc"));
    621  }
    622  public enum NatCON { CON_UNKN, CON_MSNY, CON_CONC, CON_BDRS, CON_HSRF, CON_USRF, CON_WOOD, CON_METL, CON_GRP, CON_PNTD, CON_FMWK, CON_LATT, CON_GLAS }
    623  private static final EnumMap<NatCON, S57enum> Natcon = new EnumMap<>(NatCON.class); static { Natcon.put(NatCON.CON_UNKN, new S57enum(0, ""));
    624   Natcon.put(NatCON.CON_MSNY, new S57enum(1, "masonry")); Natcon.put(NatCON.CON_CONC, new S57enum(2, "concreted")); Natcon.put(NatCON.CON_BDRS, new S57enum(3, "loose_boulders"));
    625   Natcon.put(NatCON.CON_HSRF, new S57enum(4, "hard-surfaced")); Natcon.put(NatCON.CON_USRF, new S57enum(5, "unsurfaced")); Natcon.put(NatCON.CON_WOOD, new S57enum(6, "wooden"));
    626   Natcon.put(NatCON.CON_METL, new S57enum(7, "metal")); Natcon.put(NatCON.CON_GRP, new S57enum(8, "grp")); Natcon.put(NatCON.CON_PNTD, new S57enum(9, "painted"));
    627   Natcon.put(NatCON.CON_FMWK, new S57enum(10, "framework")); Natcon.put(NatCON.CON_LATT, new S57enum(11, "latticed")); Natcon.put(NatCON.CON_GLAS, new S57enum(12, "glass"));
    628  }
    629  public enum NatSUR { SUR_UNKN, SUR_MUD, SUR_CLAY, SUR_SILT, SUR_SAND, SUR_STON, SUR_GRVL, SUR_PBBL, SUR_CBBL, SUR_ROCK, SUR_LAVA, SUR_CORL, SUR_SHEL, SUR_BLDR }
    630  private static final EnumMap<NatSUR, S57enum> Natsur = new EnumMap<>(NatSUR.class); static { Natsur.put(NatSUR.SUR_UNKN, new S57enum(0, ""));
    631   Natsur.put(NatSUR.SUR_MUD, new S57enum(1, "mud")); Natsur.put(NatSUR.SUR_CLAY, new S57enum(2, "clay")); Natsur.put(NatSUR.SUR_SILT, new S57enum(3, "silt"));
    632   Natsur.put(NatSUR.SUR_SAND, new S57enum(4, "sand")); Natsur.put(NatSUR.SUR_STON, new S57enum(5, "stones")); Natsur.put(NatSUR.SUR_GRVL, new S57enum(6, "gravel"));
    633   Natsur.put(NatSUR.SUR_PBBL, new S57enum(7, "pebbles")); Natsur.put(NatSUR.SUR_CBBL, new S57enum(8, "cobbles")); Natsur.put(NatSUR.SUR_ROCK, new S57enum(9, "rocky"));
    634   Natsur.put(NatSUR.SUR_LAVA, new S57enum(11, "lava")); Natsur.put(NatSUR.SUR_CORL, new S57enum(14, "coral")); Natsur.put(NatSUR.SUR_SHEL, new S57enum(17, "shells"));
    635   Natsur.put(NatSUR.SUR_BLDR, new S57enum(18, "boulders"));
    636  }
    637  public enum NatQUA { QUA_UNKN, QUA_FINE, QUA_MEDM, QUA_CORS, QUA_BRKN, QUA_STKY, QUA_SOFT, QUA_STIF, QUA_VCNC, QUA_CALC, QUA_HARD }
    638  private static final EnumMap<NatQUA, S57enum> Natqua = new EnumMap<>(NatQUA.class); static { Natqua.put(NatQUA.QUA_UNKN, new S57enum(0, ""));
    639   Natqua.put(NatQUA.QUA_FINE, new S57enum(1, "fine")); Natqua.put(NatQUA.QUA_MEDM, new S57enum(2, "medium")); Natqua.put(NatQUA.QUA_CORS, new S57enum(3, "coarse"));
    640   Natqua.put(NatQUA.QUA_BRKN, new S57enum(4, "broken")); Natqua.put(NatQUA.QUA_STKY, new S57enum(5, "sticky")); Natqua.put(NatQUA.QUA_SOFT, new S57enum(6, "soft"));
    641   Natqua.put(NatQUA.QUA_STIF, new S57enum(7, "stiff")); Natqua.put(NatQUA.QUA_VCNC, new S57enum(8, "volcanic")); Natqua.put(NatQUA.QUA_CALC, new S57enum(9, "calcareous"));
    642   Natqua.put(NatQUA.QUA_HARD, new S57enum(10, "hard"));
    643  }
    644  public enum PrdPRD { PRD_UNKN, PRD_OIL, PRD_GAS, PRD_WATR, PRD_STON, PRD_COAL, PRD_ORE, PRD_CHEM, PRD_DWTR, PRD_MILK, PRD_BXIT, PRD_COKE, PRD_IIGS, PRD_SALT,
    645   PRD_SAND, PRD_TMBR, PRD_SDST, PRD_SCRP, PRD_LNA, PRD_LPA, PRD_WINE, PRD_CMNT, PRD_GRAN }
    646  private static final EnumMap<PrdPRD, S57enum> Prodct = new EnumMap<>(PrdPRD.class); static { Prodct.put(PrdPRD.PRD_UNKN, new S57enum(0, ""));
    647   Prodct.put(PrdPRD.PRD_OIL, new S57enum(1, "oil")); Prodct.put(PrdPRD.PRD_GAS, new S57enum(2, "gas")); Prodct.put(PrdPRD.PRD_WATR, new S57enum(3, "water"));
    648   Prodct.put(PrdPRD.PRD_STON, new S57enum(4, "stone")); Prodct.put(PrdPRD.PRD_COAL, new S57enum(5, "coal")); Prodct.put(PrdPRD.PRD_ORE, new S57enum(6, "ore"));
    649   Prodct.put(PrdPRD.PRD_CHEM, new S57enum(7, "chemicals")); Prodct.put(PrdPRD.PRD_DWTR, new S57enum(8, "drinking_water")); Prodct.put(PrdPRD.PRD_MILK, new S57enum(9, "milk"));
    650   Prodct.put(PrdPRD.PRD_BXIT, new S57enum(10, "bauxite")); Prodct.put(PrdPRD.PRD_COKE, new S57enum(11, "coke")); Prodct.put(PrdPRD.PRD_IIGS, new S57enum(12, "iron_ingots"));
    651   Prodct.put(PrdPRD.PRD_SALT, new S57enum(13, "salt")); Prodct.put(PrdPRD.PRD_SAND, new S57enum(14, "sand")); Prodct.put(PrdPRD.PRD_TMBR, new S57enum(15, "timber"));
    652   Prodct.put(PrdPRD.PRD_SDST, new S57enum(16, "sawdust")); Prodct.put(PrdPRD.PRD_SCRP, new S57enum(17, "scrap")); Prodct.put(PrdPRD.PRD_LNA, new S57enum(18, "lng"));
    653   Prodct.put(PrdPRD.PRD_LPA, new S57enum(19, "lpg")); Prodct.put(PrdPRD.PRD_WINE, new S57enum(20, "wine")); Prodct.put(PrdPRD.PRD_CMNT, new S57enum(21, "cement"));
    654   Prodct.put(PrdPRD.PRD_GRAN, new S57enum(22, "grain"));
    655  }
    656  public enum QuaSOU { SOU_UNKN, SOU_KNWN, SOU_UKNN, SOU_DFUL, SOU_UNRL, SOU_NBFD, SOU_LKWN, SOU_LUKN, SOU_NSRV, SOU_NCNF, SOU_MANT, SOU_NMNT }
    657  private static final EnumMap<QuaSOU, S57enum> Quasou = new EnumMap<>(QuaSOU.class); static { Quasou.put(QuaSOU.SOU_UNKN, new S57enum(0, ""));
    658   Quasou.put(QuaSOU.SOU_KNWN, new S57enum(1, "known")); Quasou.put(QuaSOU.SOU_UKNN, new S57enum(2, "unknown")); Quasou.put(QuaSOU.SOU_DFUL, new S57enum(3, "doubtful"));
    659   Quasou.put(QuaSOU.SOU_UNRL, new S57enum(4, "unreliable")); Quasou.put(QuaSOU.SOU_NBFD, new S57enum(5, "no_bottom_found")); Quasou.put(QuaSOU.SOU_LKWN, new S57enum(6, "least_known"));
    660   Quasou.put(QuaSOU.SOU_LUKN, new S57enum(7, "least_unknown")); Quasou.put(QuaSOU.SOU_NSRV, new S57enum(8, "not_surveyed")); Quasou.put(QuaSOU.SOU_NCNF, new S57enum(9, "not_confirmed"));
    661   Quasou.put(QuaSOU.SOU_MANT, new S57enum(10, "maintained")); Quasou.put(QuaSOU.SOU_NMNT, new S57enum(11, "not_maintained"));
    662  }
    663  public enum RstRST { RST_UNKN, RST_NANC, RST_RANC, RST_NFSH, RST_RFSH, RST_NTRL, RST_RTRL, RST_NENT, RST_RENT, RST_NDRG, RST_RDRG, RST_NDVG, RST_RDVG, RST_NWAK, RST_TBAV, RST_NCST, RST_NDSC,
    664   RST_RDSC, RST_NEXD, RST_REXD, RST_NDRL, RST_RDRL, RST_NHAR, RST_NLTG, RST_NDRA, RST_NSTP, RST_NLND, RST_RSPD, RST_NOVT, RST_NCOV, RST_NPOV, RST_NBRT, RST_RBRT, RST_NMFT, RST_RMFT, RST_NTRN,
    665   RST_RFWD, RST_RFWW, RST_NSWM  }
    666  private static final EnumMap<RstRST, S57enum> Restrn = new EnumMap<>(RstRST.class); static { Restrn.put(RstRST.RST_UNKN, new S57enum(0, ""));
    667   Restrn.put(RstRST.RST_NANC, new S57enum(1, "no_anchoring")); Restrn.put(RstRST.RST_RANC, new S57enum(2, "restricted_anchoring")); Restrn.put(RstRST.RST_NFSH, new S57enum(3, "no_fishing"));
    668   Restrn.put(RstRST.RST_RFSH, new S57enum(4, "restricted_fishing")); Restrn.put(RstRST.RST_NTRL, new S57enum(5, "no_trawling")); Restrn.put(RstRST.RST_RTRL, new S57enum(6, "restricted_trawling"));
    669   Restrn.put(RstRST.RST_NENT, new S57enum(7, "no_entry")); Restrn.put(RstRST.RST_RENT, new S57enum(8, "restricted_entry")); Restrn.put(RstRST.RST_NDRG, new S57enum(9, "no_dredging"));
    670   Restrn.put(RstRST.RST_RDRG, new S57enum(10, "restricted_dredging")); Restrn.put(RstRST.RST_NDVG, new S57enum(11, "no_diving")); Restrn.put(RstRST.RST_RDVG, new S57enum(12, "restricted_diving"));
    671   Restrn.put(RstRST.RST_NWAK, new S57enum(13, "no_wake")); Restrn.put(RstRST.RST_TBAV, new S57enum(14, "to_be_avoided")); Restrn.put(RstRST.RST_NCST, new S57enum(15, "no_construction"));
    672   Restrn.put(RstRST.RST_NDSC, new S57enum(16, "no_discharging")); Restrn.put(RstRST.RST_RDSC, new S57enum(17, "restricted_discharging"));
    673   Restrn.put(RstRST.RST_NEXD, new S57enum(18, "no_exploration_development")); Restrn.put(RstRST.RST_REXD, new S57enum(19, "restricted_exploration_development"));
    674   Restrn.put(RstRST.RST_NDRL, new S57enum(20, "no_drilling")); Restrn.put(RstRST.RST_RDRL, new S57enum(21, "restricted_drilling"));
    675   Restrn.put(RstRST.RST_NHAR, new S57enum(22, "no_historical_artifacts_removal")); Restrn.put(RstRST.RST_NLTG, new S57enum(23, "no_lightering")); Restrn.put(RstRST.RST_NDRA, new S57enum(24, "no_dragging"));
    676    Restrn.put(RstRST.RST_NSTP, new S57enum(25, "no_stopping")); Restrn.put(RstRST.RST_NLND, new S57enum(26, "no_landing")); Restrn.put(RstRST.RST_RSPD, new S57enum(27, "restricted_speed"));
    677    Restrn.put(RstRST.RST_NOVT, new S57enum(28, "no_overtaking")); Restrn.put(RstRST.RST_NCOV, new S57enum(29, "no_convoy_overtaking")); Restrn.put(RstRST.RST_NPOV, new S57enum(30, "no_passing_overtaking"));
    678    Restrn.put(RstRST.RST_NBRT, new S57enum(31, "no_berthing")); Restrn.put(RstRST.RST_RBRT, new S57enum(32, "restricted_berthing")); Restrn.put(RstRST.RST_NMFT, new S57enum(33, "no_making_fast"));
    679    Restrn.put(RstRST.RST_RMFT, new S57enum(34, "restricted_making_fast")); Restrn.put(RstRST.RST_NTRN, new S57enum(35, "no_turning")); Restrn.put(RstRST.RST_RFWD, new S57enum(36, "restricted_fairway_depth"));
    680    Restrn.put(RstRST.RST_RFWW, new S57enum(37, "restricted_fairway_width")); Restrn.put(RstRST.RST_NSWM, new S57enum(38, "no_swimming"));
    681  }
    682  public enum SigGEN { GEN_UNKN, GEN_AUTO, GEN_WAVE, GEN_HAND, GEN_WIND }
    683  private static final EnumMap<SigGEN, S57enum> Siggen = new EnumMap<>(SigGEN.class); static { Siggen.put(SigGEN.GEN_UNKN, new S57enum(0, ""));
    684   Siggen.put(SigGEN.GEN_AUTO, new S57enum(1, "automatic")); Siggen.put(SigGEN.GEN_WAVE, new S57enum(2, "wave")); Siggen.put(SigGEN.GEN_HAND, new S57enum(3, "hand")); Siggen.put(SigGEN.GEN_WIND, new S57enum(4, "wind"));
    685  }
    686  public enum StsSTS { STS_UNKN, STS_PERM, STS_OCAS, STS_RCMD, STS_NIUS, STS_IMTT, STS_RESV, STS_TEMP, STS_PRIV, STS_MAND, STS_EXTD, STS_ILLD, STS_HIST, STS_PBLC,
    687   STS_SYNC, STS_WCHD, STS_UWCD, STS_EDBT, STS_OREQ, STS_DPAW, STS_RSNG, STS_INCR, STS_DECR, TS_STNG, STS_GOOD, STS_MODY, STS_POOR }
    688  private static final EnumMap<StsSTS, S57enum> Status = new EnumMap<>(StsSTS.class); static { Status.put(StsSTS.STS_UNKN, new S57enum(0, ""));
    689   Status.put(StsSTS.STS_PERM, new S57enum(1, "permanent")); Status.put(StsSTS.STS_OCAS, new S57enum(2, "occasional")); Status.put(StsSTS.STS_RCMD, new S57enum(3, "recommended"));
    690   Status.put(StsSTS.STS_NIUS, new S57enum(4, "not_in_use")); Status.put(StsSTS.STS_IMTT, new S57enum(5, "intermittent")); Status.put(StsSTS.STS_RESV, new S57enum(6, "reserved"));
    691   Status.put(StsSTS.STS_TEMP, new S57enum(7, "temporary")); Status.put(StsSTS.STS_PRIV, new S57enum(8, "private")); Status.put(StsSTS.STS_MAND, new S57enum(9, "mandatory"));
    692   Status.put(StsSTS.STS_EXTD, new S57enum(11, "extinguished")); Status.put(StsSTS.STS_ILLD, new S57enum(12, "illuminated")); Status.put(StsSTS.STS_HIST, new S57enum(13, "historic"));
    693   Status.put(StsSTS.STS_PBLC, new S57enum(14, "public")); Status.put(StsSTS.STS_SYNC, new S57enum(15, "synchronised")); Status.put(StsSTS.STS_WCHD, new S57enum(16, "watched"));
    694   Status.put(StsSTS.STS_UWCD, new S57enum(17, "unwatched")); Status.put(StsSTS.STS_EDBT, new S57enum(18, "existence_doubtful")); Status.put(StsSTS.STS_OREQ, new S57enum(19, "on_request"));
    695   Status.put(StsSTS.STS_DPAW, new S57enum(20, "drop_away")); Status.put(StsSTS.STS_RSNG, new S57enum(21, "rising")); Status.put(StsSTS.STS_INCR, new S57enum(22, "increasing"));
    696   Status.put(StsSTS.STS_DECR, new S57enum(23, "decreasing")); Status.put(StsSTS.TS_STNG, new S57enum(24, "strong")); Status.put(StsSTS.STS_GOOD, new S57enum(25, "good"));
    697   Status.put(StsSTS.STS_MODY, new S57enum(26, "moderately")); Status.put(StsSTS.STS_POOR, new S57enum(27, "poor"));
    698  }
    699  public enum SurTYP { TYP_UNKN, TYP_SKCH, TYP_CTLD, TYP_PSSG, TYP_REMT }
    700  private static final EnumMap<SurTYP, S57enum> Surtyp = new EnumMap<>(SurTYP.class); static { Surtyp.put(SurTYP.TYP_UNKN, new S57enum(0, ""));
    701   Surtyp.put(SurTYP.TYP_SKCH, new S57enum(1, "sketch")); Surtyp.put(SurTYP.TYP_CTLD, new S57enum(2, "controlled")); Surtyp.put(SurTYP.TYP_PSSG, new S57enum(4, "examination"));
    702   Surtyp.put(SurTYP.TYP_PSSG, new S57enum(5, "passage")); Surtyp.put(SurTYP.TYP_REMT, new S57enum(6, "remote"));
    703  }
    704  public enum TecSOU { SOU_UNKN, SOU_ESND, SOU_FSSN, SOU_MLBM, SOU_DIVR, SOU_LDLN, SOU_WDRG, SOU_LASR, SOU_VACC, SOU_EMAG, SOU_PHGY, SOU_SATL, SOU_LEVL, SOU_SSSN, SOU_COMP }
    705  private static final EnumMap<TecSOU, S57enum> Tecsou = new EnumMap<>(TecSOU.class); static { Tecsou.put(TecSOU.SOU_UNKN, new S57enum(0, ""));
    706         Tecsou.put(TecSOU.SOU_ESND, new S57enum(1, "echo-sounder")); Tecsou.put(TecSOU.SOU_FSSN, new S57enum(2, "side-scan_sonar")); Tecsou.put(TecSOU.SOU_MLBM, new S57enum(3, "multi-beam"));
    707   Tecsou.put(TecSOU.SOU_DIVR, new S57enum(4, "diver")); Tecsou.put(TecSOU.SOU_LDLN, new S57enum(5, "lead-line")); Tecsou.put(TecSOU.SOU_WDRG, new S57enum(6, "wire-drag"));
    708   Tecsou.put(TecSOU.SOU_LASR, new S57enum(7, "laser")); Tecsou.put(TecSOU.SOU_VACC, new S57enum(8, "vertical_acoustic")); Tecsou.put(TecSOU.SOU_EMAG, new S57enum(9, "electromagnetic"));
    709   Tecsou.put(TecSOU.SOU_PHGY, new S57enum(10, "photogrammetry")); Tecsou.put(TecSOU.SOU_SATL, new S57enum(11, "satellite")); Tecsou.put(TecSOU.SOU_LEVL, new S57enum(12, "levelling"));
    710   Tecsou.put(TecSOU.SOU_SSSN, new S57enum(13, "side-scan_sonar_swept")); Tecsou.put(TecSOU.SOU_COMP, new S57enum(14, "computer"));
    711  }
    712  public enum TopSHP { TOP_UNKN, TOP_CONE, TOP_ICONE, TOP_SPHR, TOP_ISD, TOP_CAN, TOP_BORD, TOP_SALT, TOP_CROS, TOP_CUBE, TOP_WEST, TOP_EAST, TOP_RHOM,
    713    TOP_NORTH, TOP_SOUTH, TOP_BESM, TOP_IBESM, TOP_FLAG, TOP_SPRH, TOP_SQUR, TOP_HRECT, TOP_VRECT, TOP_TRAP, TOP_ITRAP, TOP_TRI, TOP_ITRI, TOP_CIRC,
    714    TOP_CRSS, TOP_T, TOP_TRCL, TOP_CRCL, TOP_RHCL, TOP_CLTR, TOP_OTHR, TOP_CYSP, TOP_COSP }
    715 
    716         private static final EnumMap<TopSHP, S57enum> Topshp = new EnumMap<>(TopSHP.class); static { Topshp.put(TopSHP.TOP_UNKN, new S57enum(0, ""));
    717                 Topshp.put(TopSHP.TOP_CONE, new S57enum(1, "cone, point up")); Topshp.put(TopSHP.TOP_ICONE, new S57enum(2, "cone, point down")); Topshp.put(TopSHP.TOP_SPHR, new S57enum(3, "sphere"));
    718                 Topshp.put(TopSHP.TOP_ISD, new S57enum(4, "2 spheres")); Topshp.put(TopSHP.TOP_CAN, new S57enum(5, "cylinder")); Topshp.put(TopSHP.TOP_BORD, new S57enum(6, "board"));
    719                 Topshp.put(TopSHP.TOP_SALT, new S57enum(7, "x-shape")); Topshp.put(TopSHP.TOP_CROS, new S57enum(8, "cross")); Topshp.put(TopSHP.TOP_CUBE, new S57enum(9, "cube, point up"));
    720                 Topshp.put(TopSHP.TOP_WEST, new S57enum(10, "2 cones point together")); Topshp.put(TopSHP.TOP_EAST, new S57enum(11, "2 cones base together")); Topshp.put(TopSHP.TOP_RHOM, new S57enum(12, "rhombus"));
    721                 Topshp.put(TopSHP.TOP_NORTH, new S57enum(13, "2 cones up")); Topshp.put(TopSHP.TOP_SOUTH, new S57enum(14, "2 cones down")); Topshp.put(TopSHP.TOP_BESM, new S57enum(15, "besom, point up"));
    722                 Topshp.put(TopSHP.TOP_IBESM, new S57enum(16, "besom, point down")); Topshp.put(TopSHP.TOP_FLAG, new S57enum(17, "flag")); Topshp.put(TopSHP.TOP_SPRH, new S57enum(18, "sphere over rhombus"));
    723                 Topshp.put(TopSHP.TOP_SQUR, new S57enum(19, "square")); Topshp.put(TopSHP.TOP_HRECT, new S57enum(20, "rectangle, horizontal")); Topshp.put(TopSHP.TOP_VRECT, new S57enum(21, "rectangle, vertical"));
    724                 Topshp.put(TopSHP.TOP_TRAP, new S57enum(22, "trapezium, up")); Topshp.put(TopSHP.TOP_ITRAP, new S57enum(23, "trapezium, down")); Topshp.put(TopSHP.TOP_TRI, new S57enum(24, "triangle, point up"));
    725                 Topshp.put(TopSHP.TOP_ITRI, new S57enum(25, "triangle, point down")); Topshp.put(TopSHP.TOP_CIRC, new S57enum(26, "circle")); Topshp.put(TopSHP.TOP_CRSS, new S57enum(27, "2 upright crosses"));
    726                 Topshp.put(TopSHP.TOP_T, new S57enum(28, "t-shape")); Topshp.put(TopSHP.TOP_TRCL, new S57enum(29, "triangle, point up over circle")); Topshp.put(TopSHP.TOP_CRCL, new S57enum(30, "upright cross over circle"));
    727                 Topshp.put(TopSHP.TOP_RHCL, new S57enum(31, "rhombus over circle")); Topshp.put(TopSHP.TOP_CLTR, new S57enum(32, "circle over triangle, point up")); Topshp.put(TopSHP.TOP_OTHR, new S57enum(33, "other"));
    728                 Topshp.put(TopSHP.TOP_CYSP, new S57enum(34, "cylinder over sphere")); Topshp.put(TopSHP.TOP_COSP, new S57enum(35, "cone, point up over sphere"));
    729         }
    730  public enum TrfTRF { TRF_UNKN, TRF_INBD, TRF_OBND, TRF_ONEW, TRF_TWOW }
    731  private static final EnumMap<TrfTRF, S57enum> Trafic = new EnumMap<>(TrfTRF.class); static { Trafic.put(TrfTRF.TRF_UNKN, new S57enum(0, ""));
    732   Trafic.put(TrfTRF.TRF_INBD, new S57enum(1, "inbound")); Trafic.put(TrfTRF.TRF_OBND, new S57enum(2, "outbbound")); Trafic.put(TrfTRF.TRF_ONEW, new S57enum(3, "one-way"));
    733   Trafic.put(TrfTRF.TRF_TWOW, new S57enum(4, "two-way"));
    734  }
    735  public enum WatLEV { LEV_UNKN, LEV_PSUB, LEV_DRY, LEV_SUBM, LEV_CVRS, LEV_AWSH, LEV_FLDS, LEV_FLTG, LEV_AMWL, LEV_BMWL }
    736  private static final EnumMap<WatLEV, S57enum> Watlev = new EnumMap<>(WatLEV.class); static { Watlev.put(WatLEV.LEV_UNKN, new S57enum(0, ""));
    737   Watlev.put(WatLEV.LEV_PSUB, new S57enum(1, "part-submerged")); Watlev.put(WatLEV.LEV_DRY, new S57enum(2, "dry")); Watlev.put(WatLEV.LEV_SUBM, new S57enum(3, "submerged"));
    738   Watlev.put(WatLEV.LEV_CVRS, new S57enum(4, "covers")); Watlev.put(WatLEV.LEV_AWSH, new S57enum(5, "awash")); Watlev.put(WatLEV.LEV_FLDS, new S57enum(6, "floods"));
    739   Watlev.put(WatLEV.LEV_FLTG, new S57enum(7, "floating")); Watlev.put(WatLEV.LEV_AMWL, new S57enum(8, "above_mwl")); Watlev.put(WatLEV.LEV_BMWL, new S57enum(9, "below_mwl"));
    740  }
    741  public enum Cat_TS { TS_UNKN, TS_FLOD, TS_EBB, TS_OTHR }
    742  private static final EnumMap<Cat_TS, S57enum> Cat_ts = new EnumMap<>(Cat_TS.class); static { Cat_ts.put(Cat_TS.TS_UNKN, new S57enum(0, ""));
    743   Cat_ts.put(Cat_TS.TS_FLOD, new S57enum(1, "flood")); Cat_ts.put(Cat_TS.TS_EBB, new S57enum(2, "ebb")); Cat_ts.put(Cat_TS.TS_OTHR, new S57enum(3, "other"));
    744  }
    745  public enum UniPAU { PAU_UNKN, PAU_MTRS, PAU_DGRS, PAU_MMTR, PAU_FEET, PAU_CBLS }
    746  private static final EnumMap<UniPAU, S57enum> Punits = new EnumMap<>(UniPAU.class); static { Punits.put(UniPAU.PAU_UNKN, new S57enum(0, ""));
    747   Punits.put(UniPAU.PAU_MTRS, new S57enum(1, "metres")); Punits.put(UniPAU.PAU_DGRS, new S57enum(2, "degrees")); Punits.put(UniPAU.PAU_MMTR, new S57enum(3, "millimetres"));
    748   Punits.put(UniPAU.PAU_FEET, new S57enum(4, "feet")); Punits.put(UniPAU.PAU_CBLS, new S57enum(5, "cables"));
    749  }
    750  public enum QuaPOS { POS_UNKN, POS_SRVD, POS_USRV, POS_PSRV, POS_APRX, POS_DBTF, POS_URLB, POS_RSRV, POS_UCNF, POS_ESTM, POS_PRCS, POS_CALC }
    751  private static final EnumMap<QuaPOS, S57enum> Quapos = new EnumMap<>(QuaPOS.class); static { Quapos.put(QuaPOS.POS_UNKN, new S57enum(0, ""));
    752   Quapos.put(QuaPOS.POS_SRVD, new S57enum(1, "surveyed")); Quapos.put(QuaPOS.POS_USRV, new S57enum(2, "unsurveyed")); Quapos.put(QuaPOS.POS_PSRV, new S57enum(3, "part-surveyed"));
    753   Quapos.put(QuaPOS.POS_APRX, new S57enum(4, "approximate")); Quapos.put(QuaPOS.POS_DBTF, new S57enum(5, "doubtful")); Quapos.put(QuaPOS.POS_URLB, new S57enum(6, "unreliable"));
    754   Quapos.put(QuaPOS.POS_RSRV, new S57enum(7, "reported_unsurveyd")); Quapos.put(QuaPOS.POS_UCNF, new S57enum(8, "unconfirmed")); Quapos.put(QuaPOS.POS_ESTM, new S57enum(9, "estimated"));
    755   Quapos.put(QuaPOS.POS_PRCS, new S57enum(10, "precise")); Quapos.put(QuaPOS.POS_CALC, new S57enum(11, "calculated"));
    756  }
    757  public enum VerDAT { DAT_UNKN, DAT_MLWS, DAT_MLLWS, DAT_MSL, DAT_LLW, DAT_MLW, DAT_LLWS, DAT_AMLWS, DAT_ISLW, DAT_LWS, DAT_ALAT, DAT_NLLW, DAT_MLLW, DAT_LW, DAT_AMLW, DAT_AMLLW,
    758   DAT_MHW, DAT_MHWS, DAT_HW, DAT_AMSL, DAT_HWS, DAT_MHHW, DAT_ESLW, DAT_LAT, DAT_LOCAL, DAT_IGLD, DAT_MWL, DAT_LLWLT, DAT_HHWLT, DAT_NHHW, DAT_HAT, DAT_LLWRL, DAT_LHWRL,
    759   DAT_LMWRL, DAT_EHW, DAT_HSHW, DAT_RLWL, DAT_HSHWD, DAT_DRLWRL, DAT_RPWL, DAT_RNBL, DAT_OHIO }
    760  private static final EnumMap<VerDAT, S57enum> Verdat = new EnumMap<>(VerDAT.class); static { Verdat.put(VerDAT.DAT_UNKN, new S57enum(0, ""));
    761   Verdat.put(VerDAT.DAT_MLWS, new S57enum(1, "mlws")); Verdat.put(VerDAT.DAT_MLLWS, new S57enum(2, "mllws")); Verdat.put(VerDAT.DAT_MSL, new S57enum(3, "msl"));
    762   Verdat.put(VerDAT.DAT_LLW, new S57enum(4, "llw")); Verdat.put(VerDAT.DAT_MLW, new S57enum(5, "mlw")); Verdat.put(VerDAT.DAT_LLWS, new S57enum(6, "llws"));
    763   Verdat.put(VerDAT.DAT_AMLWS, new S57enum(7, "amlws")); Verdat.put(VerDAT.DAT_ISLW, new S57enum(8, "islw")); Verdat.put(VerDAT.DAT_LWS, new S57enum(9, "lws"));
    764   Verdat.put(VerDAT.DAT_ALAT, new S57enum(10, "alat"));  Verdat.put(VerDAT.DAT_NLLW, new S57enum(11, "nllw")); Verdat.put(VerDAT.DAT_MLLW, new S57enum(12, "mllw"));
    765   Verdat.put(VerDAT.DAT_LW, new S57enum(13, "lw")); Verdat.put(VerDAT.DAT_AMLW, new S57enum(14, "amlw")); Verdat.put(VerDAT.DAT_AMLLW, new S57enum(15, "amllw"));
    766   Verdat.put(VerDAT.DAT_MHW, new S57enum(16, "mhw")); Verdat.put(VerDAT.DAT_MHWS, new S57enum(17, "mhws")); Verdat.put(VerDAT.DAT_HW, new S57enum(18, "hw"));
    767   Verdat.put(VerDAT.DAT_AMSL, new S57enum(19, "amsl")); Verdat.put(VerDAT.DAT_HWS, new S57enum(20, "hws")); Verdat.put(VerDAT.DAT_MHHW, new S57enum(21, "mhhw"));
    768   Verdat.put(VerDAT.DAT_ESLW, new S57enum(22, "eslw")); Verdat.put(VerDAT.DAT_LAT, new S57enum(23, "lat")); Verdat.put(VerDAT.DAT_LOCAL, new S57enum(24, "local"));
    769   Verdat.put(VerDAT.DAT_IGLD, new S57enum(25, "igld1985")); Verdat.put(VerDAT.DAT_MWL, new S57enum(26, "mwl")); Verdat.put(VerDAT.DAT_LLWLT, new S57enum(27, "llwlt"));
    770   Verdat.put(VerDAT.DAT_HHWLT, new S57enum(28, "hhwlt")); Verdat.put(VerDAT.DAT_NHHW, new S57enum(29, "nhhw")); Verdat.put(VerDAT.DAT_HAT, new S57enum(30, "hat"));
    771   Verdat.put(VerDAT.DAT_LLWRL, new S57enum(31, "llwrl")); Verdat.put(VerDAT.DAT_LHWRL, new S57enum(32, "lhwrl")); Verdat.put(VerDAT.DAT_LMWRL, new S57enum(33, "lmwrl"));
    772   Verdat.put(VerDAT.DAT_EHW, new S57enum(34, "ehw_dglw")); Verdat.put(VerDAT.DAT_HSHW, new S57enum(35, "hshw_dhsw")); Verdat.put(VerDAT.DAT_RLWL, new S57enum(36, "rlwl_donau"));
    773   Verdat.put(VerDAT.DAT_HSHWD, new S57enum(37, "hshw_donau")); Verdat.put(VerDAT.DAT_DRLWRL, new S57enum(38, "drlwrl_olr")); Verdat.put(VerDAT.DAT_RPWL, new S57enum(39, "rpwl"));
    774   Verdat.put(VerDAT.DAT_RNBL, new S57enum(40, "rnbl")); Verdat.put(VerDAT.DAT_OHIO, new S57enum(41, "ohio_rd"));
    775  }
    776  public enum AddMRK { MRK_UNKN, MRK_TOPB, MRK_BOTB, MRK_RTRI, MRK_LTRI, MRK_BTRI }
    777  private static final EnumMap<AddMRK, S57enum> Addmrk = new EnumMap<>(AddMRK.class); static { Addmrk.put(AddMRK.MRK_UNKN, new S57enum(0, ""));
    778   Addmrk.put(AddMRK.MRK_TOPB, new S57enum(1, "top_board")); Addmrk.put(AddMRK.MRK_BOTB, new S57enum(2, "bottom_board")); Addmrk.put(AddMRK.MRK_RTRI, new S57enum(3, "right_triangle"));
    779   Addmrk.put(AddMRK.MRK_LTRI, new S57enum(4, "left_triangle")); Addmrk.put(AddMRK.MRK_BTRI, new S57enum(5, "bottom_triangle"));
    780  }
    781  public enum BnkWTW { BWW_UNKN, BWW_LEFT, BWW_RGHT }
    782  private static final EnumMap<BnkWTW, S57enum> Bnkwtw = new EnumMap<>(BnkWTW.class); static { Bnkwtw.put(BnkWTW.BWW_UNKN, new S57enum(0, ""));
    783  Bnkwtw.put(BnkWTW.BWW_LEFT, new S57enum(1, "left")); Bnkwtw.put(BnkWTW.BWW_RGHT, new S57enum(2, "right"));
    784  }
    785  public enum CatNMK { NMK_UNKN, NMK_NENT, NMK_CLSA, NMK_NOVK, NMK_NCOV, NMK_NPAS, NMK_NBRT, NMK_NBLL, NMK_NANK, NMK_NMOR, NMK_NTRN, NMK_NWSH,
    786   NMK_NPSL, NMK_NPSR, NMK_NMTC, NMK_NSPC, NMK_NWSK, NMK_NSLC, NMK_NUPC, NMK_NSLB, NMK_NWBK, NMK_NHSC, NMK_NLBG, NMK_MVTL, NMK_MVTR, NMK_MVTP,
    787   NMK_MVTS, NMK_KPTP, NMK_KPTS, NMK_CSTP, NMK_CSTS, NMK_STOP, NMK_SPDL, NMK_SHRN, NMK_KPLO, NMK_GWJN, NMK_GWCS, NMK_MKRC, NMK_LMDP, NMK_LMHR,
    788   NMK_LMWD, NMK_NAVR, NMK_CHDL, NMK_CHDR, NMK_CHTW, NMK_CHOW, NMK_OPTR, NMK_OPTL, NMK_PRTL, NMK_PRTR, NMK_ENTP, NMK_OVHC, NMK_WEIR, NMK_FERN,
    789   NMK_FERI, NMK_BRTP, NMK_BTLL, NMK_BTLS, NMK_BTRL, NMK_BTUP, NMK_BTP1, NMK_BTP2, NMK_BTP3, NMK_BTUN, NMK_BTN1, NMK_BTN2, NMK_BTN3, NMK_BTUM,
    790   NMK_BTU1, NMK_BTU2, NMK_BTU3, NMK_ANKP, NMK_MORP, NMK_VLBT, NMK_TRNA, NMK_SWWC, NMK_SWWR, NMK_SWWL, NMK_WRSA, NMK_WLSA, NMK_WRSL, NMK_WLSR,
    791   NMK_WRAL, NMK_WLAR, NMK_MWWC, NMK_MWWJ, NMK_MWAR, NMK_MWAL, NMK_WARL, NMK_WALR, NMK_PEND, NMK_DWTR, NMK_TELE, NMK_MTCP, NMK_SPCP, NMK_WSKP,
    792   NMK_SLCP, NMK_UPCP, NMK_SLBP, NMK_RADI, NMK_WTBP, NMK_HSCP, NMK_LBGP, NMK_KTPM, NMK_KTSM, NMK_KTMR, NMK_CRTP, NMK_CRTS, NMK_TRBM, NMK_RSPD,
    793   NMK_WRKP, NMK_PSBS, NMK_NCPS, NMK_NSMC, NMK_ATTN, NMK_FWCR, NMK_SHIP }
    794  private static final EnumMap<CatNMK, S57enum> Catnmk = new EnumMap<>(CatNMK.class); static { Catnmk.put(CatNMK.NMK_UNKN, new S57enum(0, ""));
    795   Catnmk.put(CatNMK.NMK_NENT, new S57enum(1, "no_entry")); Catnmk.put(CatNMK.NMK_CLSA, new S57enum(2, "closed_area")); Catnmk.put(CatNMK.NMK_NOVK, new S57enum(3, "no_overtaking"));
    796   Catnmk.put(CatNMK.NMK_NCOV, new S57enum(4, "no_convoy_overtaking")); Catnmk.put(CatNMK.NMK_NPAS, new S57enum(5, "no_passing")); Catnmk.put(CatNMK.NMK_NBRT, new S57enum(6, "no_berthing"));
    797   Catnmk.put(CatNMK.NMK_NBLL, new S57enum(7, "no_berthing_lateral_limit")); Catnmk.put(CatNMK.NMK_NANK, new S57enum(8, "no_anchoring")); Catnmk.put(CatNMK.NMK_NMOR, new S57enum(9, "no_mooring"));
    798   Catnmk.put(CatNMK.NMK_NTRN, new S57enum(10, "no_turning")); Catnmk.put(CatNMK.NMK_NWSH, new S57enum(11, "no_wash")); Catnmk.put(CatNMK.NMK_NPSL, new S57enum(12, "no_passage_left"));
    799   Catnmk.put(CatNMK.NMK_NPSR, new S57enum(13, "no_passage_right")); Catnmk.put(CatNMK.NMK_NMTC, new S57enum(14, "no_motor_craft")); Catnmk.put(CatNMK.NMK_NSPC, new S57enum(15, "no_sport_craft"));
    800   Catnmk.put(CatNMK.NMK_NWSK, new S57enum(16, "no_waterskiing")); Catnmk.put(CatNMK.NMK_NSLC, new S57enum(17, "no_sailing_craft")); Catnmk.put(CatNMK.NMK_NUPC, new S57enum(18, "no_unpowered_craft"));
    801   Catnmk.put(CatNMK.NMK_NSLB, new S57enum(19, "no_sailboards")); Catnmk.put(CatNMK.NMK_NWBK, new S57enum(20, "no_waterbikes")); Catnmk.put(CatNMK.NMK_NHSC, new S57enum(21, "no_high_speeds"));
    802   Catnmk.put(CatNMK.NMK_NLBG, new S57enum(22, "no_launching_beaching")); Catnmk.put(CatNMK.NMK_MVTL, new S57enum(23, "move_to_left")); Catnmk.put(CatNMK.NMK_MVTR, new S57enum(24, "move_to_right"));
    803   Catnmk.put(CatNMK.NMK_MVTP, new S57enum(25, "move_to_port")); Catnmk.put(CatNMK.NMK_MVTS, new S57enum(26, "move_to_starboard")); Catnmk.put(CatNMK.NMK_KPTP, new S57enum(27, "keep_to_port"));
    804   Catnmk.put(CatNMK.NMK_KPTS, new S57enum(28, "keep_to_starboard")); Catnmk.put(CatNMK.NMK_CSTP, new S57enum(29, "cross_to_port")); Catnmk.put(CatNMK.NMK_CSTS, new S57enum(30, "cross_to_starboard"));
    805   Catnmk.put(CatNMK.NMK_STOP, new S57enum(31, "stop")); Catnmk.put(CatNMK.NMK_SPDL, new S57enum(32, "speed_limit")); Catnmk.put(CatNMK.NMK_SHRN, new S57enum(33, "sound_horn"));
    806   Catnmk.put(CatNMK.NMK_KPLO, new S57enum(34, "keep_lookout")); Catnmk.put(CatNMK.NMK_GWJN, new S57enum(35, "give_way_junction")); Catnmk.put(CatNMK.NMK_GWCS, new S57enum(36, "give_way_crossing"));
    807   Catnmk.put(CatNMK.NMK_MKRC, new S57enum(37, "make_radio_contact")); Catnmk.put(CatNMK.NMK_LMDP, new S57enum(38, "limited_depth")); Catnmk.put(CatNMK.NMK_LMHR, new S57enum(39, "limited_headroom"));
    808   Catnmk.put(CatNMK.NMK_LMWD, new S57enum(40, "limited_width")); Catnmk.put(CatNMK.NMK_NAVR, new S57enum(41, "navigation_restrictions")); Catnmk.put(CatNMK.NMK_CHDL, new S57enum(42, "channel_distance_left"));
    809   Catnmk.put(CatNMK.NMK_CHDR, new S57enum(43, "channel_distance_right")); Catnmk.put(CatNMK.NMK_CHTW, new S57enum(44, "channel_two_way")); Catnmk.put(CatNMK.NMK_CHOW, new S57enum(45, "channel_one_way"));
    810   Catnmk.put(CatNMK.NMK_OPTR, new S57enum(46, "opening_to_right")); Catnmk.put(CatNMK.NMK_OPTL, new S57enum(47, "opening_to_left")); Catnmk.put(CatNMK.NMK_PRTL, new S57enum(48, "proceed_to_left"));
    811   Catnmk.put(CatNMK.NMK_PRTR, new S57enum(49, "proceed_to_right")); Catnmk.put(CatNMK.NMK_ENTP, new S57enum(50, "entry_permitted")); Catnmk.put(CatNMK.NMK_OVHC, new S57enum(51, "overhead_cable"));
    812   Catnmk.put(CatNMK.NMK_WEIR, new S57enum(52, "weir")); Catnmk.put(CatNMK.NMK_FERN, new S57enum(53, "ferry_non_independent"));  Catnmk.put(CatNMK.NMK_FERI, new S57enum(54, "ferry_independent"));
    813   Catnmk.put(CatNMK.NMK_BRTP, new S57enum(55, "berthing_permitted")); Catnmk.put(CatNMK.NMK_BTLL, new S57enum(56, "berthing_lateral_limit")); Catnmk.put(CatNMK.NMK_BTLS, new S57enum(57, "berthing_lateral_limits"));
    814    Catnmk.put(CatNMK.NMK_BTRL, new S57enum(58, "berth_rafting_limit"));  Catnmk.put(CatNMK.NMK_BTUP, new S57enum(59, "berthing_unmarked_pushing"));
    815    Catnmk.put(CatNMK.NMK_BTP1, new S57enum(60, "berthing_marked_pushing_1")); Catnmk.put(CatNMK.NMK_BTP2, new S57enum(61, "berthing_marked_pushing_2"));
    816    Catnmk.put(CatNMK.NMK_BTP3, new S57enum(62, "berthing_marked_pushing_3")); Catnmk.put(CatNMK.NMK_BTUN, new S57enum(63, "berthing_unmarked_non-pushing"));
    817    Catnmk.put(CatNMK.NMK_BTN1, new S57enum(64, "berthing_marked_non-pushing_1")); Catnmk.put(CatNMK.NMK_BTN2, new S57enum(65, "berthing_marked_non-pushing_2"));
    818    Catnmk.put(CatNMK.NMK_BTN3, new S57enum(66, "berthing_marked_non-pushing_3")); Catnmk.put(CatNMK.NMK_BTUM, new S57enum(67, "berthing_unmarked")); Catnmk.put(CatNMK.NMK_BTU1, new S57enum(68, "berthing_marked_1"));
    819    Catnmk.put(CatNMK.NMK_BTU2, new S57enum(69, "berthing_marked_2")); Catnmk.put(CatNMK.NMK_BTU3, new S57enum(70, "berthing_marked_3"));
    820    Catnmk.put(CatNMK.NMK_ANKP, new S57enum(71, "anchoring_permitted"));Catnmk.put(CatNMK.NMK_MORP, new S57enum(72, "mooring_permitted")); Catnmk.put(CatNMK.NMK_VLBT, new S57enum(73, "vehicle_loading_berth"));
    821    Catnmk.put(CatNMK.NMK_TRNA, new S57enum(74, "turning_area")); Catnmk.put(CatNMK.NMK_SWWC, new S57enum(75, "secondary_waterway_crossing")); Catnmk.put(CatNMK.NMK_SWWR, new S57enum(76, "secondary_waterway_right"));
    822    Catnmk.put(CatNMK.NMK_SWWL, new S57enum(77, "secondary_waterway_left")); Catnmk.put(CatNMK.NMK_WRSA, new S57enum(78, "main_waterway_right_secondary_ahead"));
    823    Catnmk.put(CatNMK.NMK_WLSA, new S57enum(79, "main_waterway_left_secondary_ahead")); Catnmk.put(CatNMK.NMK_WRSL, new S57enum(80, "main_waterway_right_secondary_left"));
    824    Catnmk.put(CatNMK.NMK_WLSR, new S57enum(81, "main_waterway_left_secondary_right")); Catnmk.put(CatNMK.NMK_WRAL, new S57enum(82, "main_waterway_right_secondary_ahead_left"));
    825    Catnmk.put(CatNMK.NMK_WLAR, new S57enum(83, "main_waterway_left_secondary_ahead_right")); Catnmk.put(CatNMK.NMK_MWWC, new S57enum(84, "main_waterway_crossing"));
    826    Catnmk.put(CatNMK.NMK_MWWJ, new S57enum(85, "main_waterway_junction")); Catnmk.put(CatNMK.NMK_MWAR, new S57enum(86, "main_waterway_ahead_right"));
    827    Catnmk.put(CatNMK.NMK_MWAL, new S57enum(87, "main_waterway_ahead_left")); Catnmk.put(CatNMK.NMK_WARL, new S57enum(88, "main_waterway_ahead_right_secondary_left"));
    828    Catnmk.put(CatNMK.NMK_WALR, new S57enum(89, "main_waterway_ahead_left_secondary_right")); Catnmk.put(CatNMK.NMK_PEND, new S57enum(90, "prohibition_ends"));
    829    Catnmk.put(CatNMK.NMK_DWTR, new S57enum(91, "drinking_water")); Catnmk.put(CatNMK.NMK_TELE, new S57enum(92, "telephone")); Catnmk.put(CatNMK.NMK_MTCP, new S57enum(93, "motor_craft_permitted"));
    830    Catnmk.put(CatNMK.NMK_SPCP, new S57enum(94, "sport_craft_permitted")); Catnmk.put(CatNMK.NMK_WSKP, new S57enum(95, "waterskiing_permitted")); Catnmk.put(CatNMK.NMK_SLCP, new S57enum(96, "sailing_craft_permitted"));
    831    Catnmk.put(CatNMK.NMK_UPCP, new S57enum(97, "unpowered_craft_permitted")); Catnmk.put(CatNMK.NMK_SLBP, new S57enum(98, "sailboards_permitted")); Catnmk.put(CatNMK.NMK_RADI, new S57enum(99, "radio_information"));
    832    Catnmk.put(CatNMK.NMK_WTBP, new S57enum(100, "waterbikes_permitted")); Catnmk.put(CatNMK.NMK_HSCP, new S57enum(101, "high_speeds_permitted")); Catnmk.put(CatNMK.NMK_LBGP, new S57enum(102, "launching_beaching_permitted"));
    833    Catnmk.put(CatNMK.NMK_KTPM, new S57enum(103, "keep_to_port_margin")); Catnmk.put(CatNMK.NMK_KTSM, new S57enum(104, "keep_to_starboard_margin")); Catnmk.put(CatNMK.NMK_KTMR, new S57enum(105, "keep_to_mid-river"));
    834    Catnmk.put(CatNMK.NMK_CRTP, new S57enum(106, "cross_river_to_port")); Catnmk.put(CatNMK.NMK_CRTS, new S57enum(107, "cross_river_to_starboard")); Catnmk.put(CatNMK.NMK_TRBM, new S57enum(108, "traffic_between_margins"));
    835    Catnmk.put(CatNMK.NMK_RSPD, new S57enum(109, "reduce_speed")); Catnmk.put(CatNMK.NMK_WRKP, new S57enum(110, "wreck_pontoon")); Catnmk.put(CatNMK.NMK_PSBS, new S57enum(111, "pass_both_sides"));
    836    Catnmk.put(CatNMK.NMK_NCPS, new S57enum(112, "no_convoy_passing")); Catnmk.put(CatNMK.NMK_NSMC, new S57enum(113, "no_small_craft")); Catnmk.put(CatNMK.NMK_ATTN, new S57enum(114, "attention"));
    837    Catnmk.put(CatNMK.NMK_FWCR, new S57enum(115, "fairway_crossing")); Catnmk.put(CatNMK.NMK_SHIP, new S57enum(112, "shipping_inspection_point"));
    838  }
    839  public enum ClsDNG { DNG_UNKN, DNG_1BLU, DNG_2BLU, DNG_3BLU, DNG_0BLU, DNG_1RED }
    840  private static final EnumMap<ClsDNG, S57enum> Clsdng = new EnumMap<>(ClsDNG.class); static { Clsdng.put(ClsDNG.DNG_UNKN, new S57enum(0, ""));
    841   Clsdng.put(ClsDNG.DNG_1BLU, new S57enum(1, "one_blue")); Clsdng.put(ClsDNG.DNG_2BLU, new S57enum(2, "two_blue")); Clsdng.put(ClsDNG.DNG_3BLU, new S57enum(3, "three_blue"));
    842   Clsdng.put(ClsDNG.DNG_0BLU, new S57enum(4, "no_blue")); Clsdng.put(ClsDNG.DNG_1RED, new S57enum(5, "one_red"));
    843  }
    844  public enum DirIMP { IMP_UNKN, IMP_UPST, IMP_DNST, IMP_LTBK, IMP_RTBK, IMP_THBR }
    845  private static final EnumMap<DirIMP, S57enum> Dirimp = new EnumMap<>(DirIMP.class); static { Dirimp.put(DirIMP.IMP_UNKN, new S57enum(0, ""));
    846   Dirimp.put(DirIMP.IMP_UPST, new S57enum(1, "upstream")); Dirimp.put(DirIMP.IMP_DNST, new S57enum(2, "downstream")); Dirimp.put(DirIMP.IMP_LTBK, new S57enum(3, "left_bank"));
    847   Dirimp.put(DirIMP.IMP_RTBK, new S57enum(4, "right_bank")); Dirimp.put(DirIMP.IMP_THBR, new S57enum(5, "to_harbour"));
    848  }
    849  public enum FncFNM { FNM_UNKN, FNM_PRHB, FNM_RGLN, FNM_RSTN, FNM_RCMD, FNM_INFO }
    850  private static final EnumMap<FncFNM, S57enum> Fnctnm = new EnumMap<>(FncFNM.class); static { Fnctnm.put(FncFNM.FNM_UNKN, new S57enum(0, ""));
    851   Fnctnm.put(FncFNM.FNM_PRHB, new S57enum(1, "prohibition")); Fnctnm.put(FncFNM.FNM_RGLN, new S57enum(2, "regulation")); Fnctnm.put(FncFNM.FNM_RSTN, new S57enum(3, "restriction"));
    852   Fnctnm.put(FncFNM.FNM_RCMD, new S57enum(4, "recommendation")); Fnctnm.put(FncFNM.FNM_INFO, new S57enum(5, "information"));
    853  }
    854  public enum BunVES { VES_UNKN, VES_BVAV, VES_NBVA }
    855  private static final EnumMap<BunVES, S57enum> Bunves = new EnumMap<>(BunVES.class); static { Bunves.put(BunVES.VES_UNKN, new S57enum(0, ""));
    856   Bunves.put(BunVES.VES_BVAV, new S57enum(1, "bunker_vessel_available")); Bunves.put(BunVES.VES_NBVA, new S57enum(2, "no_bunker_vessel_available"));
    857  }
    858  public enum CatBRT { BRT_UNKN, BRT_LODG, BRT_ULDG, BRT_OVNT, BRT_PSHN, BRT_NPSH, BRT_FLTG, BRT_FCLS, BRT_SCLS }
    859  private static final EnumMap<CatBRT, S57enum> Catbrt = new EnumMap<>(CatBRT.class); static { Catbrt.put(CatBRT.BRT_UNKN, new S57enum(0, ""));
    860   Catbrt.put(CatBRT.BRT_LODG, new S57enum(1, "loading")); Catbrt.put(CatBRT.BRT_ULDG, new S57enum(2, "unloading")); Catbrt.put(CatBRT.BRT_OVNT, new S57enum(3, "overnight_accommodation"));
    861   Catbrt.put(CatBRT.BRT_PSHN, new S57enum(4, "pushing-navigation")); Catbrt.put(CatBRT.BRT_NPSH, new S57enum(5, "non-pushing-navigation"));
    862   Catbrt.put(CatBRT.BRT_FLTG, new S57enum(6, "fleeting")); Catbrt.put(CatBRT.BRT_FCLS, new S57enum(7, "first_class")); Catbrt.put(CatBRT.BRT_SCLS, new S57enum(8, "second_class"));
    863  }
    864  public enum CatBUN { BUN_UNKN, BUN_DESL, BUN_WATR, BUN_BLST }
    865  private static final EnumMap<CatBUN, S57enum> Catbun = new EnumMap<>(CatBUN.class); static { Catbun.put(CatBUN.BUN_UNKN, new S57enum(0, ""));
    866   Catbun.put(CatBUN.BUN_DESL, new S57enum(1, "diesel")); Catbun.put(CatBUN.BUN_WATR, new S57enum(2, "water")); Catbun.put(CatBUN.BUN_BLST, new S57enum(3, "ballast"));
    867  }
    868  public enum CatCCL { CCL_UNKN, CCL_SMLV, CCL_PNCH, CCL_CMPB, CCL_DMEB, CCL_RHNB, CCL_1BPT, CCL_2PTL, CCL_2PTW, CCL_4BPT, CCL_6BPT, CCL_NCCL }
    869  private static final EnumMap<CatCCL, S57enum> Catccl = new EnumMap<>(CatCCL.class); static { Catccl.put(CatCCL.CCL_UNKN, new S57enum(0, ""));
    870   Catccl.put(CatCCL.CCL_SMLV, new S57enum(1, "small_vessels")); Catccl.put(CatCCL.CCL_PNCH, new S57enum(2, "peniche")); Catccl.put(CatCCL.CCL_CMPB, new S57enum(3, "campine_barge"));
    871   Catccl.put(CatCCL.CCL_DMEB, new S57enum(4, "dortmund-ems_barge")); Catccl.put(CatCCL.CCL_RHNB, new S57enum(5, "rhine-herne_barge")); Catccl.put(CatCCL.CCL_1BPT, new S57enum(6, "1-barge_push-tow"));
    872    Catccl.put(CatCCL.CCL_2PTL, new S57enum(7, "2-barge_push-tow_long")); Catccl.put(CatCCL.CCL_2PTW, new S57enum(8, "2-barge_push-tow_wide")); Catccl.put(CatCCL.CCL_4BPT, new S57enum(9, "4-barge_push-tow"));
    873    Catccl.put(CatCCL.CCL_6BPT, new S57enum(10, "6-barge_push-tow")); Catccl.put(CatCCL.CCL_NCCL, new S57enum(11, "no_cemt_class"));
    874  }
    875  public enum CatCOM { COM_UNKN, COM_VTSC, COM_VTSS, COM_IVSP, COM_MID, COM_LOCK, COM_BRDG, COM_CSTM, COM_HRBR }
    876  private static final EnumMap<CatCOM, S57enum> Catcom = new EnumMap<>(CatCOM.class); static { Catcom.put(CatCOM.COM_UNKN, new S57enum(0, ""));
    877   Catcom.put(CatCOM.COM_VTSC, new S57enum(1, "vts_centre")); Catcom.put(CatCOM.COM_VTSS, new S57enum(2, "vts_sector")); Catcom.put(CatCOM.COM_IVSP, new S57enum(3, "ivs_point"));
    878   Catcom.put(CatCOM.COM_MID, new S57enum(4, "mib")); Catcom.put(CatCOM.COM_LOCK, new S57enum(5, "lock")); Catcom.put(CatCOM.COM_BRDG, new S57enum(6, "bridge"));
    879   Catcom.put(CatCOM.COM_CSTM, new S57enum(7, "customs")); Catcom.put(CatCOM.COM_HRBR, new S57enum(8, "harbour"));
    880  }
    881  public enum CatHBR { HBR_UNKN, HBR_CSTM, HBR_REFG, HBR_MRNA, HBR_FISH, HBR_PRIV, HBR_ }
    882  private static final EnumMap<CatHBR, S57enum> Cathbr = new EnumMap<>(CatHBR.class); static { Cathbr.put(CatHBR.HBR_UNKN, new S57enum(0, ""));
    883   Cathbr.put(CatHBR.HBR_CSTM, new S57enum(1, "customs")); Cathbr.put(CatHBR.HBR_REFG, new S57enum(2, "refuge")); Cathbr.put(CatHBR.HBR_MRNA, new S57enum(3, "marina"));
    884   Cathbr.put(CatHBR.HBR_FISH, new S57enum(4, "fishing")); Cathbr.put(CatHBR.HBR_PRIV, new S57enum(5, "private"));
    885  }
    886  public enum CatRFD { RFD_UNKN, RFD_CRSD, RFD_WOIL, RFD_GBWT, RFD_DREF }
    887  private static final EnumMap<CatRFD, S57enum> Catrfd = new EnumMap<>(CatRFD.class); static { Catrfd.put(CatRFD.RFD_UNKN, new S57enum(0, ""));
    888   Catrfd.put(CatRFD.RFD_CRSD, new S57enum(1, "cargo_residue")); Catrfd.put(CatRFD.RFD_WOIL, new S57enum(2, "waste_oil")); Catrfd.put(CatRFD.RFD_GBWT, new S57enum(3, "grey_black_water"));
    889   Catrfd.put(CatRFD.RFD_DREF, new S57enum(4, "domestic_refuse"));
    890  }
    891  public enum CatTML { TML_UNKN, TML_PSGR, TML_FERY, TML_TSPT, TML_RORO }
    892  private static final EnumMap<CatTML, S57enum> Cattml = new EnumMap<>(CatTML.class); static { Cattml.put(CatTML.TML_UNKN, new S57enum(0, ""));
    893   Cattml.put(CatTML.TML_PSGR, new S57enum(1, "passenger")); Cattml.put(CatTML.TML_FERY, new S57enum(2, "ferry")); Cattml.put(CatTML.TML_TSPT, new S57enum(3, "transhipment"));
    894   Cattml.put(CatTML.TML_RORO, new S57enum(4, "roro"));
    895  }
    896  public enum TrsTGD { TGD_UNKN, TGD_CONT, TGD_BULK, TGD_OIL, TGD_FUEL, TGD_CHEM, TGD_LIQD, TGD_EXPL, TGD_FISH, TGD_CARS, TGD_GNRL }
    897  private static final EnumMap<TrsTGD, S57enum> Trshgd = new EnumMap<>(TrsTGD.class); static { Trshgd.put(TrsTGD.TGD_UNKN, new S57enum(0, ""));
    898   Trshgd.put(TrsTGD.TGD_CONT, new S57enum(1, "containers")); Trshgd.put(TrsTGD.TGD_BULK, new S57enum(2, "bulk")); Trshgd.put(TrsTGD.TGD_OIL, new S57enum(3, "oil"));
    899   Trshgd.put(TrsTGD.TGD_FUEL, new S57enum(4, "fuel")); Trshgd.put(TrsTGD.TGD_CHEM, new S57enum(5, "chemicals")); Trshgd.put(TrsTGD.TGD_LIQD, new S57enum(6, "liquid"));
    900   Trshgd.put(TrsTGD.TGD_EXPL, new S57enum(7, "explosive")); Trshgd.put(TrsTGD.TGD_FISH, new S57enum(8, "fish")); Trshgd.put(TrsTGD.TGD_CARS, new S57enum(9, "cars"));
    901   Trshgd.put(TrsTGD.TGD_GNRL, new S57enum(10, "general"));
    902  }
    903  public enum CatGAG { GAG_UNKN, GAG_STAF, GAG_RCRD, GAG_RCRA, GAG_RCEI, GAG_RRAI }
    904  private static final EnumMap<CatGAG, S57enum> Catgag = new EnumMap<>(CatGAG.class); static { Catgag.put(CatGAG.GAG_UNKN, new S57enum(0, ""));
    905   Catgag.put(CatGAG.GAG_STAF, new S57enum(1, "staff")); Catgag.put(CatGAG.GAG_RCRD, new S57enum(2, "recording")); Catgag.put(CatGAG.GAG_RCRA, new S57enum(3, "recording_remote_access"));
    906   Catgag.put(CatGAG.GAG_RCEI, new S57enum(4, "recording_external_indicator")); Catgag.put(CatGAG.GAG_RRAI, new S57enum(5, "recording_remote_access_indicator"));
    907  }
    908  public enum RefLEV { LEV_UNKN, LEV_BALT, LEV_ADRC, LEV_AMSD, LEV_MSL, LEV_OTHR, LEV_NG29, LEV_NA88, LEV_1912, LEV_1929 }
    909  private static final EnumMap<RefLEV, S57enum> Reflev = new EnumMap<>(RefLEV.class); static { Reflev.put(RefLEV.LEV_UNKN, new S57enum(0, ""));
    910   Reflev.put(RefLEV.LEV_BALT, new S57enum(1, "baltic")); Reflev.put(RefLEV.LEV_ADRC, new S57enum(2, "adriatic")); Reflev.put(RefLEV.LEV_AMSD, new S57enum(3, "amsterdam"));
    911   Reflev.put(RefLEV.LEV_MSL, new S57enum(4, "msl")); Reflev.put(RefLEV.LEV_OTHR, new S57enum(5, "other")); Reflev.put(RefLEV.LEV_NG29, new S57enum(6, "ngvd29"));
    912   Reflev.put(RefLEV.LEV_NA88, new S57enum(7, "navd88")); Reflev.put(RefLEV.LEV_1912, new S57enum(8, "msl1912")); Reflev.put(RefLEV.LEV_1929, new S57enum(9, "msl1929"));
    913  }
    914  public enum CatVTR { VTR_UNKN, VTR_OFFL, VTR_PRIV, VTR_CARC, VTR_CARP, VTR_PREQ, VTR_LGAT }
    915  private static final EnumMap<CatVTR, S57enum> Catvtr = new EnumMap<>(CatVTR.class); static { Catvtr.put(CatVTR.VTR_UNKN, new S57enum(0, ""));
    916   Catvtr.put(CatVTR.VTR_OFFL, new S57enum(1, "official")); Catvtr.put(CatVTR.VTR_PRIV, new S57enum(2, "private")); Catvtr.put(CatVTR.VTR_CARC, new S57enum(3, "car_cranes"));
    917   Catvtr.put(CatVTR.VTR_CARP, new S57enum(4, "car_planks")); Catvtr.put(CatVTR.VTR_PREQ, new S57enum(5, "permission_required")); Catvtr.put(CatVTR.VTR_LGAT, new S57enum(6, "locked_gate"));
    918  }
    919  public enum CatTAB { TAB_UNKN, TAB_OPPD, TAB_NOPP }
    920  private static final EnumMap<CatTAB, S57enum> Cattab = new EnumMap<>(CatTAB.class); static { Cattab.put(CatTAB.TAB_UNKN, new S57enum(0, ""));
    921   Cattab.put(CatTAB.TAB_OPPD, new S57enum(1, "operational_period")); Cattab.put(CatTAB.TAB_NOPP, new S57enum(2, "non-operational_period"));
    922  }
    923  public enum UseSHP { SHP_UNKN, SHP_LINT, SHP_OCSH, SHP_LESR }
    924  private static final EnumMap<UseSHP, S57enum> Useshp = new EnumMap<>(UseSHP.class); static { Useshp.put(UseSHP.SHP_UNKN, new S57enum(0, ""));
    925   Useshp.put(UseSHP.SHP_LINT, new S57enum(1, "liner_trade")); Useshp.put(UseSHP.SHP_OCSH, new S57enum(2, "occasional_professional_shipping")); Useshp.put(UseSHP.SHP_LESR, new S57enum(3, "leisure"));
    926  }
    927  public enum CatEXS { EXS_UNKN, EXS_LLOK, EXS_AQDT, EXS_SPLK, EXS_WSLK, EXS_OTHR }
    928  private static final EnumMap<CatEXS, S57enum> Catexs = new EnumMap<>(CatEXS.class); static { Catexs.put(CatEXS.EXS_UNKN, new S57enum(0, ""));
    929   Catexs.put(CatEXS.EXS_LLOK, new S57enum(1, "lift-lock")); Catexs.put(CatEXS.EXS_AQDT, new S57enum(2, "aqueduct")); Catexs.put(CatEXS.EXS_SPLK, new S57enum(3, "sloping_plane_lock"));
    930   Catexs.put(CatEXS.EXS_WSLK, new S57enum(4, "water_slope_lock")); Catexs.put(CatEXS.EXS_OTHR, new S57enum(5, "other"));
    931  }
    932  public enum CatWWM { WWM_UNKN, WWM_WWRT, WWM_WWLT, WWM_WWSP, WWM_CHRT, WWM_CHLT, WWM_CHSP, WWM_CHRB, WWM_CHLB, WWM_CORT, WWM_COLT, WWM_DGRT, WWM_DGLT,
    933   WWM_TORT, WWM_TOLT, WWM_JNRT, WWM_JNLT, WWM_HBRT, WWM_HBLT, WWM_BRPR }
    934  private static final EnumMap<CatWWM, S57enum> Catwwm = new EnumMap<>(CatWWM.class); static { Catwwm.put(CatWWM.WWM_UNKN, new S57enum(0, ""));
    935   Catwwm.put(CatWWM.WWM_WWRT, new S57enum(1, "waterway_right")); Catwwm.put(CatWWM.WWM_WWLT, new S57enum(2, "waterway_left")); Catwwm.put(CatWWM.WWM_WWSP, new S57enum(3, "waterway_separation"));
    936   Catwwm.put(CatWWM.WWM_CHRT, new S57enum(4, "channel_right")); Catwwm.put(CatWWM.WWM_CHLT, new S57enum(5, "channel_left")); Catwwm.put(CatWWM.WWM_CHSP, new S57enum(6, "channel_separation"));
    937   Catwwm.put(CatWWM.WWM_CHRB, new S57enum(7, "channel_right_bank")); Catwwm.put(CatWWM.WWM_CHLB, new S57enum(8, "channel_left_bank")); Catwwm.put(CatWWM.WWM_CORT, new S57enum(9, "crossover_right"));
    938   Catwwm.put(CatWWM.WWM_COLT, new S57enum(10, "crossover_left")); Catwwm.put(CatWWM.WWM_DGRT, new S57enum(11, "danger_right")); Catwwm.put(CatWWM.WWM_DGLT, new S57enum(12, "danger_left"));
    939   Catwwm.put(CatWWM.WWM_TORT, new S57enum(13, "turnoff_right")); Catwwm.put(CatWWM.WWM_TOLT, new S57enum(14, "turnoff_left")); Catwwm.put(CatWWM.WWM_JNRT, new S57enum(15, "junction_right"));
    940   Catwwm.put(CatWWM.WWM_JNLT, new S57enum(16, "junction_left")); Catwwm.put(CatWWM.WWM_HBRT, new S57enum(17, "harbour_right")); Catwwm.put(CatWWM.WWM_HBLT, new S57enum(18, "harbour_left"));
    941   Catwwm.put(CatWWM.WWM_BRPR, new S57enum(19, "bridge_pier"));
    942  }
    943  public enum Lg_SPR { SPR_UNKN, SPR_OTHR, SPR_SPOG, SPR_SPTW }
    944  private static final EnumMap<Lg_SPR, S57enum> Lg_spr = new EnumMap<>(Lg_SPR.class); static { Lg_spr.put(Lg_SPR.SPR_UNKN, new S57enum(0, ""));
    945   Lg_spr.put(Lg_SPR.SPR_OTHR, new S57enum(1, "other")); Lg_spr.put(Lg_SPR.SPR_SPOG, new S57enum(2, "speed_over_ground")); Lg_spr.put(Lg_SPR.SPR_SPTW, new S57enum(3, "speed_through_water"));
    946  }
    947  public enum Lg_WDU { WDU_UNKN, WDU_OTHR, WDU_CUMT, WDU_TONS }
    948  private static final EnumMap<Lg_WDU, S57enum> Lg_wdu = new EnumMap<>(Lg_WDU.class); static { Lg_wdu.put(Lg_WDU.WDU_UNKN, new S57enum(0, ""));
    949   Lg_wdu.put(Lg_WDU.WDU_OTHR, new S57enum(1, "other")); Lg_wdu.put(Lg_WDU.WDU_CUMT, new S57enum(2, "cubic_metres")); Lg_wdu.put(Lg_WDU.WDU_TONS, new S57enum(3, "tonnes"));
    950  }
    951  public enum Lg_REL { REL_UNKN, REL_OTHR, REL_USWW, REL_CREQ, REL_TKOP }
    952  private static final EnumMap<Lg_REL, S57enum> Lg_rel = new EnumMap<>(Lg_REL.class); static { Lg_rel.put(Lg_REL.REL_UNKN, new S57enum(0, ""));
    953   Lg_rel.put(Lg_REL.REL_OTHR, new S57enum(1, "other")); Lg_rel.put(Lg_REL.REL_USWW, new S57enum(2, "usage_of_waterway")); Lg_rel.put(Lg_REL.REL_CREQ, new S57enum(3, "carriage_of_equipment"));
    954   Lg_rel.put(Lg_REL.REL_TKOP, new S57enum(4, "task_operation"));
    955  }
    956  public enum Lg_FNC { FNC_UNKN, FNC_OTHR, FNC_PRHB, FNC_PRHE, FNC_PERM, FNC_PERE, FNC_RCMD, FNC_NRCD }
    957  private static final EnumMap<Lg_FNC, S57enum> Lg_fnc = new EnumMap<>(Lg_FNC.class); static { Lg_fnc.put(Lg_FNC.FNC_UNKN, new S57enum(0, ""));
    958   Lg_fnc.put(Lg_FNC.FNC_OTHR, new S57enum(1, "other")); Lg_fnc.put(Lg_FNC.FNC_PRHB, new S57enum(2, "prohibited")); Lg_fnc.put(Lg_FNC.FNC_PRHE, new S57enum(3, "prohibited_with_exceptions"));
    959   Lg_fnc.put(Lg_FNC.FNC_PERM, new S57enum(4, "permitted")); Lg_fnc.put(Lg_FNC.FNC_PERE, new S57enum(5, "permitted_with_exceptions")); Lg_fnc.put(Lg_FNC.FNC_RCMD, new S57enum(6, "recommended"));
    960   Lg_fnc.put(Lg_FNC.FNC_NRCD, new S57enum(7, "not_recommended"));
    961  }
    962  public enum Lc_CSX { CSX_UNKN, CSX_ALL, CSX_OTHR, CSX_NMOT, CSX_CRFT, CSX_VSSL, CSX_ILWW, CSX_SEAG, CSX_MOTR, CSX_MTNK, CSX_MCGO, CSX_CBRG, CSX_TUG, CSX_PSHR, CSX_BARG, CSX_TNKB,
    963   CSX_DMBB, CSX_LGTR, CSX_TNKL, CSX_CGOL, CSX_SBLR, CSX_PSGR, CSX_PSGS, CSX_DAYT, CSX_CABN, CSX_HSPD, CSX_FLEQ, CSX_WSIT, CSX_RCNL, CSX_DNGY, CSX_FEST, CSX_FOBJ }
    964  private static final EnumMap<Lc_CSX, S57enum> Lc_csi = new EnumMap<>(Lc_CSX.class); static { Lc_csi.put(Lc_CSX.CSX_UNKN, new S57enum(0, ""));
    965   Lc_csi.put(Lc_CSX.CSX_ALL, new S57enum(1, "all")); Lc_csi.put(Lc_CSX.CSX_OTHR, new S57enum(2, "other")); Lc_csi.put(Lc_CSX.CSX_NMOT, new S57enum(3, "non-motorized"));
    966   Lc_csi.put(Lc_CSX.CSX_CRFT, new S57enum(5, "craft")); Lc_csi.put(Lc_CSX.CSX_VSSL, new S57enum(6, "vessel")); Lc_csi.put(Lc_CSX.CSX_ILWW, new S57enum(7, "inland_waterway"));
    967   Lc_csi.put(Lc_CSX.CSX_SEAG, new S57enum(8, "sea-going")); Lc_csi.put(Lc_CSX.CSX_MOTR, new S57enum(9, "motor")); Lc_csi.put(Lc_CSX.CSX_MTNK, new S57enum(10, "motor_tanker"));
    968   Lc_csi.put(Lc_CSX.CSX_MCGO, new S57enum(11, "motor_cargo")); Lc_csi.put(Lc_CSX.CSX_CBRG, new S57enum(12, "canal_barge")); Lc_csi.put(Lc_CSX.CSX_TUG, new S57enum(13, "tug"));
    969   Lc_csi.put(Lc_CSX.CSX_PSHR, new S57enum(14, "pusher")); Lc_csi.put(Lc_CSX.CSX_BARG, new S57enum(15, "barge")); Lc_csi.put(Lc_CSX.CSX_TNKB, new S57enum(16, "tank_barge"));
    970   Lc_csi.put(Lc_CSX.CSX_DMBB, new S57enum(17, "dumb_barge")); Lc_csi.put(Lc_CSX.CSX_LGTR, new S57enum(18, "lighter")); Lc_csi.put(Lc_CSX.CSX_TNKL, new S57enum(19, "tank_lighter"));
    971   Lc_csi.put(Lc_CSX.CSX_CGOL, new S57enum(20, "cargo_lighter")); Lc_csi.put(Lc_CSX.CSX_SBLR, new S57enum(21, "ship_borne_lighter")); Lc_csi.put(Lc_CSX.CSX_PSGR, new S57enum(22, "passenger"));
    972   Lc_csi.put(Lc_CSX.CSX_PSGS, new S57enum(23, "passenger_sailing")); Lc_csi.put(Lc_CSX.CSX_DAYT, new S57enum(24, "day_trip")); Lc_csi.put(Lc_CSX.CSX_CABN, new S57enum(25, "cabin"));
    973   Lc_csi.put(Lc_CSX.CSX_HSPD, new S57enum(26, "high-speed")); Lc_csi.put(Lc_CSX.CSX_FLEQ, new S57enum(27, "floating_equipment")); Lc_csi.put(Lc_CSX.CSX_WSIT, new S57enum(28, "worksite"));
    974   Lc_csi.put(Lc_CSX.CSX_RCNL, new S57enum(29, "recreational")); Lc_csi.put(Lc_CSX.CSX_DNGY, new S57enum(30, "dinghy")); Lc_csi.put(Lc_CSX.CSX_FEST, new S57enum(31, "floating_establishment"));
    975   Lc_csi.put(Lc_CSX.CSX_FOBJ, new S57enum(32, "floating_object"));
    976  }
    977  private static final EnumMap<Lc_CSX, S57enum> Lc_cse = new EnumMap<>(Lc_CSX.class); static { Lc_cse.put(Lc_CSX.CSX_UNKN, new S57enum(0, ""));
    978   Lc_cse.put(Lc_CSX.CSX_ALL, new S57enum(1, "all")); Lc_cse.put(Lc_CSX.CSX_OTHR, new S57enum(2, "other")); Lc_cse.put(Lc_CSX.CSX_NMOT, new S57enum(3, "non-motorized"));
    979   Lc_cse.put(Lc_CSX.CSX_CRFT, new S57enum(5, "craft")); Lc_cse.put(Lc_CSX.CSX_VSSL, new S57enum(6, "vessel")); Lc_cse.put(Lc_CSX.CSX_ILWW, new S57enum(7, "inland_waterway"));
    980   Lc_cse.put(Lc_CSX.CSX_SEAG, new S57enum(8, "sea-going")); Lc_cse.put(Lc_CSX.CSX_MOTR, new S57enum(9, "motor")); Lc_cse.put(Lc_CSX.CSX_MTNK, new S57enum(10, "motor_tanker"));
    981   Lc_cse.put(Lc_CSX.CSX_MCGO, new S57enum(11, "motor_cargo")); Lc_cse.put(Lc_CSX.CSX_CBRG, new S57enum(12, "canal_barge")); Lc_cse.put(Lc_CSX.CSX_TUG, new S57enum(13, "tug"));
    982   Lc_cse.put(Lc_CSX.CSX_PSHR, new S57enum(14, "pusher")); Lc_cse.put(Lc_CSX.CSX_BARG, new S57enum(15, "barge")); Lc_cse.put(Lc_CSX.CSX_TNKB, new S57enum(16, "tank_barge"));
    983   Lc_cse.put(Lc_CSX.CSX_DMBB, new S57enum(17, "dumb_barge")); Lc_cse.put(Lc_CSX.CSX_LGTR, new S57enum(18, "lighter")); Lc_cse.put(Lc_CSX.CSX_TNKL, new S57enum(19, "tank_lighter"));
    984   Lc_cse.put(Lc_CSX.CSX_CGOL, new S57enum(20, "cargo_lighter")); Lc_cse.put(Lc_CSX.CSX_SBLR, new S57enum(21, "ship_borne_lighter")); Lc_cse.put(Lc_CSX.CSX_PSGR, new S57enum(22, "passenger"));
    985   Lc_cse.put(Lc_CSX.CSX_PSGS, new S57enum(23, "passenger_sailing")); Lc_cse.put(Lc_CSX.CSX_DAYT, new S57enum(24, "day_trip")); Lc_cse.put(Lc_CSX.CSX_CABN, new S57enum(25, "cabin"));
    986   Lc_cse.put(Lc_CSX.CSX_HSPD, new S57enum(26, "high-speed")); Lc_cse.put(Lc_CSX.CSX_FLEQ, new S57enum(27, "floating_equipment")); Lc_cse.put(Lc_CSX.CSX_WSIT, new S57enum(28, "worksite"));
    987   Lc_cse.put(Lc_CSX.CSX_RCNL, new S57enum(29, "recreational")); Lc_cse.put(Lc_CSX.CSX_DNGY, new S57enum(30, "dinghy")); Lc_cse.put(Lc_CSX.CSX_FEST, new S57enum(31, "floating_establishment"));
    988   Lc_cse.put(Lc_CSX.CSX_FOBJ, new S57enum(32, "floating_object"));
    989  }
    990  public enum Lc_ASX { ASX_UNKN, ASX_ALL, ASX_OTHR, ASX_SNGL, ASX_CONV, ASX_FMTN, ASX_RCNV, ASX_PCNV, ASX_BSTD, ASX_TCNV }
    991  private static final EnumMap<Lc_ASX, S57enum> Lc_asi = new EnumMap<>(Lc_ASX.class); static { Lc_asi.put(Lc_ASX.ASX_UNKN, new S57enum(0, ""));
    992   Lc_asi.put(Lc_ASX.ASX_ALL, new S57enum(1, "all")); Lc_asi.put(Lc_ASX.ASX_OTHR, new S57enum(2, "other")); Lc_asi.put(Lc_ASX.ASX_SNGL, new S57enum(3, "single"));
    993   Lc_asi.put(Lc_ASX.ASX_CONV, new S57enum(5, "convoy")); Lc_asi.put(Lc_ASX.ASX_FMTN, new S57enum(6, "formation")); Lc_asi.put(Lc_ASX.ASX_RCNV, new S57enum(7, "rigid_convoy"));
    994   Lc_asi.put(Lc_ASX.ASX_PCNV, new S57enum(8, "pushed_convoy")); Lc_asi.put(Lc_ASX.ASX_BSTD, new S57enum(9, "breasted")); Lc_asi.put(Lc_ASX.ASX_TCNV, new S57enum(10, "towed_convoy"));
    995  }
    996  private static final EnumMap<Lc_ASX, S57enum> Lc_ase = new EnumMap<>(Lc_ASX.class); static { Lc_ase.put(Lc_ASX.ASX_UNKN, new S57enum(0, ""));
    997   Lc_ase.put(Lc_ASX.ASX_ALL, new S57enum(1, "all")); Lc_ase.put(Lc_ASX.ASX_OTHR, new S57enum(2, "other")); Lc_ase.put(Lc_ASX.ASX_SNGL, new S57enum(3, "single"));
    998   Lc_ase.put(Lc_ASX.ASX_CONV, new S57enum(5, "convoy")); Lc_ase.put(Lc_ASX.ASX_FMTN, new S57enum(6, "formation")); Lc_ase.put(Lc_ASX.ASX_RCNV, new S57enum(7, "rigid_convoy"));
    999   Lc_ase.put(Lc_ASX.ASX_PCNV, new S57enum(8, "pushed_convoy")); Lc_ase.put(Lc_ASX.ASX_BSTD, new S57enum(9, "breasted")); Lc_ase.put(Lc_ASX.ASX_TCNV, new S57enum(10, "towed_convoy"));
    1000  }
    1001  public enum Lc_CCX { CCX_UNKN, CCX_ALL, CCX_OTHR, CCX_BULK, CCX_DRY, CCX_LIQD, CCX_LQDN, CCX_LQDC, CCX_GAS }
    1002  private static final EnumMap<Lc_CCX, S57enum> Lc_cci = new EnumMap<>(Lc_CCX.class); static { Lc_cci.put(Lc_CCX.CCX_UNKN, new S57enum(0, ""));
    1003   Lc_cci.put(Lc_CCX.CCX_ALL, new S57enum(1, "all")); Lc_cci.put(Lc_CCX.CCX_OTHR, new S57enum(2, "other")); Lc_cci.put(Lc_CCX.CCX_BULK, new S57enum(4, "bulk"));
    1004   Lc_cci.put(Lc_CCX.CCX_DRY, new S57enum(5, "dry")); Lc_cci.put(Lc_CCX.CCX_LIQD, new S57enum(6, "liquid")); Lc_cci.put(Lc_CCX.CCX_LQDN, new S57enum(7, "liquid_n"));
    1005   Lc_cci.put(Lc_CCX.CCX_LQDC, new S57enum(8, "liquid_c")); Lc_cci.put(Lc_CCX.CCX_GAS, new S57enum(9, "gas"));
    1006  }
    1007  private static final EnumMap<Lc_CCX, S57enum> Lc_cce = new EnumMap<>(Lc_CCX.class); static { Lc_cce.put(Lc_CCX.CCX_UNKN, new S57enum(0, ""));
    1008   Lc_cce.put(Lc_CCX.CCX_ALL, new S57enum(1, "all")); Lc_cce.put(Lc_CCX.CCX_OTHR, new S57enum(2, "other")); Lc_cce.put(Lc_CCX.CCX_BULK, new S57enum(4, "bulk"));
    1009   Lc_cce.put(Lc_CCX.CCX_DRY, new S57enum(5, "dry")); Lc_cce.put(Lc_CCX.CCX_LIQD, new S57enum(6, "liquid")); Lc_cce.put(Lc_CCX.CCX_LQDN, new S57enum(7, "liquid_n"));
    1010   Lc_cce.put(Lc_CCX.CCX_LQDC, new S57enum(8, "liquid_c")); Lc_cce.put(Lc_CCX.CCX_GAS, new S57enum(9, "gas"));
    1011  }
    1012 
    1013  public enum ShpTYP { TYP_UNKN, TYP_CRGO, TYP_CONT, TYP_TNKR, TYP_SAIL, TYP_FISH, TYP_SPPS, TYP_MOWR, TYP_SUBM, TYP_HSPD, TYP_BCAR, TYP_SPLN, TYP_TUGB, TYP_PSGR, TYP_FERY, TYP_BOAT }
    1014  private static final EnumMap<ShpTYP, S57enum> Shptyp = new EnumMap<>(ShpTYP.class); static { Shptyp.put(ShpTYP.TYP_UNKN, new S57enum(0, ""));
    1015   Shptyp.put(ShpTYP.TYP_CRGO, new S57enum(1, "cargo")); Shptyp.put(ShpTYP.TYP_CONT, new S57enum(2, "container")); Shptyp.put(ShpTYP.TYP_TNKR, new S57enum(3, "tanker"));
    1016   Shptyp.put(ShpTYP.TYP_SAIL, new S57enum(4, "sailing")); Shptyp.put(ShpTYP.TYP_FISH, new S57enum(5, "fishing")); Shptyp.put(ShpTYP.TYP_SPPS, new S57enum(6, "special_purpose."));
    1017   Shptyp.put(ShpTYP.TYP_MOWR, new S57enum(7, "man_of_war")); Shptyp.put(ShpTYP.TYP_SUBM, new S57enum(8, "submarine")); Shptyp.put(ShpTYP.TYP_HSPD, new S57enum(9, "high-speed"));
    1018   Shptyp.put(ShpTYP.TYP_BCAR, new S57enum(10, "bulk_carrier")); Shptyp.put(ShpTYP.TYP_SPLN, new S57enum(11, "seaplane")); Shptyp.put(ShpTYP.TYP_TUGB, new S57enum(12, "tugboat"));
    1019   Shptyp.put(ShpTYP.TYP_PSGR, new S57enum(13, "passenger")); Shptyp.put(ShpTYP.TYP_FERY, new S57enum(14, "ferry")); Shptyp.put(ShpTYP.TYP_BOAT, new S57enum(15, "boat"));
    1020  }
    1021 
    1022  public enum CatCVR { CVR_UNKN, CVR_COVR, CVR_NCVR }
    1023  private static final EnumMap<CatCVR, S57enum> Catcvr = new EnumMap<>(CatCVR.class); static { Catcvr.put(CatCVR.CVR_UNKN, new S57enum(0, ""));
    1024  Catcvr.put(CatCVR.CVR_COVR, new S57enum(1, "coverage")); Catcvr.put(CatCVR.CVR_NCVR, new S57enum(2, "no_coverage"));
    1025  }
    1026 
    1027  private static final EnumMap<Att, S57key> keys = new EnumMap<>(Att.class);
    1028  static {
    1029   keys.put(Att.UNKATT, new S57key(Conv.A, null)); keys.put(Att.AGENCY, new S57key(Conv.A, null)); keys.put(Att.BCNSHP, new S57key(Conv.E, Bcnshp));
    1030   keys.put(Att.BUISHP, new S57key(Conv.E, Buishp)); keys.put(Att.BOYSHP, new S57key(Conv.E, Boyshp)); keys.put(Att.BURDEP, new S57key(Conv.F, null));
    1031   keys.put(Att.CALSGN, new S57key(Conv.S, null)); keys.put(Att.CATAIR, new S57key(Conv.L, Catair)); keys.put(Att.CATACH, new S57key(Conv.L, Catach));
    1032   keys.put(Att.CATBRG, new S57key(Conv.L, Catbrg)); keys.put(Att.CATBUA, new S57key(Conv.E, Catbua)); keys.put(Att.CATCBL, new S57key(Conv.E, Catcbl));
    1033   keys.put(Att.CATCAN, new S57key(Conv.E, Catcan)); keys.put(Att.CATCAM, new S57key(Conv.E, Catcam)); keys.put(Att.CATCHP, new S57key(Conv.E, Catchp));
    1034   keys.put(Att.CATCOA, new S57key(Conv.E, Catcoa)); keys.put(Att.CATCTR, new S57key(Conv.E, Catctr)); keys.put(Att.CATCON, new S57key(Conv.E, Catcon));
    1035   keys.put(Att.CATCRN, new S57key(Conv.E, Catcrn)); keys.put(Att.CATDAM, new S57key(Conv.E, Catdam)); keys.put(Att.CATDIS, new S57key(Conv.E, Catdis));
    1036   keys.put(Att.CATDOC, new S57key(Conv.E, Catdoc)); keys.put(Att.CATDPG, new S57key(Conv.L, Catdpg)); keys.put(Att.CATFNC, new S57key(Conv.E, Catfnc));
    1037   keys.put(Att.CATFRY, new S57key(Conv.E, Catfry)); keys.put(Att.CATFIF, new S57key(Conv.E, Catfif)); keys.put(Att.CATFOG, new S57key(Conv.E, Catfog));
    1038   keys.put(Att.CATFOR, new S57key(Conv.E, Catfor)); keys.put(Att.CATGAT, new S57key(Conv.E, Catgat)); keys.put(Att.CATHAF, new S57key(Conv.L, Cathaf));
    1039   keys.put(Att.CATHLK, new S57key(Conv.L, Cathlk)); keys.put(Att.CATICE, new S57key(Conv.E, Catice)); keys.put(Att.CATINB, new S57key(Conv.E, Catinb));
    1040   keys.put(Att.CATLND, new S57key(Conv.L, Catlnd)); keys.put(Att.CATLMK, new S57key(Conv.L, Catlmk)); keys.put(Att.CATLAM, new S57key(Conv.E, Catlam));
    1041   keys.put(Att.CATLIT, new S57key(Conv.L, Catlit)); keys.put(Att.CATMFA, new S57key(Conv.E, Catmfa)); keys.put(Att.CATMPA, new S57key(Conv.L, Catmpa));
    1042   keys.put(Att.CATMOR, new S57key(Conv.E, Catmor)); keys.put(Att.CATNAV, new S57key(Conv.E, Catnav)); keys.put(Att.CATOBS, new S57key(Conv.E, Catobs));
    1043   keys.put(Att.CATOFP, new S57key(Conv.L, Catofp)); keys.put(Att.CATOLB, new S57key(Conv.E, Catolb)); keys.put(Att.CATPLE, new S57key(Conv.E, Catple));
    1044   keys.put(Att.CATPIL, new S57key(Conv.E, Catpil)); keys.put(Att.CATPIP, new S57key(Conv.L, Catpip)); keys.put(Att.CATPRA, new S57key(Conv.E, Catpra));
    1045   keys.put(Att.CATPYL, new S57key(Conv.E, Catpyl)); keys.put(Att.CATRAS, new S57key(Conv.E, Catras)); keys.put(Att.CATRTB, new S57key(Conv.E, Catrtb));
    1046   keys.put(Att.CATROS, new S57key(Conv.L, Catros)); keys.put(Att.CATTRK, new S57key(Conv.E, Cattrk)); keys.put(Att.CATRSC, new S57key(Conv.L, Catrsc));
    1047   keys.put(Att.CATREA, new S57key(Conv.L, Catrea)); keys.put(Att.CATROD, new S57key(Conv.E, Catrod)); keys.put(Att.CATRUN, new S57key(Conv.E, Catrun));
    1048   keys.put(Att.CATSEA, new S57key(Conv.E, Catsea)); keys.put(Att.CATSIL, new S57key(Conv.E, Catsil)); keys.put(Att.CATSLO, new S57key(Conv.E, Catslo));
    1049   keys.put(Att.CATSCF, new S57key(Conv.L, Catscf)); keys.put(Att.CATSLC, new S57key(Conv.E, Catslc)); keys.put(Att.CATSIT, new S57key(Conv.L, Catsit));
    1050   keys.put(Att.CATSIW, new S57key(Conv.L, Catsiw)); keys.put(Att.CATSPM, new S57key(Conv.L, Catspm)); keys.put(Att.CATTSS, new S57key(Conv.E, Cattss));
    1051   keys.put(Att.CATVEG, new S57key(Conv.L, Catveg)); keys.put(Att.CATWAT, new S57key(Conv.E, Catwat)); keys.put(Att.CATWED, new S57key(Conv.E, Catwed));
    1052   keys.put(Att.CATWRK, new S57key(Conv.E, Catwrk)); keys.put(Att.COLOUR, new S57key(Conv.L, Colour));
    1053   keys.put(Att.COLPAT, new S57key(Conv.L, Colpat)); keys.put(Att.COMCHA, new S57key(Conv.A, null)); keys.put(Att.CPDATE, new S57key(Conv.A, null));
    1054   keys.put(Att.CSCALE, new S57key(Conv.I, null)); keys.put(Att.CONDTN, new S57key(Conv.E, Condtn)); keys.put(Att.CONRAD, new S57key(Conv.E, Conrad));
    1055   keys.put(Att.CONVIS, new S57key(Conv.E, Convis)); keys.put(Att.CURVEL, new S57key(Conv.F, null)); keys.put(Att.DATEND, new S57key(Conv.A, null));
    1056   keys.put(Att.DATSTA, new S57key(Conv.A, null)); keys.put(Att.DRVAL1, new S57key(Conv.F, null)); keys.put(Att.DRVAL2, new S57key(Conv.F, null));
    1057   keys.put(Att.ELEVAT, new S57key(Conv.F, null)); keys.put(Att.ESTRNG, new S57key(Conv.F, null));
    1058   keys.put(Att.EXCLIT, new S57key(Conv.E, Exclit)); keys.put(Att.EXPSOU, new S57key(Conv.E, Expsou)); keys.put(Att.FUNCTN, new S57key(Conv.L, Functn));
    1059   keys.put(Att.HEIGHT, new S57key(Conv.F, null)); keys.put(Att.HUNITS, new S57key(Conv.E, Hunits)); keys.put(Att.HORACC, new S57key(Conv.F, null));
    1060   keys.put(Att.HORCLR, new S57key(Conv.F, null)); keys.put(Att.HORLEN, new S57key(Conv.F, null)); keys.put(Att.HORWID, new S57key(Conv.F, null));
    1061   keys.put(Att.ICEFAC, new S57key(Conv.F, null)); keys.put(Att.INFORM, new S57key(Conv.S, null)); keys.put(Att.JRSDTN, new S57key(Conv.E, Jrsdtn));
    1062   keys.put(Att.LIFCAP, new S57key(Conv.F, null)); keys.put(Att.LITCHR, new S57key(Conv.E, Litchr)); keys.put(Att.LITVIS, new S57key(Conv.L, Litvis));
    1063   keys.put(Att.MARSYS, new S57key(Conv.E, Marsys)); keys.put(Att.MLTYLT, new S57key(Conv.I, null)); keys.put(Att.NATION, new S57key(Conv.A, null));
    1064   keys.put(Att.NATCON, new S57key(Conv.L, Natcon)); keys.put(Att.NATSUR, new S57key(Conv.L, Natsur)); keys.put(Att.NATQUA, new S57key(Conv.L, Natqua));
    1065   keys.put(Att.NMDATE, new S57key(Conv.A, null)); keys.put(Att.OBJNAM, new S57key(Conv.S, null)); keys.put(Att.ORIENT, new S57key(Conv.F, null));
    1066   keys.put(Att.PEREND, new S57key(Conv.A, null)); keys.put(Att.PERSTA, new S57key(Conv.A, null)); keys.put(Att.PICREP, new S57key(Conv.S, null));
    1067   keys.put(Att.PILDST, new S57key(Conv.S, null)); keys.put(Att.PRCTRY, new S57key(Conv.A, null)); keys.put(Att.PRODCT, new S57key(Conv.L, Prodct));
    1068   keys.put(Att.PUBREF, new S57key(Conv.S, null)); keys.put(Att.QUASOU, new S57key(Conv.L, Quasou)); keys.put(Att.RADWAL, new S57key(Conv.A, null));
    1069   keys.put(Att.RADIUS, new S57key(Conv.F, null));
    1070   keys.put(Att.RYRMGV, new S57key(Conv.A, null)); keys.put(Att.RESTRN, new S57key(Conv.L, Restrn));
    1071   keys.put(Att.SCAMIN, new S57key(Conv.I, null)); keys.put(Att.SCVAL1, new S57key(Conv.I, null)); keys.put(Att.SCVAL2, new S57key(Conv.I, null));
    1072   keys.put(Att.SECTR1, new S57key(Conv.F, null)); keys.put(Att.SECTR2, new S57key(Conv.F, null)); keys.put(Att.SHIPAM, new S57key(Conv.A, null));
    1073   keys.put(Att.SIGFRQ, new S57key(Conv.I, null)); keys.put(Att.SIGGEN, new S57key(Conv.E, Siggen)); keys.put(Att.SIGGRP, new S57key(Conv.A, null));
    1074   keys.put(Att.SIGPER, new S57key(Conv.F, null)); keys.put(Att.SIGSEQ, new S57key(Conv.A, null)); keys.put(Att.SOUACC, new S57key(Conv.F, null));
    1075   keys.put(Att.SDISMX, new S57key(Conv.I, null)); keys.put(Att.SDISMN, new S57key(Conv.I, null)); keys.put(Att.SORDAT, new S57key(Conv.A, null));
    1076   keys.put(Att.SORIND, new S57key(Conv.A, null)); keys.put(Att.STATUS, new S57key(Conv.L, Status)); keys.put(Att.SURATH, new S57key(Conv.S, null));
    1077   keys.put(Att.SUREND, new S57key(Conv.A, null)); keys.put(Att.SURSTA, new S57key(Conv.A, null)); keys.put(Att.SURTYP, new S57key(Conv.L, Surtyp));
    1078   keys.put(Att.TECSOU, new S57key(Conv.L, Tecsou)); keys.put(Att.TXTDSC, new S57key(Conv.S, null)); keys.put(Att.TS_TSP, new S57key(Conv.A, null));
    1079   keys.put(Att.TS_TSV, new S57key(Conv.A, null)); keys.put(Att.T_ACWL, new S57key(Conv.E, null)); keys.put(Att.T_HWLW, new S57key(Conv.A, null));
    1080   keys.put(Att.T_MTOD, new S57key(Conv.E, null)); keys.put(Att.T_THDF, new S57key(Conv.A, null)); keys.put(Att.T_TINT, new S57key(Conv.I, null));
    1081   keys.put(Att.T_TSVL, new S57key(Conv.A, null)); keys.put(Att.T_VAHC, new S57key(Conv.A, null)); keys.put(Att.TIMEND, new S57key(Conv.A, null));
    1082   keys.put(Att.TIMSTA, new S57key(Conv.A, null)); keys.put(Att.TOPSHP, new S57key(Conv.E, Topshp)); keys.put(Att.TRAFIC, new S57key(Conv.E, Trafic));
    1083   keys.put(Att.VALACM, new S57key(Conv.F, null)); keys.put(Att.VALDCO, new S57key(Conv.F, null)); keys.put(Att.VALLMA, new S57key(Conv.F, null));
    1084   keys.put(Att.VALMAG, new S57key(Conv.F, null)); keys.put(Att.VALMXR, new S57key(Conv.F, null)); keys.put(Att.VALNMR, new S57key(Conv.F, null));
    1085   keys.put(Att.VALSOU, new S57key(Conv.F, null)); keys.put(Att.VERACC, new S57key(Conv.F, null)); keys.put(Att.VERCLR, new S57key(Conv.F, null));
    1086   keys.put(Att.VERCCL, new S57key(Conv.F, null)); keys.put(Att.VERCOP, new S57key(Conv.F, null)); keys.put(Att.VERCSA, new S57key(Conv.F, null));
    1087   keys.put(Att.VERDAT, new S57key(Conv.E, Verdat)); keys.put(Att.VERLEN, new S57key(Conv.F, null)); keys.put(Att.WATLEV, new S57key(Conv.E, Watlev));
    1088   keys.put(Att.CAT_TS, new S57key(Conv.E, Cat_ts)); keys.put(Att.NINFOM, new S57key(Conv.S, null));
    1089   keys.put(Att.NOBJNM, new S57key(Conv.S, null)); keys.put(Att.NPLDST, new S57key(Conv.S, null)); keys.put(Att.NTXTDS, new S57key(Conv.S, null));
    1090   keys.put(Att.HORDAT, new S57key(Conv.E, null)); keys.put(Att.POSACC, new S57key(Conv.F, null)); keys.put(Att.QUAPOS, new S57key(Conv.E, Quapos));
    1091   keys.put(Att.CLSDNG, new S57key(Conv.E, Clsdng)); keys.put(Att.DIRIMP, new S57key(Conv.L, Dirimp)); keys.put(Att.DISBK1, new S57key(Conv.F, null));
    1092   keys.put(Att.DISBK2, new S57key(Conv.F, null)); keys.put(Att.DISIPU, new S57key(Conv.F, null)); keys.put(Att.DISIPD, new S57key(Conv.F, null));
    1093   keys.put(Att.ELEVA1, new S57key(Conv.F, null)); keys.put(Att.ELEVA2, new S57key(Conv.F, null)); keys.put(Att.FNCTNM, new S57key(Conv.E, Fnctnm));
    1094   keys.put(Att.WTWDIS, new S57key(Conv.F, null)); keys.put(Att.BUNVES, new S57key(Conv.E, Bunves)); keys.put(Att.COMCTN, new S57key(Conv.S, null));
    1095   keys.put(Att.HORCLL, new S57key(Conv.F, null)); keys.put(Att.HORCLW, new S57key(Conv.F, null)); keys.put(Att.TRSHGD, new S57key(Conv.L, Trshgd));
    1096   keys.put(Att.UNLOCD, new S57key(Conv.S, null)); keys.put(Att.HIGWAT, new S57key(Conv.F, null)); keys.put(Att.HIGNAM, new S57key(Conv.S, null));
    1097   keys.put(Att.LOWWAT, new S57key(Conv.F, null)); keys.put(Att.LOWNAM, new S57key(Conv.S, null)); keys.put(Att.MEAWAT, new S57key(Conv.F, null));
    1098   keys.put(Att.MEANAM, new S57key(Conv.S, null)); keys.put(Att.OTHWAT, new S57key(Conv.F, null)); keys.put(Att.OTHNAM, new S57key(Conv.S, null));
    1099   keys.put(Att.REFLEV, new S57key(Conv.E, Reflev)); keys.put(Att.SDRLEV, new S57key(Conv.S, null)); keys.put(Att.VCRLEV, new S57key(Conv.S, null));
    1100   keys.put(Att.SCHREF, new S57key(Conv.S, null)); keys.put(Att.USESHP, new S57key(Conv.E, Useshp)); keys.put(Att.CURVHW, new S57key(Conv.F, null));
    1101   keys.put(Att.CURVLW, new S57key(Conv.F, null)); keys.put(Att.CURVMW, new S57key(Conv.F, null)); keys.put(Att.CURVOW, new S57key(Conv.F, null));
    1102   keys.put(Att.APTREF, new S57key(Conv.S, null)); keys.put(Att.SHPTYP, new S57key(Conv.E, Shptyp)); keys.put(Att.UPDMSG, new S57key(Conv.S, null));
    1103   keys.put(Att.ADDMRK, new S57key(Conv.L, Addmrk)); keys.put(Att.BNKWTW, new S57key(Conv.E, Bnkwtw));
    1104   keys.put(Att.CATNMK, new S57key(Conv.E, Catnmk)); keys.put(Att.CATBRT, new S57key(Conv.L, Catbrt)); keys.put(Att.CATBUN, new S57key(Conv.L, Catbun));
    1105   keys.put(Att.CATCCL, new S57key(Conv.L, Catccl)); keys.put(Att.CATCOM, new S57key(Conv.L, Catcom)); keys.put(Att.CATHBR, new S57key(Conv.L, Cathbr));
    1106   keys.put(Att.CATRFD, new S57key(Conv.L, Catrfd)); keys.put(Att.CATTML, new S57key(Conv.L, Cattml)); keys.put(Att.CATGAG, new S57key(Conv.L, Catgag));
    1107   keys.put(Att.CATVTR, new S57key(Conv.L, Catvtr)); keys.put(Att.CATTAB, new S57key(Conv.E, Cattab)); keys.put(Att.CATEXS, new S57key(Conv.E, Catexs));
    1108   keys.put(Att.LG_SPD, new S57key(Conv.F, null)); keys.put(Att.LG_SPR, new S57key(Conv.L, Lg_spr)); keys.put(Att.LG_BME, new S57key(Conv.F, null));
    1109   keys.put(Att.LG_LGS, new S57key(Conv.F, null)); keys.put(Att.LG_DRT, new S57key(Conv.F, null)); keys.put(Att.LG_WDP, new S57key(Conv.F, null));
    1110   keys.put(Att.LG_WDU, new S57key(Conv.E, Lg_wdu)); keys.put(Att.LG_REL, new S57key(Conv.L, Lg_rel)); keys.put(Att.LG_FNC, new S57key(Conv.L, Lg_fnc));
    1111   keys.put(Att.LG_DES, new S57key(Conv.S, null)); keys.put(Att.LG_PBR, new S57key(Conv.S, null)); keys.put(Att.LC_CSI, new S57key(Conv.L, Lc_csi));
    1112   keys.put(Att.LC_CSE, new S57key(Conv.L, Lc_cse)); keys.put(Att.LC_ASI, new S57key(Conv.L, Lc_asi)); keys.put(Att.LC_ASE, new S57key(Conv.L, Lc_ase));
    1113   keys.put(Att.LC_CCI, new S57key(Conv.L, Lc_cci)); keys.put(Att.LC_CCE, new S57key(Conv.L, Lc_cce)); keys.put(Att.LC_BM1, new S57key(Conv.F, null));
    1114   keys.put(Att.LC_BM2, new S57key(Conv.F, null)); keys.put(Att.LC_LG1, new S57key(Conv.F, null)); keys.put(Att.LC_LG2, new S57key(Conv.F, null));
    1115   keys.put(Att.LC_DR1, new S57key(Conv.F, null)); keys.put(Att.LC_DR2, new S57key(Conv.F, null)); keys.put(Att.LC_SP1, new S57key(Conv.F, null));
    1116   keys.put(Att.LC_SP2, new S57key(Conv.F, null)); keys.put(Att.LC_WD1, new S57key(Conv.F, null)); keys.put(Att.LC_WD2, new S57key(Conv.F, null));
    1117   keys.put(Att.LITRAD, new S57key(Conv.F, null)); keys.put(Att.CATCVR, new S57key(Conv.E, Catcvr));
    1118  }
    1119  
    1120  public static Enum<?> s57Enum(String val, Att att) { // Convert S57 attribute value string to SCM enumeration
    1121   EnumMap<?, ?> map = keys.get(att).map;
    1122   Enum<?> unkn = null;
    1123   int i = 0;
    1124   try {
    1125    i = Integer.parseInt(val);
    1126   } catch (Exception e) {
    1127    return unkn;
    1128   }
    1129   if (map != null) {
    1130    for (Object item : map.keySet()) {
    1131     if (unkn == null)
    1132      unkn = (Enum<?>) item;
    1133     if (((S57enum) map.get(item)).atvl.equals(i))
    1134      return (Enum<?>) item;
    1135    }
    1136   }
    1137   return unkn;
    1138  }
    1139 
    1140  public static AttVal<?> decodeValue(String val, Att att) { // Convert S57 attribute value string to SCM attribute value
    1141   Conv conv = keys.get(att).conv;
    1142   switch (conv) {
    1143   case A:
    1144   case S:
    1145    return new AttVal<>(conv, val);
    1146   case E:
    1147    ArrayList<Enum<?>> list = new ArrayList<>();
    1148    list.add(s57Enum(val, att));
    1149    return new AttVal<ArrayList<?>>(Conv.E, list);
    1150   case L:
    1151    list = new ArrayList<>();
    1152    for (String item : val.split(",")) {
    1153     list.add(s57Enum(item, att));
    1154    }
    1155    return new AttVal<ArrayList<?>>(Conv.L, list);
    1156   case I:
    1157    try {
    1158     return new AttVal<>(Conv.I, Long.parseLong(val));
    1159    } catch (Exception e) {
    1160     break;
    1161    }
    1162   case F:
    1163    try {
    1164     return new AttVal<>(Conv.F, Double.parseDouble(val));
    1165    } catch (Exception e) {
    1166     break;
    1167    }
    1168   }
    1169   return null;
    1170  }
    1171 
    1172  public static String encodeValue(AttVal<?> attval, Att att) { // Convert SCM attribute value to S57 attribute value string
    1173           if (attval != null) {
    1174                 String str = stringValue(attval, att);
    1175                 if ((attval.conv == Conv.E) || (attval.conv == Conv.L)) {
    1176                         String[] vals = str.split(";");
    1177                         str = "";
    1178                         for (String val : vals) {
    1179                                 if (!str.isEmpty()) str += ",";
    1180                                 EnumMap<?, ?> map = keys.get(att).map;
    1181                                 for (Object item : map.keySet()) {
    1182                                         if (((S57enum)map.get(item)).val.equals(val))
    1183                         str += ((S57enum)map.get(item)).atvl.toString();
    1184                       }
    1185                         }
    1186                 }
    1187                 return str;
    1188           }
    1189   return "";
    1190  }
    1191 
    1192  public static String stringValue(AttVal<?> attval, Att att) { // Convert SCM attribute value to OSM attribute value string
    1193   if (attval != null) {
    1194    switch (attval.conv) {
    1195    case A:
    1196    case S:
    1197     return (String) attval.val;
    1198    case E:
    1199     EnumMap<?, ?> map = keys.get(att).map;
    1200     return ((S57enum) map.get(((ArrayList<?>) attval.val).get(0))).val;
    1201    case L:
    1202     String str = "";
    1203     map = keys.get(att).map;
    1204     for (Object item : (ArrayList<?>) attval.val) {
    1205      if (!str.isEmpty())
    1206       str += ";";
    1207      if (item != null)
    1208       str += ((S57enum) map.get(item)).val;
    1209     }
    1210     return str;
    1211    case I:
    1212     return ((Long) attval.val).toString();
    1213    case F:
    1214     return ((Double) attval.val).toString();
    1215    }
    1216   }
    1217   return "";
    1218  }
    1219 
    1220  public static Enum<?> osmEnum(String val, Att att) { // Convert OSM attribute value string to SCM enumeration
    1221   EnumMap<?, ?> map = keys.get(att).map;
    1222   Enum<?> unkn = null;
    1223   if (map != null) {
    1224    for (Object item : map.keySet()) {
    1225     if (unkn == null)
    1226      unkn = (Enum<?>) item;
    1227     if (((S57enum) map.get(item)).val.equals(val))
    1228      return (Enum<?>) item;
    1229    }
    1230   }
    1231   return unkn;
    1232  }
    1233 
    1234  public static AttVal<?> convertValue(String val, Att att) { // Convert OSM attribute value string to SCM attribute value
    1235   switch (keys.get(att).conv) {
    1236   case A:
    1237   case S:
    1238    return new AttVal<>(Conv.S, val);
    1239   case E:
    1240    ArrayList<Enum<?>> list = new ArrayList<>();
    1241    list.add(osmEnum(val, att));
    1242    return new AttVal<ArrayList<?>>(Conv.E, list);
    1243   case L:
    1244    list = new ArrayList<>();
    1245    for (String item : val.split(";")) {
    1246     list.add(osmEnum(item, att));
    1247    }
    1248    return new AttVal<ArrayList<?>>(Conv.L, list);
    1249   case I:
    1250    try {
    1251     return new AttVal<>(Conv.I, Long.parseLong(val));
    1252    } catch (Exception e) {
    1253     break;
    1254    }
    1255   case F:
    1256    try {
    1257     return new AttVal<>(Conv.F, Double.parseDouble(val));
    1258    } catch (Exception e) {
    1259     break;
    1260    }
    1261   }
    1262   return new AttVal<>(keys.get(att).conv, null);
    1263  }
    1264  
    1265  public static Enum<?> unknAtt(Att att) {
    1266   return (Enum<?>)(keys.get(att).map.keySet().toArray()[0]);
    1267  }
    1268 
     18    // CHECKSTYLE.OFF: LineLength
     19
     20    static class S57enum {
     21        Integer atvl;
     22        String val;
     23        S57enum(Integer a, String v) {
     24            atvl = a; val = v;
     25        }
     26    }
     27
     28    public enum Conv { S, A, L, E, F, I }
     29
     30    static class S57key {
     31        Conv conv;
     32        EnumMap<?, ?> map;
     33        S57key(Conv c, EnumMap<?, S57enum> m) {
     34            conv = c; map = m;
     35        }
     36    }
     37
     38    public static class AttVal<V> {
     39        public Conv conv;
     40        public V val;
     41        AttVal(Conv c, V v) {
     42            conv = c; val = v;
     43        }
     44    }
     45
     46    public enum BcnSHP { BCN_UNKN, BCN_STAK, BCN_WTHY, BCN_TOWR, BCN_LATT, BCN_PILE, BCN_CARN, BCN_BUOY, BCN_POLE, BCN_PRCH, BCN_POST }
     47
     48    private static final EnumMap<BcnSHP, S57enum> Bcnshp = new EnumMap<>(BcnSHP.class);
     49    static {
     50        Bcnshp.put(BcnSHP.BCN_UNKN, new S57enum(0, ""));
     51        Bcnshp.put(BcnSHP.BCN_STAK, new S57enum(1, "stake")); Bcnshp.put(BcnSHP.BCN_WTHY, new S57enum(2, "withy")); Bcnshp.put(BcnSHP.BCN_TOWR, new S57enum(3, "tower"));
     52        Bcnshp.put(BcnSHP.BCN_LATT, new S57enum(4, "lattice")); Bcnshp.put(BcnSHP.BCN_PILE, new S57enum(5, "pile")); Bcnshp.put(BcnSHP.BCN_CARN, new S57enum(6, "cairn"));
     53        Bcnshp.put(BcnSHP.BCN_BUOY, new S57enum(7, "buoyant")); Bcnshp.put(BcnSHP.BCN_POLE, new S57enum(1, "pole")); Bcnshp.put(BcnSHP.BCN_PRCH, new S57enum(1, "perch"));
     54        Bcnshp.put(BcnSHP.BCN_POST, new S57enum(1, "post"));
     55    }
     56
     57    public enum BuiSHP { BUI_UNKN, BUI_HIRS, BUI_PYRD, BUI_CYLR, BUI_SPHR, BUI_CUBE }
     58
     59    private static final EnumMap<BuiSHP, S57enum> Buishp = new EnumMap<>(BuiSHP.class);
     60    static {
     61        Buishp.put(BuiSHP.BUI_UNKN, new S57enum(0, ""));
     62        Buishp.put(BuiSHP.BUI_HIRS, new S57enum(5, "high-rise")); Buishp.put(BuiSHP.BUI_PYRD, new S57enum(6, "pyramid")); Buishp.put(BuiSHP.BUI_CYLR, new S57enum(7, "cylindrical"));
     63        Buishp.put(BuiSHP.BUI_SPHR, new S57enum(8, "spherical")); Buishp.put(BuiSHP.BUI_CUBE, new S57enum(9, "cubic"));
     64    }
     65
     66    public enum BoySHP { BOY_UNKN, BOY_CONE, BOY_CAN, BOY_SPHR, BOY_PILR, BOY_SPAR, BOY_BARL, BOY_SUPR, BOY_ICE }
     67
     68    private static final EnumMap<BoySHP, S57enum> Boyshp = new EnumMap<>(BoySHP.class);
     69    static {
     70        Boyshp.put(BoySHP.BOY_UNKN, new S57enum(0, ""));
     71        Boyshp.put(BoySHP.BOY_CONE, new S57enum(1, "conical")); Boyshp.put(BoySHP.BOY_CAN, new S57enum(2, "can")); Boyshp.put(BoySHP.BOY_SPHR, new S57enum(3, "spherical"));
     72        Boyshp.put(BoySHP.BOY_PILR, new S57enum(4, "pillar")); Boyshp.put(BoySHP.BOY_SPAR, new S57enum(5, "spar")); Boyshp.put(BoySHP.BOY_BARL, new S57enum(6, "barrel"));
     73        Boyshp.put(BoySHP.BOY_SUPR, new S57enum(7, "super-buoy")); Boyshp.put(BoySHP.BOY_ICE, new S57enum(8, "ice_buoy"));
     74    }
     75
     76    public enum CatAIR { AIR_UNKN, AIR_MILA, AIR_CIVA, AIR_MILH, AIR_CIVH, AIR_GLDR, AIR_SMLP, AIR_EMRG }
     77
     78    private static final EnumMap<CatAIR, S57enum> Catair = new EnumMap<>(CatAIR.class);
     79    static {
     80        Catair.put(CatAIR.AIR_UNKN, new S57enum(0, ""));
     81        Catair.put(CatAIR.AIR_MILA, new S57enum(1, "military")); Catair.put(CatAIR.AIR_CIVA, new S57enum(2, "civil")); Catair.put(CatAIR.AIR_MILH, new S57enum(3, "military_heliport"));
     82        Catair.put(CatAIR.AIR_CIVH, new S57enum(4, "civil_heliport")); Catair.put(CatAIR.AIR_GLDR, new S57enum(5, "glider")); Catair.put(CatAIR.AIR_SMLP, new S57enum(6, "small_planes"));
     83        Catair.put(CatAIR.AIR_EMRG, new S57enum(8, "emergency"));
     84    }
     85
     86    public enum CatACH { ACH_UNKN, ACH_UNRD, ACH_DEEP, ACH_TANK, ACH_EXPL, ACH_QUAR, ACH_SEAP, ACH_SMCF, ACH_SMCM, ACH_H24P, ACH_LTPD, ACH_NPSH, ACH_DRYC, ACH_RAFT, ACH_WAIT, ACH_REPT }
     87
     88    private static final EnumMap<CatACH, S57enum> Catach = new EnumMap<>(CatACH.class);
     89    static {
     90        Catach.put(CatACH.ACH_UNKN, new S57enum(0, ""));
     91        Catach.put(CatACH.ACH_UNRD, new S57enum(1, "unrestricted")); Catach.put(CatACH.ACH_DEEP, new S57enum(2, "deep_water")); Catach.put(CatACH.ACH_TANK, new S57enum(3, "tanker"));
     92        Catach.put(CatACH.ACH_EXPL, new S57enum(4, "explosives")); Catach.put(CatACH.ACH_QUAR, new S57enum(5, "quarantine")); Catach.put(CatACH.ACH_SEAP, new S57enum(6, "seaplane"));
     93        Catach.put(CatACH.ACH_SMCF, new S57enum(7, "small_craft")); Catach.put(CatACH.ACH_SMCM, new S57enum(8, "small_craft_mooring")); Catach.put(CatACH.ACH_H24P, new S57enum(9, "24_hour"));
     94        Catach.put(CatACH.ACH_LTPD, new S57enum(10, "limited_period")); Catach.put(CatACH.ACH_NPSH, new S57enum(11, "non_pushing")); Catach.put(CatACH.ACH_DRYC, new S57enum(12, "dry_cargo"));
     95        Catach.put(CatACH.ACH_RAFT, new S57enum(13, "raft")); Catach.put(CatACH.ACH_WAIT, new S57enum(14, "waiting")); Catach.put(CatACH.ACH_REPT, new S57enum(15, "reported"));
     96    }
     97
     98    public enum CatBRG { BRG_UNKN, BRG_FIXD, BRG_OPEN, BRG_SWNG, BRG_LIFT, BRG_BASC, BRG_PONT, BRG_DRAW, BRG_TRNS, BRG_FOOT, BRG_VIAD, BRG_AQUA, BRG_SUSP }
     99
     100    private static final EnumMap<CatBRG, S57enum> Catbrg = new EnumMap<>(CatBRG.class); static {
     101        Catbrg.put(CatBRG.BRG_UNKN, new S57enum(0, ""));
     102        Catbrg.put(CatBRG.BRG_FIXD, new S57enum(1, "fixed")); Catbrg.put(CatBRG.BRG_OPEN, new S57enum(2, "opening")); Catbrg.put(CatBRG.BRG_SWNG, new S57enum(3, "swing"));
     103        Catbrg.put(CatBRG.BRG_LIFT, new S57enum(4, "lifting")); Catbrg.put(CatBRG.BRG_BASC, new S57enum(5, "bascule")); Catbrg.put(CatBRG.BRG_PONT, new S57enum(6, "pontoon"));
     104        Catbrg.put(CatBRG.BRG_DRAW, new S57enum(7, "drawbridge")); Catbrg.put(CatBRG.BRG_TRNS, new S57enum(8, "transporter")); Catbrg.put(CatBRG.BRG_FOOT, new S57enum(9, "footbridge"));
     105        Catbrg.put(CatBRG.BRG_VIAD, new S57enum(10, "viaduct")); Catbrg.put(CatBRG.BRG_AQUA, new S57enum(11, "aqueduct")); Catbrg.put(CatBRG.BRG_SUSP, new S57enum(12, "suspension"));
     106    }
     107
     108    public enum CatBUA { BUA_UNKN, BUA_URBN, BUA_STTL, BUA_VLLG, BUA_TOWN, BUA_CITY, BUA_HOLV }
     109
     110    private static final EnumMap<CatBUA, S57enum> Catbua = new EnumMap<>(CatBUA.class); static {
     111        Catbua.put(CatBUA.BUA_UNKN, new S57enum(0, ""));
     112        Catbua.put(CatBUA.BUA_URBN, new S57enum(1, "urban")); Catbua.put(CatBUA.BUA_STTL, new S57enum(2, "settlement")); Catbua.put(CatBUA.BUA_VLLG, new S57enum(3, "village"));
     113        Catbua.put(CatBUA.BUA_TOWN, new S57enum(4, "town")); Catbua.put(CatBUA.BUA_CITY, new S57enum(5, "city")); Catbua.put(CatBUA.BUA_HOLV, new S57enum(6, "holiday_village"));
     114    }
     115
     116    public enum CatCBL { CBL_UNKN, CBL_POWR, CBL_TRNS, CBL_TELE, CBL_TGPH, CBL_MOOR, CBL_OPTC, CBL_FERY }
     117
     118    private static final EnumMap<CatCBL, S57enum> Catcbl = new EnumMap<>(CatCBL.class); static {
     119        Catcbl.put(CatCBL.CBL_UNKN, new S57enum(0, ""));
     120        Catcbl.put(CatCBL.CBL_POWR, new S57enum(1, "power")); Catcbl.put(CatCBL.CBL_TRNS, new S57enum(3, "transmission")); Catcbl.put(CatCBL.CBL_TELE, new S57enum(4, "telephone"));
     121        Catcbl.put(CatCBL.CBL_TGPH, new S57enum(5, "telegraph")); Catcbl.put(CatCBL.CBL_MOOR, new S57enum(6, "mooring")); Catcbl.put(CatCBL.CBL_OPTC, new S57enum(7, "optical"));
     122        Catcbl.put(CatCBL.CBL_FERY, new S57enum(8, "ferry"));
     123    }
     124
     125    public enum CatCAN { CAN_UNKN, CAN_TRNS, CAN_DRNG, CAN_IRGN }
     126
     127    private static final EnumMap<CatCAN, S57enum> Catcan = new EnumMap<>(CatCAN.class); static {
     128        Catcan.put(CatCAN.CAN_UNKN, new S57enum(0, ""));
     129        Catcan.put(CatCAN.CAN_TRNS, new S57enum(1, "transportation")); Catcan.put(CatCAN.CAN_DRNG, new S57enum(2, "drainage")); Catcan.put(CatCAN.CAN_IRGN, new S57enum(3, "irrigation"));
     130    }
     131
     132    public enum CatCAM { CAM_UNKN, CAM_NORTH, CAM_EAST, CAM_SOUTH, CAM_WEST }
     133
     134    private static final EnumMap<CatCAM, S57enum> Catcam = new EnumMap<>(CatCAM.class); static {
     135        Catcam.put(CatCAM.CAM_UNKN, new S57enum(0, ""));
     136        Catcam.put(CatCAM.CAM_NORTH, new S57enum(1, "north")); Catcam.put(CatCAM.CAM_EAST, new S57enum(2, "east"));
     137        Catcam.put(CatCAM.CAM_SOUTH, new S57enum(3, "south")); Catcam.put(CatCAM.CAM_WEST, new S57enum(4, "west"));
     138    }
     139
     140    public enum CatCHP { CHP_UNKN, CHP_CSTM, CHP_BRDR }
     141
     142    private static final EnumMap<CatCHP, S57enum> Catchp = new EnumMap<>(CatCHP.class); static {
     143        Catchp.put(CatCHP.CHP_UNKN, new S57enum(0, ""));
     144        Catchp.put(CatCHP.CHP_CSTM, new S57enum(1, "customs")); Catchp.put(CatCHP.CHP_BRDR, new S57enum(2, "border"));
     145    }
     146
     147    public enum CatCOA { COA_UNKN, COA_STEP, COA_FLAT, COA_SAND, COA_STON, COA_SHNG, COA_GLCR, COA_MNGV, COA_MRSH, COA_CRRF, COA_ICE, COA_SHEL }
     148
     149    private static final EnumMap<CatCOA, S57enum> Catcoa = new EnumMap<>(CatCOA.class); static {
     150        Catcoa.put(CatCOA.COA_UNKN, new S57enum(0, ""));
     151        Catcoa.put(CatCOA.COA_STEP, new S57enum(1, "steep")); Catcoa.put(CatCOA.COA_FLAT, new S57enum(2, "flat")); Catcoa.put(CatCOA.COA_SAND, new S57enum(3, "sandy"));
     152        Catcoa.put(CatCOA.COA_STON, new S57enum(4, "stony")); Catcoa.put(CatCOA.COA_SHNG, new S57enum(5, "shingly")); Catcoa.put(CatCOA.COA_GLCR, new S57enum(6, "glacier"));
     153        Catcoa.put(CatCOA.COA_MNGV, new S57enum(7, "mangrove")); Catcoa.put(CatCOA.COA_MRSH, new S57enum(8, "marshy")); Catcoa.put(CatCOA.COA_CRRF, new S57enum(9, "coral_reef"));
     154        Catcoa.put(CatCOA.COA_ICE, new S57enum(10, "ice")); Catcoa.put(CatCOA.COA_SHEL, new S57enum(11, "shelly"));
     155    }
     156
     157    public enum CatCTR { CTR_UNKN, CTR_TRGN, CTR_OBSV, CTR_FIXD, CTR_BMRK, CTR_BDRY, CTR_HORM, CTR_HORS }
     158
     159    private static final EnumMap<CatCTR, S57enum> Catctr = new EnumMap<>(CatCTR.class); static {
     160        Catctr.put(CatCTR.CTR_UNKN, new S57enum(0, ""));
     161        Catctr.put(CatCTR.CTR_TRGN, new S57enum(1, "triangulation")); Catctr.put(CatCTR.CTR_OBSV, new S57enum(2, "observation")); Catctr.put(CatCTR.CTR_FIXD, new S57enum(3, "fixed"));
     162        Catctr.put(CatCTR.CTR_BMRK, new S57enum(4, "benchmark")); Catctr.put(CatCTR.CTR_BDRY, new S57enum(5, "boundary")); Catctr.put(CatCTR.CTR_HORM, new S57enum(6, "horizontal_main"));
     163        Catctr.put(CatCTR.CTR_HORS, new S57enum(7, "horizontal_secondary"));
     164    }
     165
     166    public enum CatCON { CON_UNKN, CAT_AERL, CAT_BELT }
     167
     168    private static final EnumMap<CatCON, S57enum> Catcon = new EnumMap<>(CatCON.class); static {
     169        Catcon.put(CatCON.CON_UNKN, new S57enum(0, ""));
     170        Catcon.put(CatCON.CAT_AERL, new S57enum(1, "aerial")); Catcon.put(CatCON.CAT_BELT, new S57enum(2, "belt"));
     171    }
     172
     173    public enum CatCRN { CRN_UNKN, CRN_NONS, CRN_CONT, CRN_SHRL, CRN_TRAV, CRN_AFRM, CRN_GLTH }
     174
     175    private static final EnumMap<CatCRN, S57enum> Catcrn = new EnumMap<>(CatCRN.class); static {
     176        Catcrn.put(CatCRN.CRN_UNKN, new S57enum(0, ""));
     177        Catcrn.put(CatCRN.CRN_NONS, new S57enum(1, "non-specific")); Catcrn.put(CatCRN.CRN_CONT, new S57enum(2, "container")); Catcrn.put(CatCRN.CRN_SHRL, new S57enum(3, "sheerlegs"));
     178        Catcrn.put(CatCRN.CRN_TRAV, new S57enum(4, "travelling")); Catcrn.put(CatCRN.CRN_AFRM, new S57enum(5, "a-frame")); Catcrn.put(CatCRN.CRN_GLTH, new S57enum(6, "goliath"));
     179    }
     180
     181    public enum CatDAM { DAM_UNKN, DAM_WEIR, DAM_DAM, DAM_FLDB }
     182
     183    private static final EnumMap<CatDAM, S57enum> Catdam = new EnumMap<>(CatDAM.class); static {
     184        Catdam.put(CatDAM.DAM_UNKN, new S57enum(0, ""));
     185        Catdam.put(CatDAM.DAM_WEIR, new S57enum(1, "weir")); Catdam.put(CatDAM.DAM_DAM, new S57enum(2, "dam")); Catdam.put(CatDAM.DAM_FLDB, new S57enum(3, "flood_barrage"));
     186    }
     187
     188    public enum CatDIS { DIS_UNKN, DIS_NONI, DIS_POLE, DIS_BORD, DIS_UKSH }
     189
     190    private static final EnumMap<CatDIS, S57enum> Catdis = new EnumMap<>(CatDIS.class); static {
     191        Catdis.put(CatDIS.DIS_UNKN, new S57enum(0, ""));
     192        Catdis.put(CatDIS.DIS_NONI, new S57enum(1, "not_installed")); Catdis.put(CatDIS.DIS_POLE, new S57enum(2, "pole")); Catdis.put(CatDIS.DIS_BORD, new S57enum(3, "board"));
     193        Catdis.put(CatDIS.DIS_UKSH, new S57enum(4, "unknown_shape"));
     194    }
     195
     196    public enum CatDOC { DOC_UNKN, DOC_TIDL, DOC_NTDL }
     197
     198    private static final EnumMap<CatDOC, S57enum> Catdoc = new EnumMap<>(CatDOC.class); static {
     199        Catdoc.put(CatDOC.DOC_UNKN, new S57enum(0, ""));
     200        Catdoc.put(CatDOC.DOC_TIDL, new S57enum(1, "tidal")); Catdoc.put(CatDOC.DOC_NTDL, new S57enum(2, "non-tidal"));
     201    }
     202
     203    public enum CatDPG { DPG_UNKN, DPG_GENL, DPG_CHEM, DPG_NCLR, DPG_EXPL, DPG_SPIL, DPG_VSSL }
     204
     205    private static final EnumMap<CatDPG, S57enum> Catdpg = new EnumMap<>(CatDPG.class); static {
     206        Catdpg.put(CatDPG.DPG_UNKN, new S57enum(0, ""));
     207        Catdpg.put(CatDPG.DPG_GENL, new S57enum(1, "general")); Catdpg.put(CatDPG.DPG_CHEM, new S57enum(2, "chemical")); Catdpg.put(CatDPG.DPG_NCLR, new S57enum(3, "nuclear"));
     208        Catdpg.put(CatDPG.DPG_EXPL, new S57enum(4, "explosives")); Catdpg.put(CatDPG.DPG_SPIL, new S57enum(5, "spoil")); Catdpg.put(CatDPG.DPG_VSSL, new S57enum(6, "vessel"));
     209    }
     210
     211    public enum CatFNC { FNC_UNKN, FNC_FENC, FNC_MUIR, FNC_HEDG, FNC_WALL }
     212
     213    private static final EnumMap<CatFNC, S57enum> Catfnc = new EnumMap<>(CatFNC.class); static {
     214        Catfnc.put(CatFNC.FNC_UNKN, new S57enum(0, ""));
     215        Catfnc.put(CatFNC.FNC_FENC, new S57enum(1, "fence")); Catfnc.put(CatFNC.FNC_MUIR, new S57enum(2, "muir")); Catfnc.put(CatFNC.FNC_HEDG, new S57enum(3, "hedge"));
     216        Catfnc.put(CatFNC.FNC_WALL, new S57enum(4, "wall"));
     217    }
     218
     219    public enum CatFRY { FRY_UNKN, FRY_FREE, FRY_CABL, FRY_ICE, FRY_SWWR }
     220
     221    private static final EnumMap<CatFRY, S57enum> Catfry = new EnumMap<>(CatFRY.class); static {
     222        Catfry.put(CatFRY.FRY_UNKN, new S57enum(0, ""));
     223        Catfry.put(CatFRY.FRY_FREE, new S57enum(1, "free")); Catfry.put(CatFRY.FRY_CABL, new S57enum(2, "cable")); Catfry.put(CatFRY.FRY_ICE, new S57enum(3, "ice"));
     224        Catfry.put(CatFRY.FRY_SWWR, new S57enum(4, "swinging_wire"));
     225    }
     226
     227    public enum CatFIF { FIF_UNKN, FIF_STAK, FIF_TRAP, FIF_WEIR, FIF_TUNY }
     228
     229    private static final EnumMap<CatFIF, S57enum> Catfif = new EnumMap<>(CatFIF.class); static {
     230        Catfif.put(CatFIF.FIF_UNKN, new S57enum(0, ""));
     231        Catfif.put(CatFIF.FIF_STAK, new S57enum(1, "stake")); Catfif.put(CatFIF.FIF_TRAP, new S57enum(2, "trap")); Catfif.put(CatFIF.FIF_WEIR, new S57enum(3, "weir"));
     232        Catfif.put(CatFIF.FIF_TUNY, new S57enum(4, "tunny"));
     233    }
     234
     235    public enum CatFOG { FOG_UNKN, FOG_EXPL, FOG_DIA, FOG_SIRN, FOG_NAUT, FOG_REED, FOG_TYPH, FOG_BELL, FOG_WHIS, FOG_GONG, FOG_HORN }
     236
     237    private static final EnumMap<CatFOG, S57enum> Catfog = new EnumMap<>(CatFOG.class); static {
     238        Catfog.put(CatFOG.FOG_UNKN, new S57enum(0, ""));
     239        Catfog.put(CatFOG.FOG_EXPL, new S57enum(1, "explosive")); Catfog.put(CatFOG.FOG_DIA, new S57enum(2, "diaphone")); Catfog.put(CatFOG.FOG_SIRN, new S57enum(3, "siren"));
     240        Catfog.put(CatFOG.FOG_NAUT, new S57enum(4, "nautophone")); Catfog.put(CatFOG.FOG_REED, new S57enum(5, "reed"));
     241        Catfog.put(CatFOG.FOG_TYPH, new S57enum(6, "tyfon")); Catfog.put(CatFOG.FOG_BELL, new S57enum(7, "bell")); Catfog.put(CatFOG.FOG_WHIS, new S57enum(8, "whistle"));
     242        Catfog.put(CatFOG.FOG_GONG, new S57enum(9, "gong")); Catfog.put(CatFOG.FOG_HORN, new S57enum(10, "horn"));
     243    }
     244
     245    public enum CatFOR { FOR_UNKN, FOR_CSTL, FOR_FORT, FOR_BTTY, FOR_BKHS, FOR_MTWR, FOR_RDBT }
     246
     247    private static final EnumMap<CatFOR, S57enum> Catfor = new EnumMap<>(CatFOR.class); static {
     248        Catfor.put(CatFOR.FOR_UNKN, new S57enum(0, ""));
     249        Catfor.put(CatFOR.FOR_CSTL, new S57enum(1, "castle")); Catfor.put(CatFOR.FOR_FORT, new S57enum(2, "fort")); Catfor.put(CatFOR.FOR_BTTY, new S57enum(3, "battery"));
     250        Catfor.put(CatFOR.FOR_BKHS, new S57enum(4, "blockhouse")); Catfor.put(CatFOR.FOR_MTWR, new S57enum(5, "martello_tower")); Catfor.put(CatFOR.FOR_RDBT, new S57enum(6, "redoubt"));
     251    }
     252
     253    public enum CatGAT { GAT_UNKN, GAT_GNRL, GAT_FLBG, GAT_CSSN, GAT_LOCK, GAT_DYKE, GAT_SLUC }
     254
     255    private static final EnumMap<CatGAT, S57enum> Catgat = new EnumMap<>(CatGAT.class); static {
     256        Catgat.put(CatGAT.GAT_UNKN, new S57enum(0, ""));
     257        Catgat.put(CatGAT.GAT_GNRL, new S57enum(1, "general")); Catgat.put(CatGAT.GAT_FLBG, new S57enum(2, "flood_barrage")); Catgat.put(CatGAT.GAT_CSSN, new S57enum(3, "caisson"));
     258        Catgat.put(CatGAT.GAT_LOCK, new S57enum(4, "lock")); Catgat.put(CatGAT.GAT_DYKE, new S57enum(5, "dyke")); Catgat.put(CatGAT.GAT_SLUC, new S57enum(6, "sluice"));
     259    }
     260
     261    public enum CatHAF { HAF_UNKN, HAF_RORO, HAF_TMBR, HAF_FERY, HAF_FISH, HAF_MRNA, HAF_NAVL, HAF_TNKR, HAF_PSGR, HAF_YARD, HAF_CNTR, HAF_BULK, HAF_SYNC, HAF_STCR, HAF_LUVB,
     262        HAF_REPR, HAF_QUAR, HAF_SPLN, HAF_CARG, HAF_OFFS, HAF_SSUP, HAF_MANF }
     263
     264    private static final EnumMap<CatHAF, S57enum> Cathaf = new EnumMap<>(CatHAF.class); static {
     265        Cathaf.put(CatHAF.HAF_UNKN, new S57enum(0, ""));
     266        Cathaf.put(CatHAF.HAF_RORO, new S57enum(1, "roro")); Cathaf.put(CatHAF.HAF_FERY, new S57enum(3, "ferry")); Cathaf.put(CatHAF.HAF_FISH, new S57enum(4, "fishing"));
     267        Cathaf.put(CatHAF.HAF_MRNA, new S57enum(5, "marina")); Cathaf.put(CatHAF.HAF_NAVL, new S57enum(6, "naval")); Cathaf.put(CatHAF.HAF_TNKR, new S57enum(7, "tanker"));
     268        Cathaf.put(CatHAF.HAF_PSGR, new S57enum(8, "passenger")); Cathaf.put(CatHAF.HAF_YARD, new S57enum(9, "shipyard")); Cathaf.put(CatHAF.HAF_CNTR, new S57enum(10, "container"));
     269        Cathaf.put(CatHAF.HAF_BULK, new S57enum(11, "bulk")); Cathaf.put(CatHAF.HAF_SYNC, new S57enum(12, "syncrolift")); Cathaf.put(CatHAF.HAF_STCR, new S57enum(13, "straddle_carrier"));
     270        Cathaf.put(CatHAF.HAF_LUVB, new S57enum(14, "lay_up")); Cathaf.put(CatHAF.HAF_TMBR, new S57enum(15, "timber")); Cathaf.put(CatHAF.HAF_REPR, new S57enum(16, "service_repair"));
     271        Cathaf.put(CatHAF.HAF_QUAR, new S57enum(17, "quarantine")); Cathaf.put(CatHAF.HAF_SPLN, new S57enum(18, "seaplane")); Cathaf.put(CatHAF.HAF_CARG, new S57enum(19, "cargo"));
     272        Cathaf.put(CatHAF.HAF_OFFS, new S57enum(20, "offshore_support")); Cathaf.put(CatHAF.HAF_OFFS, new S57enum(21, "port_support_base"));
     273        Cathaf.put(CatHAF.HAF_MANF, new S57enum(22, "marina_no_facilities"));
     274    }
     275
     276    public enum CatHLK { HLK_UNKN, HLK_REST, HLK_HIST, HLK_MUSM, HLK_ACCM, HLK_BWTR, HLK_CSNO }
     277
     278    private static final EnumMap<CatHLK, S57enum> Cathlk = new EnumMap<>(CatHLK.class); static {
     279        Cathlk.put(CatHLK.HLK_UNKN, new S57enum(0, ""));
     280        Cathlk.put(CatHLK.HLK_REST, new S57enum(1, "floating_restaurant")); Cathlk.put(CatHLK.HLK_HIST, new S57enum(2, "historic")); Cathlk.put(CatHLK.HLK_MUSM, new S57enum(3, "museum"));
     281        Cathlk.put(CatHLK.HLK_ACCM, new S57enum(4, "accommodation")); Cathlk.put(CatHLK.HLK_BWTR, new S57enum(5, "floating_breakwater")); Cathlk.put(CatHLK.HLK_CSNO, new S57enum(6, "casino_boat"));
     282    }
     283
     284    public enum CatICE { ICE_UNKN, ICE_FAST, ICE_SEA, ICE_GRLR, ICE_PANK, ICE_GLAS, ICE_PEAK, ICE_PACK, ICE_POLR }
     285
     286    private static final EnumMap<CatICE, S57enum> Catice = new EnumMap<>(CatICE.class); static {
     287        Catice.put(CatICE.ICE_UNKN, new S57enum(0, ""));
     288        Catice.put(CatICE.ICE_FAST, new S57enum(1, "fast")); Catice.put(CatICE.ICE_SEA, new S57enum(2, "sea")); Catice.put(CatICE.ICE_GRLR, new S57enum(3, "growler"));
     289        Catice.put(CatICE.ICE_PANK, new S57enum(4, "pancake")); Catice.put(CatICE.ICE_GLAS, new S57enum(5, "glacier")); Catice.put(CatICE.ICE_PEAK, new S57enum(6, "peak"));
     290        Catice.put(CatICE.ICE_PACK, new S57enum(7, "pack")); Catice.put(CatICE.ICE_POLR, new S57enum(8, "polar"));
     291    }
     292
     293    public enum CatINB { INB_UNKN, INB_CALM, INB_SBM }
     294
     295    private static final EnumMap<CatINB, S57enum> Catinb = new EnumMap<>(CatINB.class); static {
     296        Catinb.put(CatINB.INB_UNKN, new S57enum(0, "")); Catinb.put(CatINB.INB_CALM, new S57enum(1, "calm")); Catinb.put(CatINB.INB_SBM, new S57enum(2, "sbm"));
     297    }
     298
     299    public enum CatLND { LND_UNKN, LND_FEN, LND_MRSH, LND_BOG, LND_HTHL, LND_MNTN, LND_LOWL, LND_CNYN, LND_PDDY, LND_AGRI, LND_SVNA, LND_PARK, LND_SWMP, LND_LSLD, LND_LAVA,
     300        LND_SLTP, LND_MORN, LND_CRTR, LND_CAVE, LND_PINCL, LND_CAY }
     301
     302    private static final EnumMap<CatLND, S57enum> Catlnd = new EnumMap<>(CatLND.class); static {
     303        Catlnd.put(CatLND.LND_UNKN, new S57enum(0, ""));
     304        Catlnd.put(CatLND.LND_FEN, new S57enum(1, "fen")); Catlnd.put(CatLND.LND_MRSH, new S57enum(2, "marsh")); Catlnd.put(CatLND.LND_BOG, new S57enum(3, "bog"));
     305        Catlnd.put(CatLND.LND_HTHL, new S57enum(4, "heathland")); Catlnd.put(CatLND.LND_MNTN, new S57enum(5, "mountain")); Catlnd.put(CatLND.LND_LOWL, new S57enum(6, "lowlands"));
     306        Catlnd.put(CatLND.LND_CNYN, new S57enum(7, "canyon")); Catlnd.put(CatLND.LND_PDDY, new S57enum(8, "paddy")); Catlnd.put(CatLND.LND_AGRI, new S57enum(9, "agricultural"));
     307        Catlnd.put(CatLND.LND_SVNA, new S57enum(10, "savanna")); Catlnd.put(CatLND.LND_PARK, new S57enum(11, "parkland")); Catlnd.put(CatLND.LND_SWMP, new S57enum(12, "swamp"));
     308        Catlnd.put(CatLND.LND_LSLD, new S57enum(13, "landslide")); Catlnd.put(CatLND.LND_LAVA, new S57enum(14, "lava")); Catlnd.put(CatLND.LND_SLTP, new S57enum(15, "salt_pan"));
     309        Catlnd.put(CatLND.LND_MORN, new S57enum(16, "moraine")); Catlnd.put(CatLND.LND_CRTR, new S57enum(17, "crater")); Catlnd.put(CatLND.LND_CAVE, new S57enum(18, "cave"));
     310        Catlnd.put(CatLND.LND_PINCL, new S57enum(19, "rock_pinnacle")); Catlnd.put(CatLND.LND_CAY, new S57enum(20, "cay"));
     311    }
     312
     313    public enum CatLMK { LMK_UNKN, LMK_CARN, LMK_CMTY, LMK_CHMY, LMK_DISH, LMK_FLAG, LMK_FLAR, LMK_MAST, LMK_WNDS, LMK_MNMT, LMK_CLMN, LMK_MEML, LMK_OBLK, LMK_STAT, LMK_CROS,
     314        LMK_DOME, LMK_RADR, LMK_TOWR, LMK_WNDM, LMK_WNDG, LMK_SPIR, LMK_BLDR, LMK_TRIM, LMK_BNDM, LMK_OBSW, LMK_TORL }
     315
     316    private static final EnumMap<CatLMK, S57enum> Catlmk = new EnumMap<>(CatLMK.class); static {
     317        Catlmk.put(CatLMK.LMK_UNKN, new S57enum(0, ""));
     318        Catlmk.put(CatLMK.LMK_CARN, new S57enum(1, "cairn")); Catlmk.put(CatLMK.LMK_CMTY, new S57enum(2, "cemetery")); Catlmk.put(CatLMK.LMK_CHMY, new S57enum(3, "chimney"));
     319        Catlmk.put(CatLMK.LMK_DISH, new S57enum(4, "dish_aerial")); Catlmk.put(CatLMK.LMK_FLAG, new S57enum(5, "flagstaff")); Catlmk.put(CatLMK.LMK_FLAR, new S57enum(6, "flare_stack"));
     320        Catlmk.put(CatLMK.LMK_MAST, new S57enum(7, "mast")); Catlmk.put(CatLMK.LMK_WNDS, new S57enum(8, "windsock")); Catlmk.put(CatLMK.LMK_MNMT, new S57enum(9, "monument"));
     321        Catlmk.put(CatLMK.LMK_CLMN, new S57enum(10, "column")); Catlmk.put(CatLMK.LMK_MEML, new S57enum(11, "memorial")); Catlmk.put(CatLMK.LMK_OBLK, new S57enum(12, "obelisk"));
     322        Catlmk.put(CatLMK.LMK_STAT, new S57enum(13, "statue")); Catlmk.put(CatLMK.LMK_CROS, new S57enum(14, "cross")); Catlmk.put(CatLMK.LMK_DOME, new S57enum(15, "dome"));
     323        Catlmk.put(CatLMK.LMK_RADR, new S57enum(16, "radar_scanner")); Catlmk.put(CatLMK.LMK_TOWR, new S57enum(17, "tower")); Catlmk.put(CatLMK.LMK_WNDM, new S57enum(18, "windmill"));
     324        Catlmk.put(CatLMK.LMK_WNDG, new S57enum(19, "windmotor")); Catlmk.put(CatLMK.LMK_SPIR, new S57enum(20, "spire")); Catlmk.put(CatLMK.LMK_BLDR, new S57enum(21, "boulder"));
     325        Catlmk.put(CatLMK.LMK_TRIM, new S57enum(22, "triangulation_mark")); Catlmk.put(CatLMK.LMK_BNDM, new S57enum(23, "boundary_mark"));
     326        Catlmk.put(CatLMK.LMK_OBSW, new S57enum(24, "observation_wheel")); Catlmk.put(CatLMK.LMK_TORL, new S57enum(25, "toril"));
     327    }
     328
     329    public enum CatLAM { LAM_UNKN, LAM_PORT, LAM_STBD, LAM_PCST, LAM_PCPT, LAM_WWLT, LAM_WWRT, LAM_CHLT, LAM_CHRT, LAM_WWSN, LAM_CHSN, LAM_CHRB, LAM_CHLB, LAM_CRRT, LAM_CRLT,
     330        LAM_DRLT, LAM_DRRT, LAM_TOLT, LAM_TPRT, LAM_JBRT, LAM_JNLT, LAM_HBRT, LAM_HBLT, LAM_BRGP }
     331
     332    private static final EnumMap<CatLAM, S57enum> Catlam = new EnumMap<>(CatLAM.class); static {
     333        Catlam.put(CatLAM.LAM_UNKN, new S57enum(0, ""));
     334        Catlam.put(CatLAM.LAM_PORT, new S57enum(1, "port")); Catlam.put(CatLAM.LAM_STBD, new S57enum(2, "starboard")); Catlam.put(CatLAM.LAM_PCST, new S57enum(3, "preferred_channel_starboard"));
     335        Catlam.put(CatLAM.LAM_PCPT, new S57enum(4, "preferred_channel_port")); Catlam.put(CatLAM.LAM_WWRT, new S57enum(5, "waterway_right")); Catlam.put(CatLAM.LAM_WWLT, new S57enum(6, "waterway_left"));
     336        Catlam.put(CatLAM.LAM_CHRT, new S57enum(7, "channel_right")); Catlam.put(CatLAM.LAM_CHLT, new S57enum(8, "channel_left")); Catlam.put(CatLAM.LAM_WWSN, new S57enum(9, "waterway_separation"));
     337        Catlam.put(CatLAM.LAM_CHSN, new S57enum(10, "channel_separation")); Catlam.put(CatLAM.LAM_CHRB, new S57enum(11, "channel_right_bank")); Catlam.put(CatLAM.LAM_CHLB, new S57enum(12, "channel_left_bank"));
     338        Catlam.put(CatLAM.LAM_CRRT, new S57enum(13, "crossover_right")); Catlam.put(CatLAM.LAM_CRLT, new S57enum(14, "crossover_left")); Catlam.put(CatLAM.LAM_DRLT, new S57enum(15, "danger_right"));
     339        Catlam.put(CatLAM.LAM_DRRT, new S57enum(16, "danger_left")); Catlam.put(CatLAM.LAM_TOLT, new S57enum(17, "turnoff_right")); Catlam.put(CatLAM.LAM_TPRT, new S57enum(18, "turnoff_left"));
     340        Catlam.put(CatLAM.LAM_JBRT, new S57enum(19, "junction_right")); Catlam.put(CatLAM.LAM_JNLT, new S57enum(20, "junction_left")); Catlam.put(CatLAM.LAM_HBRT, new S57enum(21, "harbour_right"));
     341        Catlam.put(CatLAM.LAM_HBLT, new S57enum(22, "harbour_left")); Catlam.put(CatLAM.LAM_BRGP, new S57enum(23, "bridge_pier"));
     342    }
     343
     344    public enum CatLIT { LIT_UNKN, LIT_DIR, LIT_LEAD, LIT_AERO, LIT_AIR, LIT_FOG, LIT_FLDL, LIT_STRP, LIT_SUBS, LIT_SPOT, LIT_FRNT, LIT_REAR, LIT_LOWR, LIT_UPPR, LIT_MOIR, LIT_EMRG, LIT_BRNG, LIT_HORI, LIT_VERT }
     345
     346    private static final EnumMap<CatLIT, S57enum> Catlit = new EnumMap<>(CatLIT.class); static {
     347        Catlit.put(CatLIT.LIT_UNKN, new S57enum(0, ""));
     348        Catlit.put(CatLIT.LIT_DIR, new S57enum(1, "directional")); Catlit.put(CatLIT.LIT_LEAD, new S57enum(4, "leading")); Catlit.put(CatLIT.LIT_AERO, new S57enum(5, "aero"));
     349        Catlit.put(CatLIT.LIT_AIR, new S57enum(6, "air_obstruction")); Catlit.put(CatLIT.LIT_FOG, new S57enum(7, "fog_detector")); Catlit.put(CatLIT.LIT_FLDL, new S57enum(8, "floodlight"));
     350        Catlit.put(CatLIT.LIT_STRP, new S57enum(9, "strip_light")); Catlit.put(CatLIT.LIT_SUBS, new S57enum(10, "subsidiary")); Catlit.put(CatLIT.LIT_SPOT, new S57enum(11, "spotlight"));
     351        Catlit.put(CatLIT.LIT_FRNT, new S57enum(12, "front")); Catlit.put(CatLIT.LIT_REAR, new S57enum(13, "rear")); Catlit.put(CatLIT.LIT_LOWR, new S57enum(14, "lower"));
     352        Catlit.put(CatLIT.LIT_UPPR, new S57enum(15, "upper")); Catlit.put(CatLIT.LIT_MOIR, new S57enum(16, "moire")); Catlit.put(CatLIT.LIT_EMRG, new S57enum(17, "emergency"));
     353        Catlit.put(CatLIT.LIT_BRNG, new S57enum(18, "bearing")); Catlit.put(CatLIT.LIT_HORI, new S57enum(19, "horizontal")); Catlit.put(CatLIT.LIT_VERT, new S57enum(20, "vertical"));
     354    }
     355
     356    public enum CatMFA { MFA_UNKN, MFA_CRST, MFA_OYMS, MFA_FISH, MFA_SEAW, MFA_PRLC }
     357
     358    private static final EnumMap<CatMFA, S57enum> Catmfa = new EnumMap<>(CatMFA.class); static {
     359        Catmfa.put(CatMFA.MFA_UNKN, new S57enum(0, ""));
     360        Catmfa.put(CatMFA.MFA_CRST, new S57enum(1, "crustaceans")); Catmfa.put(CatMFA.MFA_OYMS, new S57enum(2, "oysters_mussels")); Catmfa.put(CatMFA.MFA_FISH, new S57enum(3, "fish"));
     361        Catmfa.put(CatMFA.MFA_SEAW, new S57enum(4, "seaweed")); Catmfa.put(CatMFA.MFA_PRLC, new S57enum(5, "pearl_culture"));
     362    }
     363
     364    public enum CatMPA { MPA_UNKN, MPA_PRCT, MPA_TRPD, MPA_SUBM, MPA_FIRG, MPA_MINL, MPA_SMLA }
     365
     366    private static final EnumMap<CatMPA, S57enum> Catmpa = new EnumMap<>(CatMPA.class); static {
     367        Catmpa.put(CatMPA.MPA_UNKN, new S57enum(0, ""));
     368        Catmpa.put(CatMPA.MPA_PRCT, new S57enum(1, "practice")); Catmpa.put(CatMPA.MPA_TRPD, new S57enum(2, "torpedo")); Catmpa.put(CatMPA.MPA_SUBM, new S57enum(3, "submarine"));
     369        Catmpa.put(CatMPA.MPA_FIRG, new S57enum(4, "firing")); Catmpa.put(CatMPA.MPA_MINL, new S57enum(5, "mine-laying")); Catmpa.put(CatMPA.MPA_SMLA, new S57enum(6, "small_arms"));
     370    }
     371
     372    public enum CatMOR { MOR_UNKN, MOR_DLPN, MOR_DDPN, MOR_BLRD, MOR_WALL, MOR_PILE, MOR_CHAN, MOR_BUOY, MOR_SHRP, MOR_AUTO, MOR_POST, MOR_WIRE, MOR_CABL }
     373
     374    private static final EnumMap<CatMOR, S57enum> Catmor = new EnumMap<>(CatMOR.class); static {
     375        Catmor.put(CatMOR.MOR_UNKN, new S57enum(0, ""));
     376        Catmor.put(CatMOR.MOR_DLPN, new S57enum(1, "dolphin")); Catmor.put(CatMOR.MOR_DDPN, new S57enum(2, "deviation_dolphin")); Catmor.put(CatMOR.MOR_BLRD, new S57enum(3, "bollard"));
     377        Catmor.put(CatMOR.MOR_WALL, new S57enum(4, "wall")); Catmor.put(CatMOR.MOR_PILE, new S57enum(5, "pile")); Catmor.put(CatMOR.MOR_CHAN, new S57enum(6, "chain"));
     378        Catmor.put(CatMOR.MOR_BUOY, new S57enum(7, "buoy")); Catmor.put(CatMOR.MOR_SHRP, new S57enum(8, "shore_ropes")); Catmor.put(CatMOR.MOR_AUTO, new S57enum(9, "automatic"));
     379        Catmor.put(CatMOR.MOR_POST, new S57enum(10, "post")); Catmor.put(CatMOR.MOR_WIRE, new S57enum(11, "wire")); Catmor.put(CatMOR.MOR_CABL, new S57enum(12, "cable"));
     380    }
     381
     382    public enum CatNAV { NAV_UNKN, NAV_CLRG, NAV_TRST, NAV_LDNG }
     383
     384    private static final EnumMap<CatNAV, S57enum> Catnav = new EnumMap<>(CatNAV.class); static {
     385        Catnav.put(CatNAV.NAV_UNKN, new S57enum(0, ""));
     386        Catnav.put(CatNAV.NAV_CLRG, new S57enum(1, "clearing")); Catnav.put(CatNAV.NAV_TRST, new S57enum(2, "transit")); Catnav.put(CatNAV.NAV_LDNG, new S57enum(3, "leading"));
     387    }
     388
     389    public enum CatOBS { OBS_UNKN, OBS_STMP, OBS_WELH, OBS_DIFF, OBS_CRIB, OBS_FHVN, OBS_FLAR, OBS_FLGD, OBS_ICEB, OBS_GTKL, OBS_BOOM, OBS_UWTB, OBS_TPLT, OBS_WEND, OBS_UWAS,
     390        OBS_REEF, OBS_MNFD, OBS_PNGO, OBS_RPLT, OBS_SCII }
     391
     392    private static final EnumMap<CatOBS, S57enum> Catobs = new EnumMap<>(CatOBS.class); static {
     393        Catobs.put(CatOBS.OBS_UNKN, new S57enum(0, ""));
     394        Catobs.put(CatOBS.OBS_STMP, new S57enum(1, "stump")); Catobs.put(CatOBS.OBS_WELH, new S57enum(2, "wellhead")); Catobs.put(CatOBS.OBS_DIFF, new S57enum(3, "diffuser"));
     395        Catobs.put(CatOBS.OBS_CRIB, new S57enum(4, "crib")); Catobs.put(CatOBS.OBS_FHVN, new S57enum(5, "fish_haven")); Catobs.put(CatOBS.OBS_FLAR, new S57enum(6, "foul_area"));
     396        Catobs.put(CatOBS.OBS_FLGD, new S57enum(7, "foul_ground")); Catobs.put(CatOBS.OBS_ICEB, new S57enum(8, "ice_boom")); Catobs.put(CatOBS.OBS_GTKL, new S57enum(9, "ground_tackle"));
     397        Catobs.put(CatOBS.OBS_BOOM, new S57enum(10, "boom")); Catobs.put(CatOBS.OBS_UWTB, new S57enum(11, "underwater_turbine")); Catobs.put(CatOBS.OBS_TPLT, new S57enum(12, "template"));
     398        Catobs.put(CatOBS.OBS_WEND, new S57enum(13, "wave_energy_device")); Catobs.put(CatOBS.OBS_UWAS, new S57enum(14, "subsurface_data")); Catobs.put(CatOBS.OBS_REEF, new S57enum(15, "artificial_reef"));
     399        Catobs.put(CatOBS.OBS_MNFD, new S57enum(16, "manifold")); Catobs.put(CatOBS.OBS_PNGO, new S57enum(17, "submerged_pingo")); Catobs.put(CatOBS.OBS_RPLT, new S57enum(18, "platform_remains"));
     400        Catobs.put(CatOBS.OBS_SCII, new S57enum(19, "scientific_instrument"));
     401    }
     402
     403    public enum CatOFP { OFP_UNKN, OFP_OIL, OFP_PROD, OFP_OBS, OFP_ALP, OFP_SALM, OFP_MOOR, OFP_AISL, OFP_FPSO, OFP_ACCN, OFP_NCCB, OFP_FOTK }
     404
     405    private static final EnumMap<CatOFP, S57enum> Catofp = new EnumMap<>(CatOFP.class); static {
     406        Catofp.put(CatOFP.OFP_UNKN, new S57enum(0, ""));
     407        Catofp.put(CatOFP.OFP_OIL, new S57enum(1, "oil")); Catofp.put(CatOFP.OFP_PROD, new S57enum(2, "production")); Catofp.put(CatOFP.OFP_OBS, new S57enum(3, "observation"));
     408        Catofp.put(CatOFP.OFP_ALP, new S57enum(4, "alp")); Catofp.put(CatOFP.OFP_SALM, new S57enum(5, "salm")); Catofp.put(CatOFP.OFP_MOOR, new S57enum(6, "mooring"));
     409        Catofp.put(CatOFP.OFP_AISL, new S57enum(7, "artificial_island")); Catofp.put(CatOFP.OFP_FPSO, new S57enum(8, "fpso")); Catofp.put(CatOFP.OFP_ACCN, new S57enum(9, "accommodation"));
     410        Catofp.put(CatOFP.OFP_NCCB, new S57enum(10, "nccb")); Catofp.put(CatOFP.OFP_FOTK, new S57enum(11, "floating_oil_tank"));
     411    }
     412
     413    public enum CatOLB { OLB_UNKN, OLB_RETN, OLB_FLTG }
     414
     415    private static final EnumMap<CatOLB, S57enum> Catolb = new EnumMap<>(CatOLB.class); static {
     416        Catolb.put(CatOLB.OLB_UNKN, new S57enum(0, ""));
     417        Catolb.put(CatOLB.OLB_RETN, new S57enum(1, "retention")); Catolb.put(CatOLB.OLB_FLTG, new S57enum(2, "floating"));
     418    }
     419
     420    public enum CatPLE { PLE_UNKN, PLE_STAK, PLE_POST, PLE_TRIP, PLE_PLNG, PLE_PARE, PLE_PIPE }
     421
     422    private static final EnumMap<CatPLE, S57enum> Catple = new EnumMap<>(CatPLE.class); static {
     423        Catple.put(CatPLE.PLE_UNKN, new S57enum(0, ""));
     424        Catple.put(CatPLE.PLE_STAK, new S57enum(1, "stake")); Catple.put(CatPLE.PLE_POST, new S57enum(3, "post")); Catple.put(CatPLE.PLE_TRIP, new S57enum(4, "tripodal"));
     425        Catple.put(CatPLE.PLE_PLNG, new S57enum(5, "piling")); Catple.put(CatPLE.PLE_PARE, new S57enum(6, "pile_area")); Catple.put(CatPLE.PLE_PIPE, new S57enum(7, "pipe"));
     426    }
     427
     428    public enum CatPIL { PIL_UNKN, PIL_CVSL, PIL_HELI, PIL_SHOR }
     429
     430    private static final EnumMap<CatPIL, S57enum> Catpil = new EnumMap<>(CatPIL.class); static {
     431        Catpil.put(CatPIL.PIL_UNKN, new S57enum(0, ""));
     432        Catpil.put(CatPIL.PIL_CVSL, new S57enum(1, "cruising_vessel")); Catpil.put(CatPIL.PIL_HELI, new S57enum(2, "helicopter")); Catpil.put(CatPIL.PIL_SHOR, new S57enum(3, "from_shore"));
     433    }
     434
     435    public enum CatPIP { PIP_UNKN, PIP_OFAL, PIP_ITAK, PIP_SEWR, PIP_BBLR, PIP_SPPL }
     436
     437    private static final EnumMap<CatPIP, S57enum> Catpip = new EnumMap<>(CatPIP.class); static {
     438        Catpip.put(CatPIP.PIP_UNKN, new S57enum(0, ""));
     439        Catpip.put(CatPIP.PIP_OFAL, new S57enum(2, "outfall")); Catpip.put(CatPIP.PIP_ITAK, new S57enum(3, "intake")); Catpip.put(CatPIP.PIP_SEWR, new S57enum(4, "sewer"));
     440        Catpip.put(CatPIP.PIP_BBLR, new S57enum(5, "bubbler")); Catpip.put(CatPIP.PIP_SPPL, new S57enum(6, "supply"));
     441    }
     442
     443    public enum CatPRA { PRA_UNKN, PRA_QRRY, PRA_MINE, PRA_STPL, PRA_PSTN, PRA_RFNY, PRA_TYRD, PRA_FACT, PRA_TFRM, PRA_WFRM, PRA_SLAG, PRA_CURF, PRA_OILF, PRA_GASF, PRA_WAVE }
     444
     445    private static final EnumMap<CatPRA, S57enum> Catpra = new EnumMap<>(CatPRA.class); static {
     446        Catpra.put(CatPRA.PRA_UNKN, new S57enum(0, ""));
     447        Catpra.put(CatPRA.PRA_QRRY, new S57enum(1, "quarry")); Catpra.put(CatPRA.PRA_MINE, new S57enum(2, "mine")); Catpra.put(CatPRA.PRA_STPL, new S57enum(3, "stockpile"));
     448        Catpra.put(CatPRA.PRA_PSTN, new S57enum(4, "power_station")); Catpra.put(CatPRA.PRA_RFNY, new S57enum(5, "refinery")); Catpra.put(CatPRA.PRA_TYRD, new S57enum(6, "timber_yard"));
     449        Catpra.put(CatPRA.PRA_FACT, new S57enum(7, "factory")); Catpra.put(CatPRA.PRA_TFRM, new S57enum(8, "tank_farm")); Catpra.put(CatPRA.PRA_WFRM, new S57enum(9, "wind_farm"));
     450        Catpra.put(CatPRA.PRA_SLAG, new S57enum(10, "slag_heap")); Catpra.put(CatPRA.PRA_CURF, new S57enum(11, "current_farm")); Catpra.put(CatPRA.PRA_OILF, new S57enum(12, "oil"));
     451        Catpra.put(CatPRA.PRA_GASF, new S57enum(13, "gas")); Catpra.put(CatPRA.PRA_WAVE, new S57enum(14, "wave_energy"));
     452    }
     453
     454    public enum CatPYL { PYL_UNKN, PYL_POWR, PYL_TELE, PYL_AERL, PYL_BRDG, PYL_PIER }
     455
     456    private static final EnumMap<CatPYL, S57enum> Catpyl = new EnumMap<>(CatPYL.class); static {
     457        Catpyl.put(CatPYL.PYL_UNKN, new S57enum(0, ""));
     458        Catpyl.put(CatPYL.PYL_POWR, new S57enum(1, "power")); Catpyl.put(CatPYL.PYL_TELE, new S57enum(2, "telecom")); Catpyl.put(CatPYL.PYL_AERL, new S57enum(3, "aerial"));
     459        Catpyl.put(CatPYL.PYL_BRDG, new S57enum(4, "bridge")); Catpyl.put(CatPYL.PYL_PIER, new S57enum(5, "bridge_pier"));
     460    }
     461
     462    public enum CatRAS { RAS_UNKN, RAS_SURV, RAS_COST }
     463
     464    private static final EnumMap<CatRAS, S57enum> Catras = new EnumMap<>(CatRAS.class); static {
     465        Catras.put(CatRAS.RAS_UNKN, new S57enum(0, ""));
     466        Catras.put(CatRAS.RAS_SURV, new S57enum(1, "surveillance")); Catras.put(CatRAS.RAS_COST, new S57enum(2, "coast"));
     467    }
     468
     469    public enum CatRTB { RTB_UNKN, RTB_RAMK, RTB_RACN, RTB_LDG }
     470
     471    private static final EnumMap<CatRTB, S57enum> Catrtb = new EnumMap<>(CatRTB.class); static {
     472        Catrtb.put(CatRTB.RTB_UNKN, new S57enum(0, ""));
     473        Catrtb.put(CatRTB.RTB_RAMK, new S57enum(1, "ramark")); Catrtb.put(CatRTB.RTB_RACN, new S57enum(2, "racon")); Catrtb.put(CatRTB.RTB_LDG, new S57enum(3, "leading"));
     474    }
     475
     476    public enum CatROS { ROS_UNKN, ROS_OMNI, ROS_DIRL, ROS_ROTP, ROS_CNSL, ROS_RDF, ROS_QTA, ROS_AERO, ROS_DECA, ROS_LORN, ROS_DGPS, ROS_TORN, ROS_OMGA, ROS_SYLD, ROS_CHKA,
     477        ROS_PCOM, ROS_COMB, ROS_FACS, ROS_TIME, ROS_PAIS, ROS_SAIS, ROS_VAIS, ROS_VANC, ROS_VASC, ROS_VAEC, ROS_VAWC, ROS_VAPL, ROS_VASL, ROS_VAID, ROS_VASW, ROS_VASP, ROS_VAWK }
     478
     479    private static final EnumMap<CatROS, S57enum> Catros = new EnumMap<>(CatROS.class); static {
     480        Catros.put(CatROS.ROS_UNKN, new S57enum(0, ""));
     481        Catros.put(CatROS.ROS_OMNI, new S57enum(1, "omnidirectional")); Catros.put(CatROS.ROS_DIRL, new S57enum(2, "directional")); Catros.put(CatROS.ROS_ROTP, new S57enum(3, "rotating_pattern"));
     482        Catros.put(CatROS.ROS_CNSL, new S57enum(4, "consol")); Catros.put(CatROS.ROS_RDF, new S57enum(5, "rdf")); Catros.put(CatROS.ROS_QTA, new S57enum(6, "qtg"));
     483        Catros.put(CatROS.ROS_AERO, new S57enum(7, "aeronautical")); Catros.put(CatROS.ROS_DECA, new S57enum(8, "decca")); Catros.put(CatROS.ROS_LORN, new S57enum(9, "loran"));
     484        Catros.put(CatROS.ROS_DGPS, new S57enum(10, "dgps")); Catros.put(CatROS.ROS_TORN, new S57enum(11, "toran")); Catros.put(CatROS.ROS_OMGA, new S57enum(12, "omega"));
     485        Catros.put(CatROS.ROS_SYLD, new S57enum(13, "syledis")); Catros.put(CatROS.ROS_CHKA, new S57enum(14, "chiaka")); Catros.put(CatROS.ROS_PCOM, new S57enum(15, "public_communication"));
     486        Catros.put(CatROS.ROS_COMB, new S57enum(16, "commercial_broadcast")); Catros.put(CatROS.ROS_FACS, new S57enum(17, "facsimile")); Catros.put(CatROS.ROS_TIME, new S57enum(18, "time_signal"));
     487        Catros.put(CatROS.ROS_PAIS, new S57enum(19, "ais")); Catros.put(CatROS.ROS_SAIS, new S57enum(20, "s-ais")); Catros.put(CatROS.ROS_VAIS, new S57enum(21, "v-ais"));
     488        Catros.put(CatROS.ROS_VANC, new S57enum(22, "v-ais_north_cardinal")); Catros.put(CatROS.ROS_VASC, new S57enum(23, "v-ais_south_cardinal"));
     489        Catros.put(CatROS.ROS_VAEC, new S57enum(24, "v-ais_east_cardinal")); Catros.put(CatROS.ROS_VAWC, new S57enum(25, "v-ais_west_cardinal"));
     490        Catros.put(CatROS.ROS_VAPL, new S57enum(26, "v-ais_port_lateral")); Catros.put(CatROS.ROS_VASL, new S57enum(27, "v-ais_starboard_lateral"));
     491        Catros.put(CatROS.ROS_VAID, new S57enum(28, "v-ais_isolated_danger")); Catros.put(CatROS.ROS_VASW, new S57enum(29, "v-ais_safe_water"));
     492        Catros.put(CatROS.ROS_VASP, new S57enum(30, "v-ais_special_purpose")); Catros.put(CatROS.ROS_VAWK, new S57enum(31, "v-ais_wreck"));
     493    }
     494
     495    public enum CatRSC { RSC_UNKN, RSC_LIFB, RSC_ROKT, RSC_LBRK, RSC_RFSW, RSC_RFIT, RSC_LBOM, RSC_RDIO, RSC_FSTA, RSC_SPLN, RSC_ACFT, RSC_STUG }
     496
     497    private static final EnumMap<CatRSC, S57enum> Catrsc = new EnumMap<>(CatRSC.class); static {
     498        Catrsc.put(CatRSC.RSC_UNKN, new S57enum(0, ""));
     499        Catrsc.put(CatRSC.RSC_LIFB, new S57enum(1, "lifeboat")); Catrsc.put(CatRSC.RSC_ROKT, new S57enum(2, "rocket")); Catrsc.put(CatRSC.RSC_LBRK, new S57enum(3, "lifeboat_rocket"));
     500        Catrsc.put(CatRSC.RSC_RFSW, new S57enum(4, "refuge_shipwrecked")); Catrsc.put(CatRSC.RSC_RFIT, new S57enum(5, "refuge_intertidal")); Catrsc.put(CatRSC.RSC_LBOM, new S57enum(6, "lifeboat_on_mooring"));
     501        Catrsc.put(CatRSC.RSC_RDIO, new S57enum(7, "radio")); Catrsc.put(CatRSC.RSC_FSTA, new S57enum(8, "first_aid")); Catrsc.put(CatRSC.RSC_SPLN, new S57enum(9, "seaplane"));
     502        Catrsc.put(CatRSC.RSC_ACFT, new S57enum(10, "aircraft")); Catrsc.put(CatRSC.RSC_STUG, new S57enum(12, "tug"));
     503    }
     504
     505    public enum CatREA { REA_UNKN, REA_SFTY, REA_NANC, REA_NFSH, REA_NATR, REA_BRDS, REA_GRSV, REA_SEAL, REA_DEGR, REA_MILY, REA_HIST, REA_INST,
     506        REA_NASF, REA_STRD, REA_MINE, REA_NDIV, REA_TBAV, REA_PROH, REA_SWIM, REA_WAIT, REA_RSCH, REA_DREG, REA_FSNC, REA_ERES, REA_NWAK, REA_SWNG,
     507        REA_WSKI, REA_ESSA, REA_PSSA, REA_DISA, REA_PSAR, REA_CRLS }
     508
     509    private static final EnumMap<CatREA, S57enum> Catrea = new EnumMap<>(CatREA.class); static {
     510        Catrea.put(CatREA.REA_UNKN, new S57enum(0, ""));
     511        Catrea.put(CatREA.REA_SFTY, new S57enum(1, "safety")); Catrea.put(CatREA.REA_NANC, new S57enum(2, "no_anchoring")); Catrea.put(CatREA.REA_NFSH, new S57enum(3, "no_fishing"));
     512        Catrea.put(CatREA.REA_NATR, new S57enum(4, "nature_reserve")); Catrea.put(CatREA.REA_BRDS, new S57enum(5, "bird_sanctuary")); Catrea.put(CatREA.REA_GRSV, new S57enum(6, "game_reserve"));
     513        Catrea.put(CatREA.REA_SEAL, new S57enum(7, "seal_sanctuary")); Catrea.put(CatREA.REA_DEGR, new S57enum(8, "degaussing_range")); Catrea.put(CatREA.REA_MILY, new S57enum(9, "military"));
     514        Catrea.put(CatREA.REA_HIST, new S57enum(10, "historic_wreck")); Catrea.put(CatREA.REA_INST, new S57enum(11, "inshore_traffic")); Catrea.put(CatREA.REA_NASF, new S57enum(12, "navigational_aid_safety"));
     515        Catrea.put(CatREA.REA_STRD, new S57enum(13, "stranding_danger")); Catrea.put(CatREA.REA_MINE, new S57enum(14, "minefield")); Catrea.put(CatREA.REA_NDIV, new S57enum(15, "no_diving"));
     516        Catrea.put(CatREA.REA_TBAV, new S57enum(16, "to_be_avoided")); Catrea.put(CatREA.REA_PROH, new S57enum(17, "prohibited")); Catrea.put(CatREA.REA_SWIM, new S57enum(18, "swimming"));
     517        Catrea.put(CatREA.REA_WAIT, new S57enum(19, "waiting")); Catrea.put(CatREA.REA_RSCH, new S57enum(20, "research")); Catrea.put(CatREA.REA_DREG, new S57enum(21, "dredging"));
     518        Catrea.put(CatREA.REA_FSNC, new S57enum(22, "fish_sanctuary")); Catrea.put(CatREA.REA_ERES, new S57enum(23, "ecological_reserve")); Catrea.put(CatREA.REA_NWAK, new S57enum(24, "no_wake"));
     519        Catrea.put(CatREA.REA_SWNG, new S57enum(25, "swinging")); Catrea.put(CatREA.REA_WSKI, new S57enum(26, "water_skiing"));
     520        Catrea.put(CatREA.REA_ESSA, new S57enum(27, "environmentally_sensitive")); Catrea.put(CatREA.REA_PSSA, new S57enum(28, "particularly_sensitive"));
     521        Catrea.put(CatREA.REA_DISA, new S57enum(29, "disengagement")); Catrea.put(CatREA.REA_PSAR, new S57enum(30, "port_security")); Catrea.put(CatREA.REA_CRLS, new S57enum(31, "coral_sactuary"));
     522    }
     523
     524    public enum CatROD { ROD_UNKN, ROD_MWAY, ROD_MAJR, ROD_MINR, ROD_TRAK, ROD_MAJS, ROD_MINS, ROD_CRSG, ROD_PATH }
     525
     526    private static final EnumMap<CatROD, S57enum> Catrod = new EnumMap<>(CatROD.class); static {
     527        Catrod.put(CatROD.ROD_UNKN, new S57enum(0, ""));
     528        Catrod.put(CatROD.ROD_MWAY, new S57enum(1, "motorway")); Catrod.put(CatROD.ROD_MAJR, new S57enum(2, "major_road")); Catrod.put(CatROD.ROD_MINR, new S57enum(3, "minor_road"));
     529        Catrod.put(CatROD.ROD_TRAK, new S57enum(4, "track")); Catrod.put(CatROD.ROD_MAJS, new S57enum(5, "major_street")); Catrod.put(CatROD.ROD_MINS, new S57enum(6, "minor_street"));
     530        Catrod.put(CatROD.ROD_CRSG, new S57enum(7, "crossing")); Catrod.put(CatROD.ROD_PATH, new S57enum(8, "path"));
     531    }
     532
     533    public enum CatRUN { RUN_UNKN, RUN_AERP, RUN_HELI }
     534
     535    private static final EnumMap<CatRUN, S57enum> Catrun = new EnumMap<>(CatRUN.class); static {
     536        Catrun.put(CatRUN.RUN_UNKN, new S57enum(0, "")); Catrun.put(CatRUN.RUN_AERP, new S57enum(1, "aeroplane")); Catrun.put(CatRUN.RUN_HELI, new S57enum(2, "helicopter"));
     537    }
     538
     539    public enum CatSEA { SEA_UNKN, SEA_GENL, SEA_GAT, SEA_BANK, SEA_DEEP, SEA_BAY, SEA_TRCH, SEA_BASN, SEA_MDFT, SEA_REEF, SEA_LEDG, SEA_CNYN, SEA_NRRW, SEA_SHOL,
     540        SEA_KNOL, SEA_RIDG, SEA_SMNT, SEA_PNCL, SEA_APLN, SEA_PLTU, SEA_SPUR, SEA_SHLF, SEA_TRGH, SEA_SDDL, SEA_AHLL, SEA_APRN, SEA_AAPN, SEA_BLND, SEA_CMGN, SEA_CRIS,
     541        SEA_ESCT, SEA_FAN, SEA_FZON, SEA_GAP, SEA_GUYT, SEA_HILL, SEA_HOLE, SEA_LEVE, SEA_MVLY, SEA_MOAT, SEA_MTNS, SEA_PEAK, SEA_PVNC, SEA_RISE, SEA_SCNL, SEA_SCHN,
     542        SEA_SEDG, SEA_SILL, SEA_SLOP, SEA_TRRC, SEA_VLLY, SEA_CANL, SEA_LAKE, SEA_RIVR, SEA_RECH }
     543
     544    private static final EnumMap<CatSEA, S57enum> Catsea = new EnumMap<>(CatSEA.class); static {
     545        Catsea.put(CatSEA.SEA_UNKN, new S57enum(0, ""));
     546        Catsea.put(CatSEA.SEA_GENL, new S57enum(1, "general")); Catsea.put(CatSEA.SEA_GAT, new S57enum(2, "gat")); Catsea.put(CatSEA.SEA_BANK, new S57enum(3, "bank"));
     547        Catsea.put(CatSEA.SEA_DEEP, new S57enum(4, "deep")); Catsea.put(CatSEA.SEA_BAY, new S57enum(5, "bay")); Catsea.put(CatSEA.SEA_TRCH, new S57enum(6, "trench"));
     548        Catsea.put(CatSEA.SEA_BASN, new S57enum(7, "basin")); Catsea.put(CatSEA.SEA_MDFT, new S57enum(8, "flat")); Catsea.put(CatSEA.SEA_REEF, new S57enum(9, "reef"));
     549        Catsea.put(CatSEA.SEA_LEDG, new S57enum(10, "ledge")); Catsea.put(CatSEA.SEA_CNYN, new S57enum(11, "canyon")); Catsea.put(CatSEA.SEA_NRRW, new S57enum(12, "narrows"));
     550        Catsea.put(CatSEA.SEA_SHOL, new S57enum(13, "shoal")); Catsea.put(CatSEA.SEA_KNOL, new S57enum(14, "knoll")); Catsea.put(CatSEA.SEA_RIDG, new S57enum(15, "ridge"));
     551        Catsea.put(CatSEA.SEA_SMNT, new S57enum(16, "seamount")); Catsea.put(CatSEA.SEA_PNCL, new S57enum(17, "pinnacle")); Catsea.put(CatSEA.SEA_APLN, new S57enum(18, "abyssal_plain"));
     552        Catsea.put(CatSEA.SEA_PLTU, new S57enum(19, "plateau")); Catsea.put(CatSEA.SEA_SPUR, new S57enum(20, "spur")); Catsea.put(CatSEA.SEA_SHLF, new S57enum(21, "shelf"));
     553        Catsea.put(CatSEA.SEA_TRGH, new S57enum(22, "trough")); Catsea.put(CatSEA.SEA_SDDL, new S57enum(23, "saddle")); Catsea.put(CatSEA.SEA_AHLL, new S57enum(24, "abyssal_hills"));
     554        Catsea.put(CatSEA.SEA_APRN, new S57enum(25, "apron")); Catsea.put(CatSEA.SEA_AAPN, new S57enum(26, "archipelagic_apron")); Catsea.put(CatSEA.SEA_BLND, new S57enum(27, "borderland"));
     555        Catsea.put(CatSEA.SEA_CMGN, new S57enum(28, "continental_margin")); Catsea.put(CatSEA.SEA_CRIS, new S57enum(29, "continental_rise")); Catsea.put(CatSEA.SEA_ESCT, new S57enum(30, "escarpment"));
     556        Catsea.put(CatSEA.SEA_FAN, new S57enum(31, "fan")); Catsea.put(CatSEA.SEA_FZON, new S57enum(32, "fracture_zone")); Catsea.put(CatSEA.SEA_GAP, new S57enum(33, "gap"));
     557        Catsea.put(CatSEA.SEA_GUYT, new S57enum(34, "guyot")); Catsea.put(CatSEA.SEA_HILL, new S57enum(35, "hill")); Catsea.put(CatSEA.SEA_HOLE, new S57enum(36, "hole"));
     558        Catsea.put(CatSEA.SEA_LEVE, new S57enum(37, "levee")); Catsea.put(CatSEA.SEA_MVLY, new S57enum(38, "median_valley")); Catsea.put(CatSEA.SEA_MOAT, new S57enum(39, "moat"));
     559        Catsea.put(CatSEA.SEA_MTNS, new S57enum(40, "mountains")); Catsea.put(CatSEA.SEA_PEAK, new S57enum(41, "peak")); Catsea.put(CatSEA.SEA_PVNC, new S57enum(42, "province"));
     560        Catsea.put(CatSEA.SEA_RISE, new S57enum(43, "rise")); Catsea.put(CatSEA.SEA_SCNL, new S57enum(44, "sea_channel")); Catsea.put(CatSEA.SEA_SCHN, new S57enum(45, "seamount_chain"));
     561        Catsea.put(CatSEA.SEA_SEDG, new S57enum(46, "shelf-edge")); Catsea.put(CatSEA.SEA_SILL, new S57enum(47, "sill")); Catsea.put(CatSEA.SEA_SLOP, new S57enum(48, "slope"));
     562        Catsea.put(CatSEA.SEA_TRRC, new S57enum(49, "terrace")); Catsea.put(CatSEA.SEA_VLLY, new S57enum(50, "valley")); Catsea.put(CatSEA.SEA_CANL, new S57enum(51, "canal"));
     563        Catsea.put(CatSEA.SEA_LAKE, new S57enum(52, "lake")); Catsea.put(CatSEA.SEA_RIVR, new S57enum(53, "river")); Catsea.put(CatSEA.SEA_RECH, new S57enum(54, "reach"));
     564    }
     565
     566    public enum CatSLC { SLC_UNKN, SLC_BWTR, SLC_GRYN, SLC_MOLE, SLC_PIER, SLC_PPER, SLC_WHRF, SLC_TWAL, SLC_RPRP, SLC_RVMT, SLC_SWAL, SLC_LSTP,
     567        SLC_RAMP, SLC_SWAY, SLC_FNDR, SLC_SFWF, SLC_OFWF, SLC_LRMP, SLC_LWAL, SLC_ICEB }
     568
     569    private static final EnumMap<CatSLC, S57enum> Catslc = new EnumMap<>(CatSLC.class); static {
     570        Catslc.put(CatSLC.SLC_UNKN, new S57enum(0, ""));
     571        Catslc.put(CatSLC.SLC_BWTR, new S57enum(1, "breakwater")); Catslc.put(CatSLC.SLC_GRYN, new S57enum(2, "groyne")); Catslc.put(CatSLC.SLC_MOLE, new S57enum(3, "mole"));
     572        Catslc.put(CatSLC.SLC_PIER, new S57enum(4, "pier")); Catslc.put(CatSLC.SLC_PPER, new S57enum(5, "promenade_pier")); Catslc.put(CatSLC.SLC_WHRF, new S57enum(6, "wharf"));
     573        Catslc.put(CatSLC.SLC_TWAL, new S57enum(7, "training_wall")); Catslc.put(CatSLC.SLC_RPRP, new S57enum(8, "rip_rap")); Catslc.put(CatSLC.SLC_RVMT, new S57enum(9, "revetment"));
     574        Catslc.put(CatSLC.SLC_SWAL, new S57enum(10, "sea_wall")); Catslc.put(CatSLC.SLC_LSTP, new S57enum(11, "landing_steps")); Catslc.put(CatSLC.SLC_RAMP, new S57enum(12, "ramp"));
     575        Catslc.put(CatSLC.SLC_SWAY, new S57enum(13, "slipway")); Catslc.put(CatSLC.SLC_FNDR, new S57enum(14, "fender")); Catslc.put(CatSLC.SLC_SFWF, new S57enum(15, "solid_face_wharf"));
     576        Catslc.put(CatSLC.SLC_OFWF, new S57enum(16, "open_face_wharf")); Catslc.put(CatSLC.SLC_LRMP, new S57enum(17, "log_ramp")); Catslc.put(CatSLC.SLC_LWAL, new S57enum(18, "lock_wall"));
     577        Catslc.put(CatSLC.SLC_ICEB, new S57enum(18, "ice_breaker"));
     578    }
     579
     580    public enum CatSIT { SIT_UNKN, SIT_PRTC, SIT_PRTE, SIT_IPT, SIT_BRTH, SIT_DOCK, SIT_LOCK, SIT_FLDB, SIT_BRDG, SIT_DRDG, SIT_TCLT, SIT_SPCL, SIT_PLTG, SIT_ONCT }
     581
     582    private static final EnumMap<CatSIT, S57enum> Catsit = new EnumMap<>(CatSIT.class); static {
     583        Catsit.put(CatSIT.SIT_UNKN, new S57enum(0, ""));
     584        Catsit.put(CatSIT.SIT_PRTC, new S57enum(1, "port_control")); Catsit.put(CatSIT.SIT_PRTE, new S57enum(2, "port_entry_departure")); Catsit.put(CatSIT.SIT_IPT, new S57enum(3, "ipt"));
     585        Catsit.put(CatSIT.SIT_BRTH, new S57enum(4, "berthing")); Catsit.put(CatSIT.SIT_DOCK, new S57enum(5, "dock")); Catsit.put(CatSIT.SIT_LOCK, new S57enum(6, "lock"));
     586        Catsit.put(CatSIT.SIT_FLDB, new S57enum(7, "flood_barrage")); Catsit.put(CatSIT.SIT_BRDG, new S57enum(8, "bridge_passage")); Catsit.put(CatSIT.SIT_DRDG, new S57enum(9, "dredging"));
     587        Catsit.put(CatSIT.SIT_TCLT, new S57enum(10, "traffic_control")); Catsit.put(CatSIT.SIT_PLTG, new S57enum(11, "pilotage")); Catsit.put(CatSIT.SIT_SPCL, new S57enum(12, "special"));
     588        Catsit.put(CatSIT.SIT_ONCT, new S57enum(13, "oncoming_traffic"));
     589    }
     590
     591    public enum CatSIW { SIW_UNKN, SIW_DNGR, SIW_OBST, SIW_CABL, SIW_MILY, SIW_DSTR, SIW_WTHR, SIW_STRM, SIW_ICE, SIW_TIME, SIW_TIDE, SIW_TSTR,
     592        SIW_TIDG, SIW_TIDS, SIW_DIVE, SIW_WTLG, SIW_VRCL, SIW_HIWM, SIW_DPTH, SIW_CURR }
     593
     594    private static final EnumMap<CatSIW, S57enum> Catsiw = new EnumMap<>(CatSIW.class); static {
     595        Catsiw.put(CatSIW.SIW_UNKN, new S57enum(0, ""));
     596        Catsiw.put(CatSIW.SIW_DNGR, new S57enum(1, "danger")); Catsiw.put(CatSIW.SIW_OBST, new S57enum(2, "maritime_obstruction")); Catsiw.put(CatSIW.SIW_CABL, new S57enum(3, "cable"));
     597        Catsiw.put(CatSIW.SIW_MILY, new S57enum(4, "military")); Catsiw.put(CatSIW.SIW_DSTR, new S57enum(5, "distress")); Catsiw.put(CatSIW.SIW_WTHR, new S57enum(6, "weather"));
     598        Catsiw.put(CatSIW.SIW_STRM, new S57enum(7, "storm")); Catsiw.put(CatSIW.SIW_ICE, new S57enum(8, "ice")); Catsiw.put(CatSIW.SIW_TIME, new S57enum(9, "time"));
     599        Catsiw.put(CatSIW.SIW_TIDE, new S57enum(10, "tide")); Catsiw.put(CatSIW.SIW_TSTR, new S57enum(11, "tidal_stream")); Catsiw.put(CatSIW.SIW_TIDG, new S57enum(12, "tide_gauge"));
     600        Catsiw.put(CatSIW.SIW_TIDS, new S57enum(13, "tide_scale")); Catsiw.put(CatSIW.SIW_DIVE, new S57enum(14, "diving")); Catsiw.put(CatSIW.SIW_WTLG, new S57enum(15, "water_level_gauge"));
     601        Catsiw.put(CatSIW.SIW_VRCL, new S57enum(16, "vertical_clearance")); Catsiw.put(CatSIW.SIW_HIWM, new S57enum(17, "high_water")); Catsiw.put(CatSIW.SIW_DPTH, new S57enum(18, "depth"));
     602        Catsiw.put(CatSIW.SIW_CURR, new S57enum(19, "current"));
     603    }
     604
     605    public enum CatSIL { SIL_UNKN, SIL_SILO, SIL_TANK, SIL_GRNE, SIL_WTRT }
     606
     607    private static final EnumMap<CatSIL, S57enum> Catsil = new EnumMap<>(CatSIL.class); static {
     608        Catsil.put(CatSIL.SIL_UNKN, new S57enum(0, ""));
     609        Catsil.put(CatSIL.SIL_SILO, new S57enum(1, "silo")); Catsil.put(CatSIL.SIL_TANK, new S57enum(2, "tank")); Catsil.put(CatSIL.SIL_GRNE, new S57enum(3, "grain_elevator"));
     610        Catsil.put(CatSIL.SIL_WTRT, new S57enum(4, "water_tower"));
     611    }
     612
     613    public enum CatSLO { SLO_UNKN, SLO_CUTG, SLO_EMBK, SLO_DUNE, SLO_HILL, SLO_PINO, SLO_CLIF, SLO_SCRE }
     614
     615    private static final EnumMap<CatSLO, S57enum> Catslo = new EnumMap<>(CatSLO.class); static {
     616        Catslo.put(CatSLO.SLO_UNKN, new S57enum(0, ""));
     617        Catslo.put(CatSLO.SLO_CUTG, new S57enum(1, "cutting")); Catslo.put(CatSLO.SLO_EMBK, new S57enum(2, "embankment")); Catslo.put(CatSLO.SLO_DUNE, new S57enum(3, "dune"));
     618        Catslo.put(CatSLO.SLO_HILL, new S57enum(4, "hill")); Catslo.put(CatSLO.SLO_PINO, new S57enum(5, "pingo")); Catslo.put(CatSLO.SLO_CLIF, new S57enum(6, "cliff")); Catslo.put(CatSLO.SLO_SCRE, new S57enum(7, "scree"));
     619    }
     620
     621    public enum CatSCF { SCF_UNKN, SCF_VBTH, SCF_CLUB, SCF_BHST, SCF_SMKR, SCF_BTYD, SCF_INN, SCF_RSRT, SCF_CHDR, SCF_PROV, SCF_DCTR, SCF_PHRM,
     622        SCF_WTRT, SCF_FUEL, SCF_ELEC, SCF_BGAS, SCF_SHWR, SCF_LAUN, SCF_WC, SCF_POST, SCF_TELE, SCF_REFB, SCF_CARP, SCF_BTPK, SCF_CRVN, SCF_CAMP,
     623        SCF_PMPO, SCF_EMRT, SCF_SLPW, SCF_VMOR, SCF_SCRB, SCF_PCNC, SCF_MECH, SCF_SECS }
     624
     625    private static final EnumMap<CatSCF, S57enum> Catscf = new EnumMap<>(CatSCF.class); static {
     626        Catscf.put(CatSCF.SCF_UNKN, new S57enum(0, ""));
     627        Catscf.put(CatSCF.SCF_VBTH, new S57enum(1, "visitor_berth")); Catscf.put(CatSCF.SCF_CLUB, new S57enum(2, "nautical_club")); Catscf.put(CatSCF.SCF_BHST, new S57enum(3, "boat_hoist"));
     628        Catscf.put(CatSCF.SCF_SMKR, new S57enum(4, "sailmaker")); Catscf.put(CatSCF.SCF_BTYD, new S57enum(5, "boatyard")); Catscf.put(CatSCF.SCF_INN, new S57enum(6, "public_inn"));
     629        Catscf.put(CatSCF.SCF_RSRT, new S57enum(7, "restaurant")); Catscf.put(CatSCF.SCF_CHDR, new S57enum(8, "chandler")); Catscf.put(CatSCF.SCF_PROV, new S57enum(9, "provisions"));
     630        Catscf.put(CatSCF.SCF_DCTR, new S57enum(10, "doctor")); Catscf.put(CatSCF.SCF_PHRM, new S57enum(11, "pharmacy")); Catscf.put(CatSCF.SCF_WTRT, new S57enum(12, "water_tap"));
     631        Catscf.put(CatSCF.SCF_FUEL, new S57enum(13, "fuel_station")); Catscf.put(CatSCF.SCF_ELEC, new S57enum(14, "electricity")); Catscf.put(CatSCF.SCF_BGAS, new S57enum(15, "bottle_gas"));
     632        Catscf.put(CatSCF.SCF_SHWR, new S57enum(16, "showers")); Catscf.put(CatSCF.SCF_LAUN, new S57enum(17, "laundrette")); Catscf.put(CatSCF.SCF_WC, new S57enum(18, "toilets"));
     633        Catscf.put(CatSCF.SCF_POST, new S57enum(19, "post_box")); Catscf.put(CatSCF.SCF_TELE, new S57enum(20, "telephone")); Catscf.put(CatSCF.SCF_REFB, new S57enum(21, "refuse_bin"));
     634        Catscf.put(CatSCF.SCF_CARP, new S57enum(22, "car_park")); Catscf.put(CatSCF.SCF_BTPK, new S57enum(23, "boat_trailers_park")); Catscf.put(CatSCF.SCF_CRVN, new S57enum(24, "caravan_site"));
     635        Catscf.put(CatSCF.SCF_CAMP, new S57enum(25, "camping_site")); Catscf.put(CatSCF.SCF_PMPO, new S57enum(26, "pump-out")); Catscf.put(CatSCF.SCF_EMRT, new S57enum(27, "emergency_telephone"));
     636        Catscf.put(CatSCF.SCF_SLPW, new S57enum(28, "slipway")); Catscf.put(CatSCF.SCF_VMOR, new S57enum(29, "visitors_mooring")); Catscf.put(CatSCF.SCF_SCRB, new S57enum(30, "scrubbing_berth"));
     637        Catscf.put(CatSCF.SCF_PCNC, new S57enum(31, "picnic_area")); Catscf.put(CatSCF.SCF_MECH, new S57enum(32, "mechanics_workshop")); Catscf.put(CatSCF.SCF_SECS, new S57enum(33, "security_service"));
     638    }
     639
     640    public enum CatSPM { SPM_UNKN, SPM_FDGA, SPM_TRGT, SPM_MSHP, SPM_DGRG, SPM_BARG, SPM_CABL, SPM_SPLG, SPM_OFAL, SPM_ODAS, SPM_RCDG, SPM_SPLA, SPM_RCZN, SPM_PRVT, SPM_MOOR, SPM_LNBY, SPM_LDNG, SPM_MDST,
     641        SPM_NOTC, SPM_TSS, SPM_NANC, SPM_NBRT, SPM_NOTK, SPM_NTWT, SPM_RWAK, SPM_SPDL, SPM_STOP, SPM_WRNG, SPM_SSSN, SPM_RVCL, SPM_MVDT, SPM_RHCL, SPM_SCNT, SPM_BRTH, SPM_OHPC, SPM_CHEG, SPM_TELE, SPM_FCRS,
     642        SPM_MTRL, SPM_PLIN, SPM_ANCH, SPM_CLRG, SPM_CTRL, SPM_DIVG, SPM_RBCN, SPM_FGND, SPM_YCHT, SPM_HPRT, SPM_GPS, SPM_SLDG, SPM_NENT, SPM_WRKP, SPM_UKPP, SPM_WELH, SPM_CHSP, SPM_MFRM, SPM_AREF }
     643
     644    private static final EnumMap<CatSPM, S57enum> Catspm = new EnumMap<>(CatSPM.class); static {
     645        Catspm.put(CatSPM.SPM_UNKN, new S57enum(0, ""));
     646        Catspm.put(CatSPM.SPM_FDGA, new S57enum(1, "firing_danger_area")); Catspm.put(CatSPM.SPM_TRGT, new S57enum(2, "target")); Catspm.put(CatSPM.SPM_MSHP, new S57enum(3, "marker_ship"));
     647        Catspm.put(CatSPM.SPM_DGRG, new S57enum(4, "degaussing_range")); Catspm.put(CatSPM.SPM_BARG, new S57enum(5, "barge")); Catspm.put(CatSPM.SPM_CABL, new S57enum(6, "cable"));
     648        Catspm.put(CatSPM.SPM_SPLG, new S57enum(7, "spoil_ground")); Catspm.put(CatSPM.SPM_OFAL, new S57enum(8, "outfall")); Catspm.put(CatSPM.SPM_ODAS, new S57enum(9, "odas"));
     649        Catspm.put(CatSPM.SPM_RCDG, new S57enum(10, "recording")); Catspm.put(CatSPM.SPM_SPLA, new S57enum(11, "seaplane_anchorage")); Catspm.put(CatSPM.SPM_RCZN, new S57enum(12, "recreation_zone"));
     650        Catspm.put(CatSPM.SPM_PRVT, new S57enum(13, "private")); Catspm.put(CatSPM.SPM_MOOR, new S57enum(14, "mooring")); Catspm.put(CatSPM.SPM_LNBY, new S57enum(15, "lanby"));
     651        Catspm.put(CatSPM.SPM_LDNG, new S57enum(16, "leading")); Catspm.put(CatSPM.SPM_MDST, new S57enum(17, "measured_distance")); Catspm.put(CatSPM.SPM_NOTC, new S57enum(18, "notice"));
     652        Catspm.put(CatSPM.SPM_TSS, new S57enum(19, "tss")); Catspm.put(CatSPM.SPM_NANC, new S57enum(20, "no_anchoring")); Catspm.put(CatSPM.SPM_NBRT, new S57enum(21, "no_berthing"));
     653        Catspm.put(CatSPM.SPM_NOTK, new S57enum(22, "no_overtaking")); Catspm.put(CatSPM.SPM_NTWT, new S57enum(23, "no_two-way_traffic")); Catspm.put(CatSPM.SPM_RWAK, new S57enum(24, "reduced_wake"));
     654        Catspm.put(CatSPM.SPM_SPDL, new S57enum(25, "speed_limit")); Catspm.put(CatSPM.SPM_STOP, new S57enum(26, "stop")); Catspm.put(CatSPM.SPM_WRNG, new S57enum(27, "warning"));
     655        Catspm.put(CatSPM.SPM_SSSN, new S57enum(28, "sound_ship_siren")); Catspm.put(CatSPM.SPM_RVCL, new S57enum(29, "restricted_vertical_clearance"));
     656        Catspm.put(CatSPM.SPM_MVDT, new S57enum(30, "maximum_vessel_draught")); Catspm.put(CatSPM.SPM_RHCL, new S57enum(31, "restricted_horizontal_clearance"));
     657        Catspm.put(CatSPM.SPM_SCNT, new S57enum(32, "strong_current")); Catspm.put(CatSPM.SPM_BRTH, new S57enum(33, "berthing")); Catspm.put(CatSPM.SPM_OHPC, new S57enum(34, "overhead_power_cable"));
     658        Catspm.put(CatSPM.SPM_CHEG, new S57enum(35, "channel_edge_gradient")); Catspm.put(CatSPM.SPM_TELE, new S57enum(36, "telephone")); Catspm.put(CatSPM.SPM_FCRS, new S57enum(37, "ferry_crossing"));
     659        Catspm.put(CatSPM.SPM_MTRL, new S57enum(38, "marine_traffic_lights")); Catspm.put(CatSPM.SPM_PLIN, new S57enum(39, "pipeline")); Catspm.put(CatSPM.SPM_ANCH, new S57enum(40, "anchorage"));
     660        Catspm.put(CatSPM.SPM_CLRG, new S57enum(41, "clearing")); Catspm.put(CatSPM.SPM_CTRL, new S57enum(42, "control")); Catspm.put(CatSPM.SPM_DIVG, new S57enum(43, "diving"));
     661        Catspm.put(CatSPM.SPM_RBCN, new S57enum(44, "refuge_beacon")); Catspm.put(CatSPM.SPM_FGND, new S57enum(45, "foul_ground")); Catspm.put(CatSPM.SPM_YCHT, new S57enum(46, "yachting"));
     662        Catspm.put(CatSPM.SPM_HPRT, new S57enum(47, "heliport")); Catspm.put(CatSPM.SPM_GPS, new S57enum(48, "gps")); Catspm.put(CatSPM.SPM_SLDG, new S57enum(49, "seaplane_landing"));
     663        Catspm.put(CatSPM.SPM_NENT, new S57enum(50, "no_entry")); Catspm.put(CatSPM.SPM_WRKP, new S57enum(51, "work_in_progress")); Catspm.put(CatSPM.SPM_UKPP, new S57enum(52, "unknown_purpose"));
     664        Catspm.put(CatSPM.SPM_WELH, new S57enum(53, "wellhead")); Catspm.put(CatSPM.SPM_CHSP, new S57enum(54, "channel_separation")); Catspm.put(CatSPM.SPM_MFRM, new S57enum(55, "marine_farm"));
     665        Catspm.put(CatSPM.SPM_AREF, new S57enum(56, "artificial_reef"));
     666    }
     667
     668    public enum CatTRK { TRK_UNKN, TRK_FIXM, TRK_NFXM }
     669
     670    private static final EnumMap<CatTRK, S57enum> Cattrk = new EnumMap<>(CatTRK.class); static {
     671        Cattrk.put(CatTRK.TRK_UNKN, new S57enum(0, ""));
     672        Cattrk.put(CatTRK.TRK_FIXM, new S57enum(1, "fixed_marks")); Cattrk.put(CatTRK.TRK_NFXM, new S57enum(2, "no_fixed_marks"));
     673    }
     674
     675    public enum CatTSS { TSS_UNKN, TSS_IMOA, TSS_NIMO }
     676
     677    private static final EnumMap<CatTSS, S57enum> Cattss = new EnumMap<>(CatTSS.class); static {
     678        Cattss.put(CatTSS.TSS_UNKN, new S57enum(0, ""));
     679        Cattss.put(CatTSS.TSS_IMOA, new S57enum(1, "imo_adopted")); Cattss.put(CatTSS.TSS_NIMO, new S57enum(2, "not_imo_adopted"));
     680    }
     681
     682    public enum CatVEG { VEG_UNKN, VEG_GRAS, VEG_PDDY, VEG_BUSH, VEG_DCDW, VEG_CONW, VEG_WOOD, VEG_MGRV, VEG_PARK, VEG_PKLD, VEG_MCRP, VEG_REED, VEG_MOSS,
     683        VEG_TREE, VEG_EVGT, VEG_CONT, VEG_PLMT, VEG_NPMT, VEG_CSAT, VEG_EUCT, VEG_DCDT, VEG_MRVT, VEG_FLOT }
     684
     685    private static final EnumMap<CatVEG, S57enum> Catveg = new EnumMap<>(CatVEG.class); static {
     686        Catveg.put(CatVEG.VEG_UNKN, new S57enum(0, ""));
     687        Catveg.put(CatVEG.VEG_GRAS, new S57enum(1, "grass")); Catveg.put(CatVEG.VEG_PDDY, new S57enum(2, "paddy")); Catveg.put(CatVEG.VEG_BUSH, new S57enum(3, "bush"));
     688        Catveg.put(CatVEG.VEG_DCDW, new S57enum(4, "deciduous_wood")); Catveg.put(CatVEG.VEG_CONW, new S57enum(5, "coniferous_wood")); Catveg.put(CatVEG.VEG_WOOD, new S57enum(6, "wood"));
     689        Catveg.put(CatVEG.VEG_MGRV, new S57enum(7, "mangroves")); Catveg.put(CatVEG.VEG_PARK, new S57enum(8, "park")); Catveg.put(CatVEG.VEG_PKLD, new S57enum(9, "parkland"));
     690        Catveg.put(CatVEG.VEG_MCRP, new S57enum(10, "mixed_crops")); Catveg.put(CatVEG.VEG_REED, new S57enum(11, "reed")); Catveg.put(CatVEG.VEG_MOSS, new S57enum(12, "moss"));
     691        Catveg.put(CatVEG.VEG_TREE, new S57enum(13, "tree")); Catveg.put(CatVEG.VEG_EVGT, new S57enum(14, "evergreen_tree")); Catveg.put(CatVEG.VEG_CONT, new S57enum(15, "coniferous_tree"));
     692        Catveg.put(CatVEG.VEG_PLMT, new S57enum(16, "palm_tree")); Catveg.put(CatVEG.VEG_NPMT, new S57enum(17, "nipa_palm_tree")); Catveg.put(CatVEG.VEG_CSAT, new S57enum(18, "casuarina_tree"));
     693        Catveg.put(CatVEG.VEG_EUCT, new S57enum(19, "eucalypt_tree")); Catveg.put(CatVEG.VEG_DCDT, new S57enum(20, "deciduous_tree")); Catveg.put(CatVEG.VEG_MRVT, new S57enum(21, "mangrove_tree"));
     694        Catveg.put(CatVEG.VEG_FLOT, new S57enum(22, "filao_tree"));
     695    }
     696
     697    public enum CatWAT { WAT_UNKN, WAT_BKRS, WAT_EDDY, WAT_OVFL, WAT_TDRP, WAT_BMBR }
     698
     699    private static final EnumMap<CatWAT, S57enum> Catwat = new EnumMap<>(CatWAT.class); static {
     700        Catwat.put(CatWAT.WAT_UNKN, new S57enum(0, ""));
     701        Catwat.put(CatWAT.WAT_BKRS, new S57enum(1, "breakers")); Catwat.put(CatWAT.WAT_EDDY, new S57enum(2, "eddies")); Catwat.put(CatWAT.WAT_OVFL, new S57enum(3, "overfalls"));
     702        Catwat.put(CatWAT.WAT_TDRP, new S57enum(4, "tide_rips")); Catwat.put(CatWAT.WAT_BMBR, new S57enum(5, "bombora"));
     703    }
     704
     705    public enum CatWED { WED_UNKN, WED_KELP, WED_SWED, WED_SGRS, WED_SGSO }
     706
     707    private static final EnumMap<CatWED, S57enum> Catwed = new EnumMap<>(CatWED.class); static {
     708        Catwed.put(CatWED.WED_UNKN, new S57enum(0, ""));
     709        Catwed.put(CatWED.WED_KELP, new S57enum(1, "kelp")); Catwed.put(CatWED.WED_SWED, new S57enum(2, "sea_weed")); Catwed.put(CatWED.WED_SGRS, new S57enum(3, "sea_grass"));
     710        Catwed.put(CatWED.WED_SGSO, new S57enum(4, "sargasso"));
     711    }
     712
     713    public enum CatWRK { WRK_UNKN, WRK_NDGR, WRK_DNGR, WRK_DREM, WRK_MSTS, WRK_HULS }
     714
     715    private static final EnumMap<CatWRK, S57enum> Catwrk = new EnumMap<>(CatWRK.class); static {
     716        Catwrk.put(CatWRK.WRK_UNKN, new S57enum(0, ""));
     717        Catwrk.put(CatWRK.WRK_NDGR, new S57enum(1, "non-dangerous")); Catwrk.put(CatWRK.WRK_DNGR, new S57enum(2, "dangerous")); Catwrk.put(CatWRK.WRK_DREM, new S57enum(3, "distributed_remains"));
     718        Catwrk.put(CatWRK.WRK_MSTS, new S57enum(4, "mast_showing")); Catwrk.put(CatWRK.WRK_HULS, new S57enum(5, "hull_showing"));
     719    }
     720
     721    public enum CatZOC { ZOC_UNKN, ZOC_A1, ZOC_A2, ZOC_B, ZOC_C, ZOC_D, ZOC_U }
     722
     723    private static final EnumMap<CatZOC, S57enum> Catzoc = new EnumMap<>(CatZOC.class); static {
     724        Catzoc.put(CatZOC.ZOC_UNKN, new S57enum(0, ""));
     725        Catzoc.put(CatZOC.ZOC_A1, new S57enum(1, "a1")); Catzoc.put(CatZOC.ZOC_A2, new S57enum(2, "a2")); Catzoc.put(CatZOC.ZOC_B, new S57enum(3, "b"));
     726        Catzoc.put(CatZOC.ZOC_C, new S57enum(4, "c")); Catzoc.put(CatZOC.ZOC_D, new S57enum(5, "d")); Catzoc.put(CatZOC.ZOC_U, new S57enum(6, "u"));
     727    }
     728
     729    public enum ColCOL { COL_UNK, COL_WHT, COL_BLK, COL_RED, COL_GRN, COL_BLU, COL_YEL, COL_GRY, COL_BRN, COL_AMB, COL_VIO, COL_ORG, COL_MAG, COL_PNK }
     730
     731    private static final EnumMap<ColCOL, S57enum> Colour = new EnumMap<>(ColCOL.class); static {
     732        Colour.put(ColCOL.COL_UNK, new S57enum(0, ""));
     733        Colour.put(ColCOL.COL_WHT, new S57enum(1, "white")); Colour.put(ColCOL.COL_BLK, new S57enum(2, "black")); Colour.put(ColCOL.COL_RED, new S57enum(3, "red"));
     734        Colour.put(ColCOL.COL_GRN, new S57enum(4, "green")); Colour.put(ColCOL.COL_BLU, new S57enum(5, "blue")); Colour.put(ColCOL.COL_YEL, new S57enum(6, "yellow"));
     735        Colour.put(ColCOL.COL_GRY, new S57enum(7, "grey")); Colour.put(ColCOL.COL_BRN, new S57enum(8, "brown")); Colour.put(ColCOL.COL_AMB, new S57enum(9, "amber"));
     736        Colour.put(ColCOL.COL_VIO, new S57enum(10, "violet")); Colour.put(ColCOL.COL_ORG, new S57enum(11, "orange")); Colour.put(ColCOL.COL_MAG, new S57enum(12, "magenta"));
     737        Colour.put(ColCOL.COL_PNK, new S57enum(13, "pink"));
     738    }
     739
     740    public enum ColPAT { PAT_UNKN, PAT_HORI, PAT_VERT, PAT_DIAG, PAT_SQUR, PAT_STRP, PAT_BRDR, PAT_CROS, PAT_SALT }
     741
     742    private static final EnumMap<ColPAT, S57enum> Colpat = new EnumMap<>(ColPAT.class); static {
     743        Colpat.put(ColPAT.PAT_UNKN, new S57enum(0, ""));
     744        Colpat.put(ColPAT.PAT_HORI, new S57enum(1, "horizontal")); Colpat.put(ColPAT.PAT_VERT, new S57enum(2, "vertical")); Colpat.put(ColPAT.PAT_DIAG, new S57enum(3, "diagonal"));
     745        Colpat.put(ColPAT.PAT_SQUR, new S57enum(4, "squared")); Colpat.put(ColPAT.PAT_STRP, new S57enum(5, "stripes")); Colpat.put(ColPAT.PAT_BRDR, new S57enum(6, "border"));
     746        Colpat.put(ColPAT.PAT_CROS, new S57enum(7, "cross")); Colpat.put(ColPAT.PAT_SALT, new S57enum(8, "saltire"));
     747    }
     748
     749    public enum CndCND { CND_UNKN, CND_UCNS, CND_RUIN, CND_URCL, CND_WLES, CND_PCNS }
     750
     751    private static final EnumMap<CndCND, S57enum> Condtn = new EnumMap<>(CndCND.class); static {
     752        Condtn.put(CndCND.CND_UNKN, new S57enum(0, ""));
     753        Condtn.put(CndCND.CND_UCNS, new S57enum(1, "under_construction")); Condtn.put(CndCND.CND_RUIN, new S57enum(2, "ruined")); Condtn.put(CndCND.CND_URCL, new S57enum(3, "under_reclamation"));
     754        Condtn.put(CndCND.CND_WLES, new S57enum(4, "wingless")); Condtn.put(CndCND.CND_PCNS, new S57enum(5, "planned_construction"));
     755    }
     756
     757    public enum ConRAD { RAD_UNKN, RAD_CNSP, RAD_NCSP, RAD_REFL }
     758
     759    private static final EnumMap<ConRAD, S57enum> Conrad = new EnumMap<>(ConRAD.class); static {
     760        Conrad.put(ConRAD.RAD_UNKN, new S57enum(0, ""));
     761        Conrad.put(ConRAD.RAD_CNSP, new S57enum(1, "conspicuous")); Conrad.put(ConRAD.RAD_NCSP, new S57enum(2, "not_conspicuous")); Conrad.put(ConRAD.RAD_REFL, new S57enum(3, "reflector"));
     762    }
     763
     764    public enum ConVIS { VIS_UNKN, VIS_CNSP, VIS_NCSP }
     765
     766    private static final EnumMap<ConVIS, S57enum> Convis = new EnumMap<>(ConVIS.class); static {
     767        Convis.put(ConVIS.VIS_UNKN, new S57enum(0, ""));
     768        Convis.put(ConVIS.VIS_CNSP, new S57enum(1, "conspicuous")); Convis.put(ConVIS.VIS_NCSP, new S57enum(2, "not_conspicuous"));
     769    }
     770
     771    public enum UniDPU { DPU_UNKN, DPU_METR, DPU_FTFT, DPU_FTHM, DPU_FTFR }
     772
     773    private static final EnumMap<UniDPU, S57enum> Dunits = new EnumMap<>(UniDPU.class); static {
     774        Dunits.put(UniDPU.DPU_UNKN, new S57enum(0, ""));
     775        Dunits.put(UniDPU.DPU_METR, new S57enum(1, "metres")); Dunits.put(UniDPU.DPU_FTFT, new S57enum(2, "fathoms_feet")); Dunits.put(UniDPU.DPU_FTHM, new S57enum(3, "fathoms"));
     776        Dunits.put(UniDPU.DPU_FTFR, new S57enum(4, "fathoms_fractions"));
     777    }
     778
     779    public enum ExcLIT { EXH_UNKN, EXH_24H, EXH_DAY, EXH_FOG, EXH_NGHT, EXH_WRNG, EXH_STRM }
     780
     781    private static final EnumMap<ExcLIT, S57enum> Exclit = new EnumMap<>(ExcLIT.class); static {
     782        Exclit.put(ExcLIT.EXH_UNKN, new S57enum(0, ""));
     783        Exclit.put(ExcLIT.EXH_24H, new S57enum(1, "24h")); Exclit.put(ExcLIT.EXH_DAY, new S57enum(2, "day")); Exclit.put(ExcLIT.EXH_FOG, new S57enum(3, "fog")); Exclit.put(ExcLIT.EXH_NGHT, new S57enum(4, "night"));
     784        Exclit.put(ExcLIT.EXH_WRNG, new S57enum(5, "warning")); Exclit.put(ExcLIT.EXH_STRM, new S57enum(6, "storm"));
     785    }
     786
     787    public enum ExpSOU { EXP_UNKN, EXP_WTHN, EXP_SHLR, EXP_DEPR }
     788
     789    private static final EnumMap<ExpSOU, S57enum> Expsou = new EnumMap<>(ExpSOU.class); static {
     790        Expsou.put(ExpSOU.EXP_UNKN, new S57enum(0, ""));
     791        Expsou.put(ExpSOU.EXP_WTHN, new S57enum(1, "within")); Expsou.put(ExpSOU.EXP_SHLR, new S57enum(2, "shoaler")); Expsou.put(ExpSOU.EXP_DEPR, new S57enum(3, "deeper"));
     792    }
     793
     794    public enum FncFNC { FNC_UNKN, FNC_HBRM, FNC_CSTM, FNC_HLTH, FNC_HOSP, FNC_POST, FNC_HOTL, FNC_RAIL, FNC_POLC, FNC_WPOL, FNC_PILO, FNC_PILL, FNC_BANK,
     795        FNC_DIST, FNC_TRNS, FNC_FCTY, FNC_POWR, FNC_ADMIN, FNC_EDUC, FNC_CHCH, FNC_CHPL, FNC_TMPL, FNC_PGDA, FNC_SHSH, FNC_BTMP, FNC_MOSQ, FNC_MRBT,
     796        FNC_LOOK, FNC_COMM, FNC_TV, FNC_RADO, FNC_RADR, FNC_LGHT, FNC_MCWV, FNC_COOL, FNC_OBS, FNC_TMBL, FNC_CLOK, FNC_CTRL, FNC_ASHM, FNC_STAD, FNC_BUSS,
     797        FNC_PTRM, FNC_SRCT, FNC_OBSV, FNC_OREC, FNC_BTHS, FNC_PMPS }
     798
     799    private static final EnumMap<FncFNC, S57enum> Functn = new EnumMap<>(FncFNC.class); static {
     800        Functn.put(FncFNC.FNC_UNKN, new S57enum(0, ""));
     801        Functn.put(FncFNC.FNC_HBRM, new S57enum(2, "harbour_master")); Functn.put(FncFNC.FNC_CSTM, new S57enum(3, "customs")); Functn.put(FncFNC.FNC_HLTH, new S57enum(4, "health"));
     802        Functn.put(FncFNC.FNC_HOSP, new S57enum(5, "hospital")); Functn.put(FncFNC.FNC_POST, new S57enum(6, "post_office")); Functn.put(FncFNC.FNC_HOTL, new S57enum(7, "hotel"));
     803        Functn.put(FncFNC.FNC_RAIL, new S57enum(8, "railway_station")); Functn.put(FncFNC.FNC_POLC, new S57enum(9, "police_station")); Functn.put(FncFNC.FNC_WPOL, new S57enum(10, "water-police_station"));
     804        Functn.put(FncFNC.FNC_PILO, new S57enum(11, "pilot_office")); Functn.put(FncFNC.FNC_PILL, new S57enum(12, "pilot_lookout")); Functn.put(FncFNC.FNC_BANK, new S57enum(13, "bank"));
     805        Functn.put(FncFNC.FNC_DIST, new S57enum(14, "district_control")); Functn.put(FncFNC.FNC_TRNS, new S57enum(15, "transit_shed")); Functn.put(FncFNC.FNC_FCTY, new S57enum(16, "factory"));
     806        Functn.put(FncFNC.FNC_POWR, new S57enum(17, "power_station")); Functn.put(FncFNC.FNC_ADMIN, new S57enum(18, "administrative")); Functn.put(FncFNC.FNC_EDUC, new S57enum(19, "educational"));
     807        Functn.put(FncFNC.FNC_CHCH, new S57enum(20, "church")); Functn.put(FncFNC.FNC_CHPL, new S57enum(21, "chapel")); Functn.put(FncFNC.FNC_TMPL, new S57enum(22, "temple"));
     808        Functn.put(FncFNC.FNC_PGDA, new S57enum(23, "pagoda")); Functn.put(FncFNC.FNC_SHSH, new S57enum(24, "shinto_shrine")); Functn.put(FncFNC.FNC_BTMP, new S57enum(25, "buddhist_temple"));
     809        Functn.put(FncFNC.FNC_MOSQ, new S57enum(26, "mosque")); Functn.put(FncFNC.FNC_MRBT, new S57enum(27, "marabout")); Functn.put(FncFNC.FNC_LOOK, new S57enum(28, "lookout"));
     810        Functn.put(FncFNC.FNC_COMM, new S57enum(29, "communication")); Functn.put(FncFNC.FNC_TV, new S57enum(30, "television")); Functn.put(FncFNC.FNC_RADO, new S57enum(31, "radio"));
     811        Functn.put(FncFNC.FNC_RADR, new S57enum(32, "radar")); Functn.put(FncFNC.FNC_LGHT, new S57enum(33, "light_support")); Functn.put(FncFNC.FNC_MCWV, new S57enum(34, "microwave"));
     812        Functn.put(FncFNC.FNC_COOL, new S57enum(35, "cooling")); Functn.put(FncFNC.FNC_OBS, new S57enum(36, "observation")); Functn.put(FncFNC.FNC_TMBL, new S57enum(37, "time_ball"));
     813        Functn.put(FncFNC.FNC_CLOK, new S57enum(38, "clock")); Functn.put(FncFNC.FNC_CTRL, new S57enum(39, "control")); Functn.put(FncFNC.FNC_ASHM, new S57enum(40, "airship_mooring"));
     814        Functn.put(FncFNC.FNC_STAD, new S57enum(41, "stadium")); Functn.put(FncFNC.FNC_BUSS, new S57enum(42, "bus_station")); Functn.put(FncFNC.FNC_PTRM, new S57enum(43, "passenger_terminal"));
     815        Functn.put(FncFNC.FNC_SRCT, new S57enum(44, "sea_rescue_control")); Functn.put(FncFNC.FNC_OBSV, new S57enum(45, "observatory")); Functn.put(FncFNC.FNC_OREC, new S57enum(46, "ore_crusher"));
     816        Functn.put(FncFNC.FNC_BTHS, new S57enum(47, "boathouse")); Functn.put(FncFNC.FNC_PMPS, new S57enum(48, "pumping_station"));
     817    }
     818
     819    public enum UniHLU { HLU_UNKN, HLU_METR, HLU_FEET, HLU_KMTR, HLU_HMTR, HLU_SMIL, HLU_NMIL }
     820
     821    private static final EnumMap<UniHLU, S57enum> Hunits = new EnumMap<>(UniHLU.class); static {
     822        Hunits.put(UniHLU.HLU_UNKN, new S57enum(0, ""));
     823        Hunits.put(UniHLU.HLU_METR, new S57enum(1, "metres")); Hunits.put(UniHLU.HLU_FEET, new S57enum(2, "feet")); Hunits.put(UniHLU.HLU_KMTR, new S57enum(3, "kilometres"));
     824        Hunits.put(UniHLU.HLU_HMTR, new S57enum(4, "hectometres")); Hunits.put(UniHLU.HLU_SMIL, new S57enum(5, "statute_miles")); Hunits.put(UniHLU.HLU_NMIL, new S57enum(6, "nautical_miles"));
     825    }
     826
     827    public enum JrsJRS { JRS_UNKN, JRS_INT, JRS_NAT, JRS_NSD }
     828
     829    private static final EnumMap<JrsJRS, S57enum> Jrsdtn = new EnumMap<>(JrsJRS.class); static {
     830        Jrsdtn.put(JrsJRS.JRS_UNKN, new S57enum(0, ""));
     831        Jrsdtn.put(JrsJRS.JRS_INT, new S57enum(1, "international")); Jrsdtn.put(JrsJRS.JRS_NAT, new S57enum(2, "national")); Jrsdtn.put(JrsJRS.JRS_NSD, new S57enum(3, "national_sub-division"));
     832    }
     833
     834    public enum LitCHR { CHR_UNKN, CHR_F, CHR_FL, CHR_LFL, CHR_Q, CHR_VQ, CHR_UQ, CHR_ISO, CHR_OC, CHR_IQ, CHR_IVQ, CHR_IUQ, CHR_MO, CHR_FFL,
     835        CHR_FLLFL, CHR_OCFL, CHR_FLFL, CHR_ALOC, CHR_ALLFL, CHR_ALFL, CHR_ALGR, CHR_QLFL, CHR_VQLFL, CHR_UQLFL, CHR_AL, CHR_ALFFL }
     836
     837    private static final EnumMap<LitCHR, S57enum> Litchr = new EnumMap<>(LitCHR.class); static {
     838        Litchr.put(LitCHR.CHR_UNKN, new S57enum(0, ""));
     839        Litchr.put(LitCHR.CHR_F, new S57enum(1, "F")); Litchr.put(LitCHR.CHR_FL, new S57enum(2, "Fl")); Litchr.put(LitCHR.CHR_LFL, new S57enum(3, "LFl")); Litchr.put(LitCHR.CHR_Q, new S57enum(4, "Q"));
     840        Litchr.put(LitCHR.CHR_VQ, new S57enum(5, "VQ")); Litchr.put(LitCHR.CHR_UQ, new S57enum(6, "UQ")); Litchr.put(LitCHR.CHR_ISO, new S57enum(7, "Iso")); Litchr.put(LitCHR.CHR_OC, new S57enum(8, "Oc"));
     841        Litchr.put(LitCHR.CHR_IQ, new S57enum(9, "IQ")); Litchr.put(LitCHR.CHR_IVQ, new S57enum(10, "IVQ")); Litchr.put(LitCHR.CHR_IUQ, new S57enum(11, "IUQ")); Litchr.put(LitCHR.CHR_MO, new S57enum(12, "Mo"));
     842        Litchr.put(LitCHR.CHR_FFL, new S57enum(13, "FFl")); Litchr.put(LitCHR.CHR_FLLFL, new S57enum(14, "FlLFl")); Litchr.put(LitCHR.CHR_OCFL, new S57enum(15, "OcFl"));
     843        Litchr.put(LitCHR.CHR_FLFL, new S57enum(16, "FLFl")); Litchr.put(LitCHR.CHR_ALOC, new S57enum(17, "Al.Oc")); Litchr.put(LitCHR.CHR_ALLFL, new S57enum(18, "Al.LFl"));
     844        Litchr.put(LitCHR.CHR_ALFL, new S57enum(19, "Al.Fl")); Litchr.put(LitCHR.CHR_ALGR, new S57enum(20, "Al.Gr")); Litchr.put(LitCHR.CHR_QLFL, new S57enum(25, "Q+LFl"));
     845        Litchr.put(LitCHR.CHR_VQLFL, new S57enum(26, "VQ+LFl")); Litchr.put(LitCHR.CHR_UQLFL, new S57enum(27, "UQ+LFl")); Litchr.put(LitCHR.CHR_AL, new S57enum(28, "Al"));
     846        Litchr.put(LitCHR.CHR_ALFFL, new S57enum(29, "Al.FFl"));
     847    }
     848
     849    public enum LitVIS { LIT_UNKN, LIT_HIGH, LIT_LOW, LIT_FANT, LIT_INTS, LIT_UINT, LIT_RSTR, LIT_OBSC, LIT_POBS }
     850
     851    private static final EnumMap<LitVIS, S57enum> Litvis = new EnumMap<>(LitVIS.class); static {
     852        Litvis.put(LitVIS.LIT_UNKN, new S57enum(0, ""));
     853        Litvis.put(LitVIS.LIT_HIGH, new S57enum(1, "high")); Litvis.put(LitVIS.LIT_LOW, new S57enum(2, "low")); Litvis.put(LitVIS.LIT_FANT, new S57enum(3, "faint"));
     854        Litvis.put(LitVIS.LIT_INTS, new S57enum(4, "intensified")); Litvis.put(LitVIS.LIT_UINT, new S57enum(5, "unintensified")); Litvis.put(LitVIS.LIT_RSTR, new S57enum(6, "restricted"));
     855        Litvis.put(LitVIS.LIT_OBSC, new S57enum(7, "obscured")); Litvis.put(LitVIS.LIT_POBS, new S57enum(8, "part_obscured"));
     856    }
     857
     858    public enum MarSYS { SYS_UNKN, SYS_IALA, SYS_IALB, SYS_NONE, SYS_OTHR, SYS_CEVN, SYS_RIWR, SYS_BWR2, SYS_BNWR, SYS_PPWB }
     859
     860    private static final EnumMap<MarSYS, S57enum> Marsys = new EnumMap<>(MarSYS.class); static {
     861        Marsys.put(MarSYS.SYS_UNKN, new S57enum(0, ""));
     862        Marsys.put(MarSYS.SYS_IALA, new S57enum(1, "iala-a")); Marsys.put(MarSYS.SYS_IALB, new S57enum(2, "iala-b")); Marsys.put(MarSYS.SYS_NONE, new S57enum(9, "none"));
     863        Marsys.put(MarSYS.SYS_OTHR, new S57enum(10, "other")); Marsys.put(MarSYS.SYS_CEVN, new S57enum(11, "cevni")); Marsys.put(MarSYS.SYS_RIWR, new S57enum(12, "riwr"));
     864        Marsys.put(MarSYS.SYS_BWR2, new S57enum(13, "bniwr2")); Marsys.put(MarSYS.SYS_BNWR, new S57enum(14, "bniwr")); Marsys.put(MarSYS.SYS_PPWB, new S57enum(15, "ppwbc"));
     865    }
     866
     867    public enum NatCON { CON_UNKN, CON_MSNY, CON_CONC, CON_BDRS, CON_HSRF, CON_USRF, CON_WOOD, CON_METL, CON_GRP, CON_PNTD, CON_FMWK, CON_LATT, CON_GLAS }
     868
     869    private static final EnumMap<NatCON, S57enum> Natcon = new EnumMap<>(NatCON.class); static {
     870        Natcon.put(NatCON.CON_UNKN, new S57enum(0, ""));
     871        Natcon.put(NatCON.CON_MSNY, new S57enum(1, "masonry")); Natcon.put(NatCON.CON_CONC, new S57enum(2, "concreted")); Natcon.put(NatCON.CON_BDRS, new S57enum(3, "loose_boulders"));
     872        Natcon.put(NatCON.CON_HSRF, new S57enum(4, "hard-surfaced")); Natcon.put(NatCON.CON_USRF, new S57enum(5, "unsurfaced")); Natcon.put(NatCON.CON_WOOD, new S57enum(6, "wooden"));
     873        Natcon.put(NatCON.CON_METL, new S57enum(7, "metal")); Natcon.put(NatCON.CON_GRP, new S57enum(8, "grp")); Natcon.put(NatCON.CON_PNTD, new S57enum(9, "painted"));
     874        Natcon.put(NatCON.CON_FMWK, new S57enum(10, "framework")); Natcon.put(NatCON.CON_LATT, new S57enum(11, "latticed")); Natcon.put(NatCON.CON_GLAS, new S57enum(12, "glass"));
     875    }
     876
     877    public enum NatSUR { SUR_UNKN, SUR_MUD, SUR_CLAY, SUR_SILT, SUR_SAND, SUR_STON, SUR_GRVL, SUR_PBBL, SUR_CBBL, SUR_ROCK, SUR_LAVA, SUR_CORL, SUR_SHEL, SUR_BLDR }
     878
     879    private static final EnumMap<NatSUR, S57enum> Natsur = new EnumMap<>(NatSUR.class); static {
     880        Natsur.put(NatSUR.SUR_UNKN, new S57enum(0, ""));
     881        Natsur.put(NatSUR.SUR_MUD, new S57enum(1, "mud")); Natsur.put(NatSUR.SUR_CLAY, new S57enum(2, "clay")); Natsur.put(NatSUR.SUR_SILT, new S57enum(3, "silt"));
     882        Natsur.put(NatSUR.SUR_SAND, new S57enum(4, "sand")); Natsur.put(NatSUR.SUR_STON, new S57enum(5, "stones")); Natsur.put(NatSUR.SUR_GRVL, new S57enum(6, "gravel"));
     883        Natsur.put(NatSUR.SUR_PBBL, new S57enum(7, "pebbles")); Natsur.put(NatSUR.SUR_CBBL, new S57enum(8, "cobbles")); Natsur.put(NatSUR.SUR_ROCK, new S57enum(9, "rocky"));
     884        Natsur.put(NatSUR.SUR_LAVA, new S57enum(11, "lava")); Natsur.put(NatSUR.SUR_CORL, new S57enum(14, "coral")); Natsur.put(NatSUR.SUR_SHEL, new S57enum(17, "shells"));
     885        Natsur.put(NatSUR.SUR_BLDR, new S57enum(18, "boulders"));
     886    }
     887
     888    public enum NatQUA { QUA_UNKN, QUA_FINE, QUA_MEDM, QUA_CORS, QUA_BRKN, QUA_STKY, QUA_SOFT, QUA_STIF, QUA_VCNC, QUA_CALC, QUA_HARD }
     889
     890    private static final EnumMap<NatQUA, S57enum> Natqua = new EnumMap<>(NatQUA.class); static {
     891        Natqua.put(NatQUA.QUA_UNKN, new S57enum(0, ""));
     892        Natqua.put(NatQUA.QUA_FINE, new S57enum(1, "fine")); Natqua.put(NatQUA.QUA_MEDM, new S57enum(2, "medium")); Natqua.put(NatQUA.QUA_CORS, new S57enum(3, "coarse"));
     893        Natqua.put(NatQUA.QUA_BRKN, new S57enum(4, "broken")); Natqua.put(NatQUA.QUA_STKY, new S57enum(5, "sticky")); Natqua.put(NatQUA.QUA_SOFT, new S57enum(6, "soft"));
     894        Natqua.put(NatQUA.QUA_STIF, new S57enum(7, "stiff")); Natqua.put(NatQUA.QUA_VCNC, new S57enum(8, "volcanic")); Natqua.put(NatQUA.QUA_CALC, new S57enum(9, "calcareous"));
     895        Natqua.put(NatQUA.QUA_HARD, new S57enum(10, "hard"));
     896    }
     897
     898    public enum PrdPRD { PRD_UNKN, PRD_OIL, PRD_GAS, PRD_WATR, PRD_STON, PRD_COAL, PRD_ORE, PRD_CHEM, PRD_DWTR, PRD_MILK, PRD_BXIT, PRD_COKE, PRD_IIGS, PRD_SALT,
     899        PRD_SAND, PRD_TMBR, PRD_SDST, PRD_SCRP, PRD_LNA, PRD_LPA, PRD_WINE, PRD_CMNT, PRD_GRAN }
     900
     901    private static final EnumMap<PrdPRD, S57enum> Prodct = new EnumMap<>(PrdPRD.class); static {
     902        Prodct.put(PrdPRD.PRD_UNKN, new S57enum(0, ""));
     903        Prodct.put(PrdPRD.PRD_OIL, new S57enum(1, "oil")); Prodct.put(PrdPRD.PRD_GAS, new S57enum(2, "gas")); Prodct.put(PrdPRD.PRD_WATR, new S57enum(3, "water"));
     904        Prodct.put(PrdPRD.PRD_STON, new S57enum(4, "stone")); Prodct.put(PrdPRD.PRD_COAL, new S57enum(5, "coal")); Prodct.put(PrdPRD.PRD_ORE, new S57enum(6, "ore"));
     905        Prodct.put(PrdPRD.PRD_CHEM, new S57enum(7, "chemicals")); Prodct.put(PrdPRD.PRD_DWTR, new S57enum(8, "drinking_water")); Prodct.put(PrdPRD.PRD_MILK, new S57enum(9, "milk"));
     906        Prodct.put(PrdPRD.PRD_BXIT, new S57enum(10, "bauxite")); Prodct.put(PrdPRD.PRD_COKE, new S57enum(11, "coke")); Prodct.put(PrdPRD.PRD_IIGS, new S57enum(12, "iron_ingots"));
     907        Prodct.put(PrdPRD.PRD_SALT, new S57enum(13, "salt")); Prodct.put(PrdPRD.PRD_SAND, new S57enum(14, "sand")); Prodct.put(PrdPRD.PRD_TMBR, new S57enum(15, "timber"));
     908        Prodct.put(PrdPRD.PRD_SDST, new S57enum(16, "sawdust")); Prodct.put(PrdPRD.PRD_SCRP, new S57enum(17, "scrap")); Prodct.put(PrdPRD.PRD_LNA, new S57enum(18, "lng"));
     909        Prodct.put(PrdPRD.PRD_LPA, new S57enum(19, "lpg")); Prodct.put(PrdPRD.PRD_WINE, new S57enum(20, "wine")); Prodct.put(PrdPRD.PRD_CMNT, new S57enum(21, "cement"));
     910        Prodct.put(PrdPRD.PRD_GRAN, new S57enum(22, "grain"));
     911    }
     912
     913    public enum QuaSOU { SOU_UNKN, SOU_KNWN, SOU_UKNN, SOU_DFUL, SOU_UNRL, SOU_NBFD, SOU_LKWN, SOU_LUKN, SOU_NSRV, SOU_NCNF, SOU_MANT, SOU_NMNT }
     914
     915    private static final EnumMap<QuaSOU, S57enum> Quasou = new EnumMap<>(QuaSOU.class); static {
     916        Quasou.put(QuaSOU.SOU_UNKN, new S57enum(0, ""));
     917        Quasou.put(QuaSOU.SOU_KNWN, new S57enum(1, "known")); Quasou.put(QuaSOU.SOU_UKNN, new S57enum(2, "unknown")); Quasou.put(QuaSOU.SOU_DFUL, new S57enum(3, "doubtful"));
     918        Quasou.put(QuaSOU.SOU_UNRL, new S57enum(4, "unreliable")); Quasou.put(QuaSOU.SOU_NBFD, new S57enum(5, "no_bottom_found")); Quasou.put(QuaSOU.SOU_LKWN, new S57enum(6, "least_known"));
     919        Quasou.put(QuaSOU.SOU_LUKN, new S57enum(7, "least_unknown")); Quasou.put(QuaSOU.SOU_NSRV, new S57enum(8, "not_surveyed")); Quasou.put(QuaSOU.SOU_NCNF, new S57enum(9, "not_confirmed"));
     920        Quasou.put(QuaSOU.SOU_MANT, new S57enum(10, "maintained")); Quasou.put(QuaSOU.SOU_NMNT, new S57enum(11, "not_maintained"));
     921    }
     922
     923    public enum RstRST { RST_UNKN, RST_NANC, RST_RANC, RST_NFSH, RST_RFSH, RST_NTRL, RST_RTRL, RST_NENT, RST_RENT, RST_NDRG, RST_RDRG, RST_NDVG, RST_RDVG, RST_NWAK, RST_TBAV, RST_NCST, RST_NDSC,
     924        RST_RDSC, RST_NEXD, RST_REXD, RST_NDRL, RST_RDRL, RST_NHAR, RST_NLTG, RST_NDRA, RST_NSTP, RST_NLND, RST_RSPD, RST_NOVT, RST_NCOV, RST_NPOV, RST_NBRT, RST_RBRT, RST_NMFT, RST_RMFT, RST_NTRN,
     925        RST_RFWD, RST_RFWW, RST_NSWM }
     926
     927    private static final EnumMap<RstRST, S57enum> Restrn = new EnumMap<>(RstRST.class); static {
     928        Restrn.put(RstRST.RST_UNKN, new S57enum(0, ""));
     929        Restrn.put(RstRST.RST_NANC, new S57enum(1, "no_anchoring")); Restrn.put(RstRST.RST_RANC, new S57enum(2, "restricted_anchoring")); Restrn.put(RstRST.RST_NFSH, new S57enum(3, "no_fishing"));
     930        Restrn.put(RstRST.RST_RFSH, new S57enum(4, "restricted_fishing")); Restrn.put(RstRST.RST_NTRL, new S57enum(5, "no_trawling")); Restrn.put(RstRST.RST_RTRL, new S57enum(6, "restricted_trawling"));
     931        Restrn.put(RstRST.RST_NENT, new S57enum(7, "no_entry")); Restrn.put(RstRST.RST_RENT, new S57enum(8, "restricted_entry")); Restrn.put(RstRST.RST_NDRG, new S57enum(9, "no_dredging"));
     932        Restrn.put(RstRST.RST_RDRG, new S57enum(10, "restricted_dredging")); Restrn.put(RstRST.RST_NDVG, new S57enum(11, "no_diving")); Restrn.put(RstRST.RST_RDVG, new S57enum(12, "restricted_diving"));
     933        Restrn.put(RstRST.RST_NWAK, new S57enum(13, "no_wake")); Restrn.put(RstRST.RST_TBAV, new S57enum(14, "to_be_avoided")); Restrn.put(RstRST.RST_NCST, new S57enum(15, "no_construction"));
     934        Restrn.put(RstRST.RST_NDSC, new S57enum(16, "no_discharging")); Restrn.put(RstRST.RST_RDSC, new S57enum(17, "restricted_discharging"));
     935        Restrn.put(RstRST.RST_NEXD, new S57enum(18, "no_exploration_development")); Restrn.put(RstRST.RST_REXD, new S57enum(19, "restricted_exploration_development"));
     936        Restrn.put(RstRST.RST_NDRL, new S57enum(20, "no_drilling")); Restrn.put(RstRST.RST_RDRL, new S57enum(21, "restricted_drilling"));
     937        Restrn.put(RstRST.RST_NHAR, new S57enum(22, "no_historical_artifacts_removal")); Restrn.put(RstRST.RST_NLTG, new S57enum(23, "no_lightering")); Restrn.put(RstRST.RST_NDRA, new S57enum(24, "no_dragging"));
     938        Restrn.put(RstRST.RST_NSTP, new S57enum(25, "no_stopping")); Restrn.put(RstRST.RST_NLND, new S57enum(26, "no_landing")); Restrn.put(RstRST.RST_RSPD, new S57enum(27, "restricted_speed"));
     939        Restrn.put(RstRST.RST_NOVT, new S57enum(28, "no_overtaking")); Restrn.put(RstRST.RST_NCOV, new S57enum(29, "no_convoy_overtaking")); Restrn.put(RstRST.RST_NPOV, new S57enum(30, "no_passing_overtaking"));
     940        Restrn.put(RstRST.RST_NBRT, new S57enum(31, "no_berthing")); Restrn.put(RstRST.RST_RBRT, new S57enum(32, "restricted_berthing")); Restrn.put(RstRST.RST_NMFT, new S57enum(33, "no_making_fast"));
     941        Restrn.put(RstRST.RST_RMFT, new S57enum(34, "restricted_making_fast")); Restrn.put(RstRST.RST_NTRN, new S57enum(35, "no_turning")); Restrn.put(RstRST.RST_RFWD, new S57enum(36, "restricted_fairway_depth"));
     942        Restrn.put(RstRST.RST_RFWW, new S57enum(37, "restricted_fairway_width")); Restrn.put(RstRST.RST_NSWM, new S57enum(38, "no_swimming"));
     943    }
     944
     945    public enum SigGEN { GEN_UNKN, GEN_AUTO, GEN_WAVE, GEN_HAND, GEN_WIND }
     946
     947    private static final EnumMap<SigGEN, S57enum> Siggen = new EnumMap<>(SigGEN.class); static {
     948        Siggen.put(SigGEN.GEN_UNKN, new S57enum(0, ""));
     949        Siggen.put(SigGEN.GEN_AUTO, new S57enum(1, "automatic")); Siggen.put(SigGEN.GEN_WAVE, new S57enum(2, "wave")); Siggen.put(SigGEN.GEN_HAND, new S57enum(3, "hand")); Siggen.put(SigGEN.GEN_WIND, new S57enum(4, "wind"));
     950    }
     951
     952    public enum StsSTS { STS_UNKN, STS_PERM, STS_OCAS, STS_RCMD, STS_NIUS, STS_IMTT, STS_RESV, STS_TEMP, STS_PRIV, STS_MAND, STS_EXTD, STS_ILLD, STS_HIST, STS_PBLC,
     953        STS_SYNC, STS_WCHD, STS_UWCD, STS_EDBT, STS_OREQ, STS_DPAW, STS_RSNG, STS_INCR, STS_DECR, TS_STNG, STS_GOOD, STS_MODY, STS_POOR }
     954
     955    private static final EnumMap<StsSTS, S57enum> Status = new EnumMap<>(StsSTS.class); static {
     956        Status.put(StsSTS.STS_UNKN, new S57enum(0, ""));
     957        Status.put(StsSTS.STS_PERM, new S57enum(1, "permanent")); Status.put(StsSTS.STS_OCAS, new S57enum(2, "occasional")); Status.put(StsSTS.STS_RCMD, new S57enum(3, "recommended"));
     958        Status.put(StsSTS.STS_NIUS, new S57enum(4, "not_in_use")); Status.put(StsSTS.STS_IMTT, new S57enum(5, "intermittent")); Status.put(StsSTS.STS_RESV, new S57enum(6, "reserved"));
     959        Status.put(StsSTS.STS_TEMP, new S57enum(7, "temporary")); Status.put(StsSTS.STS_PRIV, new S57enum(8, "private")); Status.put(StsSTS.STS_MAND, new S57enum(9, "mandatory"));
     960        Status.put(StsSTS.STS_EXTD, new S57enum(11, "extinguished")); Status.put(StsSTS.STS_ILLD, new S57enum(12, "illuminated")); Status.put(StsSTS.STS_HIST, new S57enum(13, "historic"));
     961        Status.put(StsSTS.STS_PBLC, new S57enum(14, "public")); Status.put(StsSTS.STS_SYNC, new S57enum(15, "synchronised")); Status.put(StsSTS.STS_WCHD, new S57enum(16, "watched"));
     962        Status.put(StsSTS.STS_UWCD, new S57enum(17, "unwatched")); Status.put(StsSTS.STS_EDBT, new S57enum(18, "existence_doubtful")); Status.put(StsSTS.STS_OREQ, new S57enum(19, "on_request"));
     963        Status.put(StsSTS.STS_DPAW, new S57enum(20, "drop_away")); Status.put(StsSTS.STS_RSNG, new S57enum(21, "rising")); Status.put(StsSTS.STS_INCR, new S57enum(22, "increasing"));
     964        Status.put(StsSTS.STS_DECR, new S57enum(23, "decreasing")); Status.put(StsSTS.TS_STNG, new S57enum(24, "strong")); Status.put(StsSTS.STS_GOOD, new S57enum(25, "good"));
     965        Status.put(StsSTS.STS_MODY, new S57enum(26, "moderately")); Status.put(StsSTS.STS_POOR, new S57enum(27, "poor"));
     966    }
     967
     968    public enum SurTYP { TYP_UNKN, TYP_SKCH, TYP_CTLD, TYP_PSSG, TYP_REMT }
     969
     970    private static final EnumMap<SurTYP, S57enum> Surtyp = new EnumMap<>(SurTYP.class); static {
     971        Surtyp.put(SurTYP.TYP_UNKN, new S57enum(0, ""));
     972        Surtyp.put(SurTYP.TYP_SKCH, new S57enum(1, "sketch")); Surtyp.put(SurTYP.TYP_CTLD, new S57enum(2, "controlled")); Surtyp.put(SurTYP.TYP_PSSG, new S57enum(4, "examination"));
     973        Surtyp.put(SurTYP.TYP_PSSG, new S57enum(5, "passage")); Surtyp.put(SurTYP.TYP_REMT, new S57enum(6, "remote"));
     974    }
     975
     976    public enum TecSOU { SOU_UNKN, SOU_ESND, SOU_FSSN, SOU_MLBM, SOU_DIVR, SOU_LDLN, SOU_WDRG, SOU_LASR, SOU_VACC, SOU_EMAG, SOU_PHGY, SOU_SATL, SOU_LEVL, SOU_SSSN, SOU_COMP }
     977
     978    private static final EnumMap<TecSOU, S57enum> Tecsou = new EnumMap<>(TecSOU.class); static {
     979        Tecsou.put(TecSOU.SOU_UNKN, new S57enum(0, ""));
     980        Tecsou.put(TecSOU.SOU_ESND, new S57enum(1, "echo-sounder")); Tecsou.put(TecSOU.SOU_FSSN, new S57enum(2, "side-scan_sonar")); Tecsou.put(TecSOU.SOU_MLBM, new S57enum(3, "multi-beam"));
     981        Tecsou.put(TecSOU.SOU_DIVR, new S57enum(4, "diver")); Tecsou.put(TecSOU.SOU_LDLN, new S57enum(5, "lead-line")); Tecsou.put(TecSOU.SOU_WDRG, new S57enum(6, "wire-drag"));
     982        Tecsou.put(TecSOU.SOU_LASR, new S57enum(7, "laser")); Tecsou.put(TecSOU.SOU_VACC, new S57enum(8, "vertical_acoustic")); Tecsou.put(TecSOU.SOU_EMAG, new S57enum(9, "electromagnetic"));
     983        Tecsou.put(TecSOU.SOU_PHGY, new S57enum(10, "photogrammetry")); Tecsou.put(TecSOU.SOU_SATL, new S57enum(11, "satellite")); Tecsou.put(TecSOU.SOU_LEVL, new S57enum(12, "levelling"));
     984        Tecsou.put(TecSOU.SOU_SSSN, new S57enum(13, "side-scan_sonar_swept")); Tecsou.put(TecSOU.SOU_COMP, new S57enum(14, "computer"));
     985    }
     986
     987    public enum TopSHP { TOP_UNKN, TOP_CONE, TOP_ICONE, TOP_SPHR, TOP_ISD, TOP_CAN, TOP_BORD, TOP_SALT, TOP_CROS, TOP_CUBE, TOP_WEST, TOP_EAST, TOP_RHOM,
     988        TOP_NORTH, TOP_SOUTH, TOP_BESM, TOP_IBESM, TOP_FLAG, TOP_SPRH, TOP_SQUR, TOP_HRECT, TOP_VRECT, TOP_TRAP, TOP_ITRAP, TOP_TRI, TOP_ITRI, TOP_CIRC,
     989        TOP_CRSS, TOP_T, TOP_TRCL, TOP_CRCL, TOP_RHCL, TOP_CLTR, TOP_OTHR, TOP_CYSP, TOP_COSP }
     990
     991    private static final EnumMap<TopSHP, S57enum> Topshp = new EnumMap<>(TopSHP.class); static {
     992        Topshp.put(TopSHP.TOP_UNKN, new S57enum(0, ""));
     993        Topshp.put(TopSHP.TOP_CONE, new S57enum(1, "cone, point up")); Topshp.put(TopSHP.TOP_ICONE, new S57enum(2, "cone, point down")); Topshp.put(TopSHP.TOP_SPHR, new S57enum(3, "sphere"));
     994        Topshp.put(TopSHP.TOP_ISD, new S57enum(4, "2 spheres")); Topshp.put(TopSHP.TOP_CAN, new S57enum(5, "cylinder")); Topshp.put(TopSHP.TOP_BORD, new S57enum(6, "board"));
     995        Topshp.put(TopSHP.TOP_SALT, new S57enum(7, "x-shape")); Topshp.put(TopSHP.TOP_CROS, new S57enum(8, "cross")); Topshp.put(TopSHP.TOP_CUBE, new S57enum(9, "cube, point up"));
     996        Topshp.put(TopSHP.TOP_WEST, new S57enum(10, "2 cones point together")); Topshp.put(TopSHP.TOP_EAST, new S57enum(11, "2 cones base together")); Topshp.put(TopSHP.TOP_RHOM, new S57enum(12, "rhombus"));
     997        Topshp.put(TopSHP.TOP_NORTH, new S57enum(13, "2 cones up")); Topshp.put(TopSHP.TOP_SOUTH, new S57enum(14, "2 cones down")); Topshp.put(TopSHP.TOP_BESM, new S57enum(15, "besom, point up"));
     998        Topshp.put(TopSHP.TOP_IBESM, new S57enum(16, "besom, point down")); Topshp.put(TopSHP.TOP_FLAG, new S57enum(17, "flag")); Topshp.put(TopSHP.TOP_SPRH, new S57enum(18, "sphere over rhombus"));
     999        Topshp.put(TopSHP.TOP_SQUR, new S57enum(19, "square")); Topshp.put(TopSHP.TOP_HRECT, new S57enum(20, "rectangle, horizontal")); Topshp.put(TopSHP.TOP_VRECT, new S57enum(21, "rectangle, vertical"));
     1000        Topshp.put(TopSHP.TOP_TRAP, new S57enum(22, "trapezium, up")); Topshp.put(TopSHP.TOP_ITRAP, new S57enum(23, "trapezium, down")); Topshp.put(TopSHP.TOP_TRI, new S57enum(24, "triangle, point up"));
     1001        Topshp.put(TopSHP.TOP_ITRI, new S57enum(25, "triangle, point down")); Topshp.put(TopSHP.TOP_CIRC, new S57enum(26, "circle")); Topshp.put(TopSHP.TOP_CRSS, new S57enum(27, "2 upright crosses"));
     1002        Topshp.put(TopSHP.TOP_T, new S57enum(28, "t-shape")); Topshp.put(TopSHP.TOP_TRCL, new S57enum(29, "triangle, point up over circle")); Topshp.put(TopSHP.TOP_CRCL, new S57enum(30, "upright cross over circle"));
     1003        Topshp.put(TopSHP.TOP_RHCL, new S57enum(31, "rhombus over circle")); Topshp.put(TopSHP.TOP_CLTR, new S57enum(32, "circle over triangle, point up")); Topshp.put(TopSHP.TOP_OTHR, new S57enum(33, "other"));
     1004        Topshp.put(TopSHP.TOP_CYSP, new S57enum(34, "cylinder over sphere")); Topshp.put(TopSHP.TOP_COSP, new S57enum(35, "cone, point up over sphere"));
     1005    }
     1006
     1007    public enum TrfTRF { TRF_UNKN, TRF_INBD, TRF_OBND, TRF_ONEW, TRF_TWOW }
     1008
     1009    private static final EnumMap<TrfTRF, S57enum> Trafic = new EnumMap<>(TrfTRF.class); static {
     1010        Trafic.put(TrfTRF.TRF_UNKN, new S57enum(0, ""));
     1011        Trafic.put(TrfTRF.TRF_INBD, new S57enum(1, "inbound")); Trafic.put(TrfTRF.TRF_OBND, new S57enum(2, "outbbound")); Trafic.put(TrfTRF.TRF_ONEW, new S57enum(3, "one-way"));
     1012        Trafic.put(TrfTRF.TRF_TWOW, new S57enum(4, "two-way"));
     1013    }
     1014
     1015    public enum WatLEV { LEV_UNKN, LEV_PSUB, LEV_DRY, LEV_SUBM, LEV_CVRS, LEV_AWSH, LEV_FLDS, LEV_FLTG, LEV_AMWL, LEV_BMWL }
     1016
     1017    private static final EnumMap<WatLEV, S57enum> Watlev = new EnumMap<>(WatLEV.class); static {
     1018        Watlev.put(WatLEV.LEV_UNKN, new S57enum(0, ""));
     1019        Watlev.put(WatLEV.LEV_PSUB, new S57enum(1, "part-submerged")); Watlev.put(WatLEV.LEV_DRY, new S57enum(2, "dry")); Watlev.put(WatLEV.LEV_SUBM, new S57enum(3, "submerged"));
     1020        Watlev.put(WatLEV.LEV_CVRS, new S57enum(4, "covers")); Watlev.put(WatLEV.LEV_AWSH, new S57enum(5, "awash")); Watlev.put(WatLEV.LEV_FLDS, new S57enum(6, "floods"));
     1021        Watlev.put(WatLEV.LEV_FLTG, new S57enum(7, "floating")); Watlev.put(WatLEV.LEV_AMWL, new S57enum(8, "above_mwl")); Watlev.put(WatLEV.LEV_BMWL, new S57enum(9, "below_mwl"));
     1022    }
     1023
     1024    public enum Cat_TS { TS_UNKN, TS_FLOD, TS_EBB, TS_OTHR }
     1025
     1026    private static final EnumMap<Cat_TS, S57enum> Cat_ts = new EnumMap<>(Cat_TS.class); static {
     1027        Cat_ts.put(Cat_TS.TS_UNKN, new S57enum(0, ""));
     1028        Cat_ts.put(Cat_TS.TS_FLOD, new S57enum(1, "flood")); Cat_ts.put(Cat_TS.TS_EBB, new S57enum(2, "ebb")); Cat_ts.put(Cat_TS.TS_OTHR, new S57enum(3, "other"));
     1029    }
     1030
     1031    public enum UniPAU { PAU_UNKN, PAU_MTRS, PAU_DGRS, PAU_MMTR, PAU_FEET, PAU_CBLS }
     1032
     1033    private static final EnumMap<UniPAU, S57enum> Punits = new EnumMap<>(UniPAU.class); static {
     1034        Punits.put(UniPAU.PAU_UNKN, new S57enum(0, ""));
     1035        Punits.put(UniPAU.PAU_MTRS, new S57enum(1, "metres")); Punits.put(UniPAU.PAU_DGRS, new S57enum(2, "degrees")); Punits.put(UniPAU.PAU_MMTR, new S57enum(3, "millimetres"));
     1036        Punits.put(UniPAU.PAU_FEET, new S57enum(4, "feet")); Punits.put(UniPAU.PAU_CBLS, new S57enum(5, "cables"));
     1037    }
     1038
     1039    public enum QuaPOS { POS_UNKN, POS_SRVD, POS_USRV, POS_PSRV, POS_APRX, POS_DBTF, POS_URLB, POS_RSRV, POS_UCNF, POS_ESTM, POS_PRCS, POS_CALC }
     1040
     1041    private static final EnumMap<QuaPOS, S57enum> Quapos = new EnumMap<>(QuaPOS.class); static {
     1042        Quapos.put(QuaPOS.POS_UNKN, new S57enum(0, ""));
     1043        Quapos.put(QuaPOS.POS_SRVD, new S57enum(1, "surveyed")); Quapos.put(QuaPOS.POS_USRV, new S57enum(2, "unsurveyed")); Quapos.put(QuaPOS.POS_PSRV, new S57enum(3, "part-surveyed"));
     1044        Quapos.put(QuaPOS.POS_APRX, new S57enum(4, "approximate")); Quapos.put(QuaPOS.POS_DBTF, new S57enum(5, "doubtful")); Quapos.put(QuaPOS.POS_URLB, new S57enum(6, "unreliable"));
     1045        Quapos.put(QuaPOS.POS_RSRV, new S57enum(7, "reported_unsurveyd")); Quapos.put(QuaPOS.POS_UCNF, new S57enum(8, "unconfirmed")); Quapos.put(QuaPOS.POS_ESTM, new S57enum(9, "estimated"));
     1046        Quapos.put(QuaPOS.POS_PRCS, new S57enum(10, "precise")); Quapos.put(QuaPOS.POS_CALC, new S57enum(11, "calculated"));
     1047    }
     1048
     1049    public enum VerDAT { DAT_UNKN, DAT_MLWS, DAT_MLLWS, DAT_MSL, DAT_LLW, DAT_MLW, DAT_LLWS, DAT_AMLWS, DAT_ISLW, DAT_LWS, DAT_ALAT, DAT_NLLW, DAT_MLLW, DAT_LW, DAT_AMLW, DAT_AMLLW,
     1050        DAT_MHW, DAT_MHWS, DAT_HW, DAT_AMSL, DAT_HWS, DAT_MHHW, DAT_ESLW, DAT_LAT, DAT_LOCAL, DAT_IGLD, DAT_MWL, DAT_LLWLT, DAT_HHWLT, DAT_NHHW, DAT_HAT, DAT_LLWRL, DAT_LHWRL,
     1051        DAT_LMWRL, DAT_EHW, DAT_HSHW, DAT_RLWL, DAT_HSHWD, DAT_DRLWRL, DAT_RPWL, DAT_RNBL, DAT_OHIO }
     1052
     1053    private static final EnumMap<VerDAT, S57enum> Verdat = new EnumMap<>(VerDAT.class); static {
     1054        Verdat.put(VerDAT.DAT_UNKN, new S57enum(0, ""));
     1055        Verdat.put(VerDAT.DAT_MLWS, new S57enum(1, "mlws")); Verdat.put(VerDAT.DAT_MLLWS, new S57enum(2, "mllws")); Verdat.put(VerDAT.DAT_MSL, new S57enum(3, "msl"));
     1056        Verdat.put(VerDAT.DAT_LLW, new S57enum(4, "llw")); Verdat.put(VerDAT.DAT_MLW, new S57enum(5, "mlw")); Verdat.put(VerDAT.DAT_LLWS, new S57enum(6, "llws"));
     1057        Verdat.put(VerDAT.DAT_AMLWS, new S57enum(7, "amlws")); Verdat.put(VerDAT.DAT_ISLW, new S57enum(8, "islw")); Verdat.put(VerDAT.DAT_LWS, new S57enum(9, "lws"));
     1058        Verdat.put(VerDAT.DAT_ALAT, new S57enum(10, "alat")); Verdat.put(VerDAT.DAT_NLLW, new S57enum(11, "nllw")); Verdat.put(VerDAT.DAT_MLLW, new S57enum(12, "mllw"));
     1059        Verdat.put(VerDAT.DAT_LW, new S57enum(13, "lw")); Verdat.put(VerDAT.DAT_AMLW, new S57enum(14, "amlw")); Verdat.put(VerDAT.DAT_AMLLW, new S57enum(15, "amllw"));
     1060        Verdat.put(VerDAT.DAT_MHW, new S57enum(16, "mhw")); Verdat.put(VerDAT.DAT_MHWS, new S57enum(17, "mhws")); Verdat.put(VerDAT.DAT_HW, new S57enum(18, "hw"));
     1061        Verdat.put(VerDAT.DAT_AMSL, new S57enum(19, "amsl")); Verdat.put(VerDAT.DAT_HWS, new S57enum(20, "hws")); Verdat.put(VerDAT.DAT_MHHW, new S57enum(21, "mhhw"));
     1062        Verdat.put(VerDAT.DAT_ESLW, new S57enum(22, "eslw")); Verdat.put(VerDAT.DAT_LAT, new S57enum(23, "lat")); Verdat.put(VerDAT.DAT_LOCAL, new S57enum(24, "local"));
     1063        Verdat.put(VerDAT.DAT_IGLD, new S57enum(25, "igld1985")); Verdat.put(VerDAT.DAT_MWL, new S57enum(26, "mwl")); Verdat.put(VerDAT.DAT_LLWLT, new S57enum(27, "llwlt"));
     1064        Verdat.put(VerDAT.DAT_HHWLT, new S57enum(28, "hhwlt")); Verdat.put(VerDAT.DAT_NHHW, new S57enum(29, "nhhw")); Verdat.put(VerDAT.DAT_HAT, new S57enum(30, "hat"));
     1065        Verdat.put(VerDAT.DAT_LLWRL, new S57enum(31, "llwrl")); Verdat.put(VerDAT.DAT_LHWRL, new S57enum(32, "lhwrl")); Verdat.put(VerDAT.DAT_LMWRL, new S57enum(33, "lmwrl"));
     1066        Verdat.put(VerDAT.DAT_EHW, new S57enum(34, "ehw_dglw")); Verdat.put(VerDAT.DAT_HSHW, new S57enum(35, "hshw_dhsw")); Verdat.put(VerDAT.DAT_RLWL, new S57enum(36, "rlwl_donau"));
     1067        Verdat.put(VerDAT.DAT_HSHWD, new S57enum(37, "hshw_donau")); Verdat.put(VerDAT.DAT_DRLWRL, new S57enum(38, "drlwrl_olr")); Verdat.put(VerDAT.DAT_RPWL, new S57enum(39, "rpwl"));
     1068        Verdat.put(VerDAT.DAT_RNBL, new S57enum(40, "rnbl")); Verdat.put(VerDAT.DAT_OHIO, new S57enum(41, "ohio_rd"));
     1069    }
     1070
     1071    public enum AddMRK { MRK_UNKN, MRK_TOPB, MRK_BOTB, MRK_RTRI, MRK_LTRI, MRK_BTRI }
     1072
     1073    private static final EnumMap<AddMRK, S57enum> Addmrk = new EnumMap<>(AddMRK.class); static {
     1074        Addmrk.put(AddMRK.MRK_UNKN, new S57enum(0, ""));
     1075        Addmrk.put(AddMRK.MRK_TOPB, new S57enum(1, "top_board")); Addmrk.put(AddMRK.MRK_BOTB, new S57enum(2, "bottom_board")); Addmrk.put(AddMRK.MRK_RTRI, new S57enum(3, "right_triangle"));
     1076        Addmrk.put(AddMRK.MRK_LTRI, new S57enum(4, "left_triangle")); Addmrk.put(AddMRK.MRK_BTRI, new S57enum(5, "bottom_triangle"));
     1077    }
     1078
     1079    public enum BnkWTW { BWW_UNKN, BWW_LEFT, BWW_RGHT }
     1080
     1081    private static final EnumMap<BnkWTW, S57enum> Bnkwtw = new EnumMap<>(BnkWTW.class); static {
     1082        Bnkwtw.put(BnkWTW.BWW_UNKN, new S57enum(0, ""));
     1083        Bnkwtw.put(BnkWTW.BWW_LEFT, new S57enum(1, "left")); Bnkwtw.put(BnkWTW.BWW_RGHT, new S57enum(2, "right"));
     1084    }
     1085
     1086    public enum CatNMK { NMK_UNKN, NMK_NENT, NMK_CLSA, NMK_NOVK, NMK_NCOV, NMK_NPAS, NMK_NBRT, NMK_NBLL, NMK_NANK, NMK_NMOR, NMK_NTRN, NMK_NWSH,
     1087        NMK_NPSL, NMK_NPSR, NMK_NMTC, NMK_NSPC, NMK_NWSK, NMK_NSLC, NMK_NUPC, NMK_NSLB, NMK_NWBK, NMK_NHSC, NMK_NLBG, NMK_MVTL, NMK_MVTR, NMK_MVTP,
     1088        NMK_MVTS, NMK_KPTP, NMK_KPTS, NMK_CSTP, NMK_CSTS, NMK_STOP, NMK_SPDL, NMK_SHRN, NMK_KPLO, NMK_GWJN, NMK_GWCS, NMK_MKRC, NMK_LMDP, NMK_LMHR,
     1089        NMK_LMWD, NMK_NAVR, NMK_CHDL, NMK_CHDR, NMK_CHTW, NMK_CHOW, NMK_OPTR, NMK_OPTL, NMK_PRTL, NMK_PRTR, NMK_ENTP, NMK_OVHC, NMK_WEIR, NMK_FERN,
     1090        NMK_FERI, NMK_BRTP, NMK_BTLL, NMK_BTLS, NMK_BTRL, NMK_BTUP, NMK_BTP1, NMK_BTP2, NMK_BTP3, NMK_BTUN, NMK_BTN1, NMK_BTN2, NMK_BTN3, NMK_BTUM,
     1091        NMK_BTU1, NMK_BTU2, NMK_BTU3, NMK_ANKP, NMK_MORP, NMK_VLBT, NMK_TRNA, NMK_SWWC, NMK_SWWR, NMK_SWWL, NMK_WRSA, NMK_WLSA, NMK_WRSL, NMK_WLSR,
     1092        NMK_WRAL, NMK_WLAR, NMK_MWWC, NMK_MWWJ, NMK_MWAR, NMK_MWAL, NMK_WARL, NMK_WALR, NMK_PEND, NMK_DWTR, NMK_TELE, NMK_MTCP, NMK_SPCP, NMK_WSKP,
     1093        NMK_SLCP, NMK_UPCP, NMK_SLBP, NMK_RADI, NMK_WTBP, NMK_HSCP, NMK_LBGP, NMK_KTPM, NMK_KTSM, NMK_KTMR, NMK_CRTP, NMK_CRTS, NMK_TRBM, NMK_RSPD,
     1094        NMK_WRKP, NMK_PSBS, NMK_NCPS, NMK_NSMC, NMK_ATTN, NMK_FWCR, NMK_SHIP }
     1095
     1096    private static final EnumMap<CatNMK, S57enum> Catnmk = new EnumMap<>(CatNMK.class); static {
     1097        Catnmk.put(CatNMK.NMK_UNKN, new S57enum(0, ""));
     1098        Catnmk.put(CatNMK.NMK_NENT, new S57enum(1, "no_entry")); Catnmk.put(CatNMK.NMK_CLSA, new S57enum(2, "closed_area")); Catnmk.put(CatNMK.NMK_NOVK, new S57enum(3, "no_overtaking"));
     1099        Catnmk.put(CatNMK.NMK_NCOV, new S57enum(4, "no_convoy_overtaking")); Catnmk.put(CatNMK.NMK_NPAS, new S57enum(5, "no_passing")); Catnmk.put(CatNMK.NMK_NBRT, new S57enum(6, "no_berthing"));
     1100        Catnmk.put(CatNMK.NMK_NBLL, new S57enum(7, "no_berthing_lateral_limit")); Catnmk.put(CatNMK.NMK_NANK, new S57enum(8, "no_anchoring")); Catnmk.put(CatNMK.NMK_NMOR, new S57enum(9, "no_mooring"));
     1101        Catnmk.put(CatNMK.NMK_NTRN, new S57enum(10, "no_turning")); Catnmk.put(CatNMK.NMK_NWSH, new S57enum(11, "no_wash")); Catnmk.put(CatNMK.NMK_NPSL, new S57enum(12, "no_passage_left"));
     1102        Catnmk.put(CatNMK.NMK_NPSR, new S57enum(13, "no_passage_right")); Catnmk.put(CatNMK.NMK_NMTC, new S57enum(14, "no_motor_craft")); Catnmk.put(CatNMK.NMK_NSPC, new S57enum(15, "no_sport_craft"));
     1103        Catnmk.put(CatNMK.NMK_NWSK, new S57enum(16, "no_waterskiing")); Catnmk.put(CatNMK.NMK_NSLC, new S57enum(17, "no_sailing_craft")); Catnmk.put(CatNMK.NMK_NUPC, new S57enum(18, "no_unpowered_craft"));
     1104        Catnmk.put(CatNMK.NMK_NSLB, new S57enum(19, "no_sailboards")); Catnmk.put(CatNMK.NMK_NWBK, new S57enum(20, "no_waterbikes")); Catnmk.put(CatNMK.NMK_NHSC, new S57enum(21, "no_high_speeds"));
     1105        Catnmk.put(CatNMK.NMK_NLBG, new S57enum(22, "no_launching_beaching")); Catnmk.put(CatNMK.NMK_MVTL, new S57enum(23, "move_to_left")); Catnmk.put(CatNMK.NMK_MVTR, new S57enum(24, "move_to_right"));
     1106        Catnmk.put(CatNMK.NMK_MVTP, new S57enum(25, "move_to_port")); Catnmk.put(CatNMK.NMK_MVTS, new S57enum(26, "move_to_starboard")); Catnmk.put(CatNMK.NMK_KPTP, new S57enum(27, "keep_to_port"));
     1107        Catnmk.put(CatNMK.NMK_KPTS, new S57enum(28, "keep_to_starboard")); Catnmk.put(CatNMK.NMK_CSTP, new S57enum(29, "cross_to_port")); Catnmk.put(CatNMK.NMK_CSTS, new S57enum(30, "cross_to_starboard"));
     1108        Catnmk.put(CatNMK.NMK_STOP, new S57enum(31, "stop")); Catnmk.put(CatNMK.NMK_SPDL, new S57enum(32, "speed_limit")); Catnmk.put(CatNMK.NMK_SHRN, new S57enum(33, "sound_horn"));
     1109        Catnmk.put(CatNMK.NMK_KPLO, new S57enum(34, "keep_lookout")); Catnmk.put(CatNMK.NMK_GWJN, new S57enum(35, "give_way_junction")); Catnmk.put(CatNMK.NMK_GWCS, new S57enum(36, "give_way_crossing"));
     1110        Catnmk.put(CatNMK.NMK_MKRC, new S57enum(37, "make_radio_contact")); Catnmk.put(CatNMK.NMK_LMDP, new S57enum(38, "limited_depth")); Catnmk.put(CatNMK.NMK_LMHR, new S57enum(39, "limited_headroom"));
     1111        Catnmk.put(CatNMK.NMK_LMWD, new S57enum(40, "limited_width")); Catnmk.put(CatNMK.NMK_NAVR, new S57enum(41, "navigation_restrictions")); Catnmk.put(CatNMK.NMK_CHDL, new S57enum(42, "channel_distance_left"));
     1112        Catnmk.put(CatNMK.NMK_CHDR, new S57enum(43, "channel_distance_right")); Catnmk.put(CatNMK.NMK_CHTW, new S57enum(44, "channel_two_way")); Catnmk.put(CatNMK.NMK_CHOW, new S57enum(45, "channel_one_way"));
     1113        Catnmk.put(CatNMK.NMK_OPTR, new S57enum(46, "opening_to_right")); Catnmk.put(CatNMK.NMK_OPTL, new S57enum(47, "opening_to_left")); Catnmk.put(CatNMK.NMK_PRTL, new S57enum(48, "proceed_to_left"));
     1114        Catnmk.put(CatNMK.NMK_PRTR, new S57enum(49, "proceed_to_right")); Catnmk.put(CatNMK.NMK_ENTP, new S57enum(50, "entry_permitted")); Catnmk.put(CatNMK.NMK_OVHC, new S57enum(51, "overhead_cable"));
     1115        Catnmk.put(CatNMK.NMK_WEIR, new S57enum(52, "weir")); Catnmk.put(CatNMK.NMK_FERN, new S57enum(53, "ferry_non_independent")); Catnmk.put(CatNMK.NMK_FERI, new S57enum(54, "ferry_independent"));
     1116        Catnmk.put(CatNMK.NMK_BRTP, new S57enum(55, "berthing_permitted")); Catnmk.put(CatNMK.NMK_BTLL, new S57enum(56, "berthing_lateral_limit")); Catnmk.put(CatNMK.NMK_BTLS, new S57enum(57, "berthing_lateral_limits"));
     1117        Catnmk.put(CatNMK.NMK_BTRL, new S57enum(58, "berth_rafting_limit")); Catnmk.put(CatNMK.NMK_BTUP, new S57enum(59, "berthing_unmarked_pushing"));
     1118        Catnmk.put(CatNMK.NMK_BTP1, new S57enum(60, "berthing_marked_pushing_1")); Catnmk.put(CatNMK.NMK_BTP2, new S57enum(61, "berthing_marked_pushing_2"));
     1119        Catnmk.put(CatNMK.NMK_BTP3, new S57enum(62, "berthing_marked_pushing_3")); Catnmk.put(CatNMK.NMK_BTUN, new S57enum(63, "berthing_unmarked_non-pushing"));
     1120        Catnmk.put(CatNMK.NMK_BTN1, new S57enum(64, "berthing_marked_non-pushing_1")); Catnmk.put(CatNMK.NMK_BTN2, new S57enum(65, "berthing_marked_non-pushing_2"));
     1121        Catnmk.put(CatNMK.NMK_BTN3, new S57enum(66, "berthing_marked_non-pushing_3")); Catnmk.put(CatNMK.NMK_BTUM, new S57enum(67, "berthing_unmarked")); Catnmk.put(CatNMK.NMK_BTU1, new S57enum(68, "berthing_marked_1"));
     1122        Catnmk.put(CatNMK.NMK_BTU2, new S57enum(69, "berthing_marked_2")); Catnmk.put(CatNMK.NMK_BTU3, new S57enum(70, "berthing_marked_3"));
     1123        Catnmk.put(CatNMK.NMK_ANKP, new S57enum(71, "anchoring_permitted")); Catnmk.put(CatNMK.NMK_MORP, new S57enum(72, "mooring_permitted")); Catnmk.put(CatNMK.NMK_VLBT, new S57enum(73, "vehicle_loading_berth"));
     1124        Catnmk.put(CatNMK.NMK_TRNA, new S57enum(74, "turning_area")); Catnmk.put(CatNMK.NMK_SWWC, new S57enum(75, "secondary_waterway_crossing")); Catnmk.put(CatNMK.NMK_SWWR, new S57enum(76, "secondary_waterway_right"));
     1125        Catnmk.put(CatNMK.NMK_SWWL, new S57enum(77, "secondary_waterway_left")); Catnmk.put(CatNMK.NMK_WRSA, new S57enum(78, "main_waterway_right_secondary_ahead"));
     1126        Catnmk.put(CatNMK.NMK_WLSA, new S57enum(79, "main_waterway_left_secondary_ahead")); Catnmk.put(CatNMK.NMK_WRSL, new S57enum(80, "main_waterway_right_secondary_left"));
     1127        Catnmk.put(CatNMK.NMK_WLSR, new S57enum(81, "main_waterway_left_secondary_right")); Catnmk.put(CatNMK.NMK_WRAL, new S57enum(82, "main_waterway_right_secondary_ahead_left"));
     1128        Catnmk.put(CatNMK.NMK_WLAR, new S57enum(83, "main_waterway_left_secondary_ahead_right")); Catnmk.put(CatNMK.NMK_MWWC, new S57enum(84, "main_waterway_crossing"));
     1129        Catnmk.put(CatNMK.NMK_MWWJ, new S57enum(85, "main_waterway_junction")); Catnmk.put(CatNMK.NMK_MWAR, new S57enum(86, "main_waterway_ahead_right"));
     1130        Catnmk.put(CatNMK.NMK_MWAL, new S57enum(87, "main_waterway_ahead_left")); Catnmk.put(CatNMK.NMK_WARL, new S57enum(88, "main_waterway_ahead_right_secondary_left"));
     1131        Catnmk.put(CatNMK.NMK_WALR, new S57enum(89, "main_waterway_ahead_left_secondary_right")); Catnmk.put(CatNMK.NMK_PEND, new S57enum(90, "prohibition_ends"));
     1132        Catnmk.put(CatNMK.NMK_DWTR, new S57enum(91, "drinking_water")); Catnmk.put(CatNMK.NMK_TELE, new S57enum(92, "telephone")); Catnmk.put(CatNMK.NMK_MTCP, new S57enum(93, "motor_craft_permitted"));
     1133        Catnmk.put(CatNMK.NMK_SPCP, new S57enum(94, "sport_craft_permitted")); Catnmk.put(CatNMK.NMK_WSKP, new S57enum(95, "waterskiing_permitted")); Catnmk.put(CatNMK.NMK_SLCP, new S57enum(96, "sailing_craft_permitted"));
     1134        Catnmk.put(CatNMK.NMK_UPCP, new S57enum(97, "unpowered_craft_permitted")); Catnmk.put(CatNMK.NMK_SLBP, new S57enum(98, "sailboards_permitted")); Catnmk.put(CatNMK.NMK_RADI, new S57enum(99, "radio_information"));
     1135        Catnmk.put(CatNMK.NMK_WTBP, new S57enum(100, "waterbikes_permitted")); Catnmk.put(CatNMK.NMK_HSCP, new S57enum(101, "high_speeds_permitted")); Catnmk.put(CatNMK.NMK_LBGP, new S57enum(102, "launching_beaching_permitted"));
     1136        Catnmk.put(CatNMK.NMK_KTPM, new S57enum(103, "keep_to_port_margin")); Catnmk.put(CatNMK.NMK_KTSM, new S57enum(104, "keep_to_starboard_margin")); Catnmk.put(CatNMK.NMK_KTMR, new S57enum(105, "keep_to_mid-river"));
     1137        Catnmk.put(CatNMK.NMK_CRTP, new S57enum(106, "cross_river_to_port")); Catnmk.put(CatNMK.NMK_CRTS, new S57enum(107, "cross_river_to_starboard")); Catnmk.put(CatNMK.NMK_TRBM, new S57enum(108, "traffic_between_margins"));
     1138        Catnmk.put(CatNMK.NMK_RSPD, new S57enum(109, "reduce_speed")); Catnmk.put(CatNMK.NMK_WRKP, new S57enum(110, "wreck_pontoon")); Catnmk.put(CatNMK.NMK_PSBS, new S57enum(111, "pass_both_sides"));
     1139        Catnmk.put(CatNMK.NMK_NCPS, new S57enum(112, "no_convoy_passing")); Catnmk.put(CatNMK.NMK_NSMC, new S57enum(113, "no_small_craft")); Catnmk.put(CatNMK.NMK_ATTN, new S57enum(114, "attention"));
     1140        Catnmk.put(CatNMK.NMK_FWCR, new S57enum(115, "fairway_crossing")); Catnmk.put(CatNMK.NMK_SHIP, new S57enum(112, "shipping_inspection_point"));
     1141    }
     1142
     1143    public enum ClsDNG { DNG_UNKN, DNG_1BLU, DNG_2BLU, DNG_3BLU, DNG_0BLU, DNG_1RED }
     1144
     1145    private static final EnumMap<ClsDNG, S57enum> Clsdng = new EnumMap<>(ClsDNG.class); static {
     1146        Clsdng.put(ClsDNG.DNG_UNKN, new S57enum(0, ""));
     1147        Clsdng.put(ClsDNG.DNG_1BLU, new S57enum(1, "one_blue")); Clsdng.put(ClsDNG.DNG_2BLU, new S57enum(2, "two_blue")); Clsdng.put(ClsDNG.DNG_3BLU, new S57enum(3, "three_blue"));
     1148        Clsdng.put(ClsDNG.DNG_0BLU, new S57enum(4, "no_blue")); Clsdng.put(ClsDNG.DNG_1RED, new S57enum(5, "one_red"));
     1149    }
     1150
     1151    public enum DirIMP { IMP_UNKN, IMP_UPST, IMP_DNST, IMP_LTBK, IMP_RTBK, IMP_THBR }
     1152
     1153    private static final EnumMap<DirIMP, S57enum> Dirimp = new EnumMap<>(DirIMP.class); static {
     1154        Dirimp.put(DirIMP.IMP_UNKN, new S57enum(0, ""));
     1155        Dirimp.put(DirIMP.IMP_UPST, new S57enum(1, "upstream")); Dirimp.put(DirIMP.IMP_DNST, new S57enum(2, "downstream")); Dirimp.put(DirIMP.IMP_LTBK, new S57enum(3, "left_bank"));
     1156        Dirimp.put(DirIMP.IMP_RTBK, new S57enum(4, "right_bank")); Dirimp.put(DirIMP.IMP_THBR, new S57enum(5, "to_harbour"));
     1157    }
     1158
     1159    public enum FncFNM { FNM_UNKN, FNM_PRHB, FNM_RGLN, FNM_RSTN, FNM_RCMD, FNM_INFO }
     1160
     1161    private static final EnumMap<FncFNM, S57enum> Fnctnm = new EnumMap<>(FncFNM.class); static {
     1162        Fnctnm.put(FncFNM.FNM_UNKN, new S57enum(0, ""));
     1163        Fnctnm.put(FncFNM.FNM_PRHB, new S57enum(1, "prohibition")); Fnctnm.put(FncFNM.FNM_RGLN, new S57enum(2, "regulation")); Fnctnm.put(FncFNM.FNM_RSTN, new S57enum(3, "restriction"));
     1164        Fnctnm.put(FncFNM.FNM_RCMD, new S57enum(4, "recommendation")); Fnctnm.put(FncFNM.FNM_INFO, new S57enum(5, "information"));
     1165    }
     1166
     1167    public enum BunVES { VES_UNKN, VES_BVAV, VES_NBVA }
     1168
     1169    private static final EnumMap<BunVES, S57enum> Bunves = new EnumMap<>(BunVES.class); static {
     1170        Bunves.put(BunVES.VES_UNKN, new S57enum(0, ""));
     1171        Bunves.put(BunVES.VES_BVAV, new S57enum(1, "bunker_vessel_available")); Bunves.put(BunVES.VES_NBVA, new S57enum(2, "no_bunker_vessel_available"));
     1172    }
     1173
     1174    public enum CatBRT { BRT_UNKN, BRT_LODG, BRT_ULDG, BRT_OVNT, BRT_PSHN, BRT_NPSH, BRT_FLTG, BRT_FCLS, BRT_SCLS }
     1175
     1176    private static final EnumMap<CatBRT, S57enum> Catbrt = new EnumMap<>(CatBRT.class); static {
     1177        Catbrt.put(CatBRT.BRT_UNKN, new S57enum(0, ""));
     1178        Catbrt.put(CatBRT.BRT_LODG, new S57enum(1, "loading")); Catbrt.put(CatBRT.BRT_ULDG, new S57enum(2, "unloading")); Catbrt.put(CatBRT.BRT_OVNT, new S57enum(3, "overnight_accommodation"));
     1179        Catbrt.put(CatBRT.BRT_PSHN, new S57enum(4, "pushing-navigation")); Catbrt.put(CatBRT.BRT_NPSH, new S57enum(5, "non-pushing-navigation"));
     1180        Catbrt.put(CatBRT.BRT_FLTG, new S57enum(6, "fleeting")); Catbrt.put(CatBRT.BRT_FCLS, new S57enum(7, "first_class")); Catbrt.put(CatBRT.BRT_SCLS, new S57enum(8, "second_class"));
     1181    }
     1182
     1183    public enum CatBUN { BUN_UNKN, BUN_DESL, BUN_WATR, BUN_BLST }
     1184
     1185    private static final EnumMap<CatBUN, S57enum> Catbun = new EnumMap<>(CatBUN.class); static {
     1186        Catbun.put(CatBUN.BUN_UNKN, new S57enum(0, ""));
     1187        Catbun.put(CatBUN.BUN_DESL, new S57enum(1, "diesel")); Catbun.put(CatBUN.BUN_WATR, new S57enum(2, "water")); Catbun.put(CatBUN.BUN_BLST, new S57enum(3, "ballast"));
     1188    }
     1189
     1190    public enum CatCCL { CCL_UNKN, CCL_SMLV, CCL_PNCH, CCL_CMPB, CCL_DMEB, CCL_RHNB, CCL_1BPT, CCL_2PTL, CCL_2PTW, CCL_4BPT, CCL_6BPT, CCL_NCCL }
     1191
     1192    private static final EnumMap<CatCCL, S57enum> Catccl = new EnumMap<>(CatCCL.class); static {
     1193        Catccl.put(CatCCL.CCL_UNKN, new S57enum(0, ""));
     1194        Catccl.put(CatCCL.CCL_SMLV, new S57enum(1, "small_vessels")); Catccl.put(CatCCL.CCL_PNCH, new S57enum(2, "peniche")); Catccl.put(CatCCL.CCL_CMPB, new S57enum(3, "campine_barge"));
     1195        Catccl.put(CatCCL.CCL_DMEB, new S57enum(4, "dortmund-ems_barge")); Catccl.put(CatCCL.CCL_RHNB, new S57enum(5, "rhine-herne_barge")); Catccl.put(CatCCL.CCL_1BPT, new S57enum(6, "1-barge_push-tow"));
     1196        Catccl.put(CatCCL.CCL_2PTL, new S57enum(7, "2-barge_push-tow_long")); Catccl.put(CatCCL.CCL_2PTW, new S57enum(8, "2-barge_push-tow_wide")); Catccl.put(CatCCL.CCL_4BPT, new S57enum(9, "4-barge_push-tow"));
     1197        Catccl.put(CatCCL.CCL_6BPT, new S57enum(10, "6-barge_push-tow")); Catccl.put(CatCCL.CCL_NCCL, new S57enum(11, "no_cemt_class"));
     1198    }
     1199
     1200    public enum CatCOM { COM_UNKN, COM_VTSC, COM_VTSS, COM_IVSP, COM_MID, COM_LOCK, COM_BRDG, COM_CSTM, COM_HRBR }
     1201
     1202    private static final EnumMap<CatCOM, S57enum> Catcom = new EnumMap<>(CatCOM.class); static {
     1203        Catcom.put(CatCOM.COM_UNKN, new S57enum(0, ""));
     1204        Catcom.put(CatCOM.COM_VTSC, new S57enum(1, "vts_centre")); Catcom.put(CatCOM.COM_VTSS, new S57enum(2, "vts_sector")); Catcom.put(CatCOM.COM_IVSP, new S57enum(3, "ivs_point"));
     1205        Catcom.put(CatCOM.COM_MID, new S57enum(4, "mib")); Catcom.put(CatCOM.COM_LOCK, new S57enum(5, "lock")); Catcom.put(CatCOM.COM_BRDG, new S57enum(6, "bridge"));
     1206        Catcom.put(CatCOM.COM_CSTM, new S57enum(7, "customs")); Catcom.put(CatCOM.COM_HRBR, new S57enum(8, "harbour"));
     1207    }
     1208
     1209    public enum CatHBR { HBR_UNKN, HBR_CSTM, HBR_REFG, HBR_MRNA, HBR_FISH, HBR_PRIV, HBR_ }
     1210
     1211    private static final EnumMap<CatHBR, S57enum> Cathbr = new EnumMap<>(CatHBR.class); static {
     1212        Cathbr.put(CatHBR.HBR_UNKN, new S57enum(0, ""));
     1213        Cathbr.put(CatHBR.HBR_CSTM, new S57enum(1, "customs")); Cathbr.put(CatHBR.HBR_REFG, new S57enum(2, "refuge")); Cathbr.put(CatHBR.HBR_MRNA, new S57enum(3, "marina"));
     1214        Cathbr.put(CatHBR.HBR_FISH, new S57enum(4, "fishing")); Cathbr.put(CatHBR.HBR_PRIV, new S57enum(5, "private"));
     1215    }
     1216
     1217    public enum CatRFD { RFD_UNKN, RFD_CRSD, RFD_WOIL, RFD_GBWT, RFD_DREF }
     1218
     1219    private static final EnumMap<CatRFD, S57enum> Catrfd = new EnumMap<>(CatRFD.class); static {
     1220        Catrfd.put(CatRFD.RFD_UNKN, new S57enum(0, ""));
     1221        Catrfd.put(CatRFD.RFD_CRSD, new S57enum(1, "cargo_residue")); Catrfd.put(CatRFD.RFD_WOIL, new S57enum(2, "waste_oil")); Catrfd.put(CatRFD.RFD_GBWT, new S57enum(3, "grey_black_water"));
     1222        Catrfd.put(CatRFD.RFD_DREF, new S57enum(4, "domestic_refuse"));
     1223    }
     1224
     1225    public enum CatTML { TML_UNKN, TML_PSGR, TML_FERY, TML_TSPT, TML_RORO }
     1226
     1227    private static final EnumMap<CatTML, S57enum> Cattml = new EnumMap<>(CatTML.class); static {
     1228        Cattml.put(CatTML.TML_UNKN, new S57enum(0, ""));
     1229        Cattml.put(CatTML.TML_PSGR, new S57enum(1, "passenger")); Cattml.put(CatTML.TML_FERY, new S57enum(2, "ferry")); Cattml.put(CatTML.TML_TSPT, new S57enum(3, "transhipment"));
     1230        Cattml.put(CatTML.TML_RORO, new S57enum(4, "roro"));
     1231    }
     1232
     1233    public enum TrsTGD { TGD_UNKN, TGD_CONT, TGD_BULK, TGD_OIL, TGD_FUEL, TGD_CHEM, TGD_LIQD, TGD_EXPL, TGD_FISH, TGD_CARS, TGD_GNRL }
     1234
     1235    private static final EnumMap<TrsTGD, S57enum> Trshgd = new EnumMap<>(TrsTGD.class); static {
     1236        Trshgd.put(TrsTGD.TGD_UNKN, new S57enum(0, ""));
     1237        Trshgd.put(TrsTGD.TGD_CONT, new S57enum(1, "containers")); Trshgd.put(TrsTGD.TGD_BULK, new S57enum(2, "bulk")); Trshgd.put(TrsTGD.TGD_OIL, new S57enum(3, "oil"));
     1238        Trshgd.put(TrsTGD.TGD_FUEL, new S57enum(4, "fuel")); Trshgd.put(TrsTGD.TGD_CHEM, new S57enum(5, "chemicals")); Trshgd.put(TrsTGD.TGD_LIQD, new S57enum(6, "liquid"));
     1239        Trshgd.put(TrsTGD.TGD_EXPL, new S57enum(7, "explosive")); Trshgd.put(TrsTGD.TGD_FISH, new S57enum(8, "fish")); Trshgd.put(TrsTGD.TGD_CARS, new S57enum(9, "cars"));
     1240        Trshgd.put(TrsTGD.TGD_GNRL, new S57enum(10, "general"));
     1241    }
     1242
     1243    public enum CatGAG { GAG_UNKN, GAG_STAF, GAG_RCRD, GAG_RCRA, GAG_RCEI, GAG_RRAI }
     1244
     1245    private static final EnumMap<CatGAG, S57enum> Catgag = new EnumMap<>(CatGAG.class); static {
     1246        Catgag.put(CatGAG.GAG_UNKN, new S57enum(0, ""));
     1247        Catgag.put(CatGAG.GAG_STAF, new S57enum(1, "staff")); Catgag.put(CatGAG.GAG_RCRD, new S57enum(2, "recording")); Catgag.put(CatGAG.GAG_RCRA, new S57enum(3, "recording_remote_access"));
     1248        Catgag.put(CatGAG.GAG_RCEI, new S57enum(4, "recording_external_indicator")); Catgag.put(CatGAG.GAG_RRAI, new S57enum(5, "recording_remote_access_indicator"));
     1249    }
     1250
     1251    public enum RefLEV { LEV_UNKN, LEV_BALT, LEV_ADRC, LEV_AMSD, LEV_MSL, LEV_OTHR, LEV_NG29, LEV_NA88, LEV_1912, LEV_1929 }
     1252
     1253    private static final EnumMap<RefLEV, S57enum> Reflev = new EnumMap<>(RefLEV.class); static {
     1254        Reflev.put(RefLEV.LEV_UNKN, new S57enum(0, ""));
     1255        Reflev.put(RefLEV.LEV_BALT, new S57enum(1, "baltic")); Reflev.put(RefLEV.LEV_ADRC, new S57enum(2, "adriatic")); Reflev.put(RefLEV.LEV_AMSD, new S57enum(3, "amsterdam"));
     1256        Reflev.put(RefLEV.LEV_MSL, new S57enum(4, "msl")); Reflev.put(RefLEV.LEV_OTHR, new S57enum(5, "other")); Reflev.put(RefLEV.LEV_NG29, new S57enum(6, "ngvd29"));
     1257        Reflev.put(RefLEV.LEV_NA88, new S57enum(7, "navd88")); Reflev.put(RefLEV.LEV_1912, new S57enum(8, "msl1912")); Reflev.put(RefLEV.LEV_1929, new S57enum(9, "msl1929"));
     1258    }
     1259
     1260    public enum CatVTR { VTR_UNKN, VTR_OFFL, VTR_PRIV, VTR_CARC, VTR_CARP, VTR_PREQ, VTR_LGAT }
     1261
     1262    private static final EnumMap<CatVTR, S57enum> Catvtr = new EnumMap<>(CatVTR.class); static {
     1263        Catvtr.put(CatVTR.VTR_UNKN, new S57enum(0, ""));
     1264        Catvtr.put(CatVTR.VTR_OFFL, new S57enum(1, "official")); Catvtr.put(CatVTR.VTR_PRIV, new S57enum(2, "private")); Catvtr.put(CatVTR.VTR_CARC, new S57enum(3, "car_cranes"));
     1265        Catvtr.put(CatVTR.VTR_CARP, new S57enum(4, "car_planks")); Catvtr.put(CatVTR.VTR_PREQ, new S57enum(5, "permission_required")); Catvtr.put(CatVTR.VTR_LGAT, new S57enum(6, "locked_gate"));
     1266    }
     1267
     1268    public enum CatTAB { TAB_UNKN, TAB_OPPD, TAB_NOPP }
     1269
     1270    private static final EnumMap<CatTAB, S57enum> Cattab = new EnumMap<>(CatTAB.class); static {
     1271        Cattab.put(CatTAB.TAB_UNKN, new S57enum(0, ""));
     1272        Cattab.put(CatTAB.TAB_OPPD, new S57enum(1, "operational_period")); Cattab.put(CatTAB.TAB_NOPP, new S57enum(2, "non-operational_period"));
     1273    }
     1274
     1275    public enum UseSHP { SHP_UNKN, SHP_LINT, SHP_OCSH, SHP_LESR }
     1276
     1277    private static final EnumMap<UseSHP, S57enum> Useshp = new EnumMap<>(UseSHP.class); static {
     1278        Useshp.put(UseSHP.SHP_UNKN, new S57enum(0, ""));
     1279        Useshp.put(UseSHP.SHP_LINT, new S57enum(1, "liner_trade")); Useshp.put(UseSHP.SHP_OCSH, new S57enum(2, "occasional_professional_shipping")); Useshp.put(UseSHP.SHP_LESR, new S57enum(3, "leisure"));
     1280    }
     1281
     1282    public enum CatEXS { EXS_UNKN, EXS_LLOK, EXS_AQDT, EXS_SPLK, EXS_WSLK, EXS_OTHR }
     1283
     1284    private static final EnumMap<CatEXS, S57enum> Catexs = new EnumMap<>(CatEXS.class); static {
     1285        Catexs.put(CatEXS.EXS_UNKN, new S57enum(0, ""));
     1286        Catexs.put(CatEXS.EXS_LLOK, new S57enum(1, "lift-lock")); Catexs.put(CatEXS.EXS_AQDT, new S57enum(2, "aqueduct")); Catexs.put(CatEXS.EXS_SPLK, new S57enum(3, "sloping_plane_lock"));
     1287        Catexs.put(CatEXS.EXS_WSLK, new S57enum(4, "water_slope_lock")); Catexs.put(CatEXS.EXS_OTHR, new S57enum(5, "other"));
     1288    }
     1289
     1290    public enum CatWWM { WWM_UNKN, WWM_WWRT, WWM_WWLT, WWM_WWSP, WWM_CHRT, WWM_CHLT, WWM_CHSP, WWM_CHRB, WWM_CHLB, WWM_CORT, WWM_COLT, WWM_DGRT, WWM_DGLT,
     1291        WWM_TORT, WWM_TOLT, WWM_JNRT, WWM_JNLT, WWM_HBRT, WWM_HBLT, WWM_BRPR }
     1292
     1293    private static final EnumMap<CatWWM, S57enum> Catwwm = new EnumMap<>(CatWWM.class); static {
     1294        Catwwm.put(CatWWM.WWM_UNKN, new S57enum(0, ""));
     1295        Catwwm.put(CatWWM.WWM_WWRT, new S57enum(1, "waterway_right")); Catwwm.put(CatWWM.WWM_WWLT, new S57enum(2, "waterway_left")); Catwwm.put(CatWWM.WWM_WWSP, new S57enum(3, "waterway_separation"));
     1296        Catwwm.put(CatWWM.WWM_CHRT, new S57enum(4, "channel_right")); Catwwm.put(CatWWM.WWM_CHLT, new S57enum(5, "channel_left")); Catwwm.put(CatWWM.WWM_CHSP, new S57enum(6, "channel_separation"));
     1297        Catwwm.put(CatWWM.WWM_CHRB, new S57enum(7, "channel_right_bank")); Catwwm.put(CatWWM.WWM_CHLB, new S57enum(8, "channel_left_bank")); Catwwm.put(CatWWM.WWM_CORT, new S57enum(9, "crossover_right"));
     1298        Catwwm.put(CatWWM.WWM_COLT, new S57enum(10, "crossover_left")); Catwwm.put(CatWWM.WWM_DGRT, new S57enum(11, "danger_right")); Catwwm.put(CatWWM.WWM_DGLT, new S57enum(12, "danger_left"));
     1299        Catwwm.put(CatWWM.WWM_TORT, new S57enum(13, "turnoff_right")); Catwwm.put(CatWWM.WWM_TOLT, new S57enum(14, "turnoff_left")); Catwwm.put(CatWWM.WWM_JNRT, new S57enum(15, "junction_right"));
     1300        Catwwm.put(CatWWM.WWM_JNLT, new S57enum(16, "junction_left")); Catwwm.put(CatWWM.WWM_HBRT, new S57enum(17, "harbour_right")); Catwwm.put(CatWWM.WWM_HBLT, new S57enum(18, "harbour_left"));
     1301        Catwwm.put(CatWWM.WWM_BRPR, new S57enum(19, "bridge_pier"));
     1302    }
     1303
     1304    public enum Lg_SPR { SPR_UNKN, SPR_OTHR, SPR_SPOG, SPR_SPTW }
     1305
     1306    private static final EnumMap<Lg_SPR, S57enum> Lg_spr = new EnumMap<>(Lg_SPR.class); static {
     1307        Lg_spr.put(Lg_SPR.SPR_UNKN, new S57enum(0, ""));
     1308        Lg_spr.put(Lg_SPR.SPR_OTHR, new S57enum(1, "other")); Lg_spr.put(Lg_SPR.SPR_SPOG, new S57enum(2, "speed_over_ground")); Lg_spr.put(Lg_SPR.SPR_SPTW, new S57enum(3, "speed_through_water"));
     1309    }
     1310
     1311    public enum Lg_WDU { WDU_UNKN, WDU_OTHR, WDU_CUMT, WDU_TONS }
     1312
     1313    private static final EnumMap<Lg_WDU, S57enum> Lg_wdu = new EnumMap<>(Lg_WDU.class); static {
     1314        Lg_wdu.put(Lg_WDU.WDU_UNKN, new S57enum(0, ""));
     1315        Lg_wdu.put(Lg_WDU.WDU_OTHR, new S57enum(1, "other")); Lg_wdu.put(Lg_WDU.WDU_CUMT, new S57enum(2, "cubic_metres")); Lg_wdu.put(Lg_WDU.WDU_TONS, new S57enum(3, "tonnes"));
     1316    }
     1317
     1318    public enum Lg_REL { REL_UNKN, REL_OTHR, REL_USWW, REL_CREQ, REL_TKOP }
     1319
     1320    private static final EnumMap<Lg_REL, S57enum> Lg_rel = new EnumMap<>(Lg_REL.class); static {
     1321        Lg_rel.put(Lg_REL.REL_UNKN, new S57enum(0, ""));
     1322        Lg_rel.put(Lg_REL.REL_OTHR, new S57enum(1, "other")); Lg_rel.put(Lg_REL.REL_USWW, new S57enum(2, "usage_of_waterway")); Lg_rel.put(Lg_REL.REL_CREQ, new S57enum(3, "carriage_of_equipment"));
     1323        Lg_rel.put(Lg_REL.REL_TKOP, new S57enum(4, "task_operation"));
     1324    }
     1325
     1326    public enum Lg_FNC { FNC_UNKN, FNC_OTHR, FNC_PRHB, FNC_PRHE, FNC_PERM, FNC_PERE, FNC_RCMD, FNC_NRCD }
     1327
     1328    private static final EnumMap<Lg_FNC, S57enum> Lg_fnc = new EnumMap<>(Lg_FNC.class); static {
     1329        Lg_fnc.put(Lg_FNC.FNC_UNKN, new S57enum(0, ""));
     1330        Lg_fnc.put(Lg_FNC.FNC_OTHR, new S57enum(1, "other")); Lg_fnc.put(Lg_FNC.FNC_PRHB, new S57enum(2, "prohibited")); Lg_fnc.put(Lg_FNC.FNC_PRHE, new S57enum(3, "prohibited_with_exceptions"));
     1331        Lg_fnc.put(Lg_FNC.FNC_PERM, new S57enum(4, "permitted")); Lg_fnc.put(Lg_FNC.FNC_PERE, new S57enum(5, "permitted_with_exceptions")); Lg_fnc.put(Lg_FNC.FNC_RCMD, new S57enum(6, "recommended"));
     1332        Lg_fnc.put(Lg_FNC.FNC_NRCD, new S57enum(7, "not_recommended"));
     1333    }
     1334
     1335    public enum Lc_CSX { CSX_UNKN, CSX_ALL, CSX_OTHR, CSX_NMOT, CSX_CRFT, CSX_VSSL, CSX_ILWW, CSX_SEAG, CSX_MOTR, CSX_MTNK, CSX_MCGO, CSX_CBRG, CSX_TUG, CSX_PSHR, CSX_BARG, CSX_TNKB,
     1336        CSX_DMBB, CSX_LGTR, CSX_TNKL, CSX_CGOL, CSX_SBLR, CSX_PSGR, CSX_PSGS, CSX_DAYT, CSX_CABN, CSX_HSPD, CSX_FLEQ, CSX_WSIT, CSX_RCNL, CSX_DNGY, CSX_FEST, CSX_FOBJ }
     1337
     1338    private static final EnumMap<Lc_CSX, S57enum> Lc_csi = new EnumMap<>(Lc_CSX.class); static {
     1339        Lc_csi.put(Lc_CSX.CSX_UNKN, new S57enum(0, ""));
     1340        Lc_csi.put(Lc_CSX.CSX_ALL, new S57enum(1, "all")); Lc_csi.put(Lc_CSX.CSX_OTHR, new S57enum(2, "other")); Lc_csi.put(Lc_CSX.CSX_NMOT, new S57enum(3, "non-motorized"));
     1341        Lc_csi.put(Lc_CSX.CSX_CRFT, new S57enum(5, "craft")); Lc_csi.put(Lc_CSX.CSX_VSSL, new S57enum(6, "vessel")); Lc_csi.put(Lc_CSX.CSX_ILWW, new S57enum(7, "inland_waterway"));
     1342        Lc_csi.put(Lc_CSX.CSX_SEAG, new S57enum(8, "sea-going")); Lc_csi.put(Lc_CSX.CSX_MOTR, new S57enum(9, "motor")); Lc_csi.put(Lc_CSX.CSX_MTNK, new S57enum(10, "motor_tanker"));
     1343        Lc_csi.put(Lc_CSX.CSX_MCGO, new S57enum(11, "motor_cargo")); Lc_csi.put(Lc_CSX.CSX_CBRG, new S57enum(12, "canal_barge")); Lc_csi.put(Lc_CSX.CSX_TUG, new S57enum(13, "tug"));
     1344        Lc_csi.put(Lc_CSX.CSX_PSHR, new S57enum(14, "pusher")); Lc_csi.put(Lc_CSX.CSX_BARG, new S57enum(15, "barge")); Lc_csi.put(Lc_CSX.CSX_TNKB, new S57enum(16, "tank_barge"));
     1345        Lc_csi.put(Lc_CSX.CSX_DMBB, new S57enum(17, "dumb_barge")); Lc_csi.put(Lc_CSX.CSX_LGTR, new S57enum(18, "lighter")); Lc_csi.put(Lc_CSX.CSX_TNKL, new S57enum(19, "tank_lighter"));
     1346        Lc_csi.put(Lc_CSX.CSX_CGOL, new S57enum(20, "cargo_lighter")); Lc_csi.put(Lc_CSX.CSX_SBLR, new S57enum(21, "ship_borne_lighter")); Lc_csi.put(Lc_CSX.CSX_PSGR, new S57enum(22, "passenger"));
     1347        Lc_csi.put(Lc_CSX.CSX_PSGS, new S57enum(23, "passenger_sailing")); Lc_csi.put(Lc_CSX.CSX_DAYT, new S57enum(24, "day_trip")); Lc_csi.put(Lc_CSX.CSX_CABN, new S57enum(25, "cabin"));
     1348        Lc_csi.put(Lc_CSX.CSX_HSPD, new S57enum(26, "high-speed")); Lc_csi.put(Lc_CSX.CSX_FLEQ, new S57enum(27, "floating_equipment")); Lc_csi.put(Lc_CSX.CSX_WSIT, new S57enum(28, "worksite"));
     1349        Lc_csi.put(Lc_CSX.CSX_RCNL, new S57enum(29, "recreational")); Lc_csi.put(Lc_CSX.CSX_DNGY, new S57enum(30, "dinghy")); Lc_csi.put(Lc_CSX.CSX_FEST, new S57enum(31, "floating_establishment"));
     1350        Lc_csi.put(Lc_CSX.CSX_FOBJ, new S57enum(32, "floating_object"));
     1351    }
     1352
     1353    private static final EnumMap<Lc_CSX, S57enum> Lc_cse = new EnumMap<>(Lc_CSX.class); static {
     1354        Lc_cse.put(Lc_CSX.CSX_UNKN, new S57enum(0, ""));
     1355        Lc_cse.put(Lc_CSX.CSX_ALL, new S57enum(1, "all")); Lc_cse.put(Lc_CSX.CSX_OTHR, new S57enum(2, "other")); Lc_cse.put(Lc_CSX.CSX_NMOT, new S57enum(3, "non-motorized"));
     1356        Lc_cse.put(Lc_CSX.CSX_CRFT, new S57enum(5, "craft")); Lc_cse.put(Lc_CSX.CSX_VSSL, new S57enum(6, "vessel")); Lc_cse.put(Lc_CSX.CSX_ILWW, new S57enum(7, "inland_waterway"));
     1357        Lc_cse.put(Lc_CSX.CSX_SEAG, new S57enum(8, "sea-going")); Lc_cse.put(Lc_CSX.CSX_MOTR, new S57enum(9, "motor")); Lc_cse.put(Lc_CSX.CSX_MTNK, new S57enum(10, "motor_tanker"));
     1358        Lc_cse.put(Lc_CSX.CSX_MCGO, new S57enum(11, "motor_cargo")); Lc_cse.put(Lc_CSX.CSX_CBRG, new S57enum(12, "canal_barge")); Lc_cse.put(Lc_CSX.CSX_TUG, new S57enum(13, "tug"));
     1359        Lc_cse.put(Lc_CSX.CSX_PSHR, new S57enum(14, "pusher")); Lc_cse.put(Lc_CSX.CSX_BARG, new S57enum(15, "barge")); Lc_cse.put(Lc_CSX.CSX_TNKB, new S57enum(16, "tank_barge"));
     1360        Lc_cse.put(Lc_CSX.CSX_DMBB, new S57enum(17, "dumb_barge")); Lc_cse.put(Lc_CSX.CSX_LGTR, new S57enum(18, "lighter")); Lc_cse.put(Lc_CSX.CSX_TNKL, new S57enum(19, "tank_lighter"));
     1361        Lc_cse.put(Lc_CSX.CSX_CGOL, new S57enum(20, "cargo_lighter")); Lc_cse.put(Lc_CSX.CSX_SBLR, new S57enum(21, "ship_borne_lighter")); Lc_cse.put(Lc_CSX.CSX_PSGR, new S57enum(22, "passenger"));
     1362        Lc_cse.put(Lc_CSX.CSX_PSGS, new S57enum(23, "passenger_sailing")); Lc_cse.put(Lc_CSX.CSX_DAYT, new S57enum(24, "day_trip")); Lc_cse.put(Lc_CSX.CSX_CABN, new S57enum(25, "cabin"));
     1363        Lc_cse.put(Lc_CSX.CSX_HSPD, new S57enum(26, "high-speed")); Lc_cse.put(Lc_CSX.CSX_FLEQ, new S57enum(27, "floating_equipment")); Lc_cse.put(Lc_CSX.CSX_WSIT, new S57enum(28, "worksite"));
     1364        Lc_cse.put(Lc_CSX.CSX_RCNL, new S57enum(29, "recreational")); Lc_cse.put(Lc_CSX.CSX_DNGY, new S57enum(30, "dinghy")); Lc_cse.put(Lc_CSX.CSX_FEST, new S57enum(31, "floating_establishment"));
     1365        Lc_cse.put(Lc_CSX.CSX_FOBJ, new S57enum(32, "floating_object"));
     1366    }
     1367
     1368    public enum Lc_ASX { ASX_UNKN, ASX_ALL, ASX_OTHR, ASX_SNGL, ASX_CONV, ASX_FMTN, ASX_RCNV, ASX_PCNV, ASX_BSTD, ASX_TCNV }
     1369
     1370    private static final EnumMap<Lc_ASX, S57enum> Lc_asi = new EnumMap<>(Lc_ASX.class); static {
     1371        Lc_asi.put(Lc_ASX.ASX_UNKN, new S57enum(0, ""));
     1372        Lc_asi.put(Lc_ASX.ASX_ALL, new S57enum(1, "all")); Lc_asi.put(Lc_ASX.ASX_OTHR, new S57enum(2, "other")); Lc_asi.put(Lc_ASX.ASX_SNGL, new S57enum(3, "single"));
     1373        Lc_asi.put(Lc_ASX.ASX_CONV, new S57enum(5, "convoy")); Lc_asi.put(Lc_ASX.ASX_FMTN, new S57enum(6, "formation")); Lc_asi.put(Lc_ASX.ASX_RCNV, new S57enum(7, "rigid_convoy"));
     1374        Lc_asi.put(Lc_ASX.ASX_PCNV, new S57enum(8, "pushed_convoy")); Lc_asi.put(Lc_ASX.ASX_BSTD, new S57enum(9, "breasted")); Lc_asi.put(Lc_ASX.ASX_TCNV, new S57enum(10, "towed_convoy"));
     1375    }
     1376
     1377    private static final EnumMap<Lc_ASX, S57enum> Lc_ase = new EnumMap<>(Lc_ASX.class); static {
     1378        Lc_ase.put(Lc_ASX.ASX_UNKN, new S57enum(0, ""));
     1379        Lc_ase.put(Lc_ASX.ASX_ALL, new S57enum(1, "all")); Lc_ase.put(Lc_ASX.ASX_OTHR, new S57enum(2, "other")); Lc_ase.put(Lc_ASX.ASX_SNGL, new S57enum(3, "single"));
     1380        Lc_ase.put(Lc_ASX.ASX_CONV, new S57enum(5, "convoy")); Lc_ase.put(Lc_ASX.ASX_FMTN, new S57enum(6, "formation")); Lc_ase.put(Lc_ASX.ASX_RCNV, new S57enum(7, "rigid_convoy"));
     1381        Lc_ase.put(Lc_ASX.ASX_PCNV, new S57enum(8, "pushed_convoy")); Lc_ase.put(Lc_ASX.ASX_BSTD, new S57enum(9, "breasted")); Lc_ase.put(Lc_ASX.ASX_TCNV, new S57enum(10, "towed_convoy"));
     1382    }
     1383
     1384    public enum Lc_CCX { CCX_UNKN, CCX_ALL, CCX_OTHR, CCX_BULK, CCX_DRY, CCX_LIQD, CCX_LQDN, CCX_LQDC, CCX_GAS }
     1385
     1386    private static final EnumMap<Lc_CCX, S57enum> Lc_cci = new EnumMap<>(Lc_CCX.class); static {
     1387        Lc_cci.put(Lc_CCX.CCX_UNKN, new S57enum(0, ""));
     1388        Lc_cci.put(Lc_CCX.CCX_ALL, new S57enum(1, "all")); Lc_cci.put(Lc_CCX.CCX_OTHR, new S57enum(2, "other")); Lc_cci.put(Lc_CCX.CCX_BULK, new S57enum(4, "bulk"));
     1389        Lc_cci.put(Lc_CCX.CCX_DRY, new S57enum(5, "dry")); Lc_cci.put(Lc_CCX.CCX_LIQD, new S57enum(6, "liquid")); Lc_cci.put(Lc_CCX.CCX_LQDN, new S57enum(7, "liquid_n"));
     1390        Lc_cci.put(Lc_CCX.CCX_LQDC, new S57enum(8, "liquid_c")); Lc_cci.put(Lc_CCX.CCX_GAS, new S57enum(9, "gas"));
     1391    }
     1392
     1393    private static final EnumMap<Lc_CCX, S57enum> Lc_cce = new EnumMap<>(Lc_CCX.class); static {
     1394        Lc_cce.put(Lc_CCX.CCX_UNKN, new S57enum(0, ""));
     1395        Lc_cce.put(Lc_CCX.CCX_ALL, new S57enum(1, "all")); Lc_cce.put(Lc_CCX.CCX_OTHR, new S57enum(2, "other")); Lc_cce.put(Lc_CCX.CCX_BULK, new S57enum(4, "bulk"));
     1396        Lc_cce.put(Lc_CCX.CCX_DRY, new S57enum(5, "dry")); Lc_cce.put(Lc_CCX.CCX_LIQD, new S57enum(6, "liquid")); Lc_cce.put(Lc_CCX.CCX_LQDN, new S57enum(7, "liquid_n"));
     1397        Lc_cce.put(Lc_CCX.CCX_LQDC, new S57enum(8, "liquid_c")); Lc_cce.put(Lc_CCX.CCX_GAS, new S57enum(9, "gas"));
     1398    }
     1399
     1400    public enum ShpTYP { TYP_UNKN, TYP_CRGO, TYP_CONT, TYP_TNKR, TYP_SAIL, TYP_FISH, TYP_SPPS, TYP_MOWR, TYP_SUBM, TYP_HSPD, TYP_BCAR, TYP_SPLN, TYP_TUGB, TYP_PSGR, TYP_FERY, TYP_BOAT }
     1401
     1402    private static final EnumMap<ShpTYP, S57enum> Shptyp = new EnumMap<>(ShpTYP.class); static {
     1403        Shptyp.put(ShpTYP.TYP_UNKN, new S57enum(0, ""));
     1404        Shptyp.put(ShpTYP.TYP_CRGO, new S57enum(1, "cargo")); Shptyp.put(ShpTYP.TYP_CONT, new S57enum(2, "container")); Shptyp.put(ShpTYP.TYP_TNKR, new S57enum(3, "tanker"));
     1405        Shptyp.put(ShpTYP.TYP_SAIL, new S57enum(4, "sailing")); Shptyp.put(ShpTYP.TYP_FISH, new S57enum(5, "fishing")); Shptyp.put(ShpTYP.TYP_SPPS, new S57enum(6, "special_purpose."));
     1406        Shptyp.put(ShpTYP.TYP_MOWR, new S57enum(7, "man_of_war")); Shptyp.put(ShpTYP.TYP_SUBM, new S57enum(8, "submarine")); Shptyp.put(ShpTYP.TYP_HSPD, new S57enum(9, "high-speed"));
     1407        Shptyp.put(ShpTYP.TYP_BCAR, new S57enum(10, "bulk_carrier")); Shptyp.put(ShpTYP.TYP_SPLN, new S57enum(11, "seaplane")); Shptyp.put(ShpTYP.TYP_TUGB, new S57enum(12, "tugboat"));
     1408        Shptyp.put(ShpTYP.TYP_PSGR, new S57enum(13, "passenger")); Shptyp.put(ShpTYP.TYP_FERY, new S57enum(14, "ferry")); Shptyp.put(ShpTYP.TYP_BOAT, new S57enum(15, "boat"));
     1409    }
     1410
     1411    public enum CatCVR { CVR_UNKN, CVR_COVR, CVR_NCVR }
     1412
     1413    private static final EnumMap<CatCVR, S57enum> Catcvr = new EnumMap<>(CatCVR.class); static {
     1414        Catcvr.put(CatCVR.CVR_UNKN, new S57enum(0, ""));
     1415        Catcvr.put(CatCVR.CVR_COVR, new S57enum(1, "coverage")); Catcvr.put(CatCVR.CVR_NCVR, new S57enum(2, "no_coverage"));
     1416    }
     1417
     1418    private static final EnumMap<Att, S57key> keys = new EnumMap<>(Att.class);
     1419    static {
     1420        keys.put(Att.UNKATT, new S57key(Conv.A, null)); keys.put(Att.AGENCY, new S57key(Conv.A, null)); keys.put(Att.BCNSHP, new S57key(Conv.E, Bcnshp));
     1421        keys.put(Att.BUISHP, new S57key(Conv.E, Buishp)); keys.put(Att.BOYSHP, new S57key(Conv.E, Boyshp)); keys.put(Att.BURDEP, new S57key(Conv.F, null));
     1422        keys.put(Att.CALSGN, new S57key(Conv.S, null)); keys.put(Att.CATAIR, new S57key(Conv.L, Catair)); keys.put(Att.CATACH, new S57key(Conv.L, Catach));
     1423        keys.put(Att.CATBRG, new S57key(Conv.L, Catbrg)); keys.put(Att.CATBUA, new S57key(Conv.E, Catbua)); keys.put(Att.CATCBL, new S57key(Conv.E, Catcbl));
     1424        keys.put(Att.CATCAN, new S57key(Conv.E, Catcan)); keys.put(Att.CATCAM, new S57key(Conv.E, Catcam)); keys.put(Att.CATCHP, new S57key(Conv.E, Catchp));
     1425        keys.put(Att.CATCOA, new S57key(Conv.E, Catcoa)); keys.put(Att.CATCTR, new S57key(Conv.E, Catctr)); keys.put(Att.CATCON, new S57key(Conv.E, Catcon));
     1426        keys.put(Att.CATCRN, new S57key(Conv.E, Catcrn)); keys.put(Att.CATDAM, new S57key(Conv.E, Catdam)); keys.put(Att.CATDIS, new S57key(Conv.E, Catdis));
     1427        keys.put(Att.CATDOC, new S57key(Conv.E, Catdoc)); keys.put(Att.CATDPG, new S57key(Conv.L, Catdpg)); keys.put(Att.CATFNC, new S57key(Conv.E, Catfnc));
     1428        keys.put(Att.CATFRY, new S57key(Conv.E, Catfry)); keys.put(Att.CATFIF, new S57key(Conv.E, Catfif)); keys.put(Att.CATFOG, new S57key(Conv.E, Catfog));
     1429        keys.put(Att.CATFOR, new S57key(Conv.E, Catfor)); keys.put(Att.CATGAT, new S57key(Conv.E, Catgat)); keys.put(Att.CATHAF, new S57key(Conv.L, Cathaf));
     1430        keys.put(Att.CATHLK, new S57key(Conv.L, Cathlk)); keys.put(Att.CATICE, new S57key(Conv.E, Catice)); keys.put(Att.CATINB, new S57key(Conv.E, Catinb));
     1431        keys.put(Att.CATLND, new S57key(Conv.L, Catlnd)); keys.put(Att.CATLMK, new S57key(Conv.L, Catlmk)); keys.put(Att.CATLAM, new S57key(Conv.E, Catlam));
     1432        keys.put(Att.CATLIT, new S57key(Conv.L, Catlit)); keys.put(Att.CATMFA, new S57key(Conv.E, Catmfa)); keys.put(Att.CATMPA, new S57key(Conv.L, Catmpa));
     1433        keys.put(Att.CATMOR, new S57key(Conv.E, Catmor)); keys.put(Att.CATNAV, new S57key(Conv.E, Catnav)); keys.put(Att.CATOBS, new S57key(Conv.E, Catobs));
     1434        keys.put(Att.CATOFP, new S57key(Conv.L, Catofp)); keys.put(Att.CATOLB, new S57key(Conv.E, Catolb)); keys.put(Att.CATPLE, new S57key(Conv.E, Catple));
     1435        keys.put(Att.CATPIL, new S57key(Conv.E, Catpil)); keys.put(Att.CATPIP, new S57key(Conv.L, Catpip)); keys.put(Att.CATPRA, new S57key(Conv.E, Catpra));
     1436        keys.put(Att.CATPYL, new S57key(Conv.E, Catpyl)); keys.put(Att.CATRAS, new S57key(Conv.E, Catras)); keys.put(Att.CATRTB, new S57key(Conv.E, Catrtb));
     1437        keys.put(Att.CATROS, new S57key(Conv.L, Catros)); keys.put(Att.CATTRK, new S57key(Conv.E, Cattrk)); keys.put(Att.CATRSC, new S57key(Conv.L, Catrsc));
     1438        keys.put(Att.CATREA, new S57key(Conv.L, Catrea)); keys.put(Att.CATROD, new S57key(Conv.E, Catrod)); keys.put(Att.CATRUN, new S57key(Conv.E, Catrun));
     1439        keys.put(Att.CATSEA, new S57key(Conv.E, Catsea)); keys.put(Att.CATSIL, new S57key(Conv.E, Catsil)); keys.put(Att.CATSLO, new S57key(Conv.E, Catslo));
     1440        keys.put(Att.CATSCF, new S57key(Conv.L, Catscf)); keys.put(Att.CATSLC, new S57key(Conv.E, Catslc)); keys.put(Att.CATSIT, new S57key(Conv.L, Catsit));
     1441        keys.put(Att.CATSIW, new S57key(Conv.L, Catsiw)); keys.put(Att.CATSPM, new S57key(Conv.L, Catspm)); keys.put(Att.CATTSS, new S57key(Conv.E, Cattss));
     1442        keys.put(Att.CATVEG, new S57key(Conv.L, Catveg)); keys.put(Att.CATWAT, new S57key(Conv.E, Catwat)); keys.put(Att.CATWED, new S57key(Conv.E, Catwed));
     1443        keys.put(Att.CATWRK, new S57key(Conv.E, Catwrk)); keys.put(Att.COLOUR, new S57key(Conv.L, Colour));
     1444        keys.put(Att.COLPAT, new S57key(Conv.L, Colpat)); keys.put(Att.COMCHA, new S57key(Conv.A, null)); keys.put(Att.CPDATE, new S57key(Conv.A, null));
     1445        keys.put(Att.CSCALE, new S57key(Conv.I, null)); keys.put(Att.CONDTN, new S57key(Conv.E, Condtn)); keys.put(Att.CONRAD, new S57key(Conv.E, Conrad));
     1446        keys.put(Att.CONVIS, new S57key(Conv.E, Convis)); keys.put(Att.CURVEL, new S57key(Conv.F, null)); keys.put(Att.DATEND, new S57key(Conv.A, null));
     1447        keys.put(Att.DATSTA, new S57key(Conv.A, null)); keys.put(Att.DRVAL1, new S57key(Conv.F, null)); keys.put(Att.DRVAL2, new S57key(Conv.F, null));
     1448        keys.put(Att.ELEVAT, new S57key(Conv.F, null)); keys.put(Att.ESTRNG, new S57key(Conv.F, null));
     1449        keys.put(Att.EXCLIT, new S57key(Conv.E, Exclit)); keys.put(Att.EXPSOU, new S57key(Conv.E, Expsou)); keys.put(Att.FUNCTN, new S57key(Conv.L, Functn));
     1450        keys.put(Att.HEIGHT, new S57key(Conv.F, null)); keys.put(Att.HUNITS, new S57key(Conv.E, Hunits)); keys.put(Att.HORACC, new S57key(Conv.F, null));
     1451        keys.put(Att.HORCLR, new S57key(Conv.F, null)); keys.put(Att.HORLEN, new S57key(Conv.F, null)); keys.put(Att.HORWID, new S57key(Conv.F, null));
     1452        keys.put(Att.ICEFAC, new S57key(Conv.F, null)); keys.put(Att.INFORM, new S57key(Conv.S, null)); keys.put(Att.JRSDTN, new S57key(Conv.E, Jrsdtn));
     1453        keys.put(Att.LIFCAP, new S57key(Conv.F, null)); keys.put(Att.LITCHR, new S57key(Conv.E, Litchr)); keys.put(Att.LITVIS, new S57key(Conv.L, Litvis));
     1454        keys.put(Att.MARSYS, new S57key(Conv.E, Marsys)); keys.put(Att.MLTYLT, new S57key(Conv.I, null)); keys.put(Att.NATION, new S57key(Conv.A, null));
     1455        keys.put(Att.NATCON, new S57key(Conv.L, Natcon)); keys.put(Att.NATSUR, new S57key(Conv.L, Natsur)); keys.put(Att.NATQUA, new S57key(Conv.L, Natqua));
     1456        keys.put(Att.NMDATE, new S57key(Conv.A, null)); keys.put(Att.OBJNAM, new S57key(Conv.S, null)); keys.put(Att.ORIENT, new S57key(Conv.F, null));
     1457        keys.put(Att.PEREND, new S57key(Conv.A, null)); keys.put(Att.PERSTA, new S57key(Conv.A, null)); keys.put(Att.PICREP, new S57key(Conv.S, null));
     1458        keys.put(Att.PILDST, new S57key(Conv.S, null)); keys.put(Att.PRCTRY, new S57key(Conv.A, null)); keys.put(Att.PRODCT, new S57key(Conv.L, Prodct));
     1459        keys.put(Att.PUBREF, new S57key(Conv.S, null)); keys.put(Att.QUASOU, new S57key(Conv.L, Quasou)); keys.put(Att.RADWAL, new S57key(Conv.A, null));
     1460        keys.put(Att.RADIUS, new S57key(Conv.F, null));
     1461        keys.put(Att.RYRMGV, new S57key(Conv.A, null)); keys.put(Att.RESTRN, new S57key(Conv.L, Restrn));
     1462        keys.put(Att.SCAMIN, new S57key(Conv.I, null)); keys.put(Att.SCVAL1, new S57key(Conv.I, null)); keys.put(Att.SCVAL2, new S57key(Conv.I, null));
     1463        keys.put(Att.SECTR1, new S57key(Conv.F, null)); keys.put(Att.SECTR2, new S57key(Conv.F, null)); keys.put(Att.SHIPAM, new S57key(Conv.A, null));
     1464        keys.put(Att.SIGFRQ, new S57key(Conv.I, null)); keys.put(Att.SIGGEN, new S57key(Conv.E, Siggen)); keys.put(Att.SIGGRP, new S57key(Conv.A, null));
     1465        keys.put(Att.SIGPER, new S57key(Conv.F, null)); keys.put(Att.SIGSEQ, new S57key(Conv.A, null)); keys.put(Att.SOUACC, new S57key(Conv.F, null));
     1466        keys.put(Att.SDISMX, new S57key(Conv.I, null)); keys.put(Att.SDISMN, new S57key(Conv.I, null)); keys.put(Att.SORDAT, new S57key(Conv.A, null));
     1467        keys.put(Att.SORIND, new S57key(Conv.A, null)); keys.put(Att.STATUS, new S57key(Conv.L, Status)); keys.put(Att.SURATH, new S57key(Conv.S, null));
     1468        keys.put(Att.SUREND, new S57key(Conv.A, null)); keys.put(Att.SURSTA, new S57key(Conv.A, null)); keys.put(Att.SURTYP, new S57key(Conv.L, Surtyp));
     1469        keys.put(Att.TECSOU, new S57key(Conv.L, Tecsou)); keys.put(Att.TXTDSC, new S57key(Conv.S, null)); keys.put(Att.TS_TSP, new S57key(Conv.A, null));
     1470        keys.put(Att.TS_TSV, new S57key(Conv.A, null)); keys.put(Att.T_ACWL, new S57key(Conv.E, null)); keys.put(Att.T_HWLW, new S57key(Conv.A, null));
     1471        keys.put(Att.T_MTOD, new S57key(Conv.E, null)); keys.put(Att.T_THDF, new S57key(Conv.A, null)); keys.put(Att.T_TINT, new S57key(Conv.I, null));
     1472        keys.put(Att.T_TSVL, new S57key(Conv.A, null)); keys.put(Att.T_VAHC, new S57key(Conv.A, null)); keys.put(Att.TIMEND, new S57key(Conv.A, null));
     1473        keys.put(Att.TIMSTA, new S57key(Conv.A, null)); keys.put(Att.TOPSHP, new S57key(Conv.E, Topshp)); keys.put(Att.TRAFIC, new S57key(Conv.E, Trafic));
     1474        keys.put(Att.VALACM, new S57key(Conv.F, null)); keys.put(Att.VALDCO, new S57key(Conv.F, null)); keys.put(Att.VALLMA, new S57key(Conv.F, null));
     1475        keys.put(Att.VALMAG, new S57key(Conv.F, null)); keys.put(Att.VALMXR, new S57key(Conv.F, null)); keys.put(Att.VALNMR, new S57key(Conv.F, null));
     1476        keys.put(Att.VALSOU, new S57key(Conv.F, null)); keys.put(Att.VERACC, new S57key(Conv.F, null)); keys.put(Att.VERCLR, new S57key(Conv.F, null));
     1477        keys.put(Att.VERCCL, new S57key(Conv.F, null)); keys.put(Att.VERCOP, new S57key(Conv.F, null)); keys.put(Att.VERCSA, new S57key(Conv.F, null));
     1478        keys.put(Att.VERDAT, new S57key(Conv.E, Verdat)); keys.put(Att.VERLEN, new S57key(Conv.F, null)); keys.put(Att.WATLEV, new S57key(Conv.E, Watlev));
     1479        keys.put(Att.CAT_TS, new S57key(Conv.E, Cat_ts)); keys.put(Att.NINFOM, new S57key(Conv.S, null));
     1480        keys.put(Att.NOBJNM, new S57key(Conv.S, null)); keys.put(Att.NPLDST, new S57key(Conv.S, null)); keys.put(Att.NTXTDS, new S57key(Conv.S, null));
     1481        keys.put(Att.HORDAT, new S57key(Conv.E, null)); keys.put(Att.POSACC, new S57key(Conv.F, null)); keys.put(Att.QUAPOS, new S57key(Conv.E, Quapos));
     1482        keys.put(Att.CLSDNG, new S57key(Conv.E, Clsdng)); keys.put(Att.DIRIMP, new S57key(Conv.L, Dirimp)); keys.put(Att.DISBK1, new S57key(Conv.F, null));
     1483        keys.put(Att.DISBK2, new S57key(Conv.F, null)); keys.put(Att.DISIPU, new S57key(Conv.F, null)); keys.put(Att.DISIPD, new S57key(Conv.F, null));
     1484        keys.put(Att.ELEVA1, new S57key(Conv.F, null)); keys.put(Att.ELEVA2, new S57key(Conv.F, null)); keys.put(Att.FNCTNM, new S57key(Conv.E, Fnctnm));
     1485        keys.put(Att.WTWDIS, new S57key(Conv.F, null)); keys.put(Att.BUNVES, new S57key(Conv.E, Bunves)); keys.put(Att.COMCTN, new S57key(Conv.S, null));
     1486        keys.put(Att.HORCLL, new S57key(Conv.F, null)); keys.put(Att.HORCLW, new S57key(Conv.F, null)); keys.put(Att.TRSHGD, new S57key(Conv.L, Trshgd));
     1487        keys.put(Att.UNLOCD, new S57key(Conv.S, null)); keys.put(Att.HIGWAT, new S57key(Conv.F, null)); keys.put(Att.HIGNAM, new S57key(Conv.S, null));
     1488        keys.put(Att.LOWWAT, new S57key(Conv.F, null)); keys.put(Att.LOWNAM, new S57key(Conv.S, null)); keys.put(Att.MEAWAT, new S57key(Conv.F, null));
     1489        keys.put(Att.MEANAM, new S57key(Conv.S, null)); keys.put(Att.OTHWAT, new S57key(Conv.F, null)); keys.put(Att.OTHNAM, new S57key(Conv.S, null));
     1490        keys.put(Att.REFLEV, new S57key(Conv.E, Reflev)); keys.put(Att.SDRLEV, new S57key(Conv.S, null)); keys.put(Att.VCRLEV, new S57key(Conv.S, null));
     1491        keys.put(Att.SCHREF, new S57key(Conv.S, null)); keys.put(Att.USESHP, new S57key(Conv.E, Useshp)); keys.put(Att.CURVHW, new S57key(Conv.F, null));
     1492        keys.put(Att.CURVLW, new S57key(Conv.F, null)); keys.put(Att.CURVMW, new S57key(Conv.F, null)); keys.put(Att.CURVOW, new S57key(Conv.F, null));
     1493        keys.put(Att.APTREF, new S57key(Conv.S, null)); keys.put(Att.SHPTYP, new S57key(Conv.E, Shptyp)); keys.put(Att.UPDMSG, new S57key(Conv.S, null));
     1494        keys.put(Att.ADDMRK, new S57key(Conv.L, Addmrk)); keys.put(Att.BNKWTW, new S57key(Conv.E, Bnkwtw));
     1495        keys.put(Att.CATNMK, new S57key(Conv.E, Catnmk)); keys.put(Att.CATBRT, new S57key(Conv.L, Catbrt)); keys.put(Att.CATBUN, new S57key(Conv.L, Catbun));
     1496        keys.put(Att.CATCCL, new S57key(Conv.L, Catccl)); keys.put(Att.CATCOM, new S57key(Conv.L, Catcom)); keys.put(Att.CATHBR, new S57key(Conv.L, Cathbr));
     1497        keys.put(Att.CATRFD, new S57key(Conv.L, Catrfd)); keys.put(Att.CATTML, new S57key(Conv.L, Cattml)); keys.put(Att.CATGAG, new S57key(Conv.L, Catgag));
     1498        keys.put(Att.CATVTR, new S57key(Conv.L, Catvtr)); keys.put(Att.CATTAB, new S57key(Conv.E, Cattab)); keys.put(Att.CATEXS, new S57key(Conv.E, Catexs));
     1499        keys.put(Att.LG_SPD, new S57key(Conv.F, null)); keys.put(Att.LG_SPR, new S57key(Conv.L, Lg_spr)); keys.put(Att.LG_BME, new S57key(Conv.F, null));
     1500        keys.put(Att.LG_LGS, new S57key(Conv.F, null)); keys.put(Att.LG_DRT, new S57key(Conv.F, null)); keys.put(Att.LG_WDP, new S57key(Conv.F, null));
     1501        keys.put(Att.LG_WDU, new S57key(Conv.E, Lg_wdu)); keys.put(Att.LG_REL, new S57key(Conv.L, Lg_rel)); keys.put(Att.LG_FNC, new S57key(Conv.L, Lg_fnc));
     1502        keys.put(Att.LG_DES, new S57key(Conv.S, null)); keys.put(Att.LG_PBR, new S57key(Conv.S, null)); keys.put(Att.LC_CSI, new S57key(Conv.L, Lc_csi));
     1503        keys.put(Att.LC_CSE, new S57key(Conv.L, Lc_cse)); keys.put(Att.LC_ASI, new S57key(Conv.L, Lc_asi)); keys.put(Att.LC_ASE, new S57key(Conv.L, Lc_ase));
     1504        keys.put(Att.LC_CCI, new S57key(Conv.L, Lc_cci)); keys.put(Att.LC_CCE, new S57key(Conv.L, Lc_cce)); keys.put(Att.LC_BM1, new S57key(Conv.F, null));
     1505        keys.put(Att.LC_BM2, new S57key(Conv.F, null)); keys.put(Att.LC_LG1, new S57key(Conv.F, null)); keys.put(Att.LC_LG2, new S57key(Conv.F, null));
     1506        keys.put(Att.LC_DR1, new S57key(Conv.F, null)); keys.put(Att.LC_DR2, new S57key(Conv.F, null)); keys.put(Att.LC_SP1, new S57key(Conv.F, null));
     1507        keys.put(Att.LC_SP2, new S57key(Conv.F, null)); keys.put(Att.LC_WD1, new S57key(Conv.F, null)); keys.put(Att.LC_WD2, new S57key(Conv.F, null));
     1508        keys.put(Att.LITRAD, new S57key(Conv.F, null)); keys.put(Att.CATCVR, new S57key(Conv.E, Catcvr));
     1509    }
     1510
     1511    public static Enum<?> s57Enum(String val, Att att) { // Convert S57 attribute value string to SCM enumeration
     1512        EnumMap<?, ?> map = keys.get(att).map;
     1513        Enum<?> unkn = null;
     1514        int i = 0;
     1515        try {
     1516            i = Integer.parseInt(val);
     1517        } catch (Exception e) {
     1518            return unkn;
     1519        }
     1520        if (map != null) {
     1521            for (Object item : map.keySet()) {
     1522                if (unkn == null)
     1523                    unkn = (Enum<?>) item;
     1524                if (((S57enum) map.get(item)).atvl.equals(i))
     1525                    return (Enum<?>) item;
     1526            }
     1527        }
     1528        return unkn;
     1529    }
     1530
     1531    public static AttVal<?> decodeValue(String val, Att att) { // Convert S57 attribute value string to SCM attribute value
     1532        Conv conv = keys.get(att).conv;
     1533        switch (conv) {
     1534        case A:
     1535        case S:
     1536            return new AttVal<>(conv, val);
     1537        case E:
     1538            ArrayList<Enum<?>> list = new ArrayList<>();
     1539            list.add(s57Enum(val, att));
     1540            return new AttVal<ArrayList<?>>(Conv.E, list);
     1541        case L:
     1542            list = new ArrayList<>();
     1543            for (String item : val.split(",")) {
     1544                list.add(s57Enum(item, att));
     1545            }
     1546            return new AttVal<ArrayList<?>>(Conv.L, list);
     1547        case I:
     1548            try {
     1549                return new AttVal<>(Conv.I, Long.parseLong(val));
     1550            } catch (Exception e) {
     1551                break;
     1552            }
     1553        case F:
     1554            try {
     1555                return new AttVal<>(Conv.F, Double.parseDouble(val));
     1556            } catch (Exception e) {
     1557                break;
     1558            }
     1559        }
     1560        return null;
     1561    }
     1562
     1563    public static String encodeValue(AttVal<?> attval, Att att) { // Convert SCM attribute value to S57 attribute value string
     1564        if (attval != null) {
     1565            String str = stringValue(attval, att);
     1566            if ((attval.conv == Conv.E) || (attval.conv == Conv.L)) {
     1567                String[] vals = str.split(";");
     1568                str = "";
     1569                for (String val : vals) {
     1570                    if (!str.isEmpty()) str += ",";
     1571                    EnumMap<?, ?> map = keys.get(att).map;
     1572                    for (Object item : map.keySet()) {
     1573                        if (((S57enum) map.get(item)).val.equals(val))
     1574                            str += ((S57enum) map.get(item)).atvl.toString();
     1575                    }
     1576                }
     1577            }
     1578            return str;
     1579        }
     1580        return "";
     1581    }
     1582
     1583    public static String stringValue(AttVal<?> attval, Att att) { // Convert SCM attribute value to OSM attribute value string
     1584        if (attval != null) {
     1585            switch (attval.conv) {
     1586            case A:
     1587            case S:
     1588                return (String) attval.val;
     1589            case E:
     1590                EnumMap<?, ?> map = keys.get(att).map;
     1591                return ((S57enum) map.get(((ArrayList<?>) attval.val).get(0))).val;
     1592            case L:
     1593                String str = "";
     1594                map = keys.get(att).map;
     1595                for (Object item : (ArrayList<?>) attval.val) {
     1596                    if (!str.isEmpty())
     1597                        str += ";";
     1598                    if (item != null)
     1599                        str += ((S57enum) map.get(item)).val;
     1600                }
     1601                return str;
     1602            case I:
     1603                return ((Long) attval.val).toString();
     1604            case F:
     1605                return ((Double) attval.val).toString();
     1606            }
     1607        }
     1608        return "";
     1609    }
     1610
     1611    public static Enum<?> osmEnum(String val, Att att) { // Convert OSM attribute value string to SCM enumeration
     1612        EnumMap<?, ?> map = keys.get(att).map;
     1613        Enum<?> unkn = null;
     1614        if (map != null) {
     1615            for (Object item : map.keySet()) {
     1616                if (unkn == null)
     1617                    unkn = (Enum<?>) item;
     1618                if (((S57enum) map.get(item)).val.equals(val))
     1619                    return (Enum<?>) item;
     1620            }
     1621        }
     1622        return unkn;
     1623    }
     1624
     1625    public static AttVal<?> convertValue(String val, Att att) { // Convert OSM attribute value string to SCM attribute value
     1626        switch (keys.get(att).conv) {
     1627        case A:
     1628        case S:
     1629            return new AttVal<>(Conv.S, val);
     1630        case E:
     1631            ArrayList<Enum<?>> list = new ArrayList<>();
     1632            list.add(osmEnum(val, att));
     1633            return new AttVal<ArrayList<?>>(Conv.E, list);
     1634        case L:
     1635            list = new ArrayList<>();
     1636            for (String item : val.split(";")) {
     1637                list.add(osmEnum(item, att));
     1638            }
     1639            return new AttVal<ArrayList<?>>(Conv.L, list);
     1640        case I:
     1641            try {
     1642                return new AttVal<>(Conv.I, Long.parseLong(val));
     1643            } catch (Exception e) {
     1644                break;
     1645            }
     1646        case F:
     1647            try {
     1648                return new AttVal<>(Conv.F, Double.parseDouble(val));
     1649            } catch (Exception e) {
     1650                break;
     1651            }
     1652        }
     1653        return new AttVal<>(keys.get(att).conv, null);
     1654    }
     1655
     1656    public static Enum<?> unknAtt(Att att) {
     1657        return (Enum<?>) (keys.get(att).map.keySet().toArray()[0]);
     1658    }
    12691659}
Note: See TracChangeset for help on using the changeset viewer.