Introduce AbstractNetworkProvider.parsePosition() for custom parsable positions.

This commit is contained in:
Andreas Schildbach 2015-01-11 23:16:16 +01:00
parent e386dac23e
commit 3c5dc7c328
9 changed files with 122 additions and 46 deletions

View file

@ -1620,7 +1620,7 @@ public abstract class AbstractEfaProvider extends AbstractNetworkProvider
new LinkedList<Departure>(), new LinkedList<LineDestination>()); new LinkedList<Departure>(), new LinkedList<LineDestination>());
} }
final Position position = normalizePlatformName(XmlPullUtil.optAttr(pp, "platformName", null)); final Position position = parsePosition(XmlPullUtil.optAttr(pp, "platformName", null));
XmlPullUtil.enter(pp, "itdDeparture"); XmlPullUtil.enter(pp, "itdDeparture");
@ -1726,7 +1726,7 @@ public abstract class AbstractEfaProvider extends AbstractNetworkProvider
XmlPullUtil.enter(pp, "r"); XmlPullUtil.enter(pp, "r");
final String assignedId = XmlPullUtil.valueTag(pp, "id"); final String assignedId = XmlPullUtil.valueTag(pp, "id");
XmlPullUtil.valueTag(pp, "a"); XmlPullUtil.valueTag(pp, "a");
final Position position = new Position(XmlPullUtil.optValueTag(pp, "pl", null)); final Position position = super.parsePosition(XmlPullUtil.optValueTag(pp, "pl", null));
XmlPullUtil.skipExit(pp, "r"); XmlPullUtil.skipExit(pp, "r");
/* final Point positionCoordinate = */coordStrToPoint(XmlPullUtil.optValueTag(pp, "c", null)); /* final Point positionCoordinate = */coordStrToPoint(XmlPullUtil.optValueTag(pp, "c", null));
@ -2438,7 +2438,7 @@ public abstract class AbstractEfaProvider extends AbstractNetworkProvider
final Location departureLocation = processItdPointAttributes(pp); final Location departureLocation = processItdPointAttributes(pp);
if (firstDepartureLocation == null) if (firstDepartureLocation == null)
firstDepartureLocation = departureLocation; firstDepartureLocation = departureLocation;
final Position departurePosition = normalizePlatformName(XmlPullUtil.optAttr(pp, "platformName", null)); final Position departurePosition = parsePosition(XmlPullUtil.optAttr(pp, "platformName", null));
XmlPullUtil.enter(pp, "itdPoint"); XmlPullUtil.enter(pp, "itdPoint");
if (XmlPullUtil.test(pp, "itdMapItemList")) if (XmlPullUtil.test(pp, "itdMapItemList"))
XmlPullUtil.next(pp); XmlPullUtil.next(pp);
@ -2462,7 +2462,7 @@ public abstract class AbstractEfaProvider extends AbstractNetworkProvider
throw new IllegalStateException(); throw new IllegalStateException();
final Location arrivalLocation = processItdPointAttributes(pp); final Location arrivalLocation = processItdPointAttributes(pp);
lastArrivalLocation = arrivalLocation; lastArrivalLocation = arrivalLocation;
final Position arrivalPosition = normalizePlatformName(XmlPullUtil.optAttr(pp, "platformName", null)); final Position arrivalPosition = parsePosition(XmlPullUtil.optAttr(pp, "platformName", null));
XmlPullUtil.enter(pp, "itdPoint"); XmlPullUtil.enter(pp, "itdPoint");
if (XmlPullUtil.test(pp, "itdMapItemList")) if (XmlPullUtil.test(pp, "itdMapItemList"))
XmlPullUtil.next(pp); XmlPullUtil.next(pp);
@ -2618,7 +2618,7 @@ public abstract class AbstractEfaProvider extends AbstractNetworkProvider
{ {
final Location stopLocation = processItdPointAttributes(pp); final Location stopLocation = processItdPointAttributes(pp);
final Position stopPosition = normalizePlatformName(XmlPullUtil.optAttr(pp, "platformName", null)); final Position stopPosition = parsePosition(XmlPullUtil.optAttr(pp, "platformName", null));
XmlPullUtil.enter(pp, "itdPoint"); XmlPullUtil.enter(pp, "itdPoint");
XmlPullUtil.require(pp, "itdDateTime"); XmlPullUtil.require(pp, "itdDateTime");
@ -2880,7 +2880,7 @@ public abstract class AbstractEfaProvider extends AbstractNetworkProvider
XmlPullUtil.enter(pp, "r"); XmlPullUtil.enter(pp, "r");
final String id = XmlPullUtil.valueTag(pp, "id"); final String id = XmlPullUtil.valueTag(pp, "id");
XmlPullUtil.optValueTag(pp, "a", null); XmlPullUtil.optValueTag(pp, "a", null);
final Position position = new Position(XmlPullUtil.optValueTag(pp, "pl", null)); final Position position = super.parsePosition(XmlPullUtil.optValueTag(pp, "pl", null));
final String place = normalizeLocationName(XmlPullUtil.optValueTag(pp, "pc", null)); final String place = normalizeLocationName(XmlPullUtil.optValueTag(pp, "pc", null));
final Point coord = coordStrToPoint(XmlPullUtil.optValueTag(pp, "c", null)); final Point coord = coordStrToPoint(XmlPullUtil.optValueTag(pp, "c", null));
XmlPullUtil.skipExit(pp, "r"); XmlPullUtil.skipExit(pp, "r");
@ -3209,32 +3209,23 @@ public abstract class AbstractEfaProvider extends AbstractNetworkProvider
return Currency.getInstance(currencyStr); return Currency.getInstance(currencyStr);
} }
private static final Pattern P_PLATFORM_NAME = Pattern.compile("(?:Gleis|Gl\\.|Bstg\\.)?\\s*" + // private static final Pattern P_POSITION = Pattern.compile(
"(\\d+)\\s*" + // "(?:Gleis|Gl\\.|Bahnsteig|Bstg\\.|Bussteig|Busstg\\.|Steig|Hp\\.|Stop|Pos\\.|Zone|Platform)?\\s*(.+)", Pattern.CASE_INSENSITIVE);
"(?:([A-Z])\\s*(?:-\\s*([A-Z]))?)?", Pattern.CASE_INSENSITIVE);
private static final Position normalizePlatformName(final String platformName) @Override
protected Position parsePosition(final String position)
{ {
if (platformName != null) if (position == null)
{ return null;
final Matcher m = P_PLATFORM_NAME.matcher(platformName);
if (m.matches())
{
final String simple = Integer.toString(Integer.parseInt(m.group(1)));
if (m.group(2) != null && m.group(3) != null)
return new Position(simple + m.group(2) + "-" + m.group(3));
else if (m.group(2) != null)
return new Position(simple + m.group(2));
else
return new Position(simple);
}
else
{
return new Position(platformName);
}
}
return null; if (position.startsWith("Ri.") || position.startsWith("Richtung "))
return null;
final Matcher m = P_POSITION.matcher(position);
if (m.matches())
return super.parsePosition(m.group(1));
return super.parsePosition(position);
} }
private void appendLocation(final StringBuilder uri, final Location location, final String paramSuffix) private void appendLocation(final StringBuilder uri, final Location location, final String paramSuffix)

View file

@ -330,7 +330,7 @@ public abstract class AbstractHafasProvider extends AbstractNetworkProvider
throw new IllegalStateException("cannot handle: " + type); throw new IllegalStateException("cannot handle: " + type);
} }
private static final Position parsePlatform(final XmlPullParser pp) throws XmlPullParserException, IOException private final Position parsePlatform(final XmlPullParser pp) throws XmlPullParserException, IOException
{ {
XmlPullUtil.enter(pp, "Platform"); XmlPullUtil.enter(pp, "Platform");
final String platformText = XmlPullUtil.valueTag(pp, "Text"); final String platformText = XmlPullUtil.valueTag(pp, "Text");
@ -339,7 +339,7 @@ public abstract class AbstractHafasProvider extends AbstractNetworkProvider
if (platformText == null || platformText.length() == 0) if (platformText == null || platformText.length() == 0)
return null; return null;
else else
return new Position(platformText); return parsePosition(platformText);
} }
public SuggestLocationsResult suggestLocations(final CharSequence constraint) throws IOException public SuggestLocationsResult suggestLocations(final CharSequence constraint) throws IOException
@ -627,7 +627,7 @@ public abstract class AbstractHafasProvider extends AbstractNetworkProvider
predictedTime = null; predictedTime = null;
} }
final Position position = platform != null ? new Position("Gl. " + ParserUtils.resolveEntities(platform)) : null; final Position position = parsePosition(ParserUtils.resolveEntities(platform));
final String destinationName; final String destinationName;
if (dir != null) if (dir != null)
@ -2272,7 +2272,7 @@ public abstract class AbstractHafasProvider extends AbstractNetworkProvider
} }
} }
private static final Pattern P_POSITION_PLATFORM = Pattern.compile("Gleis\\s*([^\\s]*)\\s*", Pattern.CASE_INSENSITIVE); private static final Pattern P_POSITION_PLATFORM = Pattern.compile("Gleis\\s*(.*)\\s*", Pattern.CASE_INSENSITIVE);
private Position normalizePosition(final String position) private Position normalizePosition(final String position)
{ {
@ -2281,9 +2281,9 @@ public abstract class AbstractHafasProvider extends AbstractNetworkProvider
final Matcher m = P_POSITION_PLATFORM.matcher(position); final Matcher m = P_POSITION_PLATFORM.matcher(position);
if (!m.matches()) if (!m.matches())
return new Position(position); return parsePosition(position);
return new Position(m.group(1)); return parsePosition(m.group(1));
} }
public NearbyStationsResult queryNearbyStations(final Location location, final int maxDistance, final int maxStations) throws IOException public NearbyStationsResult queryNearbyStations(final Location location, final int maxDistance, final int maxStations) throws IOException

View file

@ -24,8 +24,11 @@ import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.TimeZone; import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import de.schildbach.pte.dto.Point; import de.schildbach.pte.dto.Point;
import de.schildbach.pte.dto.Position;
import de.schildbach.pte.dto.Product; import de.schildbach.pte.dto.Product;
import de.schildbach.pte.dto.Style; import de.schildbach.pte.dto.Style;
@ -157,4 +160,32 @@ public abstract class AbstractNetworkProvider implements NetworkProvider
return normalized.toString(); return normalized.toString();
} }
private static final Pattern P_NAME_SECTION = Pattern.compile("(\\d+)\\s*" + //
"([A-Z](?:\\s*-?\\s*[A-Z])?)?", Pattern.CASE_INSENSITIVE);
private static final Pattern P_NAME_NOSW = Pattern.compile("(\\d+)\\s*" + //
"(Nord|Süd|Ost|West)", Pattern.CASE_INSENSITIVE);
protected Position parsePosition(final String position)
{
if (position == null)
return null;
final Matcher mSection = P_NAME_SECTION.matcher(position);
if (mSection.matches())
{
final String name = Integer.toString(Integer.parseInt(mSection.group(1)));
if (mSection.group(2) != null)
return new Position(name, mSection.group(2).replaceAll("\\s+", ""));
else
return new Position(name);
}
final Matcher mNosw = P_NAME_NOSW.matcher(position);
if (mNosw.matches())
return new Position(Integer.toString(Integer.parseInt(mNosw.group(1))), mNosw.group(2).substring(0, 1));
return new Position(position);
}
} }

View file

@ -250,8 +250,7 @@ public class InvgProvider extends AbstractHafasProvider
destination = new Location(LocationType.ANY, null, null, destinationName); destination = new Location(LocationType.ANY, null, null, destinationName);
} }
final Position position = mDepFine.group(7) != null ? new Position("Gl. " + ParserUtils.resolveEntities(mDepFine.group(7))) final Position position = parsePosition(ParserUtils.resolveEntities(mDepFine.group(7)));
: null;
final Departure dep = new Departure(plannedTime.getTime(), predictedTime != null ? predictedTime.getTime() : null, line, final Departure dep = new Departure(plannedTime.getTime(), predictedTime != null ? predictedTime.getTime() : null, line,
position, destination, null, null); position, destination, null, null);

View file

@ -17,6 +17,8 @@
package de.schildbach.pte; package de.schildbach.pte;
import de.schildbach.pte.dto.Position;
/** /**
* @author Andreas Schildbach * @author Andreas Schildbach
*/ */
@ -34,4 +36,16 @@ public class MvgProvider extends AbstractEfaProvider
{ {
return NETWORK_ID; return NETWORK_ID;
} }
@Override
protected Position parsePosition(final String position)
{
if (position == null)
return null;
if (position.startsWith(" - "))
return super.parsePosition(position.substring(3));
return super.parsePosition(position);
}
} }

View file

@ -19,8 +19,11 @@ package de.schildbach.pte;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import de.schildbach.pte.dto.Point; import de.schildbach.pte.dto.Point;
import de.schildbach.pte.dto.Position;
import de.schildbach.pte.dto.Style; import de.schildbach.pte.dto.Style;
/** /**
@ -73,6 +76,28 @@ public class MvvProvider extends AbstractEfaProvider
return super.parseLine(mot, symbol, name, longName, trainType, trainNum, trainName); return super.parseLine(mot, symbol, name, longName, trainType, trainNum, trainName);
} }
private static final Pattern P_POSITION = Pattern.compile("(Fern|Regio|S-Bahn|U-Bahn|U\\d(?:/U\\d)*)\\s+(.*)");
@Override
protected Position parsePosition(final String position)
{
if (position == null)
return null;
final Matcher m = P_POSITION.matcher(position);
if (m.matches())
{
final char t = m.group(1).charAt(0);
final Position p = super.parsePosition(m.group(2));
if (t == 'S' || t == 'U')
return new Position(p.name + "(" + t + ")", p.section);
else
return p;
}
return super.parsePosition(position);
}
private static final Map<String, Style> STYLES = new HashMap<String, Style>(); private static final Map<String, Style> STYLES = new HashMap<String, Style>();
static static

View file

@ -256,8 +256,7 @@ public class SeptaProvider extends AbstractHafasProvider
destination = new Location(LocationType.ANY, null, null, destinationName); destination = new Location(LocationType.ANY, null, null, destinationName);
} }
final Position position = mDepFine.group(7) != null ? new Position("Gl. " + ParserUtils.resolveEntities(mDepFine.group(7))) final Position position = parsePosition(ParserUtils.resolveEntities(mDepFine.group(7)));
: null;
final Departure dep = new Departure(plannedTime.getTime(), predictedTime != null ? predictedTime.getTime() : null, line, final Departure dep = new Departure(plannedTime.getTime(), predictedTime != null ? predictedTime.getTime() : null, line,
position, destination, null, null); position, destination, null, null);

View file

@ -275,8 +275,7 @@ public class ShProvider extends AbstractHafasProvider
destination = new Location(LocationType.ANY, null, null, destinationName); destination = new Location(LocationType.ANY, null, null, destinationName);
} }
final Position position = mDepFine.group(6) != null ? new Position("Gl. " + ParserUtils.resolveEntities(mDepFine.group(6))) final Position position = parsePosition(ParserUtils.resolveEntities(mDepFine.group(6)));
: null;
final Departure dep = new Departure(plannedTime.getTime(), null, line, position, destination, null, null); final Departure dep = new Departure(plannedTime.getTime(), null, line, position, destination, null, null);

View file

@ -25,18 +25,33 @@ import java.io.Serializable;
public final class Position implements Serializable public final class Position implements Serializable
{ {
public final String name; public final String name;
public final String section;
public Position(final String name) public Position(final String name)
{ {
this(name, null);
}
public Position(final String name, final String section)
{
if (name == null)
throw new IllegalArgumentException("name cannot be null");
// else if (name.length() > 5)
// throw new IllegalArgumentException("name too long: " + name);
if (section != null && section.length() > 3)
throw new IllegalArgumentException("section too long: " + section);
this.name = name; this.name = name;
this.section = section;
} }
@Override @Override
public String toString() public String toString()
{ {
final StringBuilder builder = new StringBuilder("Position("); final StringBuilder builder = new StringBuilder(name);
builder.append(name != null ? name : "null"); if (section != null)
builder.append(")"); builder.append(section);
return builder.toString(); return builder.toString();
} }
@ -48,7 +63,9 @@ public final class Position implements Serializable
if (!(o instanceof Position)) if (!(o instanceof Position))
return false; return false;
final Position other = (Position) o; final Position other = (Position) o;
if (!nullSafeEquals(this.name, other.name)) if (!this.name.equals(other.name))
return false;
if (!nullSafeEquals(this.section, other.section))
return false; return false;
return true; return true;
} }
@ -57,7 +74,8 @@ public final class Position implements Serializable
public int hashCode() public int hashCode()
{ {
int hashCode = 0; int hashCode = 0;
hashCode += nullSafeHashCode(name); hashCode += name.hashCode();
hashCode += nullSafeHashCode(section);
return hashCode; return hashCode;
} }