departures for Hannover

git-svn-id: https://public-transport-enabler.googlecode.com/svn/trunk@208 0924bc21-9374-b0fa-ee44-9ff1593b38f0
This commit is contained in:
andreas.schildbach 2010-09-29 15:39:44 +00:00
parent 75ac46e270
commit f66cb36bb5
7 changed files with 716 additions and 131 deletions

View file

@ -15,6 +15,13 @@
<scope>provided</scope>
</dependency>
<dependency>
<groupId>net.sf.kxml</groupId>
<artifactId>kxml2</artifactId>
<version>2.3.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>

View file

@ -18,11 +18,20 @@
package de.schildbach.pte;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
import de.schildbach.pte.util.XmlPullUtil;
/**
* @author Andreas Schildbach
*/
@ -112,4 +121,78 @@ public abstract class AbstractEfaProvider implements NetworkProvider
{
return (double) value / 1000000;
}
protected abstract String parseLine(String number, String symbol, String mot);
public QueryDeparturesResult queryDepartures(final String uri) throws IOException
{
try
{
final CharSequence page = ParserUtils.scrape(uri);
// System.out.println(page);
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, "odvNameElem");
final int locationId = Integer.parseInt(pp.getAttributeValue(null, "stopID"));
final String location = pp.nextText();
final Calendar departureTime = new GregorianCalendar();
final List<Departure> departures = new ArrayList<Departure>(8);
XmlPullUtil.jumpToStartTag(pp, null, "itdDepartureList");
while (XmlPullUtil.jumpToStartTag(pp, null, "itdDeparture"))
{
if (Integer.parseInt(pp.getAttributeValue(null, "stopID")) == locationId)
{
String position = pp.getAttributeValue(null, "platform");
if (position != null)
position = "Gl. " + position;
departureTime.clear();
XmlPullUtil.jumpToStartTag(pp, null, "itdDate");
processItdDate(pp, departureTime);
XmlPullUtil.jumpToStartTag(pp, null, "itdTime");
processItdTime(pp, departureTime);
XmlPullUtil.jumpToStartTag(pp, null, "itdServingLine");
final String line = parseLine(pp.getAttributeValue(null, "number"), pp.getAttributeValue(null, "symbol"), pp.getAttributeValue(
null, "motType"));
final boolean isRealtime = pp.getAttributeValue(null, "realtime").equals("1");
final String destination = 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));
}
}
return new QueryDeparturesResult(uri, locationId, location, departures);
}
catch (final XmlPullParserException x)
{
throw new RuntimeException(x);
}
}
private void processItdDate(final XmlPullParser pp, final Calendar calendar) throws XmlPullParserException, IOException
{
pp.require(XmlPullParser.START_TAG, null, "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")));
}
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.MINUTE, Integer.parseInt(pp.getAttributeValue(null, "minute")));
}
}

View file

@ -19,14 +19,27 @@ package de.schildbach.pte;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;
/**
* @author Andreas Schildbach
*/
public class GvhProvider extends AbstractEfaProvider
{
public static final String NETWORK_ID = "mobil.gvh.de";
private static final String API_BASE = "http://mobil.gvh.de/mobile2/";
public boolean hasCapabilities(final Capability... capabilities)
{
for (final Capability capability : capabilities)
if (capability == Capability.DEPARTURES)
return true;
return false;
}
private static final String AUTOCOMPLETE_URI = API_BASE
+ "XML_STOPFINDER_REQUEST?outputFormat=XML&coordOutputFormat=WGS84&name_sf=%s&type_sf=any";
private static final String ENCODING = "ISO-8859-1";
@ -52,24 +65,94 @@ public class GvhProvider extends AbstractEfaProvider
return null;
}
public StationLocationResult stationLocation(String stationId) throws IOException
{
throw new UnsupportedOperationException();
}
public String departuresQueryUri(String stationId, int maxDepartures)
{
throw new UnsupportedOperationException();
final StringBuilder uri = new StringBuilder();
uri.append(API_BASE).append("XSLT_DM_REQUEST");
uri.append("?outputFormat=XML");
uri.append("&coordOutputFormat=WGS84");
uri.append("&type_dm=stop");
uri.append("&name_dm=").append(stationId);
uri.append("&mode=direct");
return uri.toString();
}
public GetConnectionDetailsResult getConnectionDetails(String connectionUri) throws IOException
{
throw new UnsupportedOperationException();
}
private static final Pattern P_LINE_RE = Pattern.compile("RE\\d+");
private static final Pattern P_LINE_RB = Pattern.compile("RB\\d+");
public boolean hasCapabilities(Capability... capabilities)
@Override
protected String parseLine(final String number, final String symbol, final String mot)
{
throw new UnsupportedOperationException();
}
if (!number.equals(symbol))
throw new IllegalStateException("number " + number + ", symbol " + symbol);
public int[] lineColors(String line)
int t = Integer.parseInt(mot);
if (t == 0)
{
throw new UnsupportedOperationException();
final String[] parts = number.split(" ", 3);
final String type = parts[0];
final String num = parts.length >= 2 ? parts[1] : null;
final String str = type + (num != null ? num : "");
if (type.equals("EC")) // Eurocity
return 'I' + str;
if (type.equals("IC")) // Intercity
return 'I' + str;
if (type.equals("ICE")) // Intercity Express
return 'I' + str;
if (type.equals("THA")) // Thalys
return 'I' + str;
if (type.equals("IR")) // Interregio
return 'R' + str;
if (type.equals("RE")) // Regional-Express
return 'R' + str;
if (P_LINE_RE.matcher(type).matches())
return 'R' + str;
if (type.equals("RB")) // Regionalbahn
return 'R' + str;
if (P_LINE_RB.matcher(type).matches())
return 'R' + str;
if (type.equals("R")) // Regionalzug
return 'R' + str;
if (type.equals("WFB")) // Westfalenbahn
return 'R' + str;
if (type.equals("NWB")) // NordWestBahn
return 'R' + str;
if (type.equals("ME")) // Metronom
return 'R' + str;
if (type.equals("ERB")) // eurobahn
return 'R' + str;
if (type.equals("CAN")) // cantus
return 'R' + str;
if (type.equals("HEX")) // Veolia Verkehr Sachsen-Anhalt
return 'R' + str;
if (type.equals("EB")) // Erfurter Bahn
return 'R' + str;
if (type.equals("MRB")) // Mittelrheinbahn
return 'R' + str;
if (type.equals("ABR")) // ABELLIO Rail NRW
return 'R' + str;
throw new IllegalArgumentException("cannot normalize: " + number);
}
if (t == 1)
return 'S' + number;
if (t == 3 || t == 4)
return 'T' + number;
if (t == 5 || t == 6 || t == 7 || t == 10)
return 'B' + number;
if (t == 9)
return 'F' + number;
if (t == 11)
return '?' + number;
throw new IllegalStateException("cannot normalize mot '" + mot + "' number '" + number + "'");
}
public QueryConnectionsResult queryConnections(LocationType fromType, String from, LocationType viaType, String via, LocationType toType,
@ -78,18 +161,32 @@ public class GvhProvider extends AbstractEfaProvider
throw new UnsupportedOperationException();
}
public QueryDeparturesResult queryDepartures(String queryUri) throws IOException
{
throw new UnsupportedOperationException();
}
public QueryConnectionsResult queryMoreConnections(String uri) throws IOException
{
throw new UnsupportedOperationException();
}
public StationLocationResult stationLocation(String stationId) throws IOException
public GetConnectionDetailsResult getConnectionDetails(String connectionUri) throws IOException
{
throw new UnsupportedOperationException();
}
private static final Map<Character, int[]> LINES = new HashMap<Character, int[]>();
static
{
LINES.put('I', new int[] { Color.WHITE, Color.RED, Color.RED });
LINES.put('R', new int[] { Color.GRAY, Color.WHITE });
LINES.put('S', new int[] { Color.parseColor("#006e34"), Color.WHITE });
LINES.put('U', new int[] { Color.parseColor("#003090"), Color.WHITE });
LINES.put('T', new int[] { Color.parseColor("#cc0000"), Color.WHITE });
LINES.put('B', new int[] { Color.parseColor("#993399"), Color.WHITE });
LINES.put('F', new int[] { Color.BLUE, Color.WHITE });
LINES.put('?', new int[] { Color.DKGRAY, Color.WHITE });
}
public int[] lineColors(final String line)
{
return LINES.get(line.charAt(0));
}
}

View file

@ -18,15 +18,9 @@
package de.schildbach.pte;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author Andreas Schildbach
@ -109,113 +103,8 @@ public class LinzProvider extends AbstractEfaProvider
return uri.toString();
}
private static final Pattern P_DEPARTURES_HEAD_COARSE = Pattern.compile(".*?" //
+ "(?:" //
+ "<itdOdv type=\"stop\" usage=\"dm\">(.*?)</itdOdv>.*?" // head
+ "(?:<itdDepartureList>(.*?)</itdDepartureList>.*?)?" // departures
+ "|" //
+ "(Server-Wartung).*?" // messages
+ ")" //
, Pattern.DOTALL);
private static final Pattern P_DEPARTURES_HEAD_FINE = Pattern.compile(".*?" //
+ "<odvNameElem .*? stopID=\"(\\d+)\" [^>]*>" // locationId
+ "([^<]*).*?" // location
, Pattern.DOTALL);
private static final Pattern P_DEPARTURES_COARSE = Pattern.compile("<itdDeparture (.*?)</itdDeparture>", Pattern.DOTALL);
private static final Pattern P_DEPARTURES_FINE = Pattern.compile("" //
+ "stopID=\"(\\d+)\" [^>]* area=\"(\\d+)\" platform=\"(\\d+)?\" platformName=\"\".*?" // locationId
+ "<itdDate year=\"(\\d+)\" month=\"(\\d+)\" day=\"(\\d+)\" weekday=\"\\d+\"/>" // date
+ "<itdTime hour=\"(\\d+)\" minute=\"(\\d+)\" ap=\"\"/>" // time
+ ".*?" //
+ "<itdServingLine [^>]* number=\"([^<]*)\" symbol=\"([^<]*)\" motType=\"(\\d+)\" " // line, symbol, type
+ "realtime=\"(\\d+)\" " // realtime
+ "direction=\"([^\"]*)\" destID=\"(\\d+)\"" // destination, destinationId
+ ".*?" //
, Pattern.DOTALL);
public QueryDeparturesResult queryDepartures(final String uri) throws IOException
{
final CharSequence page = ParserUtils.scrape(uri);
// parse page
final Matcher mHeadCoarse = P_DEPARTURES_HEAD_COARSE.matcher(page);
if (mHeadCoarse.matches())
{
if (mHeadCoarse.group(3) != null)
return new QueryDeparturesResult(uri, QueryDeparturesResult.Status.SERVICE_DOWN);
final String headerText = mHeadCoarse.group(1);
final String departuresText = mHeadCoarse.group(2);
final Matcher mHeadFine = P_DEPARTURES_HEAD_FINE.matcher(headerText);
if (mHeadFine.matches())
{
final int locationId = Integer.parseInt(mHeadFine.group(1));
final String location = ParserUtils.resolveEntities(mHeadFine.group(2));
final List<Departure> departures = new ArrayList<Departure>(8);
if (departuresText != null)
{
final Matcher mDepCoarse = P_DEPARTURES_COARSE.matcher(departuresText);
while (mDepCoarse.find())
{
final Matcher mDepFine = P_DEPARTURES_FINE.matcher(mDepCoarse.group(1));
if (mDepFine.matches())
{
if (Integer.parseInt(mDepFine.group(1)) == locationId)
{
final String area = mDepFine.group(2); // FIXME not clear what this is
final String position = mDepFine.group(3) != null ? "Gl. " + mDepFine.group(3) : null;
final Date departureDate = parseDate(mDepFine.group(4), mDepFine.group(5), mDepFine.group(6), mDepFine.group(7),
mDepFine.group(8));
final String line = parseLine(mDepFine.group(9), mDepFine.group(10), mDepFine.group(11));
final boolean isRealtime = mDepFine.group(12).equals("1");
final String destination = mDepFine.group(13);
final int destinationId = Integer.parseInt(mDepFine.group(14));
departures.add(new Departure(!isRealtime ? departureDate : null, isRealtime ? departureDate : null, line, LINES
.get(line.charAt(0)), null, position, destinationId, destination, null));
}
}
else
{
throw new IllegalArgumentException("cannot parse '" + mDepCoarse.group(1) + "' on " + uri);
}
}
}
return new QueryDeparturesResult(uri, locationId, location, departures);
}
else
{
throw new IllegalArgumentException("cannot parse '" + headerText + "' on " + uri);
}
}
else
{
throw new IllegalArgumentException("cannot parse '" + page + "' on " + uri);
}
}
private static Date parseDate(final String year, final String month, final String day, final String hour, final String minute)
{
final Calendar calendar = new GregorianCalendar();
calendar.clear();
calendar.set(Calendar.YEAR, Integer.parseInt(year));
calendar.set(Calendar.MONTH, Integer.parseInt(month) - 1);
calendar.set(Calendar.DAY_OF_MONTH, Integer.parseInt(day));
calendar.set(Calendar.HOUR, Integer.parseInt(hour));
calendar.set(Calendar.MINUTE, Integer.parseInt(minute));
return calendar.getTime();
}
private String parseLine(final String number, final String symbol, final String mot)
@Override
protected String parseLine(final String number, final String symbol, final String mot)
{
if (!number.equals(symbol))
throw new IllegalStateException("number " + number + ", symbol " + symbol);
@ -229,7 +118,7 @@ public class LinzProvider extends AbstractEfaProvider
if (t == 8)
return 'C' + number;
throw new IllegalStateException("cannot normalize type '" + mot + "' line '" + number + "'");
throw new IllegalStateException("cannot normalize mot '" + mot + "' number '" + number + "'");
}
private static final Map<Character, int[]> LINES = new HashMap<Character, int[]>();

View file

@ -0,0 +1,367 @@
/*
* For license please see accompanying LICENSE.txt file (available also at http://www.xmlpull.org/).
* According to www.xmlpull.org, this code is in the public domain.
*/
package de.schildbach.pte.util;
import java.io.IOException;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;
/**
* Handy functions that combines XmlPull API into higher level functionality.
*
* @author <a href="http://www.extreme.indiana.edu/~aslom/">Aleksander Slominski</a>
* @author Naresh Bhatia
*/
public class XmlPullUtil
{
public static final String XSI_NS = "http://www.w3.org/2001/XMLSchema-instance";
private XmlPullUtil()
{
}
/**
* Return value of attribute with given name and no namespace.
*/
public static String getAttributeValue(XmlPullParser pp, String name)
{
return pp.getAttributeValue(XmlPullParser.NO_NAMESPACE, name);
}
/**
* Return PITarget from Processing Instruction (PI) as defined in XML 1.0 Section 2.6 Processing Instructions <code>[16] PI ::= '&lt;?' PITarget (S (Char* - (Char* '?>' Char*)))? '?>'</code>
*/
public static String getPITarget(XmlPullParser pp) throws IllegalStateException
{
int eventType;
try
{
eventType = pp.getEventType();
}
catch (XmlPullParserException ex)
{
// should never happen ...
throw new IllegalStateException("could not determine parser state: " + ex + pp.getPositionDescription());
}
if (eventType != XmlPullParser.PROCESSING_INSTRUCTION)
throw new IllegalStateException("parser must be on processing instruction and not " + XmlPullParser.TYPES[eventType]
+ pp.getPositionDescription());
final String PI = pp.getText();
for (int i = 0; i < PI.length(); i++)
{
if (isS(PI.charAt(i)))
{
// assert i > 0
return PI.substring(0, i);
}
}
return PI;
}
/**
* Return everything past PITarget and S from Processing Instruction (PI) as defined in XML 1.0 Section 2.6
* Processing Instructions <code>[16] PI ::= '&lt;?' PITarget (S (Char* - (Char* '?>' Char*)))? '?>'</code>
*
* <p>
* <b>NOTE:</b> if there is no PI data it returns empty string.
*/
public static String getPIData(XmlPullParser pp) throws IllegalStateException
{
int eventType;
try
{
eventType = pp.getEventType();
}
catch (XmlPullParserException ex)
{
// should never happen ...
throw new IllegalStateException("could not determine parser state: " + ex + pp.getPositionDescription());
}
if (eventType != XmlPullParser.PROCESSING_INSTRUCTION)
throw new IllegalStateException("parser must be on processing instruction and not " + XmlPullParser.TYPES[eventType]
+ pp.getPositionDescription());
final String PI = pp.getText();
int pos = -1;
for (int i = 0; i < PI.length(); i++)
{
if (isS(PI.charAt(i)))
{
pos = i;
}
else if (pos > 0)
{
return PI.substring(i);
}
}
return "";
}
/**
* Return true if chacters is S as defined in XML 1.0 <code>S ::= (#x20 | #x9 | #xD | #xA)+</code>
*/
private static boolean isS(char ch)
{
return (ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t');
}
/**
* Skip sub tree that is currently porser positioned on. <br>
* NOTE: parser must be on START_TAG and when funtion returns parser will be positioned on corresponding END_TAG
*/
public static void skipSubTree(XmlPullParser pp) throws XmlPullParserException, IOException
{
pp.require(XmlPullParser.START_TAG, null, null);
int level = 1;
while (level > 0)
{
int eventType = pp.next();
if (eventType == XmlPullParser.END_TAG)
--level;
else if (eventType == XmlPullParser.START_TAG)
++level;
}
}
/**
* call parser nextTag() and check that it is START_TAG, throw exception if not.
*/
public static void nextStartTag(XmlPullParser pp) throws XmlPullParserException, IOException
{
if (pp.nextTag() != XmlPullParser.START_TAG)
throw new XmlPullParserException("expected START_TAG and not " + pp.getPositionDescription());
}
/**
* combine nextTag(); pp.require(XmlPullParser.START_TAG, null, name);
*/
public static void nextStartTag(XmlPullParser pp, String name) throws XmlPullParserException, IOException
{
pp.nextTag();
pp.require(XmlPullParser.START_TAG, null, name);
}
/**
* combine nextTag(); pp.require(XmlPullParser.START_TAG, namespace, name);
*/
public static void nextStartTag(XmlPullParser pp, String namespace, String name) throws XmlPullParserException, IOException
{
pp.nextTag();
pp.require(XmlPullParser.START_TAG, namespace, name);
}
/**
* combine nextTag(); pp.require(XmlPullParser.END_TAG, namespace, name);
*/
public static void nextEndTag(XmlPullParser pp, String namespace, String name) throws XmlPullParserException, IOException
{
pp.nextTag();
pp.require(XmlPullParser.END_TAG, namespace, name);
}
/**
* Read text content of element ith given namespace and name (use null namespace do indicate that nemspace should
* not be checked)
*/
public static String nextText(XmlPullParser pp, String namespace, String name) throws IOException, XmlPullParserException
{
if (name == null)
throw new XmlPullParserException("name for element can not be null");
pp.require(XmlPullParser.START_TAG, namespace, name);
return pp.nextText();
}
/**
* Read attribute value and return it or throw exception if current element does not have such attribute.
*/
public static String getRequiredAttributeValue(XmlPullParser pp, String namespace, String name) throws IOException, XmlPullParserException
{
final String value = pp.getAttributeValue(namespace, name);
if (value == null)
throw new XmlPullParserException("required attribute " + name + " is not present");
else
return value;
}
/**
* Call parser nextTag() and check that it is END_TAG, throw exception if not.
*/
public static void nextEndTag(XmlPullParser pp) throws XmlPullParserException, IOException
{
if (pp.nextTag() != XmlPullParser.END_TAG)
throw new XmlPullParserException("expected END_TAG and not" + pp.getPositionDescription());
}
/**
* Tests if the current event is of the given type and if the namespace and name match. null will match any
* namespace and any name. If the test passes a true is returned otherwise a false is returned.
*/
public static boolean matches(XmlPullParser pp, int type, String namespace, String name) throws XmlPullParserException
{
boolean matches = type == pp.getEventType() && (namespace == null || namespace.equals(pp.getNamespace()))
&& (name == null || name.equals(pp.getName()));
return matches;
}
/**
* Writes a simple element such as <username>johndoe</username>. The namespace and elementText are allowed to be
* null. If elementText is null, an xsi:nil="true" will be added as an attribute.
*/
public static void writeSimpleElement(XmlSerializer serializer, String namespace, String elementName, String elementText) throws IOException,
XmlPullParserException
{
if (elementName == null)
throw new XmlPullParserException("name for element can not be null");
serializer.startTag(namespace, elementName);
if (elementText == null)
{
serializer.attribute(XSI_NS, "nil", "true");
}
else
{
serializer.text(elementText);
}
serializer.endTag(namespace, elementName);
}
/**
* This method bypasses all child subtrees until it reached END_TAG for current tree. Parser must be on START_TAG of
* one of child subtrees.
*/
public static void jumpToEndOfTree(final XmlPullParser pp) throws XmlPullParserException, IOException
{
pp.require(XmlPullParser.START_TAG, null, null);
while (true)
{
int eventType = pp.next();
if (eventType == XmlPullParser.START_TAG)
{
skipSubTree(pp);
pp.require(XmlPullParser.END_TAG, null, null);
pp.next(); // skip end tag
}
else if (eventType == XmlPullParser.END_TAG)
{
break;
}
}
}
/**
* This method bypasses all child subtrees until it finds a child subtree with start tag that matches the tag name
* (if not null) and namespsce (if not null) passed in. Parser must be positioned on START_TAG.
* <p>
* If succesfulpositions parser on such START_TAG and return true otherwise this method returns false and parser is
* positioned on END_TAG signaling last element in curren subtree.
*/
public static boolean jumpToSubTree(final XmlPullParser pp, final String tagNamespace, final String tagName) throws XmlPullParserException,
IOException
{
if (tagNamespace == null && tagName == null)
throw new IllegalArgumentException("namespace and name argument can not be both null:" + pp.getPositionDescription());
pp.require(XmlPullParser.START_TAG, null, null);
while (true)
{
int eventType = pp.next();
if (eventType == XmlPullParser.START_TAG)
{
String name = pp.getName();
String namespace = pp.getNamespace();
boolean matches = (tagNamespace != null && tagNamespace.equals(namespace)) || (tagName != null && tagName.equals(name));
if (matches)
{
return true;
}
skipSubTree(pp);
pp.require(XmlPullParser.END_TAG, name, namespace);
pp.next(); // skip end tag
}
else if (eventType == XmlPullParser.END_TAG)
{
return false;
}
}
}
/**
* This method bypasses all events until it finds a start tag that has passed in namespace (if not null) and
* namespace (if not null).
*
* @return true if such START_TAG was found or false otherwise (and parser is on END_DOCUMENT).
*/
public static boolean jumpToStartTag(final XmlPullParser pp, final String tagNamespace, final String tagName) throws XmlPullParserException,
IOException
{
if (tagNamespace == null && tagName == null)
throw new IllegalArgumentException("namespace and name argument can not be both null:" + pp.getPositionDescription());
while (true)
{
int eventType = pp.next();
if (eventType == XmlPullParser.START_TAG)
{
String name = pp.getName();
String namespace = pp.getNamespace();
boolean matches = (tagNamespace != null && tagNamespace.equals(namespace)) || (tagName != null && tagName.equals(name));
if (matches)
{
return true;
}
}
else if (eventType == XmlPullParser.END_DOCUMENT)
{
return false;
}
}
}
/**
* This method bypasses all events until it finds an end tag that has passed in namespace (if not null) and
* namespace (if not null).
*
* @return true if such END_TAG was found or false otherwise (and parser is on END_DOCUMENT).
*/
public static boolean jumpToEndTag(final XmlPullParser pp, final String tagNamespace, final String tagName) throws XmlPullParserException,
IOException
{
if (tagNamespace == null && tagName == null)
throw new IllegalArgumentException("namespace and name argument can not be both null:" + pp.getPositionDescription());
while (true)
{
int eventType = pp.next();
if (eventType == XmlPullParser.END_TAG)
{
String name = pp.getName();
String namespace = pp.getNamespace();
boolean matches = (tagNamespace != null && tagNamespace.equals(namespace)) || (tagName != null && tagName.equals(name));
if (matches)
{
return true;
}
}
else if (eventType == XmlPullParser.END_DOCUMENT)
{
return false;
}
}
}
}

View file

@ -0,0 +1,49 @@
/*
* Copyright 2010 the original author or authors.
*
* This program 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 3 of the License, or
* (at your option) any later version.
*
* This program 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 program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.schildbach.pte.live;
import java.util.List;
import org.junit.Test;
import de.schildbach.pte.Autocomplete;
import de.schildbach.pte.GvhProvider;
import de.schildbach.pte.Station;
/**
* @author Andreas Schildbach
*/
public class GvhProviderLiveTest
{
private final GvhProvider provider = new GvhProvider();
@Test
public void autocomplete() throws Exception
{
final List<Autocomplete> results = provider.autocompleteStations("Hannover");
System.out.println(results.size() + " " + results);
}
@Test
public void nearby() throws Exception
{
final List<Station> results = provider.nearbyStations("25000031", 0, 0, 0, 0);
System.out.println(results.size() + " " + results);
}
}

View file

@ -0,0 +1,93 @@
/*
* Copyright 2010 the original author or authors.
*
* This program 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 3 of the License, or
* (at your option) any later version.
*
* This program 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 program. If not, see <http://www.gnu.org/licenses/>.
*/
package de.schildbach.pte.live;
import java.util.Date;
import org.junit.Test;
import de.schildbach.pte.LinzProvider;
import de.schildbach.pte.QueryConnectionsResult;
import de.schildbach.pte.QueryDeparturesResult;
import de.schildbach.pte.NetworkProvider.LocationType;
import de.schildbach.pte.NetworkProvider.WalkSpeed;
/**
* @author Andreas Schildbach
*/
public class LinzProviderLiveTest
{
private LinzProvider provider = new LinzProvider();
@Test
public void queryDepartures() throws Exception
{
final QueryDeparturesResult result = provider.queryDepartures(provider.departuresQueryUri("60501720", 0));
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, WalkSpeed.FAST);
System.out.println(result);
// final QueryConnectionsResult moreResult = provider.queryMoreConnections(result.linkLater);
// System.out.println(moreResult);
}
@Test
public void longConnection() throws Exception
{
final QueryConnectionsResult result = provider.queryConnections(LocationType.STATION, "Linz Auwiesen", null, null, LocationType.STATION,
"Linz Hafen", new Date(), true, WalkSpeed.SLOW);
System.out.println(result);
// final QueryConnectionsResult moreResult = provider.queryMoreConnections(result.linkLater);
// System.out.println(moreResult);
}
@Test
public void connectionBetweenCoordinates() throws Exception
{
final QueryConnectionsResult result = provider.queryConnections(LocationType.WGS84, "48.165238,11.577473", null, null, LocationType.WGS84,
"47.987199,11.326532", new Date(), true, WalkSpeed.NORMAL);
System.out.println(result);
// final QueryConnectionsResult moreResult = provider.queryMoreConnections(result.linkLater);
// System.out.println(moreResult);
}
@Test
public void connectionBetweenCoordinateAndStation() throws Exception
{
final QueryConnectionsResult result = provider.queryConnections(LocationType.WGS84, "48.238341,11.478230", null, null, LocationType.ANY,
"Ostbahnhof", new Date(), true, WalkSpeed.NORMAL);
System.out.println(result);
// final QueryConnectionsResult moreResult = provider.queryMoreConnections(result.linkLater);
// System.out.println(moreResult);
}
@Test
public void connectionBetweenAddresses() throws Exception
{
final QueryConnectionsResult result = provider.queryConnections(LocationType.ADDRESS, "München, Maximilianstr. 1", null, null,
LocationType.ADDRESS, "Starnberg, Jahnstraße 50", new Date(), true, WalkSpeed.NORMAL);
System.out.println(result);
// final QueryConnectionsResult moreResult = provider.queryMoreConnections(result.linkLater);
// System.out.println(moreResult);
}
}