Commit 1e44cd5576433a4cff91030e50aba65248169280
1 parent
84aa038169
Exists in
master
added alpha support for zones
Showing 1 changed file with 176 additions and 1 deletions Inline Diff
src/main/java/fr/femto/extractor/track/Main.java
View file @
1e44cd5
package fr.femto.extractor.track; | 1 | 1 | package fr.femto.extractor.track; | |
2 | 2 | |||
import dk.dma.ais.message.AisMessage; | 3 | 3 | import dk.dma.ais.message.*; | |
import dk.dma.ais.sentence.Vdm; | 4 | 4 | import dk.dma.ais.sentence.Vdm; | |
5 | 5 | |||
import java.io.*; | 6 | 6 | import java.io.*; | |
import java.text.SimpleDateFormat; | 7 | 7 | import java.text.SimpleDateFormat; | |
8 | import java.util.ArrayList; | |||
import java.util.List; | 8 | 9 | import java.util.List; | |
9 | 10 | |||
import static com.google.common.collect.Lists.newArrayList; | 10 | 11 | import static com.google.common.collect.Lists.newArrayList; | |
12 | import static java.lang.Double.parseDouble; | |||
import static java.lang.Integer.parseInt; | 11 | 13 | import static java.lang.Integer.parseInt; | |
import static java.lang.Long.parseLong; | 12 | 14 | import static java.lang.Long.parseLong; | |
import static java.lang.System.nanoTime; | 13 | 15 | import static java.lang.System.nanoTime; | |
import static java.time.Instant.now; | 14 | 16 | import static java.time.Instant.now; | |
import static java.util.Arrays.asList; | 15 | 17 | import static java.util.Arrays.asList; | |
import static java.util.Date.from; | 16 | 18 | import static java.util.Date.from; | |
17 | 19 | |||
public class Main { | 18 | 20 | public class Main { | |
19 | 21 | |||
private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("dd-MM_hh-mm-ss"); | 20 | 22 | private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("dd-MM_hh-mm-ss"); | |
23 | private static final double EARTH_RADIUS = 6_371_000; // [m] | |||
21 | 24 | |||
public static void main(String[] args) throws Exception { | 22 | 25 | public static void main(String[] args) throws Exception { | |
final long startTime = nanoTime(); | 23 | 26 | final long startTime = nanoTime(); | |
if (args.length == 2 && args[0].compareToIgnoreCase("-mm") == 0) { | 24 | 27 | if (args.length == 2 && args[0].compareToIgnoreCase("-mm") == 0) { | |
final File input = new File(args[1]); | 25 | 28 | final File input = new File(args[1]); | |
printMinMaxTimestamps(input); | 26 | 29 | printMinMaxTimestamps(input); | |
30 | } else if (args.length == 2 && args[0].compareToIgnoreCase("-id") == 0) { | |||
31 | final File input = new File(args[1]); | |||
32 | printAllMMSIs(input); | |||
} | 27 | 33 | } | |
if (args.length == 3) { | 28 | 34 | if (args.length == 3) { | |
if (args[0].compareToIgnoreCase("-ev") == 0) { | 29 | 35 | if (args[0].compareToIgnoreCase("-ev") == 0) { | |
final File input = new File(args[1]); | 30 | 36 | final File input = new File(args[1]); | |
final List<Integer> userIDs = newArrayList(); | 31 | 37 | final List<Integer> userIDs = newArrayList(); | |
asList(args[2].split(",")).forEach(id -> userIDs.add(parseInt(id))); | 32 | 38 | asList(args[2].split(",")).forEach(id -> userIDs.add(parseInt(id))); | |
extractVessels( | 33 | 39 | extractVessels( | |
input, | 34 | 40 | input, | |
new File(input.getParentFile(), getDateStr() + "_" + input.getName()), | 35 | 41 | new File(input.getParentFile(), getDateStr() + "_" + input.getName()), | |
userIDs); | 36 | 42 | userIDs); | |
} | 37 | 43 | } | |
if (args[0].compareToIgnoreCase("-fp") == 0) { | 38 | 44 | if (args[0].compareToIgnoreCase("-fp") == 0) { | |
final File input = new File(args[1]); | 39 | 45 | final File input = new File(args[1]); | |
filterOutPattern( | 40 | 46 | filterOutPattern( | |
input, | 41 | 47 | input, | |
new File(input.getParentFile(), getDateStr() + "_" + input.getName()), | 42 | 48 | new File(input.getParentFile(), getDateStr() + "_" + input.getName()), | |
args[2]); | 43 | 49 | args[2]); | |
} | 44 | 50 | } | |
if (args[0].compareToIgnoreCase("-ep") == 0) { | 45 | 51 | if (args[0].compareToIgnoreCase("-ep") == 0) { | |
final File input = new File(args[1]); | 46 | 52 | final File input = new File(args[1]); | |
extractPattern( | 47 | 53 | extractPattern( | |
input, | 48 | 54 | input, | |
new File(input.getParentFile(), getDateStr() + "_" + input.getName()), | 49 | 55 | new File(input.getParentFile(), getDateStr() + "_" + input.getName()), | |
args[2]); | 50 | 56 | args[2]); | |
} | 51 | 57 | } | |
} | 52 | 58 | } | |
if (args.length == 4 && args[0].compareToIgnoreCase("-tw") == 0) { | 53 | 59 | if (args.length == 4 && args[0].compareToIgnoreCase("-tw") == 0) { | |
final File input = new File(args[1]); | 54 | 60 | final File input = new File(args[1]); | |
final long lowerTimestamp = parseLong(args[2]); | 55 | 61 | final long lowerTimestamp = parseLong(args[2]); | |
extractTimeWindow( | 56 | 62 | extractTimeWindow( | |
input, | 57 | 63 | input, | |
new File(input.getParentFile(), getDateStr() + "_" + input.getName()), | 58 | 64 | new File(input.getParentFile(), getDateStr() + "_" + input.getName()), | |
lowerTimestamp, | 59 | 65 | lowerTimestamp, | |
lowerTimestamp + parseLong(args[3]) * 3600); | 60 | 66 | lowerTimestamp + parseLong(args[3]) * 3600); | |
} | 61 | 67 | } | |
68 | if (args.length == 5 && args[0].compareToIgnoreCase("-zo") == 0) { | |||
69 | final File input = new File(args[1]); | |||
70 | final double lat = parseDouble(args[2]); | |||
71 | final double lon = parseDouble(args[3]); | |||
72 | final int rad = parseInt(args[4]); | |||
73 | extractArea(input,new File(input.getParentFile(), getDateStr() + "_zoneExtract_" + input.getName()), | |||
74 | lat,lon,rad); | |||
75 | } | |||
final long endTime = nanoTime(); | 62 | 76 | final long endTime = nanoTime(); | |
System.out.println("Execution time in milliseconds: " + (endTime - startTime) / 1000000); | 63 | 77 | System.out.println("Execution time in milliseconds: " + (endTime - startTime) / 1000000); | |
} | 64 | 78 | } | |
65 | 79 | |||
private static String getDateStr() { | 66 | 80 | private static String getDateStr() { | |
return DATE_FORMAT.format(from(now())); | 67 | 81 | return DATE_FORMAT.format(from(now())); | |
} | 68 | 82 | } | |
69 | 83 | |||
84 | private static void printAllMMSIs(final File input) throws IOException { | |||
85 | try (final FileReader fileReader = new FileReader(input); | |||
86 | final BufferedReader bufferedReader = new BufferedReader(fileReader);) { | |||
87 | String currentMessage = bufferedReader.readLine(); | |||
88 | List<Integer> mmsis = new ArrayList<>(); | |||
89 | while (currentMessage != null) { | |||
90 | if (!currentMessage.isEmpty()) { | |||
91 | final Vdm vdm = new Vdm(); | |||
92 | try { | |||
93 | vdm.parse(currentMessage); | |||
94 | int mmsi = AisMessage.getInstance(vdm).getUserId(); | |||
95 | if(!mmsis.contains(mmsi)) { | |||
96 | mmsis.add(mmsi); | |||
97 | System.out.println(mmsi); | |||
98 | } | |||
99 | } catch (final Exception ignored) { | |||
100 | ||||
101 | } | |||
102 | } | |||
103 | currentMessage = bufferedReader.readLine(); | |||
104 | } | |||
105 | } | |||
106 | } | |||
107 | ||||
private static void printMinMaxTimestamps(final File input) throws IOException { | 70 | 108 | private static void printMinMaxTimestamps(final File input) throws IOException { | |
try (final FileReader fileReader = new FileReader(input); | 71 | 109 | try (final FileReader fileReader = new FileReader(input); | |
final BufferedReader bufferedReader = new BufferedReader(fileReader)) { | 72 | 110 | final BufferedReader bufferedReader = new BufferedReader(fileReader)) { | |
String currentMessage = bufferedReader.readLine(); | 73 | 111 | String currentMessage = bufferedReader.readLine(); | |
long maxTimestamp = Long.MIN_VALUE; | 74 | 112 | long maxTimestamp = Long.MIN_VALUE; | |
long minTimestamp = Long.MAX_VALUE; | 75 | 113 | long minTimestamp = Long.MAX_VALUE; | |
while (currentMessage != null) { | 76 | 114 | while (currentMessage != null) { | |
if (!currentMessage.isEmpty()) { | 77 | 115 | if (!currentMessage.isEmpty()) { | |
try { | 78 | 116 | try { | |
final long timestamp = parseLong(currentMessage.substring(3).split(",")[0]); | 79 | 117 | final long timestamp = parseLong(currentMessage.substring(3).split(",")[0]); | |
if (timestamp < minTimestamp) { | 80 | 118 | if (timestamp < minTimestamp) { | |
minTimestamp = timestamp; | 81 | 119 | minTimestamp = timestamp; | |
} | 82 | 120 | } | |
if (timestamp > maxTimestamp) { | 83 | 121 | if (timestamp > maxTimestamp) { | |
maxTimestamp = timestamp; | 84 | 122 | maxTimestamp = timestamp; | |
} | 85 | 123 | } | |
} catch (final Exception ignored) { | 86 | 124 | } catch (final Exception ignored) { | |
} | 87 | 125 | } | |
} | 88 | 126 | } | |
currentMessage = bufferedReader.readLine(); | 89 | 127 | currentMessage = bufferedReader.readLine(); | |
} | 90 | 128 | } | |
System.out.println("Min timestamp: " + minTimestamp); | 91 | 129 | System.out.println("Min timestamp: " + minTimestamp); | |
System.out.println("Max timestamp: " + maxTimestamp); | 92 | 130 | System.out.println("Max timestamp: " + maxTimestamp); | |
} | 93 | 131 | } | |
} | 94 | 132 | } | |
95 | 133 | |||
private static void extractVessels(final File input, | 96 | 134 | private static void extractVessels(final File input, | |
final File output, | 97 | 135 | final File output, | |
final List<Integer> MMSIs) throws IOException { | 98 | 136 | final List<Integer> MMSIs) throws IOException { | |
try (final FileReader fileReader = new FileReader(input); | 99 | 137 | try (final FileReader fileReader = new FileReader(input); | |
final BufferedReader bufferedReader = new BufferedReader(fileReader); | 100 | 138 | final BufferedReader bufferedReader = new BufferedReader(fileReader); | |
final FileWriter fileWriter = new FileWriter(output); | 101 | 139 | final FileWriter fileWriter = new FileWriter(output); | |
final BufferedWriter bufferedWriter = new BufferedWriter(fileWriter)) { | 102 | 140 | final BufferedWriter bufferedWriter = new BufferedWriter(fileWriter)) { | |
String currentMessage = bufferedReader.readLine(); | 103 | 141 | String currentMessage = bufferedReader.readLine(); | |
while (currentMessage != null) { | 104 | 142 | while (currentMessage != null) { | |
if (!currentMessage.isEmpty()) { | 105 | 143 | if (!currentMessage.isEmpty()) { | |
final Vdm vdm = new Vdm(); | 106 | 144 | final Vdm vdm = new Vdm(); | |
try { | 107 | 145 | try { | |
vdm.parse(currentMessage); | 108 | 146 | vdm.parse(currentMessage); | |
if (MMSIs.contains(AisMessage.getInstance(vdm).getUserId())) { | 109 | 147 | if (MMSIs.contains(AisMessage.getInstance(vdm).getUserId())) { | |
bufferedWriter.write(currentMessage + "\n"); | 110 | 148 | bufferedWriter.write(currentMessage + "\n"); | |
} | 111 | 149 | } | |
} catch (final Exception ignored) { | 112 | 150 | } catch (final Exception ignored) { | |
113 | 151 | |||
} | 114 | 152 | } | |
} | 115 | 153 | } | |
currentMessage = bufferedReader.readLine(); | 116 | 154 | currentMessage = bufferedReader.readLine(); | |
} | 117 | 155 | } | |
} | 118 | 156 | } | |
} | 119 | 157 | } | |
120 | 158 | |||
private static void filterOutPattern(final File input, | 121 | 159 | private static void filterOutPattern(final File input, | |
final File output, | 122 | 160 | final File output, | |
final String pattern) throws IOException { | 123 | 161 | final String pattern) throws IOException { | |
try (final FileReader fileReader = new FileReader(input); | 124 | 162 | try (final FileReader fileReader = new FileReader(input); | |
final BufferedReader bufferedReader = new BufferedReader(fileReader); | 125 | 163 | final BufferedReader bufferedReader = new BufferedReader(fileReader); | |
final FileWriter fileWriter = new FileWriter(output); | 126 | 164 | final FileWriter fileWriter = new FileWriter(output); | |
final BufferedWriter bufferedWriter = new BufferedWriter(fileWriter)) { | 127 | 165 | final BufferedWriter bufferedWriter = new BufferedWriter(fileWriter)) { | |
String currentMessage = bufferedReader.readLine(); | 128 | 166 | String currentMessage = bufferedReader.readLine(); | |
while (currentMessage != null) { | 129 | 167 | while (currentMessage != null) { | |
if (!currentMessage.isEmpty()) { | 130 | 168 | if (!currentMessage.isEmpty()) { | |
if (!currentMessage.contains(pattern)) { | 131 | 169 | if (!currentMessage.contains(pattern)) { | |
bufferedWriter.write(currentMessage + "\n"); | 132 | 170 | bufferedWriter.write(currentMessage + "\n"); | |
} | 133 | 171 | } | |
} | 134 | 172 | } | |
currentMessage = bufferedReader.readLine(); | 135 | 173 | currentMessage = bufferedReader.readLine(); | |
} | 136 | 174 | } | |
} | 137 | 175 | } | |
} | 138 | 176 | } | |
139 | 177 | |||
private static void extractPattern(final File input, | 140 | 178 | private static void extractPattern(final File input, | |
final File output, | 141 | 179 | final File output, | |
final String pattern) throws IOException { | 142 | 180 | final String pattern) throws IOException { | |
try (final FileReader fileReader = new FileReader(input); | 143 | 181 | try (final FileReader fileReader = new FileReader(input); | |
final BufferedReader bufferedReader = new BufferedReader(fileReader); | 144 | 182 | final BufferedReader bufferedReader = new BufferedReader(fileReader); | |
final FileWriter fileWriter = new FileWriter(output); | 145 | 183 | final FileWriter fileWriter = new FileWriter(output); | |
final BufferedWriter bufferedWriter = new BufferedWriter(fileWriter)) { | 146 | 184 | final BufferedWriter bufferedWriter = new BufferedWriter(fileWriter)) { | |
String currentMessage = bufferedReader.readLine(); | 147 | 185 | String currentMessage = bufferedReader.readLine(); | |
while (currentMessage != null) { | 148 | 186 | while (currentMessage != null) { | |
if (!currentMessage.isEmpty()) { | 149 | 187 | if (!currentMessage.isEmpty()) { | |
if (currentMessage.contains(pattern)) { | 150 | 188 | if (currentMessage.contains(pattern)) { | |
bufferedWriter.write(currentMessage + "\n"); | 151 | 189 | bufferedWriter.write(currentMessage + "\n"); | |
} | 152 | 190 | } | |
} | 153 | 191 | } | |
currentMessage = bufferedReader.readLine(); | 154 | 192 | currentMessage = bufferedReader.readLine(); | |
} | 155 | 193 | } | |
} | 156 | 194 | } | |
} | 157 | 195 | } | |
158 | 196 | |||
private static void extractTimeWindow(final File input, | 159 | 197 | private static void extractTimeWindow(final File input, | |
final File output, | 160 | 198 | final File output, | |
final long lowerTimestamp, | 161 | 199 | final long lowerTimestamp, | |
final long upperTimestamp) throws IOException { | 162 | 200 | final long upperTimestamp) throws IOException { | |
try (final FileReader fileReader = new FileReader(input); | 163 | 201 | try (final FileReader fileReader = new FileReader(input); | |
final BufferedReader bufferedReader = new BufferedReader(fileReader); | 164 | 202 | final BufferedReader bufferedReader = new BufferedReader(fileReader); | |
final FileWriter fileWriter = new FileWriter(output); | 165 | 203 | final FileWriter fileWriter = new FileWriter(output); | |
final BufferedWriter bufferedWriter = new BufferedWriter(fileWriter)) { | 166 | 204 | final BufferedWriter bufferedWriter = new BufferedWriter(fileWriter)) { | |
String currentMessage = bufferedReader.readLine(); | 167 | 205 | String currentMessage = bufferedReader.readLine(); | |
while (currentMessage != null) { | 168 | 206 | while (currentMessage != null) { | |
if (!currentMessage.isEmpty()) { | 169 | 207 | if (!currentMessage.isEmpty()) { | |
try { | 170 | 208 | try { | |
final long timestamp = parseLong(currentMessage.substring(3).split(",")[0]); | 171 | 209 | final long timestamp = parseLong(currentMessage.substring(3).split(",")[0]); | |
if (lowerTimestamp <= timestamp && timestamp <= upperTimestamp) { | 172 | 210 | if (lowerTimestamp <= timestamp && timestamp <= upperTimestamp) { | |
bufferedWriter.write(currentMessage + "\n"); | 173 | 211 | bufferedWriter.write(currentMessage + "\n"); | |
} | 174 | 212 | } | |
} catch (final Exception ignored) { | 175 | 213 | } catch (final Exception ignored) { | |
176 | 214 | |||
} | 177 | 215 | } | |
} | 178 | 216 | } | |
currentMessage = bufferedReader.readLine(); | 179 | 217 | currentMessage = bufferedReader.readLine(); | |
} | 180 | 218 | } | |
} | 181 | 219 | } | |
220 | } | |||
221 | ||||
222 | private static void extractArea(final File input, | |||
223 | final File output, | |||
224 | final double lat, | |||
225 | final double lon, | |||
226 | final int radius) throws IOException { | |||
227 | try (final FileReader fileReader = new FileReader(input); | |||
228 | final BufferedReader bufferedReader = new BufferedReader(fileReader); | |||
229 | final FileWriter fileWriter = new FileWriter(output); | |||
230 | final BufferedWriter bufferedWriter = new BufferedWriter(fileWriter)) { | |||
231 | String currentMessage = bufferedReader.readLine(); | |||
232 | List<Integer> mmsis = new ArrayList<>(); | |||
233 | while (currentMessage != null) { | |||
234 | if (!currentMessage.isEmpty()) { | |||
235 | final Vdm vdm = new Vdm(); | |||
236 | try { | |||
237 | vdm.parse(currentMessage); | |||
238 | AisPosition pos = extractPosition(AisMessage.getInstance(vdm)); | |||
239 | int mmsi = AisMessage.getInstance(vdm).getUserId(); | |||
240 | if (pos.getLatitude() < 91 && | |||
241 | calcDistanceInMeter(pos.getLatitudeDouble(),pos.getLongitudeDouble(), | |||
242 | lat, lon) < (radius * 1000) && | |||
243 | !(mmsis.size() > 20 && !mmsis.contains(mmsi))) { | |||
244 | bufferedWriter.write(currentMessage + "\n"); | |||
245 | if(!mmsis.contains(mmsi)) { | |||
246 | mmsis.add(mmsi); | |||
247 | } | |||
248 | } | |||
249 | } catch (final Exception ignored) { | |||
250 | ||||
251 | } | |||
252 | } | |||
253 | currentMessage = bufferedReader.readLine(); | |||
254 | } | |||
255 | } | |||
256 | } | |||
257 | ||||
258 | private static AisPosition extractPosition(AisMessage msg) { | |||
259 | return new PositionVisitor() { | |||
260 | @Override | |||
261 | public AisPosition visitPositionMessage(AisPositionMessage aisMessage) { | |||
262 | return aisMessage.getPos(); | |||
263 | } | |||
264 | ||||
265 | @Override | |||
266 | public AisPosition visitMessage4(AisMessage4 aisMessage) { | |||
267 | return aisMessage.getPos(); | |||
268 | } | |||
269 | ||||
270 | @Override | |||
271 | public AisPosition visitMessage9(AisMessage9 aisMessage) { | |||
272 | return aisMessage.getPos(); | |||
273 | } | |||
274 | ||||
275 | @Override | |||
276 | public AisPosition visitMessage18(AisMessage18 aisMessage) { | |||
277 | return aisMessage.getPos(); | |||
278 | } | |||
279 | ||||
280 | @Override | |||
281 | public AisPosition visitMessage19(AisMessage19 aisMessage) { | |||
282 | return aisMessage.getPos(); | |||
283 | } | |||
284 | ||||
285 | @Override | |||
286 | public AisPosition visitMessage21(AisMessage21 aisMessage) { | |||
287 | return aisMessage.getPos(); | |||
288 | } | |||
289 | ||||
290 | @Override | |||
291 | public AisPosition visitMessage27(AisMessage27 aisMessage) { | |||
292 | return aisMessage.getPos(); | |||
293 | } | |||
294 | }.doSwitch(msg); | |||
295 | } | |||
296 | ||||
297 | private interface PositionVisitor { | |||
298 | ||||
299 | AisPosition visitPositionMessage(final AisPositionMessage aisMessage); | |||
300 | ||||
301 | AisPosition visitMessage4(final AisMessage4 aisMessage); | |||
302 | ||||
303 | AisPosition visitMessage9(final AisMessage9 aisMessage); | |||
304 | ||||
305 | AisPosition visitMessage18(final AisMessage18 aisMessage); | |||
306 | ||||
307 | AisPosition visitMessage19(final AisMessage19 aisMessage); | |||
308 | ||||
309 | AisPosition visitMessage21(final AisMessage21 aisMessage); | |||
310 | ||||
311 | AisPosition visitMessage27(final AisMessage27 aisMessage); | |||
312 | ||||
313 | default AisPosition visitDefault() { | |||
314 | return new AisPosition(91,181); | |||
315 | } | |||
316 | ||||
317 | default AisPosition doSwitch(final AisMessage aisMessage) { | |||
318 | if (aisMessage instanceof AisPositionMessage) { | |||
319 | return visitPositionMessage((AisPositionMessage) aisMessage); | |||
320 | } | |||
321 | if (aisMessage instanceof AisMessage4) { | |||
322 | return visitMessage4((AisMessage4) aisMessage); | |||
323 | } | |||
324 | if (aisMessage instanceof AisMessage9) { | |||
325 | return visitMessage9((AisMessage9) aisMessage); | |||
326 | } | |||
327 | if (aisMessage instanceof AisMessage18) { | |||
328 | return visitMessage18((AisMessage18) aisMessage); | |||
329 | } | |||
330 | if (aisMessage instanceof AisMessage19) { | |||
331 | return visitMessage19((AisMessage19) aisMessage); | |||
332 | } | |||
333 | if (aisMessage instanceof AisMessage21) { | |||
334 | return visitMessage21((AisMessage21) aisMessage); | |||
335 | } | |||
336 | if (aisMessage instanceof AisMessage27) { | |||
337 | return visitMessage27((AisMessage27) aisMessage); | |||
338 | } | |||
339 | return visitDefault(); | |||
340 | } | |||
341 | } | |||
342 | ||||
343 | private static double calcDistanceInMeter(final double lat1, final double lon1, final double lat2, final double lon2) { | |||
344 | final double LAT_1_RADIANS = Math.toRadians(lat1); | |||
345 | final double LAT_2_RADIANS = Math.toRadians(lat2); |