diff --git a/src/de/schildbach/pte/AbstractEfaProvider.java b/src/de/schildbach/pte/AbstractEfaProvider.java new file mode 100644 index 00000000..a901282a --- /dev/null +++ b/src/de/schildbach/pte/AbstractEfaProvider.java @@ -0,0 +1,115 @@ +/* + * 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 . + */ + +package de.schildbach.pte; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * @author Andreas Schildbach + */ +public abstract class AbstractEfaProvider implements NetworkProvider +{ + private static final Pattern P_AUTOCOMPLETE = Pattern.compile("" // + + "(?:" // + + "]* nameWithPlace=\"([^\"]*)\"" // + + "|" // + + "]* locality=\"([^\"]*)\"" // + + ")"); + + protected abstract String autocompleteUri(final CharSequence constraint); + + public List autocompleteStations(final CharSequence constraint) throws IOException + { + final CharSequence page = ParserUtils.scrape(autocompleteUri(constraint)); + + final List results = new ArrayList(); + + final Matcher m = P_AUTOCOMPLETE.matcher(page); + while (m.find()) + { + if (m.group(1) != null) + { + final int sId = Integer.parseInt(m.group(1)); + // final double sLon = latLonToDouble(Integer.parseInt(mAutocomplete.group(2))); + // final double sLat = latLonToDouble(Integer.parseInt(mAutocomplete.group(3))); + final String sName = m.group(4).trim(); + results.add(new Autocomplete(LocationType.STATION, sId, sName)); + } + else if (m.group(5) != null) + { + final String sName = m.group(5).trim(); + results.add(new Autocomplete(LocationType.ANY, 0, sName)); + } + } + + return results; + } + + private static final Pattern P_NEARBY = Pattern.compile("]*? nameWithPlace=\"([^\"]*)\" distance=\"(\\d+)\"" // + + "|distance=\"(\\d+)\" [^>]*? nameWithPlace=\"([^\"]*)\" [^>]*? stopID=\"(\\d+)\" [^>]*? x=\"(\\d+)\" y=\"(\\d+)\"" // + + ")"); + + protected abstract String nearbyLatLonUri(double lat, double lon); + + protected abstract String nearbyStationUri(String stationId); + + public List nearbyStations(final String stationId, final double lat, final double lon, final int maxDistance, final int maxStations) + throws IOException + { + String uri = null; + if (lat != 0 || lon != 0) + uri = nearbyLatLonUri(lat, lon); + if (uri == null && stationId != null) + uri = nearbyStationUri(stationId); + if (uri == null) + 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(); + + final Matcher mNearby = P_NEARBY.matcher(page); + while (mNearby.find()) + { + final boolean firstSyntax = mNearby.group(1) != null; + final int sId = Integer.parseInt(mNearby.group(firstSyntax ? 1 : 8)); + final double sLon = latLonToDouble(Integer.parseInt(mNearby.group(firstSyntax ? 2 : 9))); + final double sLat = latLonToDouble(Integer.parseInt(mNearby.group(firstSyntax ? 3 : 10))); + final String sName = mNearby.group(firstSyntax ? 4 : 7).trim(); + final int sDist = Integer.parseInt(mNearby.group(firstSyntax ? 5 : 6)); + + final Station station = new Station(sId, sName, sLat, sLon, sDist, null, null); + stations.add(station); + } + + if (maxStations == 0 || maxStations >= stations.size()) + return stations; + else + return stations.subList(0, maxStations); + } + + private static double latLonToDouble(final int value) + { + return (double) value / 1000000; + } +} diff --git a/src/de/schildbach/pte/GvhProvider.java b/src/de/schildbach/pte/GvhProvider.java new file mode 100644 index 00000000..5c41d1b0 --- /dev/null +++ b/src/de/schildbach/pte/GvhProvider.java @@ -0,0 +1,95 @@ +/* + * 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 . + */ + +package de.schildbach.pte; + +import java.io.IOException; +import java.util.Date; + +/** + * @author Andreas Schildbach + */ +public class GvhProvider extends AbstractEfaProvider +{ + private static final String API_BASE = "http://mobil.gvh.de/mobile2/"; + + 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"; + + @Override + protected String autocompleteUri(final CharSequence constraint) + { + return String.format(AUTOCOMPLETE_URI, ParserUtils.urlEncode(constraint.toString(), ENCODING)); + } + + private static final String NEARBY_STATION_URI = API_BASE + + "XSLT_DM_REQUEST?outputFormat=XML&coordOutputFormat=WGS84&name_dm=%s&type_dm=stop&itOptionsActive=1&ptOptionsActive=1&useProxFootSearch=1&mergeDep=1&useAllStops=1&mode=direct"; + + @Override + protected String nearbyStationUri(final String stationId) + { + return String.format(NEARBY_STATION_URI, stationId); + } + + @Override + protected String nearbyLatLonUri(final double lat, final double lon) + { + return null; + } + + public String departuresQueryUri(String stationId, int maxDepartures) + { + throw new UnsupportedOperationException(); + } + + public GetConnectionDetailsResult getConnectionDetails(String connectionUri) throws IOException + { + throw new UnsupportedOperationException(); + } + + public boolean hasCapabilities(Capability... capabilities) + { + throw new UnsupportedOperationException(); + } + + public int[] lineColors(String line) + { + throw new UnsupportedOperationException(); + } + + public QueryConnectionsResult queryConnections(LocationType fromType, String from, LocationType viaType, String via, LocationType toType, + String to, Date date, boolean dep, WalkSpeed walkSpeed) throws IOException + { + 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 + { + throw new UnsupportedOperationException(); + } +} diff --git a/src/de/schildbach/pte/LinzProvider.java b/src/de/schildbach/pte/LinzProvider.java index 07f710c2..e24fb795 100644 --- a/src/de/schildbach/pte/LinzProvider.java +++ b/src/de/schildbach/pte/LinzProvider.java @@ -31,7 +31,7 @@ import java.util.regex.Pattern; /** * @author Andreas Schildbach */ -public class LinzProvider implements NetworkProvider +public class LinzProvider extends AbstractEfaProvider { public static final String NETWORK_ID = "www.linzag.at"; public static final String API_BASE = "http://www.linzag.at/linz/"; @@ -48,90 +48,34 @@ public class LinzProvider implements NetworkProvider private static final String AUTOCOMPLETE_URI = API_BASE + "XML_STOPFINDER_REQUEST" + "?outputFormat=XML&coordOutputFormat=WGS84&name_sf=%s&type_sf=%s"; private static final String AUTOCOMPLETE_TYPE = "any"; // any, stop, street, poi - private static final Pattern P_AUTOCOMPLETE = Pattern.compile("" // - + "(?:" // - + "]* nameWithPlace=\"([^\"]*)\"" // - + "|" // - + "]* locality=\"([^\"]*)\"" // - + ")"); private static final String ENCODING = "ISO-8859-1"; - public List autocompleteStations(final CharSequence constraint) throws IOException + @Override + protected String autocompleteUri(final CharSequence constraint) { - final String uri = String.format(AUTOCOMPLETE_URI, ParserUtils.urlEncode(constraint.toString(), ENCODING), AUTOCOMPLETE_TYPE); - final CharSequence page = ParserUtils.scrape(uri); - - final List results = new ArrayList(); - - final Matcher m = P_AUTOCOMPLETE.matcher(page); - while (m.find()) - { - if (m.group(1) != null) - { - final int sId = Integer.parseInt(m.group(1)); - // final double sLon = latLonToDouble(Integer.parseInt(mAutocomplete.group(2))); - // final double sLat = latLonToDouble(Integer.parseInt(mAutocomplete.group(3))); - final String sName = m.group(4).trim(); - results.add(new Autocomplete(LocationType.STATION, sId, sName)); - } - else if (m.group(5) != null) - { - final String sName = m.group(5).trim(); - results.add(new Autocomplete(LocationType.ANY, 0, sName)); - } - } - - return results; + return String.format(AUTOCOMPLETE_URI, ParserUtils.urlEncode(constraint.toString(), ENCODING), AUTOCOMPLETE_TYPE); } private static final String NEARBY_LATLON_URI = API_BASE + "XSLT_DM_REQUEST" + "?outputFormat=XML&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 = 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"; - private static final Pattern P_NEARBY = Pattern - .compile("]* nameWithPlace=\"([^\"]*)\" distance=\"(\\d+)\""); - public List nearbyStations(final String stationId, final double lat, final double lon, final int maxDistance, final int maxStations) - throws IOException + @Override + protected String nearbyStationUri(final String stationId) { - 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(); - - final Matcher mNearby = P_NEARBY.matcher(page); - while (mNearby.find()) - { - final int sId = Integer.parseInt(mNearby.group(1)); - final double sLon = latLonToDouble(Integer.parseInt(mNearby.group(2))); - final double sLat = latLonToDouble(Integer.parseInt(mNearby.group(3))); - final String sName = mNearby.group(4).trim(); - final int sDist = Integer.parseInt(mNearby.group(5)); - - final Station station = new Station(sId, sName, sLat, sLon, sDist, null, null); - stations.add(station); - } - - if (maxStations == 0 || maxStations >= stations.size()) - return stations; - else - return stations.subList(0, maxStations); + return String.format(NEARBY_STATION_URI, stationId); } - - private static double latLonToDouble(int value) - { - return (double) value / 1000000; - } - + public StationLocationResult stationLocation(final String stationId) throws IOException { throw new UnsupportedOperationException();