From 9f5e01151159d84494147d00098631caf9e336f0 Mon Sep 17 00:00:00 2001 From: "andreas.schildbach" Date: Mon, 20 Sep 2010 12:00:20 +0000 Subject: [PATCH] scan stations nearby given station (rather than just lat/lon) git-svn-id: https://public-transport-enabler.googlecode.com/svn/trunk@169 0924bc21-9374-b0fa-ee44-9ff1593b38f0 --- src/de/schildbach/pte/BahnProvider.java | 10 ++-- src/de/schildbach/pte/MvvProvider.java | 22 +++++--- src/de/schildbach/pte/NetworkProvider.java | 10 ++-- src/de/schildbach/pte/OebbProvider.java | 38 ++++++++++++- src/de/schildbach/pte/RmvProvider.java | 62 ++++++++++++++++++---- src/de/schildbach/pte/SbbProvider.java | 46 +++++++++++++++- src/de/schildbach/pte/SncbProvider.java | 46 +++++++++++++++- src/de/schildbach/pte/TflProvider.java | 3 +- src/de/schildbach/pte/VbbProvider.java | 3 +- 9 files changed, 208 insertions(+), 32 deletions(-) diff --git a/src/de/schildbach/pte/BahnProvider.java b/src/de/schildbach/pte/BahnProvider.java index 5aa36ddb..5ae7fa0a 100644 --- a/src/de/schildbach/pte/BahnProvider.java +++ b/src/de/schildbach/pte/BahnProvider.java @@ -79,14 +79,18 @@ public final class BahnProvider implements NetworkProvider private final static Pattern P_NEARBY_STATIONS = Pattern .compile("(.+?)"); - public List nearbyStations(final double lat, final double lon, final int maxDistance, final int maxStations) throws IOException + public List nearbyStations(final String stationId, final double lat, final double lon, final int maxDistance, final int maxStations) + throws IOException { + if (lat == 0 && lon == 0) + throw new IllegalArgumentException("lat/lon must be given"); + + final List stations = new ArrayList(); + final String url = "http://mobile.bahn.de/bin/mobil/query.exe/dox" + "?performLocating=2&tpl=stopsnear&look_maxdist=" + (maxDistance > 0 ? maxDistance : 5000) + "&look_stopclass=1023" + "&look_x=" + latLonToInt(lon) + "&look_y=" + latLonToInt(lat); final CharSequence page = ParserUtils.scrape(url); - final List stations = new ArrayList(); - final Matcher m = P_NEARBY_STATIONS.matcher(page); while (m.find()) { diff --git a/src/de/schildbach/pte/MvvProvider.java b/src/de/schildbach/pte/MvvProvider.java index 47952a0b..6d4399fc 100644 --- a/src/de/schildbach/pte/MvvProvider.java +++ b/src/de/schildbach/pte/MvvProvider.java @@ -91,14 +91,24 @@ public class MvvProvider implements NetworkProvider return results; } - private static final String NEARBY_URI = "http://efa.mvv-muenchen.de/ultralite/XML_DM_REQUEST" + 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"; + private final String NEARBY_STATION_URI = "http://efa.mvv-muenchen.de/ultralite/XML_DM_REQUEST" + + "?mode=direct&coordOutputFormat=WGS84&mergeDep=1&useAllStops=1&name_dm=%d&type_dm=stop&itOptionsActive=1&ptOptionsActive=1&useProxFootSearch=1&excludedMeans=checkbox"; private static final Pattern P_NEARBY_COARSE = Pattern.compile("(.*?)"); - private static final Pattern P_NEARBY_FINE = Pattern.compile(".*?(.*?).*?.*?(.*?).*?.*?(\\d+),(\\d+).*?"); + private static final Pattern P_NEARBY_FINE = Pattern.compile(".*?(.*?).*?.*?(.*?).*?.*?(?:(\\d+),(\\d+).*?)?"); - public List nearbyStations(final double lat, final double lon, final int maxDistance, final int maxStations) throws IOException + public List nearbyStations(final String stationId, final double lat, final double lon, final int maxDistance, final int maxStations) + throws IOException { - final String uri = String.format(NEARBY_URI, lon, lat); + String uri; + if (lat != 0 || lon != 0) + uri = String.format(NEARBY_LATLON_URI, lon, lat); + else if (stationId != null) + uri = String.format(NEARBY_STATION_URI, stationId); + else + throw new IllegalArgumentException("at least one of stationId or lat/lon must be given"); + final CharSequence page = ParserUtils.scrape(uri); final List stations = new ArrayList(); @@ -111,8 +121,8 @@ public class MvvProvider implements NetworkProvider { final String sName = mNearbyFine.group(1).trim(); final int sId = Integer.parseInt(mNearbyFine.group(2)); - final double sLon = latLonToDouble(Integer.parseInt(mNearbyFine.group(3))); - final double sLat = latLonToDouble(Integer.parseInt(mNearbyFine.group(4))); + final double sLon = mNearbyFine.group(3) != null ? latLonToDouble(Integer.parseInt(mNearbyFine.group(3))) : 0; + final double sLat = mNearbyFine.group(4) != null ? latLonToDouble(Integer.parseInt(mNearbyFine.group(4))) : 0; final Station station = new Station(sId, sName, sLat, sLon, 0, null, null); stations.add(station); diff --git a/src/de/schildbach/pte/NetworkProvider.java b/src/de/schildbach/pte/NetworkProvider.java index d4f23552..8a4cd6d1 100644 --- a/src/de/schildbach/pte/NetworkProvider.java +++ b/src/de/schildbach/pte/NetworkProvider.java @@ -56,12 +56,14 @@ public interface NetworkProvider List autocompleteStations(CharSequence constraint) throws IOException; /** - * Determine stations near to given location + * Determine stations near to given location. At least one of stationId or lat/lon pair must be given. * + * @param stationId + * id of station to look up nearby stations (optional) * @param lat - * latitude + * latitude (optional) * @param lon - * longitude + * longitude (optional) * @param maxDistance * maximum distance in meters, or {@code 0} * @param maxStations @@ -69,7 +71,7 @@ public interface NetworkProvider * @return nearby stations * @throws IOException */ - List nearbyStations(double lat, double lon, int maxDistance, int maxStations) throws IOException; + List nearbyStations(String stationId, double lat, double lon, int maxDistance, int maxStations) throws IOException; /** * Look up location of station. diff --git a/src/de/schildbach/pte/OebbProvider.java b/src/de/schildbach/pte/OebbProvider.java index 7ebafb3d..c328a038 100644 --- a/src/de/schildbach/pte/OebbProvider.java +++ b/src/de/schildbach/pte/OebbProvider.java @@ -56,9 +56,43 @@ public class OebbProvider implements NetworkProvider return results; } - public List nearbyStations(final double lat, final double lon, final int maxDistance, final int maxStations) throws IOException + private final String NEARBY_URI = "http://fahrplan.oebb.at/bin/stboard.exe/dn?distance=50&near=Suchen&input=%d"; + private final static Pattern P_NEARBY_COARSE = Pattern.compile("(.*?)", Pattern.DOTALL); + private final static Pattern P_NEARBY_FINE = Pattern.compile(".*?stboard\\.exe/.*?&input=.*?%23(\\d+)&.*?>(.*?).*?", Pattern.DOTALL); + + public List nearbyStations(final String stationId, final double lat, final double lon, final int maxDistance, final int maxStations) + throws IOException { - throw new UnsupportedOperationException(); + if (stationId == null) + throw new IllegalArgumentException("stationId must be given"); + + final List stations = new ArrayList(); + + final String uri = String.format(NEARBY_URI, stationId); + final CharSequence page = ParserUtils.scrape(uri); + + final Matcher mCoarse = P_NEARBY_COARSE.matcher(page); + while (mCoarse.find()) + { + final Matcher mFine = P_NEARBY_FINE.matcher(mCoarse.group(1)); + if (mFine.matches()) + { + final int parsedId = Integer.parseInt(mFine.group(1)); + final String parsedName = ParserUtils.resolveEntities(mFine.group(2)); + + final Station station = new Station(parsedId, parsedName, 0, 0, 0, null, null); + stations.add(station); + } + else + { + throw new IllegalArgumentException("cannot parse '" + mCoarse.group(1) + "' on " + uri); + } + } + + if (maxStations == 0 || maxStations >= stations.size()) + return stations; + else + return stations.subList(0, maxStations); } public StationLocationResult stationLocation(final String stationId) throws IOException diff --git a/src/de/schildbach/pte/RmvProvider.java b/src/de/schildbach/pte/RmvProvider.java index 3d5b71f3..c8783fd1 100644 --- a/src/de/schildbach/pte/RmvProvider.java +++ b/src/de/schildbach/pte/RmvProvider.java @@ -81,22 +81,62 @@ public class RmvProvider implements NetworkProvider private final static Pattern P_NEARBY_STATIONS = Pattern.compile("\\n" + "(.+?)\\s*\\((\\d+) m/[A-Z]+\\)\\n", Pattern.DOTALL); - public List nearbyStations(final double lat, final double lon, final int maxDistance, final int maxStations) throws IOException - { - final String url = "http://www.rmv.de/auskunft/bin/jp/stboard.exe/dox?input=" + lat + "%20" + lon; - final CharSequence page = ParserUtils.scrape(url); + private final String NEARBY_URI = "http://www.rmv.de/auskunft/bin/jp/stboard.exe/dn?L=vs_rmv&distance=50&near&input=%d"; + private final static Pattern P_NEARBY_COARSE = Pattern.compile("(.*?)", Pattern.DOTALL); + private final static Pattern P_NEARBY_FINE = Pattern.compile(".*?auskunft/bin/jp/stboard\\.exe/dn\\?L=vs_rmv&input=(\\d+).*?" + + "&REQMapRoute0\\.Location0\\.X=(-?\\d+)&REQMapRoute0\\.Location0\\.Y=(-?\\d+)" // + + "&REQMapRoute0\\.Location0\\.Name=(.*?)\">.*?", Pattern.DOTALL); + public List nearbyStations(final String stationId, final double lat, final double lon, final int maxDistance, final int maxStations) + throws IOException + { final List stations = new ArrayList(); - final Matcher m = P_NEARBY_STATIONS.matcher(page); - while (m.find()) + if (lat != 0 || lon != 0) { - final int sId = Integer.parseInt(m.group(1)); - final String sName = ParserUtils.resolveEntities(m.group(2)); - final int sDist = Integer.parseInt(m.group(3)); + final String url = "http://www.rmv.de/auskunft/bin/jp/stboard.exe/dox?input=" + lat + "%20" + lon; + final CharSequence page = ParserUtils.scrape(url); - final Station station = new Station(sId, sName, 0, 0, sDist, null, null); - stations.add(station); + final Matcher m = P_NEARBY_STATIONS.matcher(page); + while (m.find()) + { + final int sId = Integer.parseInt(m.group(1)); + final String sName = ParserUtils.resolveEntities(m.group(2)); + final int sDist = Integer.parseInt(m.group(3)); + + final Station station = new Station(sId, sName, 0, 0, sDist, null, null); + stations.add(station); + } + } + else if (stationId != null) + { + final String uri = String.format(NEARBY_URI, stationId); + + final CharSequence page = ParserUtils.scrape(uri); + + final Matcher mCoarse = P_NEARBY_COARSE.matcher(page); + while (mCoarse.find()) + { + final Matcher mFine = P_NEARBY_FINE.matcher(mCoarse.group(1)); + if (mFine.matches()) + { + final int parsedId = Integer.parseInt(mFine.group(1)); + final double parsedLon = latLonToDouble(Integer.parseInt(mFine.group(2))); + final double parsedLat = latLonToDouble(Integer.parseInt(mFine.group(3))); + final String parsedName = ParserUtils.resolveEntities(mFine.group(4)); + + final Station station = new Station(parsedId, parsedName, parsedLat, parsedLon, 0, null, null); + stations.add(station); + } + else + { + throw new IllegalArgumentException("cannot parse '" + mCoarse.group(1) + "' on " + uri); + } + } + } + else + { + throw new IllegalArgumentException("at least one of stationId or lat/lon must be given"); } if (maxStations == 0 || maxStations >= stations.size()) diff --git a/src/de/schildbach/pte/SbbProvider.java b/src/de/schildbach/pte/SbbProvider.java index 22627dcc..3db67992 100644 --- a/src/de/schildbach/pte/SbbProvider.java +++ b/src/de/schildbach/pte/SbbProvider.java @@ -78,9 +78,51 @@ public class SbbProvider implements NetworkProvider return results; } - public List nearbyStations(final double lat, final double lon, final int maxDistance, final int maxStations) throws IOException + private final static String NEARBY_URI = "http://fahrplan.sbb.ch/bin/bhftafel.exe/dn?input=%d&distance=50&near=Anzeigen"; + private final static Pattern P_NEARBY_COARSE = Pattern.compile("(.*?)", Pattern.DOTALL); + private final static Pattern P_NEARBY_FINE = Pattern.compile(".*?&REQMapRoute0\\.Location0\\.X=(-?\\d+)&REQMapRoute0\\.Location0\\.Y=(-?\\d+)" + + "&REQMapRoute0\\.Location0\\.Name=(.*?)&sturl=.*?dn\\?input=(\\d+).*?", Pattern.DOTALL); + + public List nearbyStations(final String stationId, final double lat, final double lon, final int maxDistance, final int maxStations) + throws IOException { - throw new UnsupportedOperationException(); + if (stationId == null) + throw new IllegalArgumentException("stationId must be given"); + + final List stations = new ArrayList(); + + final String uri = String.format(NEARBY_URI, stationId); + final CharSequence page = ParserUtils.scrape(uri); + + final Matcher mCoarse = P_NEARBY_COARSE.matcher(page); + while (mCoarse.find()) + { + final Matcher mFine = P_NEARBY_FINE.matcher(mCoarse.group(1)); + if (mFine.matches()) + { + final double parsedLon = latLonToDouble(Integer.parseInt(mFine.group(1))); + final double parsedLat = latLonToDouble(Integer.parseInt(mFine.group(2))); + final String parsedName = ParserUtils.resolveEntities(mFine.group(3)); + final int parsedId = Integer.parseInt(mFine.group(4)); + + final Station station = new Station(parsedId, parsedName, parsedLat, parsedLon, 0, null, null); + stations.add(station); + } + else + { + throw new IllegalArgumentException("cannot parse '" + mCoarse.group(1) + "' on " + uri); + } + } + + if (maxStations == 0 || maxStations >= stations.size()) + return stations; + else + return stations.subList(0, maxStations); + } + + private static double latLonToDouble(int value) + { + return (double) value / 1000000; } public StationLocationResult stationLocation(final String stationId) throws IOException diff --git a/src/de/schildbach/pte/SncbProvider.java b/src/de/schildbach/pte/SncbProvider.java index 0219dc60..2a74b150 100644 --- a/src/de/schildbach/pte/SncbProvider.java +++ b/src/de/schildbach/pte/SncbProvider.java @@ -27,9 +27,51 @@ public class SncbProvider implements NetworkProvider throw new UnsupportedOperationException(); } - public List nearbyStations(final double lat, final double lon, final int maxDistance, final int maxStations) throws IOException + private final String NEARBY_URI = "http://hari.b-rail.be/HAFAS/bin/stboard.exe/en?input=%d&distance=50&near=Anzeigen"; + private final static Pattern P_NEARBY_COARSE = Pattern.compile("(.*?)", Pattern.DOTALL); + private final static Pattern P_NEARBY_FINE = Pattern.compile(".*?&REQMapRoute0\\.Location0\\.X=(-?\\d+)&REQMapRoute0\\.Location0\\.Y=(-?\\d+)" + + "&REQMapRoute0\\.Location0\\.Name=(.*?)\">.*?en\\?input=(\\d+).*?", Pattern.DOTALL); + + public List nearbyStations(final String stationId, final double lat, final double lon, final int maxDistance, final int maxStations) + throws IOException { - throw new UnsupportedOperationException(); + if (stationId == null) + throw new IllegalArgumentException("stationId must be given"); + + final List stations = new ArrayList(); + + final String uri = String.format(NEARBY_URI, stationId); + final CharSequence page = ParserUtils.scrape(uri); + + final Matcher mCoarse = P_NEARBY_COARSE.matcher(page); + while (mCoarse.find()) + { + final Matcher mFine = P_NEARBY_FINE.matcher(mCoarse.group(1)); + if (mFine.matches()) + { + final double parsedLon = latLonToDouble(Integer.parseInt(mFine.group(1))); + final double parsedLat = latLonToDouble(Integer.parseInt(mFine.group(2))); + final String parsedName = ParserUtils.resolveEntities(mFine.group(3)); + final int parsedId = Integer.parseInt(mFine.group(4)); + + final Station station = new Station(parsedId, parsedName, parsedLat, parsedLon, 0, null, null); + stations.add(station); + } + else + { + throw new IllegalArgumentException("cannot parse '" + mCoarse.group(1) + "' on " + uri); + } + } + + if (maxStations == 0 || maxStations >= stations.size()) + return stations; + else + return stations.subList(0, maxStations); + } + + private static double latLonToDouble(int value) + { + return (double) value / 1000000; } public StationLocationResult stationLocation(final String stationId) throws IOException diff --git a/src/de/schildbach/pte/TflProvider.java b/src/de/schildbach/pte/TflProvider.java index e86d99e4..4bd5c23d 100644 --- a/src/de/schildbach/pte/TflProvider.java +++ b/src/de/schildbach/pte/TflProvider.java @@ -45,7 +45,8 @@ public class TflProvider implements NetworkProvider throw new UnsupportedOperationException(); } - public List nearbyStations(final double lat, final double lon, final int maxDistance, final int maxStations) throws IOException + public List nearbyStations(final String stationId, final double lat, final double lon, final int maxDistance, final int maxStations) + throws IOException { throw new UnsupportedOperationException(); } diff --git a/src/de/schildbach/pte/VbbProvider.java b/src/de/schildbach/pte/VbbProvider.java index 4e973226..72f33781 100644 --- a/src/de/schildbach/pte/VbbProvider.java +++ b/src/de/schildbach/pte/VbbProvider.java @@ -96,7 +96,8 @@ public final class VbbProvider implements NetworkProvider return results; } - public List nearbyStations(final double lat, final double lon, final int maxDistance, final int maxStations) throws IOException + public List nearbyStations(final String stationId, final double lat, final double lon, final int maxDistance, final int maxStations) + throws IOException { throw new UnsupportedOperationException(); }