All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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