au.gov.amsa.risky.format.Downsample Maven / Gradle / Ivy
package au.gov.amsa.risky.format;
import java.io.File;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;
import com.github.davidmoten.rx.Functions;
import rx.Observable;
import rx.Observable.Transformer;
import rx.functions.Action2;
import rx.functions.Func1;
/**
* Assumes input stream is in time order.
*/
public class Downsample implements Transformer {
private final long minTimeBetweenFixesMs;
private final Func1 selector;
public Downsample(long minTimeBetweenFixesMs, Func1 selector) {
this.minTimeBetweenFixesMs = minTimeBetweenFixesMs;
this.selector = selector;
}
public static Downsample minTimeStep(long duration, TimeUnit unit) {
return new Downsample(unit.toMillis(duration), Functions. alwaysFalse());
}
public static Downsample minTimeStep(long duration, TimeUnit unit,
Func1 selector) {
return new Downsample(unit.toMillis(duration), selector);
}
@Override
public Observable call(Observable fixes) {
Observable result = fixes.scan((latest, fix) -> {
if (fix.fix().mmsi() != latest.fix().mmsi())
throw new RuntimeException("can only downsample a single vessel");
else if (fix.fix().time() < latest.fix().time())
throw new RuntimeException("not in ascending time order!");
else if (fix.fix().time() - latest.fix().time() >= minTimeBetweenFixesMs
|| selector.call(fix))
return fix;
else
return latest;
});
if (minTimeBetweenFixesMs > 0)
// throw away repeats
result = result.distinctUntilChanged(f -> f.fix().time());
return result;
}
public static Observable downsample(final File input, final File output,
Pattern pattern, final long duration, final TimeUnit unit) {
return Formats.transform(input, output, pattern, Downsample.minTimeStep(duration, unit),
FIXES_WRITER_WITHOUT_MMSI, Functions. identity());
}
private static Action2, File> FIXES_WRITER_WITHOUT_MMSI = (list, file) -> {
BinaryFixesWriter.writeFixes(list, file, false, false, BinaryFixesFormat.WITHOUT_MMSI);
};
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy