Added lanes to gpx export. Write route segments to gpx.
This commit is contained in:
parent
b192fc7cd9
commit
0fb78ed4f6
15 changed files with 1107 additions and 102 deletions
|
@ -94,8 +94,13 @@ public class GPXUtilities {
|
|||
}
|
||||
}
|
||||
|
||||
public interface GPXExtensionsWriter {
|
||||
public void writeExtensions(XmlSerializer serializer);
|
||||
}
|
||||
|
||||
public static class GPXExtensions {
|
||||
Map<String, String> extensions = null;
|
||||
GPXExtensionsWriter extensionsWriter = null;
|
||||
|
||||
public Map<String, String> getExtensionsToRead() {
|
||||
if (extensions == null) {
|
||||
|
@ -104,6 +109,14 @@ public class GPXUtilities {
|
|||
return extensions;
|
||||
}
|
||||
|
||||
public GPXExtensionsWriter getExtensionsWriter() {
|
||||
return extensionsWriter;
|
||||
}
|
||||
|
||||
public void setExtensionsWriter(GPXExtensionsWriter extensionsWriter) {
|
||||
this.extensionsWriter = extensionsWriter;
|
||||
}
|
||||
|
||||
public int getColor(int defColor) {
|
||||
String clrValue = null;
|
||||
if (extensions != null) {
|
||||
|
@ -1600,10 +1613,17 @@ public class GPXUtilities {
|
|||
}
|
||||
|
||||
private static void writeExtensions(XmlSerializer serializer, GPXExtensions p) throws IOException {
|
||||
if (!p.getExtensionsToRead().isEmpty()) {
|
||||
Map<String, String> extensionsToRead = p.getExtensionsToRead();
|
||||
GPXExtensionsWriter extensionsWriter = p.getExtensionsWriter();
|
||||
if (!extensionsToRead.isEmpty() || extensionsWriter != null) {
|
||||
serializer.startTag(null, "extensions");
|
||||
for (Entry<String, String> s : p.getExtensionsToRead().entrySet()) {
|
||||
writeNotNullText(serializer, s.getKey(), s.getValue());
|
||||
if (!extensionsToRead.isEmpty()) {
|
||||
for (Entry<String, String> s : extensionsToRead.entrySet()) {
|
||||
writeNotNullText(serializer, s.getKey(), s.getValue());
|
||||
}
|
||||
}
|
||||
if (extensionsWriter != null) {
|
||||
extensionsWriter.writeExtensions(serializer);
|
||||
}
|
||||
serializer.endTag(null, "extensions");
|
||||
}
|
||||
|
|
|
@ -1,19 +1,8 @@
|
|||
package net.osmand.binary;
|
||||
|
||||
import gnu.trove.iterator.TLongObjectIterator;
|
||||
import gnu.trove.list.array.TIntArrayList;
|
||||
import gnu.trove.list.array.TLongArrayList;
|
||||
import gnu.trove.map.hash.TIntObjectHashMap;
|
||||
import gnu.trove.map.hash.TLongObjectHashMap;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import com.google.protobuf.CodedInputStream;
|
||||
import com.google.protobuf.InvalidProtocolBufferException;
|
||||
import com.google.protobuf.WireFormat;
|
||||
|
||||
import net.osmand.PlatformUtil;
|
||||
import net.osmand.ResultMatcher;
|
||||
|
@ -25,27 +14,51 @@ 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.MapUtils;
|
||||
import net.osmand.util.OpeningHoursParser;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
|
||||
import com.google.protobuf.CodedInputStream;
|
||||
import com.google.protobuf.InvalidProtocolBufferException;
|
||||
import com.google.protobuf.WireFormat;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import gnu.trove.iterator.TLongObjectIterator;
|
||||
import gnu.trove.list.array.TIntArrayList;
|
||||
import gnu.trove.list.array.TLongArrayList;
|
||||
import gnu.trove.map.hash.TIntObjectHashMap;
|
||||
import gnu.trove.map.hash.TLongObjectHashMap;
|
||||
|
||||
public class BinaryMapRouteReaderAdapter {
|
||||
protected static final Log LOG = PlatformUtil.getLog(BinaryMapRouteReaderAdapter.class);
|
||||
private static final int SHIFT_COORDINATES = 4;
|
||||
|
||||
private static class RouteTypeCondition {
|
||||
private static class RouteTypeCondition implements StringExternalizable<RouteDataBundle> {
|
||||
String condition = "";
|
||||
OpeningHoursParser.OpeningHours hours = null;
|
||||
String value;
|
||||
int ruleid;
|
||||
|
||||
@Override
|
||||
public void writeToBundle(RouteDataBundle bundle) {
|
||||
bundle.putString("condition", condition);
|
||||
bundle.putString("value", value);
|
||||
bundle.putInt("ruleid", ruleid);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromBundle(RouteDataBundle bundle) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public static class RouteTypeRule {
|
||||
public static class RouteTypeRule implements StringExternalizable<RouteDataBundle> {
|
||||
private final static int ACCESS = 1;
|
||||
private final static int ONEWAY = 2;
|
||||
private final static int HIGHWAY_TYPE = 3;
|
||||
|
@ -79,6 +92,22 @@ public class BinaryMapRouteReaderAdapter {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToBundle(RouteDataBundle bundle) {
|
||||
bundle.putString("t", t);
|
||||
bundle.putString("v", v);
|
||||
bundle.putInt("intValue", intValue);
|
||||
bundle.putFloat("floatValue", floatValue);
|
||||
bundle.putInt("type", type);
|
||||
bundle.putList("conditions", "condition", conditions);
|
||||
bundle.putInt("forward", forward);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromBundle(RouteDataBundle bundle) {
|
||||
|
||||
}
|
||||
|
||||
public int isForward() {
|
||||
return forward;
|
||||
}
|
||||
|
@ -228,7 +257,7 @@ public class BinaryMapRouteReaderAdapter {
|
|||
}
|
||||
}
|
||||
|
||||
public static class RouteRegion extends BinaryIndexPart {
|
||||
public static class RouteRegion extends BinaryIndexPart implements StringExternalizable<RouteDataBundle> {
|
||||
public int regionsRead;
|
||||
public List<RouteTypeRule> routeEncodingRules = new ArrayList<BinaryMapRouteReaderAdapter.RouteTypeRule>();
|
||||
public Map<String, Integer> decodingRules = null;
|
||||
|
@ -240,11 +269,36 @@ public class BinaryMapRouteReaderAdapter {
|
|||
int destinationTypeRule = -1;
|
||||
int destinationRefTypeRule = -1;
|
||||
private RouteRegion referenceRouteRegion;
|
||||
|
||||
|
||||
@Override
|
||||
public void writeToBundle(RouteDataBundle bundle) {
|
||||
bundle.putInt("regionsRead", regionsRead);
|
||||
bundle.putList("routeEncodingRules", "rule", routeEncodingRules);
|
||||
bundle.putMap("decodingRules", decodingRules);
|
||||
bundle.putList("subregions", "subregion", subregions);
|
||||
bundle.putList("basesubregions", "subregion", 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";
|
||||
}
|
||||
|
||||
|
||||
public int getFieldNumber() {
|
||||
return OsmandOdb.OsmAndStructure.ROUTINGINDEX_FIELD_NUMBER;
|
||||
|
@ -452,7 +506,7 @@ public class BinaryMapRouteReaderAdapter {
|
|||
}
|
||||
|
||||
// Used in C++
|
||||
public static class RouteSubregion {
|
||||
public static class RouteSubregion implements StringExternalizable<RouteDataBundle> {
|
||||
private final static int INT_SIZE = 4;
|
||||
public final RouteRegion routeReg;
|
||||
public RouteSubregion(RouteSubregion copy) {
|
||||
|
@ -477,7 +531,52 @@ public class BinaryMapRouteReaderAdapter {
|
|||
public int shiftToData;
|
||||
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("routeRegIndex", regionIndex);
|
||||
|
||||
bundle.putInt("left", left);
|
||||
bundle.putInt("right", right);
|
||||
bundle.putInt("top", top);
|
||||
bundle.putInt("bottom", bottom);
|
||||
|
||||
bundle.putList("subregions", "subregion", subregions);
|
||||
bundle.putList("dataObjects", "object", dataObjects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromBundle(RouteDataBundle bundle) {
|
||||
|
||||
}
|
||||
|
||||
public int getEstimatedSize(){
|
||||
int shallow = 7 * INT_SIZE + 4*3;
|
||||
if (subregions != null) {
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
package net.osmand.binary;
|
||||
|
||||
import net.osmand.router.RouteDataResources;
|
||||
|
||||
public class RouteDataBundle extends StringBundle {
|
||||
|
||||
private RouteDataResources resources;
|
||||
|
||||
public RouteDataBundle(RouteDataResources resources) {
|
||||
this.resources = resources;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StringBundle newInstance() {
|
||||
return new RouteDataBundle(resources);
|
||||
}
|
||||
|
||||
public RouteDataResources getResources() {
|
||||
return resources;
|
||||
}
|
||||
}
|
|
@ -1,11 +1,6 @@
|
|||
package net.osmand.binary;
|
||||
|
||||
|
||||
import gnu.trove.map.hash.TIntObjectHashMap;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import java.util.Arrays;
|
||||
|
||||
import net.osmand.Location;
|
||||
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteRegion;
|
||||
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteTypeRule;
|
||||
|
@ -13,12 +8,18 @@ import net.osmand.util.Algorithms;
|
|||
import net.osmand.util.MapUtils;
|
||||
import net.osmand.util.TransliterationHelper;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class RouteDataObject {
|
||||
import gnu.trove.map.hash.TIntObjectHashMap;
|
||||
|
||||
|
||||
public class RouteDataObject implements StringExternalizable<RouteDataBundle> {
|
||||
/*private */static final int RESTRICTION_SHIFT = 3;
|
||||
/*private */static final int RESTRICTION_MASK = 7;
|
||||
public static int HEIGHT_UNDEFINED = -80000;
|
||||
|
||||
|
||||
public final RouteRegion region;
|
||||
// all these arrays supposed to be immutable!
|
||||
// These fields accessible from C++
|
||||
|
@ -36,11 +37,36 @@ public class RouteDataObject {
|
|||
public int[] nameIds;
|
||||
// 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("regionIndex", regionIndex);
|
||||
|
||||
bundle.putArray("types", types);
|
||||
bundle.putArray("pointsX", pointsX);
|
||||
bundle.putArray("pointsY", pointsY);
|
||||
bundle.putArray("restrictions", restrictions);
|
||||
bundle.putArray("pointTypes", pointTypes);
|
||||
bundle.putArray("pointNames", pointNames);
|
||||
bundle.putArray("pointNameTypes", pointNameTypes);
|
||||
bundle.putLong("id", id);
|
||||
bundle.putMap("names", names);
|
||||
bundle.putArray("nameIds", nameIds);
|
||||
bundle.putArray("heightDistanceArray", heightDistanceArray);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromBundle(RouteDataBundle bundle) {
|
||||
|
||||
}
|
||||
|
||||
public RouteDataObject(RouteRegion region) {
|
||||
this.region = region;
|
||||
}
|
||||
|
||||
|
||||
public RouteDataObject(RouteRegion region, int[] nameIds, String[] nameValues) {
|
||||
this.region = region;
|
||||
this.nameIds = nameIds;
|
||||
|
@ -65,7 +91,7 @@ public class RouteDataObject {
|
|||
this.pointNameTypes = copy.pointNameTypes;
|
||||
this.id = copy.id;
|
||||
}
|
||||
|
||||
|
||||
public boolean compareRoute(RouteDataObject thatObj) {
|
||||
if (this.id == thatObj.id
|
||||
&& Arrays.equals(this.pointsX, thatObj.pointsX)
|
||||
|
@ -76,11 +102,11 @@ public class RouteDataObject {
|
|||
if (thatObj.region == null) {
|
||||
throw new IllegalStateException("Illegal routing object: " + thatObj.id);
|
||||
}
|
||||
|
||||
|
||||
boolean equals = true;
|
||||
equals = equals && Arrays.equals(this.restrictions, thatObj.restrictions);
|
||||
equals = equals && Arrays.equals(this.restrictionsVia, thatObj.restrictionsVia);
|
||||
|
||||
|
||||
if (equals) {
|
||||
if (this.types == null || thatObj.types == null) {
|
||||
equals = this.types == thatObj.types;
|
||||
|
@ -161,7 +187,7 @@ public class RouteDataObject {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public float[] calculateHeightArray() {
|
||||
if(heightDistanceArray != null) {
|
||||
return heightDistanceArray;
|
||||
|
@ -172,8 +198,8 @@ public class RouteDataObject {
|
|||
heightDistanceArray = new float[0];
|
||||
return heightDistanceArray;
|
||||
}
|
||||
|
||||
heightDistanceArray = new float[2*getPointsLength()];
|
||||
|
||||
heightDistanceArray = new float[2*getPointsLength()];
|
||||
double plon = 0;
|
||||
double plat = 0;
|
||||
float prevHeight = startHeight;
|
||||
|
@ -214,7 +240,7 @@ public class RouteDataObject {
|
|||
}
|
||||
prevHeight = height;
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
heightDistanceArray[0] = 0;
|
||||
heightDistanceArray[1] = startHeight;
|
||||
|
@ -228,19 +254,19 @@ public class RouteDataObject {
|
|||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
|
||||
public String getName(){
|
||||
if(names != null ) {
|
||||
return names.get(region.nameTypeRule);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public String getName(String lang){
|
||||
return getName(lang, false);
|
||||
}
|
||||
|
||||
|
||||
public String getName(String lang, boolean transliterate){
|
||||
if(names != null ) {
|
||||
if(Algorithms.isEmpty(lang)) {
|
||||
|
@ -263,11 +289,11 @@ public class RouteDataObject {
|
|||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public int[] getNameIds() {
|
||||
return nameIds;
|
||||
}
|
||||
|
||||
|
||||
public TIntObjectHashMap<String> getNames() {
|
||||
return names;
|
||||
}
|
||||
|
@ -393,7 +419,7 @@ public class RouteDataObject {
|
|||
public int getRestrictionType(int i) {
|
||||
return (int) (restrictions[i] & RESTRICTION_MASK);
|
||||
}
|
||||
|
||||
|
||||
public RestrictionInfo getRestrictionInfo(int k) {
|
||||
RestrictionInfo ri = new RestrictionInfo();
|
||||
ri.toWay = getRestrictionId(k);
|
||||
|
@ -403,26 +429,26 @@ public class RouteDataObject {
|
|||
}
|
||||
return ri;
|
||||
}
|
||||
|
||||
|
||||
public long getRestrictionVia(int i) {
|
||||
if(restrictionsVia != null && restrictionsVia.length > i) {
|
||||
return restrictionsVia[i];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
public long getRestrictionId(int i) {
|
||||
return restrictions[i] >> RESTRICTION_SHIFT;
|
||||
}
|
||||
|
||||
|
||||
public boolean hasPointTypes() {
|
||||
return pointTypes != null;
|
||||
}
|
||||
|
||||
|
||||
public boolean hasPointNames() {
|
||||
return pointNames != null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void insert(int pos, int x31, int y31) {
|
||||
int[] opointsX = pointsX;
|
||||
|
@ -455,14 +481,14 @@ public class RouteDataObject {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public String[] getPointNames(int ind) {
|
||||
if (pointNames == null || ind >= pointNames.length) {
|
||||
return null;
|
||||
}
|
||||
return pointNames[ind];
|
||||
}
|
||||
|
||||
|
||||
public int[] getPointNameTypes(int ind) {
|
||||
if (pointNameTypes == null || ind >= pointNameTypes.length) {
|
||||
return null;
|
||||
|
@ -476,11 +502,11 @@ public class RouteDataObject {
|
|||
}
|
||||
return pointTypes[ind];
|
||||
}
|
||||
|
||||
|
||||
public int[] getTypes() {
|
||||
return types;
|
||||
}
|
||||
|
||||
|
||||
public void processConditionalTags(long conditionalTime) {
|
||||
int sz = types.length;
|
||||
for (int i = 0; i < sz; i++) {
|
||||
|
@ -582,7 +608,7 @@ public class RouteDataObject {
|
|||
}
|
||||
return def;
|
||||
}
|
||||
|
||||
|
||||
public static float parseLength(String v, float def) {
|
||||
float f = 0;
|
||||
// 14'10" 14 - inches, 10 feet
|
||||
|
@ -602,10 +628,10 @@ public class RouteDataObject {
|
|||
}
|
||||
}
|
||||
if(pref.contains("km")) {
|
||||
f *= 1000;
|
||||
f *= 1000;
|
||||
}
|
||||
if(pref.contains("\"") || pref.contains("in")) {
|
||||
f *= 0.0254;
|
||||
f *= 0.0254;
|
||||
} else if (pref.contains("\'") || pref.contains("ft") || pref.contains("feet")) {
|
||||
// foot to meters
|
||||
f *= 0.3048;
|
||||
|
@ -618,7 +644,7 @@ public class RouteDataObject {
|
|||
}
|
||||
return def;
|
||||
}
|
||||
|
||||
|
||||
public static float parseWeightInTon(String v, float def) {
|
||||
int i = Algorithms.findFirstNumberEndIndex(v);
|
||||
if (i > 0) {
|
||||
|
@ -631,7 +657,7 @@ public class RouteDataObject {
|
|||
}
|
||||
return def;
|
||||
}
|
||||
|
||||
|
||||
public boolean loop() {
|
||||
return pointsX[0] == pointsX[pointsX.length - 1] && pointsY[0] == pointsY[pointsY.length - 1];
|
||||
}
|
||||
|
@ -662,7 +688,7 @@ public class RouteDataObject {
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public boolean tunnel(){
|
||||
int sz = types.length;
|
||||
for(int i=0; i<sz; i++) {
|
||||
|
@ -754,7 +780,7 @@ public class RouteDataObject {
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
public String getRoute() {
|
||||
int sz = types.length;
|
||||
for (int i = 0; i < sz; i++) {
|
||||
|
@ -803,7 +829,7 @@ public class RouteDataObject {
|
|||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public String getValue(int pnt, String tag) {
|
||||
if (pointTypes != null && pnt < pointTypes.length && pointTypes[pnt] != null) {
|
||||
for (int i = 0; i < pointTypes[pnt].length; i++) {
|
||||
|
@ -823,7 +849,7 @@ public class RouteDataObject {
|
|||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public static String getHighway(int[] types, RouteRegion region) {
|
||||
String highway = null;
|
||||
int sz = types.length;
|
||||
|
@ -836,7 +862,7 @@ public class RouteDataObject {
|
|||
}
|
||||
return highway;
|
||||
}
|
||||
|
||||
|
||||
public int getLanes() {
|
||||
int sz = types.length;
|
||||
for (int i = 0; i < sz; i++) {
|
||||
|
@ -848,7 +874,7 @@ public class RouteDataObject {
|
|||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
public double directionRoute(int startPoint, boolean plus) {
|
||||
// same goes to C++
|
||||
// Victor : the problem to put more than 5 meters that BinaryRoutePlanner will treat
|
||||
|
@ -865,7 +891,7 @@ public class RouteDataObject {
|
|||
}
|
||||
return direction;
|
||||
}
|
||||
|
||||
|
||||
public boolean isRoadDeleted() {
|
||||
int[] pt = getTypes();
|
||||
int sz = pt.length;
|
||||
|
@ -921,7 +947,7 @@ public class RouteDataObject {
|
|||
int kx = getPoint31XTile(k + 1);
|
||||
int ky = getPoint31YTile(k + 1);
|
||||
d += simplifyDistance(kx, ky, x, y);
|
||||
|
||||
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
@ -957,7 +983,7 @@ public class RouteDataObject {
|
|||
private double simplifyDistance(int x, int y, int px, int py) {
|
||||
return Math.abs(px - x) * 0.011d + Math.abs(py - y) * 0.01863d;
|
||||
}
|
||||
|
||||
|
||||
private static void assertTrueLength(String vl, float exp){
|
||||
float dest = parseLength(vl, 0);
|
||||
if(exp != dest) {
|
||||
|
@ -966,7 +992,7 @@ public class RouteDataObject {
|
|||
System.out.println("OK " + vl);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void main(String[] args) {
|
||||
assertTrueLength("10 km", 10000);
|
||||
assertTrueLength("0.01 km", 10);
|
||||
|
@ -987,7 +1013,7 @@ public class RouteDataObject {
|
|||
assertTrueLength("14 feet", 4.2672f);
|
||||
assertTrueLength("14 mile", 22530.76f);
|
||||
assertTrueLength("14 cm", 0.14f);
|
||||
|
||||
|
||||
// float badValue = -1;
|
||||
// assertTrueLength("none", badValue);
|
||||
// assertTrueLength("m 4.1", badValue);
|
||||
|
@ -1012,18 +1038,18 @@ public class RouteDataObject {
|
|||
return MessageFormat.format("Road id {0} name {1} ref {2}", (getId() / 64) + "", name == null ? "" : name,
|
||||
rf == null ? "" : rf);
|
||||
}
|
||||
|
||||
|
||||
public static class RestrictionInfo {
|
||||
public int type;
|
||||
public long toWay;
|
||||
public long viaWay;
|
||||
|
||||
|
||||
public RestrictionInfo next; // optional to simulate linked list
|
||||
|
||||
|
||||
public int length() {
|
||||
if(next == null) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return next.length() + 1;
|
||||
}
|
||||
}
|
||||
|
@ -1047,5 +1073,5 @@ public class RouteDataObject {
|
|||
restrictionsVia[k] = viaWay;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
365
OsmAnd-java/src/main/java/net/osmand/binary/StringBundle.java
Normal file
365
OsmAnd-java/src/main/java/net/osmand/binary/StringBundle.java
Normal file
|
@ -0,0 +1,365 @@
|
|||
package net.osmand.binary;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import gnu.trove.iterator.TIntObjectIterator;
|
||||
import gnu.trove.map.hash.TIntObjectHashMap;
|
||||
|
||||
public class StringBundle {
|
||||
|
||||
private Map<String, Item> map = new LinkedHashMap<>();
|
||||
|
||||
public enum ItemType {
|
||||
STRING,
|
||||
LIST,
|
||||
MAP
|
||||
}
|
||||
|
||||
public StringBundle newInstance() {
|
||||
return new StringBundle();
|
||||
}
|
||||
|
||||
public static abstract class Item<T> {
|
||||
|
||||
private String name;
|
||||
private ItemType type;
|
||||
private T value;
|
||||
|
||||
private Item(String name, ItemType type, T value) {
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public ItemType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public T getValue() {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
public static class StringItem extends Item<String> {
|
||||
|
||||
private StringItem(String name, String value) {
|
||||
super(name, ItemType.STRING, value);
|
||||
}
|
||||
|
||||
private StringItem(String name, int value) {
|
||||
super(name, ItemType.STRING, String.valueOf(value));
|
||||
}
|
||||
|
||||
private StringItem(String name, long value) {
|
||||
super(name, ItemType.STRING, String.valueOf(value));
|
||||
}
|
||||
|
||||
private StringItem(String name, float value) {
|
||||
super(name, ItemType.STRING, String.valueOf(value));
|
||||
}
|
||||
|
||||
private StringItem(String name, boolean value) {
|
||||
super(name, ItemType.STRING, String.valueOf(value));
|
||||
}
|
||||
|
||||
public int asInt() throws NumberFormatException {
|
||||
return Integer.parseInt(getValue());
|
||||
}
|
||||
}
|
||||
|
||||
public static class StringListItem extends Item<List<Item>> {
|
||||
|
||||
private StringListItem(String name, List<Item> list) {
|
||||
super(name, ItemType.LIST, list);
|
||||
}
|
||||
}
|
||||
|
||||
public static class StringMapItem extends Item<Map<String, Item>> {
|
||||
|
||||
private StringMapItem(String name, Map<String, Item> map) {
|
||||
super(name, ItemType.MAP, map);
|
||||
}
|
||||
}
|
||||
|
||||
public static class StringBundleItem extends StringMapItem {
|
||||
|
||||
private StringBundleItem(String name, StringBundle bundle) {
|
||||
super(name, bundle.map);
|
||||
}
|
||||
}
|
||||
|
||||
public Map<String, Item> getMap() {
|
||||
return Collections.unmodifiableMap(map);
|
||||
}
|
||||
|
||||
public void putInt(String key, int value) {
|
||||
map.put(key, new StringItem(key, value));
|
||||
}
|
||||
|
||||
public int getInt(String key) throws IllegalArgumentException {
|
||||
Item item = map.get(key);
|
||||
if (item instanceof StringItem) {
|
||||
return ((StringItem) item).asInt();
|
||||
} else {
|
||||
throw new IllegalArgumentException("The item is " + item.getClass().getSimpleName() + " but must be StringItem");
|
||||
}
|
||||
}
|
||||
|
||||
public void putLong(String key, long value) {
|
||||
map.put(key, new StringItem(key, value));
|
||||
}
|
||||
|
||||
public void putFloat(String key, float value) {
|
||||
map.put(key, new StringItem(key, value));
|
||||
}
|
||||
|
||||
public void putBoolean(String key, boolean value) {
|
||||
map.put(key, new StringItem(key, value));
|
||||
}
|
||||
|
||||
public void putString(String key, String value) {
|
||||
if (value != null) {
|
||||
map.put(key, new StringItem(key, value));
|
||||
}
|
||||
}
|
||||
|
||||
public void putObject(String key, StringExternalizable object) {
|
||||
if (object != null) {
|
||||
StringBundle bundle = newInstance();
|
||||
object.writeToBundle(bundle);
|
||||
map.put(key, new StringBundleItem(key, bundle));
|
||||
}
|
||||
}
|
||||
|
||||
public void putList(String key, String itemName, List<? extends StringExternalizable> list) {
|
||||
if (list != null) {
|
||||
List<Item> itemList = new ArrayList<>();
|
||||
for (StringExternalizable ex : list) {
|
||||
if (ex != null) {
|
||||
StringBundle bundle = newInstance();
|
||||
ex.writeToBundle(bundle);
|
||||
itemList.add(new StringBundleItem(itemName, bundle));
|
||||
}
|
||||
}
|
||||
map.put(key, new StringListItem(key, itemList));
|
||||
}
|
||||
}
|
||||
|
||||
public void putBundleList(String key, String itemName, List<StringBundle> list) {
|
||||
if (list != null) {
|
||||
List<Item> itemList = new ArrayList<>();
|
||||
for (StringBundle bundle : list) {
|
||||
itemList.add(new StringBundleItem(itemName, bundle));
|
||||
}
|
||||
map.put(key, new StringListItem(key, itemList));
|
||||
}
|
||||
}
|
||||
|
||||
public void putBundle(String key, StringBundle bundle) {
|
||||
map.put(key, new StringBundleItem(key, bundle));
|
||||
}
|
||||
|
||||
public void putArray(String key, int[] array) {
|
||||
if (array != null) {
|
||||
map.put(key, new StringItem(key, intArrayToString(array)));
|
||||
}
|
||||
}
|
||||
|
||||
public void putArray(String key, int[][] array) {
|
||||
if (array != null) {
|
||||
map.put(key, new StringItem(key, intIntArrayToString(array)));
|
||||
}
|
||||
}
|
||||
|
||||
public void putArray(String key, long[] array) {
|
||||
if (array != null) {
|
||||
map.put(key, new StringItem(key, longArrayToString(array)));
|
||||
}
|
||||
}
|
||||
|
||||
public void putArray(String key, float[] array) {
|
||||
if (array != null) {
|
||||
map.put(key, new StringItem(key, floatArrayToString(array)));
|
||||
}
|
||||
}
|
||||
|
||||
public void putArray(String key, String[] array) {
|
||||
if (array != null) {
|
||||
map.put(key, new StringItem(key, strArrayToString(array)));
|
||||
}
|
||||
}
|
||||
|
||||
public void putArray(String key, String[][] array) {
|
||||
if (array != null) {
|
||||
map.put(key, new StringItem(key, strStrArrayToString(array)));
|
||||
}
|
||||
}
|
||||
|
||||
public <T> void putMap(String key, TIntObjectHashMap<T> map) {
|
||||
if (map != null) {
|
||||
StringBundle bundle = newInstance();
|
||||
TIntObjectIterator<T> it = map.iterator();
|
||||
while (it.hasNext()) {
|
||||
it.advance();
|
||||
int k = it.key();
|
||||
T v = it.value();
|
||||
bundle.putString(String.valueOf(k), String.valueOf(v));
|
||||
}
|
||||
this.map.put(key, new StringBundleItem(key, bundle));
|
||||
}
|
||||
}
|
||||
|
||||
public <K, V> void putMap(String key, Map<K, V> map) {
|
||||
if (map != null) {
|
||||
StringBundle bundle = newInstance();
|
||||
for (Map.Entry<K, V> entry : map.entrySet()) {
|
||||
bundle.putString(String.valueOf(entry.getKey()), String.valueOf(entry.getValue()));
|
||||
}
|
||||
this.map.put(key, new StringBundleItem(key, bundle));
|
||||
}
|
||||
}
|
||||
|
||||
private String intArrayToString(int[] a) {
|
||||
if (a == null) {
|
||||
return null;
|
||||
}
|
||||
StringBuilder b = new StringBuilder();
|
||||
for (int value : a) {
|
||||
if (b.length() > 0) {
|
||||
b.append(",");
|
||||
}
|
||||
b.append(value);
|
||||
}
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
private int[] stringToIntArray(String a) throws NumberFormatException {
|
||||
if (a == null) {
|
||||
return null;
|
||||
}
|
||||
String[] items = a.split(",");
|
||||
int[] res = new int[items.length];
|
||||
for (int i = 0; i < items.length; i++) {
|
||||
res[i] = Integer.parseInt(items[i]);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
private String longArrayToString(long[] a) {
|
||||
if (a == null) {
|
||||
return null;
|
||||
}
|
||||
StringBuilder b = new StringBuilder();
|
||||
for (long value : a) {
|
||||
if (b.length() > 0) {
|
||||
b.append(",");
|
||||
}
|
||||
b.append(value);
|
||||
}
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
private long[] stringToLongArray(String a) throws NumberFormatException {
|
||||
if (a == null) {
|
||||
return null;
|
||||
}
|
||||
String[] items = a.split(",");
|
||||
long[] res = new long[items.length];
|
||||
for (int i = 0; i < items.length; i++) {
|
||||
res[i] = Integer.parseInt(items[i]);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
private String floatArrayToString(float[] a) {
|
||||
if (a == null) {
|
||||
return null;
|
||||
}
|
||||
StringBuilder b = new StringBuilder();
|
||||
for (float value : a) {
|
||||
if (b.length() > 0) {
|
||||
b.append(",");
|
||||
}
|
||||
b.append(value);
|
||||
}
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
private float[] stringToFloatArray(String a) throws NumberFormatException {
|
||||
if (a == null) {
|
||||
return null;
|
||||
}
|
||||
String[] items = a.split(",");
|
||||
float[] res = new float[items.length];
|
||||
for (int i = 0; i < items.length; i++) {
|
||||
res[i] = Float.parseFloat(items[i]);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
private String intIntArrayToString(int[][] a) {
|
||||
if (a == null) {
|
||||
return null;
|
||||
}
|
||||
StringBuilder b = new StringBuilder();
|
||||
for (int[] value : a) {
|
||||
if (b.length() > 0) {
|
||||
b.append(";");
|
||||
}
|
||||
b.append(intArrayToString(value));
|
||||
}
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
private int[][] stringToIntIntArray(String a) throws NumberFormatException {
|
||||
if (a == null) {
|
||||
return null;
|
||||
}
|
||||
String[] items = a.split(";");
|
||||
int[][] res = new int[items.length][];
|
||||
for (int i = 0; i < items.length; i++) {
|
||||
String[] subItems = a.split(",");
|
||||
res[i] = new int[subItems.length];
|
||||
for (int k = 0; k < subItems.length; k++) {
|
||||
res[i][k] = Integer.parseInt(subItems[k]);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
private String strArrayToString(String[] a) {
|
||||
if (a == null) {
|
||||
return null;
|
||||
}
|
||||
StringBuilder b = new StringBuilder();
|
||||
for (String value : a) {
|
||||
if (b.length() > 0) {
|
||||
b.append(0x1E);
|
||||
}
|
||||
b.append(value);
|
||||
}
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
private String strStrArrayToString(String[][] a) {
|
||||
if (a == null) {
|
||||
return null;
|
||||
}
|
||||
StringBuilder b = new StringBuilder();
|
||||
for (String[] value : a) {
|
||||
if (b.length() > 0) {
|
||||
b.append(0x1F);
|
||||
}
|
||||
b.append(strArrayToString(value));
|
||||
}
|
||||
return b.toString();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
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;
|
||||
}
|
||||
|
||||
protected StringBundle getBundle() {
|
||||
return bundle;
|
||||
}
|
||||
|
||||
public String getResult() {
|
||||
return result;
|
||||
}
|
||||
|
||||
protected abstract void writeItem(String name, Item item);
|
||||
|
||||
public void writeBundle() {
|
||||
for (Entry<String, Item> entry : bundle.getMap().entrySet()) {
|
||||
writeItem(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,100 @@
|
|||
package net.osmand.binary;
|
||||
|
||||
import net.osmand.PlatformUtil;
|
||||
import net.osmand.binary.StringBundle.Item;
|
||||
import net.osmand.binary.StringBundle.StringItem;
|
||||
import net.osmand.binary.StringBundle.StringListItem;
|
||||
import net.osmand.binary.StringBundle.StringMapItem;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.xmlpull.v1.XmlSerializer;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.StringWriter;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writeItem(String name, Item item) {
|
||||
if (serializer != null) {
|
||||
try {
|
||||
writeItemImpl(name, item);
|
||||
} catch (Exception e) {
|
||||
log.error("Error writing string bundle as xml", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeBundle() {
|
||||
if (serializer != null) {
|
||||
super.writeBundle();
|
||||
try {
|
||||
serializer.flush();
|
||||
if (writer != null) {
|
||||
result = writer.toString();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("Error writing string bundle as xml", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void writeItemImpl(String name, Item item) throws IOException {
|
||||
if (serializer != null && item != null) {
|
||||
switch (item.getType()) {
|
||||
case STRING: {
|
||||
StringItem stringItem = (StringItem) item;
|
||||
serializer.startTag(null, "s");
|
||||
serializer.attribute(null, "n", name);
|
||||
serializer.text(stringItem.getValue());
|
||||
serializer.endTag(null, "s");
|
||||
break;
|
||||
}
|
||||
case LIST: {
|
||||
StringListItem listItem = (StringListItem) item;
|
||||
serializer.startTag(null, name);
|
||||
for (Item i : listItem.getValue()) {
|
||||
writeItemImpl(i.getName(), i);
|
||||
}
|
||||
serializer.endTag(null, name);
|
||||
break;
|
||||
}
|
||||
case MAP: {
|
||||
StringMapItem mapItem = (StringMapItem) item;
|
||||
serializer.startTag(null, name);
|
||||
for (Entry<String, Item> entry : mapItem.getValue().entrySet()) {
|
||||
writeItemImpl(entry.getKey(), entry.getValue());
|
||||
}
|
||||
serializer.endTag(null, name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
package net.osmand.binary;
|
||||
|
||||
public interface StringExternalizable<T extends StringBundle> {
|
||||
|
||||
public void writeToBundle(T bundle);
|
||||
|
||||
public void readFromBundle(T bundle);
|
||||
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package net.osmand.router;
|
||||
|
||||
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteRegion;
|
||||
import net.osmand.binary.RouteDataObject;
|
||||
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class RouteDataResources {
|
||||
|
||||
private List<RouteSegmentResult> routeSegments = new LinkedList<>();
|
||||
private List<RouteDataObject> routeDataObjects = new LinkedList<>();
|
||||
private List<RouteRegion> routeRegions = new LinkedList<>();
|
||||
|
||||
public List<RouteSegmentResult> getRouteSegments() {
|
||||
return routeSegments;
|
||||
}
|
||||
|
||||
public List<RouteDataObject> getRouteDataObjects() {
|
||||
return routeDataObjects;
|
||||
}
|
||||
|
||||
public List<RouteRegion> getRouteRegions() {
|
||||
return routeRegions;
|
||||
}
|
||||
}
|
118
OsmAnd-java/src/main/java/net/osmand/router/RouteExporter.java
Normal file
118
OsmAnd-java/src/main/java/net/osmand/router/RouteExporter.java
Normal file
|
@ -0,0 +1,118 @@
|
|||
package net.osmand.router;
|
||||
|
||||
import net.osmand.GPXUtilities;
|
||||
import net.osmand.GPXUtilities.GPXExtensionsWriter;
|
||||
import net.osmand.GPXUtilities.GPXFile;
|
||||
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.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;
|
||||
|
||||
import java.io.File;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
public class RouteExporter {
|
||||
|
||||
private static final String OSMAND_ROUTER = "OsmAndRouter";
|
||||
|
||||
private File file;
|
||||
private List<RouteSegmentResult> route;
|
||||
private List<Location> locations;
|
||||
|
||||
public RouteExporter(File file, List<RouteSegmentResult> route, List<Location> locations) {
|
||||
this.file = file;
|
||||
this.route = route;
|
||||
this.locations = locations;
|
||||
}
|
||||
|
||||
public Exception export() {
|
||||
RouteDataResources resources = new RouteDataResources();
|
||||
final RouteDataBundle bundle = new RouteDataBundle(resources);
|
||||
|
||||
for (RouteSegmentResult sr : route) {
|
||||
sr.collectResources(resources);
|
||||
}
|
||||
|
||||
List<StringBundle> routeItems = new ArrayList<>();
|
||||
for (RouteSegmentResult sr : route) {
|
||||
RouteDataBundle itemBundle = new RouteDataBundle(resources);
|
||||
sr.writeToBundle(itemBundle);
|
||||
routeItems.add(itemBundle);
|
||||
}
|
||||
bundle.putBundleList("route", "segment", routeItems);
|
||||
|
||||
List<StringBundle> segments = new ArrayList<>();
|
||||
for (RouteSegmentResult segment : resources.getRouteSegments()) {
|
||||
RouteDataBundle segmentBundle = new RouteDataBundle(resources);
|
||||
segment.writeToBundle(segmentBundle);
|
||||
segments.add(segmentBundle);
|
||||
}
|
||||
bundle.putBundleList("segments", "segment", segments);
|
||||
|
||||
List<StringBundle> dataObjects = new ArrayList<>();
|
||||
for (RouteDataObject dataObject : resources.getRouteDataObjects()) {
|
||||
RouteDataBundle objectBundle = new RouteDataBundle(resources);
|
||||
dataObject.writeToBundle(objectBundle);
|
||||
dataObjects.add(objectBundle);
|
||||
}
|
||||
bundle.putBundleList("objects", "object", 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", "region", regions);
|
||||
|
||||
GPXFile gpx = new GPXFile("OsmAnd");
|
||||
gpx.author = OSMAND_ROUTER;
|
||||
Track track = new Track();
|
||||
track.name = new SimpleDateFormat("yyyy-MM-dd_HH-mm_EEE", Locale.US).format(new Date());
|
||||
gpx.tracks.add(track);
|
||||
TrkSegment trkSegment = new TrkSegment();
|
||||
track.segments.add(trkSegment);
|
||||
for (int i = 0; i< locations.size(); i++) {
|
||||
Location loc = locations.get(i);
|
||||
WptPt pt = new WptPt();
|
||||
pt.lat = loc.getLatitude();
|
||||
pt.lon = loc.getLongitude();
|
||||
if (loc.hasSpeed()) {
|
||||
pt.speed = loc.getSpeed();
|
||||
}
|
||||
if (loc.hasAltitude()) {
|
||||
pt.ele = loc.getAltitude();
|
||||
}
|
||||
if (loc.hasAccuracy()) {
|
||||
pt.hdop = loc.getAccuracy();
|
||||
}
|
||||
trkSegment.points.add(pt);
|
||||
}
|
||||
|
||||
GPXExtensionsWriter extensionsWriter = new GPXExtensionsWriter() {
|
||||
@Override
|
||||
public void writeExtensions(XmlSerializer serializer) {
|
||||
StringBundleWriter bundleWriter = new StringBundleXmlWriter(bundle, serializer);
|
||||
bundleWriter.writeBundle();
|
||||
}
|
||||
};
|
||||
gpx.setExtensionsWriter(extensionsWriter);
|
||||
|
||||
Exception result = GPXUtilities.writeGpxFile(file, gpx);
|
||||
return result;
|
||||
}
|
||||
}
|
|
@ -1,19 +1,23 @@
|
|||
package net.osmand.router;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteTypeRule;
|
||||
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteRegion;
|
||||
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteSubregion;
|
||||
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.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class RouteSegmentResult {
|
||||
|
||||
public class RouteSegmentResult implements StringExternalizable<RouteDataBundle> {
|
||||
private final RouteDataObject object;
|
||||
private int startPointIndex;
|
||||
private int endPointIndex;
|
||||
|
@ -34,7 +38,123 @@ public class RouteSegmentResult {
|
|||
this.endPointIndex = endPointIndex;
|
||||
updateCapacity();
|
||||
}
|
||||
|
||||
|
||||
void collectResources(RouteDataResources resources) {
|
||||
List<RouteSegmentResult> segments = resources.getRouteSegments();
|
||||
List<RouteDataObject> dataObjects = resources.getRouteDataObjects();
|
||||
List<RouteRegion> regions = resources.getRouteRegions();
|
||||
if (!segments.contains(this)) {
|
||||
segments.add(this);
|
||||
}
|
||||
if (attachedRoutes != null) {
|
||||
for (List<RouteSegmentResult> routes : attachedRoutes) {
|
||||
if (routes != null) {
|
||||
for (RouteSegmentResult route : routes) {
|
||||
if (!segments.contains(route)) {
|
||||
segments.add(route);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (preAttachedRoutes != null) {
|
||||
for (RouteSegmentResult[] routes : preAttachedRoutes) {
|
||||
if (routes != null) {
|
||||
for (RouteSegmentResult route : routes) {
|
||||
if (!segments.contains(route)) {
|
||||
segments.add(route);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!dataObjects.contains(object)) {
|
||||
dataObjects.add(object);
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToBundle(RouteDataBundle bundle) {
|
||||
List<RouteDataObject> dataObjects = bundle.getResources().getRouteDataObjects();
|
||||
int dataObjectIndex = dataObjects.indexOf(object);
|
||||
assert dataObjectIndex != -1;
|
||||
bundle.putInt("objectIndex", dataObjectIndex);
|
||||
|
||||
bundle.putInt("startPointIndex", startPointIndex);
|
||||
bundle.putInt("endPointIndex", endPointIndex);
|
||||
|
||||
List<RouteSegmentResult> segments = bundle.getResources().getRouteSegments();
|
||||
if (attachedRoutes != null) {
|
||||
Set<Integer> attachedRoutesIndexes = new HashSet<>();
|
||||
for (List<RouteSegmentResult> routes : attachedRoutes) {
|
||||
if (routes != null) {
|
||||
for (RouteSegmentResult route : routes) {
|
||||
int segmentIndex = segments.indexOf(route);
|
||||
assert segmentIndex != -1;
|
||||
attachedRoutesIndexes.add(segmentIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
int[] attachedRoutesIndexesArray = new int[attachedRoutesIndexes.size()];
|
||||
Iterator<Integer> it = attachedRoutesIndexes.iterator();
|
||||
int i = 0;
|
||||
while (it.hasNext()) {
|
||||
int index = it.next();
|
||||
attachedRoutesIndexesArray[i++] = index;
|
||||
}
|
||||
bundle.putArray("attachedRoutes", attachedRoutesIndexesArray);
|
||||
}
|
||||
|
||||
if (preAttachedRoutes != null) {
|
||||
Set<Integer> preAttachedRoutesIndexes = new HashSet<>();
|
||||
for (RouteSegmentResult[] routes : preAttachedRoutes) {
|
||||
if (routes != null) {
|
||||
for (RouteSegmentResult route : routes) {
|
||||
int segmentIndex = segments.indexOf(route);
|
||||
assert segmentIndex != -1;
|
||||
preAttachedRoutesIndexes.add(segmentIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
int[] preAttachedRoutesIndexesArray = new int[preAttachedRoutesIndexes.size()];
|
||||
Iterator<Integer> it = preAttachedRoutesIndexes.iterator();
|
||||
int i = 0;
|
||||
while (it.hasNext()) {
|
||||
int index = it.next();
|
||||
preAttachedRoutesIndexesArray[i++] = index;
|
||||
}
|
||||
bundle.putArray("preAttachedRoutes", preAttachedRoutesIndexesArray);
|
||||
}
|
||||
bundle.putFloat("segmentTime", segmentTime);
|
||||
bundle.putFloat("routingTime", routingTime);
|
||||
bundle.putFloat("speed", speed);
|
||||
bundle.putFloat("distance", distance);
|
||||
bundle.putString("description", description);
|
||||
|
||||
bundle.putObject("turnType", turnType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromBundle(RouteDataBundle bundle) {
|
||||
|
||||
}
|
||||
|
||||
public float[] getHeightValues() {
|
||||
float[] pf = object.calculateHeightArray();
|
||||
if(pf == null || pf.length == 0) {
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
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 {
|
||||
public class TurnType implements StringExternalizable<RouteDataBundle> {
|
||||
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$
|
||||
|
@ -18,7 +22,23 @@ public class TurnType {
|
|||
public static final int OFFR = 12; // Off route //$NON-NLS-1$
|
||||
public static final int RNDB = 13; // Roundabout
|
||||
public static final int RNLB = 14; // Roundabout left
|
||||
|
||||
|
||||
@Override
|
||||
public void writeToBundle(RouteDataBundle bundle) {
|
||||
bundle.putInt("value", value);
|
||||
bundle.putInt("exitOut", exitOut);
|
||||
bundle.putFloat("turnAngle", turnAngle);
|
||||
bundle.putBoolean("skipToSpeak", skipToSpeak);
|
||||
bundle.putArray("lanes", lanes);
|
||||
bundle.putBoolean("possiblyLeftTurn", possiblyLeftTurn);
|
||||
bundle.putBoolean("possiblyRightTurn", possiblyRightTurn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readFromBundle(RouteDataBundle bundle) {
|
||||
|
||||
}
|
||||
|
||||
public static TurnType straight() {
|
||||
return valueOf(C, false);
|
||||
}
|
||||
|
|
|
@ -817,4 +817,30 @@ public class Algorithms {
|
|||
return array;
|
||||
}
|
||||
}
|
||||
|
||||
public static String arrayToString(int[] a) {
|
||||
if (a == null || a.length == 0) {
|
||||
return null;
|
||||
}
|
||||
StringBuilder b = new StringBuilder();
|
||||
for (int value : a) {
|
||||
if (b.length() > 0) {
|
||||
b.append(",");
|
||||
}
|
||||
b.append(value);
|
||||
}
|
||||
return b.toString();
|
||||
}
|
||||
|
||||
public static int[] stringToArray(String array) throws NumberFormatException {
|
||||
if (array == null || array.length() == 0) {
|
||||
return null;
|
||||
}
|
||||
String[] items = array.split(",");
|
||||
int[] res = new int[items.length];
|
||||
for (int i = 0; i < items.length; i++) {
|
||||
res[i] = Integer.parseInt(items[i]);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
|
@ -4,6 +4,7 @@ import android.content.Context;
|
|||
import android.support.annotation.Nullable;
|
||||
import android.system.Os;
|
||||
|
||||
import net.osmand.IndexConstants;
|
||||
import net.osmand.Location;
|
||||
import net.osmand.PlatformUtil;
|
||||
import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteRegion;
|
||||
|
@ -12,11 +13,13 @@ import net.osmand.binary.RouteDataObject;
|
|||
import net.osmand.data.LatLon;
|
||||
import net.osmand.data.LocationPoint;
|
||||
import net.osmand.data.QuadRect;
|
||||
import net.osmand.plus.AppInitializer;
|
||||
import net.osmand.plus.ApplicationMode;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.R;
|
||||
import net.osmand.plus.routing.AlarmInfo.AlarmInfoType;
|
||||
import net.osmand.router.ExitInfo;
|
||||
import net.osmand.router.RouteExporter;
|
||||
import net.osmand.router.RouteSegmentResult;
|
||||
import net.osmand.router.RoutingContext;
|
||||
import net.osmand.router.TurnType;
|
||||
|
@ -25,6 +28,7 @@ import net.osmand.util.MapUtils;
|
|||
|
||||
import org.apache.commons.logging.Log;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
@ -168,8 +172,12 @@ public class RouteCalculationResult {
|
|||
this.routeRecalcDistance = ctx.getSettings().ROUTE_RECALCULATION_DISTANCE.getModeValue(mode);
|
||||
this.routeVisibleAngle = routeService == RouteProvider.RouteService.STRAIGHT ?
|
||||
ctx.getSettings().ROUTE_STRAIGHT_ANGLE.getModeValue(mode) : 0;
|
||||
|
||||
RouteExporter exporter = new RouteExporter(new File(ctx.getAppPath(IndexConstants.GPX_INDEX_DIR), "test.gpx"), list, locations);
|
||||
exporter.export();
|
||||
|
||||
}
|
||||
|
||||
|
||||
public ApplicationMode getAppMode() {
|
||||
return appMode;
|
||||
}
|
||||
|
|
|
@ -6,23 +6,20 @@ import android.os.Build;
|
|||
import android.os.Bundle;
|
||||
import android.util.Base64;
|
||||
|
||||
import net.osmand.Location;
|
||||
import net.osmand.PlatformUtil;
|
||||
import net.osmand.binary.BinaryMapIndexReader;
|
||||
import net.osmand.data.DataTileManager;
|
||||
import net.osmand.data.LatLon;
|
||||
import net.osmand.data.LocationPoint;
|
||||
import net.osmand.data.WptLocationPoint;
|
||||
import net.osmand.osm.edit.Node;
|
||||
import net.osmand.osm.edit.Way;
|
||||
import net.osmand.osm.io.NetworkUtils;
|
||||
import net.osmand.plus.ApplicationMode;
|
||||
import net.osmand.GPXUtilities;
|
||||
import net.osmand.GPXUtilities.GPXFile;
|
||||
import net.osmand.GPXUtilities.Route;
|
||||
import net.osmand.GPXUtilities.Track;
|
||||
import net.osmand.GPXUtilities.TrkSegment;
|
||||
import net.osmand.GPXUtilities.WptPt;
|
||||
import net.osmand.Location;
|
||||
import net.osmand.PlatformUtil;
|
||||
import net.osmand.binary.BinaryMapIndexReader;
|
||||
import net.osmand.data.LatLon;
|
||||
import net.osmand.data.LocationPoint;
|
||||
import net.osmand.data.WptLocationPoint;
|
||||
import net.osmand.osm.io.NetworkUtils;
|
||||
import net.osmand.plus.ApplicationMode;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.OsmandSettings;
|
||||
import net.osmand.plus.OsmandSettings.CommonPreference;
|
||||
|
@ -902,6 +899,17 @@ public class RouteProvider {
|
|||
if (sturn != null) {
|
||||
turnType.setTurnAngle((float) Double.parseDouble(sturn));
|
||||
}
|
||||
String slanes = item.getExtensionsToRead().get("lanes");
|
||||
if (slanes != null) {
|
||||
try {
|
||||
int[] lanes = Algorithms.stringToArray(slanes);
|
||||
if (lanes != null && lanes.length > 0) {
|
||||
turnType.setLanes(lanes);
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
RouteDirectionInfo dirInfo = new RouteDirectionInfo(avgSpeed, turnType);
|
||||
dirInfo.setDescriptionRoute(item.desc); //$NON-NLS-1$
|
||||
dirInfo.routePointOffset = offset;
|
||||
|
@ -1058,6 +1066,10 @@ public class RouteProvider {
|
|||
extensions.put("turn", dirInfo.getTurnType().toXmlString());
|
||||
extensions.put("turn-angle", dirInfo.getTurnType().getTurnAngle() + "");
|
||||
}
|
||||
int[] lanes = dirInfo.getTurnType().getLanes();
|
||||
if (lanes != null && lanes.length > 0) {
|
||||
extensions.put("lanes", Algorithms.arrayToString(lanes));
|
||||
}
|
||||
extensions.put("offset", (dirInfo.routePointOffset - currentRoute) + "");
|
||||
|
||||
// Issue #2894
|
||||
|
|
Loading…
Reference in a new issue