From 8419822b3060dd715608e57a087add65091fbc58 Mon Sep 17 00:00:00 2001 From: "andreas.schildbach" Date: Thu, 30 Sep 2010 17:08:17 +0000 Subject: [PATCH] use common line parser for efa based apis git-svn-id: https://public-transport-enabler.googlecode.com/svn/trunk@213 0924bc21-9374-b0fa-ee44-9ff1593b38f0 --- .../schildbach/pte/AbstractEfaProvider.java | 204 +++++++++++++++++- src/de/schildbach/pte/GvhProvider.java | 189 ---------------- src/de/schildbach/pte/LinzProvider.java | 22 +- src/de/schildbach/pte/MvvProvider.java | 158 ++++---------- 4 files changed, 242 insertions(+), 331 deletions(-) diff --git a/src/de/schildbach/pte/AbstractEfaProvider.java b/src/de/schildbach/pte/AbstractEfaProvider.java index 2b40636b..941e5d80 100644 --- a/src/de/schildbach/pte/AbstractEfaProvider.java +++ b/src/de/schildbach/pte/AbstractEfaProvider.java @@ -123,7 +123,198 @@ public abstract class AbstractEfaProvider implements NetworkProvider return (double) value / 1000000; } - protected abstract String parseLine(String number, String symbol, String mot); + private static final Pattern P_LINE_RE = Pattern.compile("RE\\d+"); + private static final Pattern P_LINE_RB = Pattern.compile("RB\\d+"); + private static final Pattern P_LINE_U = Pattern.compile("U\\d+"); + + protected String parseLine(final String number, final String symbol, final String mot) + { + if (!number.equals(symbol)) + throw new IllegalStateException("number " + number + ", symbol " + symbol); + + final int t = Integer.parseInt(mot); + + if (t == 0) + { + 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("EN")) // Euronight + return 'I' + str; + if (type.equals("IC")) // Intercity + return 'I' + str; + if (type.equals("ICE")) // Intercity Express + return 'I' + str; + if (type.equals("CNL")) // City Night Line + return 'I' + str; + if (type.equals("THA")) // Thalys + return 'I' + str; + if (type.equals("TGV")) // TGV + return 'I' + str; + if (type.equals("RJ")) // railjet + return 'I' + str; + + if (type.equals("IR")) // Interregio + return 'R' + str; + if (type.equals("IRE")) // Interregio-Express + 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("D")) // Schnellzug + 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; + if (type.equals("NEB")) // Niederbarnimer Eisenbahn + return 'R' + str; + if (type.equals("OE")) // Ostdeutsche Eisenbahn + return 'R' + str; + if (type.equals("MR")) // Märkische Regiobahn + return 'R' + str; + if (type.equals("OLA")) // Ostseeland Verkehr + return 'R' + str; + if (type.equals("UBB")) // Usedomer Bäderbahn + return 'R' + str; + if (type.equals("EVB")) // Elbe-Weser + return 'R' + str; + if (type.equals("PEG")) // Prignitzer Eisenbahngesellschaft + return 'R' + str; + if (type.equals("RTB")) // Rurtalbahn + return 'R' + str; + if (type.equals("STB")) // Süd-Thüringen-Bahn + return 'R' + str; + if (type.equals("HTB")) // Hellertalbahn + return 'R' + str; + if (type.equals("VBG")) // Vogtlandbahn + return 'R' + str; + if (type.equals("VX")) // Vogtland Express + return 'R' + str; + if (type.equals("CB")) // City-Bahn Chemnitz + return 'R' + str; + if (type.equals("VEC")) // VECTUS Verkehrsgesellschaft + return 'R' + str; + if (type.equals("HzL")) // Hohenzollerische Landesbahn + return 'R' + str; + if (type.equals("OSB")) // Ortenau-S-Bahn + return 'R' + str; + if (type.equals("SBB")) // SBB + return 'R' + str; + if (type.equals("MBB")) // Mecklenburgische Bäderbahn Molli + return 'R' + str; + if (type.equals("OS")) // Regionalbahn + return 'R' + str; + if (type.equals("SP")) + return 'R' + str; + if (type.equals("Dab")) // Daadetalbahn + return 'R' + str; + if (type.equals("FEG")) // Freiberger Eisenbahngesellschaft + return 'R' + str; + if (type.equals("ARR")) // ARRIVA + return 'R' + str; + if (type.equals("HSB")) // Harzer Schmalspurbahn + return 'R' + str; + if (type.equals("SBE")) // Sächsisch-Böhmische Eisenbahngesellschaft + return 'R' + str; + if (type.equals("ALX")) // Arriva-Länderbahn-Express + return 'R' + str; + if (type.equals("MEr")) // metronom regional + return 'R' + str; + if (type.equals("AKN")) // AKN Eisenbahn + return 'R' + str; + if (type.equals("ZUG")) // Regionalbahn + return 'R' + str; + if (type.equals("SOE")) // Sächsisch-Oberlausitzer Eisenbahngesellschaft + return 'R' + str; + if (type.equals("VIA")) // VIAS + return 'R' + str; + if (type.equals("BRB")) // Bayerische Regiobahn + return 'R' + str; + if (type.equals("BLB")) // Berchtesgadener Land Bahn + return 'R' + str; + if (type.equals("HLB")) // Hessische Landesbahn + return 'R' + str; + if (type.equals("NOB")) // NordOstseeBahn + return 'R' + str; + if (type.equals("WEG")) // Wieslauftalbahn + return 'R' + str; + if (type.equals("NBE")) // Nordbahn Eisenbahngesellschaft + return 'R' + str; + if (type.equals("VEN")) // Rhenus Veniro + return 'R' + str; + if (type.equals("DPN")) // Nahreisezug + return 'R' + str; + if (type.equals("SHB")) // Schleswig-Holstein-Bahn + return 'R' + str; + if (type.equals("RBG")) // Regental Bahnbetriebs GmbH + return 'R' + str; + if (type.equals("BOB")) // Bayerische Oberlandbahn + return 'R' + str; + if (type.equals("SWE")) // Südwestdeutsche Verkehrs AG + return 'R' + str; + if (type.equals("VE")) // Vetter + return 'R' + str; + if (type.equals("SDG")) // Sächsische Dampfeisenbahngesellschaft + return 'R' + str; + if (type.equals("PRE")) // Pressnitztalbahn + return 'R' + str; + + if (type.equals("BSB")) // Breisgau-S-Bahn + return 'S' + str; + + if (P_LINE_U.matcher(type).matches()) + return 'U' + str; + + if (type.equals("RT")) // RegioTram + return 'T' + str; + if (type.equals("STR")) // Nordhausen + return 'T' + str; + + throw new IllegalArgumentException("cannot normalize: " + number); + } + if (t == 1) + return 'S' + number; + if (t == 2) + return 'U' + number; + if (t == 3 || t == 4) + return 'T' + number; + if (t == 5 || t == 6 || t == 7 || t == 10) + return 'B' + number; + if (t == 8) + return 'C' + number; + if (t == 9) + return 'F' + number; + if (t == 11) + return '?' + number; + + throw new IllegalStateException("cannot normalize mot '" + mot + "' number '" + number + "'"); + } public QueryDeparturesResult queryDepartures(final String uri) throws IOException { @@ -142,7 +333,7 @@ public abstract class AbstractEfaProvider implements NetworkProvider XmlPullUtil.jumpToStartTag(pp, null, "odvNameElem"); final int locationId = Integer.parseInt(pp.getAttributeValue(null, "stopID")); - final String location = pp.nextText(); + final String location = normalizeLocationName(pp.nextText()); final Calendar departureTime = new GregorianCalendar(); final List departures = new ArrayList(8); @@ -178,7 +369,7 @@ public abstract class AbstractEfaProvider implements NetworkProvider 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 String destination = normalizeLocationName(pp.getAttributeValue(null, "direction")); final int destinationId = Integer.parseInt(pp.getAttributeValue(null, "destID")); XmlPullUtil.skipRestOfTree(pp); @@ -220,4 +411,11 @@ public abstract class AbstractEfaProvider implements NetworkProvider calendar.set(Calendar.HOUR, Integer.parseInt(pp.getAttributeValue(null, "hour"))); calendar.set(Calendar.MINUTE, Integer.parseInt(pp.getAttributeValue(null, "minute"))); } + + private static final Pattern P_STATION_NAME_WHITESPACE = Pattern.compile("\\s+"); + + private static String normalizeLocationName(final String name) + { + return P_STATION_NAME_WHITESPACE.matcher(name).replaceAll(" "); + } } diff --git a/src/de/schildbach/pte/GvhProvider.java b/src/de/schildbach/pte/GvhProvider.java index 9e8be733..03644edb 100644 --- a/src/de/schildbach/pte/GvhProvider.java +++ b/src/de/schildbach/pte/GvhProvider.java @@ -21,7 +21,6 @@ import java.io.IOException; import java.util.Date; import java.util.HashMap; import java.util.Map; -import java.util.regex.Pattern; /** * @author Andreas Schildbach @@ -82,194 +81,6 @@ public class GvhProvider extends AbstractEfaProvider return uri.toString(); } - private static final Pattern P_LINE_RE = Pattern.compile("RE\\d+"); - private static final Pattern P_LINE_RB = Pattern.compile("RB\\d+"); - private static final Pattern P_LINE_U = Pattern.compile("U\\d+"); - - @Override - protected String parseLine(final String number, final String symbol, final String mot) - { - if (!number.equals(symbol)) - throw new IllegalStateException("number " + number + ", symbol " + symbol); - - final int t = Integer.parseInt(mot); - - if (t == 0) - { - 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("EN")) // Euronight - return 'I' + str; - if (type.equals("IC")) // Intercity - return 'I' + str; - if (type.equals("ICE")) // Intercity Express - return 'I' + str; - if (type.equals("CNL")) // City Night Line - return 'I' + str; - if (type.equals("THA")) // Thalys - return 'I' + str; - if (type.equals("TGV")) // TGV - return 'I' + str; - if (type.equals("RJ")) // railjet - return 'I' + str; - - if (type.equals("IR")) // Interregio - return 'R' + str; - if (type.equals("IRE")) // Interregio-Express - 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("D")) // Schnellzug - 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; - if (type.equals("NEB")) // Niederbarnimer Eisenbahn - return 'R' + str; - if (type.equals("OE")) // Ostdeutsche Eisenbahn - return 'R' + str; - if (type.equals("MR")) // Märkische Regiobahn - return 'R' + str; - if (type.equals("OLA")) // Ostseeland Verkehr - return 'R' + str; - if (type.equals("UBB")) // Usedomer Bäderbahn - return 'R' + str; - if (type.equals("EVB")) // Elbe-Weser - return 'R' + str; - if (type.equals("PEG")) // Prignitzer Eisenbahngesellschaft - return 'R' + str; - if (type.equals("RTB")) // Rurtalbahn - return 'R' + str; - if (type.equals("STB")) // Süd-Thüringen-Bahn - return 'R' + str; - if (type.equals("HTB")) // Hellertalbahn - return 'R' + str; - if (type.equals("VBG")) // Vogtlandbahn - return 'R' + str; - if (type.equals("VX")) // Vogtland Express - return 'R' + str; - if (type.equals("CB")) // City-Bahn Chemnitz - return 'R' + str; - if (type.equals("VEC")) // VECTUS Verkehrsgesellschaft - return 'R' + str; - if (type.equals("HzL")) // Hohenzollerische Landesbahn - return 'R' + str; - if (type.equals("OSB")) // Ortenau-S-Bahn - return 'R' + str; - if (type.equals("SBB")) // SBB - return 'R' + str; - if (type.equals("MBB")) // Mecklenburgische Bäderbahn Molli - return 'R' + str; - if (type.equals("OS")) // Regionalbahn - return 'R' + str; - if (type.equals("SP")) - return 'R' + str; - if (type.equals("Dab")) // Daadetalbahn - return 'R' + str; - if (type.equals("FEG")) // Freiberger Eisenbahngesellschaft - return 'R' + str; - if (type.equals("ARR")) // ARRIVA - return 'R' + str; - if (type.equals("HSB")) // Harzer Schmalspurbahn - return 'R' + str; - if (type.equals("SBE")) // Sächsisch-Böhmische Eisenbahngesellschaft - return 'R' + str; - if (type.equals("ALX")) // Arriva-Länderbahn-Express - return 'R' + str; - if (type.equals("MEr")) // metronom regional - return 'R' + str; - if (type.equals("AKN")) // AKN Eisenbahn - return 'R' + str; - if (type.equals("ZUG")) // Regionalbahn - return 'R' + str; - if (type.equals("SOE")) // Sächsisch-Oberlausitzer Eisenbahngesellschaft - return 'R' + str; - if (type.equals("VIA")) // VIAS - return 'R' + str; - if (type.equals("BRB")) // Bayerische Regiobahn - return 'R' + str; - if (type.equals("BLB")) // Berchtesgadener Land Bahn - return 'R' + str; - if (type.equals("HLB")) // Hessische Landesbahn - return 'R' + str; - if (type.equals("NOB")) // NordOstseeBahn - return 'R' + str; - if (type.equals("WEG")) // Wieslauftalbahn - return 'R' + str; - if (type.equals("NBE")) // Nordbahn Eisenbahngesellschaft - return 'R' + str; - if (type.equals("VEN")) // Rhenus Veniro - return 'R' + str; - if (type.equals("DPN")) // Nahreisezug - return 'R' + str; - if (type.equals("SHB")) // Schleswig-Holstein-Bahn - return 'R' + str; - if (type.equals("RBG")) // Regental Bahnbetriebs GmbH - return 'R' + str; - if (type.equals("BOB")) // Bayerische Oberlandbahn - return 'R' + str; - if (type.equals("SWE")) // Südwestdeutsche Verkehrs AG - return 'R' + str; - if (type.equals("VE")) // Vetter - return 'R' + str; - if (type.equals("SDG")) // Sächsische Dampfeisenbahngesellschaft - return 'R' + str; - - if (type.equals("BSB")) // Breisgau-S-Bahn - return 'S' + str; - - if (P_LINE_U.matcher(type).matches()) - return 'U' + str; - - if (type.equals("RT")) // RegioTram - return 'T' + str; - if (type.equals("STR")) // Nordhausen - return 'T' + 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, String to, Date date, boolean dep, WalkSpeed walkSpeed) throws IOException { diff --git a/src/de/schildbach/pte/LinzProvider.java b/src/de/schildbach/pte/LinzProvider.java index 3b5b5e2f..d2162276 100644 --- a/src/de/schildbach/pte/LinzProvider.java +++ b/src/de/schildbach/pte/LinzProvider.java @@ -59,7 +59,7 @@ public class LinzProvider extends AbstractEfaProvider { return String.format(NEARBY_LATLON_URI, lon, lat); } - + private static final String NEARBY_STATION_URI = API_BASE + "XSLT_DM_REQUEST" + "?outputFormat=XML&mode=direct&coordOutputFormat=WGS84&mergeDep=1&useAllStops=1&name_dm=%s&type_dm=stop&itOptionsActive=1&ptOptionsActive=1&useProxFootSearch=1&excludedMeans=checkbox"; @@ -69,7 +69,7 @@ public class LinzProvider extends AbstractEfaProvider { return String.format(NEARBY_STATION_URI, stationId); } - + public StationLocationResult stationLocation(final String stationId) throws IOException { throw new UnsupportedOperationException(); @@ -103,24 +103,6 @@ public class LinzProvider extends AbstractEfaProvider return uri.toString(); } - @Override - protected String parseLine(final String number, final String symbol, final String mot) - { - if (!number.equals(symbol)) - throw new IllegalStateException("number " + number + ", symbol " + symbol); - - int t = Integer.parseInt(mot); - - if (t == 4) - return 'T' + number; - if (t == 5 || t == 6 || t == 7 || t == 10) - return 'B' + number; - if (t == 8) - return 'C' + number; - - throw new IllegalStateException("cannot normalize mot '" + mot + "' number '" + number + "'"); - } - private static final Map LINES = new HashMap(); static diff --git a/src/de/schildbach/pte/MvvProvider.java b/src/de/schildbach/pte/MvvProvider.java index bf33401a..ed61572e 100644 --- a/src/de/schildbach/pte/MvvProvider.java +++ b/src/de/schildbach/pte/MvvProvider.java @@ -30,14 +30,13 @@ import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; -import de.schildbach.pte.QueryDeparturesResult.Status; - /** * @author Andreas Schildbach */ -public class MvvProvider implements NetworkProvider +public class MvvProvider extends AbstractEfaProvider { public static final String NETWORK_ID = "efa.mvv-muenchen.de"; + private static final String API_BASE = "http://efa.mvv-muenchen.de/mobile/"; private static final long PARSER_DAY_ROLLOVER_THRESHOLD_MS = 12 * 60 * 60 * 1000; private static final String ENCODING = "ISO-8859-1"; @@ -58,9 +57,16 @@ public class MvvProvider implements NetworkProvider private static final Pattern P_AUTOCOMPLETE_COARSE = Pattern.compile("

(.*?)

"); private static final Pattern P_AUTOCOMPLETE_FINE = Pattern.compile(".*?(.*?).*?(.*?).*?(.*?).*?(.*?).*?"); + @Override + protected String autocompleteUri(final CharSequence constraint) + { + return String.format(AUTOCOMPLETE_URI, ParserUtils.urlEncode(constraint.toString(), ENCODING), AUTOCOMPLETE_TYPE); + } + + @Override public List autocompleteStations(final CharSequence constraint) throws IOException { - final String uri = String.format(AUTOCOMPLETE_URI, ParserUtils.urlEncode(constraint.toString(), ENCODING), AUTOCOMPLETE_TYPE); + final String uri = autocompleteUri(constraint); final CharSequence page = ParserUtils.scrape(uri); final List results = new ArrayList(); @@ -97,19 +103,34 @@ public class MvvProvider implements NetworkProvider private static final String NEARBY_LATLON_URI = "http://efa.mvv-muenchen.de/ultralite/XML_DM_REQUEST" + "?mode=direct&coordOutputFormat=WGS84&mergeDep=1&useAllStops=1&name_dm=%2.6f:%2.6f:WGS84&type_dm=coord&itOptionsActive=1&ptOptionsActive=1&useProxFootSearch=1&excludedMeans=checkbox"; + + @Override + protected String nearbyLatLonUri(final double lat, final double lon) + { + return String.format(NEARBY_LATLON_URI, lon, lat); + } + private static final String NEARBY_STATION_URI = "http://efa.mvv-muenchen.de/ultralite/XML_DM_REQUEST" + "?mode=direct&coordOutputFormat=WGS84&mergeDep=1&useAllStops=1&name_dm=%s&type_dm=stop&itOptionsActive=1&ptOptionsActive=1&useProxFootSearch=1&excludedMeans=checkbox"; + + @Override + protected String nearbyStationUri(final String stationId) + { + return String.format(NEARBY_STATION_URI, stationId); + } + private static final Pattern P_NEARBY_COARSE = Pattern.compile("(.*?)"); private static final Pattern P_NEARBY_FINE = Pattern.compile(".*?(.*?).*?.*?(.*?).*?.*?(?:(\\d+),(\\d+).*?)?"); + @Override public List nearbyStations(final String stationId, final double lat, final double lon, final int maxDistance, final int maxStations) throws IOException { String uri; if (lat != 0 || lon != 0) - uri = String.format(NEARBY_LATLON_URI, lon, lat); + uri = nearbyLatLonUri(lat, lon); else if (stationId != null) - uri = String.format(NEARBY_STATION_URI, stationId); + uri = nearbyStationUri(stationId); else throw new IllegalArgumentException("at least one of stationId or lat/lon must be given"); @@ -151,21 +172,6 @@ public class MvvProvider implements NetworkProvider public StationLocationResult stationLocation(final String stationId) throws IOException { throw new UnsupportedOperationException(); - - // private Pattern P_GEO = - // Pattern.compile(".*?var latact = \"(\\d+\\.\\d+)\";.*?var lonact = \"(\\d+\\.\\d+)\";.*?", Pattern.DOTALL); - - // final String urlGeo = - // "http://www.mvv-muenchen.de/de/home/fahrgastinformation/mvv-netz/sis/sdb/googlemaps/index.html?id=" - // + id; - // final CharSequence pageGeo = ParserUtils.scrape(urlGeo); - // final Matcher mGeo = P_GEO.matcher(pageGeo); - // if (mGeo.matches()) - // { - // mvvLat = Double.parseDouble(mGeo.group(1)); - // mvvLon = Double.parseDouble(mGeo.group(2)); - // } - } private static final Map WALKSPEED_MAP = new HashMap(); @@ -186,7 +192,7 @@ public class MvvProvider implements NetworkProvider final DateFormat HOUR_FORMAT = new SimpleDateFormat("H"); final DateFormat MINUTE_FORMAT = new SimpleDateFormat("m"); - final StringBuilder uri = new StringBuilder("http://efa.mvv-muenchen.de/mobile/XSLT_TRIP_REQUEST2"); + final StringBuilder uri = new StringBuilder(API_BASE + "XSLT_TRIP_REQUEST2"); uri.append("?language=de"); uri.append("&sessionID=0"); uri.append("&requestID=0"); @@ -411,10 +417,8 @@ public class MvvProvider implements NetworkProvider final String to = ParserUtils.resolveEntities(mHead.group(2)); // final String via = ParserUtils.resolveEntities(mHead.group(3)); final Date currentDate = parseDate(mHead.group(4), mHead.group(5), mHead.group(6)); - final String linkEarlier = mHead.group(7) != null ? "http://efa.mvv-muenchen.de/mobile/" + ParserUtils.resolveEntities(mHead.group(7)) - : null; - final String linkLater = mHead.group(8) != null ? "http://efa.mvv-muenchen.de/mobile/" + ParserUtils.resolveEntities(mHead.group(8)) - : null; + final String linkEarlier = mHead.group(7) != null ? API_BASE + ParserUtils.resolveEntities(mHead.group(7)) : null; + final String linkLater = mHead.group(8) != null ? API_BASE + ParserUtils.resolveEntities(mHead.group(8)) : null; final List connections = new ArrayList(); final Matcher mConCoarse = P_CONNECTIONS_COARSE.matcher(page); @@ -423,7 +427,7 @@ public class MvvProvider implements NetworkProvider final Matcher mConFine = P_CONNECTIONS_FINE.matcher(mConCoarse.group(1)); if (mConFine.matches()) { - final String link = "http://efa.mvv-muenchen.de/mobile/" + ParserUtils.resolveEntities(mConFine.group(3)); + final String link = API_BASE + ParserUtils.resolveEntities(mConFine.group(3)); if (mConFine.group(6) == null) { @@ -613,100 +617,16 @@ public class MvvProvider implements NetworkProvider return time; } - private static final String DEPARTURE_URL = "http://efa.mvv-muenchen.de/mobile/XSLT_DM_REQUEST?typeInfo_dm=stopID&mode=direct&nameInfo_dm="; - public String departuresQueryUri(final String stationId, final int maxDepartures) { - return DEPARTURE_URL + stationId; - } - - private static final Pattern P_DEPARTURES_HEAD_COARSE = Pattern.compile(".*?(.*?Linie/Richtung.*?).*?", Pattern.DOTALL); - private static final Pattern P_DEPARTURES_HEAD_FINE = Pattern.compile(".*?" // - + "Von:[\\xa0\\s]*(.*?)
.*?" // location - + "Datum:[\\xa0\\s]*\\w{2}\\.,\\s(\\d+)\\.\\s(\\w{3,4})\\.[\\xa0\\s]+(\\d{4})
.*?" // date - , Pattern.DOTALL); - private static final Pattern P_DEPARTURES_COARSE = Pattern.compile("(.+?)", Pattern.DOTALL); - private static final Pattern P_DEPARTURES_FINE = Pattern.compile(".*?" // - + "(?:[\\xa0\\s]*[\\xa0\\s]*(\\d+)\\.(\\d+)\\.[\\xa0\\s]*)?" // date - + "(\\d{1,2}):(\\d{2}).*?" // time - + "(?:\"(.*?)\".*?)?" // product - + "\\s*([^<]*?)[\\xa0\\s]*(?:.*?)?" // line - + "
\\s*(.*?)\\s*
.*?" // destination - , Pattern.DOTALL); - private static final Pattern P_DEPARTURES_URI_STATION_ID = Pattern.compile("nameInfo_dm=(\\d+)"); - - public QueryDeparturesResult queryDepartures(final String uri) throws IOException - { - final CharSequence page = ParserUtils.scrape(uri); - - final Matcher mStationId = P_DEPARTURES_URI_STATION_ID.matcher(uri); - if (!mStationId.find()) - throw new IllegalStateException(uri); - final int stationId = Integer.parseInt(mStationId.group(1)); - - final Matcher mHeadCoarse = P_DEPARTURES_HEAD_COARSE.matcher(page); - if (mHeadCoarse.matches()) - { - final Matcher mHeadFine = P_DEPARTURES_HEAD_FINE.matcher(mHeadCoarse.group(1)); - if (mHeadFine.matches()) - { - final String location = ParserUtils.resolveEntities(mHeadFine.group(1)); - final Date currentTime = parseDate(mHeadFine.group(2), mHeadFine.group(3), mHeadFine.group(4)); - final List departures = new ArrayList(8); - - final Calendar calendar = new GregorianCalendar(); - - final Matcher mDepCoarse = P_DEPARTURES_COARSE.matcher(mHeadCoarse.group(1)); - while (mDepCoarse.find()) - { - final Matcher mDepFine = P_DEPARTURES_FINE.matcher(mDepCoarse.group(1)); - if (mDepFine.matches()) - { - calendar.setTime(currentTime); - final String day = mDepFine.group(1); - if (day != null) - calendar.set(Calendar.DAY_OF_MONTH, Integer.parseInt(day)); - final String month = mDepFine.group(2); - if (month != null) - calendar.set(Calendar.MONTH, Integer.parseInt(month) - 1); - calendar.set(Calendar.HOUR_OF_DAY, Integer.parseInt(mDepFine.group(3))); - calendar.set(Calendar.MINUTE, Integer.parseInt(mDepFine.group(4))); - - final String normalizedLine = normalizeLine(mDepFine.group(5), mDepFine.group(6)); - - final String destination = normalizeStationName(mDepFine.group(7)); - - final String position = null; // TODO - - final Departure departure = new Departure(calendar.getTime(), normalizedLine, LINES.get(normalizedLine), position, 0, - destination); - - departures.add(departure); - } - else - { - throw new IllegalArgumentException("cannot parse '" + mDepCoarse.group(1) + "' on " + uri); - } - } - - return new QueryDeparturesResult(uri, stationId, location, departures); - } - else - { - throw new IllegalArgumentException("cannot parse '" + mHeadCoarse.group(1) + "' on " + uri); - } - } - else - { - return new QueryDeparturesResult(uri, Status.NO_INFO); - } - } - - private static final Pattern P_STATION_NAME_WHITESPACE = Pattern.compile("\\s+"); - - private String normalizeStationName(String name) - { - return P_STATION_NAME_WHITESPACE.matcher(name).replaceAll(" "); + 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(); } private static final Pattern P_NORMALIZE_LINE_TRAM = Pattern.compile("[12]\\d");