autocomplete result object, use ultralite API for MVV

git-svn-id: https://public-transport-enabler.googlecode.com/svn/trunk@123 0924bc21-9374-b0fa-ee44-9ff1593b38f0
This commit is contained in:
andreas.schildbach 2010-09-01 19:34:54 +00:00
parent 16376d8947
commit 197202e275
9 changed files with 96 additions and 44 deletions

View file

@ -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 <http://www.gnu.org/licenses/>.
*/
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 + "]";
}
}

View file

@ -55,25 +55,25 @@ public final class BahnProvider implements NetworkProvider
.compile(".*<input type=\"hidden\" name=\"input\" value=\"(.+?)#\\d+?\" />.*", Pattern.DOTALL); .compile(".*<input type=\"hidden\" name=\"input\" value=\"(.+?)#\\d+?\" />.*", Pattern.DOTALL);
private static final Pattern P_MULTI_NAME = Pattern.compile("<option value=\".+?#\\d+?\">(.+?)</option>", Pattern.DOTALL); private static final Pattern P_MULTI_NAME = Pattern.compile("<option value=\".+?#\\d+?\">(.+?)</option>", Pattern.DOTALL);
public List<String> autoCompleteStationName(CharSequence constraint) throws IOException public List<Autocomplete> autocompleteStations(final CharSequence constraint) throws IOException
{ {
final CharSequence page = ParserUtils.scrape(NAME_URL + ParserUtils.urlEncode(constraint.toString())); final CharSequence page = ParserUtils.scrape(NAME_URL + ParserUtils.urlEncode(constraint.toString()));
final List<String> names = new ArrayList<String>(); final List<Autocomplete> results = new ArrayList<Autocomplete>();
final Matcher mSingle = P_SINGLE_NAME.matcher(page); final Matcher mSingle = P_SINGLE_NAME.matcher(page);
if (mSingle.matches()) if (mSingle.matches())
{ {
names.add(ParserUtils.resolveEntities(mSingle.group(1))); results.add(new Autocomplete(0, ParserUtils.resolveEntities(mSingle.group(1))));
} }
else else
{ {
final Matcher mMulti = P_MULTI_NAME.matcher(page); final Matcher mMulti = P_MULTI_NAME.matcher(page);
while (mMulti.find()) 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 private final static Pattern P_NEARBY_STATIONS = Pattern

View file

@ -51,29 +51,43 @@ public class MvvProvider implements NetworkProvider
return true; 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 String AUTOCOMPLETE_URI = "http://efa.mvv-muenchen.de/ultralite/XML_STOPFINDER_REQUEST"
private static final Pattern P_SINGLE_NAME = Pattern.compile(".*Von:[\\xa0\\s]+</b>(.+?)<br />.*", Pattern.DOTALL); + "?coordOutputFormat=WGS84&anyObjFilter_sf=126&locationServerActive=1&name_sf=%s&type_sf=%s";
private static final Pattern P_MULTI_NAME = Pattern.compile("<option value=\"\\d+:\\d+\">(.+?)</option>", Pattern.DOTALL); private static final String AUTOCOMPLETE_TYPE = "any"; // any, stop, street, poi
private static final Pattern P_AUTOCOMPLETE_COARSE = Pattern.compile("<p>(.*?)</p>");
private static final Pattern P_AUTOCOMPLETE_FINE = Pattern.compile(".*?<n>(.*?)</n>.*?<ty>(.*?)</ty>.*?<id>(.*?)</id>.*?<pc>(.*?)</pc>.*?");
public List<String> autoCompleteStationName(final CharSequence constraint) throws IOException public List<Autocomplete> 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<String> names = new ArrayList<String>(); final List<Autocomplete> results = new ArrayList<Autocomplete>();
final Matcher mSingle = P_SINGLE_NAME.matcher(page); final Matcher mAutocompleteCoarse = P_AUTOCOMPLETE_COARSE.matcher(page);
if (mSingle.matches()) while (mAutocompleteCoarse.find())
{ {
names.add(ParserUtils.resolveEntities(mSingle.group(1))); final Matcher mAutocompleteFine = P_AUTOCOMPLETE_FINE.matcher(mAutocompleteCoarse.group(1));
} if (mAutocompleteFine.matches())
else {
{ final String location = mAutocompleteFine.group(1);
final Matcher mMulti = P_MULTI_NAME.matcher(page); final String type = mAutocompleteFine.group(2);
while (mMulti.find()) final int locationId = Integer.parseInt(mAutocompleteFine.group(3));
names.add(ParserUtils.resolveEntities(mMulti.group(1))); 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" private static final String NEARBY_URI = "http://efa.mvv-muenchen.de/ultralite/XML_DM_REQUEST"

View file

@ -48,7 +48,7 @@ public interface NetworkProvider
* @return auto-complete suggestions * @return auto-complete suggestions
* @throws IOException * @throws IOException
*/ */
List<String> autoCompleteStationName(CharSequence constraint) throws IOException; List<Autocomplete> autocompleteStations(CharSequence constraint) throws IOException;
/** /**
* Determine stations near to given location * Determine stations near to given location

View file

@ -35,25 +35,25 @@ public class OebbProvider implements NetworkProvider
.compile(".*?<input type=\"hidden\" name=\"input\" value=\"(.+?)#(\\d+)\">.*", Pattern.DOTALL); .compile(".*?<input type=\"hidden\" name=\"input\" value=\"(.+?)#(\\d+)\">.*", Pattern.DOTALL);
private static final Pattern P_MULTI_NAME = Pattern.compile("<option value=\".+?#(\\d+?)\">(.+?)</option>", Pattern.DOTALL); private static final Pattern P_MULTI_NAME = Pattern.compile("<option value=\".+?#(\\d+?)\">(.+?)</option>", Pattern.DOTALL);
public List<String> autoCompleteStationName(final CharSequence constraint) throws IOException public List<Autocomplete> autocompleteStations(final CharSequence constraint) throws IOException
{ {
final CharSequence page = ParserUtils.scrape(NAME_URL + ParserUtils.urlEncode(constraint.toString())); final CharSequence page = ParserUtils.scrape(NAME_URL + ParserUtils.urlEncode(constraint.toString()));
final List<String> names = new ArrayList<String>(); final List<Autocomplete> results = new ArrayList<Autocomplete>();
final Matcher mSingle = P_SINGLE_NAME.matcher(page); final Matcher mSingle = P_SINGLE_NAME.matcher(page);
if (mSingle.matches()) if (mSingle.matches())
{ {
names.add(ParserUtils.resolveEntities(mSingle.group(1))); results.add(new Autocomplete(0, ParserUtils.resolveEntities(mSingle.group(1))));
} }
else else
{ {
final Matcher mMulti = P_MULTI_NAME.matcher(page); final Matcher mMulti = P_MULTI_NAME.matcher(page);
while (mMulti.find()) 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<Station> nearbyStations(final double lat, final double lon, final int maxDistance, final int maxStations) throws IOException public List<Station> nearbyStations(final double lat, final double lon, final int maxDistance, final int maxStations) throws IOException

View file

@ -56,25 +56,25 @@ public class RmvProvider implements NetworkProvider
.compile(".*<input type=\"hidden\" name=\"input\" value=\"(.+?)#\\d+?\" />.*", Pattern.DOTALL); .compile(".*<input type=\"hidden\" name=\"input\" value=\"(.+?)#\\d+?\" />.*", Pattern.DOTALL);
private static final Pattern P_MULTI_NAME = Pattern.compile("<a href=\"/auskunft/bin/jp/stboard.exe/dox.*?\">\\s*(.*?)\\s*</a>", Pattern.DOTALL); private static final Pattern P_MULTI_NAME = Pattern.compile("<a href=\"/auskunft/bin/jp/stboard.exe/dox.*?\">\\s*(.*?)\\s*</a>", Pattern.DOTALL);
public List<String> autoCompleteStationName(final CharSequence constraint) throws IOException public List<Autocomplete> autocompleteStations(final CharSequence constraint) throws IOException
{ {
final CharSequence page = ParserUtils.scrape(NAME_URL + ParserUtils.urlEncode(constraint.toString())); final CharSequence page = ParserUtils.scrape(NAME_URL + ParserUtils.urlEncode(constraint.toString()));
final List<String> names = new ArrayList<String>(); final List<Autocomplete> results = new ArrayList<Autocomplete>();
final Matcher mSingle = P_SINGLE_NAME.matcher(page); final Matcher mSingle = P_SINGLE_NAME.matcher(page);
if (mSingle.matches()) if (mSingle.matches())
{ {
names.add(ParserUtils.resolveEntities(mSingle.group(1))); results.add(new Autocomplete(0, ParserUtils.resolveEntities(mSingle.group(1))));
} }
else else
{ {
final Matcher mMulti = P_MULTI_NAME.matcher(page); final Matcher mMulti = P_MULTI_NAME.matcher(page);
while (mMulti.find()) 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("<a href=\"/auskunft/bin/jp/stboard.exe/dox.+?input=(\\d+).*?\">\\n" private final static Pattern P_NEARBY_STATIONS = Pattern.compile("<a href=\"/auskunft/bin/jp/stboard.exe/dox.+?input=(\\d+).*?\">\\n"

View file

@ -57,25 +57,25 @@ public class SbbProvider implements NetworkProvider
+ "(.*?)\n?" // + "(.*?)\n?" //
+ "</a>", Pattern.DOTALL); + "</a>", Pattern.DOTALL);
public List<String> autoCompleteStationName(final CharSequence constraint) throws IOException public List<Autocomplete> autocompleteStations(final CharSequence constraint) throws IOException
{ {
final CharSequence page = ParserUtils.scrape(NAME_URL + ParserUtils.urlEncode(constraint.toString())); final CharSequence page = ParserUtils.scrape(NAME_URL + ParserUtils.urlEncode(constraint.toString()));
final List<String> names = new ArrayList<String>(); final List<Autocomplete> results = new ArrayList<Autocomplete>();
final Matcher mSingle = P_SINGLE_NAME.matcher(page); final Matcher mSingle = P_SINGLE_NAME.matcher(page);
if (mSingle.matches()) if (mSingle.matches())
{ {
names.add(ParserUtils.resolveEntities(mSingle.group(1))); results.add(new Autocomplete(0, ParserUtils.resolveEntities(mSingle.group(1))));
} }
else else
{ {
final Matcher mMulti = P_MULTI_NAME.matcher(page); final Matcher mMulti = P_MULTI_NAME.matcher(page);
while (mMulti.find()) 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<Station> nearbyStations(final double lat, final double lon, final int maxDistance, final int maxStations) throws IOException public List<Station> nearbyStations(final double lat, final double lon, final int maxDistance, final int maxStations) throws IOException

View file

@ -22,7 +22,7 @@ public class SncbProvider implements NetworkProvider
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
public List<String> autoCompleteStationName(final CharSequence constraint) throws IOException public List<Autocomplete> autocompleteStations(final CharSequence constraint) throws IOException
{ {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }

View file

@ -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 String AUTOCOMPLETE_MASTID_URL = "http://mobil.bvg.de/IstAbfahrtzeiten/index/mobil?input=";
private static final Pattern P_SINGLE_MASTID = Pattern.compile(".*Ist-Abfahrtzeiten.*?<strong>(.*?)</strong>.*", Pattern.DOTALL); private static final Pattern P_SINGLE_MASTID = Pattern.compile(".*Ist-Abfahrtzeiten.*?<strong>(.*?)</strong>.*", Pattern.DOTALL);
public List<String> autoCompleteStationName(CharSequence constraint) throws IOException public List<Autocomplete> autocompleteStations(final CharSequence constraint) throws IOException
{ {
final List<String> names = new ArrayList<String>(); final List<Autocomplete> results = new ArrayList<Autocomplete>();
if (P_AUTOCOMPLETE_IS_MAST.matcher(constraint).matches()) 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); final Matcher mSingle = P_SINGLE_MASTID.matcher(page);
if (mSingle.matches()) if (mSingle.matches())
{ {
names.add(ParserUtils.resolveEntities(mSingle.group(1))); results.add(new Autocomplete(0, ParserUtils.resolveEntities(mSingle.group(1))));
} }
} }
else else
@ -82,17 +82,17 @@ public final class VbbProvider implements NetworkProvider
final Matcher mSingle = P_SINGLE_NAME.matcher(page); final Matcher mSingle = P_SINGLE_NAME.matcher(page);
if (mSingle.matches()) if (mSingle.matches())
{ {
names.add(ParserUtils.resolveEntities(mSingle.group(1))); results.add(new Autocomplete(0, ParserUtils.resolveEntities(mSingle.group(1))));
} }
else else
{ {
final Matcher mMulti = P_MULTI_NAME.matcher(page); final Matcher mMulti = P_MULTI_NAME.matcher(page);
while (mMulti.find()) 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<Station> nearbyStations(final double lat, final double lon, final int maxDistance, final int maxStations) throws IOException public List<Station> nearbyStations(final double lat, final double lon, final int maxDistance, final int maxStations) throws IOException