show intermediate stops in directions

git-svn-id: https://public-transport-enabler.googlecode.com/svn/trunk@332 0924bc21-9374-b0fa-ee44-9ff1593b38f0
This commit is contained in:
andreas.schildbach 2010-10-30 17:35:59 +00:00
parent 0edcbe09a4
commit f5b3752950
9 changed files with 220 additions and 90 deletions

View file

@ -47,6 +47,7 @@ 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.Stop;
import de.schildbach.pte.dto.QueryConnectionsResult.Status;
import de.schildbach.pte.util.Color;
import de.schildbach.pte.util.ParserUtils;
@ -694,7 +695,7 @@ public abstract class AbstractEfaProvider implements NetworkProvider
XmlPullUtil.jumpToStartTag(pp, null, "itdServingLines");
if (!pp.isEmptyElementTag())
{
XmlPullUtil.enter(pp);
XmlPullUtil.enter(pp, "itdServingLines");
while (XmlPullUtil.test(pp, "itdServingLine"))
{
try
@ -716,7 +717,7 @@ public abstract class AbstractEfaProvider implements NetworkProvider
XmlPullUtil.enter(pp);
XmlPullUtil.exit(pp);
}
XmlPullUtil.exit(pp);
XmlPullUtil.exit(pp, "itdServingLines");
}
else
{
@ -726,30 +727,44 @@ public abstract class AbstractEfaProvider implements NetworkProvider
final List<Departure> departures = new ArrayList<Departure>(8);
XmlPullUtil.require(pp, "itdDepartureList");
while (XmlPullUtil.nextStartTagInsideTree(pp, null, "itdDeparture"))
if (!pp.isEmptyElementTag())
{
if (Integer.parseInt(pp.getAttributeValue(null, "stopID")) == locationId)
XmlPullUtil.enter(pp, "itdDepartureList");
while (XmlPullUtil.test(pp, "itdDeparture"))
{
final String position = normalizePlatform(pp.getAttributeValue(null, "platform"), pp.getAttributeValue(null, "platformName"));
if (Integer.parseInt(pp.getAttributeValue(null, "stopID")) == locationId)
{
final String position = normalizePlatform(pp.getAttributeValue(null, "platform"), pp.getAttributeValue(null,
"platformName"));
departureTime.clear();
XmlPullUtil.enter(pp, "itdDeparture");
processItdDateTime(pp, departureTime);
departureTime.clear();
processItdDateTime(pp, departureTime);
if (!XmlPullUtil.nextStartTagInsideTree(pp, null, "itdServingLine"))
throw new IllegalStateException("itdServingLine not found:" + pp.getPositionDescription());
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"));
XmlPullUtil.skipRestOfTree(pp);
// TODO
if (XmlPullUtil.test(pp, "itdRTDateTime"))
XmlPullUtil.next(pp);
departures.add(new Departure(!isRealtime ? departureTime.getTime() : null, isRealtime ? departureTime.getTime() : null, line,
lineColors(line), null, position, destinationId, destination, null));
XmlPullUtil.require(pp, "itdServingLine");
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"));
departures.add(new Departure(!isRealtime ? departureTime.getTime() : null, isRealtime ? departureTime.getTime() : null,
line, lineColors(line), null, position, destinationId, destination, null));
}
else
{
XmlPullUtil.enter(pp, "itdDeparture");
}
XmlPullUtil.exit(pp, "itdDeparture");
}
XmlPullUtil.skipRestOfTree(pp);
XmlPullUtil.exit(pp, "itdDepartureList");
}
return new QueryDeparturesResult(new Location(LocationType.STATION, locationId, 0, 0, location), departures, lines);
@ -782,37 +797,37 @@ public abstract class AbstractEfaProvider implements NetworkProvider
}
}
private void processItdDateTime(final XmlPullParser pp, final Calendar calendar) throws XmlPullParserException, IOException
private void findAndProcessItdDateTime(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());
processItdDateTime(pp, calendar);
}
private void processItdDateTime(final XmlPullParser pp, final Calendar calendar) throws XmlPullParserException, IOException
{
XmlPullUtil.enter(pp, "itdDateTime");
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);
XmlPullUtil.exit(pp, "itdDateTime");
}
private void processItdDate(final XmlPullParser pp, final Calendar calendar) throws XmlPullParserException, IOException
{
pp.require(XmlPullParser.START_TAG, null, "itdDate");
XmlPullUtil.require(pp, "itdDate");
calendar.set(Calendar.YEAR, Integer.parseInt(pp.getAttributeValue(null, "year")));
calendar.set(Calendar.MONTH, Integer.parseInt(pp.getAttributeValue(null, "month")) - 1);
calendar.set(Calendar.DAY_OF_MONTH, Integer.parseInt(pp.getAttributeValue(null, "day")));
XmlPullUtil.next(pp);
}
private void processItdTime(final XmlPullParser pp, final Calendar calendar) throws XmlPullParserException, IOException
{
pp.require(XmlPullParser.START_TAG, null, "itdTime");
XmlPullUtil.require(pp, "itdTime");
calendar.set(Calendar.HOUR_OF_DAY, Integer.parseInt(pp.getAttributeValue(null, "hour")));
calendar.set(Calendar.MINUTE, Integer.parseInt(pp.getAttributeValue(null, "minute")));
XmlPullUtil.next(pp);
}
private static final Pattern P_STATION_NAME_WHITESPACE = Pattern.compile("\\s+");
@ -955,27 +970,35 @@ public abstract class AbstractEfaProvider implements NetworkProvider
return new QueryConnectionsResult(Status.INVALID_DATE);
}
final Calendar departureTime = new GregorianCalendar(), arrivalTime = new GregorianCalendar();
final Calendar departureTime = new GregorianCalendar(), arrivalTime = new GregorianCalendar(), stopTime = new GregorianCalendar();
departureTime.setTimeZone(timeZone());
arrivalTime.setTimeZone(timeZone());
final List<Connection> connections = new ArrayList<Connection>();
if (XmlPullUtil.jumpToStartTag(pp, null, "itdRouteList"))
{
while (XmlPullUtil.nextStartTagInsideTree(pp, null, "itdRoute"))
XmlPullUtil.enter(pp, "itdRouteList");
while (XmlPullUtil.test(pp, "itdRoute"))
{
final String id = pp.getAttributeValue(null, "routeIndex") + "-" + pp.getAttributeValue(null, "routeTripIndex");
XmlPullUtil.enter(pp, "itdRoute");
XmlPullUtil.jumpToStartTag(pp, null, "itdPartialRouteList");
if (XmlPullUtil.test(pp, "itdMapItemList"))
XmlPullUtil.next(pp);
XmlPullUtil.enter(pp, "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"))
while (XmlPullUtil.test(pp, "itdPartialRoute"))
{
XmlPullUtil.jumpToStartTag(pp, null, "itdPoint");
XmlPullUtil.enter(pp, "itdPartialRoute");
XmlPullUtil.test(pp, "itdPoint");
if (!"departure".equals(pp.getAttributeValue(null, "usage")))
throw new IllegalStateException();
final int departureId = Integer.parseInt(pp.getAttributeValue(null, "stopID"));
@ -984,12 +1007,15 @@ public abstract class AbstractEfaProvider implements NetworkProvider
firstDeparture = departure;
final String departurePosition = normalizePlatform(pp.getAttributeValue(null, "platform"), pp.getAttributeValue(null,
"platformName"));
XmlPullUtil.enter(pp, "itdPoint");
if (XmlPullUtil.test(pp, "itdMapItemList"))
XmlPullUtil.next(pp);
processItdDateTime(pp, departureTime);
if (firstDepartureTime == null)
firstDepartureTime = departureTime.getTime();
XmlPullUtil.skipRestOfTree(pp);
XmlPullUtil.exit(pp, "itdPoint");
XmlPullUtil.jumpToStartTag(pp, null, "itdPoint");
XmlPullUtil.test(pp, "itdPoint");
if (!"arrival".equals(pp.getAttributeValue(null, "usage")))
throw new IllegalStateException();
final int arrivalId = Integer.parseInt(pp.getAttributeValue(null, "stopID"));
@ -997,11 +1023,14 @@ public abstract class AbstractEfaProvider implements NetworkProvider
lastArrival = arrival;
final String arrivalPosition = normalizePlatform(pp.getAttributeValue(null, "platform"), pp.getAttributeValue(null,
"platformName"));
XmlPullUtil.enter(pp, "itdPoint");
if (XmlPullUtil.test(pp, "itdMapItemList"))
XmlPullUtil.next(pp);
processItdDateTime(pp, arrivalTime);
lastArrivalTime = arrivalTime.getTime();
XmlPullUtil.skipRestOfTree(pp);
XmlPullUtil.exit(pp, "itdPoint");
XmlPullUtil.jumpToStartTag(pp, null, "itdMeansOfTransport");
XmlPullUtil.test(pp, "itdMeansOfTransport");
final String productName = pp.getAttributeValue(null, "productName");
if ("Fussweg".equals(productName)) // type99
{
@ -1017,10 +1046,16 @@ public abstract class AbstractEfaProvider implements NetworkProvider
{
parts.add(new Connection.Footway(min, departureId, departure, arrivalId, arrival));
}
XmlPullUtil.enter(pp, "itdMeansOfTransport");
XmlPullUtil.exit(pp, "itdMeansOfTransport");
}
else if ("gesicherter Anschluss".equals(productName) || "nicht umsteigen".equals(productName)) // type97
{
// ignore
XmlPullUtil.enter(pp, "itdMeansOfTransport");
XmlPullUtil.exit(pp, "itdMeansOfTransport");
}
else
{
@ -1029,19 +1064,60 @@ public abstract class AbstractEfaProvider implements NetworkProvider
final String destination = normalizeLocationName(pp.getAttributeValue(null, "destination"));
final String line = parseLine(pp.getAttributeValue(null, "motType"), pp.getAttributeValue(null, "shortname"), pp
.getAttributeValue(null, "name"));
parts.add(new Connection.Trip(line, lineColors(line), destinationId, destination, departureTime.getTime(),
departurePosition, departureId, departure, arrivalTime.getTime(), arrivalPosition, arrivalId, arrival));
}
XmlPullUtil.skipRestOfTree(pp);
XmlPullUtil.skipRestOfTree(pp);
XmlPullUtil.enter(pp, "itdMeansOfTransport");
XmlPullUtil.exit(pp, "itdMeansOfTransport");
if (XmlPullUtil.test(pp, "itdRBLControlled"))
XmlPullUtil.next(pp);
if (XmlPullUtil.test(pp, "itdInfoTextList"))
XmlPullUtil.next(pp);
if (XmlPullUtil.test(pp, "itdFootPathInfo"))
XmlPullUtil.next(pp);
if (XmlPullUtil.test(pp, "infoLink"))
XmlPullUtil.next(pp);
XmlPullUtil.enter(pp, "itdStopSeq");
final List<Stop> intermediateStops = new LinkedList<Stop>();
while (XmlPullUtil.test(pp, "itdPoint"))
{
final int stopId = Integer.parseInt(pp.getAttributeValue(null, "stopID"));
final String stopName = normalizeLocationName(pp.getAttributeValue(null, "name"));
final String stopPosition = normalizePlatform(pp.getAttributeValue(null, "platform"), pp.getAttributeValue(null,
"platformName"));
XmlPullUtil.enter(pp, "itdPoint");
processItdDateTime(pp, stopTime);
XmlPullUtil.exit(pp, "itdPoint");
intermediateStops.add(new Stop(new Location(LocationType.STATION, stopId, 0, 0, stopName), stopPosition, stopTime
.getTime()));
}
XmlPullUtil.exit(pp, "itdStopSeq");
// remove first and last, because they are not intermediate
if (intermediateStops.get(0).location.id != departureId)
throw new IllegalStateException();
if (intermediateStops.get(intermediateStops.size() - 1).location.id != arrivalId)
throw new IllegalStateException();
intermediateStops.remove(0);
intermediateStops.remove(intermediateStops.size() - 1);
parts.add(new Connection.Trip(line, lineColors(line), destinationId, destination, departureTime.getTime(),
departurePosition, departureId, departure, arrivalTime.getTime(), arrivalPosition, arrivalId, arrival,
intermediateStops));
}
XmlPullUtil.exit(pp, "itdPartialRoute");
}
XmlPullUtil.exit(pp, "itdPartialRouteList");
connections
.add(new Connection(id, uri, firstDepartureTime, lastArrivalTime, null, null, 0, firstDeparture, 0, lastArrival, parts));
XmlPullUtil.skipRestOfTree(pp);
XmlPullUtil.exit(pp, "itdRoute");
}
XmlPullUtil.exit(pp, "itdRouteList");
return new QueryConnectionsResult(uri, from, via, to, commandLink(sessionId, "tripNext"), connections);
}
else

View file

@ -443,7 +443,7 @@ public abstract class AbstractHafasProvider implements NetworkProvider
if (min == 0 || line != null)
{
parts.add(new Connection.Trip(line, lineColors(line), 0, direction, departureTime, departurePos, departure.id,
departure.name, arrivalTime, arrivalPos, arrival.id, arrival.name));
departure.name, arrivalTime, arrivalPos, arrival.id, arrival.name, null));
}
else
{

View file

@ -366,7 +366,7 @@ public final class BahnProvider extends AbstractHafasProvider
final Date departureDateTime = ParserUtils.joinDateTime(departureDate, departureTime);
final Date arrivalDateTime = ParserUtils.joinDateTime(arrivalDate, arrivalTime);
lastTrip = new Connection.Trip(line, line != null ? lineColors(line) : null, 0, null, departureDateTime,
departurePosition, 0, departure, arrivalDateTime, arrivalPosition, 0, arrival);
departurePosition, 0, departure, arrivalDateTime, arrivalPosition, 0, arrival, null);
parts.add(lastTrip);
if (firstDepartureTime == null)

View file

@ -381,7 +381,7 @@ public final class BvgProvider implements NetworkProvider
final String arrival = ParserUtils.resolveEntities(mDetFine.group(10));
parts.add(new Connection.Trip(line, line != null ? LINES.get(line) : null, 0, destination, departureTime, departurePosition,
departureId, departure, arrivalTime, arrivalPosition, arrivalId, arrival));
departureId, departure, arrivalTime, arrivalPosition, arrivalId, arrival, null));
if (firstDepartureTime == null)
firstDepartureTime = departureTime;

View file

@ -423,7 +423,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), 0, null, detailsDepartureDateTime,
departurePosition, departureId, departure, detailsArrivalDateTime, arrivalPosition, arrivalId, arrival);
departurePosition, departureId, departure, detailsArrivalDateTime, arrivalPosition, arrivalId, arrival, null);
connection.parts.add(trip);
}
else

View file

@ -356,7 +356,7 @@ public class RmvProvider extends AbstractHafasProvider
final String arrivalPosition = ParserUtils.resolveEntities(mDetFine.group(6));
lastTrip = new Connection.Trip(line, line != null ? lineColors(line) : null, 0, destination, departureTime,
departurePosition, 0, departure, arrivalTime, arrivalPosition, 0, arrival);
departurePosition, 0, departure, arrivalTime, arrivalPosition, 0, arrival, null);
parts.add(lastTrip);
if (firstDepartureTime == null)

View file

@ -27,17 +27,17 @@ import java.util.List;
*/
public final class Connection implements Serializable
{
final public String id;
final public String link;
final public Date departureTime;
final public Date arrivalTime;
final public String line;
final public int[] lineColors;
final public int fromId;
final public String from;
final public int toId;
final public String to;
final public List<Part> parts;
public final String id;
public final String link;
public final Date departureTime;
public final Date arrivalTime;
public final String line;
public final int[] lineColors;
public final int fromId;
public final String from;
public final int toId;
public final String to;
public final List<Part> parts;
public Connection(final String id, final String link, final Date departureTime, final Date arrivalTime, final String line,
final int[] lineColors, final int fromId, final String from, final int toId, final String to, final List<Part> parts)
@ -85,22 +85,23 @@ public final class Connection implements Serializable
public final static class Trip implements Part
{
final public String line;
final public int[] lineColors;
final public int destinationId;
final public String destination;
final public Date departureTime;
final public String departurePosition;
final public int departureId;
final public String departure;
final public Date arrivalTime;
final public String arrivalPosition;
final public int arrivalId;
final public String arrival;
public final String line;
public final int[] lineColors;
public final int destinationId;
public final String destination;
public final Date departureTime;
public final String departurePosition;
public final int departureId;
public final String departure;
public final Date arrivalTime;
public final String arrivalPosition;
public final int arrivalId;
public final String arrival;
public final List<Stop> intermediateStops;
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)
final int arrivalId, final String arrival, final List<Stop> intermediateStops)
{
this.line = line;
this.lineColors = lineColors;
@ -114,6 +115,7 @@ public final class Connection implements Serializable
this.arrivalPosition = arrivalPosition;
this.arrivalId = arrivalId;
this.arrival = arrival;
this.intermediateStops = intermediateStops;
}
@Override
@ -136,12 +138,12 @@ public final class Connection implements Serializable
public final static class Footway implements Part
{
final public int min;
final public int departureId;
final public String departure;
final public int arrivalId;
final public String arrival;
final public int arrivalLat, arrivalLon;
public final int min;
public final int departureId;
public final String departure;
public final int arrivalId;
public final String arrival;
public final int arrivalLat, arrivalLon;
public Footway(final int min, final int departureId, final String departure, final int arrivalId, final String arrival, final int arrivalLat,
final int arrivalLon)

View file

@ -0,0 +1,34 @@
package de.schildbach.pte.dto;
import java.io.Serializable;
import java.util.Date;
/**
* @author Andreas Schildbach
*/
public final class Stop implements Serializable
{
public final Location location;
public final String position;
public final Date time;
public Stop(final Location location, final String position, final Date time)
{
this.location = location;
this.position = position;
this.time = time;
}
@Override
public String toString()
{
StringBuilder builder = new StringBuilder("Stop(");
builder.append(location);
builder.append(",");
builder.append(position != null ? position : "null");
builder.append(",");
builder.append(time != null ? time : "null");
builder.append(")");
return builder.toString();
}
}

View file

@ -30,6 +30,11 @@ public final class XmlPullUtil
throw new IllegalStateException("cannot find <" + tagName + " />");
}
public static void require(final XmlPullParser pp, final String tagName) throws XmlPullParserException, IOException
{
pp.require(XmlPullParser.START_TAG, null, tagName);
}
/**
* enters current tag
*
@ -45,7 +50,30 @@ public final class XmlPullUtil
pp.next();
}
public static void enter(final XmlPullParser pp, final String tagName) throws XmlPullParserException, IOException
{
pp.require(XmlPullParser.START_TAG, null, tagName);
enter(pp);
}
public static void exit(final XmlPullParser pp) throws XmlPullParserException, IOException
{
exitSkipToEnd(pp);
if (pp.getEventType() != XmlPullParser.END_TAG)
throw new IllegalStateException("expecting end tag to exit");
pp.next();
}
public static void exit(final XmlPullParser pp, final String tagName) throws XmlPullParserException, IOException
{
exitSkipToEnd(pp);
pp.require(XmlPullParser.END_TAG, null, tagName);
pp.next();
}
private static void exitSkipToEnd(final XmlPullParser pp) throws XmlPullParserException, IOException
{
while (pp.getEventType() != XmlPullParser.END_TAG)
{
@ -56,11 +84,6 @@ public final class XmlPullUtil
else
throw new IllegalStateException();
}
if (pp.getEventType() != XmlPullParser.END_TAG)
throw new IllegalStateException("expecting end tag to exit");
pp.next();
}
public static boolean test(final XmlPullParser pp, final String tagName) throws XmlPullParserException
@ -74,11 +97,6 @@ public final class XmlPullUtil
pp.next();
}
public static void require(final XmlPullParser pp, final String tagName) throws XmlPullParserException, IOException
{
pp.require(XmlPullParser.START_TAG, null, tagName);
}
public static String attr(final XmlPullParser pp, final String attrName)
{
return pp.getAttributeValue(null, attrName);