removed unused formatting
This commit is contained in:
parent
8a7fa9fa81
commit
cb0b1d8855
2 changed files with 0 additions and 877 deletions
|
@ -8,10 +8,6 @@ import java.util.Locale;
|
|||
import java.util.TimeZone;
|
||||
|
||||
public abstract class Formatter {
|
||||
private static final int OUTPUT_FORMAT_GPX = 0;
|
||||
private static final int OUTPUT_FORMAT_KML = 1;
|
||||
private static final int OUTPUT_FORMAT_JSON = 2;
|
||||
private static final int OUTPUT_FORMAT_CSV = 3;
|
||||
|
||||
static final String MESSAGES_HEADER = "Longitude\tLatitude\tElevation\tDistance\tCostPerKm\tElevCost\tTurnCost\tNodeCost\tInitialCost\tWayTags\tNodeTags\tTime\tEnergy";
|
||||
|
||||
|
|
|
@ -7,33 +7,20 @@ package btools.router;
|
|||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.EOFException;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.StringWriter;
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.NumberFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import btools.mapaccess.MatchedWaypoint;
|
||||
import btools.mapaccess.OsmPos;
|
||||
import btools.util.CompactLongMap;
|
||||
import btools.util.FrozenLongMap;
|
||||
import btools.util.StringUtils;
|
||||
|
||||
public final class OsmTrack {
|
||||
final public static String version = "1.7.3";
|
||||
|
@ -395,751 +382,8 @@ public final class OsmTrack {
|
|||
public int plainAscend;
|
||||
public int cost;
|
||||
public int energy;
|
||||
|
||||
/**
|
||||
* writes the track in gpx-format to a file
|
||||
*
|
||||
* @param filename the filename to write to
|
||||
*/
|
||||
public void writeGpx(String filename) throws Exception {
|
||||
BufferedWriter bw = new BufferedWriter(new FileWriter(filename));
|
||||
formatAsGpx(bw);
|
||||
bw.close();
|
||||
}
|
||||
|
||||
public String formatAsGpx() {
|
||||
try {
|
||||
StringWriter sw = new StringWriter(8192);
|
||||
BufferedWriter bw = new BufferedWriter(sw);
|
||||
formatAsGpx(bw);
|
||||
bw.close();
|
||||
return sw.toString();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public String formatAsGpx(BufferedWriter sb) throws IOException {
|
||||
int turnInstructionMode = voiceHints != null ? voiceHints.turnInstructionMode : 0;
|
||||
|
||||
sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
|
||||
if (turnInstructionMode != 9) {
|
||||
for (int i = messageList.size() - 1; i >= 0; i--) {
|
||||
String message = messageList.get(i);
|
||||
if (i < messageList.size() - 1)
|
||||
message = "(alt-index " + i + ": " + message + " )";
|
||||
if (message != null)
|
||||
sb.append("<!-- ").append(message).append(" -->\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (turnInstructionMode == 4) { // comment style
|
||||
sb.append("<!-- $transport-mode$").append(voiceHints.getTransportMode()).append("$ -->\n");
|
||||
sb.append("<!-- cmd idx lon lat d2next geometry -->\n");
|
||||
sb.append("<!-- $turn-instruction-start$\n");
|
||||
for (VoiceHint hint : voiceHints.list) {
|
||||
sb.append(String.format(" $turn$%6s;%6d;%10s;%10s;%6d;%s$\n", hint.getCommandString(), hint.indexInTrack,
|
||||
formatILon(hint.ilon), formatILat(hint.ilat), (int) (hint.distanceToNext), hint.formatGeometry()));
|
||||
}
|
||||
sb.append(" $turn-instruction-end$ -->\n");
|
||||
}
|
||||
sb.append("<gpx \n");
|
||||
sb.append(" xmlns=\"http://www.topografix.com/GPX/1/1\" \n");
|
||||
sb.append(" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" \n");
|
||||
if (turnInstructionMode == 9) { // BRouter style
|
||||
sb.append(" xmlns:brouter=\"Not yet documented\" \n");
|
||||
}
|
||||
if (turnInstructionMode == 7) { // old locus style
|
||||
sb.append(" xmlns:locus=\"http://www.locusmap.eu\" \n");
|
||||
}
|
||||
sb.append(" xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd\" \n");
|
||||
|
||||
if (turnInstructionMode == 3) {
|
||||
sb.append(" creator=\"OsmAndRouter\" version=\"1.1\">\n");
|
||||
} else {
|
||||
sb.append(" creator=\"BRouter-" + version + "\" version=\"1.1\">\n");
|
||||
}
|
||||
if (turnInstructionMode == 9) {
|
||||
sb.append(" <metadata>\n");
|
||||
sb.append(" <name>").append(name).append("</name>\n");
|
||||
sb.append(" <extensions>\n");
|
||||
sb.append(" <brouter:info>").append(messageList.get(0)).append("</brouter:info>\n");
|
||||
if (params != null && params.size() > 0) {
|
||||
sb.append(" <brouter:params><![CDATA[");
|
||||
int i = 0;
|
||||
for (Map.Entry<String, String> e : params.entrySet()) {
|
||||
if (i++ != 0) sb.append("&");
|
||||
sb.append(e.getKey()).append("=").append(e.getValue());
|
||||
}
|
||||
sb.append("]]></brouter:params>\n");
|
||||
}
|
||||
sb.append(" </extensions>\n");
|
||||
sb.append(" </metadata>\n");
|
||||
}
|
||||
if (turnInstructionMode == 3 || turnInstructionMode == 8) { // osmand style, cruiser
|
||||
float lastRteTime = 0;
|
||||
|
||||
sb.append(" <rte>\n");
|
||||
|
||||
float rteTime = getVoiceHintTime(0);
|
||||
StringBuffer first = new StringBuffer();
|
||||
// define start point
|
||||
{
|
||||
first.append(" <rtept lat=\"").append(formatILat(nodes.get(0).getILat())).append("\" lon=\"")
|
||||
.append(formatILon(nodes.get(0).getILon())).append("\">\n")
|
||||
.append(" <desc>start</desc>\n <extensions>\n");
|
||||
if (rteTime != lastRteTime) { // add timing only if available
|
||||
double t = rteTime - lastRteTime;
|
||||
first.append(" <time>").append("" + (int) (t + 0.5)).append("</time>\n");
|
||||
lastRteTime = rteTime;
|
||||
}
|
||||
first.append(" <offset>0</offset>\n </extensions>\n </rtept>\n");
|
||||
}
|
||||
if (turnInstructionMode == 8) {
|
||||
if (matchedWaypoints.get(0).direct && voiceHints.list.get(0).indexInTrack == 0) {
|
||||
// has a voice hint do nothing, voice hint will do
|
||||
} else {
|
||||
sb.append(first.toString());
|
||||
}
|
||||
} else {
|
||||
sb.append(first.toString());
|
||||
}
|
||||
|
||||
for (int i = 0; i < voiceHints.list.size(); i++) {
|
||||
VoiceHint hint = voiceHints.list.get(i);
|
||||
sb.append(" <rtept lat=\"").append(formatILat(hint.ilat)).append("\" lon=\"")
|
||||
.append(formatILon(hint.ilon)).append("\">\n")
|
||||
.append(" <desc>")
|
||||
.append(turnInstructionMode == 3 ? hint.getMessageString() : hint.getCruiserMessageString())
|
||||
.append("</desc>\n <extensions>\n");
|
||||
|
||||
rteTime = getVoiceHintTime(i + 1);
|
||||
|
||||
if (rteTime != lastRteTime) { // add timing only if available
|
||||
double t = rteTime - lastRteTime;
|
||||
sb.append(" <time>").append("" + (int) (t + 0.5)).append("</time>\n");
|
||||
lastRteTime = rteTime;
|
||||
}
|
||||
sb.append(" <turn>")
|
||||
.append(turnInstructionMode == 3 ? hint.getCommandString() : hint.getCruiserCommandString())
|
||||
.append("</turn>\n <turn-angle>").append("" + (int) hint.angle)
|
||||
.append("</turn-angle>\n <offset>").append("" + hint.indexInTrack).append("</offset>\n </extensions>\n </rtept>\n");
|
||||
}
|
||||
sb.append(" <rtept lat=\"").append(formatILat(nodes.get(nodes.size() - 1).getILat())).append("\" lon=\"")
|
||||
.append(formatILon(nodes.get(nodes.size() - 1).getILon())).append("\">\n")
|
||||
.append(" <desc>destination</desc>\n <extensions>\n");
|
||||
sb.append(" <time>0</time>\n");
|
||||
sb.append(" <offset>").append("" + (nodes.size() - 1)).append("</offset>\n </extensions>\n </rtept>\n");
|
||||
|
||||
sb.append("</rte>\n");
|
||||
}
|
||||
|
||||
if (turnInstructionMode == 7) { // old locus style
|
||||
float lastRteTime = getVoiceHintTime(0);
|
||||
|
||||
for (int i = 0; i < voiceHints.list.size(); i++) {
|
||||
VoiceHint hint = voiceHints.list.get(i);
|
||||
sb.append(" <wpt lon=\"").append(formatILon(hint.ilon)).append("\" lat=\"")
|
||||
.append(formatILat(hint.ilat)).append("\">")
|
||||
.append(hint.selev == Short.MIN_VALUE ? "" : "<ele>" + (hint.selev / 4.) + "</ele>")
|
||||
.append("<name>").append(hint.getMessageString()).append("</name>")
|
||||
.append("<extensions><locus:rteDistance>").append("" + hint.distanceToNext).append("</locus:rteDistance>");
|
||||
float rteTime = getVoiceHintTime(i + 1);
|
||||
if (rteTime != lastRteTime) { // add timing only if available
|
||||
double t = rteTime - lastRteTime;
|
||||
double speed = hint.distanceToNext / t;
|
||||
sb.append("<locus:rteTime>").append("" + t).append("</locus:rteTime>")
|
||||
.append("<locus:rteSpeed>").append("" + speed).append("</locus:rteSpeed>");
|
||||
lastRteTime = rteTime;
|
||||
}
|
||||
sb.append("<locus:rtePointAction>").append("" + hint.getLocusAction()).append("</locus:rtePointAction></extensions>")
|
||||
.append("</wpt>\n");
|
||||
}
|
||||
}
|
||||
if (turnInstructionMode == 5) { // gpsies style
|
||||
for (VoiceHint hint : voiceHints.list) {
|
||||
sb.append(" <wpt lon=\"").append(formatILon(hint.ilon)).append("\" lat=\"")
|
||||
.append(formatILat(hint.ilat)).append("\">")
|
||||
.append("<name>").append(hint.getMessageString()).append("</name>")
|
||||
.append("<sym>").append(hint.getSymbolString().toLowerCase()).append("</sym>")
|
||||
.append("<type>").append(hint.getSymbolString()).append("</type>")
|
||||
.append("</wpt>\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (turnInstructionMode == 6) { // orux style
|
||||
for (VoiceHint hint : voiceHints.list) {
|
||||
sb.append(" <wpt lat=\"").append(formatILat(hint.ilat)).append("\" lon=\"")
|
||||
.append(formatILon(hint.ilon)).append("\">")
|
||||
.append(hint.selev == Short.MIN_VALUE ? "" : "<ele>" + (hint.selev / 4.) + "</ele>")
|
||||
.append("<extensions>\n" +
|
||||
" <om:oruxmapsextensions xmlns:om=\"http://www.oruxmaps.com/oruxmapsextensions/1/0\">\n" +
|
||||
" <om:ext type=\"ICON\" subtype=\"0\">").append("" + hint.getOruxAction())
|
||||
.append("</om:ext>\n" +
|
||||
" </om:oruxmapsextensions>\n" +
|
||||
" </extensions>\n" +
|
||||
" </wpt>\n");
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i <= pois.size() - 1; i++) {
|
||||
OsmNodeNamed poi = pois.get(i);
|
||||
sb.append(" <wpt lon=\"").append(formatILon(poi.ilon)).append("\" lat=\"")
|
||||
.append(formatILat(poi.ilat)).append("\">\n")
|
||||
.append(" <name>").append(StringUtils.escapeXml10(poi.name)).append("</name>\n")
|
||||
.append(" </wpt>\n");
|
||||
}
|
||||
|
||||
if (exportWaypoints) {
|
||||
for (int i = 0; i <= matchedWaypoints.size() - 1; i++) {
|
||||
MatchedWaypoint wt = matchedWaypoints.get(i);
|
||||
sb.append(" <wpt lon=\"").append(formatILon(wt.waypoint.ilon)).append("\" lat=\"")
|
||||
.append(formatILat(wt.waypoint.ilat)).append("\">\n")
|
||||
.append(" <name>").append(StringUtils.escapeXml10(wt.name)).append("</name>\n");
|
||||
if (i == 0) {
|
||||
sb.append(" <type>from</type>\n");
|
||||
} else if (i == matchedWaypoints.size() - 1) {
|
||||
sb.append(" <type>to</type>\n");
|
||||
} else {
|
||||
sb.append(" <type>via</type>\n");
|
||||
}
|
||||
sb.append(" </wpt>\n");
|
||||
}
|
||||
}
|
||||
sb.append(" <trk>\n");
|
||||
if (turnInstructionMode == 9
|
||||
|| turnInstructionMode == 2
|
||||
|| turnInstructionMode == 8
|
||||
|| turnInstructionMode == 4) { // Locus, comment, cruise, brouter style
|
||||
sb.append(" <src>").append(name).append("</src>\n");
|
||||
sb.append(" <type>").append(voiceHints.getTransportMode()).append("</type>\n");
|
||||
} else {
|
||||
sb.append(" <name>").append(name).append("</name>\n");
|
||||
}
|
||||
|
||||
if (turnInstructionMode == 7) {
|
||||
sb.append(" <extensions>\n");
|
||||
sb.append(" <locus:rteComputeType>").append("" + voiceHints.getLocusRouteType()).append("</locus:rteComputeType>\n");
|
||||
sb.append(" <locus:rteSimpleRoundabouts>1</locus:rteSimpleRoundabouts>\n");
|
||||
sb.append(" </extensions>\n");
|
||||
}
|
||||
|
||||
|
||||
// all points
|
||||
sb.append(" <trkseg>\n");
|
||||
String lastway = "";
|
||||
boolean bNextDirect = false;
|
||||
OsmPathElement nn = null;
|
||||
String aSpeed;
|
||||
|
||||
for (int idx = 0; idx < nodes.size(); idx++) {
|
||||
OsmPathElement n = nodes.get(idx);
|
||||
String sele = n.getSElev() == Short.MIN_VALUE ? "" : "<ele>" + n.getElev() + "</ele>";
|
||||
VoiceHint hint = getVoiceHint(idx);
|
||||
MatchedWaypoint mwpt = getMatchedWaypoint(idx);
|
||||
|
||||
if (showTime) {
|
||||
sele += "<time>" + getFormattedTime3(n.getTime()) + "</time>";
|
||||
}
|
||||
if (turnInstructionMode == 8) {
|
||||
if (mwpt != null &&
|
||||
!mwpt.name.startsWith("via") && !mwpt.name.startsWith("from") && !mwpt.name.startsWith("to")) {
|
||||
sele += "<name>" + mwpt.name + "</name>";
|
||||
}
|
||||
}
|
||||
boolean bNeedHeader = false;
|
||||
if (turnInstructionMode == 9) { // trkpt/sym style
|
||||
|
||||
if (hint != null) {
|
||||
|
||||
if (mwpt != null &&
|
||||
!mwpt.name.startsWith("via") && !mwpt.name.startsWith("from") && !mwpt.name.startsWith("to")) {
|
||||
sele += "<name>" + mwpt.name + "</name>";
|
||||
}
|
||||
sele += "<desc>" + hint.getCruiserMessageString() + "</desc>";
|
||||
sele += "<sym>" + hint.getCommandString(hint.cmd) + "</sym>";
|
||||
if (mwpt != null) {
|
||||
sele += "<type>Via</type>";
|
||||
}
|
||||
sele += "<extensions>";
|
||||
if (showspeed) {
|
||||
double speed = 0;
|
||||
if (nn != null) {
|
||||
int dist = n.calcDistance(nn);
|
||||
float dt = n.getTime() - nn.getTime();
|
||||
if (dt != 0.f) {
|
||||
speed = ((3.6f * dist) / dt + 0.5);
|
||||
}
|
||||
}
|
||||
sele += "<brouter:speed>" + (((int) (speed * 10)) / 10.f) + "</brouter:speed>";
|
||||
}
|
||||
|
||||
sele += "<brouter:voicehint>" + hint.getCommandString() + ";" + (int) (hint.distanceToNext) + "," + hint.formatGeometry() + "</brouter:voicehint>";
|
||||
if (n.message != null && n.message.wayKeyValues != null && !n.message.wayKeyValues.equals(lastway)) {
|
||||
sele += "<brouter:way>" + n.message.wayKeyValues + "</brouter:way>";
|
||||
lastway = n.message.wayKeyValues;
|
||||
}
|
||||
if (n.message != null && n.message.nodeKeyValues != null) {
|
||||
sele += "<brouter:node>" + n.message.nodeKeyValues + "</brouter:node>";
|
||||
}
|
||||
sele += "</extensions>";
|
||||
|
||||
}
|
||||
if (idx == 0 && hint == null) {
|
||||
if (mwpt != null && mwpt.direct) {
|
||||
sele += "<desc>beeline</desc>";
|
||||
} else {
|
||||
sele += "<desc>start</desc>";
|
||||
}
|
||||
sele += "<type>Via</type>";
|
||||
|
||||
} else if (idx == nodes.size() - 1 && hint == null) {
|
||||
|
||||
sele += "<desc>end</desc>";
|
||||
sele += "<type>Via</type>";
|
||||
|
||||
} else {
|
||||
if (mwpt != null && hint == null) {
|
||||
if (mwpt.direct) {
|
||||
// bNextDirect = true;
|
||||
sele += "<desc>beeline</desc>";
|
||||
} else {
|
||||
sele += "<desc>" + mwpt.name + "</desc>";
|
||||
}
|
||||
sele += "<type>Via</type>";
|
||||
bNextDirect = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (hint == null) {
|
||||
bNeedHeader = (showspeed || (n.message != null && n.message.wayKeyValues != null && !n.message.wayKeyValues.equals(lastway))) ||
|
||||
(n.message != null && n.message.nodeKeyValues != null);
|
||||
if (bNeedHeader) {
|
||||
sele += "<extensions>";
|
||||
if (showspeed) {
|
||||
double speed = 0;
|
||||
if (nn != null) {
|
||||
int dist = n.calcDistance(nn);
|
||||
float dt = n.getTime() - nn.getTime();
|
||||
if (dt != 0.f) {
|
||||
speed = ((3.6f * dist) / dt + 0.5);
|
||||
}
|
||||
}
|
||||
sele += "<brouter:speed>" + (((int) (speed * 10)) / 10.f) + "</brouter:speed>";
|
||||
}
|
||||
if (n.message != null && n.message.wayKeyValues != null && !n.message.wayKeyValues.equals(lastway)) {
|
||||
sele += "<brouter:way>" + n.message.wayKeyValues + "</brouter:way>";
|
||||
lastway = n.message.wayKeyValues;
|
||||
}
|
||||
if (n.message != null && n.message.nodeKeyValues != null) {
|
||||
sele += "<brouter:node>" + n.message.nodeKeyValues + "</brouter:node>";
|
||||
}
|
||||
sele += "</extensions>";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (turnInstructionMode == 2) { // locus style new
|
||||
if (hint != null) {
|
||||
if (mwpt != null) {
|
||||
if (!mwpt.name.startsWith("via") && !mwpt.name.startsWith("from") && !mwpt.name.startsWith("to")) {
|
||||
sele += "<name>" + mwpt.name + "</name>";
|
||||
}
|
||||
if (mwpt.direct && bNextDirect) {
|
||||
sele += "<src>" + hint.getLocusSymbolString() + "</src><sym>pass_place</sym><type>Shaping</type>";
|
||||
// bNextDirect = false;
|
||||
} else if (mwpt.direct) {
|
||||
if (idx == 0)
|
||||
sele += "<sym>pass_place</sym><type>Via</type>";
|
||||
else
|
||||
sele += "<sym>pass_place</sym><type>Shaping</type>";
|
||||
bNextDirect = true;
|
||||
} else if (bNextDirect) {
|
||||
sele += "<src>beeline</src><sym>" + hint.getLocusSymbolString() + "</sym><type>Shaping</type>";
|
||||
bNextDirect = false;
|
||||
} else {
|
||||
sele += "<sym>" + hint.getLocusSymbolString() + "</sym><type>Via</type>";
|
||||
}
|
||||
} else {
|
||||
sele += "<sym>" + hint.getLocusSymbolString() + "</sym>";
|
||||
}
|
||||
} else {
|
||||
if (idx == 0 && hint == null) {
|
||||
|
||||
int pos = sele.indexOf("<sym");
|
||||
if (pos != -1) {
|
||||
sele = sele.substring(0, pos);
|
||||
}
|
||||
if (mwpt != null && !mwpt.name.startsWith("from"))
|
||||
sele += "<name>" + mwpt.name + "</name>";
|
||||
if (mwpt != null && mwpt.direct) {
|
||||
bNextDirect = true;
|
||||
}
|
||||
sele += "<sym>pass_place</sym>";
|
||||
sele += "<type>Via</type>";
|
||||
|
||||
} else if (idx == nodes.size() - 1 && hint == null) {
|
||||
|
||||
int pos = sele.indexOf("<sym");
|
||||
if (pos != -1) {
|
||||
sele = sele.substring(0, pos);
|
||||
}
|
||||
if (mwpt != null && mwpt.name != null && !mwpt.name.startsWith("to"))
|
||||
sele += "<name>" + mwpt.name + "</name>";
|
||||
if (bNextDirect) {
|
||||
sele += "<src>beeline</src>";
|
||||
}
|
||||
sele += "<sym>pass_place</sym>";
|
||||
sele += "<type>Via</type>";
|
||||
|
||||
} else {
|
||||
if (mwpt != null) {
|
||||
if (!mwpt.name.startsWith("via") && !mwpt.name.startsWith("from") && !mwpt.name.startsWith("to")) {
|
||||
sele += "<name>" + mwpt.name + "</name>";
|
||||
}
|
||||
if (mwpt.direct && bNextDirect) {
|
||||
sele += "<src>beeline</src><sym>pass_place</sym><type>Shaping</type>";
|
||||
} else if (mwpt.direct) {
|
||||
if (idx == 0)
|
||||
sele += "<sym>pass_place</sym><type>Via</type>";
|
||||
else
|
||||
sele += "<sym>pass_place</sym><type>Shaping</type>";
|
||||
bNextDirect = true;
|
||||
} else if (bNextDirect) {
|
||||
sele += "<src>beeline</src><sym>pass_place</sym><type>Shaping</type>";
|
||||
bNextDirect = false;
|
||||
} else if (mwpt.name.startsWith("via") ||
|
||||
mwpt.name.startsWith("from") ||
|
||||
mwpt.name.startsWith("to")) {
|
||||
if (bNextDirect) {
|
||||
sele += "<src>beeline</src><sym>pass_place</sym><type>Shaping</type>";
|
||||
} else {
|
||||
sele += "<sym>pass_place</sym><type>Via</type>";
|
||||
}
|
||||
bNextDirect = false;
|
||||
} else {
|
||||
sele += "<name>" + mwpt.name + "</name>";
|
||||
sele += "<sym>pass_place</sym><type>Via</type>";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
sb.append(" <trkpt lon=\"").append(formatILon(n.getILon())).append("\" lat=\"")
|
||||
.append(formatILat(n.getILat())).append("\">").append(sele).append("</trkpt>\n");
|
||||
|
||||
nn = n;
|
||||
}
|
||||
|
||||
sb.append(" </trkseg>\n");
|
||||
sb.append(" </trk>\n");
|
||||
sb.append("</gpx>\n");
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
static public String formatAsGpxWaypoint(OsmNodeNamed n) {
|
||||
try {
|
||||
StringWriter sw = new StringWriter(8192);
|
||||
BufferedWriter bw = new BufferedWriter(sw);
|
||||
formatGpxHeader(bw);
|
||||
formatWaypointGpx(bw, n);
|
||||
formatGpxFooter(bw);
|
||||
bw.close();
|
||||
sw.close();
|
||||
return sw.toString();
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
static public void formatGpxHeader(BufferedWriter sb) throws IOException {
|
||||
sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
|
||||
sb.append("<gpx \n");
|
||||
sb.append(" xmlns=\"http://www.topografix.com/GPX/1/1\" \n");
|
||||
sb.append(" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" \n");
|
||||
sb.append(" xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd\" \n");
|
||||
sb.append(" creator=\"BRouter-" + version + "\" version=\"1.1\">\n");
|
||||
}
|
||||
|
||||
static public void formatGpxFooter(BufferedWriter sb) throws IOException {
|
||||
sb.append("</gpx>\n");
|
||||
}
|
||||
|
||||
static public void formatWaypointGpx(BufferedWriter sb, OsmNodeNamed n) throws IOException {
|
||||
sb.append(" <wpt lon=\"").append(formatILon(n.ilon)).append("\" lat=\"")
|
||||
.append(formatILat(n.ilat)).append("\">");
|
||||
if (n.getSElev() != Short.MIN_VALUE) {
|
||||
sb.append("<ele>").append("" + n.getElev()).append("</ele>");
|
||||
}
|
||||
if (n.name != null) {
|
||||
sb.append("<name>").append(StringUtils.escapeXml10(n.name)).append("</name>");
|
||||
}
|
||||
if (n.nodeDescription != null) {
|
||||
sb.append("<desc>").append("hat desc").append("</desc>");
|
||||
}
|
||||
sb.append("</wpt>\n");
|
||||
}
|
||||
|
||||
public void writeKml(String filename) throws Exception {
|
||||
BufferedWriter bw = new BufferedWriter(new FileWriter(filename));
|
||||
|
||||
bw.write(formatAsKml());
|
||||
bw.close();
|
||||
}
|
||||
|
||||
public String formatAsKml() {
|
||||
StringBuilder sb = new StringBuilder(8192);
|
||||
|
||||
sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
|
||||
|
||||
sb.append("<kml xmlns=\"http://earth.google.com/kml/2.0\">\n");
|
||||
sb.append(" <Document>\n");
|
||||
sb.append(" <name>KML Samples</name>\n");
|
||||
sb.append(" <open>1</open>\n");
|
||||
sb.append(" <distance>3.497064</distance>\n");
|
||||
sb.append(" <traveltime>872</traveltime>\n");
|
||||
sb.append(" <description>To enable simple instructions add: 'instructions=1' as parameter to the URL</description>\n");
|
||||
sb.append(" <Folder>\n");
|
||||
sb.append(" <name>Paths</name>\n");
|
||||
sb.append(" <visibility>0</visibility>\n");
|
||||
sb.append(" <description>Examples of paths.</description>\n");
|
||||
sb.append(" <Placemark>\n");
|
||||
sb.append(" <name>Tessellated</name>\n");
|
||||
sb.append(" <visibility>0</visibility>\n");
|
||||
sb.append(" <description><![CDATA[If the <tessellate> tag has a value of 1, the line will contour to the underlying terrain]]></description>\n");
|
||||
sb.append(" <LineString>\n");
|
||||
sb.append(" <tessellate>1</tessellate>\n");
|
||||
sb.append(" <coordinates>");
|
||||
|
||||
for (OsmPathElement n : nodes) {
|
||||
sb.append(formatILon(n.getILon())).append(",").append(formatILat(n.getILat())).append("\n");
|
||||
}
|
||||
|
||||
sb.append(" </coordinates>\n");
|
||||
sb.append(" </LineString>\n");
|
||||
sb.append(" </Placemark>\n");
|
||||
sb.append(" </Folder>\n");
|
||||
if (exportWaypoints || !pois.isEmpty()) {
|
||||
if (!pois.isEmpty()) {
|
||||
sb.append(" <Folder>\n");
|
||||
sb.append(" <name>poi</name>\n");
|
||||
for (int i = 0; i < pois.size(); i++) {
|
||||
OsmNodeNamed poi = pois.get(i);
|
||||
createPlaceMark(sb, poi.name, poi.ilat, poi.ilon);
|
||||
}
|
||||
sb.append(" </Folder>\n");
|
||||
}
|
||||
|
||||
if (exportWaypoints) {
|
||||
int size = matchedWaypoints.size();
|
||||
createFolder(sb, "start", matchedWaypoints.subList(0, 1));
|
||||
if (matchedWaypoints.size() > 2) {
|
||||
createFolder(sb, "via", matchedWaypoints.subList(1, size - 1));
|
||||
}
|
||||
createFolder(sb, "end", matchedWaypoints.subList(size - 1, size));
|
||||
}
|
||||
}
|
||||
sb.append(" </Document>\n");
|
||||
sb.append("</kml>\n");
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private void createFolder(StringBuilder sb, String type, List<MatchedWaypoint> waypoints) {
|
||||
sb.append(" <Folder>\n");
|
||||
sb.append(" <name>" + type + "</name>\n");
|
||||
for (int i = 0; i < waypoints.size(); i++) {
|
||||
MatchedWaypoint wp = waypoints.get(i);
|
||||
createPlaceMark(sb, wp.name, wp.waypoint.ilat, wp.waypoint.ilon);
|
||||
}
|
||||
sb.append(" </Folder>\n");
|
||||
}
|
||||
|
||||
private void createPlaceMark(StringBuilder sb, String name, int ilat, int ilon) {
|
||||
sb.append(" <Placemark>\n");
|
||||
sb.append(" <name>" + StringUtils.escapeXml10(name) + "</name>\n");
|
||||
sb.append(" <Point>\n");
|
||||
sb.append(" <coordinates>" + formatILon(ilon) + "," + formatILat(ilat) + "</coordinates>\n");
|
||||
sb.append(" </Point>\n");
|
||||
sb.append(" </Placemark>\n");
|
||||
}
|
||||
|
||||
public List<String> iternity;
|
||||
|
||||
public void writeJson(String filename) throws Exception {
|
||||
BufferedWriter bw = new BufferedWriter(new FileWriter(filename));
|
||||
|
||||
bw.write(formatAsGeoJson());
|
||||
bw.close();
|
||||
}
|
||||
|
||||
|
||||
public String formatAsGeoJson() {
|
||||
int turnInstructionMode = voiceHints != null ? voiceHints.turnInstructionMode : 0;
|
||||
|
||||
StringBuilder sb = new StringBuilder(8192);
|
||||
|
||||
sb.append("{\n");
|
||||
sb.append(" \"type\": \"FeatureCollection\",\n");
|
||||
sb.append(" \"features\": [\n");
|
||||
sb.append(" {\n");
|
||||
sb.append(" \"type\": \"Feature\",\n");
|
||||
sb.append(" \"properties\": {\n");
|
||||
sb.append(" \"creator\": \"BRouter-" + version + "\",\n");
|
||||
sb.append(" \"name\": \"").append(name).append("\",\n");
|
||||
sb.append(" \"track-length\": \"").append(distance).append("\",\n");
|
||||
sb.append(" \"filtered ascend\": \"").append(ascend).append("\",\n");
|
||||
sb.append(" \"plain-ascend\": \"").append(plainAscend).append("\",\n");
|
||||
sb.append(" \"total-time\": \"").append(getTotalSeconds()).append("\",\n");
|
||||
sb.append(" \"total-energy\": \"").append(energy).append("\",\n");
|
||||
sb.append(" \"cost\": \"").append(cost).append("\",\n");
|
||||
if (voiceHints != null && !voiceHints.list.isEmpty()) {
|
||||
sb.append(" \"voicehints\": [\n");
|
||||
for (VoiceHint hint : voiceHints.list) {
|
||||
sb.append(" [");
|
||||
sb.append(hint.indexInTrack);
|
||||
sb.append(',').append(hint.getJsonCommandIndex());
|
||||
sb.append(',').append(hint.getExitNumber());
|
||||
sb.append(',').append(hint.distanceToNext);
|
||||
sb.append(',').append((int) hint.angle);
|
||||
|
||||
// not always include geometry because longer and only needed for comment style
|
||||
if (turnInstructionMode == 4) { // comment style
|
||||
sb.append(",\"").append(hint.formatGeometry()).append("\"");
|
||||
}
|
||||
|
||||
sb.append("],\n");
|
||||
}
|
||||
sb.deleteCharAt(sb.lastIndexOf(","));
|
||||
sb.append(" ],\n");
|
||||
}
|
||||
if (showSpeedProfile) { // set in profile
|
||||
List<String> sp = aggregateSpeedProfile();
|
||||
if (sp.size() > 0) {
|
||||
sb.append(" \"speedprofile\": [\n");
|
||||
for (int i = sp.size() - 1; i >= 0; i--) {
|
||||
sb.append(" [").append(sp.get(i)).append(i > 0 ? "],\n" : "]\n");
|
||||
}
|
||||
sb.append(" ],\n");
|
||||
}
|
||||
}
|
||||
// ... traditional message list
|
||||
{
|
||||
sb.append(" \"messages\": [\n");
|
||||
sb.append(" [\"").append(MESSAGES_HEADER.replaceAll("\t", "\", \"")).append("\"],\n");
|
||||
for (String m : aggregateMessages()) {
|
||||
sb.append(" [\"").append(m.replaceAll("\t", "\", \"")).append("\"],\n");
|
||||
}
|
||||
sb.deleteCharAt(sb.lastIndexOf(","));
|
||||
sb.append(" ],\n");
|
||||
}
|
||||
|
||||
if (getTotalSeconds() > 0) {
|
||||
sb.append(" \"times\": [");
|
||||
DecimalFormat decimalFormat = (DecimalFormat) NumberFormat.getInstance(Locale.ENGLISH);
|
||||
decimalFormat.applyPattern("0.###");
|
||||
for (OsmPathElement n : nodes) {
|
||||
sb.append(decimalFormat.format(n.getTime())).append(",");
|
||||
}
|
||||
sb.deleteCharAt(sb.lastIndexOf(","));
|
||||
sb.append("]\n");
|
||||
} else {
|
||||
sb.deleteCharAt(sb.lastIndexOf(","));
|
||||
}
|
||||
|
||||
sb.append(" },\n");
|
||||
|
||||
if (iternity != null) {
|
||||
sb.append(" \"iternity\": [\n");
|
||||
for (String s : iternity) {
|
||||
sb.append(" \"").append(s).append("\",\n");
|
||||
}
|
||||
sb.deleteCharAt(sb.lastIndexOf(","));
|
||||
sb.append(" ],\n");
|
||||
}
|
||||
sb.append(" \"geometry\": {\n");
|
||||
sb.append(" \"type\": \"LineString\",\n");
|
||||
sb.append(" \"coordinates\": [\n");
|
||||
|
||||
OsmPathElement nn = null;
|
||||
for (OsmPathElement n : nodes) {
|
||||
String sele = n.getSElev() == Short.MIN_VALUE ? "" : ", " + n.getElev();
|
||||
if (showspeed) { // hack: show speed instead of elevation
|
||||
double speed = 0;
|
||||
if (nn != null) {
|
||||
int dist = n.calcDistance(nn);
|
||||
float dt = n.getTime() - nn.getTime();
|
||||
if (dt != 0.f) {
|
||||
speed = ((3.6f * dist) / dt + 0.5);
|
||||
}
|
||||
}
|
||||
sele = ", " + (((int) (speed * 10)) / 10.f);
|
||||
}
|
||||
sb.append(" [").append(formatILon(n.getILon())).append(", ").append(formatILat(n.getILat()))
|
||||
.append(sele).append("],\n");
|
||||
nn = n;
|
||||
}
|
||||
sb.deleteCharAt(sb.lastIndexOf(","));
|
||||
|
||||
sb.append(" ]\n");
|
||||
sb.append(" }\n");
|
||||
if (exportWaypoints || !pois.isEmpty()) {
|
||||
sb.append(" },\n");
|
||||
for (int i = 0; i <= pois.size() - 1; i++) {
|
||||
OsmNodeNamed poi = pois.get(i);
|
||||
addFeature(sb, "poi", poi.name, poi.ilat, poi.ilon);
|
||||
if (i < matchedWaypoints.size() - 1) {
|
||||
sb.append(",");
|
||||
}
|
||||
sb.append(" \n");
|
||||
}
|
||||
if (exportWaypoints) {
|
||||
for (int i = 0; i <= matchedWaypoints.size() - 1; i++) {
|
||||
String type;
|
||||
if (i == 0) {
|
||||
type = "from";
|
||||
} else if (i == matchedWaypoints.size() - 1) {
|
||||
type = "to";
|
||||
} else {
|
||||
type = "via";
|
||||
}
|
||||
|
||||
MatchedWaypoint wp = matchedWaypoints.get(i);
|
||||
addFeature(sb, type, wp.name, wp.waypoint.ilat, wp.waypoint.ilon);
|
||||
if (i < matchedWaypoints.size() - 1) {
|
||||
sb.append(",");
|
||||
}
|
||||
sb.append(" \n");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
sb.append(" }\n");
|
||||
}
|
||||
sb.append(" ]\n");
|
||||
sb.append("}\n");
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private void addFeature(StringBuilder sb, String type, String name, int ilat, int ilon) {
|
||||
sb.append(" {\n");
|
||||
sb.append(" \"type\": \"Feature\",\n");
|
||||
sb.append(" \"properties\": {\n");
|
||||
sb.append(" \"name\": \"" + StringUtils.escapeJson(name) + "\",\n");
|
||||
sb.append(" \"type\": \"" + type + "\"\n");
|
||||
sb.append(" },\n");
|
||||
sb.append(" \"geometry\": {\n");
|
||||
sb.append(" \"type\": \"Point\",\n");
|
||||
sb.append(" \"coordinates\": [\n");
|
||||
sb.append(" " + formatILon(ilon) + ",\n");
|
||||
sb.append(" " + formatILat(ilat) + "\n");
|
||||
sb.append(" ]\n");
|
||||
sb.append(" }\n");
|
||||
sb.append(" }");
|
||||
}
|
||||
|
||||
public VoiceHint getVoiceHint(int i) {
|
||||
if (voiceHints == null) return null;
|
||||
for (VoiceHint hint : voiceHints.list) {
|
||||
|
@ -1173,123 +417,6 @@ public final class OsmTrack {
|
|||
return (int) (s + 0.5);
|
||||
}
|
||||
|
||||
public String getFormattedTime() {
|
||||
return format1(getTotalSeconds() / 60.) + "m";
|
||||
}
|
||||
|
||||
public String getFormattedTime2() {
|
||||
int seconds = (int) (getTotalSeconds() + 0.5);
|
||||
int hours = seconds / 3600;
|
||||
int minutes = (seconds - hours * 3600) / 60;
|
||||
seconds = seconds - hours * 3600 - minutes * 60;
|
||||
String time = "";
|
||||
if (hours != 0)
|
||||
time = "" + hours + "h ";
|
||||
if (minutes != 0)
|
||||
time = time + minutes + "m ";
|
||||
if (seconds != 0)
|
||||
time = time + seconds + "s";
|
||||
return time;
|
||||
}
|
||||
|
||||
SimpleDateFormat TIMESTAMP_FORMAT;
|
||||
|
||||
public String getFormattedTime3(float time) {
|
||||
if (TIMESTAMP_FORMAT == null) {
|
||||
TIMESTAMP_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.US);
|
||||
TIMESTAMP_FORMAT.setTimeZone(TimeZone.getTimeZone("UTC"));
|
||||
}
|
||||
// yyyy-mm-ddThh:mm:ss.SSSZ
|
||||
Date d = new Date((long) (time * 1000f));
|
||||
return TIMESTAMP_FORMAT.format(d);
|
||||
}
|
||||
|
||||
public String getFormattedEnergy() {
|
||||
return format1(energy / 3600000.) + "kwh";
|
||||
}
|
||||
|
||||
private static String formatILon(int ilon) {
|
||||
return formatPos(ilon - 180000000);
|
||||
}
|
||||
|
||||
private static String formatILat(int ilat) {
|
||||
return formatPos(ilat - 90000000);
|
||||
}
|
||||
|
||||
private static String formatPos(int p) {
|
||||
boolean negative = p < 0;
|
||||
if (negative)
|
||||
p = -p;
|
||||
char[] ac = new char[12];
|
||||
int i = 11;
|
||||
while (p != 0 || i > 3) {
|
||||
ac[i--] = (char) ('0' + (p % 10));
|
||||
p /= 10;
|
||||
if (i == 5)
|
||||
ac[i--] = '.';
|
||||
}
|
||||
if (negative)
|
||||
ac[i--] = '-';
|
||||
return new String(ac, i + 1, 11 - i);
|
||||
}
|
||||
|
||||
private String format1(double n) {
|
||||
String s = "" + (long) (n * 10 + 0.5);
|
||||
int len = s.length();
|
||||
return s.substring(0, len - 1) + "." + s.charAt(len - 1);
|
||||
}
|
||||
|
||||
public void dumpMessages(String filename, RoutingContext rc) throws Exception {
|
||||
BufferedWriter bw = filename == null ? null : new BufferedWriter(new FileWriter(filename));
|
||||
writeMessages(bw, rc);
|
||||
}
|
||||
|
||||
public void writeMessages(BufferedWriter bw, RoutingContext rc) throws Exception {
|
||||
dumpLine(bw, MESSAGES_HEADER);
|
||||
for (String m : aggregateMessages()) {
|
||||
dumpLine(bw, m);
|
||||
}
|
||||
if (bw != null)
|
||||
bw.close();
|
||||
}
|
||||
|
||||
private void dumpLine(BufferedWriter bw, String s) throws Exception {
|
||||
if (bw == null) {
|
||||
System.out.println(s);
|
||||
} else {
|
||||
bw.write(s);
|
||||
bw.write("\n");
|
||||
}
|
||||
}
|
||||
|
||||
public void readGpx(String filename) throws Exception {
|
||||
File f = new File(filename);
|
||||
if (!f.exists())
|
||||
return;
|
||||
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(f)));
|
||||
|
||||
for (; ; ) {
|
||||
String line = br.readLine();
|
||||
if (line == null)
|
||||
break;
|
||||
|
||||
int idx0 = line.indexOf("<trkpt lon=\"");
|
||||
if (idx0 >= 0) {
|
||||
idx0 += 12;
|
||||
int idx1 = line.indexOf('"', idx0);
|
||||
int ilon = (int) ((Double.parseDouble(line.substring(idx0, idx1)) + 180.) * 1000000. + 0.5);
|
||||
int idx2 = line.indexOf(" lat=\"");
|
||||
if (idx2 < 0)
|
||||
continue;
|
||||
idx2 += 6;
|
||||
int idx3 = line.indexOf('"', idx2);
|
||||
int ilat = (int) ((Double.parseDouble(line.substring(idx2, idx3)) + 90.) * 1000000. + 0.5);
|
||||
nodes.add(OsmPathElement.create(ilon, ilat, (short) 0, null, false));
|
||||
}
|
||||
}
|
||||
br.close();
|
||||
}
|
||||
|
||||
public boolean equalsTrack(OsmTrack t) {
|
||||
if (nodes.size() != t.nodes.size())
|
||||
return false;
|
||||
|
|
Loading…
Reference in a new issue