/*
* Copyright (C) 2014 Alec Dhuse
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package co.foldingmap.mapImportExport;
import co.foldingmap.map.vector.LatLonAltBox;
import co.foldingmap.map.vector.CoordinateList;
import co.foldingmap.map.vector.VectorObjectList;
import co.foldingmap.map.vector.VectorObject;
import co.foldingmap.map.vector.Coordinate;
import co.foldingmap.map.vector.MapPoint;
import co.foldingmap.map.vector.LineString;
import co.foldingmap.map.DigitalMap;
import co.foldingmap.map.MapUtilities;
import co.foldingmap.xml.XmlWriter;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.SimpleTimeZone;
/**
*
* @author Alec
*/
public class GpxExporter {
/**
* Returns this coordinates timestamp.
* This function is used rather than the one in Coordinate because stupid
* Garmin Basecamp will not except timestamp with hours 1-24.
*
* @param c The coordinate to get the timestamp from.
* @return The timestamp in yyyy-mm-ddThh:mm:ssZ format
*/
public static String getTimestamp(Coordinate c) {
SimpleDateFormat timestampDateFormat;
timestampDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
timestampDateFormat.setTimeZone(new SimpleTimeZone(0, "Z"));
return timestampDateFormat.format(c.getDate()) + "Z";
}
public static void export(DigitalMap mapData, File fileOut) {
float maxlat, maxlon, minlat, minlon;
XmlWriter writer;
LatLonAltBox bounds;
VectorObjectList<VectorObject> lines, objects, points;
StringBuilder gpxTag, sb;
writer = new XmlWriter(fileOut);
gpxTag = new StringBuilder();
sb = new StringBuilder();
//get map bounds info
bounds = mapData.getBoundary();
maxlat = bounds.getNorth();
maxlon = bounds.getEast();
minlat = bounds.getSouth();
minlon = bounds.getWest();
sb.append("\t\t");
sb.append("<bounds maxlat=\"");
sb.append(maxlat);
sb.append("\" maxlon=\"");
sb.append(maxlon);
sb.append("\" minlat=\"");
sb.append(minlat);
sb.append("\" minlon=\"");
sb.append(minlon);
sb.append("\"></bounds>");
sb.append("\n");
writer.writeText("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n");
writer.writeText("<gpx xmlns=\"http://www.topografix.com/GPX/1/1\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" creator=\"Folding Map\" version=\"1.1\" xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd\">\n");
writer.increaseIndent();
//write meta data
writer.openTag("metadata");
writer.openTag("link href=\"http://foldingmap.co\"");
writer.writeTag("text", "Folding Map");
writer.closeTag("link");
writer.writeTag("time", MapUtilities.getCurrentTimestamp());
writer.writeText(sb.toString());
writer.closeTag("metadata");
//export Objects
objects = new VectorObjectList<VectorObject>(mapData.getAllMapObjects());
points = objects.getMapPoints();
lines = objects.getLineStrings();
//export MapPoints
for (VectorObject obj: points)
exportMapPoint(writer, (MapPoint) obj);
//export LineStrings
for (VectorObject obj: lines)
exportLineString(writer, (LineString) obj);
writer.decreaseIndent();
writer.writeText("</gpx>");
writer.closeFile();
}
/**
* Exports LineStrings to a GPX track
*
* @param writer The XML writer
* @param line The LineString to export.
*/
public static void exportLineString(XmlWriter writer, LineString line) {
CoordinateList<Coordinate> cList;
StringBuilder sb;
try {
cList = line.getCoordinateList();
writer.openTag("trk");
writer.writeTag("name", line.getDescription());
writer.openTag("trkseg");
for (Coordinate c: cList) {
sb = new StringBuilder();
sb.append("trkpt lat=\"");
sb.append(c.getLatitude());
sb.append("\" lon=\"");
sb.append(c.getLongitude());
sb.append("\"");
writer.openTag(sb.toString());
writer.writeTag("ele", Float.toString(c.getAltitude()));
writer.writeTag("time", getTimestamp(c));
writer.closeTag("trkpt");
}
writer.closeTag("trkseg");
writer.closeTag("trk");
} catch (Exception e) {
System.err.println("Error in GpxExporter.exportLineString(KmlWriter, LineString) - " + e);
}
}
public static void exportMapPoint(XmlWriter writer, MapPoint point) {
Coordinate c = point.getCoordinateList().get(0);
StringBuilder sb = new StringBuilder();
GpxGarminExtensions garminExt = new GpxGarminExtensions();
sb.append("wpt lat=\"");
sb.append(c.getLatitude());
sb.append("\" lon=\"");
sb.append(c.getLongitude());
sb.append("\"");
writer.openTag(sb.toString());
writer.writeTag("ele", Float.toString(c.getAltitude()));
writer.writeTag("time", getTimestamp(c));
writer.writeTag("name", point.getName());
writer.writeTag("cmt", point.getDescription());
writer.writeTag("desc", point.getDescription());
writer.writeTag("sym", garminExt.getSymbolFromClass(point.getObjectClass()));
writer.closeTag("wpt");
}
}