/* Copyright (c) 2011 Danish Maritime Authority.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dk.dma.ais.lib;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.PrintWriter;
import java.nio.file.Paths;
import java.util.Date;
import java.util.List;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.concurrent.atomic.AtomicInteger;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.beust.jcommander.Parameter;
import com.google.inject.Injector;
import dk.dma.ais.packet.AisPacket;
import dk.dma.ais.packet.AisPacketFilters;
import java.util.function.Predicate;
/**
* @author Jens Tuxen
*
*/
public final class AisGapsToCSV extends AbstractCommandLineDirectoryReader {
/** The logger. */
static final Logger LOG = LoggerFactory.getLogger(AisGapsToCSV.class);
@Parameter(names = "-start", description = "Start date (inclusive), format == yyyy-MM-ddZ")
private volatile Date start;
@Parameter(names = "-stop", description = "Stop date (exclusive), format == yyyy-MM-ddZ")
private volatile Date stop;
@Parameter(names = "-output")
private String output = ".";
@Parameter(names = "-filename", required = false, description = "output file path")
private String filename = new Date().toLocaleString() + "_GAP.csv";
@Parameter(names = "-sourceFilters", required = false, description = "List of sources to inspect")
private List<String> sourceFilters;
private PrintWriter fos;
private ConcurrentSkipListMap<Integer, Boolean> seconds = new ConcurrentSkipListMap<Integer, Boolean>();
private Predicate<AisPacket> sourceFiltersPredicate;
/**
* start time of first processed packet
*/
Long startTime;
public Long getStartTime() {
if (startTime == null) {
startTime = System.currentTimeMillis();
}
return startTime;
}
private final AtomicInteger count = new AtomicInteger();
/*
* (non-Javadoc)
*
* @see
* dk.dma.ais.lib.AbstractCommandLineDirectoryReader#run(com.google.inject
* .Injector)
*/
@Override
protected void run(Injector injector) throws Exception {
Integer startTime = (int) (start.getTime() / 1000);
Integer stopTime = (int) (stop.getTime() / 1000);
fos = new PrintWriter(new BufferedWriter(new FileWriter(Paths.get(
output, filename).toFile())));
// initialize a very big collection of seconds
LOG.debug("Initializing HashMap");
for (int i = startTime; i < stopTime; i++) {
seconds.put(i, false);
}
LOG.debug("Initialized HashMap");
if (sourceFilters != null) {
sourceFiltersPredicate = AisPacketFilters
.filterOnSourceId(sourceFilters.toArray(new String[0]));
}
// start the reading (blocks until done)
LOG.debug("Starting Directory Reader");
super.run(injector);
LOG.debug("Writing CSV file");
for (Entry<Integer, Boolean> entry : seconds.entrySet()) {
fos.write(entry.getKey().toString() + ","
+ entry.getValue().toString() + "\n");
}
}
/**
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
new AisGapsToCSV().execute(args);
}
@Override
public void accept(final AisPacket t) {
Integer totalPackets = count.incrementAndGet();
if (totalPackets % 100000 == 0) {
Long start = getStartTime();
Long ms = System.currentTimeMillis() - start;
LOG.debug("Total Packets: "+totalPackets+" "+(totalPackets / ((double)ms / 1000))+ " packets/s");
}
final long timestamp = t.getBestTimestamp() / 1000;
if (t != null && timestamp > 0) {
if (sourceFiltersPredicate != null && !sourceFiltersPredicate.test(t)) {
return;
}
seconds.remove((int) timestamp);
}
}
}