autocomplete for all efa based providers

git-svn-id: https://public-transport-enabler.googlecode.com/svn/trunk@245 0924bc21-9374-b0fa-ee44-9ff1593b38f0
This commit is contained in:
andreas.schildbach 2010-10-06 11:36:18 +00:00
parent b11faf1cd7
commit b4bf75d875
10 changed files with 250 additions and 41 deletions

View file

@ -26,7 +26,6 @@ import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.xmlpull.v1.XmlPullParser;
@ -47,40 +46,76 @@ import de.schildbach.pte.util.XmlPullUtil;
*/
public abstract class AbstractEfaProvider implements NetworkProvider
{
private static final Pattern P_AUTOCOMPLETE = Pattern.compile("" //
+ "(?:" //
+ "<itdOdvAssignedStop stopID=\"(\\d+)\" x=\"(\\d+)\" y=\"(\\d+)\" mapName=\"WGS84\" [^>]* nameWithPlace=\"([^\"]*)\"" //
+ "|" //
+ "<odvNameElem [^>]* locality=\"([^\"]*)\"" //
+ ")");
protected abstract String autocompleteUri(final CharSequence constraint);
public List<Autocomplete> autocompleteStations(final CharSequence constraint) throws IOException
{
final CharSequence page = ParserUtils.scrape(autocompleteUri(constraint));
final String uri = autocompleteUri(constraint);
final List<Autocomplete> results = new ArrayList<Autocomplete>();
final Matcher m = P_AUTOCOMPLETE.matcher(page);
while (m.find())
try
{
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));
}
}
final CharSequence page = ParserUtils.scrape(uri);
final List<Autocomplete> results = new ArrayList<Autocomplete>();
return results;
final XmlPullParserFactory factory = XmlPullParserFactory.newInstance(System.getProperty(XmlPullParserFactory.PROPERTY_NAME), null);
final XmlPullParser pp = factory.newPullParser();
pp.setInput(new StringReader(page.toString()));
// parse odv name elements
XmlPullUtil.jumpToStartTag(pp, null, "itdOdv");
final String usage = pp.getAttributeValue(null, "usage");
if (!"origin".equals(usage))
throw new IllegalStateException();
XmlPullUtil.nextStartTagInsideTree(pp, null, "itdOdvName");
final String nameState = pp.getAttributeValue(null, "state");
if ("list".equals(nameState))
{
while (XmlPullUtil.nextStartTagInsideTree(pp, null, "odvNameElem"))
{
final String type = pp.getAttributeValue(null, "anyType");
int id = Integer.parseInt(pp.getAttributeValue(null, "id"));
if (id < 0)
id = 0;
final String name = normalizeLocationName(pp.nextText());
results.add(new Autocomplete(type(type), id, name));
}
}
// parse assigned stops
if (XmlPullUtil.jumpToStartTag(pp, null, "itdOdvAssignedStops"))
{
while (XmlPullUtil.nextStartTagInsideTree(pp, null, "itdOdvAssignedStop"))
{
final int id = Integer.parseInt(pp.getAttributeValue(null, "stopID"));
final String name = normalizeLocationName(pp.getAttributeValue(null, "nameWithPlace"));
final Autocomplete autocomplete = new Autocomplete(LocationType.STATION, id, name);
if (!results.contains(autocomplete))
results.add(autocomplete);
XmlPullUtil.skipRestOfTree(pp);
}
}
return results;
}
catch (final XmlPullParserException x)
{
throw new RuntimeException(x);
}
}
private static LocationType type(final String type)
{
if (type.equals("stop"))
return LocationType.STATION;
if (type.equals("poi"))
return LocationType.POI;
if (type.equals("street"))
return LocationType.ADDRESS;
if (type.equals("loc"))
return LocationType.ANY;
throw new IllegalArgumentException("unknown type: " + type);
}
private static final Pattern P_NEARBY_MESSAGES = Pattern.compile("(unsere Server zur Zeit ausgelastet)");

View file

@ -42,13 +42,12 @@ public class GvhProvider extends AbstractEfaProvider
}
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";
+ "XSLT_TRIP_REQUEST2?outputFormat=XML&locationServerActive=1&type_origin=any&name_origin=%s";
@Override
protected String autocompleteUri(final CharSequence constraint)
{
return String.format(AUTOCOMPLETE_URI, ParserUtils.urlEncode(constraint.toString(), ENCODING));
return String.format(AUTOCOMPLETE_URI, ParserUtils.urlEncode(constraint.toString(), "ISO-8859-1"));
}
private static final String NEARBY_STATION_URI = API_BASE

View file

@ -41,15 +41,12 @@ public class LinzProvider extends AbstractEfaProvider
return false;
}
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 String ENCODING = "ISO-8859-1";
private static final String AUTOCOMPLETE_URI = API_BASE + "XSLT_TRIP_REQUEST2?outputFormat=XML&name_origin=%s&type_origin=any";
@Override
protected String autocompleteUri(final CharSequence constraint)
{
return String.format(AUTOCOMPLETE_URI, ParserUtils.urlEncode(constraint.toString(), ENCODING), AUTOCOMPLETE_TYPE);
return String.format(AUTOCOMPLETE_URI, ParserUtils.urlEncode(constraint.toString(), "ISO-8859-1"));
}
private static final String NEARBY_LATLON_URI = API_BASE

View file

@ -21,6 +21,7 @@ import java.util.Date;
import de.schildbach.pte.dto.GetConnectionDetailsResult;
import de.schildbach.pte.dto.QueryConnectionsResult;
import de.schildbach.pte.util.ParserUtils;
/**
* @author Andreas Schildbach
@ -39,10 +40,13 @@ public class VrnProvider extends AbstractEfaProvider
return false;
}
private static final String AUTOCOMPLETE_URI = API_BASE
+ "XSLT_TRIP_REQUEST2?outputFormat=XML&locationServerActive=1&type_origin=any&name_origin=%s";
@Override
protected String autocompleteUri(CharSequence constraint)
protected String autocompleteUri(final CharSequence constraint)
{
throw new UnsupportedOperationException();
return String.format(AUTOCOMPLETE_URI, ParserUtils.urlEncode(constraint.toString(), "ISO-8859-1"));
}
@Override

View file

@ -21,6 +21,7 @@ import java.util.Date;
import de.schildbach.pte.dto.GetConnectionDetailsResult;
import de.schildbach.pte.dto.QueryConnectionsResult;
import de.schildbach.pte.util.ParserUtils;
/**
* @author Andreas Schildbach
@ -39,10 +40,12 @@ public class VrrProvider extends AbstractEfaProvider
return false;
}
private static final String AUTOCOMPLETE_URI = API_BASE + "XSLT_TRIP_REQUEST2?outputFormat=XML&type_origin=any&name_origin=%s";
@Override
protected String autocompleteUri(CharSequence constraint)
protected String autocompleteUri(final CharSequence constraint)
{
throw new UnsupportedOperationException();
return String.format(AUTOCOMPLETE_URI, ParserUtils.urlEncode(constraint.toString(), "ISO-8859-1"));
}
@Override

View file

@ -37,7 +37,34 @@ public final class Autocomplete
@Override
public String toString()
{
// return getClass().getName() + "[" + locationId + " " + location + "]";
return location; // invoked by AutoCompleteTextView in landscape orientation
}
public String toDebugString()
{
return "[" + locationType + " " + locationId + " '" + location + "']";
}
@Override
public boolean equals(Object o)
{
if (o == this)
return true;
if (!(o instanceof Autocomplete))
return false;
final Autocomplete other = (Autocomplete) o;
if (this.locationType != other.locationType)
return false;
if (this.locationId != other.locationId)
return false;
if (this.locationId != 0)
return true;
return this.location.equals(other.location);
}
@Override
public int hashCode()
{
return locationType.hashCode(); // FIXME not very discriminative
}
}

View file

@ -31,6 +31,38 @@ public class GvhProviderLiveTest
{
private final GvhProvider provider = new GvhProvider();
@Test
public void autocompleteIncomplete() throws Exception
{
final List<Autocomplete> autocompletes = provider.autocompleteStations("Kur");
list(autocompletes);
}
@Test
public void autocompleteIdentified() throws Exception
{
final List<Autocomplete> autocompletes = provider.autocompleteStations("Hannover, Hannoversche Straße");
list(autocompletes);
}
@Test
public void autocompleteCity() throws Exception
{
final List<Autocomplete> autocompletes = provider.autocompleteStations("Hannover");
list(autocompletes);
}
private void list(final List<Autocomplete> autocompletes)
{
System.out.print(autocompletes.size() + " ");
for (final Autocomplete autocomplete : autocompletes)
System.out.print(autocomplete.toDebugString() + " ");
System.out.println();
}
@Test
public void autocomplete() throws Exception
{

View file

@ -18,12 +18,14 @@
package de.schildbach.pte.live;
import java.util.Date;
import java.util.List;
import org.junit.Test;
import de.schildbach.pte.LinzProvider;
import de.schildbach.pte.NetworkProvider.LocationType;
import de.schildbach.pte.NetworkProvider.WalkSpeed;
import de.schildbach.pte.dto.Autocomplete;
import de.schildbach.pte.dto.QueryConnectionsResult;
import de.schildbach.pte.dto.QueryDeparturesResult;
@ -35,6 +37,38 @@ public class LinzProviderLiveTest
private LinzProvider provider = new LinzProvider();
private static final String ALL_PRODUCTS = "IRSUTBFC";
@Test
public void autocompleteIncomplete() throws Exception
{
final List<Autocomplete> autocompletes = provider.autocompleteStations("Linz, H");
list(autocompletes);
}
@Test
public void autocompleteIdentified() throws Exception
{
final List<Autocomplete> autocompletes = provider.autocompleteStations("Leonding, Haag");
list(autocompletes);
}
@Test
public void autocompleteCity() throws Exception
{
final List<Autocomplete> autocompletes = provider.autocompleteStations("Linz");
list(autocompletes);
}
private void list(final List<Autocomplete> autocompletes)
{
System.out.print(autocompletes.size() + " ");
for (final Autocomplete autocomplete : autocompletes)
System.out.print(autocomplete.toDebugString() + " ");
System.out.println();
}
@Test
public void queryDepartures() throws Exception
{

View file

@ -16,9 +16,12 @@
*/
package de.schildbach.pte.live;
import java.util.List;
import org.junit.Test;
import de.schildbach.pte.VrnProvider;
import de.schildbach.pte.dto.Autocomplete;
import de.schildbach.pte.dto.NearbyStationsResult;
import de.schildbach.pte.dto.QueryDeparturesResult;
@ -29,6 +32,46 @@ public class VrnProviderLiveTest
{
private final VrnProvider provider = new VrnProvider();
@Test
public void autocompleteIncomplete() throws Exception
{
final List<Autocomplete> autocompletes = provider.autocompleteStations("Kur");
list(autocompletes);
}
@Test
public void autocompleteIdentified() throws Exception
{
final List<Autocomplete> autocompletes = provider.autocompleteStations("Bremen, KUR");
list(autocompletes);
}
@Test
public void autocompleteLocality() throws Exception
{
final List<Autocomplete> autocompletes = provider.autocompleteStations("Bremen");
list(autocompletes);
}
@Test
public void autocompleteCity() throws Exception
{
final List<Autocomplete> autocompletes = provider.autocompleteStations("Mannheim");
list(autocompletes);
}
private void list(final List<Autocomplete> autocompletes)
{
System.out.print(autocompletes.size() + " ");
for (final Autocomplete autocomplete : autocompletes)
System.out.print(autocomplete.toDebugString() + " ");
System.out.println();
}
@Test
public void nearbyStation() throws Exception
{

View file

@ -16,9 +16,12 @@
*/
package de.schildbach.pte.live;
import java.util.List;
import org.junit.Test;
import de.schildbach.pte.VrrProvider;
import de.schildbach.pte.dto.Autocomplete;
import de.schildbach.pte.dto.NearbyStationsResult;
import de.schildbach.pte.dto.QueryDeparturesResult;
@ -29,6 +32,38 @@ public class VrrProviderLiveTest
{
private final VrrProvider provider = new VrrProvider();
@Test
public void autocompleteIncomplete() throws Exception
{
final List<Autocomplete> autocompletes = provider.autocompleteStations("Kur");
list(autocompletes);
}
@Test
public void autocompleteIdentified() throws Exception
{
final List<Autocomplete> autocompletes = provider.autocompleteStations("Düsseldorf, Am Frohnhof");
list(autocompletes);
}
@Test
public void autocompleteCity() throws Exception
{
final List<Autocomplete> autocompletes = provider.autocompleteStations("Düsseldorf");
list(autocompletes);
}
private void list(final List<Autocomplete> autocompletes)
{
System.out.print(autocompletes.size() + " ");
for (final Autocomplete autocomplete : autocompletes)
System.out.print(autocomplete.toDebugString() + " ");
System.out.println();
}
@Test
public void nearbyStation() throws Exception
{