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>());
}
final Position position = normalizePlatformName(XmlPullUtil.optAttr(pp, "platformName", null));
final Position position = parsePosition(XmlPullUtil.optAttr(pp, "platformName", null));
XmlPullUtil.enter(pp, "itdDeparture");
@ -1726,7 +1726,7 @@ public abstract class AbstractEfaProvider extends AbstractNetworkProvider
XmlPullUtil.enter(pp, "r");
final String assignedId = XmlPullUtil.valueTag(pp, "id");
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");
/* final Point positionCoordinate = */coordStrToPoint(XmlPullUtil.optValueTag(pp, "c", null));
@ -2438,7 +2438,7 @@ public abstract class AbstractEfaProvider extends AbstractNetworkProvider
final Location departureLocation = processItdPointAttributes(pp);
if (firstDepartureLocation == null)
firstDepartureLocation = departureLocation;
final Position departurePosition = normalizePlatformName(XmlPullUtil.optAttr(pp, "platformName", null));
final Position departurePosition = parsePosition(XmlPullUtil.optAttr(pp, "platformName", null));
XmlPullUtil.enter(pp, "itdPoint");
if (XmlPullUtil.test(pp, "itdMapItemList"))
XmlPullUtil.next(pp);
@ -2462,7 +2462,7 @@ public abstract class AbstractEfaProvider extends AbstractNetworkProvider
throw new IllegalStateException();
final Location arrivalLocation = processItdPointAttributes(pp);
lastArrivalLocation = arrivalLocation;
final Position arrivalPosition = normalizePlatformName(XmlPullUtil.optAttr(pp, "platformName", null));
final Position arrivalPosition = parsePosition(XmlPullUtil.optAttr(pp, "platformName", null));
XmlPullUtil.enter(pp, "itdPoint");
if (XmlPullUtil.test(pp, "itdMapItemList"))
XmlPullUtil.next(pp);
@ -2618,7 +2618,7 @@ public abstract class AbstractEfaProvider extends AbstractNetworkProvider
{
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.require(pp, "itdDateTime");
@ -2880,7 +2880,7 @@ public abstract class AbstractEfaProvider extends AbstractNetworkProvider
XmlPullUtil.enter(pp, "r");
final String id = XmlPullUtil.valueTag(pp, "id");
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 Point coord = coordStrToPoint(XmlPullUtil.optValueTag(pp, "c", null));
XmlPullUtil.skipExit(pp, "r");
@ -3209,32 +3209,23 @@ public abstract class AbstractEfaProvider extends AbstractNetworkProvider
return Currency.getInstance(currencyStr);
}
private static final Pattern P_PLATFORM_NAME = Pattern.compile("(?:Gleis|Gl\\.|Bstg\\.)?\\s*" + //
"(\\d+)\\s*" + //
"(?:([A-Z])\\s*(?:-\\s*([A-Z]))?)?", Pattern.CASE_INSENSITIVE);
private static final Pattern P_POSITION = Pattern.compile(
"(?:Gleis|Gl\\.|Bahnsteig|Bstg\\.|Bussteig|Busstg\\.|Steig|Hp\\.|Stop|Pos\\.|Zone|Platform)?\\s*(.+)", Pattern.CASE_INSENSITIVE);
private static final Position normalizePlatformName(final String platformName)
@Override
protected Position parsePosition(final String position)
{
if (platformName != 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);
}
}
if (position == null)
return null;
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)

View file

@ -330,7 +330,7 @@ public abstract class AbstractHafasProvider extends AbstractNetworkProvider
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");
final String platformText = XmlPullUtil.valueTag(pp, "Text");
@ -339,7 +339,7 @@ public abstract class AbstractHafasProvider extends AbstractNetworkProvider
if (platformText == null || platformText.length() == 0)
return null;
else
return new Position(platformText);
return parsePosition(platformText);
}
public SuggestLocationsResult suggestLocations(final CharSequence constraint) throws IOException
@ -627,7 +627,7 @@ public abstract class AbstractHafasProvider extends AbstractNetworkProvider
predictedTime = null;
}
final Position position = platform != null ? new Position("Gl. " + ParserUtils.resolveEntities(platform)) : null;
final Position position = parsePosition(ParserUtils.resolveEntities(platform));
final String destinationName;
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)
{
@ -2281,9 +2281,9 @@ public abstract class AbstractHafasProvider extends AbstractNetworkProvider
final Matcher m = P_POSITION_PLATFORM.matcher(position);
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

View file

@ -24,8 +24,11 @@ import java.util.HashSet;
import java.util.Map;
import java.util.Set;
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.Position;
import de.schildbach.pte.dto.Product;
import de.schildbach.pte.dto.Style;
@ -157,4 +160,32 @@ public abstract class AbstractNetworkProvider implements NetworkProvider
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);
}
final Position position = mDepFine.group(7) != null ? new Position("Gl. " + ParserUtils.resolveEntities(mDepFine.group(7)))
: null;
final Position position = parsePosition(ParserUtils.resolveEntities(mDepFine.group(7)));
final Departure dep = new Departure(plannedTime.getTime(), predictedTime != null ? predictedTime.getTime() : null, line,
position, destination, null, null);

View file

@ -17,6 +17,8 @@
package de.schildbach.pte;
import de.schildbach.pte.dto.Position;
/**
* @author Andreas Schildbach
*/
@ -34,4 +36,16 @@ public class MvgProvider extends AbstractEfaProvider
{
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.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import de.schildbach.pte.dto.Point;
import de.schildbach.pte.dto.Position;
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);
}
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>();
static

View file

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

View file

@ -275,8 +275,7 @@ public class ShProvider extends AbstractHafasProvider
destination = new Location(LocationType.ANY, null, null, destinationName);
}
final Position position = mDepFine.group(6) != null ? new Position("Gl. " + ParserUtils.resolveEntities(mDepFine.group(6)))
: null;
final Position position = parsePosition(ParserUtils.resolveEntities(mDepFine.group(6)));
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 String name;
public final String section;
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.section = section;
}
@Override
public String toString()
{
final StringBuilder builder = new StringBuilder("Position(");
builder.append(name != null ? name : "null");
builder.append(")");
final StringBuilder builder = new StringBuilder(name);
if (section != null)
builder.append(section);
return builder.toString();
}
@ -48,7 +63,9 @@ public final class Position implements Serializable
if (!(o instanceof Position))
return false;
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 true;
}
@ -57,7 +74,8 @@ public final class Position implements Serializable
public int hashCode()
{
int hashCode = 0;
hashCode += nullSafeHashCode(name);
hashCode += name.hashCode();
hashCode += nullSafeHashCode(section);
return hashCode;
}