org.muehleisen.hannes.taxiapp.TaxiRoute.java Source code

Java tutorial

Introduction

Here is the source code for org.muehleisen.hannes.taxiapp.TaxiRoute.java

Source

package org.muehleisen.hannes.taxiapp;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.zip.ZipInputStream;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.filefilter.SuffixFileFilter;
import org.apache.commons.io.filefilter.TrueFileFilter;
import org.apache.log4j.Logger;
import org.opentripplanner.routing.algorithm.EarliestArrivalSPTService;
import org.opentripplanner.routing.impl.GraphServiceImpl;
import org.opentripplanner.routing.impl.RetryingPathServiceImpl;
import org.opentripplanner.routing.services.PathService;
import org.opentripplanner.routing.spt.GraphPath;

import com.martiansoftware.jsap.FlaggedOption;
import com.martiansoftware.jsap.JSAP;
import com.martiansoftware.jsap.JSAPException;
import com.martiansoftware.jsap.JSAPResult;

// this reads trip data from http://www.andresmh.com/nyctaxitrips/
public class TaxiRoute extends Thread {

    private static Logger log = Logger.getLogger(TaxiRoute.class);

    private String graph;
    private String taxilog;
    private PathService ps = null;
    private long deliveries = 0;

    public TaxiRoute(String graph, String taxilog) {
        this.graph = graph;
        this.taxilog = taxilog;
    }

    @Override
    public void run() {
        log.info(this.getClass().getSimpleName() + " starting...");

        BlockingQueue<Runnable> taskQueue = new LinkedBlockingDeque<Runnable>(100);
        ExecutorService ex = new ThreadPoolExecutor(Runtime.getRuntime().availableProcessors(),
                Runtime.getRuntime().availableProcessors(), Integer.MAX_VALUE, TimeUnit.DAYS, taskQueue,
                new ThreadPoolExecutor.DiscardPolicy());
        // create rainbow table for driver lookup
        log.info("Creating driver license rainbow table.");
        RouteLogEntry.initLrt();

        // bring up routing service
        log.info("Bringing up OTP Graph Service from '" + graph + "'.");
        GraphServiceImpl graphService = new GraphServiceImpl();
        graphService.setPath(graph);
        graphService.startup();
        ps = new RetryingPathServiceImpl(graphService, new EarliestArrivalSPTService());

        // read taxi files
        log.info("Reading taxi files from '" + taxilog + "'.");
        Collection<File> files = FileUtils.listFiles(new File(taxilog), new SuffixFileFilter(".csv.zip"),
                TrueFileFilter.INSTANCE);
        for (File f : files) {
            log.info("Reading '" + f + "'.");
            try {
                ZipInputStream z = new ZipInputStream(new FileInputStream(f));
                z.getNextEntry(); // ZIP files have many entries. In this case,
                                  // only one
                BufferedReader r = new BufferedReader(new InputStreamReader(z));
                r.readLine(); // header
                String line = null;
                while ((line = r.readLine()) != null) {
                    RouteLogEntry rle = new RouteLogEntry(line);
                    if (!rle.hasGeo()) {
                        continue;
                    }
                    while (taskQueue.remainingCapacity() < 1) {
                        Thread.sleep(100);
                    }
                    ex.submit(new RouteTask(rle));
                }
                r.close();
                z.close();
            } catch (Exception e) {
                log.error("Failed to read taxi file from '" + taxilog + "'.", e);
            }
        }
        ex.shutdown();
        try {
            ex.awaitTermination(Integer.MAX_VALUE, TimeUnit.DAYS);
        } catch (InterruptedException e) {
            // ...
        }
        log.info(deliveries);
    }

    private class RouteTask implements Runnable {
        private RouteLogEntry rle = null;

        public RouteTask(RouteLogEntry rle) {
            this.rle = rle;
        }

        @Override
        public void run() {
            List<GraphPath> paths = ps.getPaths(rle.toRoutingRequest());
            if (paths.size() != 1) {
                return;
            }
            deliver(new RouteTaskResult(rle, paths.get(0)));
        }
    }

    private static class RouteTaskResult {
        private RouteLogEntry rle;
        private GraphPath gp;

        public RouteTaskResult(RouteLogEntry rle, GraphPath gp) {
            this.rle = rle;
            this.gp = gp;
        }

        public RouteLogEntry getRouteLogEntry() {
            return rle;
        }

        public GraphPath getGraphPath() {
            return gp;
        }
    }

    // command line argument handling
    public static void main(String[] args) throws JSAPException {
        JSAP jsap = new JSAP();

        jsap.registerParameter(new FlaggedOption("graph").setShortFlag('g').setLongFlag("graph")
                .setStringParser(JSAP.STRING_PARSER).setRequired(true).setHelp("OTP Graph"));

        jsap.registerParameter(new FlaggedOption("taxilog").setShortFlag('t').setLongFlag("taxilog")
                .setStringParser(JSAP.STRING_PARSER).setRequired(true).setHelp("NY Taxi Log"));

        JSAPResult res = jsap.parse(args);

        if (!res.success()) {
            @SuppressWarnings("rawtypes")
            Iterator errs = res.getErrorMessageIterator();
            while (errs.hasNext()) {
                System.err.println(errs.next());
            }
            System.err.println("Usage: " + jsap.getUsage() + "\nParameters: " + jsap.getHelp());
            System.exit(-1);
        }
        new TaxiRoute(res.getString("graph"), res.getString("taxilog")).start();
    }

    public synchronized void deliver(RouteTaskResult rtr) {
        System.out.println(rtr.getRouteLogEntry().getLicense() + "\t"
                + rtr.getRouteLogEntry().getTripDistanceMeters() + "\t"
                + rtr.getRouteLogEntry().getDistanceCrowfliesMeters() + "\t"
                + rtr.getRouteLogEntry().getPickupWeekday() + "\t" + rtr.getRouteLogEntry().getPickupHourOfDay()
                + "\t" + rtr.getRouteLogEntry().getTripTimeInSecs() + "\t" + rtr.getGraphPath().getDuration()
        // + "\t" + rtr.getDistanceRouteMeters()
        );
        deliveries++;
    }
}