mirror of
https://gitlab.com/oeffi/public-transport-enabler.git
synced 2025-07-17 23:49:50 +00:00
AbstractHafasClientInterfaceProvider: Parse 'polyG' for the exact path of a trip.
This commit is contained in:
parent
979a5c95a4
commit
2550c68771
4 changed files with 156 additions and 2 deletions
|
@ -78,6 +78,7 @@ import de.schildbach.pte.dto.Trip;
|
|||
import de.schildbach.pte.dto.TripOptions;
|
||||
import de.schildbach.pte.exception.ParserException;
|
||||
import de.schildbach.pte.util.ParserUtils;
|
||||
import de.schildbach.pte.util.PolylineFormat;
|
||||
|
||||
import okhttp3.HttpUrl;
|
||||
|
||||
|
@ -552,7 +553,7 @@ public abstract class AbstractHafasClientInterfaceProvider extends AbstractHafas
|
|||
? "\"jnyFltrL\":[{\"value\":\"" + jnyFltr + "\",\"mode\":\"BIT\",\"type\":\"PROD\"}]," : "") //
|
||||
+ "\"gisFltrL\":[{\"mode\":\"FB\",\"profile\":{\"type\":\"F\",\"linDistRouting\":false,\"maxdist\":2000},\"type\":\"M\",\"meta\":\""
|
||||
+ meta + "\"}]," //
|
||||
+ "\"getPolyline\":false,\"getPasslist\":true,\"getIST\":false,\"getEco\":false,\"extChgTime\":-1}", //
|
||||
+ "\"getPolyline\":true,\"getPasslist\":true,\"getIST\":false,\"getEco\":false,\"extChgTime\":-1}", //
|
||||
false);
|
||||
|
||||
final HttpUrl url = requestUrl(request);
|
||||
|
@ -620,6 +621,7 @@ public abstract class AbstractHafasClientInterfaceProvider extends AbstractHafas
|
|||
final JSONArray locList = common.getJSONArray("locL");
|
||||
final List<String> operators = parseOpList(common.getJSONArray("opL"));
|
||||
final List<Line> lines = parseProdList(common.getJSONArray("prodL"), operators, styles);
|
||||
final List<String> encodedPolylines = parsePolyList(common.getJSONArray("polyL"));
|
||||
|
||||
final JSONArray outConList = res.optJSONArray("outConL");
|
||||
final List<Trip> trips = new ArrayList<>(outConList.length());
|
||||
|
@ -673,6 +675,27 @@ public abstract class AbstractHafasClientInterfaceProvider extends AbstractHafas
|
|||
intermediateStops = null;
|
||||
}
|
||||
|
||||
final List<Point> path;
|
||||
final JSONObject polyG = jny.optJSONObject("polyG");
|
||||
if (polyG != null) {
|
||||
final int crdSysX = polyG.optInt("crdSysX", -1);
|
||||
if (crdSysX != -1) {
|
||||
final String crdSysType = crdSysList.getJSONObject(crdSysX).getString("type");
|
||||
if (!"WGS84".equals(crdSysType))
|
||||
throw new RuntimeException("unknown type: " + crdSysType);
|
||||
}
|
||||
final JSONArray polyXList = polyG.getJSONArray("polyXL");
|
||||
path = new LinkedList<>();
|
||||
final int polyXListLen = polyXList.length();
|
||||
checkState(polyXListLen <= 1);
|
||||
for (int i = 0; i < polyXListLen; i++) {
|
||||
final String encodedPolyline = encodedPolylines.get(polyXList.getInt(i));
|
||||
path.addAll(PolylineFormat.decode(encodedPolyline));
|
||||
}
|
||||
} else {
|
||||
path = null;
|
||||
}
|
||||
|
||||
final JSONArray remList = jny.optJSONArray("remL");
|
||||
String message = null;
|
||||
if (remList != null) {
|
||||
|
@ -684,7 +707,7 @@ public abstract class AbstractHafasClientInterfaceProvider extends AbstractHafas
|
|||
}
|
||||
}
|
||||
|
||||
leg = new Trip.Public(line, destination, departureStop, arrivalStop, intermediateStops, null,
|
||||
leg = new Trip.Public(line, destination, departureStop, arrivalStop, intermediateStops, path,
|
||||
message);
|
||||
} else if ("DEVI".equals(secType)) {
|
||||
leg = new Trip.Individual(Trip.Individual.Type.TRANSFER, departureStop.location,
|
||||
|
@ -1036,6 +1059,18 @@ public abstract class AbstractHafasClientInterfaceProvider extends AbstractHafas
|
|||
return lines;
|
||||
}
|
||||
|
||||
private List<String> parsePolyList(final JSONArray polyList) throws JSONException {
|
||||
final int len = polyList.length();
|
||||
final List<String> polylines = new ArrayList<>(len);
|
||||
|
||||
for (int i = 0; i < len; i++) {
|
||||
final JSONObject poly = polyList.getJSONObject(i);
|
||||
checkState(poly.getBoolean("delta"));
|
||||
polylines.add(poly.getString("crdEncYX"));
|
||||
}
|
||||
return polylines;
|
||||
}
|
||||
|
||||
protected Line newLine(final String id, final String operator, final Product product, final @Nullable String name,
|
||||
final @Nullable String shortName, final @Nullable String number, final Style style) {
|
||||
final String longName;
|
||||
|
|
|
@ -43,6 +43,10 @@ public final class Point implements Serializable {
|
|||
return new Point(lat / 1E6, lon / 1E6);
|
||||
}
|
||||
|
||||
public static Point from1E5(final int lat, final int lon) {
|
||||
return new Point(lat / 1E5, lon / 1E5);
|
||||
}
|
||||
|
||||
public double getLatAsDouble() {
|
||||
return lat;
|
||||
}
|
||||
|
@ -59,6 +63,14 @@ public final class Point implements Serializable {
|
|||
return (int) Math.round(lon * 1E6);
|
||||
}
|
||||
|
||||
public int getLatAs1E5() {
|
||||
return (int) Math.round(lat * 1E5);
|
||||
}
|
||||
|
||||
public int getLonAs1E5() {
|
||||
return (int) Math.round(lon * 1E5);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (o == this)
|
||||
|
|
67
enabler/src/de/schildbach/pte/util/PolylineFormat.java
Normal file
67
enabler/src/de/schildbach/pte/util/PolylineFormat.java
Normal file
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Copyright 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.schildbach.pte.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import de.schildbach.pte.dto.Point;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Implementation of the
|
||||
* <a href="https://developers.google.com/maps/documentation/utilities/polylinealgorithm">Encoded Polyline
|
||||
* Algorithm Format</a>.
|
||||
* </p>
|
||||
*
|
||||
* @author Andreas Schildbach
|
||||
*/
|
||||
public final class PolylineFormat {
|
||||
public static List<Point> decode(final String encodedPolyline) {
|
||||
final int len = encodedPolyline.length();
|
||||
final List<Point> path = new ArrayList<>(len / 2);
|
||||
|
||||
int lat = 0;
|
||||
int lon = 0;
|
||||
int index = 0;
|
||||
while (index < len) {
|
||||
int latResult = 1;
|
||||
int latShift = 0;
|
||||
int latB;
|
||||
do {
|
||||
latB = encodedPolyline.charAt(index++) - 63 - 1;
|
||||
latResult += latB << latShift;
|
||||
latShift += 5;
|
||||
} while (latB >= 0x1f);
|
||||
lat += (latResult & 1) != 0 ? ~(latResult >> 1) : (latResult >> 1);
|
||||
|
||||
int lonResult = 1;
|
||||
int lonShift = 0;
|
||||
int lonB;
|
||||
do {
|
||||
lonB = encodedPolyline.charAt(index++) - 63 - 1;
|
||||
lonResult += lonB << lonShift;
|
||||
lonShift += 5;
|
||||
} while (lonB >= 0x1f);
|
||||
lon += (lonResult & 1) != 0 ? ~(lonResult >> 1) : (lonResult >> 1);
|
||||
|
||||
path.add(Point.from1E5(lat, lon));
|
||||
}
|
||||
return path;
|
||||
}
|
||||
}
|
40
enabler/test/de/schildbach/pte/util/PolylineFormatTest.java
Normal file
40
enabler/test/de/schildbach/pte/util/PolylineFormatTest.java
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package de.schildbach.pte.util;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import de.schildbach.pte.dto.Point;
|
||||
|
||||
/**
|
||||
* @author Andreas Schildbach
|
||||
*/
|
||||
public class PolylineFormatTest {
|
||||
@Test
|
||||
public void test() {
|
||||
final List<Point> polyline = PolylineFormat.decode(
|
||||
"}qfeHyn|bBnBdA\\R]xBzA|@r@f@u@hCWS{@bCe@t@e@v@h@vCIFu@`@MPDJ@L?NAPIZXf@|@`Br@pAHLZp@~@jBbArBbBjDLTTd@fAzBcFnH[d@Vf@iA`BWb@t@zAb@~@LTNNdCzE~A{BAA??");
|
||||
assertEquals(44, polyline.size());
|
||||
assertEquals(Point.fromDouble(48.2078300, 16.3711700), polyline.get(0));
|
||||
assertEquals(Point.fromDouble(48.2051400, 16.3579600), polyline.get(43));
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue