diff --git a/src/de/schildbach/pte/BahnProvider.java b/src/de/schildbach/pte/BahnProvider.java index 234fdaab..1a60afdc 100644 --- a/src/de/schildbach/pte/BahnProvider.java +++ b/src/de/schildbach/pte/BahnProvider.java @@ -160,8 +160,8 @@ public final class BahnProvider implements NetworkProvider private static final Pattern P_CHECK_CONNECTIONS_ERROR = Pattern .compile("(?:(zu dicht beieinander|mehrfach vorhanden oder identisch)|(leider konnte zu Ihrer Anfrage keine Verbindung gefunden werden))"); - public QueryConnectionsResult queryConnections(final String from, final String via, final String to, final Date date, final boolean dep) - throws IOException + public QueryConnectionsResult queryConnections(final LocationType fromType, final String from, final LocationType viaType, final String via, + final LocationType toType, final String to, final Date date, final boolean dep) throws IOException { final String uri = connectionsQueryUri(from, via, to, date, dep); final CharSequence page = ParserUtils.scrape(uri); diff --git a/src/de/schildbach/pte/MvvProvider.java b/src/de/schildbach/pte/MvvProvider.java index 96572a98..fb51bae3 100644 --- a/src/de/schildbach/pte/MvvProvider.java +++ b/src/de/schildbach/pte/MvvProvider.java @@ -86,7 +86,8 @@ public class MvvProvider implements NetworkProvider throw new UnsupportedOperationException(); } - private String connectionsQueryUri(final String from, final String via, final String to, final Date date, final boolean dep) + private String connectionsQueryUri(final LocationType fromType, final String from, final LocationType viaType, final String via, + final LocationType toType, final String to, final Date date, final boolean dep) { final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyyMMdd"); final DateFormat YEAR_FORMAT = new SimpleDateFormat("yyyy"); @@ -115,51 +116,83 @@ public class MvvProvider implements NetworkProvider uri.append("&itdDateMonth=").append(ParserUtils.urlEncode(MONTH_FORMAT.format(date))); uri.append("&itdDateYear=").append(ParserUtils.urlEncode(YEAR_FORMAT.format(date))); uri.append("&locationServerActive=1"); - uri.append("&useProxFootSearch=1"); // Take stops close to the stop/start into account and possibly use them - // instead + uri.append("&useProxFootSearch=1"); // Take nearby stops into account and possibly use them instead uri.append("&anySigWhenPerfectNoOtherMatches=1"); uri.append("&lineRestriction=403"); - uri.append("&useHouseNumberList_origin=1"); - uri.append("&place_origin="); // coarse-grained location, e.g. city - uri.append("&placeState_origin=empty"); // empty|identified - uri.append("&nameState_origin=empty"); // empty|identified|list|notidentified - uri.append("&placeInfo_origin=invalid"); // invalid - uri.append("&nameInfo_origin=invalid"); // invalid - uri.append("&typeInfo_origin=invalid"); // invalid - uri.append("&reducedAnyWithoutAddressObjFilter_origin=102"); - uri.append("&reducedAnyPostcodeObjFilter_origin=64"); - uri.append("&reducedAnyTooManyObjFilter_origin=2"); - uri.append("&type_origin=stop"); // any|stop|poi|address - uri.append("&name_origin=").append(ParserUtils.urlEncode(from, ENCODING)); // fine-grained location + if (fromType == LocationType.WGS84) + { + final String[] parts = from.split(","); + final double lat = Double.parseDouble(parts[0]); + final double lon = Double.parseDouble(parts[1]); + uri.append("&nameInfo_origin=").append(String.format("%2.5f:%2.5f", lon, lat)).append(":WGS84[DD.ddddd]"); + uri.append("&typeInfo_origin=coord"); + } + else + { + uri.append("&useHouseNumberList_origin=1"); + uri.append("&place_origin="); // coarse-grained location, e.g. city + uri.append("&placeState_origin=empty"); // empty|identified + uri.append("&nameState_origin=empty"); // empty|identified|list|notidentified + uri.append("&placeInfo_origin=invalid"); // invalid + uri.append("&nameInfo_origin=invalid"); // invalid + uri.append("&typeInfo_origin=invalid"); // invalid + uri.append("&reducedAnyWithoutAddressObjFilter_origin=102"); + uri.append("&reducedAnyPostcodeObjFilter_origin=64"); + uri.append("&reducedAnyTooManyObjFilter_origin=2"); + uri.append("&type_origin=stop"); // any|stop|poi|address + uri.append("&name_origin=").append(ParserUtils.urlEncode(from, ENCODING)); // fine-grained location + } - uri.append("&useHouseNumberList_destination=1"); - uri.append("&place_destination="); // coarse-grained location, e.g. city - uri.append("&placeState_destination=empty"); // empty|identified - uri.append("&nameState_destination=empty"); // empty|identified|list|notidentified - uri.append("&placeInfo_destination=invalid"); // invalid - uri.append("&nameInfo_destination=invalid"); // invalid - uri.append("&typeInfo_destination=invalid"); // invalid - uri.append("&reducedAnyWithoutAddressObjFilter_destination=102"); - uri.append("&reducedAnyPostcodeObjFilter_destination=64"); - uri.append("&reducedAnyTooManyObjFilter_destination=2"); - uri.append("&type_destination=stop"); // any|stop|poi|address - uri.append("&name_destination=").append(ParserUtils.urlEncode(to, ENCODING)); // fine-grained location + if (toType == LocationType.WGS84) + { + final String[] parts = to.split(","); + final double lat = Double.parseDouble(parts[0]); + final double lon = Double.parseDouble(parts[1]); + uri.append("&nameInfo_destination=").append(String.format("%2.5f:%2.5f", lon, lat)).append(":WGS84[DD.ddddd]"); + uri.append("&typeInfo_destination=coord"); + } + else + { + uri.append("&useHouseNumberList_destination=1"); + uri.append("&place_destination="); // coarse-grained location, e.g. city + uri.append("&placeState_destination=empty"); // empty|identified + uri.append("&nameState_destination=empty"); // empty|identified|list|notidentified + uri.append("&placeInfo_destination=invalid"); // invalid + uri.append("&nameInfo_destination=invalid"); // invalid + uri.append("&typeInfo_destination=invalid"); // invalid + uri.append("&reducedAnyWithoutAddressObjFilter_destination=102"); + uri.append("&reducedAnyPostcodeObjFilter_destination=64"); + uri.append("&reducedAnyTooManyObjFilter_destination=2"); + uri.append("&type_destination=stop"); // any|stop|poi|address + uri.append("&name_destination=").append(ParserUtils.urlEncode(to, ENCODING)); // fine-grained location + } if (via != null) { - uri.append("&useHouseNumberList_via=1"); - uri.append("&place_via="); - uri.append("&placeState_via=empty"); - uri.append("&nameState_via=empty"); - uri.append("&placeInfo_via=invalid"); - uri.append("&nameInfo_via=invalid"); - uri.append("&typeInfo_via=invalid"); - uri.append("&reducedAnyWithoutAddressObjFilter_via=102"); - uri.append("&reducedAnyPostcodeObjFilter_via=64"); - uri.append("&reducedAnyTooManyObjFilter_via=2"); - uri.append("&type_via=stop"); // any - uri.append("&name_via=").append(ParserUtils.urlEncode(via, ENCODING)); + if (viaType == LocationType.WGS84) + { + final String[] parts = via.split(","); + final double lat = Double.parseDouble(parts[0]); + final double lon = Double.parseDouble(parts[1]); + uri.append("&nameInfo_via=").append(String.format("%2.5f:%2.5f", lon, lat)).append(":WGS84[DD.ddddd]"); + uri.append("&typeInfo_via=coord"); + } + else + { + uri.append("&useHouseNumberList_via=1"); + uri.append("&place_via="); + uri.append("&placeState_via=empty"); + uri.append("&nameState_via=empty"); + uri.append("&placeInfo_via=invalid"); + uri.append("&nameInfo_via=invalid"); + uri.append("&typeInfo_via=invalid"); + uri.append("&reducedAnyWithoutAddressObjFilter_via=102"); + uri.append("&reducedAnyPostcodeObjFilter_via=64"); + uri.append("&reducedAnyTooManyObjFilter_via=2"); + uri.append("&type_via=stop"); + uri.append("&name_via=").append(ParserUtils.urlEncode(via, ENCODING)); + } } uri.append("&itdTripDateTimeDepArr=").append(dep ? "dep" : "arr"); @@ -176,10 +209,10 @@ public class MvvProvider implements NetworkProvider private static final Pattern P_CHECK_CONNECTIONS_ERROR = Pattern.compile("(?:(xxxzudichtxxx)|(konnte keine Verbindung gefunden werden))", Pattern.CASE_INSENSITIVE); - public QueryConnectionsResult queryConnections(final String from, final String via, final String to, final Date date, final boolean dep) - throws IOException + public QueryConnectionsResult queryConnections(final LocationType fromType, final String from, final LocationType viaType, final String via, + final LocationType toType, final String to, final Date date, final boolean dep) throws IOException { - final String uri = connectionsQueryUri(from, via, to, date, dep); + final String uri = connectionsQueryUri(fromType, from, viaType, via, toType, to, date, dep); CharSequence page = ParserUtils.scrape(uri); while (page.length() == 0) { diff --git a/src/de/schildbach/pte/NetworkProvider.java b/src/de/schildbach/pte/NetworkProvider.java index 46b041d2..0f69b19d 100644 --- a/src/de/schildbach/pte/NetworkProvider.java +++ b/src/de/schildbach/pte/NetworkProvider.java @@ -33,6 +33,11 @@ public interface NetworkProvider NEARBY_STATIONS, DEPARTURES, CONNECTIONS } + public enum LocationType + { + ANY, WGS84 + } + boolean hasCapabilities(Capability... capabilities); /** @@ -74,10 +79,16 @@ public interface NetworkProvider /** * Query connections, asking for any ambiguousnesses * + * @param fromType + * type of location to route from, mandatory * @param from * location to route from, mandatory + * @param viaType + * type of location to route via, may be {@code null} * @param via * location to route via, may be {@code null} + * @param toType + * type of location to route to, mandatory * @param to * location to route to, mandatory * @param date @@ -87,7 +98,8 @@ public interface NetworkProvider * @return result object that can contain alternatives to clear up ambiguousnesses, or contains possible connections * @throws IOException */ - QueryConnectionsResult queryConnections(String from, String via, String to, Date date, boolean dep) throws IOException; + QueryConnectionsResult queryConnections(LocationType fromType, String from, LocationType viaType, String via, LocationType toType, String to, + Date date, boolean dep) throws IOException; /** * Query more connections (e.g. earlier or later) diff --git a/src/de/schildbach/pte/RmvProvider.java b/src/de/schildbach/pte/RmvProvider.java index c62eb856..58ad154c 100644 --- a/src/de/schildbach/pte/RmvProvider.java +++ b/src/de/schildbach/pte/RmvProvider.java @@ -169,8 +169,8 @@ public class RmvProvider implements NetworkProvider private static final Pattern P_CHECK_CONNECTIONS_ERROR = Pattern.compile( "(?:(mehrfach vorhanden oder identisch)|(keine Verbindung gefunden werden))", Pattern.CASE_INSENSITIVE); - public QueryConnectionsResult queryConnections(final String from, final String via, final String to, final Date date, final boolean dep) - throws IOException + public QueryConnectionsResult queryConnections(final LocationType fromType, final String from, final LocationType viaType, final String via, + final LocationType toType, final String to, final Date date, final boolean dep) throws IOException { final String uri = connectionsQueryUri(from, via, to, date, dep); final CharSequence page = ParserUtils.scrape(uri); diff --git a/src/de/schildbach/pte/SbbProvider.java b/src/de/schildbach/pte/SbbProvider.java index 4787a95f..c47f7e83 100644 --- a/src/de/schildbach/pte/SbbProvider.java +++ b/src/de/schildbach/pte/SbbProvider.java @@ -125,8 +125,8 @@ public class SbbProvider implements NetworkProvider private static final Pattern P_ADDRESSES = Pattern.compile("\\s*(.*?)\\s*", Pattern.DOTALL); private static final Pattern P_CHECK_CONNECTIONS_ERROR = Pattern.compile("(keine Verbindung gefunden werden)"); - public QueryConnectionsResult queryConnections(final String from, final String via, final String to, final Date date, final boolean dep) - throws IOException + public QueryConnectionsResult queryConnections(final LocationType fromType, final String from, final LocationType viaType, final String via, + final LocationType toType, final String to, final Date date, final boolean dep) throws IOException { final String uri = connectionsQueryUri(from, via, to, date, dep); final CharSequence page = ParserUtils.scrape(uri); diff --git a/src/de/schildbach/pte/VbbProvider.java b/src/de/schildbach/pte/VbbProvider.java index 1779db98..f8fc4941 100644 --- a/src/de/schildbach/pte/VbbProvider.java +++ b/src/de/schildbach/pte/VbbProvider.java @@ -183,8 +183,8 @@ public final class VbbProvider implements NetworkProvider private static final Pattern P_CHECK_TO = Pattern.compile("Nach:"); private static final Pattern P_CHECK_CONNECTIONS_ERROR = Pattern.compile("(zu dicht beieinander)|(keine Verbindung gefunden)"); - public QueryConnectionsResult queryConnections(final String from, final String via, final String to, final Date date, final boolean dep) - throws IOException + public QueryConnectionsResult queryConnections(final LocationType fromType, final String from, final LocationType viaType, final String via, + final LocationType toType, final String to, final Date date, final boolean dep) throws IOException { final String uri = connectionsQueryUri(from, via, to, date, dep); final CharSequence page = ParserUtils.scrape(uri); diff --git a/test/de/schildbach/pte/live/MvvProviderLiveTest.java b/test/de/schildbach/pte/live/MvvProviderLiveTest.java new file mode 100644 index 00000000..3955b159 --- /dev/null +++ b/test/de/schildbach/pte/live/MvvProviderLiveTest.java @@ -0,0 +1,74 @@ +/* + * 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.live; + +import java.util.Date; + +import org.junit.Test; + +import de.schildbach.pte.MvvProvider; +import de.schildbach.pte.QueryConnectionsResult; +import de.schildbach.pte.NetworkProvider.LocationType; + +/** + * @author Andreas Schildbach + */ +public class MvvProviderLiveTest +{ + private MvvProvider provider = new MvvProvider(); + + @Test + public void shortConnection() throws Exception + { + final QueryConnectionsResult result = provider.queryConnections(LocationType.ANY, "Marienplatz", null, null, LocationType.ANY, "Pasing", + new Date(), true); + 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.ANY, "Starnberg, Arbeitsamt", null, null, LocationType.ANY, + "Ackermannstraße", new Date(), true); + 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); + 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); + System.out.println(result); + final QueryConnectionsResult moreResult = provider.queryMoreConnections(result.linkLater); + System.out.println(moreResult); + } +} diff --git a/test/de/schildbach/pte/live/SbbProviderLiveTest.java b/test/de/schildbach/pte/live/SbbProviderLiveTest.java index 38e41e41..da091f23 100644 --- a/test/de/schildbach/pte/live/SbbProviderLiveTest.java +++ b/test/de/schildbach/pte/live/SbbProviderLiveTest.java @@ -23,6 +23,7 @@ import org.junit.Test; import de.schildbach.pte.QueryConnectionsResult; import de.schildbach.pte.SbbProvider; +import de.schildbach.pte.NetworkProvider.LocationType; /** * @author Andreas Schildbach @@ -32,9 +33,10 @@ public class SbbProviderLiveTest private SbbProvider provider = new SbbProvider(); @Test - public void fastConnection() throws Exception + public void shortConnection() throws Exception { - final QueryConnectionsResult result = provider.queryConnections("Zürich!", null, "Bern", new Date(), true); + final QueryConnectionsResult result = provider.queryConnections(LocationType.ANY, "Zürich!", null, null, LocationType.ANY, "Bern", + new Date(), true); System.out.println(result); final QueryConnectionsResult moreResult = provider.queryMoreConnections(result.linkLater); System.out.println(moreResult); @@ -43,7 +45,8 @@ public class SbbProviderLiveTest @Test public void slowConnection() throws Exception { - final QueryConnectionsResult result = provider.queryConnections("Schocherswil, Alte Post!", null, "Laconnex, Mollach", new Date(), true); + final QueryConnectionsResult result = provider.queryConnections(LocationType.ANY, "Schocherswil, Alte Post!", null, null, LocationType.ANY, + "Laconnex, Mollach", new Date(), true); System.out.println(result); final QueryConnectionsResult moreResult = provider.queryMoreConnections(result.linkLater); System.out.println(moreResult);