Commit 1e44cd5576433a4cff91030e50aba65248169280

Authored by avernott
1 parent 84aa038169
Exists in master

added alpha support for zones

Showing 1 changed file with 176 additions and 1 deletions Side-by-side Diff

src/main/java/fr/femto/extractor/track/Main.java View file @ 1e44cd5
1 1 package fr.femto.extractor.track;
2 2  
3   -import dk.dma.ais.message.AisMessage;
  3 +import dk.dma.ais.message.*;
4 4 import dk.dma.ais.sentence.Vdm;
5 5  
6 6 import java.io.*;
7 7 import java.text.SimpleDateFormat;
  8 +import java.util.ArrayList;
8 9 import java.util.List;
9 10  
10 11 import static com.google.common.collect.Lists.newArrayList;
  12 +import static java.lang.Double.parseDouble;
11 13 import static java.lang.Integer.parseInt;
12 14 import static java.lang.Long.parseLong;
13 15 import static java.lang.System.nanoTime;
14 16  
... ... @@ -18,12 +20,16 @@
18 20 public class Main {
19 21  
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  
22 25 public static void main(String[] args) throws Exception {
23 26 final long startTime = nanoTime();
24 27 if (args.length == 2 && args[0].compareToIgnoreCase("-mm") == 0) {
25 28 final File input = new File(args[1]);
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 }
28 34 if (args.length == 3) {
29 35 if (args[0].compareToIgnoreCase("-ev") == 0) {
... ... @@ -59,6 +65,14 @@
59 65 lowerTimestamp,
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 + }
62 76 final long endTime = nanoTime();
63 77 System.out.println("Execution time in milliseconds: " + (endTime - startTime) / 1000000);
64 78 }
... ... @@ -67,6 +81,30 @@
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 +
70 108 private static void printMinMaxTimestamps(final File input) throws IOException {
71 109 try (final FileReader fileReader = new FileReader(input);
72 110 final BufferedReader bufferedReader = new BufferedReader(fileReader)) {
... ... @@ -179,6 +217,143 @@
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);
  346 + final double DELTA_LAT_RADIANS = Math.toRadians(lat2 - lat1);
  347 + final double DELTA_LON_RADIANS = Math.toRadians(lon2 - lon1);
  348 +
  349 + final double A = Math.sin(DELTA_LAT_RADIANS * 0.5) * Math.sin(DELTA_LAT_RADIANS * 0.5) +
  350 + Math.cos(LAT_1_RADIANS) *
  351 + Math.cos(LAT_2_RADIANS) *
  352 + Math.sin(DELTA_LON_RADIANS * 0.5) *
  353 + Math.sin(DELTA_LON_RADIANS * 0.5);
  354 + final double c = 2 * Math.atan2(Math.sqrt(A), Math.sqrt(1 - A));
  355 +
  356 + return EARTH_RADIUS * c;
182 357 }
183 358 }