Truncate route date

This commit is contained in:
max-klaus 2020-03-11 21:37:46 +03:00
parent d69553bdd8
commit 2bbb8b212d
10 changed files with 203 additions and 243 deletions

View file

@ -14,7 +14,7 @@ import net.osmand.binary.OsmandOdb.OsmAndRoutingIndex.RouteEncodingRule;
import net.osmand.binary.OsmandOdb.RestrictionData;
import net.osmand.binary.OsmandOdb.RouteData;
import net.osmand.binary.RouteDataObject.RestrictionInfo;
import net.osmand.router.RouteDataResources;
import net.osmand.util.Algorithms;
import net.osmand.util.MapUtils;
import net.osmand.util.OpeningHoursParser;
@ -92,10 +92,32 @@ public class BinaryMapRouteReaderAdapter {
}
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((t == null) ? 0 : t.hashCode());
result = prime * result + ((v == null) ? 0 : v.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
RouteTypeRule other = (RouteTypeRule) obj;
return Algorithms.objectEquals(other.t, t) && Algorithms.objectEquals(other.v, v);
}
@Override
public void writeToBundle(RouteDataBundle bundle) {
bundle.putString("t", t);
bundle.putString("v", v);
/*
if (intValue != 0) {
bundle.putInt("i", intValue);
}
@ -109,6 +131,7 @@ public class BinaryMapRouteReaderAdapter {
bundle.putInt("fw", forward);
}
bundle.putList("conditions", "c", conditions);
*/
}
@Override
@ -116,6 +139,11 @@ public class BinaryMapRouteReaderAdapter {
}
@Override
public String toString() {
return t + "=" + v;
}
public int isForward() {
return forward;
}
@ -265,7 +293,7 @@ public class BinaryMapRouteReaderAdapter {
}
}
public static class RouteRegion extends BinaryIndexPart implements StringExternalizable<RouteDataBundle> {
public static class RouteRegion extends BinaryIndexPart {
public int regionsRead;
public List<RouteTypeRule> routeEncodingRules = new ArrayList<BinaryMapRouteReaderAdapter.RouteTypeRule>();
public Map<String, Integer> decodingRules = null;
@ -278,32 +306,6 @@ public class BinaryMapRouteReaderAdapter {
int destinationRefTypeRule = -1;
private RouteRegion referenceRouteRegion;
@Override
public void writeToBundle(RouteDataBundle bundle) {
bundle.putInt("regRead", regionsRead);
bundle.putList("encRules", "r", routeEncodingRules);
bundle.putMap("decRules", decodingRules);
bundle.putList("subreg", "s", subregions);
bundle.putList("basesubreg", "s", basesubregions);
bundle.putInt("nameTypeRule", nameTypeRule);
bundle.putInt("refTypeRule", refTypeRule);
bundle.putInt("destinationTypeRule", destinationTypeRule);
bundle.putInt("destinationRefTypeRule", destinationRefTypeRule);
if (referenceRouteRegion != null) {
List<RouteRegion> regions = bundle.getResources().getRouteRegions();
int regionIndex = regions.indexOf(referenceRouteRegion);
assert regionIndex != -1;
bundle.putInt("referenceRouteRegionIndex", regionIndex);
}
}
@Override
public void readFromBundle(RouteDataBundle bundle) {
}
public String getPartName() {
return "Routing";
}
@ -514,7 +516,7 @@ public class BinaryMapRouteReaderAdapter {
}
// Used in C++
public static class RouteSubregion implements StringExternalizable<RouteDataBundle> {
public static class RouteSubregion {
private final static int INT_SIZE = 4;
public final RouteRegion routeReg;
public RouteSubregion(RouteSubregion copy) {
@ -540,51 +542,6 @@ public class BinaryMapRouteReaderAdapter {
public List<RouteSubregion> subregions = null;
public List<RouteDataObject> dataObjects = null;
public void collectResources(RouteDataResources resources) {
List<RouteDataObject> dataObjects = resources.getRouteDataObjects();
List<RouteRegion> regions = resources.getRouteRegions();
if (this.dataObjects != null) {
for (RouteDataObject dataObject : this.dataObjects) {
if (!dataObjects.contains(dataObject)) {
dataObjects.add(dataObject);
}
}
}
if (routeReg != null && !regions.contains(routeReg)) {
regions.add(routeReg);
}
if (subregions != null) {
for (RouteSubregion subregion : subregions) {
RouteRegion routeReg = subregion.routeReg;
if (routeReg != null && !regions.contains(routeReg)) {
regions.add(routeReg);
}
subregion.collectResources(resources);
}
}
}
@Override
public void writeToBundle(RouteDataBundle bundle) {
List<RouteRegion> regions = bundle.getResources().getRouteRegions();
int regionIndex = regions.indexOf(routeReg);
assert regionIndex == -1;
bundle.putInt("ri", regionIndex);
bundle.putInt("l", left);
bundle.putInt("r", right);
bundle.putInt("t", top);
bundle.putInt("b", bottom);
bundle.putList("subregions", "s", subregions);
bundle.putList("dataObjects", "o", dataObjects);
}
@Override
public void readFromBundle(RouteDataBundle bundle) {
}
public int getEstimatedSize(){
int shallow = 7 * INT_SIZE + 4*3;
if (subregions != null) {

View file

@ -1,6 +1,5 @@
package net.osmand.binary;
import net.osmand.Location;
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteRegion;
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteTypeRule;
@ -10,12 +9,10 @@ import net.osmand.util.TransliterationHelper;
import java.text.MessageFormat;
import java.util.Arrays;
import java.util.List;
import gnu.trove.map.hash.TIntObjectHashMap;
public class RouteDataObject implements StringExternalizable<RouteDataBundle> {
public class RouteDataObject {
/*private */static final int RESTRICTION_SHIFT = 3;
/*private */static final int RESTRICTION_MASK = 7;
public static int HEIGHT_UNDEFINED = -80000;
@ -38,26 +35,6 @@ public class RouteDataObject implements StringExternalizable<RouteDataBundle> {
// mixed array [0, height, cumulative_distance height, cumulative_distance, height, ...] - length is length(points)*2
public float[] heightDistanceArray = null;
@Override
public void writeToBundle(RouteDataBundle bundle) {
List<RouteRegion> regions = bundle.getResources().getRouteRegions();
int regionIndex = regions.indexOf(region);
assert regionIndex != -1;
bundle.putInt("ri", regionIndex);
bundle.putArray("t", types);
bundle.putArray("pt", pointTypes);
bundle.putArray("pn", pointNames);
bundle.putArray("pnt", pointNameTypes);
bundle.putMap("n", names);
bundle.putArray("ni", nameIds);
}
@Override
public void readFromBundle(RouteDataBundle bundle) {
}
public RouteDataObject(RouteRegion region) {
this.region = region;
}

View file

@ -310,12 +310,26 @@ public class StringBundle {
return null;
}
StringBuilder b = new StringBuilder();
for (int[] value : a) {
if (b.length() > 0) {
for (int i = 0; i < a.length; i++) {
if (i > 0) {
b.append(";");
}
b.append(intArrayToString(value));
int[] arr = a[i];
if (arr != null && arr.length > 0) {
b.append(intArrayToString(arr));
}
}
/*
for (int i = 0; i < a.length; i++) {
int[] value = a[i];
if (value != null && value.length > 0) {
if (b.length() > 0) {
b.append(";");
}
b.append(i).append(":").append(intArrayToString(value));
}
}
*/
return b.toString();
}
@ -323,6 +337,7 @@ public class StringBundle {
if (a == null) {
return null;
}
/*
String[] items = a.split(";");
int[][] res = new int[items.length][];
for (int i = 0; i < items.length; i++) {
@ -332,7 +347,8 @@ public class StringBundle {
res[i][k] = Integer.parseInt(subItems[k]);
}
}
return res;
*/
return null;//res;
}
private String strArrayToString(String[] a) {
@ -354,11 +370,14 @@ public class StringBundle {
return null;
}
StringBuilder b = new StringBuilder();
for (String[] value : a) {
if (b.length() > 0) {
b.append(0x1F);
for (int i = 0; i < a.length; i++) {
String[] value = a[i];
if (value != null && value.length > 0) {
if (b.length() > 0) {
b.append(0x1F);
}
b.append(String.valueOf(i)).append(":").append(strArrayToString(value));
}
b.append(strArrayToString(value));
}
return b.toString();
}

View file

@ -2,14 +2,11 @@ package net.osmand.binary;
import net.osmand.binary.StringBundle.Item;
import java.io.IOException;
import java.util.Map;
import java.util.Map.Entry;
public abstract class StringBundleWriter {
private StringBundle bundle;
protected String result;
public StringBundleWriter(StringBundle bundle) {
this.bundle = bundle;
@ -19,10 +16,6 @@ public abstract class StringBundleWriter {
return bundle;
}
public String getResult() {
return result;
}
protected abstract void writeItem(String name, Item item);
public void writeBundle() {

View file

@ -10,7 +10,6 @@ import org.apache.commons.logging.Log;
import org.xmlpull.v1.XmlSerializer;
import java.io.IOException;
import java.io.StringWriter;
import java.util.List;
import java.util.Map.Entry;
@ -18,23 +17,8 @@ public class StringBundleXmlWriter extends StringBundleWriter {
public final static Log log = PlatformUtil.getLog(StringBundleXmlWriter.class);
private StringWriter writer;
private XmlSerializer serializer;
public StringBundleXmlWriter(StringBundle bundle) {
super(bundle);
writer = new StringWriter();
serializer = PlatformUtil.newSerializer();
try {
serializer.setOutput(writer);
serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
serializer.startDocument("UTF-8", true);
} catch (IOException e) {
serializer = null;
}
}
public StringBundleXmlWriter(StringBundle bundle, XmlSerializer serializer) {
super(bundle);
this.serializer = serializer;
@ -57,9 +41,6 @@ public class StringBundleXmlWriter extends StringBundleWriter {
super.writeBundle();
try {
serializer.flush();
if (writer != null) {
result = writer.toString();
}
} catch (Exception e) {
log.error("Error writing string bundle as xml", e);
}
@ -72,10 +53,6 @@ public class StringBundleXmlWriter extends StringBundleWriter {
case STRING: {
StringItem stringItem = (StringItem) item;
serializer.attribute(null, name, stringItem.getValue());
//serializer.startTag(null, "s");
//serializer.attribute(null, "n", name);
//serializer.text(stringItem.getValue());
//serializer.endTag(null, "s");
break;
}
case LIST: {

View file

@ -1,23 +1,16 @@
package net.osmand.router;
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteRegion;
import net.osmand.binary.RouteDataObject;
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteTypeRule;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.LinkedHashMap;
import java.util.Map;
public class RouteDataResources {
private List<RouteDataObject> routeDataObjects = new LinkedList<>();
private List<RouteRegion> routeRegions = new LinkedList<>();
private Map<RouteTypeRule, Integer> rules = new LinkedHashMap<>();
public List<RouteDataObject> getRouteDataObjects() {
return routeDataObjects;
public Map<RouteTypeRule, Integer> getRules() {
return rules;
}
public List<RouteRegion> getRouteRegions() {
return routeRegions;
}
}

View file

@ -7,13 +7,11 @@ import net.osmand.GPXUtilities.Track;
import net.osmand.GPXUtilities.TrkSegment;
import net.osmand.GPXUtilities.WptPt;
import net.osmand.Location;
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteRegion;
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteTypeRule;
import net.osmand.binary.RouteDataBundle;
import net.osmand.binary.RouteDataObject;
import net.osmand.binary.StringBundle;
import net.osmand.binary.StringBundleWriter;
import net.osmand.binary.StringBundleXmlWriter;
import net.osmand.util.Algorithms;
import org.xmlpull.v1.XmlSerializer;
@ -44,7 +42,10 @@ public class RouteExporter {
final RouteDataBundle bundle = new RouteDataBundle(resources);
for (RouteSegmentResult sr : route) {
sr.collectResources(resources);
sr.collectTypes(resources);
}
for (RouteSegmentResult sr : route) {
sr.collectNames(resources);
}
List<StringBundle> routeItems = new ArrayList<>();
@ -53,23 +54,16 @@ public class RouteExporter {
sr.writeToBundle(itemBundle);
routeItems.add(itemBundle);
}
bundle.putBundleList("route", "s", routeItems);
bundle.putBundleList("route", "segment", routeItems);
List<StringBundle> dataObjects = new ArrayList<>();
for (RouteDataObject dataObject : resources.getRouteDataObjects()) {
Map<RouteTypeRule, Integer> rules = resources.getRules();
for (RouteTypeRule rule : rules.keySet()) {
RouteDataBundle objectBundle = new RouteDataBundle(resources);
dataObject.writeToBundle(objectBundle);
rule.writeToBundle(objectBundle);
dataObjects.add(objectBundle);
}
bundle.putBundleList("objects", "o", dataObjects);
List<StringBundle> regions = new ArrayList<>();
for (RouteRegion routeRegion : resources.getRouteRegions()) {
RouteDataBundle regionBundle = new RouteDataBundle(resources);
routeRegion.writeToBundle(regionBundle);
regions.add(regionBundle);
}
bundle.putBundleList("regions", "r", regions);
bundle.putBundleList("types", "type", dataObjects);
GPXFile gpx = new GPXFile("OsmAnd");
gpx.author = OSMAND_ROUTER;

View file

@ -1,24 +1,5 @@
package net.osmand.router;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import gnu.trove.iterator.TIntIterator;
import gnu.trove.list.array.TIntArrayList;
import gnu.trove.set.hash.TIntHashSet;
import net.osmand.PlatformUtil;
import net.osmand.binary.BinaryMapIndexReader;
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteTypeRule;
@ -37,6 +18,26 @@ import net.osmand.util.Algorithms;
import net.osmand.util.MapAlgorithms;
import net.osmand.util.MapUtils;
import org.apache.commons.logging.Log;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import gnu.trove.iterator.TIntIterator;
import gnu.trove.list.array.TIntArrayList;
import gnu.trove.set.hash.TIntHashSet;
public class RouteResultPreparation {
public static boolean PRINT_TO_CONSOLE_ROUTE_INFORMATION_TO_TEST = false;
@ -1563,7 +1564,7 @@ public class RouteResultPreparation {
return null;
}
private static int[] calculateRawTurnLanes(String turnLanes, int calcTurnType) {
public static int[] calculateRawTurnLanes(String turnLanes, int calcTurnType) {
String[] splitLaneOptions = turnLanes.split("\\|", -1);
int[] lanes = new int[splitLaneOptions.length];
for (int i = 0; i < splitLaneOptions.length; i++) {

View file

@ -1,17 +1,21 @@
package net.osmand.router;
import net.osmand.binary.BinaryMapRouteReaderAdapter;
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteRegion;
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteSubregion;
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteTypeRule;
import net.osmand.binary.RouteDataBundle;
import net.osmand.binary.RouteDataObject;
import net.osmand.binary.StringExternalizable;
import net.osmand.data.LatLon;
import net.osmand.util.Algorithms;
import net.osmand.util.MapUtils;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
public class RouteSegmentResult implements StringExternalizable<RouteDataBundle> {
@ -27,8 +31,10 @@ public class RouteSegmentResult implements StringExternalizable<RouteDataBundle>
private String description = "";
// this make not possible to make turns in between segment result for now
private TurnType turnType;
private static final DecimalFormat SPEED_FORMATTER = new DecimalFormat("#.##");
public RouteSegmentResult(RouteDataObject object, int startPointIndex, int endPointIndex) {
this.object = object;
this.startPointIndex = startPointIndex;
@ -36,46 +42,110 @@ public class RouteSegmentResult implements StringExternalizable<RouteDataBundle>
updateCapacity();
}
void collectResources(RouteDataResources resources) {
List<RouteDataObject> dataObjects = resources.getRouteDataObjects();
List<RouteRegion> regions = resources.getRouteRegions();
if (!dataObjects.contains(object)) {
dataObjects.add(object);
void collectTypes(RouteDataResources resources) {
Map<RouteTypeRule, Integer> rules = resources.getRules();
if (object.types != null) {
collectRules(rules, object.types);
}
RouteRegion region = object.region;
if (!regions.contains(region)) {
regions.add(region);
}
List<RouteSubregion> baseSubregions = region.getBaseSubregions();
if (baseSubregions != null) {
for (RouteSubregion subregion : baseSubregions) {
subregion.collectResources(resources);
}
}
List<RouteSubregion> subregions = region.getSubregions();
if (subregions != null) {
for (RouteSubregion subregion : subregions) {
subregion.collectResources(resources);
if (object.pointTypes != null) {
for (int[] types : object.pointTypes) {
if (types != null) {
collectRules(rules, types);
}
}
}
}
void collectNames(RouteDataResources resources) {
Map<RouteTypeRule, Integer> rules = resources.getRules();
if (object.nameIds != null) {
for (int nameId : object.nameIds) {
String name = object.names.get(nameId);
String tag = object.region.quickGetEncodingRule(nameId).getTag();
RouteTypeRule r = new RouteTypeRule(tag, name);
if (!rules.containsKey(r)) {
rules.put(r, rules.size());
}
}
}
}
private void collectRules(Map<RouteTypeRule, Integer> rules, int[] types) {
RouteRegion region = object.region;
for (int type : types) {
RouteTypeRule rule = region.quickGetEncodingRule(type);
if (!rules.containsKey(rule)) {
rules.put(rule, rules.size());
}
}
}
private int[] convertTypes(int[] types, Map<RouteTypeRule, Integer> rules) {
int[] res = new int[types.length];
for (int i = 0; i < types.length; i++) {
int type = types[i];
RouteTypeRule rule = object.region.quickGetEncodingRule(type);
Integer ruleId = rules.get(rule);
if (ruleId == null) {
throw new IllegalArgumentException("Cannot find collected rule: " + rule.toString());
}
res[i] = ruleId;
}
return res;
}
private int[][] convertTypes(int[][] types, Map<RouteTypeRule, Integer> rules) {
int[][] res = new int[types.length][];
for (int i = 0; i < types.length; i++) {
int[] typesArr = types[i];
if (typesArr != null) {
res[i] = convertTypes(typesArr, rules);
}
}
return res;
}
private int[] convertNameIds(int[] nameIds, Map<RouteTypeRule, Integer> rules) {
int[] res = new int[nameIds.length];
for (int i = 0; i < nameIds.length; i++) {
int nameId = nameIds[i];
String name = object.names.get(nameId);
String tag = object.region.quickGetEncodingRule(nameId).getTag();
RouteTypeRule rule = new RouteTypeRule(tag, name);
Integer ruleId = rules.get(rule);
if (ruleId == null) {
throw new IllegalArgumentException("Cannot find collected rule: " + rule.toString());
}
res[i] = ruleId;
}
return res;
}
@Override
public void writeToBundle(RouteDataBundle bundle) {
List<RouteDataObject> dataObjects = bundle.getResources().getRouteDataObjects();
int dataObjectIndex = dataObjects.indexOf(object);
assert dataObjectIndex != -1;
bundle.putInt("i", dataObjectIndex);
bundle.putInt("si", startPointIndex);
bundle.putInt("ei", endPointIndex);
bundle.putFloat("st", segmentTime);
bundle.putFloat("rt", routingTime);
bundle.putFloat("s", speed);
bundle.putFloat("d", distance);
bundle.putObject("t", turnType);
Map<RouteTypeRule, Integer> rules = bundle.getResources().getRules();
bundle.putFloat("segmentTime", segmentTime);
bundle.putString("speed", SPEED_FORMATTER.format(speed));
if (turnType != null) {
bundle.putString("turnType", turnType.toXmlString());
String turnLanes = object.getValue("turn:lanes");
if (!Algorithms.isEmpty(turnLanes)) {
int[] rawLanes = RouteResultPreparation.calculateRawTurnLanes(turnLanes, turnType.getValue());
if (rawLanes.length > 0) {
StringBuilder turnLanesRes = new StringBuilder();
for (int lane : rawLanes) {
if (turnLanesRes.length() > 0) {
turnLanesRes.append(",");
}
turnLanesRes.append(TurnType.valueOf(lane, false).toXmlString());
}
bundle.putString("turnLanes", turnLanesRes.toString());
}
}
}
bundle.putArray("types", convertTypes(object.types, rules));
bundle.putArray("pointTypes", convertTypes(object.pointTypes, rules));
bundle.putArray("names", convertNameIds(object.nameIds, rules));
}
@Override

View file

@ -1,13 +1,8 @@
package net.osmand.router;
import net.osmand.binary.RouteDataBundle;
import net.osmand.binary.StringBundle;
import net.osmand.binary.StringExternalizable;
import gnu.trove.list.array.TIntArrayList;
import gnu.trove.set.hash.TIntHashSet;
public class TurnType implements StringExternalizable<RouteDataBundle> {
public class TurnType {
public static final int C = 1;//"C"; // continue (go straight) //$NON-NLS-1$
public static final int TL = 2; // turn left //$NON-NLS-1$
public static final int TSLL = 3; // turn slightly left //$NON-NLS-1$
@ -23,22 +18,6 @@ public class TurnType implements StringExternalizable<RouteDataBundle> {
public static final int RNDB = 13; // Roundabout
public static final int RNLB = 14; // Roundabout left
@Override
public void writeToBundle(RouteDataBundle bundle) {
bundle.putInt("v", value);
bundle.putInt("eo", exitOut);
bundle.putFloat("ta", turnAngle);
bundle.putBoolean("sts", skipToSpeak);
bundle.putArray("ln", lanes);
bundle.putBoolean("plt", possiblyLeftTurn);
bundle.putBoolean("prt", possiblyRightTurn);
}
@Override
public void readFromBundle(RouteDataBundle bundle) {
}
public static TurnType straight() {
return valueOf(C, false);
}