source: osm/applications/editors/josm/plugins/seachart/src/s57/S57dec.java@ 32101

Last change on this file since 32101 was 31722, checked in by malcolmh, 9 years ago

[seachart] update

File size: 6.4 KB
Line 
1/* Copyright 2014 Malcolm Herring
2 *
3 * This is free software: you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation, version 3 of the License.
6 *
7 * For a copy of the GNU General Public License, see <http://www.gnu.org/licenses/>.
8 */
9
10package s57;
11
12import java.io.FileInputStream;
13import java.io.IOException;
14
15import s57.S57dat.*;
16import s57.S57map.*;
17
18public 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 boolean ddr = false;
24 int length = 0;
25 int fields = 0;;
26 int mapfl, mapfp, mapts, entry;
27 String tag;
28 int len;
29 int pos;
30 boolean inFeature = false;
31
32 double comf = 1;
33 double somf = 1;
34 long name = 0;
35 S57map.Nflag nflag = Nflag.ANON;
36 S57map.Pflag pflag = S57map.Pflag.NOSP;
37 long objl = 0;
38
39 while (in.read(leader) == 24) {
40 try {
41 length = Integer.parseInt(new String(leader, 0, 5)) - 24;
42 ddr = (leader[6] == 'L');
43 fields = Integer.parseInt(new String(leader, 12, 5)) - 24;
44 } catch (Exception e) {
45 System.err.println("Invalid file format - Encrypted/compressed ENC file?");
46 System.exit(-1);
47 }
48 mapfl = leader[20] - '0';
49 mapfp = leader[21] - '0';
50 mapts = leader[23] - '0';
51 entry = mapfl + mapfp + mapts;
52 byte[] record = new byte[length];
53 if (in.read(record) != length)
54 break;
55 for (int idx = 0; idx < fields-1; idx += entry) {
56 tag = new String(record, idx, mapts);
57 len = Integer.parseInt(new String(record, idx+mapts, mapfl));
58 pos = Integer.parseInt(new String(record, idx+mapts+mapfl, mapfp));
59 if (!ddr) {
60 switch (tag.toString()) {
61 case "0001":
62 int i8rn = ((Long) S57dat.decSubf(record, fields + pos, S57field.I8RI, S57subf.I8RN)).intValue();
63 if (i8rn != ++S57dat.rnum) {
64 System.err.println("Out of order record ID");
65 in.close();
66 System.exit(-1);
67 }
68 break;
69 case "DSSI":
70 S57dat.decSubf(record, fields + pos, S57field.DSSI, S57subf.AALL);
71 S57dat.decSubf(S57subf.NALL);
72 break;
73 case "DSPM":
74 comf = (double) (Long) S57dat.decSubf(record, fields + pos, S57field.DSPM, S57subf.COMF);
75 somf = (double) (Long) S57dat.decSubf(S57subf.SOMF);
76 break;
77 case "FRID":
78 inFeature = true;
79 switch (((Long)S57dat.decSubf(record, fields + pos, S57field.FRID, S57subf.PRIM)).intValue()) {
80 case 1:
81 pflag = S57map.Pflag.POINT;
82 break;
83 case 2:
84 pflag = S57map.Pflag.LINE;
85 break;
86 case 3:
87 pflag = S57map.Pflag.AREA;
88 break;
89 default:
90 pflag = S57map.Pflag.NOSP;
91 }
92 objl = (Long)S57dat.decSubf(S57subf.OBJL);
93 break;
94 case "FOID":
95 name = (Long) S57dat.decSubf(record, fields + pos, S57field.LNAM, S57subf.LNAM);
96 map.newFeature(name, pflag, objl);
97 break;
98 case "ATTF":
99 S57dat.setField(record, fields + pos, S57field.ATTF, len);
100 do {
101 long attl = (Long) S57dat.decSubf(S57subf.ATTL);
102 String atvl = ((String) S57dat.decSubf(S57subf.ATVL)).trim();
103 if (!atvl.isEmpty()) {
104 map.newAtt(attl, atvl);
105 }
106 } while (S57dat.more());
107 break;
108 case "FFPT":
109 S57dat.setField(record, fields + pos, S57field.FFPT, len);
110 do {
111 name = (Long) S57dat.decSubf(S57subf.LNAM);
112 int rind = ((Long) S57dat.decSubf(S57subf.RIND)).intValue();
113 S57dat.decSubf(S57subf.COMT);
114 map.newObj(name, rind);
115 } while (S57dat.more());
116 break;
117 case "FSPT":
118 S57dat.setField(record, fields + pos, S57field.FSPT, len);
119 do {
120 name = (Long) S57dat.decSubf(S57subf.NAME) << 16;
121 map.newPrim(name, (Long) S57dat.decSubf(S57subf.ORNT), (Long) S57dat.decSubf(S57subf.USAG));
122 S57dat.decSubf(S57subf.MASK);
123 } while (S57dat.more());
124 break;
125 case "VRID":
126 inFeature = false;
127 name = (long) (Long)S57dat.decSubf(record, fields + pos, S57field.VRID, S57subf.RCNM);
128 switch ((int) name) {
129 case 110:
130 nflag = Nflag.ISOL;
131 break;
132 case 120:
133 nflag = Nflag.CONN;
134 break;
135 default:
136 nflag = Nflag.ANON;
137 break;
138 }
139 name <<= 32;
140 name += (Long) S57dat.decSubf(S57subf.RCID);
141 name <<= 16;
142 if (nflag == Nflag.ANON) {
143 map.newEdge(name);
144 }
145 break;
146 case "VRPT":
147 S57dat.setField(record, fields + pos, S57field.VRPT, len);
148 do {
149 long conn = (Long) S57dat.decSubf(S57subf.NAME) << 16;
150 int topi = ((Long) S57dat.decSubf(S57subf.TOPI)).intValue();
151 map.addConn(conn, topi);
152 S57dat.decSubf(S57subf.MASK);
153 } while (S57dat.more());
154 break;
155 case "SG2D":
156 S57dat.setField(record, fields + pos, S57field.SG2D, len);
157 do {
158 double lat = (double) ((Long) S57dat.decSubf(S57subf.YCOO)) / comf;
159 double lon = (double) ((Long) S57dat.decSubf(S57subf.XCOO)) / comf;
160 if (nflag == Nflag.ANON) {
161 map.newNode(++name, lat, lon, nflag);
162 } else {
163 map.newNode(name, lat, lon, nflag);
164 }
165 lat = Math.toRadians(lat);
166 lon = Math.toRadians(lon);
167 if (lat < map.bounds.minlat)
168 map.bounds.minlat = lat;
169 if (lat > map.bounds.maxlat)
170 map.bounds.maxlat = lat;
171 if (lon < map.bounds.minlon)
172 map.bounds.minlon = lon;
173 if (lon > map.bounds.maxlon)
174 map.bounds.maxlon = lon;
175 } while (S57dat.more());
176 break;
177 case "SG3D":
178 S57dat.setField(record, fields + pos, S57field.SG3D, len);
179 do {
180 double lat = (double) ((Long) S57dat.decSubf(S57subf.YCOO)) / comf;
181 double lon = (double) ((Long) S57dat.decSubf(S57subf.XCOO)) / comf;
182 double depth = (double) ((Long) S57dat.decSubf(S57subf.VE3D)) / somf;
183 map.newNode(name++, lat, lon, depth);
184 lat = Math.toRadians(lat);
185 lon = Math.toRadians(lon);
186 if (lat < map.bounds.minlat)
187 map.bounds.minlat = lat;
188 if (lat > map.bounds.maxlat)
189 map.bounds.maxlat = lat;
190 if (lon < map.bounds.minlon)
191 map.bounds.minlon = lon;
192 if (lon > map.bounds.maxlon)
193 map.bounds.maxlon = lon;
194 } while (S57dat.more());
195 break;
196 default:
197 break;
198 }
199 }
200 if (inFeature) {
201 map.endFeature();
202 inFeature = false;
203 }
204 }
205 }
206 map.endFile();
207 in.close();
208
209 return;
210 }
211
212}
Note: See TracBrowser for help on using the repository browser.