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

org.vesalainen.nmea.processor.Tracker Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (C) 2015 tkv
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see .
 */
package org.vesalainen.nmea.processor;

import org.vesalainen.nmea.util.AbstractSampleConsumer;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.math.BigDecimal;
import java.time.Instant;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.stream.Stream;
import org.vesalainen.nmea.jaxb.router.TrackerType;
import org.vesalainen.nmea.util.NMEAFilters;
import org.vesalainen.nmea.util.NMEASample;
import org.vesalainen.nmea.util.TrackOutput;
import org.vesalainen.parsers.nmea.NMEAService;

/**
 * @author tkv
 */
public class Tracker extends AbstractSampleConsumer implements AutoCloseable
{
    private static final long SecondInMillis = 1000;
    private static final long MinuteInMillis = 60*SecondInMillis;
    private static final long HourInMillis = 60*MinuteInMillis;
    private static final long DayInMillis = 24*HourInMillis;
    private static final String[] Prefixes = new String[]{
        "latitude",
        "longitude"
            };
    private long nextDayMillis;
    private double bearingTolerance = 3;
    private double minDistance = 0.1;
    private float maxSpeedAcceleration = 1;
    private long maxPassive = TimeUnit.MINUTES.toMillis(15);
    private boolean buffered;
    private File directory;
    private final TrackOutput track;
    private int count;
    private Timer timer;
    private WatchDog closer;
    private boolean active;
    /**
     * This is for testing
     * @param out
     * @throws IOException 
     */
    Tracker(String dirStr) throws IOException
    {
        super(Tracker.class);
        this.directory = new File(dirStr);
        track = new TrackOutput(directory)
                .setBuffered(buffered);
    }

    public Tracker(TrackerType trackerType) throws FileNotFoundException, IOException
    {
        super(Tracker.class);
        Long bt = trackerType.getBearingTolerance();
        if (bt != null)
        {
            bearingTolerance = bt;
        }
        BigDecimal md = trackerType.getMinDistance();
        if (md != null)
        {
            minDistance = md.doubleValue();
        }
        BigDecimal ms = trackerType.getMaxSpeedAcceleration();
        if (ms != null)
        {
            maxSpeedAcceleration = ms.floatValue();
        }
        Long mp = trackerType.getMaxPassive();
        if (mp != null)
        {
            maxPassive = mp.longValue();
        }
        Boolean isBuffered = trackerType.isBuffered();
        if (isBuffered != null)
        {
            buffered = isBuffered;
        }
        this.directory = new File(trackerType.getDirectory());
        track = new TrackOutput(directory)
                .setBuffered(buffered);
    }
    
    @Override
    public String[] getProperties()
    {
        return Prefixes;
    }

    @Override
    public void init(Stream stream)
    {
        Stream accFilter = stream
                .filter(NMEAFilters.locationFilter(maxSpeedAcceleration))
                .filter(NMEAFilters.minDistanceFilter(minDistance));
        this.stream = NMEAFilters.bearingToleranceFilter(accFilter, bearingTolerance);
    }

    @Override
    public void start(NMEAService service)
    {
        super.start(service);
        closer = new WatchDog();
        timer = new Timer();
        timer.scheduleAtFixedRate(closer, maxPassive, maxPassive);
    }

    @Override
    public void stop()
    {
        timer.cancel();
        super.stop();
    }

    @Override
    protected void process(NMEASample sample)
    {
        output(sample.getTime(), sample.getProperty("latitude"), sample.getProperty("longitude"));
    }
    public void output(long time, float latitude, float longitude)
    {
        active = true;
        count++;
        try
        {
            if (nextDayMillis == 0)
            {
                ZonedDateTime zdt = ZonedDateTime.ofInstant(Instant.ofEpochMilli(time), ZoneOffset.UTC);
                nextDayMillis = time + DayInMillis - (
                        HourInMillis*zdt.getHour() +
                        MinuteInMillis*zdt.getMinute() +
                        SecondInMillis*zdt.getSecond()
                        );
            }
            else
            {
                if (nextDayMillis < time)
                {
                    track.close();
                    nextDayMillis = time + DayInMillis;
                }
            }
            track.output(time, latitude, longitude);
        }
        catch (IOException ex)
        {
            log(Level.SEVERE, ex, ex.getMessage());
        }
    }

    int getCount()
    {
        return count;
    }

    @Override
    public void close() throws Exception
    {
        if (track != null)
        {
            track.close();
            count = 0;
        }
    }

    private class WatchDog extends TimerTask
    {

        @Override
        public void run()
        {
            try
            {
                if (!active)
                {
                    close();
                }
                active = false;
            }
            catch (Exception ex)
            {
                log(Level.WARNING, ex, "timed close failed %s", ex.getMessage());
            }
        }
        
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy