org.emergya.backtrackTSP.DistanceMatrix.java Source code

Java tutorial

Introduction

Here is the source code for org.emergya.backtrackTSP.DistanceMatrix.java

Source

/**
 * Copyright (C) 2012, Emergya (http://www.emergya.es)
 * 
 * @author <a href="mailto:marias@emergya.com">Mara Arias de Reyna</a>
 * 
 *         This file is part of GoFleet
 * 
 *         This software 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 2 of the License, or (at
 *         your option) any later version.
 * 
 *         This software 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 library; if not, write to the Free Software
 *         Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 *         02110-1301 USA
 * 
 *         As a special exception, if you link this library with other files to
 *         produce an executable, this library does not by itself cause the
 *         resulting executable to be covered by the GNU General Public License.
 *         This exception does not however invalidate any other reasons why the
 *         executable file might be covered by the GNU General Public License.
 */
package org.emergya.backtrackTSP;

import java.io.IOException;
import java.text.ParseException;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.namespace.QName;

import net.opengis.gml.v_3_1_1.DirectPositionType;
import net.opengis.gml.v_3_1_1.PointType;
import net.opengis.xls.v_1_2_0.AbstractLocationType;
import net.opengis.xls.v_1_2_0.DetermineRouteRequestType;
import net.opengis.xls.v_1_2_0.DetermineRouteResponseType;
import net.opengis.xls.v_1_2_0.PositionType;
import net.opengis.xls.v_1_2_0.RoutePlanType;
import net.opengis.xls.v_1_2_0.WayPointListType;
import net.opengis.xls.v_1_2_0.WayPointType;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.emergya.osrm.OSRM;
import org.gofleet.openLS.tsp.TSPStop;

import com.vividsolutions.jts.geom.Point;

public class DistanceMatrix {

    private Map<Key, Double> distances = new HashMap<Key, Double>();
    private static Log LOG = LogFactory.getLog(DistanceMatrix.class);

    private OSRM osrm;
    private org.gofleet.configuration.Configuration configuration;

    public DistanceMatrix() {
        this.osrm = new OSRM();
    }

    public DistanceMatrix(OSRM osrm, org.gofleet.configuration.Configuration configuration) {
        super();
        this.osrm = osrm;
        this.configuration = configuration;
    }

    public Double distance(BacktrackStop from, BacktrackStop to) throws InterruptedException {
        Key k = new Key(from.id, to.id);
        Double d = null;
        synchronized (distances) {
            d = distances.get(k);
        }
        if (d != null) {
            return d;
        } else {
            if (LOG.isDebugEnabled())
                LOG.debug("DistanceMatrix.distance(" + k + ")");
            return calculateDistance(from, to, k);
        }
    }

    private Double calculateDistance(TSPStop from, TSPStop to, Key k) throws InterruptedException {
        String host_port = "localhost:5000";
        String http = "http";
        if (configuration != null) {
            if (configuration.get("OSRM_SSL", "off").equals("on"))
                http = "https";
            host_port = configuration.get("OSRM_HOST", "localhost:5000");
        }
        DetermineRouteRequestType param = new DetermineRouteRequestType();

        if (param.getRoutePlan() == null)
            param.setRoutePlan(new RoutePlanType());

        if (param.getRoutePlan().getWayPointList() == null)
            param.getRoutePlan().setWayPointList(new WayPointListType());

        WayPointListType waypointList = param.getRoutePlan().getWayPointList();

        WayPointType start = getWayPoint(from.getPosition());
        WayPointType end = getWayPoint(to.getPosition());

        waypointList.setStartPoint(start);
        waypointList.setEndPoint(end);

        try {
            DetermineRouteResponseType res = (DetermineRouteResponseType) osrm.routePlan(param, host_port, http,
                    Locale.ROOT);
            double cost = res.getRouteSummary().getTotalDistance().getValue().doubleValue();
            synchronized (distances) {
                distances.put(k, cost);
            }
            return cost;
        } catch (IOException e) {
            LOG.error("Error extracting distance from " + from + " to " + to);
            return Double.MAX_VALUE;
        } catch (ParseException e) {
            LOG.error("Error extracting distance from " + from + " to " + to);
            return Double.MAX_VALUE;
        } catch (JAXBException e) {
            LOG.error("Error extracting distance from " + from + " to " + to);
            return Double.MAX_VALUE;
        }
    }

    @SuppressWarnings("restriction")
    private WayPointType getWayPoint(Point position) {
        WayPointType point = new WayPointType();
        point.setStop(Boolean.TRUE);

        PositionType postype = new PositionType();
        PointType pointtype = new PointType();
        DirectPositionType directPosition = new DirectPositionType();

        directPosition.setSrsName("EPSG:" + position.getSRID());
        directPosition.getValue().add(position.getX());
        directPosition.getValue().add(position.getY());

        pointtype.setPos(directPosition);
        postype.setPoint(pointtype);
        JAXBElement<? extends AbstractLocationType> value = new JAXBElement<PositionType>(
                new QName("http://www.opengis.net/gml", "pos", "gml"), PositionType.class, postype);
        point.setLocation(value);

        return point;
    }

}

class Key {

    protected Key(Integer from, Integer to) {
        super();
        this.from = from;
        this.to = to;
    }

    private Integer from;
    private Integer to;

    public Integer getFrom() {
        return from;
    }

    public void setFrom(Integer from) {
        this.from = from;
    }

    public Integer getTo() {
        return to;
    }

    public void setTo(Integer to) {
        this.to = to;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((from == null) ? 0 : from.hashCode());
        result = prime * result + ((to == null) ? 0 : to.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (!(obj instanceof Key))
            return false;
        Key other = (Key) obj;
        return other.getFrom().equals(this.from) && other.getTo().equals(this.to);
    }

    @Override
    public String toString() {
        return "{ K<" + this.getFrom() + "->" + this.getTo() + ">}";
    }

}