From 1e44cd5576433a4cff91030e50aba65248169280 Mon Sep 17 00:00:00 2001 From: avernott Date: Wed, 20 Nov 2019 11:36:04 +0100 Subject: [PATCH] added alpha support for zones --- src/main/java/fr/femto/extractor/track/Main.java | 177 +++++++++++++++++++++- 1 file changed, 176 insertions(+), 1 deletion(-) diff --git a/src/main/java/fr/femto/extractor/track/Main.java b/src/main/java/fr/femto/extractor/track/Main.java index 22cec0d..a03885b 100644 --- a/src/main/java/fr/femto/extractor/track/Main.java +++ b/src/main/java/fr/femto/extractor/track/Main.java @@ -1,13 +1,15 @@ package fr.femto.extractor.track; -import dk.dma.ais.message.AisMessage; +import dk.dma.ais.message.*; import dk.dma.ais.sentence.Vdm; import java.io.*; import java.text.SimpleDateFormat; +import java.util.ArrayList; import java.util.List; import static com.google.common.collect.Lists.newArrayList; +import static java.lang.Double.parseDouble; import static java.lang.Integer.parseInt; import static java.lang.Long.parseLong; import static java.lang.System.nanoTime; @@ -18,12 +20,16 @@ import static java.util.Date.from; public class Main { private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("dd-MM_hh-mm-ss"); + private static final double EARTH_RADIUS = 6_371_000; // [m] public static void main(String[] args) throws Exception { final long startTime = nanoTime(); if (args.length == 2 && args[0].compareToIgnoreCase("-mm") == 0) { final File input = new File(args[1]); printMinMaxTimestamps(input); + } else if (args.length == 2 && args[0].compareToIgnoreCase("-id") == 0) { + final File input = new File(args[1]); + printAllMMSIs(input); } if (args.length == 3) { if (args[0].compareToIgnoreCase("-ev") == 0) { @@ -59,6 +65,14 @@ public class Main { lowerTimestamp, lowerTimestamp + parseLong(args[3]) * 3600); } + if (args.length == 5 && args[0].compareToIgnoreCase("-zo") == 0) { + final File input = new File(args[1]); + final double lat = parseDouble(args[2]); + final double lon = parseDouble(args[3]); + final int rad = parseInt(args[4]); + extractArea(input,new File(input.getParentFile(), getDateStr() + "_zoneExtract_" + input.getName()), + lat,lon,rad); + } final long endTime = nanoTime(); System.out.println("Execution time in milliseconds: " + (endTime - startTime) / 1000000); } @@ -67,6 +81,30 @@ public class Main { return DATE_FORMAT.format(from(now())); } + private static void printAllMMSIs(final File input) throws IOException { + try (final FileReader fileReader = new FileReader(input); + final BufferedReader bufferedReader = new BufferedReader(fileReader);) { + String currentMessage = bufferedReader.readLine(); + List mmsis = new ArrayList<>(); + while (currentMessage != null) { + if (!currentMessage.isEmpty()) { + final Vdm vdm = new Vdm(); + try { + vdm.parse(currentMessage); + int mmsi = AisMessage.getInstance(vdm).getUserId(); + if(!mmsis.contains(mmsi)) { + mmsis.add(mmsi); + System.out.println(mmsi); + } + } catch (final Exception ignored) { + + } + } + currentMessage = bufferedReader.readLine(); + } + } + } + private static void printMinMaxTimestamps(final File input) throws IOException { try (final FileReader fileReader = new FileReader(input); final BufferedReader bufferedReader = new BufferedReader(fileReader)) { @@ -180,4 +218,141 @@ public class Main { } } } + + private static void extractArea(final File input, + final File output, + final double lat, + final double lon, + final int radius) throws IOException { + try (final FileReader fileReader = new FileReader(input); + final BufferedReader bufferedReader = new BufferedReader(fileReader); + final FileWriter fileWriter = new FileWriter(output); + final BufferedWriter bufferedWriter = new BufferedWriter(fileWriter)) { + String currentMessage = bufferedReader.readLine(); + List mmsis = new ArrayList<>(); + while (currentMessage != null) { + if (!currentMessage.isEmpty()) { + final Vdm vdm = new Vdm(); + try { + vdm.parse(currentMessage); + AisPosition pos = extractPosition(AisMessage.getInstance(vdm)); + int mmsi = AisMessage.getInstance(vdm).getUserId(); + if (pos.getLatitude() < 91 && + calcDistanceInMeter(pos.getLatitudeDouble(),pos.getLongitudeDouble(), + lat, lon) < (radius * 1000) && + !(mmsis.size() > 20 && !mmsis.contains(mmsi))) { + bufferedWriter.write(currentMessage + "\n"); + if(!mmsis.contains(mmsi)) { + mmsis.add(mmsi); + } + } + } catch (final Exception ignored) { + + } + } + currentMessage = bufferedReader.readLine(); + } + } + } + + private static AisPosition extractPosition(AisMessage msg) { + return new PositionVisitor() { + @Override + public AisPosition visitPositionMessage(AisPositionMessage aisMessage) { + return aisMessage.getPos(); + } + + @Override + public AisPosition visitMessage4(AisMessage4 aisMessage) { + return aisMessage.getPos(); + } + + @Override + public AisPosition visitMessage9(AisMessage9 aisMessage) { + return aisMessage.getPos(); + } + + @Override + public AisPosition visitMessage18(AisMessage18 aisMessage) { + return aisMessage.getPos(); + } + + @Override + public AisPosition visitMessage19(AisMessage19 aisMessage) { + return aisMessage.getPos(); + } + + @Override + public AisPosition visitMessage21(AisMessage21 aisMessage) { + return aisMessage.getPos(); + } + + @Override + public AisPosition visitMessage27(AisMessage27 aisMessage) { + return aisMessage.getPos(); + } + }.doSwitch(msg); + } + + private interface PositionVisitor { + + AisPosition visitPositionMessage(final AisPositionMessage aisMessage); + + AisPosition visitMessage4(final AisMessage4 aisMessage); + + AisPosition visitMessage9(final AisMessage9 aisMessage); + + AisPosition visitMessage18(final AisMessage18 aisMessage); + + AisPosition visitMessage19(final AisMessage19 aisMessage); + + AisPosition visitMessage21(final AisMessage21 aisMessage); + + AisPosition visitMessage27(final AisMessage27 aisMessage); + + default AisPosition visitDefault() { + return new AisPosition(91,181); + } + + default AisPosition doSwitch(final AisMessage aisMessage) { + if (aisMessage instanceof AisPositionMessage) { + return visitPositionMessage((AisPositionMessage) aisMessage); + } + if (aisMessage instanceof AisMessage4) { + return visitMessage4((AisMessage4) aisMessage); + } + if (aisMessage instanceof AisMessage9) { + return visitMessage9((AisMessage9) aisMessage); + } + if (aisMessage instanceof AisMessage18) { + return visitMessage18((AisMessage18) aisMessage); + } + if (aisMessage instanceof AisMessage19) { + return visitMessage19((AisMessage19) aisMessage); + } + if (aisMessage instanceof AisMessage21) { + return visitMessage21((AisMessage21) aisMessage); + } + if (aisMessage instanceof AisMessage27) { + return visitMessage27((AisMessage27) aisMessage); + } + return visitDefault(); + } + } + + private static double calcDistanceInMeter(final double lat1, final double lon1, final double lat2, final double lon2) { + final double LAT_1_RADIANS = Math.toRadians(lat1); + final double LAT_2_RADIANS = Math.toRadians(lat2); + final double DELTA_LAT_RADIANS = Math.toRadians(lat2 - lat1); + final double DELTA_LON_RADIANS = Math.toRadians(lon2 - lon1); + + final double A = Math.sin(DELTA_LAT_RADIANS * 0.5) * Math.sin(DELTA_LAT_RADIANS * 0.5) + + Math.cos(LAT_1_RADIANS) * + Math.cos(LAT_2_RADIANS) * + Math.sin(DELTA_LON_RADIANS * 0.5) * + Math.sin(DELTA_LON_RADIANS * 0.5); + final double c = 2 * Math.atan2(Math.sqrt(A), Math.sqrt(1 - A)); + + return EARTH_RADIUS * c; + } } \ No newline at end of file -- 1.7.10.4