package au.gov.amsa.risky.format;
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
public final class FixImpl implements HasFix, Fix {
public static boolean validate = true;
private final int mmsi;
private final float lat;
private final float lon;
private final long time;
private final Optional<NavigationalStatus> navigationalStatus;
private final Optional<Float> speedOverGroundKnots;
private final Optional<Float> courseOverGroundDegrees;
private final Optional<Float> headingDegrees;
private final AisClass aisClass;
private final Optional<Integer> latencySeconds;
private final Optional<Short> source;
public FixImpl(int mmsi, float lat, float lon, long time, AisClass aisClass) {
this(mmsi, lat, lon, time, Optional.absent(), Optional.absent(), Optional.absent(),
Optional.absent(), Optional.absent(), Optional.absent(), aisClass);
}
public FixImpl(int mmsi, float lat, float lon, long time, Optional<Integer> latencySeconds,
Optional<Short> source, Optional<NavigationalStatus> navigationalStatus,
Optional<Float> speedOverGroundKnots, Optional<Float> courseOverGroundDegrees,
Optional<Float> headingDegrees, AisClass aisClass) {
if (validate) {
Preconditions.checkNotNull(navigationalStatus);
Preconditions.checkNotNull(courseOverGroundDegrees);
Preconditions.checkNotNull(headingDegrees);
Preconditions.checkNotNull(aisClass);
Preconditions.checkNotNull(latencySeconds);
Preconditions.checkNotNull(source);
if (courseOverGroundDegrees.isPresent()) {
Preconditions.checkArgument(
courseOverGroundDegrees.get() < 360 && courseOverGroundDegrees.get() >= 0,
"cog=" + courseOverGroundDegrees.get());
}
if (headingDegrees.isPresent()) {
Preconditions
.checkArgument(headingDegrees.get() < 360 && headingDegrees.get() >= 0);
}
Preconditions.checkArgument(lat >= -90 && lat <= 90);
Preconditions.checkArgument(lon >= -180 && lon <= 180);
}
this.mmsi = mmsi;
this.lat = lat;
this.lon = lon;
this.time = time;
this.latencySeconds = latencySeconds;
this.source = source;
this.navigationalStatus = navigationalStatus;
this.speedOverGroundKnots = speedOverGroundKnots;
this.courseOverGroundDegrees = courseOverGroundDegrees;
this.headingDegrees = headingDegrees;
this.aisClass = aisClass;
}
@Override
public int mmsi() {
return mmsi;
}
@Override
public long time() {
return time;
}
@Override
public float lat() {
return lat;
}
@Override
public float lon() {
return lon;
}
@Override
public Optional<NavigationalStatus> navigationalStatus() {
return navigationalStatus;
}
@Override
public Optional<Float> speedOverGroundKnots() {
return speedOverGroundKnots;
}
@Override
public Optional<Float> courseOverGroundDegrees() {
return courseOverGroundDegrees;
}
@Override
public Optional<Float> headingDegrees() {
return headingDegrees;
}
@Override
public AisClass aisClass() {
return aisClass;
}
@Override
public Optional<Integer> latencySeconds() {
return latencySeconds;
}
@Override
public Optional<Short> source() {
return source;
}
@Override
public Optional<Byte> rateOfTurn() {
return Optional.absent();
}
@Override
public String toString() {
StringBuilder b = new StringBuilder();
b.append("Fix [mmsi=");
b.append(mmsi);
b.append(", lat=");
b.append(lat);
b.append(", lon=");
b.append(lon);
b.append(", time=");
b.append(DateTimeFormatter.ISO_DATE_TIME
.format(ZonedDateTime.ofInstant(Instant.ofEpochMilli(time), ZoneId.of("UTC"))));
b.append(", navigationalStatus=");
b.append(navigationalStatus.orNull());
b.append(", speedOverGroundKnots=");
b.append(speedOverGroundKnots.orNull());
b.append(", courseOverGroundDegrees=");
b.append(courseOverGroundDegrees.orNull());
b.append(", headingDegrees=");
b.append(headingDegrees.orNull());
b.append(", aisClass=");
b.append(aisClass);
b.append(", latencySeconds=");
b.append(latencySeconds.orNull());
b.append(", source=");
b.append(source.orNull());
b.append("]");
return b.toString();
}
@Override
public Fix fix() {
return this;
}
}