rudimentary connections for all efa based providers

git-svn-id: https://public-transport-enabler.googlecode.com/svn/trunk@246 0924bc21-9374-b0fa-ee44-9ff1593b38f0
This commit is contained in:
andreas.schildbach 2010-10-08 17:43:57 +00:00
parent b4bf75d875
commit 875bd1d651
15 changed files with 725 additions and 193 deletions

View file

@ -22,8 +22,10 @@ import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
@ -33,10 +35,14 @@ import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
import de.schildbach.pte.dto.Autocomplete;
import de.schildbach.pte.dto.Connection;
import de.schildbach.pte.dto.Departure;
import de.schildbach.pte.dto.GetConnectionDetailsResult;
import de.schildbach.pte.dto.NearbyStationsResult;
import de.schildbach.pte.dto.QueryConnectionsResult;
import de.schildbach.pte.dto.QueryDeparturesResult;
import de.schildbach.pte.dto.Station;
import de.schildbach.pte.dto.QueryConnectionsResult.Status;
import de.schildbach.pte.util.Color;
import de.schildbach.pte.util.ParserUtils;
import de.schildbach.pte.util.XmlPullUtil;
@ -69,17 +75,7 @@ public abstract class AbstractEfaProvider implements NetworkProvider
XmlPullUtil.nextStartTagInsideTree(pp, null, "itdOdvName");
final String nameState = pp.getAttributeValue(null, "state");
if ("list".equals(nameState))
{
while (XmlPullUtil.nextStartTagInsideTree(pp, null, "odvNameElem"))
{
final String type = pp.getAttributeValue(null, "anyType");
int id = Integer.parseInt(pp.getAttributeValue(null, "id"));
if (id < 0)
id = 0;
final String name = normalizeLocationName(pp.nextText());
results.add(new Autocomplete(type(type), id, name));
}
}
processOdvNameElem(results, pp);
// parse assigned stops
if (XmlPullUtil.jumpToStartTag(pp, null, "itdOdvAssignedStops"))
@ -105,16 +101,33 @@ public abstract class AbstractEfaProvider implements NetworkProvider
}
}
private void processOdvNameElem(final List<Autocomplete> results, final XmlPullParser pp) throws XmlPullParserException, IOException
{
while (XmlPullUtil.nextStartTagInsideTree(pp, null, "odvNameElem"))
{
final String type = pp.getAttributeValue(null, "anyType");
int id = Integer.parseInt(pp.getAttributeValue(null, "id"));
if (id < 0)
id = 0;
final String name = normalizeLocationName(pp.nextText());
results.add(new Autocomplete(type(type), id, name));
}
}
private static LocationType type(final String type)
{
if (type.equals("stop"))
return LocationType.STATION;
if (type.equals("poi"))
return LocationType.POI;
if (type.equals("street"))
return LocationType.ADDRESS;
if (type.equals("loc"))
return LocationType.ANY;
if (type.equals("street"))
return LocationType.ADDRESS;
if (type.equals("singlehouse"))
return LocationType.ADDRESS;
if (type.equals("address"))
return LocationType.ADDRESS;
throw new IllegalArgumentException("unknown type: " + type);
}
@ -235,16 +248,16 @@ public abstract class AbstractEfaProvider implements NetworkProvider
private static final Pattern P_LINE_U = Pattern.compile("U\\d+");
private static final Pattern P_LINE_NUMBER = Pattern.compile("\\d+");
protected String parseLine(final String number, final String symbol, final String mot)
protected String parseLine(final String mot, final String name, final String longName)
{
if (!number.equals(symbol))
throw new IllegalStateException("number " + number + ", symbol " + symbol);
if (mot == null || name == null || longName == null)
throw new IllegalStateException("cannot normalize mot '" + mot + "' name '" + name + "' long '" + longName + "'");
final int t = Integer.parseInt(mot);
if (t == 0)
{
final String[] parts = number.split(" ", 3);
final String[] parts = longName.split(" ", 3);
final String type = parts[0];
final String num = parts.length >= 2 ? parts[1] : null;
final String str = type + (num != null ? num : "");
@ -451,24 +464,24 @@ public abstract class AbstractEfaProvider implements NetworkProvider
if (P_LINE_NUMBER.matcher(type).matches())
return "?";
throw new IllegalArgumentException("cannot normalize: " + number);
throw new IllegalArgumentException("cannot normalize: " + longName);
}
if (t == 1)
return 'S' + number;
return 'S' + name;
if (t == 2)
return 'U' + number;
return 'U' + name;
if (t == 3 || t == 4)
return 'T' + number;
return 'T' + name;
if (t == 5 || t == 6 || t == 7 || t == 10)
return 'B' + number;
return 'B' + name;
if (t == 8)
return 'C' + number;
return 'C' + name;
if (t == 9)
return 'F' + number;
return 'F' + name;
if (t == 11)
return '?' + number;
return '?' + name;
throw new IllegalStateException("cannot normalize mot '" + mot + "' number '" + number + "'");
throw new IllegalStateException("cannot normalize mot '" + mot + "' name '" + name + "' long '" + longName + "'");
}
public QueryDeparturesResult queryDepartures(final String uri) throws IOException
@ -512,25 +525,12 @@ public abstract class AbstractEfaProvider implements NetworkProvider
departureTime.clear();
if (!XmlPullUtil.nextStartTagInsideTree(pp, null, "itdDateTime"))
throw new IllegalStateException("itdDateTime not found:" + pp.getPositionDescription());
if (!XmlPullUtil.nextStartTagInsideTree(pp, null, "itdDate"))
throw new IllegalStateException("itdDate not found:" + pp.getPositionDescription());
processItdDate(pp, departureTime);
XmlPullUtil.skipRestOfTree(pp);
if (!XmlPullUtil.nextStartTagInsideTree(pp, null, "itdTime"))
throw new IllegalStateException("itdTime not found:" + pp.getPositionDescription());
processItdTime(pp, departureTime);
XmlPullUtil.skipRestOfTree(pp);
XmlPullUtil.skipRestOfTree(pp);
processItdDateTime(pp, departureTime);
if (!XmlPullUtil.nextStartTagInsideTree(pp, null, "itdServingLine"))
throw new IllegalStateException("itdServingLine not found:" + pp.getPositionDescription());
final String line = parseLine(pp.getAttributeValue(null, "number"), pp.getAttributeValue(null, "symbol"), pp
.getAttributeValue(null, "motType"));
final String line = parseLine(pp.getAttributeValue(null, "motType"), pp.getAttributeValue(null, "number"), pp
.getAttributeValue(null, "number"));
final boolean isRealtime = pp.getAttributeValue(null, "realtime").equals("1");
final String destination = normalizeLocationName(pp.getAttributeValue(null, "direction"));
final int destinationId = Integer.parseInt(pp.getAttributeValue(null, "destID"));
@ -564,6 +564,24 @@ public abstract class AbstractEfaProvider implements NetworkProvider
}
}
private void processItdDateTime(final XmlPullParser pp, final Calendar calendar) throws XmlPullParserException, IOException
{
if (!XmlPullUtil.nextStartTagInsideTree(pp, null, "itdDateTime"))
throw new IllegalStateException("itdDateTime not found:" + pp.getPositionDescription());
if (!XmlPullUtil.nextStartTagInsideTree(pp, null, "itdDate"))
throw new IllegalStateException("itdDate not found:" + pp.getPositionDescription());
processItdDate(pp, calendar);
XmlPullUtil.skipRestOfTree(pp);
if (!XmlPullUtil.nextStartTagInsideTree(pp, null, "itdTime"))
throw new IllegalStateException("itdTime not found:" + pp.getPositionDescription());
processItdTime(pp, calendar);
XmlPullUtil.skipRestOfTree(pp);
XmlPullUtil.skipRestOfTree(pp);
}
private void processItdDate(final XmlPullParser pp, final Calendar calendar) throws XmlPullParserException, IOException
{
pp.require(XmlPullParser.START_TAG, null, "itdDate");
@ -575,7 +593,7 @@ public abstract class AbstractEfaProvider implements NetworkProvider
private void processItdTime(final XmlPullParser pp, final Calendar calendar) throws XmlPullParserException, IOException
{
pp.require(XmlPullParser.START_TAG, null, "itdTime");
calendar.set(Calendar.HOUR, Integer.parseInt(pp.getAttributeValue(null, "hour")));
calendar.set(Calendar.HOUR_OF_DAY, Integer.parseInt(pp.getAttributeValue(null, "hour")));
calendar.set(Calendar.MINUTE, Integer.parseInt(pp.getAttributeValue(null, "minute")));
}
@ -591,7 +609,197 @@ public abstract class AbstractEfaProvider implements NetworkProvider
return (double) value / 1000000;
}
protected final String productParams(final String products)
public QueryConnectionsResult queryConnections(final LocationType fromType, final String from, final LocationType viaType, final String via,
final LocationType toType, final String to, final Date date, final boolean dep, final String products, final WalkSpeed walkSpeed)
throws IOException
{
final String uri = connectionsQueryUri(fromType, from, viaType, via, toType, to, date, dep, products, walkSpeed) + "&sessionID=0";
final CharSequence page = ParserUtils.scrape(uri);
return queryConnections(uri, page);
}
public QueryConnectionsResult queryMoreConnections(final String uri) throws IOException
{
final CharSequence page = ParserUtils.scrape(uri);
return queryConnections(uri, page);
}
private QueryConnectionsResult queryConnections(final String uri, final CharSequence page) throws IOException
{
try
{
final XmlPullParserFactory factory = XmlPullParserFactory.newInstance(System.getProperty(XmlPullParserFactory.PROPERTY_NAME), null);
final XmlPullParser pp = factory.newPullParser();
pp.setInput(new StringReader(page.toString()));
XmlPullUtil.jumpToStartTag(pp, null, "itdRequest");
final String sessionId = pp.getAttributeValue(null, "sessionID");
// parse odv name elements
List<Autocomplete> ambiguousFrom = null, ambiguousTo = null, ambiguousVia = null;
String from = null, to = null;
XmlPullUtil.jumpToStartTag(pp, null, "itdOdv");
if (!"origin".equals(pp.getAttributeValue(null, "usage")))
throw new IllegalStateException();
XmlPullUtil.nextStartTagInsideTree(pp, null, "itdOdvName");
final String originState = pp.getAttributeValue(null, "state");
if ("list".equals(originState))
{
ambiguousFrom = new ArrayList<Autocomplete>();
processOdvNameElem(ambiguousFrom, pp);
}
else if ("identified".equals(originState))
{
XmlPullUtil.nextStartTagInsideTree(pp, null, "odvNameElem");
from = pp.nextText();
}
XmlPullUtil.jumpToStartTag(pp, null, "itdOdv");
if (!"destination".equals(pp.getAttributeValue(null, "usage")))
throw new IllegalStateException();
XmlPullUtil.nextStartTagInsideTree(pp, null, "itdOdvName");
final String destinationState = pp.getAttributeValue(null, "state");
if ("list".equals(destinationState))
{
ambiguousTo = new ArrayList<Autocomplete>();
processOdvNameElem(ambiguousTo, pp);
}
else if ("identified".equals(destinationState))
{
XmlPullUtil.nextStartTagInsideTree(pp, null, "odvNameElem");
to = pp.nextText();
}
XmlPullUtil.jumpToStartTag(pp, null, "itdOdv");
if (!"via".equals(pp.getAttributeValue(null, "usage")))
throw new IllegalStateException();
XmlPullUtil.nextStartTagInsideTree(pp, null, "itdOdvName");
final String viaState = pp.getAttributeValue(null, "state");
if ("list".equals(viaState))
{
ambiguousVia = new ArrayList<Autocomplete>();
processOdvNameElem(ambiguousVia, pp);
}
else if ("identified".equals(viaState))
{
// TODO parse identified name/id
}
if (ambiguousFrom != null || ambiguousTo != null || ambiguousVia != null)
return new QueryConnectionsResult(ambiguousFrom, ambiguousVia, ambiguousTo);
final Calendar departureTime = new GregorianCalendar(), arrivalTime = new GregorianCalendar();
final List<Connection> connections = new ArrayList<Connection>();
if (XmlPullUtil.jumpToStartTag(pp, null, "itdRouteList"))
{
while (XmlPullUtil.nextStartTagInsideTree(pp, null, "itdRoute"))
{
final String id = pp.getAttributeValue(null, "routeIndex") + "-" + pp.getAttributeValue(null, "routeTripIndex");
XmlPullUtil.jumpToStartTag(pp, null, "itdPartialRouteList");
final List<Connection.Part> parts = new LinkedList<Connection.Part>();
String firstDeparture = null;
Date firstDepartureTime = null;
String lastArrival = null;
Date lastArrivalTime = null;
while (XmlPullUtil.nextStartTagInsideTree(pp, null, "itdPartialRoute"))
{
XmlPullUtil.jumpToStartTag(pp, null, "itdPoint");
if (!"departure".equals(pp.getAttributeValue(null, "usage")))
throw new IllegalStateException();
final int departureId = Integer.parseInt(pp.getAttributeValue(null, "stopID"));
final String departure = normalizeLocationName(pp.getAttributeValue(null, "name"));
if (firstDeparture == null)
firstDeparture = departure;
final String departurePosition = pp.getAttributeValue(null, "platform");
processItdDateTime(pp, departureTime);
if (firstDepartureTime == null)
firstDepartureTime = departureTime.getTime();
XmlPullUtil.skipRestOfTree(pp);
XmlPullUtil.jumpToStartTag(pp, null, "itdPoint");
if (!"arrival".equals(pp.getAttributeValue(null, "usage")))
throw new IllegalStateException();
final int arrivalId = Integer.parseInt(pp.getAttributeValue(null, "stopID"));
final String arrival = normalizeLocationName(pp.getAttributeValue(null, "name"));
lastArrival = arrival;
final String arrivalPosition = pp.getAttributeValue(null, "platform");
processItdDateTime(pp, arrivalTime);
lastArrivalTime = arrivalTime.getTime();
XmlPullUtil.skipRestOfTree(pp);
XmlPullUtil.jumpToStartTag(pp, null, "itdMeansOfTransport");
Connection.Part part;
if (!"Fussweg".equals(pp.getAttributeValue(null, "productName")))
{
final String destinationIdStr = pp.getAttributeValue(null, "destID");
final int destinationId = destinationIdStr.length() > 0 ? Integer.parseInt(destinationIdStr) : 0;
final String destination = normalizeLocationName(pp.getAttributeValue(null, "destination"));
final String line = parseLine(pp.getAttributeValue(null, "motType"), pp.getAttributeValue(null, "shortname"), pp
.getAttributeValue(null, "name"));
part = new Connection.Trip(line, LINES.get(line.charAt(0)), destinationId, destination, departureTime.getTime(),
departurePosition, departureId, departure, arrivalTime.getTime(), arrivalPosition, arrivalId, arrival);
}
else
{
final int min = (int) (arrivalTime.getTimeInMillis() - departureTime.getTimeInMillis()) / 1000 / 60;
part = new Connection.Footway(min, departureId, departurePosition, arrivalId, arrivalPosition);
}
XmlPullUtil.skipRestOfTree(pp);
parts.add(part);
XmlPullUtil.skipRestOfTree(pp);
}
connections
.add(new Connection(id, uri, firstDepartureTime, lastArrivalTime, null, null, 0, firstDeparture, 0, lastArrival, parts));
XmlPullUtil.skipRestOfTree(pp);
}
return new QueryConnectionsResult(uri, from, to, null, commandLink(sessionId, "tripPrev"), commandLink(sessionId, "tripNext"),
connections);
}
else
{
return new QueryConnectionsResult(Status.NO_CONNECTIONS);
}
}
catch (final XmlPullParserException x)
{
throw new RuntimeException(x);
}
}
public GetConnectionDetailsResult getConnectionDetails(final String connectionUri) throws IOException
{
throw new UnsupportedOperationException();
}
protected abstract String connectionsQueryUri(LocationType fromType, String from, LocationType viaType, String via, LocationType toType,
String to, Date date, boolean dep, String products, WalkSpeed walkSpeed);
protected abstract String commandLink(String sessionId, String command);
protected static final String locationTypeValue(final LocationType locationType)
{
if (locationType == LocationType.STATION)
return "stop";
if (locationType == LocationType.ADDRESS)
return "any"; // strange, matches with anyObjFilter
if (locationType == LocationType.POI)
return "any";
if (locationType == LocationType.ANY)
return "any";
throw new IllegalArgumentException(locationType.toString());
}
protected static final String productParams(final String products)
{
if (products == null)
return "";
@ -620,6 +828,15 @@ public abstract class AbstractEfaProvider implements NetworkProvider
return params.toString();
}
protected static final Map<WalkSpeed, String> WALKSPEED_MAP = new HashMap<WalkSpeed, String>();
static
{
WALKSPEED_MAP.put(WalkSpeed.SLOW, "slow");
WALKSPEED_MAP.put(WalkSpeed.NORMAL, "normal");
WALKSPEED_MAP.put(WalkSpeed.FAST, "fast");
}
private static final Map<Character, int[]> LINES = new HashMap<Character, int[]>();
static

View file

@ -187,9 +187,9 @@ public final class BahnProvider implements NetworkProvider
return QueryConnectionsResult.INVALID_DATE;
}
List<String> fromAddresses = null;
List<String> viaAddresses = null;
List<String> toAddresses = null;
List<Autocomplete> fromAddresses = null;
List<Autocomplete> viaAddresses = null;
List<Autocomplete> toAddresses = null;
final Matcher mPreAddress = P_PRE_ADDRESS.matcher(page);
while (mPreAddress.find())
@ -198,12 +198,12 @@ public final class BahnProvider implements NetworkProvider
final String options = mPreAddress.group(2);
final Matcher mAddresses = P_ADDRESSES.matcher(options);
final List<String> addresses = new ArrayList<String>();
final List<Autocomplete> addresses = new ArrayList<Autocomplete>();
while (mAddresses.find())
{
final String address = ParserUtils.resolveEntities(mAddresses.group(1)).trim();
if (!addresses.contains(address))
addresses.add(address);
addresses.add(new Autocomplete(LocationType.ANY, 0, address));
}
if (type.equals("REQ0JourneyStopsS0K"))
@ -217,7 +217,7 @@ public final class BahnProvider implements NetworkProvider
}
if (fromAddresses != null || viaAddresses != null || toAddresses != null)
return new QueryConnectionsResult(QueryConnectionsResult.Status.AMBIGUOUS, fromAddresses, viaAddresses, toAddresses);
return new QueryConnectionsResult(fromAddresses, viaAddresses, toAddresses);
else
return queryConnections(uri, page);
}
@ -371,7 +371,7 @@ public final class BahnProvider implements NetworkProvider
final Date departureDateTime = ParserUtils.joinDateTime(departureDate, departureTime);
final Date arrivalDateTime = ParserUtils.joinDateTime(arrivalDate, arrivalTime);
lastTrip = new Connection.Trip(line, line != null ? LINES.get(line.charAt(0)) : null, null, departureDateTime,
lastTrip = new Connection.Trip(line, line != null ? LINES.get(line.charAt(0)) : null, 0, null, departureDateTime,
departurePosition, 0, departure, arrivalDateTime, arrivalPosition, 0, arrival);
parts.add(lastTrip);

View file

@ -17,11 +17,10 @@
package de.schildbach.pte;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import de.schildbach.pte.dto.GetConnectionDetailsResult;
import de.schildbach.pte.dto.QueryConnectionsResult;
import de.schildbach.pte.util.ParserUtils;
/**
@ -35,7 +34,8 @@ public class GvhProvider extends AbstractEfaProvider
public boolean hasCapabilities(final Capability... capabilities)
{
for (final Capability capability : capabilities)
if (capability == Capability.DEPARTURES)
if (capability == Capability.DEPARTURES || capability == Capability.CONNECTIONS || capability == Capability.LOCATION_STATION_ID
|| capability == Capability.LOCATION_WGS84)
return true;
return false;
@ -77,19 +77,87 @@ public class GvhProvider extends AbstractEfaProvider
return uri.toString();
}
public QueryConnectionsResult queryConnections(LocationType fromType, String from, LocationType viaType, String via, LocationType toType,
String to, Date date, boolean dep, String products, WalkSpeed walkSpeed) throws IOException
@Override
protected String connectionsQueryUri(final LocationType fromType, final String from, final LocationType viaType, final String via,
final LocationType toType, final String to, final Date date, final boolean dep, final String products, final WalkSpeed walkSpeed)
{
throw new UnsupportedOperationException();
final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyyMMdd");
final DateFormat TIME_FORMAT = new SimpleDateFormat("HHmm");
final StringBuilder uri = new StringBuilder();
uri.append(API_BASE);
uri.append("XSLT_TRIP_REQUEST2");
uri.append("?language=de");
uri.append("&outputFormat=XML");
uri.append("&coordOutputFormat=WGS84");
if (fromType == LocationType.WGS84)
{
final String[] parts = from.split(",\\s*", 2);
final int lat = Integer.parseInt(parts[0]);
final int lon = Integer.parseInt(parts[1]);
uri.append("&nameInfo_origin=").append(String.format("%2.6f:%2.6f", lon / 1E6, lat / 1E6)).append(":WGS84[DD.dddddd]");
uri.append("&typeInfo_origin=coord");
}
else
{
uri.append("&type_origin=").append(locationTypeValue(fromType));
uri.append("&name_origin=").append(ParserUtils.urlEncode(from, "ISO-8859-1")); // fine-grained location
}
if (toType == LocationType.WGS84)
{
final String[] parts = to.split(",\\s*", 2);
final int lat = Integer.parseInt(parts[0]);
final int lon = Integer.parseInt(parts[1]);
uri.append("&nameInfo_destination=").append(String.format("%2.6f:%2.6f", lon / 1E6, lat / 1E6)).append(":WGS84[DD.dddddd]");
uri.append("&typeInfo_destination=coord");
}
else
{
uri.append("&type_destination=").append(locationTypeValue(toType));
uri.append("&name_destination=").append(ParserUtils.urlEncode(to, "ISO-8859-1")); // fine-grained location
}
if (via != null)
{
if (viaType == LocationType.WGS84)
{
final String[] parts = via.split(",\\s*", 2);
final int lat = Integer.parseInt(parts[0]);
final int lon = Integer.parseInt(parts[1]);
uri.append("&nameInfo_via=").append(String.format("%2.6f:%2.6f", lon / 1E6, lat / 1E6)).append(":WGS84[DD.dddddd]");
uri.append("&typeInfo_via=coord");
}
else
{
uri.append("&type_via=").append(locationTypeValue(viaType));
uri.append("&name_via=").append(ParserUtils.urlEncode(via, "ISO-8859-1"));
}
}
uri.append("&itdDate=").append(ParserUtils.urlEncode(DATE_FORMAT.format(date)));
uri.append("&itdTime=").append(ParserUtils.urlEncode(TIME_FORMAT.format(date)));
uri.append("&itdTripDateTimeDepArr=").append(dep ? "dep" : "arr");
// TODO products
uri.append("&changeSpeed=").append(WALKSPEED_MAP.get(walkSpeed));
uri.append("&locationServerActive=1");
return uri.toString();
}
public QueryConnectionsResult queryMoreConnections(String uri) throws IOException
@Override
protected String commandLink(final String sessionId, final String command)
{
throw new UnsupportedOperationException();
}
public GetConnectionDetailsResult getConnectionDetails(String connectionUri) throws IOException
{
throw new UnsupportedOperationException();
final StringBuilder uri = new StringBuilder();
uri.append(API_BASE);
uri.append("XSLT_TRIP_REQUEST2");
uri.append("?sessionID=").append(sessionId);
uri.append("&command=").append(command);
return uri.toString();
}
}

View file

@ -17,11 +17,10 @@
package de.schildbach.pte;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import de.schildbach.pte.dto.GetConnectionDetailsResult;
import de.schildbach.pte.dto.QueryConnectionsResult;
import de.schildbach.pte.util.ParserUtils;
/**
@ -35,7 +34,8 @@ public class LinzProvider extends AbstractEfaProvider
public boolean hasCapabilities(final Capability... capabilities)
{
for (final Capability capability : capabilities)
if (capability == Capability.DEPARTURES)
if (capability == Capability.DEPARTURES || capability == Capability.CONNECTIONS || capability == Capability.LOCATION_STATION_ID
|| capability == Capability.LOCATION_WGS84)
return true;
return false;
@ -69,21 +69,92 @@ public class LinzProvider extends AbstractEfaProvider
return String.format(NEARBY_STATION_URI, stationId);
}
public QueryConnectionsResult queryConnections(final LocationType fromType, final String from, final LocationType viaType, final String via,
@Override
protected String connectionsQueryUri(final LocationType fromType, final String from, final LocationType viaType, final String via,
final LocationType toType, final String to, final Date date, final boolean dep, final String products, final WalkSpeed walkSpeed)
throws IOException
{
throw new UnsupportedOperationException();
final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyyMMdd");
final DateFormat TIME_FORMAT = new SimpleDateFormat("HHmm");
final StringBuilder uri = new StringBuilder();
uri.append(API_BASE);
uri.append("XSLT_TRIP_REQUEST2");
uri.append("?language=de");
uri.append("&outputFormat=XML");
uri.append("&coordOutputFormat=WGS84");
if (fromType == LocationType.WGS84)
{
final String[] parts = from.split(",\\s*", 2);
final int lat = Integer.parseInt(parts[0]);
final int lon = Integer.parseInt(parts[1]);
uri.append("&nameInfo_origin=").append(String.format("%2.6f:%2.6f", lon / 1E6, lat / 1E6)).append(":WGS84[DD.dddddd]");
uri.append("&typeInfo_origin=coord");
}
else
{
uri.append("&place_origin="); // coarse-grained location, e.g. city
uri.append("&placeState_origin=empty"); // empty|identified
uri.append("&type_origin=").append(locationTypeValue(fromType));
uri.append("&name_origin=").append(ParserUtils.urlEncode(from, "ISO-8859-1")); // fine-grained location
}
if (toType == LocationType.WGS84)
{
final String[] parts = to.split(",\\s*", 2);
final int lat = Integer.parseInt(parts[0]);
final int lon = Integer.parseInt(parts[1]);
uri.append("&nameInfo_destination=").append(String.format("%2.6f:%2.6f", lon / 1E6, lat / 1E6)).append(":WGS84[DD.dddddd]");
uri.append("&typeInfo_destination=coord");
}
else
{
uri.append("&place_destination="); // coarse-grained location, e.g. city
uri.append("&placeState_destination=empty"); // empty|identified
uri.append("&type_destination=").append(locationTypeValue(toType));
uri.append("&name_destination=").append(ParserUtils.urlEncode(to, "ISO-8859-1")); // fine-grained location
}
if (via != null)
{
if (viaType == LocationType.WGS84)
{
final String[] parts = via.split(",\\s*", 2);
final int lat = Integer.parseInt(parts[0]);
final int lon = Integer.parseInt(parts[1]);
uri.append("&nameInfo_via=").append(String.format("%2.6f:%2.6f", lon / 1E6, lat / 1E6)).append(":WGS84[DD.dddddd]");
uri.append("&typeInfo_via=coord");
}
else
{
uri.append("&place_via=");
uri.append("&placeState_via=empty");
uri.append("&type_via=").append(locationTypeValue(viaType));
uri.append("&name_via=").append(ParserUtils.urlEncode(via, "ISO-8859-1"));
}
}
uri.append("&itdDate=").append(ParserUtils.urlEncode(DATE_FORMAT.format(date)));
uri.append("&itdTime=").append(ParserUtils.urlEncode(TIME_FORMAT.format(date)));
uri.append("&itdTripDateTimeDepArr=").append(dep ? "dep" : "arr");
// TODO products
uri.append("&changeSpeed=").append(WALKSPEED_MAP.get(walkSpeed));
return uri.toString();
}
public QueryConnectionsResult queryMoreConnections(final String uri) throws IOException
@Override
protected String commandLink(final String sessionId, final String command)
{
throw new UnsupportedOperationException();
}
public GetConnectionDetailsResult getConnectionDetails(final String connectionUri) throws IOException
{
throw new UnsupportedOperationException();
final StringBuilder uri = new StringBuilder();
uri.append(API_BASE);
uri.append("XSLT_TRIP_REQUEST2");
uri.append("?sessionID=").append(sessionId);
uri.append("&command=").append(command);
return uri.toString();
}
public String departuresQueryUri(final String stationId, final int maxDepartures)

View file

@ -174,15 +174,8 @@ public class MvvProvider extends AbstractEfaProvider
return new NearbyStationsResult(uri, stations.subList(0, maxStations));
}
private static final Map<WalkSpeed, String> WALKSPEED_MAP = new HashMap<WalkSpeed, String>();
static
{
WALKSPEED_MAP.put(WalkSpeed.SLOW, "slow");
WALKSPEED_MAP.put(WalkSpeed.NORMAL, "normal");
WALKSPEED_MAP.put(WalkSpeed.FAST, "fast");
}
private String connectionsQueryUri(final LocationType fromType, final String from, final LocationType viaType, final String via,
@Override
protected String connectionsQueryUri(final LocationType fromType, final String from, final LocationType viaType, final String via,
final LocationType toType, final String to, final Date date, final boolean dep, final String products, final WalkSpeed walkSpeed)
{
final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyyMMdd");
@ -221,7 +214,7 @@ public class MvvProvider extends AbstractEfaProvider
final String[] parts = from.split(",\\s*", 2);
final int lat = Integer.parseInt(parts[0]);
final int lon = Integer.parseInt(parts[1]);
uri.append("&nameInfo_origin=").append(String.format("%2.5f:%2.5f", lon / 1E6, lat / 1E6)).append(":WGS84[DD.ddddd]");
uri.append("&nameInfo_origin=").append(String.format("%2.6f:%2.6f", lon / 1E6, lat / 1E6)).append(":WGS84[DD.dddddd]");
uri.append("&typeInfo_origin=coord");
}
else
@ -246,7 +239,7 @@ public class MvvProvider extends AbstractEfaProvider
final String[] parts = to.split(",\\s*", 2);
final int lat = Integer.parseInt(parts[0]);
final int lon = Integer.parseInt(parts[1]);
uri.append("&nameInfo_destination=").append(String.format("%2.5f:%2.5f", lon / 1E6, lat / 1E6)).append(":WGS84[DD.ddddd]");
uri.append("&nameInfo_destination=").append(String.format("%2.6f:%2.6f", lon / 1E6, lat / 1E6)).append(":WGS84[DD.dddddd]");
uri.append("&typeInfo_destination=coord");
}
else
@ -273,7 +266,7 @@ public class MvvProvider extends AbstractEfaProvider
final String[] parts = via.split(",\\s*", 2);
final int lat = Integer.parseInt(parts[0]);
final int lon = Integer.parseInt(parts[1]);
uri.append("&nameInfo_via=").append(String.format("%2.5f:%2.5f", lon / 1E6, lat / 1E6)).append(":WGS84[DD.ddddd]");
uri.append("&nameInfo_via=").append(String.format("%2.6f:%2.6f", lon / 1E6, lat / 1E6)).append(":WGS84[DD.dddddd]");
uri.append("&typeInfo_via=coord");
}
else
@ -336,8 +329,9 @@ public class MvvProvider extends AbstractEfaProvider
private static final Pattern P_CHECK_CONNECTIONS_ERROR = Pattern.compile(
"(Start und Ziel sind identisch)|(konnte keine Verbindung gefunden werden)", Pattern.CASE_INSENSITIVE);
@Override
public QueryConnectionsResult queryConnections(final LocationType fromType, final String from, final LocationType viaType, final String via,
final LocationType toType, final String to, final Date date, final boolean dep, String products, final WalkSpeed walkSpeed)
final LocationType toType, final String to, final Date date, final boolean dep, final String products, final WalkSpeed walkSpeed)
throws IOException
{
final String uri = connectionsQueryUri(fromType, from, viaType, via, toType, to, date, dep, products, walkSpeed);
@ -353,9 +347,9 @@ public class MvvProvider extends AbstractEfaProvider
return QueryConnectionsResult.NO_CONNECTIONS;
}
List<String> fromAddresses = null;
List<String> viaAddresses = null;
List<String> toAddresses = null;
List<Autocomplete> fromAddresses = null;
List<Autocomplete> viaAddresses = null;
List<Autocomplete> toAddresses = null;
final Matcher mPreAddress = P_PRE_ADDRESS.matcher(page);
while (mPreAddress.find())
@ -364,12 +358,12 @@ public class MvvProvider extends AbstractEfaProvider
final String options = mPreAddress.group(2);
final Matcher mAddresses = P_ADDRESSES.matcher(options);
final List<String> addresses = new ArrayList<String>();
final List<Autocomplete> addresses = new ArrayList<Autocomplete>();
while (mAddresses.find())
{
final String address = ParserUtils.resolveEntities(mAddresses.group(1)).trim();
if (!addresses.contains(address))
addresses.add(address);
addresses.add(new Autocomplete(LocationType.ANY, 0, address));
}
if (type.equals("name_origin"))
@ -383,11 +377,12 @@ public class MvvProvider extends AbstractEfaProvider
}
if (fromAddresses != null || viaAddresses != null || toAddresses != null)
return new QueryConnectionsResult(QueryConnectionsResult.Status.AMBIGUOUS, fromAddresses, viaAddresses, toAddresses);
return new QueryConnectionsResult(fromAddresses, viaAddresses, toAddresses);
else
return queryConnections(uri, page);
}
@Override
public QueryConnectionsResult queryMoreConnections(final String uri) throws IOException
{
final CharSequence page = ParserUtils.scrape(uri);
@ -501,6 +496,7 @@ public class MvvProvider extends AbstractEfaProvider
+ ").*?", Pattern.DOTALL);
private static final Pattern P_CONNECTION_DETAILS_ERRORS = Pattern.compile("(session has expired)", Pattern.CASE_INSENSITIVE);
@Override
public GetConnectionDetailsResult getConnectionDetails(final String uri) throws IOException
{
final CharSequence page = ParserUtils.scrape(uri);
@ -552,7 +548,7 @@ public class MvvProvider extends AbstractEfaProvider
final String normalizedLine = normalizeLine(product, line);
parts.add(new Connection.Trip(normalizedLine, LINES.get(normalizedLine), destination, departureTime, null, 0, departure,
parts.add(new Connection.Trip(normalizedLine, LINES.get(normalizedLine), 0, destination, departureTime, null, 0, departure,
arrivalTime, null, 0, arrival));
if (firstDepartureTime == null)
@ -620,6 +616,12 @@ public class MvvProvider extends AbstractEfaProvider
return time;
}
@Override
protected String commandLink(final String sessionId, final String command)
{
return null;
}
public String departuresQueryUri(final String stationId, final int maxDepartures)
{
final StringBuilder uri = new StringBuilder();

View file

@ -247,9 +247,9 @@ public class OebbProvider extends AbstractHafasProvider
throw new SessionExpiredException();
}
List<String> fromAddresses = null;
List<String> viaAddresses = null;
List<String> toAddresses = null;
List<Autocomplete> fromAddresses = null;
List<Autocomplete> viaAddresses = null;
List<Autocomplete> toAddresses = null;
final Matcher mPreAddress = P_PRE_ADDRESS.matcher(page);
while (mPreAddress.find())
@ -258,12 +258,12 @@ public class OebbProvider extends AbstractHafasProvider
final String options = mPreAddress.group(2);
final Matcher mAddresses = P_ADDRESSES.matcher(options);
final List<String> addresses = new ArrayList<String>();
final List<Autocomplete> addresses = new ArrayList<Autocomplete>();
while (mAddresses.find())
{
final String address = ParserUtils.resolveEntities(mAddresses.group(1)).trim();
if (!addresses.contains(address))
addresses.add(address);
addresses.add(new Autocomplete(LocationType.ANY, 0, address));
}
if (type.equals("REQ0JourneyStopsS0K"))
@ -277,7 +277,7 @@ public class OebbProvider extends AbstractHafasProvider
}
if (fromAddresses != null || viaAddresses != null || toAddresses != null)
return new QueryConnectionsResult(QueryConnectionsResult.Status.AMBIGUOUS, fromAddresses, viaAddresses, toAddresses);
return new QueryConnectionsResult(fromAddresses, viaAddresses, toAddresses);
else
return queryConnections(baseUri, page);
}
@ -439,7 +439,7 @@ public class OebbProvider extends AbstractHafasProvider
final String arrivalPosition = mDetFine.group(12) != null ? ParserUtils.resolveEntities(mDetFine.group(12)) : null;
final Connection.Trip trip = new Connection.Trip(line, lineColors(line), null, detailsDepartureDateTime,
final Connection.Trip trip = new Connection.Trip(line, lineColors(line), 0, null, detailsDepartureDateTime,
departurePosition, departureId, departure, detailsArrivalDateTime, arrivalPosition, arrivalId, arrival);
connection.parts.add(trip);
}

View file

@ -186,9 +186,9 @@ public class RmvProvider extends AbstractHafasProvider
return QueryConnectionsResult.INVALID_DATE;
}
List<String> fromAddresses = null;
List<String> viaAddresses = null;
List<String> toAddresses = null;
List<Autocomplete> fromAddresses = null;
List<Autocomplete> viaAddresses = null;
List<Autocomplete> toAddresses = null;
final Matcher mPreAddress = P_PRE_ADDRESS.matcher(page);
while (mPreAddress.find())
@ -196,12 +196,12 @@ public class RmvProvider extends AbstractHafasProvider
final String type = mPreAddress.group(1);
final Matcher mAddresses = P_ADDRESSES.matcher(page);
final List<String> addresses = new ArrayList<String>();
final List<Autocomplete> addresses = new ArrayList<Autocomplete>();
while (mAddresses.find())
{
final String address = ParserUtils.resolveEntities(mAddresses.group(1)).trim();
if (!addresses.contains(address))
addresses.add(address);
addresses.add(new Autocomplete(LocationType.ANY, 0, address));
}
if (type == null)
@ -215,7 +215,7 @@ public class RmvProvider extends AbstractHafasProvider
}
if (fromAddresses != null || viaAddresses != null || toAddresses != null)
return new QueryConnectionsResult(QueryConnectionsResult.Status.AMBIGUOUS, fromAddresses, viaAddresses, toAddresses);
return new QueryConnectionsResult(fromAddresses, viaAddresses, toAddresses);
else
return queryConnections(uri, page);
}
@ -362,8 +362,8 @@ public class RmvProvider extends AbstractHafasProvider
final String arrivalPosition = ParserUtils.resolveEntities(mDetFine.group(6));
lastTrip = new Connection.Trip(line, line != null ? lineColors(line) : null, destination, departureTime, departurePosition,
0, departure, arrivalTime, arrivalPosition, 0, arrival);
lastTrip = new Connection.Trip(line, line != null ? lineColors(line) : null, 0, destination, departureTime,
departurePosition, 0, departure, arrivalTime, arrivalPosition, 0, arrival);
parts.add(lastTrip);
if (firstDepartureTime == null)

View file

@ -162,9 +162,9 @@ public class SbbProvider extends AbstractHafasProvider
return QueryConnectionsResult.INVALID_DATE;
}
List<String> fromAddresses = null;
List<String> viaAddresses = null;
List<String> toAddresses = null;
List<Autocomplete> fromAddresses = null;
List<Autocomplete> viaAddresses = null;
List<Autocomplete> toAddresses = null;
final Matcher mPreAddress = P_PRE_ADDRESS.matcher(page);
while (mPreAddress.find())
@ -173,12 +173,12 @@ public class SbbProvider extends AbstractHafasProvider
final String options = mPreAddress.group(2);
final Matcher mAddresses = P_ADDRESSES.matcher(options);
final List<String> addresses = new ArrayList<String>();
final List<Autocomplete> addresses = new ArrayList<Autocomplete>();
while (mAddresses.find())
{
final String address = ParserUtils.resolveEntities(mAddresses.group(1)).trim();
if (!addresses.contains(address))
addresses.add(address);
addresses.add(new Autocomplete(LocationType.ANY, 0, address));
}
if (type.equals("REQ0JourneyStopsS0K"))
@ -192,7 +192,7 @@ public class SbbProvider extends AbstractHafasProvider
}
if (fromAddresses != null || viaAddresses != null || toAddresses != null)
return new QueryConnectionsResult(QueryConnectionsResult.Status.AMBIGUOUS, fromAddresses, viaAddresses, toAddresses);
return new QueryConnectionsResult(fromAddresses, viaAddresses, toAddresses);
else
return queryConnections(uri, page);
}
@ -340,7 +340,7 @@ public class SbbProvider extends AbstractHafasProvider
final String arrivalPosition = mDetFine.group(13) != null ? ParserUtils.resolveEntities(mDetFine.group(13)) : null;
final Connection.Trip trip = new Connection.Trip(line, lineColors(line), null, departureTime, departurePosition,
final Connection.Trip trip = new Connection.Trip(line, lineColors(line), 0, null, departureTime, departurePosition,
departureId, departure, arrivalTime, arrivalPosition, arrivalId, arrival);
connection.parts.add(trip);
}

View file

@ -238,12 +238,12 @@ public final class VbbProvider implements NetworkProvider
final Matcher mAddress = P_CHECK_ADDRESS.matcher(page);
final List<String> addresses = new ArrayList<String>();
final List<Autocomplete> addresses = new ArrayList<Autocomplete>();
while (mAddress.find())
{
final String address = ParserUtils.resolveEntities(mAddress.group(1));
if (!addresses.contains(address))
addresses.add(address);
addresses.add(new Autocomplete(LocationType.ANY, 0, address));
}
if (addresses.isEmpty())
@ -253,13 +253,13 @@ public final class VbbProvider implements NetworkProvider
else if (P_CHECK_FROM.matcher(page).find())
{
if (P_CHECK_TO.matcher(page).find())
return new QueryConnectionsResult(QueryConnectionsResult.Status.AMBIGUOUS, null, addresses, null);
return new QueryConnectionsResult(null, addresses, null);
else
return new QueryConnectionsResult(QueryConnectionsResult.Status.AMBIGUOUS, null, null, addresses);
return new QueryConnectionsResult(null, null, addresses);
}
else
{
return new QueryConnectionsResult(QueryConnectionsResult.Status.AMBIGUOUS, addresses, null, null);
return new QueryConnectionsResult(addresses, null, null);
}
}
@ -418,7 +418,7 @@ public final class VbbProvider implements NetworkProvider
final String arrival = ParserUtils.resolveEntities(mDetFine.group(10));
parts.add(new Connection.Trip(line, line != null ? LINES.get(line) : null, destination, departureTime, departurePosition,
parts.add(new Connection.Trip(line, line != null ? LINES.get(line) : null, 0, destination, departureTime, departurePosition,
departureId, departure, arrivalTime, arrivalPosition, arrivalId, arrival));
if (firstDepartureTime == null)

View file

@ -16,11 +16,10 @@
*/
package de.schildbach.pte;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import de.schildbach.pte.dto.GetConnectionDetailsResult;
import de.schildbach.pte.dto.QueryConnectionsResult;
import de.schildbach.pte.util.ParserUtils;
/**
@ -34,7 +33,8 @@ public class VrnProvider extends AbstractEfaProvider
public boolean hasCapabilities(final Capability... capabilities)
{
for (final Capability capability : capabilities)
if (capability == Capability.DEPARTURES)
if (capability == Capability.DEPARTURES || capability == Capability.CONNECTIONS || capability == Capability.LOCATION_STATION_ID
|| capability == Capability.LOCATION_WGS84)
return true;
return false;
@ -77,19 +77,87 @@ public class VrnProvider extends AbstractEfaProvider
return uri.toString();
}
public QueryConnectionsResult queryConnections(LocationType fromType, String from, LocationType viaType, String via, LocationType toType,
String to, Date date, boolean dep, String products, WalkSpeed walkSpeed) throws IOException
@Override
protected String connectionsQueryUri(final LocationType fromType, final String from, final LocationType viaType, final String via,
final LocationType toType, final String to, final Date date, final boolean dep, final String products, final WalkSpeed walkSpeed)
{
throw new UnsupportedOperationException();
final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyyMMdd");
final DateFormat TIME_FORMAT = new SimpleDateFormat("HHmm");
final StringBuilder uri = new StringBuilder();
uri.append(API_BASE);
uri.append("XSLT_TRIP_REQUEST2");
uri.append("?language=de");
uri.append("&outputFormat=XML");
uri.append("&coordOutputFormat=WGS84");
if (fromType == LocationType.WGS84)
{
final String[] parts = from.split(",\\s*", 2);
final int lat = Integer.parseInt(parts[0]);
final int lon = Integer.parseInt(parts[1]);
uri.append("&nameInfo_origin=").append(String.format("%2.6f:%2.6f", lon / 1E6, lat / 1E6)).append(":WGS84[DD.dddddd]");
uri.append("&typeInfo_origin=coord");
}
else
{
uri.append("&type_origin=").append(locationTypeValue(fromType));
uri.append("&name_origin=").append(ParserUtils.urlEncode(from, "ISO-8859-1")); // fine-grained location
}
if (toType == LocationType.WGS84)
{
final String[] parts = to.split(",\\s*", 2);
final int lat = Integer.parseInt(parts[0]);
final int lon = Integer.parseInt(parts[1]);
uri.append("&nameInfo_destination=").append(String.format("%2.6f:%2.6f", lon / 1E6, lat / 1E6)).append(":WGS84[DD.dddddd]");
uri.append("&typeInfo_destination=coord");
}
else
{
uri.append("&type_destination=").append(locationTypeValue(toType));
uri.append("&name_destination=").append(ParserUtils.urlEncode(to, "ISO-8859-1")); // fine-grained location
}
if (via != null)
{
if (viaType == LocationType.WGS84)
{
final String[] parts = via.split(",\\s*", 2);
final int lat = Integer.parseInt(parts[0]);
final int lon = Integer.parseInt(parts[1]);
uri.append("&nameInfo_via=").append(String.format("%2.6f:%2.6f", lon / 1E6, lat / 1E6)).append(":WGS84[DD.dddddd]");
uri.append("&typeInfo_via=coord");
}
else
{
uri.append("&type_via=").append(locationTypeValue(viaType));
uri.append("&name_via=").append(ParserUtils.urlEncode(via, "ISO-8859-1"));
}
}
uri.append("&itdDate=").append(ParserUtils.urlEncode(DATE_FORMAT.format(date)));
uri.append("&itdTime=").append(ParserUtils.urlEncode(TIME_FORMAT.format(date)));
uri.append("&itdTripDateTimeDepArr=").append(dep ? "dep" : "arr");
// TODO products
uri.append("&changeSpeed=").append(WALKSPEED_MAP.get(walkSpeed));
uri.append("&locationServerActive=1");
return uri.toString();
}
public QueryConnectionsResult queryMoreConnections(String uri) throws IOException
@Override
protected String commandLink(final String sessionId, final String command)
{
throw new UnsupportedOperationException();
}
public GetConnectionDetailsResult getConnectionDetails(String connectionUri) throws IOException
{
throw new UnsupportedOperationException();
final StringBuilder uri = new StringBuilder();
uri.append(API_BASE);
uri.append("XSLT_TRIP_REQUEST2");
uri.append("?sessionID=").append(sessionId);
uri.append("&command=").append(command);
return uri.toString();
}
}

View file

@ -16,11 +16,10 @@
*/
package de.schildbach.pte;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import de.schildbach.pte.dto.GetConnectionDetailsResult;
import de.schildbach.pte.dto.QueryConnectionsResult;
import de.schildbach.pte.util.ParserUtils;
/**
@ -34,7 +33,8 @@ public class VrrProvider extends AbstractEfaProvider
public boolean hasCapabilities(final Capability... capabilities)
{
for (final Capability capability : capabilities)
if (capability == Capability.DEPARTURES)
if (capability == Capability.DEPARTURES || capability == Capability.CONNECTIONS || capability == Capability.LOCATION_STATION_ID
|| capability == Capability.LOCATION_WGS84)
return true;
return false;
@ -76,19 +76,87 @@ public class VrrProvider extends AbstractEfaProvider
return uri.toString();
}
public QueryConnectionsResult queryConnections(LocationType fromType, String from, LocationType viaType, String via, LocationType toType,
String to, Date date, boolean dep, String products, WalkSpeed walkSpeed) throws IOException
@Override
protected String connectionsQueryUri(final LocationType fromType, final String from, final LocationType viaType, final String via,
final LocationType toType, final String to, final Date date, final boolean dep, final String products, final WalkSpeed walkSpeed)
{
throw new UnsupportedOperationException();
final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyyMMdd");
final DateFormat TIME_FORMAT = new SimpleDateFormat("HHmm");
final StringBuilder uri = new StringBuilder();
uri.append(API_BASE);
uri.append("XSLT_TRIP_REQUEST2");
uri.append("?language=de");
uri.append("&outputFormat=XML");
uri.append("&coordOutputFormat=WGS84");
if (fromType == LocationType.WGS84)
{
final String[] parts = from.split(",\\s*", 2);
final int lat = Integer.parseInt(parts[0]);
final int lon = Integer.parseInt(parts[1]);
uri.append("&nameInfo_origin=").append(String.format("%2.6f:%2.6f", lon / 1E6, lat / 1E6)).append(":WGS84[DD.dddddd]");
uri.append("&typeInfo_origin=coord");
}
else
{
uri.append("&type_origin=").append(locationTypeValue(fromType));
uri.append("&name_origin=").append(ParserUtils.urlEncode(from, "ISO-8859-1")); // fine-grained location
}
if (toType == LocationType.WGS84)
{
final String[] parts = to.split(",\\s*", 2);
final int lat = Integer.parseInt(parts[0]);
final int lon = Integer.parseInt(parts[1]);
uri.append("&nameInfo_destination=").append(String.format("%2.6f:%2.6f", lon / 1E6, lat / 1E6)).append(":WGS84[DD.dddddd]");
uri.append("&typeInfo_destination=coord");
}
else
{
uri.append("&type_destination=").append(locationTypeValue(toType));
uri.append("&name_destination=").append(ParserUtils.urlEncode(to, "ISO-8859-1")); // fine-grained location
}
if (via != null)
{
if (viaType == LocationType.WGS84)
{
final String[] parts = via.split(",\\s*", 2);
final int lat = Integer.parseInt(parts[0]);
final int lon = Integer.parseInt(parts[1]);
uri.append("&nameInfo_via=").append(String.format("%2.6f:%2.6f", lon / 1E6, lat / 1E6)).append(":WGS84[DD.dddddd]");
uri.append("&typeInfo_via=coord");
}
else
{
uri.append("&type_via=").append(locationTypeValue(viaType));
uri.append("&name_via=").append(ParserUtils.urlEncode(via, "ISO-8859-1"));
}
}
uri.append("&itdDate=").append(ParserUtils.urlEncode(DATE_FORMAT.format(date)));
uri.append("&itdTime=").append(ParserUtils.urlEncode(TIME_FORMAT.format(date)));
uri.append("&itdTripDateTimeDepArr=").append(dep ? "dep" : "arr");
// TODO products
uri.append("&changeSpeed=").append(WALKSPEED_MAP.get(walkSpeed));
uri.append("&locationServerActive=1");
return uri.toString();
}
public QueryConnectionsResult queryMoreConnections(String uri) throws IOException
@Override
protected String commandLink(final String sessionId, final String command)
{
throw new UnsupportedOperationException();
}
public GetConnectionDetailsResult getConnectionDetails(String connectionUri) throws IOException
{
throw new UnsupportedOperationException();
final StringBuilder uri = new StringBuilder();
uri.append(API_BASE);
uri.append("XSLT_TRIP_REQUEST2");
uri.append("?sessionID=").append(sessionId);
uri.append("&command=").append(command);
return uri.toString();
}
}

View file

@ -91,6 +91,7 @@ public final class Connection implements Serializable
{
final public String line;
final public int[] lineColors;
final public int destinationId;
final public String destination;
final public Date departureTime;
final public String departurePosition;
@ -101,12 +102,13 @@ public final class Connection implements Serializable
final public int arrivalId;
final public String arrival;
public Trip(final String line, final int[] lineColors, final String destination, final Date departureTime, final String departurePosition,
final int departureId, final String departure, final Date arrivalTime, final String arrivalPosition, final int arrivalId,
final String arrival)
public Trip(final String line, final int[] lineColors, final int destinationId, final String destination, final Date departureTime,
final String departurePosition, final int departureId, final String departure, final Date arrivalTime, final String arrivalPosition,
final int arrivalId, final String arrival)
{
this.line = line;
this.lineColors = lineColors;
this.destinationId = destinationId;
this.destination = destination;
this.departureTime = departureTime;
this.departurePosition = departurePosition;
@ -124,7 +126,7 @@ public final class Connection implements Serializable
final StringBuilder builder = new StringBuilder(getClass().getName() + "[");
builder.append("line=").append(line);
builder.append(",");
builder.append("destination=").append(destination);
builder.append("destination=").append(destination).append("/").append(destinationId);
builder.append(",");
builder.append("departure=").append(departureTime).append("/").append(departurePosition).append("/").append(departureId).append("/")
.append(departure);

View file

@ -31,15 +31,15 @@ public final class QueryConnectionsResult implements Serializable
OK, AMBIGUOUS, TOO_CLOSE, NO_CONNECTIONS, INVALID_DATE;
}
public static final QueryConnectionsResult TOO_CLOSE = new QueryConnectionsResult(Status.TOO_CLOSE, null, null, null);
public static final QueryConnectionsResult NO_CONNECTIONS = new QueryConnectionsResult(Status.NO_CONNECTIONS, null, null, null);
public static final QueryConnectionsResult INVALID_DATE = new QueryConnectionsResult(Status.INVALID_DATE, null, null, null);
public static final QueryConnectionsResult TOO_CLOSE = new QueryConnectionsResult(Status.TOO_CLOSE);
public static final QueryConnectionsResult NO_CONNECTIONS = new QueryConnectionsResult(Status.NO_CONNECTIONS);
public static final QueryConnectionsResult INVALID_DATE = new QueryConnectionsResult(Status.INVALID_DATE);
public final Status status;
public final List<String> ambiguousFromAddresses;
public final List<String> ambiguousViaAddresses;
public final List<String> ambiguousToAddresses;
public final List<Autocomplete> ambiguousFrom;
public final List<Autocomplete> ambiguousVia;
public final List<Autocomplete> ambiguousTo;
public final String queryUri;
public final String from;
@ -49,23 +49,6 @@ public final class QueryConnectionsResult implements Serializable
public final String linkLater;
public final List<Connection> connections;
public QueryConnectionsResult(final Status status, final List<String> ambiguousFromAddresses, final List<String> ambiguousViaAddresses,
final List<String> ambiguousToAddresses)
{
this.status = status;
this.ambiguousFromAddresses = ambiguousFromAddresses;
this.ambiguousViaAddresses = ambiguousViaAddresses;
this.ambiguousToAddresses = ambiguousToAddresses;
this.queryUri = null;
this.from = null;
this.to = null;
this.currentDate = null;
this.linkEarlier = null;
this.linkLater = null;
this.connections = null;
}
public QueryConnectionsResult(final String queryUri, final String from, final String to, final Date currentDate, final String linkEarlier,
final String linkLater, final List<Connection> connections)
{
@ -78,9 +61,41 @@ public final class QueryConnectionsResult implements Serializable
this.linkLater = linkLater;
this.connections = connections;
this.ambiguousFromAddresses = null;
this.ambiguousViaAddresses = null;
this.ambiguousToAddresses = null;
this.ambiguousFrom = null;
this.ambiguousVia = null;
this.ambiguousTo = null;
}
public QueryConnectionsResult(final List<Autocomplete> ambiguousFrom, final List<Autocomplete> ambiguousVia, final List<Autocomplete> ambiguousTo)
{
this.status = Status.AMBIGUOUS;
this.ambiguousFrom = ambiguousFrom;
this.ambiguousVia = ambiguousVia;
this.ambiguousTo = ambiguousTo;
this.queryUri = null;
this.from = null;
this.to = null;
this.currentDate = null;
this.linkEarlier = null;
this.linkLater = null;
this.connections = null;
}
public QueryConnectionsResult(final Status status)
{
this.status = status;
this.ambiguousFrom = null;
this.ambiguousVia = null;
this.ambiguousTo = null;
this.queryUri = null;
this.from = null;
this.to = null;
this.currentDate = null;
this.linkEarlier = null;
this.linkLater = null;
this.connections = null;
}
@Override
@ -90,12 +105,12 @@ public final class QueryConnectionsResult implements Serializable
builder.append("[").append(this.status).append(": ");
if (connections != null)
builder.append(connections.size()).append(" connections, ");
if (ambiguousFromAddresses != null)
builder.append(ambiguousFromAddresses.size()).append(" ambiguous fromAddresses, ");
if (ambiguousViaAddresses != null)
builder.append(ambiguousViaAddresses.size()).append(" ambiguous viaAddresses, ");
if (ambiguousToAddresses != null)
builder.append(ambiguousToAddresses.size()).append(" ambiguous toAddresses, ");
if (ambiguousFrom != null)
builder.append(ambiguousFrom.size()).append(" ambiguous from, ");
if (ambiguousVia != null)
builder.append(ambiguousVia.size()).append(" ambiguous via, ");
if (ambiguousTo != null)
builder.append(ambiguousTo.size()).append(" ambiguous to, ");
if (builder.substring(builder.length() - 2).equals(", "))
builder.setLength(builder.length() - 2);
builder.append("]");

View file

@ -16,13 +16,17 @@
*/
package de.schildbach.pte.live;
import java.util.Date;
import java.util.List;
import org.junit.Test;
import de.schildbach.pte.GvhProvider;
import de.schildbach.pte.NetworkProvider.LocationType;
import de.schildbach.pte.NetworkProvider.WalkSpeed;
import de.schildbach.pte.dto.Autocomplete;
import de.schildbach.pte.dto.NearbyStationsResult;
import de.schildbach.pte.dto.QueryConnectionsResult;
/**
* @author Andreas Schildbach
@ -30,6 +34,7 @@ import de.schildbach.pte.dto.NearbyStationsResult;
public class GvhProviderLiveTest
{
private final GvhProvider provider = new GvhProvider();
private static final String ALL_PRODUCTS = "IRSUTBFC";
@Test
public void autocompleteIncomplete() throws Exception
@ -78,4 +83,12 @@ public class GvhProviderLiveTest
System.out.println(result.stations.size() + " " + result.stations);
}
@Test
public void incompleteConnection() throws Exception
{
final QueryConnectionsResult result = provider.queryConnections(LocationType.ANY, "hann", null, null, LocationType.ANY, "laat", new Date(),
true, ALL_PRODUCTS, WalkSpeed.FAST);
System.out.println(result);
}
}

View file

@ -76,14 +76,22 @@ public class LinzProviderLiveTest
System.out.println(result);
}
@Test
public void incompleteConnection() throws Exception
{
final QueryConnectionsResult result = provider.queryConnections(LocationType.ANY, "linz", null, null, LocationType.ANY, "gel", new Date(),
true, ALL_PRODUCTS, WalkSpeed.FAST);
System.out.println(result);
}
@Test
public void shortConnection() throws Exception
{
final QueryConnectionsResult result = provider.queryConnections(LocationType.STATION, "Linz Hauptbahnhof", null, null, LocationType.STATION,
"Linz Auwiesen", new Date(), true, ALL_PRODUCTS, WalkSpeed.FAST);
System.out.println(result);
// final QueryConnectionsResult moreResult = provider.queryMoreConnections(result.linkLater);
// System.out.println(moreResult);
final QueryConnectionsResult moreResult = provider.queryMoreConnections(result.linkLater);
System.out.println(moreResult);
}
@Test