Fix read / write gpx route extensions
This commit is contained in:
parent
dedbbb4c26
commit
66f0b4cd77
5 changed files with 225 additions and 179 deletions
|
@ -2,6 +2,9 @@
|
||||||
package net.osmand;
|
package net.osmand;
|
||||||
|
|
||||||
|
|
||||||
|
import net.osmand.binary.StringBundle;
|
||||||
|
import net.osmand.binary.StringBundleWriter;
|
||||||
|
import net.osmand.binary.StringBundleXmlWriter;
|
||||||
import net.osmand.data.QuadRect;
|
import net.osmand.data.QuadRect;
|
||||||
import net.osmand.util.Algorithms;
|
import net.osmand.util.Algorithms;
|
||||||
|
|
||||||
|
@ -13,7 +16,6 @@ import org.xmlpull.v1.XmlSerializer;
|
||||||
import java.io.BufferedInputStream;
|
import java.io.BufferedInputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
@ -437,6 +439,44 @@ public class GPXUtilities {
|
||||||
public double maxlon;
|
public double maxlon;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class RouteSegment {
|
||||||
|
public String id;
|
||||||
|
public String length;
|
||||||
|
public String segmentTime;
|
||||||
|
public String speed;
|
||||||
|
public String turnType;
|
||||||
|
public String turnAngle;
|
||||||
|
public String types;
|
||||||
|
public String pointTypes;
|
||||||
|
public String names;
|
||||||
|
|
||||||
|
public StringBundle getStringBundle() {
|
||||||
|
StringBundle bundle = new StringBundle();
|
||||||
|
bundle.putString("id", id);
|
||||||
|
bundle.putString("length", length);
|
||||||
|
bundle.putString("segmentTime", segmentTime);
|
||||||
|
bundle.putString("speed", speed);
|
||||||
|
bundle.putString("turnType", turnType);
|
||||||
|
bundle.putString("turnAngle", turnAngle);
|
||||||
|
bundle.putString("types", types);
|
||||||
|
bundle.putString("pointTypes", pointTypes);
|
||||||
|
bundle.putString("names", names);
|
||||||
|
return bundle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class RouteType {
|
||||||
|
public String tag;
|
||||||
|
public String value;
|
||||||
|
|
||||||
|
public StringBundle getStringBundle() {
|
||||||
|
StringBundle bundle = new StringBundle();
|
||||||
|
bundle.putString("t", tag);
|
||||||
|
bundle.putString("v", value);
|
||||||
|
return bundle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static class GPXTrackAnalysis {
|
public static class GPXTrackAnalysis {
|
||||||
public float totalDistance = 0;
|
public float totalDistance = 0;
|
||||||
public float totalDistanceWithoutGaps = 0;
|
public float totalDistanceWithoutGaps = 0;
|
||||||
|
@ -1006,6 +1046,9 @@ public class GPXUtilities {
|
||||||
private List<WptPt> points = new ArrayList<>();
|
private List<WptPt> points = new ArrayList<>();
|
||||||
public List<Route> routes = new ArrayList<>();
|
public List<Route> routes = new ArrayList<>();
|
||||||
|
|
||||||
|
public List<RouteSegment> routeSegments = new ArrayList<>();
|
||||||
|
public List<RouteType> routeTypes = new ArrayList<>();
|
||||||
|
|
||||||
public Exception error = null;
|
public Exception error = null;
|
||||||
public String path = "";
|
public String path = "";
|
||||||
public boolean showCurrentTrack;
|
public boolean showCurrentTrack;
|
||||||
|
@ -1032,6 +1075,10 @@ public class GPXUtilities {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean hasRoute() {
|
||||||
|
return !routeSegments.isEmpty() && !routeTypes.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
public List<WptPt> getPoints() {
|
public List<WptPt> getPoints() {
|
||||||
return Collections.unmodifiableList(points);
|
return Collections.unmodifiableList(points);
|
||||||
}
|
}
|
||||||
|
@ -1744,6 +1791,7 @@ public class GPXUtilities {
|
||||||
serializer.endTag(null, "wpt"); //$NON-NLS-1$
|
serializer.endTag(null, "wpt"); //$NON-NLS-1$
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assignRouteExtensionWriter(file);
|
||||||
writeExtensions(serializer, file);
|
writeExtensions(serializer, file);
|
||||||
|
|
||||||
serializer.endTag(null, "gpx"); //$NON-NLS-1$
|
serializer.endTag(null, "gpx"); //$NON-NLS-1$
|
||||||
|
@ -1756,6 +1804,29 @@ public class GPXUtilities {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void assignRouteExtensionWriter(final GPXFile gpxFile) {
|
||||||
|
if (gpxFile.hasRoute() && gpxFile.getExtensionsWriter() == null) {
|
||||||
|
gpxFile.setExtensionsWriter(new GPXExtensionsWriter() {
|
||||||
|
@Override
|
||||||
|
public void writeExtensions(XmlSerializer serializer) {
|
||||||
|
StringBundle bundle = new StringBundle();
|
||||||
|
List<StringBundle> segmentsBundle = new ArrayList<>();
|
||||||
|
for (RouteSegment segment : gpxFile.routeSegments) {
|
||||||
|
segmentsBundle.add(segment.getStringBundle());
|
||||||
|
}
|
||||||
|
bundle.putBundleList("route", "segment", segmentsBundle);
|
||||||
|
List<StringBundle> typesBundle = new ArrayList<>();
|
||||||
|
for (RouteType routeType : gpxFile.routeTypes) {
|
||||||
|
typesBundle.add(routeType.getStringBundle());
|
||||||
|
}
|
||||||
|
bundle.putBundleList("types", "type", typesBundle);
|
||||||
|
StringBundleWriter bundleWriter = new StringBundleXmlWriter(bundle, serializer);
|
||||||
|
bundleWriter.writeBundle();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static String getFilename(String path) {
|
private static String getFilename(String path) {
|
||||||
if(path != null) {
|
if(path != null) {
|
||||||
int i = path.lastIndexOf('/');
|
int i = path.lastIndexOf('/');
|
||||||
|
@ -1973,23 +2044,7 @@ public class GPXUtilities {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static GPXFile loadGPXFile(InputStream f) {
|
public static GPXFile loadGPXFile(InputStream f) {
|
||||||
return loadGPXFile(f, null, null);
|
GPXFile gpxFile = new GPXFile(null);
|
||||||
}
|
|
||||||
|
|
||||||
public static GPXFile loadGPXFile(InputStream f, GPXFile gpxFile, GPXExtensionsReader extensionsReader) {
|
|
||||||
boolean readExtensionsOnly = false;
|
|
||||||
if (gpxFile == null) {
|
|
||||||
gpxFile = new GPXFile(null);
|
|
||||||
} else {
|
|
||||||
if (f == null) {
|
|
||||||
try {
|
|
||||||
f = new FileInputStream(new File(gpxFile.path));
|
|
||||||
} catch (FileNotFoundException e) {
|
|
||||||
return gpxFile;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
readExtensionsOnly = extensionsReader != null;
|
|
||||||
}
|
|
||||||
SimpleDateFormat format = new SimpleDateFormat(GPX_TIME_FORMAT, Locale.US);
|
SimpleDateFormat format = new SimpleDateFormat(GPX_TIME_FORMAT, Locale.US);
|
||||||
format.setTimeZone(TimeZone.getTimeZone("UTC"));
|
format.setTimeZone(TimeZone.getTimeZone("UTC"));
|
||||||
SimpleDateFormat formatMillis = new SimpleDateFormat(GPX_TIME_FORMAT_MILLIS, Locale.US);
|
SimpleDateFormat formatMillis = new SimpleDateFormat(GPX_TIME_FORMAT_MILLIS, Locale.US);
|
||||||
|
@ -2003,6 +2058,10 @@ public class GPXUtilities {
|
||||||
Stack<GPXExtensions> parserState = new Stack<>();
|
Stack<GPXExtensions> parserState = new Stack<>();
|
||||||
boolean extensionReadMode = false;
|
boolean extensionReadMode = false;
|
||||||
boolean routePointExtension = false;
|
boolean routePointExtension = false;
|
||||||
|
List<RouteSegment> routeSegments = gpxFile.routeSegments;
|
||||||
|
List<RouteType> routeTypes = gpxFile.routeTypes;
|
||||||
|
boolean routeExtension = false;
|
||||||
|
boolean typesExtension = false;
|
||||||
parserState.push(gpxFile);
|
parserState.push(gpxFile);
|
||||||
int tok;
|
int tok;
|
||||||
while ((tok = parser.next()) != XmlPullParser.END_DOCUMENT) {
|
while ((tok = parser.next()) != XmlPullParser.END_DOCUMENT) {
|
||||||
|
@ -2011,37 +2070,50 @@ public class GPXUtilities {
|
||||||
String tag = parser.getName();
|
String tag = parser.getName();
|
||||||
if (extensionReadMode && parse != null && !routePointExtension) {
|
if (extensionReadMode && parse != null && !routePointExtension) {
|
||||||
String tagName = tag.toLowerCase();
|
String tagName = tag.toLowerCase();
|
||||||
boolean extensionsRead = false;
|
if (routeExtension) {
|
||||||
if (extensionsReader != null) {
|
if (tagName.equals("segment")) {
|
||||||
extensionsRead = extensionsReader.readExtensions(gpxFile, parser);
|
RouteSegment segment = parseRouteSegmentAttributes(parser);
|
||||||
|
routeSegments.add(segment);
|
||||||
|
}
|
||||||
|
} else if (typesExtension) {
|
||||||
|
if (tagName.equals("type")) {
|
||||||
|
RouteType type = parseRouteTypeAttributes(parser);
|
||||||
|
routeTypes.add(type);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!readExtensionsOnly && !extensionsRead) {
|
switch (tagName) {
|
||||||
switch (tagName) {
|
case "routepointextension":
|
||||||
case "routepointextension":
|
routePointExtension = true;
|
||||||
routePointExtension = true;
|
if (parse instanceof WptPt) {
|
||||||
if (parse instanceof WptPt) {
|
parse.getExtensionsToWrite().put("offset", routeTrackSegment.points.size() + "");
|
||||||
parse.getExtensionsToWrite().put("offset", routeTrackSegment.points.size() + "");
|
}
|
||||||
}
|
break;
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
case "route":
|
||||||
Map<String, String> values = readTextMap(parser, tag);
|
routeExtension = true;
|
||||||
if (values.size() > 0) {
|
break;
|
||||||
for (Entry<String, String> entry : values.entrySet()) {
|
|
||||||
String t = entry.getKey().toLowerCase();
|
case "types":
|
||||||
String value = entry.getValue();
|
typesExtension = true;
|
||||||
parse.getExtensionsToWrite().put(t, value);
|
break;
|
||||||
if (tag.equals("speed") && parse instanceof WptPt) {
|
|
||||||
try {
|
default:
|
||||||
((WptPt) parse).speed = Float.parseFloat(value);
|
Map<String, String> values = readTextMap(parser, tag);
|
||||||
} catch (NumberFormatException e) {
|
if (values.size() > 0) {
|
||||||
log.debug(e.getMessage(), e);
|
for (Entry<String, String> entry : values.entrySet()) {
|
||||||
}
|
String t = entry.getKey().toLowerCase();
|
||||||
|
String value = entry.getValue();
|
||||||
|
parse.getExtensionsToWrite().put(t, value);
|
||||||
|
if (tag.equals("speed") && parse instanceof WptPt) {
|
||||||
|
try {
|
||||||
|
((WptPt) parse).speed = Float.parseFloat(value);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
log.debug(e.getMessage(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
}
|
||||||
}
|
break;
|
||||||
}
|
}
|
||||||
} else if (parse != null && tag.equals("extensions")) {
|
} else if (parse != null && tag.equals("extensions")) {
|
||||||
extensionReadMode = true;
|
extensionReadMode = true;
|
||||||
|
@ -2051,7 +2123,7 @@ public class GPXUtilities {
|
||||||
routeTrackSegment.points.add(wptPt);
|
routeTrackSegment.points.add(wptPt);
|
||||||
parserState.push(wptPt);
|
parserState.push(wptPt);
|
||||||
}
|
}
|
||||||
} else if (!readExtensionsOnly) {
|
} else {
|
||||||
if (parse instanceof GPXFile) {
|
if (parse instanceof GPXFile) {
|
||||||
if (tag.equals("gpx")) {
|
if (tag.equals("gpx")) {
|
||||||
((GPXFile) parse).author = parser.getAttributeValue("", "creator");
|
((GPXFile) parse).author = parser.getAttributeValue("", "creator");
|
||||||
|
@ -2247,7 +2319,12 @@ public class GPXUtilities {
|
||||||
if (parse != null && tag.equals("extensions")) {
|
if (parse != null && tag.equals("extensions")) {
|
||||||
extensionReadMode = false;
|
extensionReadMode = false;
|
||||||
}
|
}
|
||||||
if (readExtensionsOnly) {
|
if (extensionReadMode && tag.equals("route")) {
|
||||||
|
routeExtension = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (extensionReadMode && tag.equals("types")) {
|
||||||
|
typesExtension = false;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2327,6 +2404,27 @@ public class GPXUtilities {
|
||||||
return wpt;
|
return wpt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static RouteSegment parseRouteSegmentAttributes(XmlPullParser parser) {
|
||||||
|
RouteSegment segment = new RouteSegment();
|
||||||
|
segment.id = parser.getAttributeValue("", "id");
|
||||||
|
segment.length = parser.getAttributeValue("", "length");
|
||||||
|
segment.segmentTime = parser.getAttributeValue("", "segmentTime");
|
||||||
|
segment.speed = parser.getAttributeValue("", "speed");
|
||||||
|
segment.turnType = parser.getAttributeValue("", "turnType");
|
||||||
|
segment.turnAngle = parser.getAttributeValue("", "turnAngle");
|
||||||
|
segment.types = parser.getAttributeValue("", "types");
|
||||||
|
segment.pointTypes = parser.getAttributeValue("", "pointTypes");
|
||||||
|
segment.names = parser.getAttributeValue("", "names");
|
||||||
|
return segment;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static RouteType parseRouteTypeAttributes(XmlPullParser parser) {
|
||||||
|
RouteType type = new RouteType();
|
||||||
|
type.tag = parser.getAttributeValue("", "t");
|
||||||
|
type.value = parser.getAttributeValue("", "v");
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
private static Bounds parseBoundsAttributes(XmlPullParser parser) {
|
private static Bounds parseBoundsAttributes(XmlPullParser parser) {
|
||||||
Bounds bounds = new Bounds();
|
Bounds bounds = new Bounds();
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -21,7 +21,7 @@ public class StringBundle {
|
||||||
private static final DecimalFormat FIVE_DIGITS_FORMATTER = new DecimalFormat("#.#####");
|
private static final DecimalFormat FIVE_DIGITS_FORMATTER = new DecimalFormat("#.#####");
|
||||||
private static final DecimalFormat SIX_DIGITS_FORMATTER = new DecimalFormat("#.######");
|
private static final DecimalFormat SIX_DIGITS_FORMATTER = new DecimalFormat("#.######");
|
||||||
|
|
||||||
private Map<String, Item> map = new LinkedHashMap<>();
|
private Map<String, Item<?>> map = new LinkedHashMap<>();
|
||||||
|
|
||||||
public enum ItemType {
|
public enum ItemType {
|
||||||
STRING,
|
STRING,
|
||||||
|
@ -32,7 +32,7 @@ public class StringBundle {
|
||||||
public StringBundle() {
|
public StringBundle() {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected StringBundle(Map<String, Item> map) {
|
protected StringBundle(Map<String, Item<?>> map) {
|
||||||
this.map = map;
|
this.map = map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,16 +156,16 @@ public class StringBundle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class StringListItem extends Item<List<Item>> {
|
public static class StringListItem extends Item<List<Item<?>>> {
|
||||||
|
|
||||||
private StringListItem(String name, List<Item> list) {
|
private StringListItem(String name, List<Item<?>> list) {
|
||||||
super(name, ItemType.LIST, list);
|
super(name, ItemType.LIST, list);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class StringMapItem extends Item<Map<String, Item>> {
|
public static class StringMapItem extends Item<Map<String, Item<?>>> {
|
||||||
|
|
||||||
private StringMapItem(String name, Map<String, Item> map) {
|
private StringMapItem(String name, Map<String, Item<?>> map) {
|
||||||
super(name, ItemType.MAP, map);
|
super(name, ItemType.MAP, map);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -177,11 +177,11 @@ public class StringBundle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<String, Item> getMap() {
|
public Map<String, Item<?>> getMap() {
|
||||||
return Collections.unmodifiableMap(map);
|
return Collections.unmodifiableMap(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Item getItem(String key) {
|
public Item<?> getItem(String key) {
|
||||||
return map.get(key);
|
return map.get(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,7 +190,7 @@ public class StringBundle {
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getInt(String key, int defaultValue) {
|
public int getInt(String key, int defaultValue) {
|
||||||
Item item = map.get(key);
|
Item<?> item = map.get(key);
|
||||||
return item instanceof StringItem ? ((StringItem) item).asInt(defaultValue) : defaultValue;
|
return item instanceof StringItem ? ((StringItem) item).asInt(defaultValue) : defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -199,7 +199,7 @@ public class StringBundle {
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getLong(String key, long defaultValue) {
|
public long getLong(String key, long defaultValue) {
|
||||||
Item item = map.get(key);
|
Item<?> item = map.get(key);
|
||||||
return item instanceof StringItem ? ((StringItem) item).asLong(defaultValue) : defaultValue;
|
return item instanceof StringItem ? ((StringItem) item).asLong(defaultValue) : defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,7 +212,7 @@ public class StringBundle {
|
||||||
}
|
}
|
||||||
|
|
||||||
public float getFloat(String key, float defaultValue) {
|
public float getFloat(String key, float defaultValue) {
|
||||||
Item item = map.get(key);
|
Item<?> item = map.get(key);
|
||||||
return item instanceof StringItem ? ((StringItem) item).asFloat(defaultValue) : defaultValue;
|
return item instanceof StringItem ? ((StringItem) item).asFloat(defaultValue) : defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -221,7 +221,7 @@ public class StringBundle {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean getBoolean(String key, boolean defaultValue) {
|
public boolean getBoolean(String key, boolean defaultValue) {
|
||||||
Item item = map.get(key);
|
Item<?> item = map.get(key);
|
||||||
return item instanceof StringItem ? ((StringItem) item).asBoolean(defaultValue) : defaultValue;
|
return item instanceof StringItem ? ((StringItem) item).asBoolean(defaultValue) : defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -232,35 +232,13 @@ public class StringBundle {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getString(String key, String defaultValue) {
|
public String getString(String key, String defaultValue) {
|
||||||
Item item = map.get(key);
|
Item<?> item = map.get(key);
|
||||||
return item instanceof StringItem ? ((StringItem) item).getValue() : defaultValue;
|
return item instanceof StringItem ? ((StringItem) item).getValue() : defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
public void putBundleList(String key, String itemName, List<StringBundle> list) {
|
||||||
if (list != null) {
|
if (list != null) {
|
||||||
List<Item> itemList = new ArrayList<>();
|
List<Item<?>> itemList = new ArrayList<>();
|
||||||
for (StringBundle bundle : list) {
|
for (StringBundle bundle : list) {
|
||||||
itemList.add(new StringBundleItem(itemName, bundle));
|
itemList.add(new StringBundleItem(itemName, bundle));
|
||||||
}
|
}
|
||||||
|
@ -279,7 +257,7 @@ public class StringBundle {
|
||||||
}
|
}
|
||||||
|
|
||||||
public int[] getIntArray(String key, int[] defaultValue) {
|
public int[] getIntArray(String key, int[] defaultValue) {
|
||||||
Item item = map.get(key);
|
Item<?> item = map.get(key);
|
||||||
return item instanceof StringItem ? ((StringItem) item).asIntArray(defaultValue) : defaultValue;
|
return item instanceof StringItem ? ((StringItem) item).asIntArray(defaultValue) : defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -290,7 +268,7 @@ public class StringBundle {
|
||||||
}
|
}
|
||||||
|
|
||||||
public int[][] getIntIntArray(String key, int[][] defaultValue) {
|
public int[][] getIntIntArray(String key, int[][] defaultValue) {
|
||||||
Item item = map.get(key);
|
Item<?> item = map.get(key);
|
||||||
return item instanceof StringItem ? ((StringItem) item).asIntIntArray(defaultValue) : defaultValue;
|
return item instanceof StringItem ? ((StringItem) item).asIntIntArray(defaultValue) : defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,10 +16,10 @@ public abstract class StringBundleWriter {
|
||||||
return bundle;
|
return bundle;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract void writeItem(String name, Item item);
|
protected abstract void writeItem(String name, Item<?> item);
|
||||||
|
|
||||||
public void writeBundle() {
|
public void writeBundle() {
|
||||||
for (Entry<String, Item> entry : bundle.getMap().entrySet()) {
|
for (Entry<String, Item<?>> entry : bundle.getMap().entrySet()) {
|
||||||
writeItem(entry.getKey(), entry.getValue());
|
writeItem(entry.getKey(), entry.getValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ public class StringBundleXmlWriter extends StringBundleWriter {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void writeItem(String name, Item item) {
|
protected void writeItem(String name, Item<?> item) {
|
||||||
if (serializer != null) {
|
if (serializer != null) {
|
||||||
try {
|
try {
|
||||||
writeItemImpl(name, item);
|
writeItemImpl(name, item);
|
||||||
|
@ -47,7 +47,7 @@ public class StringBundleXmlWriter extends StringBundleWriter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeItemImpl(String name, Item item) throws IOException {
|
private void writeItemImpl(String name, Item<?> item) throws IOException {
|
||||||
if (serializer != null && item != null) {
|
if (serializer != null && item != null) {
|
||||||
switch (item.getType()) {
|
switch (item.getType()) {
|
||||||
case STRING: {
|
case STRING: {
|
||||||
|
@ -58,13 +58,13 @@ public class StringBundleXmlWriter extends StringBundleWriter {
|
||||||
case LIST: {
|
case LIST: {
|
||||||
StringListItem listItem = (StringListItem) item;
|
StringListItem listItem = (StringListItem) item;
|
||||||
serializer.startTag(null, name);
|
serializer.startTag(null, name);
|
||||||
List<Item> list = listItem.getValue();
|
List<Item<?>> list = listItem.getValue();
|
||||||
for (Item i : list) {
|
for (Item<?> i : list) {
|
||||||
if (i.getType() == StringBundle.ItemType.STRING) {
|
if (i.getType() == StringBundle.ItemType.STRING) {
|
||||||
writeItemImpl(i.getName(), i);
|
writeItemImpl(i.getName(), i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (Item i : list) {
|
for (Item<?> i : list) {
|
||||||
if (i.getType() != StringBundle.ItemType.STRING) {
|
if (i.getType() != StringBundle.ItemType.STRING) {
|
||||||
writeItemImpl(i.getName(), i);
|
writeItemImpl(i.getName(), i);
|
||||||
}
|
}
|
||||||
|
@ -75,14 +75,14 @@ public class StringBundleXmlWriter extends StringBundleWriter {
|
||||||
case MAP: {
|
case MAP: {
|
||||||
StringMapItem mapItem = (StringMapItem) item;
|
StringMapItem mapItem = (StringMapItem) item;
|
||||||
serializer.startTag(null, name);
|
serializer.startTag(null, name);
|
||||||
for (Entry<String, Item> entry : mapItem.getValue().entrySet()) {
|
for (Entry<String, Item<?>> entry : mapItem.getValue().entrySet()) {
|
||||||
Item i = entry.getValue();
|
Item<?> i = entry.getValue();
|
||||||
if (i.getType() == StringBundle.ItemType.STRING) {
|
if (i.getType() == StringBundle.ItemType.STRING) {
|
||||||
writeItemImpl(entry.getKey(), i);
|
writeItemImpl(entry.getKey(), i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (Entry<String, Item> entry : mapItem.getValue().entrySet()) {
|
for (Entry<String, Item<?>> entry : mapItem.getValue().entrySet()) {
|
||||||
Item i = entry.getValue();
|
Item<?> i = entry.getValue();
|
||||||
if (i.getType() != StringBundle.ItemType.STRING) {
|
if (i.getType() != StringBundle.ItemType.STRING) {
|
||||||
writeItemImpl(entry.getKey(), i);
|
writeItemImpl(entry.getKey(), i);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
package net.osmand.router;
|
package net.osmand.router;
|
||||||
|
|
||||||
import net.osmand.GPXUtilities;
|
import net.osmand.GPXUtilities;
|
||||||
import net.osmand.GPXUtilities.GPXExtensionsReader;
|
|
||||||
import net.osmand.GPXUtilities.GPXFile;
|
import net.osmand.GPXUtilities.GPXFile;
|
||||||
|
import net.osmand.GPXUtilities.RouteSegment;
|
||||||
|
import net.osmand.GPXUtilities.RouteType;
|
||||||
import net.osmand.GPXUtilities.WptPt;
|
import net.osmand.GPXUtilities.WptPt;
|
||||||
import net.osmand.Location;
|
import net.osmand.Location;
|
||||||
import net.osmand.PlatformUtil;
|
import net.osmand.PlatformUtil;
|
||||||
|
@ -10,11 +11,8 @@ import net.osmand.binary.BinaryMapRouteReaderAdapter.RouteRegion;
|
||||||
import net.osmand.binary.RouteDataBundle;
|
import net.osmand.binary.RouteDataBundle;
|
||||||
import net.osmand.binary.RouteDataObject;
|
import net.osmand.binary.RouteDataObject;
|
||||||
import net.osmand.binary.StringBundle;
|
import net.osmand.binary.StringBundle;
|
||||||
import net.osmand.binary.StringBundleReader;
|
|
||||||
import net.osmand.binary.StringBundleXmlReader;
|
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.xmlpull.v1.XmlPullParser;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
|
@ -31,6 +29,10 @@ public class RouteImporter {
|
||||||
private File file;
|
private File file;
|
||||||
private GPXFile gpxFile;
|
private GPXFile gpxFile;
|
||||||
|
|
||||||
|
private List<RouteSegmentResult> route = new ArrayList<>();
|
||||||
|
private RouteRegion region = new RouteRegion();
|
||||||
|
private RouteDataResources resources = new RouteDataResources();
|
||||||
|
|
||||||
public RouteImporter(File file) {
|
public RouteImporter(File file) {
|
||||||
this.file = file;
|
this.file = file;
|
||||||
}
|
}
|
||||||
|
@ -40,90 +42,14 @@ public class RouteImporter {
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<RouteSegmentResult> importRoute() {
|
public List<RouteSegmentResult> importRoute() {
|
||||||
|
|
||||||
final List<RouteSegmentResult> route = new ArrayList<>();
|
|
||||||
final RouteRegion region = new RouteRegion();
|
|
||||||
final RouteDataResources resources = new RouteDataResources();
|
|
||||||
|
|
||||||
GPXExtensionsReader extensionsReader = new GPXExtensionsReader() {
|
|
||||||
@Override
|
|
||||||
public boolean readExtensions(GPXFile res, XmlPullParser parser) throws Exception {
|
|
||||||
if (!resources.hasLocations()) {
|
|
||||||
List<Location> locations = resources.getLocations();
|
|
||||||
double lastElevation = HEIGHT_UNDEFINED;
|
|
||||||
if (res.tracks.size() > 0 && res.tracks.get(0).segments.size() > 0 && res.tracks.get(0).segments.get(0).points.size() > 0) {
|
|
||||||
for (WptPt point : res.tracks.get(0).segments.get(0).points) {
|
|
||||||
Location loc = new Location("", point.getLatitude(), point.getLongitude());
|
|
||||||
if (!Double.isNaN(point.ele)) {
|
|
||||||
loc.setAltitude(point.ele);
|
|
||||||
lastElevation = point.ele;
|
|
||||||
} else if (lastElevation != HEIGHT_UNDEFINED) {
|
|
||||||
loc.setAltitude(lastElevation);
|
|
||||||
}
|
|
||||||
locations.add(loc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
String tag = parser.getName();
|
|
||||||
if ("route".equals(tag)) {
|
|
||||||
int tok;
|
|
||||||
while ((tok = parser.next()) != XmlPullParser.END_DOCUMENT) {
|
|
||||||
if (tok == XmlPullParser.START_TAG) {
|
|
||||||
tag = parser.getName();
|
|
||||||
if ("segment".equals(tag)) {
|
|
||||||
StringBundleReader bundleReader = new StringBundleXmlReader(parser);
|
|
||||||
RouteDataObject object = new RouteDataObject(region);
|
|
||||||
RouteSegmentResult segment = new RouteSegmentResult(object);
|
|
||||||
bundleReader.readBundle();
|
|
||||||
segment.readFromBundle(new RouteDataBundle(resources, bundleReader.getBundle()));
|
|
||||||
route.add(segment);
|
|
||||||
}
|
|
||||||
} else if (tok == XmlPullParser.END_TAG) {
|
|
||||||
tag = parser.getName();
|
|
||||||
if ("route".equals(tag)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if ("types".equals(tag)) {
|
|
||||||
int tok;
|
|
||||||
int i = 0;
|
|
||||||
while ((tok = parser.next()) != XmlPullParser.END_DOCUMENT) {
|
|
||||||
if (tok == XmlPullParser.START_TAG) {
|
|
||||||
tag = parser.getName();
|
|
||||||
if ("type".equals(tag)) {
|
|
||||||
StringBundleReader bundleReader = new StringBundleXmlReader(parser);
|
|
||||||
bundleReader.readBundle();
|
|
||||||
StringBundle bundle = bundleReader.getBundle();
|
|
||||||
String t = bundle.getString("t", null);
|
|
||||||
String v = bundle.getString("v", null);
|
|
||||||
region.initRouteEncodingRule(i++, t, v);
|
|
||||||
}
|
|
||||||
} else if (tok == XmlPullParser.END_TAG) {
|
|
||||||
tag = parser.getName();
|
|
||||||
if ("types".equals(tag)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (gpxFile != null) {
|
if (gpxFile != null) {
|
||||||
GPXUtilities.loadGPXFile(null, gpxFile, extensionsReader);
|
parseRoute();
|
||||||
for (RouteSegmentResult segment : route) {
|
|
||||||
segment.fillNames(resources);
|
|
||||||
}
|
|
||||||
} else if (file != null) {
|
} else if (file != null) {
|
||||||
FileInputStream fis = null;
|
FileInputStream fis = null;
|
||||||
try {
|
try {
|
||||||
fis = new FileInputStream(file);
|
fis = new FileInputStream(file);
|
||||||
GPXFile gpxFile = GPXUtilities.loadGPXFile(fis, null, extensionsReader);
|
gpxFile = GPXUtilities.loadGPXFile(fis);
|
||||||
for (RouteSegmentResult segment : route) {
|
parseRoute();
|
||||||
segment.fillNames(resources);
|
|
||||||
}
|
|
||||||
gpxFile.path = file.getAbsolutePath();
|
gpxFile.path = file.getAbsolutePath();
|
||||||
gpxFile.modifiedTime = file.lastModified();
|
gpxFile.modifiedTime = file.lastModified();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
@ -139,7 +65,51 @@ public class RouteImporter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return route;
|
return route;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void parseRoute() {
|
||||||
|
collectLocations();
|
||||||
|
collectSegments();
|
||||||
|
collectTypes();
|
||||||
|
for (RouteSegmentResult segment : route) {
|
||||||
|
segment.fillNames(resources);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void collectLocations() {
|
||||||
|
List<Location> locations = resources.getLocations();
|
||||||
|
double lastElevation = HEIGHT_UNDEFINED;
|
||||||
|
if (gpxFile.tracks.size() > 0 && gpxFile.tracks.get(0).segments.size() > 0 && gpxFile.tracks.get(0).segments.get(0).points.size() > 0) {
|
||||||
|
for (WptPt point : gpxFile.tracks.get(0).segments.get(0).points) {
|
||||||
|
Location loc = new Location("", point.getLatitude(), point.getLongitude());
|
||||||
|
if (!Double.isNaN(point.ele)) {
|
||||||
|
loc.setAltitude(point.ele);
|
||||||
|
lastElevation = point.ele;
|
||||||
|
} else if (lastElevation != HEIGHT_UNDEFINED) {
|
||||||
|
loc.setAltitude(lastElevation);
|
||||||
|
}
|
||||||
|
locations.add(loc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void collectSegments() {
|
||||||
|
for (RouteSegment segment : gpxFile.routeSegments) {
|
||||||
|
RouteDataObject object = new RouteDataObject(region);
|
||||||
|
RouteSegmentResult segmentResult = new RouteSegmentResult(object);
|
||||||
|
segmentResult.readFromBundle(new RouteDataBundle(resources, segment.getStringBundle()));
|
||||||
|
route.add(segmentResult);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void collectTypes() {
|
||||||
|
int i = 0;
|
||||||
|
for (RouteType routeType : gpxFile.routeTypes) {
|
||||||
|
StringBundle bundle = routeType.getStringBundle();
|
||||||
|
String t = bundle.getString("t", null);
|
||||||
|
String v = bundle.getString("v", null);
|
||||||
|
region.initRouteEncodingRule(i++, t, v);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue