source: osm/applications/editors/josm/plugins/seachart/src/s57/S57enc.java@ 31735

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

[seachart] update

File size: 17.8 KB
Line 
1/* Copyright 2015 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.UnsupportedEncodingException;
13import java.nio.ByteBuffer;
14import java.text.SimpleDateFormat;
15import java.util.ArrayList;
16import java.util.Arrays;
17import java.util.Calendar;
18import java.util.HashMap;
19import java.util.Map;
20import java.util.Map.Entry;
21import java.util.zip.CRC32;
22
23import s57.S57obj.*;
24import s57.S57val.AttVal;
25import s57.S57att.Att;
26import s57.S57dat.*;
27import s57.S57map.*;
28
29public 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 int agen = 3878;
111 static int cscl = 10000;
112
113 static int idx;
114 static int recs;
115 static int isols;
116 static int conns;
117 static int metas;
118 static int geos;
119 static int edges;
120
121 static long hash(long val) {
122 byte[] bval = ByteBuffer.allocate(Long.SIZE).putLong(val).array();
123 CRC32 crc = new CRC32();
124 crc.update(bval);
125 return crc.getValue();
126 }
127
128 public static int encodeChart(S57map map, HashMap<String, String> meta, byte[] buf) throws IndexOutOfBoundsException, UnsupportedEncodingException {
129
130 //M_COVR & MNSYS in BB if not in map
131 if (!map.features.containsKey(Obj.M_COVR)) {
132 S57osm.OSMmeta(map);
133 }
134
135 byte[] record;
136 ArrayList<Fparams> fields;
137
138 String date = new SimpleDateFormat("yyyyMMdd").format(Calendar.getInstance().getTime());
139 ArrayList<Fparams> ds = new ArrayList<Fparams>();
140 ds.add(new Fparams(S57field.DSID, new Object[] { 10, 1, 1, 4, "0S000000.000", 1, 0, date, date, "03.1", 1, "ENC", "", 1, agen, "Generated by OpenSeaMap.org" }));
141 ds.add(new Fparams(S57field.DSSI, new Object[] { 2, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0 }));
142 ArrayList<Fparams> dp = new ArrayList<Fparams>();
143 dp.add(new Fparams(S57field.DSPM, new Object[] { 20, 2, 2, 23, 23, cscl, 1, 1, 1, 1, 10000000, 10, "" }));
144
145 isols = conns = metas = geos = edges = 0;
146 System.arraycopy(header, 0, buf, 0, header.length);
147 idx = header.length;
148 record = S57dat.encRecord(1, ds);
149 System.arraycopy(record, 0, buf, idx, record.length);
150 idx += record.length;
151 record = S57dat.encRecord(2, dp);
152 System.arraycopy(record, 0, buf, idx, record.length);
153 idx += record.length;
154 recs = 3;
155
156 // Depths
157 Object[] depths = new Object[0];
158 for (Map.Entry<Long, S57map.Snode> entry : map.nodes.entrySet()) {
159 S57map.Snode node = entry.getValue();
160 if (node.flg == Nflag.DPTH) {
161 Object[] dval = new Object[] { (Math.toDegrees(node.lat) * COMF), (Math.toDegrees(node.lon) * COMF), (node.val * SOMF) };
162 depths = Arrays.copyOf(depths, (depths.length + dval.length));
163 System.arraycopy(dval, 0, depths, (depths.length - dval.length), dval.length);
164 }
165 }
166 if (depths.length > 0) {
167 fields = new ArrayList<Fparams>();
168 fields.add(new Fparams(S57field.VRID, new Object[] { 110, -2, 1, 1 }));
169 fields.add(new Fparams(S57field.SG3D, depths));
170 record = S57dat.encRecord(recs++, fields);
171 System.arraycopy(record, 0, buf, idx, record.length);
172 idx += record.length;
173 isols++;
174 }
175
176 // Isolated nodes
177 for (Map.Entry<Long, S57map.Snode> entry : map.nodes.entrySet()) {
178 S57map.Snode node = entry.getValue();
179 if (node.flg == Nflag.ISOL) {
180 fields = new ArrayList<Fparams>();
181 fields.add(new Fparams(S57field.VRID, new Object[] { 110, hash(entry.getKey()), 1, 1 }));
182 fields.add(new Fparams(S57field.SG2D, new Object[] { (Math.toDegrees(node.lat) * COMF), (Math.toDegrees(node.lon) * COMF) }));
183 record = S57dat.encRecord(recs++, fields);
184 System.arraycopy(record, 0, buf, idx, record.length);
185 idx += record.length;
186 isols++;
187 }
188 }
189
190 // Connected nodes
191 for (Map.Entry<Long, S57map.Snode> entry : map.nodes.entrySet()) {
192 S57map.Snode node = entry.getValue();
193 if (node.flg == Nflag.CONN) {
194 fields = new ArrayList<Fparams>();
195 fields.add(new Fparams(S57field.VRID, new Object[] { 120, hash(entry.getKey()), 1, 1 }));
196 fields.add(new Fparams(S57field.SG2D, new Object[] { (Math.toDegrees(node.lat) * COMF), (Math.toDegrees(node.lon) * COMF) }));
197 record = S57dat.encRecord(recs++, fields);
198 System.arraycopy(record, 0, buf, idx, record.length);
199 idx += record.length;
200 conns++;
201 }
202 }
203
204 // Edges
205 for (Map.Entry<Long, S57map.Edge> entry : map.edges.entrySet()) {
206 S57map.Edge edge = entry.getValue();
207 fields = new ArrayList<Fparams>();
208 fields.add(new Fparams(S57field.VRID, new Object[] { 130, hash(entry.getKey()), 1, 1 }));
209 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 }));
210 Object[] nodes = new Object[0];
211 for (long ref : edge.nodes) {
212 Object[] nval = new Object[] { (Math.toDegrees(map.nodes.get(ref).lat) * COMF), (Math.toDegrees(map.nodes.get(ref).lon) * COMF) };
213 nodes = Arrays.copyOf(nodes, (nodes.length + nval.length));
214 System.arraycopy(nval, 0, nodes, (nodes.length - nval.length), nval.length);
215 }
216 if (nodes.length > 0) {
217 fields.add(new Fparams(S57field.SG2D, nodes));
218 }
219 record = S57dat.encRecord(recs++, fields);
220 System.arraycopy(record, 0, buf, idx, record.length);
221 idx += record.length;
222 edges++;
223 }
224
225 // Meta & Geo objects
226 boolean soundings = false;
227 for (Entry<Obj, ArrayList<Feature>> entry : map.features.entrySet()) {
228 Obj obj = entry.getKey();
229 for (Feature feature : entry.getValue()) {
230 if (obj == Obj.SOUNDG) {
231 if (soundings) {
232 continue;
233 } else {
234 soundings = true;
235 }
236 }
237 int prim = feature.geom.prim.ordinal();
238 prim = (prim == 0) ? 255 : prim;
239 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;
240
241 ArrayList<Fparams> geom = new ArrayList<Fparams>();
242 int outers = (feature.geom.prim == Pflag.POINT) ? 1 : feature.geom.comps.get(0).size;
243 for (Prim elem : feature.geom.elems) {
244 if (feature.geom.prim == Pflag.POINT) {
245 if (obj == Obj.SOUNDG) {
246 geom.add(new Fparams(S57field.FSPT, new Object[] { ((-2 << 8) + 110l), 255, 255, 255 }));
247 } else {
248 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 }));
249 }
250 } else {
251 geom.add(new Fparams(S57field.FSPT, new Object[] { ((hash(elem.id) << 8) + 130l), (elem.forward ? 1 : 2), ((outers-- > 0) ? 1 : 2), 2 }));
252 }
253 }
254
255 ArrayList<ArrayList<Fparams>> objects = new ArrayList<ArrayList<Fparams>>();
256 ArrayList<Long> slaves = new ArrayList<Long>();
257 long slaveid = feature.id & 0x01ffffffffffffffl;
258 for (Entry<Obj, ObjTab> objs : feature.objs.entrySet()) {
259 Obj objobj = objs.getKey();
260 boolean master = true;
261 for (Entry<Integer, AttMap> object : objs.getValue().entrySet()) {
262 ArrayList<Fparams> objatts = new ArrayList<Fparams>();
263 master = (feature.type == objobj) && ((object.getKey() == 0) || (object.getKey() == 1));
264 long id = hash(master ? feature.id : slaveid);
265 objatts.add(new Fparams(S57field.FRID, new Object[] { 100, id, prim, grup, S57obj.encodeType(objobj), 1, 1 }));
266 objatts.add(new Fparams(S57field.FOID, new Object[] { agen, id, 1 }));
267 Object[] attf = new Object[0];
268 Object[] natf = new Object[0];
269 for (Entry<Att, AttVal<?>> att : object.getValue().entrySet()) {
270 if (!((obj == Obj.SOUNDG) && (att.getKey() == Att.VALSOU))) {
271 long attl = S57att.encodeAttribute(att.getKey());
272 Object[] next = new Object[] { attl, S57val.encodeValue(att.getValue(), att.getKey()) };
273 if ((attl < 300) || (attl > 304)) {
274 attf = Arrays.copyOf(attf, (attf.length + next.length));
275 System.arraycopy(next, 0, attf, (attf.length - next.length), next.length);
276 } else {
277 natf = Arrays.copyOf(natf, (natf.length + next.length));
278 System.arraycopy(next, 0, natf, (natf.length - next.length), next.length);
279 }
280 }
281 }
282 if (attf.length > 0) {
283 objatts.add(new Fparams(S57field.ATTF, attf));
284 }
285 if (natf.length > 0) {
286 objatts.add(new Fparams(S57field.NATF, attf));
287 }
288 if (master) {
289 objects.add(objatts);
290 } else {
291 slaves.add(id);
292 objects.add(0, objatts);
293 slaveid += 0x0100000000000000l;
294 }
295 }
296 }
297
298 if (!slaves.isEmpty()) {
299 ArrayList<Fparams> refs = new ArrayList<Fparams>();
300 Object[] params = new Object[0];
301 while (!slaves.isEmpty()) {
302 long id = slaves.remove(0);
303 Object[] next = new Object[] { (long) ((((id & 0xffffffff) + 0x100000000l) << 16) + (agen & 0xffff)), 2, "" };
304 params = Arrays.copyOf(params, (params.length + next.length));
305 System.arraycopy(next, 0, params, (params.length - next.length), next.length);
306 }
307 refs.add(new Fparams(S57field.FFPT, params));
308 objects.get(objects.size() - 1).addAll(refs);
309 }
310
311 for (ArrayList<Fparams> object : objects) {
312 object.addAll(geom);
313 record = S57dat.encRecord(recs++, object);
314 System.arraycopy(record, 0, buf, idx, record.length);
315 idx += record.length;
316 if ((obj == Obj.M_COVR) || (obj == Obj.M_NSYS)) {
317 metas++;
318 } else {
319 geos++;
320 }
321 }
322 }
323 }
324
325 // Re-write DSID/DSSI with final totals
326 ds = new ArrayList<Fparams>();
327 ds.add(new Fparams(S57field.DSID, new Object[] { 10, 1, 1, 4, "0S000000.000", 1, 0, date, date, "03.1", 1, "ENC", "", 1, agen, "Generated by OpenSeaMap.org" }));
328 ds.add(new Fparams(S57field.DSSI, new Object[] { 2, 1, 2, metas, 0, geos, 0, isols, conns, edges, 0 }));
329 record = S57dat.encRecord(1, ds);
330 System.arraycopy(record, 0, buf, header.length, record.length);
331
332 return idx;
333 }
334
335}
Note: See TracBrowser for help on using the repository browser.