View Javadoc
1   package au.gov.amsa.navigation;
2   
3   import java.util.concurrent.TimeUnit;
4   
5   import com.google.common.base.Optional;
6   
7   import au.gov.amsa.navigation.VesselPosition.NavigationalStatus;
8   import au.gov.amsa.risky.format.AisClass;
9   import au.gov.amsa.risky.format.Fix;
10  import au.gov.amsa.risky.format.HasFix;
11  import rx.functions.Func1;
12  
13  public class VesselPositions {
14  
15      private static final double KNOTS_TO_METRES_PER_SECOND = 1852.0 / TimeUnit.HOURS.toSeconds(1);
16  
17      // TODO unit test
18      public static VesselPosition toVesselPosition(Fix fix, Optional<?> data) {
19          return VesselPosition.builder().id(new Mmsi(fix.mmsi())).lat(fix.lat()).lon(fix.lon())
20                  .time(fix.time()).cls(fix.aisClass() == AisClass.A ? VesselClass.A : VesselClass.B)
21                  .cogDegrees(toDouble(fix.courseOverGroundDegrees()))
22                  .headingDegrees(toDouble(fix.headingDegrees()))
23                  .speedMetresPerSecond(
24                          multiply(fix.speedOverGroundKnots(), KNOTS_TO_METRES_PER_SECOND))
25                  .navigationalStatus(fix.navigationalStatus().isPresent()
26                          ? NavigationalStatus.values()[fix.navigationalStatus().get().ordinal()]
27                          : NavigationalStatus.NOT_DEFINED)
28                  .positionAisNmea(Optional.<String> absent())
29                  .shipStaticAisNmea(Optional.<String> absent())
30                  // set data
31                  .data(data)
32                  // build
33                  .build();
34      }
35  
36      public static Func1<HasFix, VesselPosition> TO_VESSEL_POSITION = fix -> toVesselPosition(
37              fix.fix(), Optional.absent());
38  
39      public static <T extends HasFix> Func1<T, VesselPosition> toVesselPosition(
40              final Func1<T, Optional<?>> dataExtractor) {
41          return fix -> toVesselPosition(fix.fix(), dataExtractor.call(fix));
42      }
43  
44      private static Optional<Double> toDouble(Optional<Float> value) {
45          if (!value.isPresent())
46              return Optional.absent();
47          else
48              return Optional.of((double) value.get());
49      }
50  
51      private static Optional<Double> multiply(Optional<Float> value, double factor) {
52          if (!value.isPresent())
53              return Optional.absent();
54          else
55              return Optional.of((double) value.get() * factor);
56      }
57  
58  }