diff --git a/src/de/schildbach/pte/Autocomplete.java b/src/de/schildbach/pte/Autocomplete.java new file mode 100644 index 00000000..9d9388a2 --- /dev/null +++ b/src/de/schildbach/pte/Autocomplete.java @@ -0,0 +1,38 @@ +/* + * 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; + +/** + * @author Andreas Schildbach + */ +public final class Autocomplete +{ + public final int locationId; + public final String location; + + public Autocomplete(final int locationId, final String location) + { + this.locationId = locationId; + this.location = location; + } + + @Override + public String toString() + { + return getClass().getName() + "[" + locationId + " " + location + "]"; + } +} diff --git a/src/de/schildbach/pte/BahnProvider.java b/src/de/schildbach/pte/BahnProvider.java index 64648d6c..f9dc6dca 100644 --- a/src/de/schildbach/pte/BahnProvider.java +++ b/src/de/schildbach/pte/BahnProvider.java @@ -55,25 +55,25 @@ public final class BahnProvider implements NetworkProvider .compile(".*.*", Pattern.DOTALL); private static final Pattern P_MULTI_NAME = Pattern.compile("", Pattern.DOTALL); - public List autoCompleteStationName(CharSequence constraint) throws IOException + public List autocompleteStations(final CharSequence constraint) throws IOException { final CharSequence page = ParserUtils.scrape(NAME_URL + ParserUtils.urlEncode(constraint.toString())); - final List names = new ArrayList(); + final List results = new ArrayList(); final Matcher mSingle = P_SINGLE_NAME.matcher(page); if (mSingle.matches()) { - names.add(ParserUtils.resolveEntities(mSingle.group(1))); + results.add(new Autocomplete(0, ParserUtils.resolveEntities(mSingle.group(1)))); } else { final Matcher mMulti = P_MULTI_NAME.matcher(page); while (mMulti.find()) - names.add(ParserUtils.resolveEntities(mMulti.group(1))); + results.add(new Autocomplete(0, ParserUtils.resolveEntities(mMulti.group(1)))); } - return names; + return results; } private final static Pattern P_NEARBY_STATIONS = Pattern diff --git a/src/de/schildbach/pte/MvvProvider.java b/src/de/schildbach/pte/MvvProvider.java index 9fb5104a..6b5b2433 100644 --- a/src/de/schildbach/pte/MvvProvider.java +++ b/src/de/schildbach/pte/MvvProvider.java @@ -51,29 +51,43 @@ public class MvvProvider implements NetworkProvider return true; } - private static final String AUTOCOMPLETE_NAME_URL = "http://efa.mvv-muenchen.de/mobile/XSLT_DM_REQUEST?anySigWhenPerfectNoOtherMatches=1&command=&itdLPxx_advancedOptions=0&itdLPxx_odvPPType=&language=de&limit=20&locationServerActive=1&nameInfo_dm=invalid&nameState_dm=empty&nameState_dm=empty&placeInfo_dm=invalid&placeState_dm=empty&place_dm=&reducedAnyPostcodeObjFilter_dm=64&reducedAnyTooManyObjFilter_dm=2&reducedAnyWithoutAddressObjFilter_dm=102&requestID=0&selectAssignedStops=1&sessionID=0&typeInfo_dm=invalid&type_dm=stop&useHouseNumberList_dm=1&name_dm="; - private static final Pattern P_SINGLE_NAME = Pattern.compile(".*Von:[\\xa0\\s]+(.+?)
.*", Pattern.DOTALL); - private static final Pattern P_MULTI_NAME = Pattern.compile("", Pattern.DOTALL); + private static final String AUTOCOMPLETE_URI = "http://efa.mvv-muenchen.de/ultralite/XML_STOPFINDER_REQUEST" + + "?coordOutputFormat=WGS84&anyObjFilter_sf=126&locationServerActive=1&name_sf=%s&type_sf=%s"; + private static final String AUTOCOMPLETE_TYPE = "any"; // any, stop, street, poi + private static final Pattern P_AUTOCOMPLETE_COARSE = Pattern.compile("

(.*?)

"); + private static final Pattern P_AUTOCOMPLETE_FINE = Pattern.compile(".*?(.*?).*?(.*?).*?(.*?).*?(.*?).*?"); - public List autoCompleteStationName(final CharSequence constraint) throws IOException + public List autocompleteStations(final CharSequence constraint) throws IOException { - final CharSequence page = ParserUtils.scrape(AUTOCOMPLETE_NAME_URL + ParserUtils.urlEncode(constraint.toString(), ENCODING)); + final String uri = String.format(AUTOCOMPLETE_URI, ParserUtils.urlEncode(constraint.toString(), ENCODING), AUTOCOMPLETE_TYPE); + final CharSequence page = ParserUtils.scrape(uri); - final List names = new ArrayList(); + final List results = new ArrayList(); - final Matcher mSingle = P_SINGLE_NAME.matcher(page); - if (mSingle.matches()) + final Matcher mAutocompleteCoarse = P_AUTOCOMPLETE_COARSE.matcher(page); + while (mAutocompleteCoarse.find()) { - names.add(ParserUtils.resolveEntities(mSingle.group(1))); - } - else - { - final Matcher mMulti = P_MULTI_NAME.matcher(page); - while (mMulti.find()) - names.add(ParserUtils.resolveEntities(mMulti.group(1))); + final Matcher mAutocompleteFine = P_AUTOCOMPLETE_FINE.matcher(mAutocompleteCoarse.group(1)); + if (mAutocompleteFine.matches()) + { + final String location = mAutocompleteFine.group(1); + final String type = mAutocompleteFine.group(2); + final int locationId = Integer.parseInt(mAutocompleteFine.group(3)); + final String city = mAutocompleteFine.group(4); + + if (type.equals("stop")) + { + final Autocomplete result = new Autocomplete(locationId, city + ", " + location); + results.add(result); + } + } + else + { + throw new IllegalArgumentException("cannot parse '" + mAutocompleteCoarse.group(1) + "' on " + uri); + } } - return names; + return results; } private static final String NEARBY_URI = "http://efa.mvv-muenchen.de/ultralite/XML_DM_REQUEST" diff --git a/src/de/schildbach/pte/NetworkProvider.java b/src/de/schildbach/pte/NetworkProvider.java index c939cfcc..1049dc31 100644 --- a/src/de/schildbach/pte/NetworkProvider.java +++ b/src/de/schildbach/pte/NetworkProvider.java @@ -48,7 +48,7 @@ public interface NetworkProvider * @return auto-complete suggestions * @throws IOException */ - List autoCompleteStationName(CharSequence constraint) throws IOException; + List autocompleteStations(CharSequence constraint) throws IOException; /** * Determine stations near to given location diff --git a/src/de/schildbach/pte/OebbProvider.java b/src/de/schildbach/pte/OebbProvider.java index f71f7e0d..3b060d6b 100644 --- a/src/de/schildbach/pte/OebbProvider.java +++ b/src/de/schildbach/pte/OebbProvider.java @@ -35,25 +35,25 @@ public class OebbProvider implements NetworkProvider .compile(".*?.*", Pattern.DOTALL); private static final Pattern P_MULTI_NAME = Pattern.compile("", Pattern.DOTALL); - public List autoCompleteStationName(final CharSequence constraint) throws IOException + public List autocompleteStations(final CharSequence constraint) throws IOException { final CharSequence page = ParserUtils.scrape(NAME_URL + ParserUtils.urlEncode(constraint.toString())); - final List names = new ArrayList(); + final List results = new ArrayList(); final Matcher mSingle = P_SINGLE_NAME.matcher(page); if (mSingle.matches()) { - names.add(ParserUtils.resolveEntities(mSingle.group(1))); + results.add(new Autocomplete(0, ParserUtils.resolveEntities(mSingle.group(1)))); } else { final Matcher mMulti = P_MULTI_NAME.matcher(page); while (mMulti.find()) - names.add(ParserUtils.resolveEntities(mMulti.group(2))); + results.add(new Autocomplete(0, ParserUtils.resolveEntities(mMulti.group(2)))); } - return names; + return results; } public List nearbyStations(final double lat, final double lon, final int maxDistance, final int maxStations) throws IOException diff --git a/src/de/schildbach/pte/RmvProvider.java b/src/de/schildbach/pte/RmvProvider.java index 43d3c42d..0d498f6f 100644 --- a/src/de/schildbach/pte/RmvProvider.java +++ b/src/de/schildbach/pte/RmvProvider.java @@ -56,25 +56,25 @@ public class RmvProvider implements NetworkProvider .compile(".*.*", Pattern.DOTALL); private static final Pattern P_MULTI_NAME = Pattern.compile("\\s*(.*?)\\s*", Pattern.DOTALL); - public List autoCompleteStationName(final CharSequence constraint) throws IOException + public List autocompleteStations(final CharSequence constraint) throws IOException { final CharSequence page = ParserUtils.scrape(NAME_URL + ParserUtils.urlEncode(constraint.toString())); - final List names = new ArrayList(); + final List results = new ArrayList(); final Matcher mSingle = P_SINGLE_NAME.matcher(page); if (mSingle.matches()) { - names.add(ParserUtils.resolveEntities(mSingle.group(1))); + results.add(new Autocomplete(0, ParserUtils.resolveEntities(mSingle.group(1)))); } else { final Matcher mMulti = P_MULTI_NAME.matcher(page); while (mMulti.find()) - names.add(ParserUtils.resolveEntities(mMulti.group(1))); + results.add(new Autocomplete(0, ParserUtils.resolveEntities(mMulti.group(1)))); } - return names; + return results; } private final static Pattern P_NEARBY_STATIONS = Pattern.compile("\\n" diff --git a/src/de/schildbach/pte/SbbProvider.java b/src/de/schildbach/pte/SbbProvider.java index a9cb985f..25a164b3 100644 --- a/src/de/schildbach/pte/SbbProvider.java +++ b/src/de/schildbach/pte/SbbProvider.java @@ -57,25 +57,25 @@ public class SbbProvider implements NetworkProvider + "(.*?)\n?" // + "", Pattern.DOTALL); - public List autoCompleteStationName(final CharSequence constraint) throws IOException + public List autocompleteStations(final CharSequence constraint) throws IOException { final CharSequence page = ParserUtils.scrape(NAME_URL + ParserUtils.urlEncode(constraint.toString())); - final List names = new ArrayList(); + final List results = new ArrayList(); final Matcher mSingle = P_SINGLE_NAME.matcher(page); if (mSingle.matches()) { - names.add(ParserUtils.resolveEntities(mSingle.group(1))); + results.add(new Autocomplete(0, ParserUtils.resolveEntities(mSingle.group(1)))); } else { final Matcher mMulti = P_MULTI_NAME.matcher(page); while (mMulti.find()) - names.add(ParserUtils.resolveEntities(mMulti.group(2))); + results.add(new Autocomplete(0, ParserUtils.resolveEntities(mMulti.group(2)))); } - return names; + return results; } public List nearbyStations(final double lat, final double lon, final int maxDistance, final int maxStations) throws IOException diff --git a/src/de/schildbach/pte/SncbProvider.java b/src/de/schildbach/pte/SncbProvider.java index d6d0fca9..8247bdc3 100644 --- a/src/de/schildbach/pte/SncbProvider.java +++ b/src/de/schildbach/pte/SncbProvider.java @@ -22,7 +22,7 @@ public class SncbProvider implements NetworkProvider throw new UnsupportedOperationException(); } - public List autoCompleteStationName(final CharSequence constraint) throws IOException + public List autocompleteStations(final CharSequence constraint) throws IOException { throw new UnsupportedOperationException(); } diff --git a/src/de/schildbach/pte/VbbProvider.java b/src/de/schildbach/pte/VbbProvider.java index 876b0ac0..a1963773 100644 --- a/src/de/schildbach/pte/VbbProvider.java +++ b/src/de/schildbach/pte/VbbProvider.java @@ -61,9 +61,9 @@ public final class VbbProvider implements NetworkProvider private static final String AUTOCOMPLETE_MASTID_URL = "http://mobil.bvg.de/IstAbfahrtzeiten/index/mobil?input="; private static final Pattern P_SINGLE_MASTID = Pattern.compile(".*Ist-Abfahrtzeiten.*?(.*?).*", Pattern.DOTALL); - public List autoCompleteStationName(CharSequence constraint) throws IOException + public List autocompleteStations(final CharSequence constraint) throws IOException { - final List names = new ArrayList(); + final List results = new ArrayList(); if (P_AUTOCOMPLETE_IS_MAST.matcher(constraint).matches()) { @@ -72,7 +72,7 @@ public final class VbbProvider implements NetworkProvider final Matcher mSingle = P_SINGLE_MASTID.matcher(page); if (mSingle.matches()) { - names.add(ParserUtils.resolveEntities(mSingle.group(1))); + results.add(new Autocomplete(0, ParserUtils.resolveEntities(mSingle.group(1)))); } } else @@ -82,17 +82,17 @@ public final class VbbProvider implements NetworkProvider final Matcher mSingle = P_SINGLE_NAME.matcher(page); if (mSingle.matches()) { - names.add(ParserUtils.resolveEntities(mSingle.group(1))); + results.add(new Autocomplete(0, ParserUtils.resolveEntities(mSingle.group(1)))); } else { final Matcher mMulti = P_MULTI_NAME.matcher(page); while (mMulti.find()) - names.add(ParserUtils.resolveEntities(mMulti.group(1))); + results.add(new Autocomplete(0, ParserUtils.resolveEntities(mMulti.group(1)))); } } - return names; + return results; } public List nearbyStations(final double lat, final double lon, final int maxDistance, final int maxStations) throws IOException