Package org.openstreetmap.josm.io

Source Code of org.openstreetmap.josm.io.GpxWriter

// License: GPL. For details, see LICENSE file.
package org.openstreetmap.josm.io;

import static org.openstreetmap.josm.tools.I18n.tr;

import java.io.BufferedWriter;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import java.util.Collection;
import java.util.Map;
import java.util.Map.Entry;

import javax.xml.XMLConstants;

import org.openstreetmap.josm.data.Bounds;
import org.openstreetmap.josm.data.coor.LatLon;
import org.openstreetmap.josm.data.gpx.Extensions;
import org.openstreetmap.josm.data.gpx.GpxConstants;
import org.openstreetmap.josm.data.gpx.GpxData;
import org.openstreetmap.josm.data.gpx.GpxLink;
import org.openstreetmap.josm.data.gpx.GpxRoute;
import org.openstreetmap.josm.data.gpx.GpxTrack;
import org.openstreetmap.josm.data.gpx.GpxTrackSegment;
import org.openstreetmap.josm.data.gpx.IWithAttributes;
import org.openstreetmap.josm.data.gpx.WayPoint;

/**
* Writes GPX files from GPX data or OSM data.
*/
public class GpxWriter extends XmlWriter implements GpxConstants {

    public GpxWriter(PrintWriter out) {
        super(out);
    }

    public GpxWriter(OutputStream out) {
        super(new PrintWriter(new BufferedWriter(new OutputStreamWriter(out, StandardCharsets.UTF_8))));
    }

    private GpxData data;
    private String indent = "";

    private static final int WAY_POINT = 0;
    private static final int ROUTE_POINT = 1;
    private static final int TRACK_POINT = 2;

    public void write(GpxData data) {
        this.data = data;
        // We write JOSM specific meta information into gpx 'extensions' elements.
        // In particular it is noted whether the gpx data is from the OSM server
        // (so the rendering of clouds of anonymous TrackPoints can be improved)
        // and some extra synchronization info for export of AudioMarkers.
        // It is checked in advance, if any extensions are used, so we know whether
        // a namespace declaration is necessary.
        boolean hasExtensions = data.fromServer;
        if (!hasExtensions) {
            for (WayPoint wpt : data.waypoints) {
                Extensions extensions = (Extensions) wpt.get(META_EXTENSIONS);
                if (extensions != null && !extensions.isEmpty()) {
                    hasExtensions = true;
                    break;
                }
            }
        }

        out.println("<?xml version='1.0' encoding='UTF-8'?>");
        out.println("<gpx version=\"1.1\" creator=\"JOSM GPX export\" xmlns=\"http://www.topografix.com/GPX/1/1\"\n" +
                (hasExtensions ? String.format("    xmlns:josm=\"%s\"%n", JOSM_EXTENSIONS_NAMESPACE_URI) : "") +
                "    xmlns:xsi=\""+XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI+"\" \n" +
                "    xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd\">");
        indent = "  ";
        writeMetaData();
        writeWayPoints();
        writeRoutes();
        writeTracks();
        out.print("</gpx>");
        out.flush();
    }

    private void writeAttr(IWithAttributes obj) {
        for (String key : WPT_KEYS) {
            if (key.equals(META_LINKS)) {
                @SuppressWarnings("unchecked")
                Collection<GpxLink> lValue = (Collection<GpxLink>) obj.getCollection(key);
                if (lValue != null) {
                    for (GpxLink link : lValue) {
                        gpxLink(link);
                    }
                }
            } else if (key.equals(META_EXTENSIONS)) {
                Extensions extensions = (Extensions) obj.get(key);
                if (extensions != null) {
                    gpxExtensions(extensions);
                }
            } else {
                String value = obj.getString(key);
                if (value != null) {
                    simpleTag(key, value);
                }
            }
        }
    }

    @SuppressWarnings("unchecked")
    private void writeMetaData() {
        Map<String, Object> attr = data.attr;
        openln("metadata");

        // write the description
        if (attr.containsKey(META_DESC)) {
            simpleTag("desc", (String)attr.get(META_DESC));
        }

        // write the author details
        if (attr.containsKey(META_AUTHOR_NAME)
                || attr.containsKey(META_AUTHOR_EMAIL)) {
            openln("author");
            // write the name
            simpleTag("name", (String) attr.get(META_AUTHOR_NAME));
            // write the email address
            if (attr.containsKey(META_AUTHOR_EMAIL)) {
                String[] tmp = ((String)attr.get(META_AUTHOR_EMAIL)).split("@");
                if (tmp.length == 2) {
                    inline("email", "id=\"" + tmp[0] + "\" domain=\""+tmp[1]+"\"");
                }
            }
            // write the author link
            gpxLink((GpxLink) attr.get(META_AUTHOR_LINK));
            closeln("author");
        }

        // write the copyright details
        if (attr.containsKey(META_COPYRIGHT_LICENSE)
                || attr.containsKey(META_COPYRIGHT_YEAR)) {
            openAtt("copyright", "author=\""+ attr.get(META_COPYRIGHT_AUTHOR) +"\"");
            if (attr.containsKey(META_COPYRIGHT_YEAR)) {
                simpleTag("year", (String) attr.get(META_COPYRIGHT_YEAR));
            }
            if (attr.containsKey(META_COPYRIGHT_LICENSE)) {
                simpleTag("license", encode((String) attr.get(META_COPYRIGHT_LICENSE)));
            }
            closeln("copyright");
        }

        // write links
        if (attr.containsKey(META_LINKS)) {
            for (GpxLink link : (Collection<GpxLink>) attr.get(META_LINKS)) {
                gpxLink(link);
            }
        }

        // write keywords
        if (attr.containsKey(META_KEYWORDS)) {
            simpleTag("keywords", (String)attr.get(META_KEYWORDS));
        }

        Bounds bounds = data.recalculateBounds();
        if (bounds != null) {
            String b = "minlat=\"" + bounds.getMinLat() + "\" minlon=\"" + bounds.getMinLon() +
            "\" maxlat=\"" + bounds.getMaxLat() + "\" maxlon=\"" + bounds.getMaxLon() + "\"" ;
            inline("bounds", b);
        }

        if (data.fromServer) {
            openln("extensions");
            simpleTag("josm:from-server", "true");
            closeln("extensions");
        }

        closeln("metadata");
    }

    private void writeWayPoints() {
        for (WayPoint pnt : data.waypoints) {
            wayPoint(pnt, WAY_POINT);
        }
    }

    private void writeRoutes() {
        for (GpxRoute rte : data.routes) {
            openln("rte");
            writeAttr(rte);
            for (WayPoint pnt : rte.routePoints) {
                wayPoint(pnt, ROUTE_POINT);
            }
            closeln("rte");
        }
    }

    private void writeTracks() {
        for (GpxTrack trk : data.tracks) {
            openln("trk");
            writeAttr(trk);
            for (GpxTrackSegment seg : trk.getSegments()) {
                openln("trkseg");
                for (WayPoint pnt : seg.getWayPoints()) {
                    wayPoint(pnt, TRACK_POINT);
                }
                closeln("trkseg");
            }
            closeln("trk");
        }
    }

    private void openln(String tag) {
        open(tag);
        out.println();
    }

    private void open(String tag) {
        out.print(indent + "<" + tag + ">");
        indent += "  ";
    }

    private void openAtt(String tag, String attributes) {
        out.println(indent + "<" + tag + " " + attributes + ">");
        indent += "  ";
    }

    private void inline(String tag, String attributes) {
        out.println(indent + "<" + tag + " " + attributes + "/>");
    }

    private void close(String tag) {
        indent = indent.substring(2);
        out.print(indent + "</" + tag + ">");
    }

    private void closeln(String tag) {
        close(tag);
        out.println();
    }

    /**
     * if content not null, open tag, write encoded content, and close tag
     * else do nothing.
     */
    private void simpleTag(String tag, String content) {
        if (content != null && content.length() > 0) {
            open(tag);
            out.print(encode(content));
            out.println("</" + tag + ">");
            indent = indent.substring(2);
        }
    }

    /**
     * output link
     */
    private void gpxLink(GpxLink link) {
        if (link != null) {
            openAtt("link", "href=\"" + link.uri + "\"");
            simpleTag("text", link.text);
            simpleTag("type", link.type);
            closeln("link");
        }
    }

    /**
     * output a point
     */
    private void wayPoint(WayPoint pnt, int mode) {
        String type;
        switch(mode) {
        case WAY_POINT:
            type = "wpt";
            break;
        case ROUTE_POINT:
            type = "rtept";
            break;
        case TRACK_POINT:
            type = "trkpt";
            break;
        default:
            throw new RuntimeException(tr("Unknown mode {0}.", mode));
        }
        if (pnt != null) {
            LatLon c = pnt.getCoor();
            String coordAttr = "lat=\"" + c.lat() + "\" lon=\"" + c.lon() + "\"";
            if (pnt.attr.isEmpty()) {
                inline(type, coordAttr);
            } else {
                openAtt(type, coordAttr);
                writeAttr(pnt);
                closeln(type);
            }
        }
    }

    private void gpxExtensions(Extensions extensions) {
        if (extensions != null && !extensions.isEmpty()) {
            openln("extensions");
            for (Entry<String, String> e : extensions.entrySet()) {
                simpleTag("josm:" + e.getKey(), e.getValue());
            }
            closeln("extensions");
        }
    }
}
TOP

Related Classes of org.openstreetmap.josm.io.GpxWriter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.