Datei:HmProfil.jar.kmz: Unterschied zwischen den Versionen

Aus Radreise-Wiki
(→‎Sourcecode: Pfade angepasst)
 
(4 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt)
Zeile 1: Zeile 1:
== Beschreibung ==
== Beschreibung ==


Java jar-Datei zum Erstellen der Höhenprofile. Vor der Benutzung umbenennen in "HmProfil.jar"
Java jar-Datei zum Erstellen der Höhenprofile. Vor der Benutzung umbenennen in "HmProfil.jar.zip", entpacken und umbenennen in "HmProfil.jar".


[[Kategorie: Verwaltungs-Software]]
[[Kategorie: Verwaltungs-Software]]
Zeile 8: Zeile 8:


{{cc}}
{{cc}}
== Sourcecode ==
<nowiki>
import java.util.ArrayList;
import java.util.Arrays;
public class GeoPoint {
    String name = "";
    String rawTrackPoint;
    float lon;
    float lat;
    float alt;
    //distance to first point of track
    float dist;
    // coordinates on screen and in image
    int x;
    int y;
    public GeoPoint () {
    }
    public GeoPoint (double lat, double lon) {
        name = "";
        this.lat = (float) lat;
        this.lon = (float) lon;
    }
    public GeoPoint (String rawTrackPoint) {
        name = "";
        this.rawTrackPoint = rawTrackPoint;
        splitRawTrackPoint (rawTrackPoint);
    }
    public GeoPoint (String name, String rawTrackPoint) {
        this.name = name;
        this.rawTrackPoint = rawTrackPoint;
        splitRawTrackPoint (rawTrackPoint);
    }
    public GeoPoint (String rawTrackPoint, String name, String link) {
        this.name = name;
        this.rawTrackPoint = rawTrackPoint;
        splitRawTrackPoint (rawTrackPoint);
    }
    private void splitRawTrackPoint (String rawTrackPoint) {
        //System.out.println("rawTrackPoint: " + rawTrackPoint);
        ArrayList rawGeoData = new ArrayList (Arrays.asList (rawTrackPoint.split (",")));
        switch (rawGeoData.size ()) {
            case 2:
                lon = (new Float ((String) rawGeoData.get (0))).floatValue ();
                lat = (new Float ((String) rawGeoData.get (1))).floatValue ();
                alt = 0;
                break;
            case 3:
                lon = (new Float ((String) rawGeoData.get (0))).floatValue ();
                lat = (new Float ((String) rawGeoData.get (1))).floatValue ();
                alt = (new Float ((String) rawGeoData.get (2))).floatValue ();
                break;
            default:
                System.out.println ("Error: Trackpoint data is not valid: " + rawTrackPoint);
                System.exit (1);
        }
    }
    static double getDistance (TrackPoint tp1, TrackPoint tp2) {
        double lat1 = tp1.lat / 180 * Math.PI;
        double lon1 = tp1.lon / 180 * Math.PI;
        double lat2 = tp2.lat / 180 * Math.PI;
        double lon2 = tp2.lon / 180 * Math.PI;
        double dist = Math.acos (
                Math.sin (lat1) * Math.sin (lat2) +
                        Math.cos (lat1) * Math.cos (lat2) *
                                Math.cos (lon2 - lon1)
        ) * 6378.137; // radius of the equator
        if (Double.isNaN (dist)) dist = 0;
        return dist;
    }
}
import java.util.ArrayList;
import java.util.Arrays;
public class GPS_Track extends ArrayList <TrackPoint> {
    float minLon = +180;
    float maxLon = -180;
    float minLat =  +90;
    float maxLat =  -90;
    float minAlt = 10000;
    float maxAlt = -1000;
    double length;
    public GPS_Track () {}
    public void addPath (String rawPath) {
        TrackPoint tp;
        ArrayList rawTrackpoints = new ArrayList (Arrays.asList (rawPath.split (" ")));
        for (Object rawTrackpoint : rawTrackpoints) {
            tp = new TrackPoint ((String) rawTrackpoint);
            if (tp.lon < minLon) minLon = tp.lon;
            if (tp.lon > maxLon) maxLon = tp.lon;
            if (tp.lat < minLat) minLat = tp.lat;
            if (tp.lat > maxLat) maxLat = tp.lat;
            if (tp.alt < minAlt) minAlt = tp.alt;
            if (tp.alt > maxAlt) maxAlt = tp.alt;
            this.add (tp);
        }
        length = getPathLength (get (0), get (size () - 1));
    }
    public int getClosestPoint (GeoPoint placeMark) {
        double lat = placeMark.lat;
        double lon = placeMark.lon;
        double dist = 1000;
        TrackPoint tp;
        TrackPoint tpNear = null;
        for (Object o : this) {
            tp = (TrackPoint) o;
            if (tp.name.equals ("") || tp.name.equals ("TP")) {
                if (dist > Math.abs (lon - tp.lon) + Math.abs (lat - tp.lat)) {
                    dist = Math.abs (lon - tp.lon) + Math.abs (lat - tp.lat);
                    tpNear = tp;
                }
            }
        }
        return indexOf (tpNear);
        /* more exact but slower
        if (dist > TrackPoint.getDistance(tp, new TrackPoint(lat, lon))) {
            dist = TrackPoint.getDistance(tp, new TrackPoint(lat, lon));
            tpNear = tp;*/
    }
    public float getPathLength (TrackPoint tp0, TrackPoint tp1) {
        float dist = 0;
        int i0 = getClosestPoint (tp0);
        int i1 = getClosestPoint (tp1);
        for (int i = i0 + 1; i <= i1; i++) {
            dist += TrackPoint.getDistance (get (i - 1), get (i));
            //System.out.print(((TrackPoint)get(i)).rawTrackPoint);
            //System.out.println(" : " + dist);
        }
        return dist;
    }
    public void printTrackData () {
        for (Object o : this) {
            TrackPoint tp = (TrackPoint) o;
            System.out.println ("::" + tp.lon + "::" + tp.lat + "::" + tp.alt + "::");
        }
        System.out.println ();
    }
}import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
public class HmProfil {
    final String KML_DIR_PATH = "../kml/";
    final String OUT_DIR_PATH = "../upload/";
    String    routeName;
    File      kmlFile;
    GPS_Track gps_track = new GPS_Track ();
    Roadbook  roadbook  = new Roadbook ();
    public HmProfil (String routeName) {
        this.routeName = routeName;
        System.out.println ("\nReading " + this.routeName + " ...\n");
        kmlFile = new File (KML_DIR_PATH + this.routeName + ".kml");
        try {
            DefaultHandler handler = new KML_Parser (gps_track, roadbook);
            SAXParser saxParser = SAXParserFactory.newInstance ().newSAXParser ();
            saxParser.parse (kmlFile, handler);
        } catch (ParserConfigurationException e) {
            e.printStackTrace ();
        } catch (SAXException e) {
            e.printStackTrace ();
        } catch (IOException e) {
            e.printStackTrace ();
        }
        System.out.format ("  trackpoints  : %d%n"    , gps_track.size ());
        System.out.format ("  track length : %.2f km%n", gps_track.length);
        System.out.println ("\nGenerating Profile and Thumbnail ...\n");
        Profil profil = new Profil (gps_track, roadbook);
        profil.drawImage (OUT_DIR_PATH + routeName + ".png");
        profil.drawThumb (OUT_DIR_PATH + routeName + "_s.png");
    }
    public static void main (String[] args) {
        String routeName = joinStrings (args);
        new HmProfil (routeName);
        System.exit (0);
    }
    private static String joinStrings (String[] args) {
        // Vorsicht: Es dürfen keine Kommas im input-String sein
        return (Arrays.toString(args).replace("[", "").replaceAll("[],,]", ""));
    }
}
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class KML_Parser extends DefaultHandler {
    private StringBuffer textBuffer  = null;
    private String      content    = null;
    private String      name        = null;
    private int          folderDepth = 0;
    private int          nameCount  = 0;
    private GPS_Track    gps_track;
    private Roadbook    roadbook;
    public KML_Parser (GPS_Track gps_track, Roadbook roadbook) {
        this.gps_track = gps_track;
        this.roadbook  = roadbook;
    }
    @Override
    public void startElement (
            String    namespaceURI,
            String    localName,
            String    qName,
            Attributes attrs) throws SAXException {
        String elementName = ("".equals (localName)) ? qName : localName;
        //System.out.println (folderDepth + " " + elementName);
        if (elementName.equals ("Folder")) folderDepth = 1;
        if (elementName.equals ("name")) nameCount ++;
    }
    @Override
    public void endElement (String namespaceURI,
                            String localName,
                            String qName) throws SAXException {
        if (textBuffer != null) content = textBuffer.toString ().trim ();
        textBuffer = null;
        String elementName = ("".equals (localName)) ? qName : localName;
        if ( (elementName.equals ("coordinates")) && (folderDepth == 0)) {
            //System.out.println (">" + content + "<");
            gps_track.addPath (content);
        }
        if ( (elementName.equals ("name")) && (nameCount > 3)) {
            name = content;
        }
        if ( (elementName.equals ("coordinates")) && (folderDepth == 1)) {
            roadbook.addPlacePoint (name, content);
        }
    }
    @Override
    public void characters (char[] buf, int offset, int len) throws SAXException {
        String s = new String (buf, offset, len);
        if (textBuffer == null) textBuffer = new StringBuffer (s);
        else                    textBuffer.append (s);
    }
}
public class PlacePoint extends GeoPoint {
    public PlacePoint (String rawTrackPoint, String name) {
        super(rawTrackPoint, name);
    }
}
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import javax.imageio.ImageIO;
public class Profil {
    GPS_Track gpsTrack;
    Roadbook  roadbook;
    BufferedImage image;
    int imageHeight;
    int imageWidth;
    float altStep = 20;  // 20 m Unterteilung
    int altHeight = 16;  // 16 Pixel pro 20 m
    float kmStep  =  5;  // 5 km Unterteilung
    int kmWidth  = 42;  // 42 Pixel pro 5 km
    float altCorr;
    float deltaAlt = 0;  // Differenz der max/min Höhenmeter
    int altAvg    = 6;  // Höhenglättungs-Faktor
    int xBorder  = 60;  // Linker und rechter Rand
    int yBorder  = 30;
    public Profil (GPS_Track gps_track, Roadbook roadbook) {
        this.gpsTrack = gps_track;
        this.roadbook = roadbook;
        TrackPoint trackPoint;
        deltaAlt = gps_track.maxAlt - gps_track.minAlt;
        // Korrektur für flache Profile, damit Ortsnamen noch passen
        if (deltaAlt < 150) {
            altCorr = 150;
            deltaAlt += altCorr;
        }
        Iterator i = gps_track.iterator ();
        int tpi = 0;
        while (i.hasNext ()) {
            trackPoint = (TrackPoint) i.next ();
            trackPoint.dist = gps_track.getPathLength (gps_track.get (0), trackPoint);
            if ( trackPoint.name.equals ("") ) tpi++;
        }
        // Glättung der Höhenwerte
        float avg;
        for (int k = 1; k <= altAvg; k++) {
            for (int j = 0; j < tpi; j++) {
                trackPoint = gps_track.get (j);
                if (j == 0) {
                    avg = (trackPoint.alt + (gps_track.get (1)).alt) / 2;
                    trackPoint.alt = avg;
                } else if (j == tpi - 1) {
                    avg = ((gps_track.get (j - 1)).alt + trackPoint.alt) / 2;
                    trackPoint.alt = avg;
                } else {
                    avg = ((gps_track.get (j - 1)).alt + trackPoint.alt + (gps_track.get (j + 1)).alt) / 3;
                    trackPoint.alt = avg;
                }
            }
        }
    }
    void drawImage (String filePath) {
        TrackPoint tp;
        imageWidth = (int) Math.round (gpsTrack.length / kmStep) * kmWidth + 2 * xBorder;
        imageHeight = Math.round (deltaAlt / altStep) * altHeight + 2 * yBorder;
        image = new BufferedImage (imageWidth, imageHeight, BufferedImage.TYPE_INT_RGB);
        Graphics2D g2 = (Graphics2D) image.getGraphics ();
        g2.setBackground (Color.WHITE);
        g2.clearRect (0, 0, imageWidth, imageHeight);
        g2.setColor (Color.LIGHT_GRAY);
        for (int i = -100; i < 3500; i += altStep) {
            if ((i >= gpsTrack.minAlt) && (i <= gpsTrack.maxAlt + altCorr)) {
                int y = Math.round (
                        (gpsTrack.maxAlt + altCorr - i) /
                                (gpsTrack.maxAlt + altCorr - gpsTrack.minAlt) *
                                (imageHeight - 2 * yBorder)
                ) + yBorder;
                g2.drawLine (xBorder / 2, y, imageWidth - xBorder / 2, y);
                String s = (new Integer (i)).toString ();
                g2.drawString (s, 3, y + 4);
                g2.drawString (s, imageWidth - 23, y + 4);
            }
        }
        for (int i = 0; i < gpsTrack.length + kmStep; i += kmStep) {
            String s = Integer.toString (i);
            int x = Math.round ((float) (i / gpsTrack.length) * (imageWidth - 2 * xBorder)) + xBorder;
            g2.drawString (s, x - 2, yBorder);
            g2.drawLine (x, yBorder + 4, x, imageHeight - yBorder / 2);
        }
        g2.setStroke (new BasicStroke (6, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
        g2.setColor (Color.ORANGE);
        for (int i = 0; i < gpsTrack.size (); i++) {
            tp = gpsTrack.get (i);
            if (tp.name.equals ("")) {
                float dist = tp.dist;
                int x = Math.round ((float) (dist / gpsTrack.length) * (imageWidth - 2 * xBorder)) + xBorder;
                int y = Math.round ((gpsTrack.maxAlt + altCorr - tp.alt) / (gpsTrack.maxAlt + altCorr - gpsTrack.minAlt) * (imageHeight - 2 * yBorder)) + yBorder;
                g2.drawLine (x, y, x, imageHeight - yBorder / 2);
            }
        }
        g2.setStroke (new BasicStroke (6, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
        g2.setColor (Color.RED);
        int xPrev = -1;
        int yPrev = -1;
        for (int i = 0; i < gpsTrack.size (); i++) {
            tp = gpsTrack.get (i);
            if (tp.name.equals ("")) {
                float dist = tp.dist;
                int x = Math.round ((float) (dist / gpsTrack.length) * (imageWidth - 2 * xBorder)) + xBorder;
                int y = Math.round ((gpsTrack.maxAlt + altCorr - tp.alt) / (gpsTrack.maxAlt + altCorr - gpsTrack.minAlt) * (imageHeight - 2 * yBorder)) + yBorder;
                if (i == 0) g2.drawLine (x, y, x, y);
                else g2.drawLine (xPrev, yPrev, x, y);
                xPrev = x;
                yPrev = y;
            }
        }
        g2.setColor (Color.BLACK);
        AffineTransform fontAT = new AffineTransform ();
        fontAT.rotate (Math.toRadians (270));
        Font font = new Font ("ARIAL", Font.PLAIN, 16);
        Font rotatedFont = font.deriveFont (fontAT);
        g2.setFont (rotatedFont);
        for (int i = 0; i < roadbook.size (); i++) {
            PlacePoint pp = roadbook.get (i);
            int j = gpsTrack.getClosestPoint (pp);
            double dist = gpsTrack.getPathLength (gpsTrack.get (0), gpsTrack.get (j));
            int x = Math.round ((float) (dist / gpsTrack.length) * (imageWidth - 2 * xBorder)) + xBorder;
            //g2.drawLine(x, 0, x, height);
            g2.drawString (pp.name, x + 4, imageHeight - yBorder / 2);
        }
        try {
            ImageIO.write (image, "png", new File (filePath));
            System.out.println ("  Profile " + filePath + " generated");
        } catch (IOException ex) {
            ex.printStackTrace ();
        }
    }
    void drawThumb (String filePath) {
        xBorder = 0;
        yBorder = 0;
        imageWidth = 196;
        imageHeight = 120;
        image = new BufferedImage (imageWidth, imageHeight, BufferedImage.TYPE_INT_RGB);
        TrackPoint tp;
        Graphics2D g2 = (Graphics2D) image.getGraphics ();
        g2.setBackground (Color.WHITE);
        g2.clearRect (0, 0, imageWidth, imageHeight);
        g2.setStroke (new BasicStroke (2, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
        g2.setColor (Color.ORANGE);
        for (int i = 0; i < gpsTrack.size (); i++) {
            tp = gpsTrack.get (i);
            if (tp.name.equals ("") || tp.name.equals ("TP")) {
                float dist = tp.dist;
                int x = Math.round ((float) (dist / gpsTrack.length) * (imageWidth - 2 * xBorder)) + xBorder;
                int y = Math.round ((gpsTrack.maxAlt + altCorr - tp.alt) / (gpsTrack.maxAlt + altCorr - gpsTrack.minAlt) * (imageHeight - 2 * yBorder)) + yBorder;
                g2.drawLine (x, y, x, imageHeight - yBorder / 2);
            }
        }
        g2.setStroke (new BasicStroke (2, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
        g2.setColor (Color.RED);
        int xPrev = -1;
        int yPrev = -1;
        for (int i = 0; i < gpsTrack.size (); i++) {
            tp = gpsTrack.get (i);
            if (tp.name.equals ("") || tp.name.equals ("TP")) {
                float dist = tp.dist;
                int x = Math.round ((float) (dist / gpsTrack.length) * (imageWidth - 2 * xBorder)) + xBorder;
                int y = Math.round ((gpsTrack.maxAlt + altCorr - tp.alt) / (gpsTrack.maxAlt + altCorr - gpsTrack.minAlt) * (imageHeight - 2 * yBorder)) + yBorder;
                if (i == 0) g2.drawLine (x, y, x, y);
                else g2.drawLine (xPrev, yPrev, x, y);
                xPrev = x;
                yPrev = y;
            }
        }
        g2.setColor (Color.BLACK);
        Font font = new Font ("ARIAL", Font.PLAIN, 11);
        g2.setFont (font);
        String s = (Math.round (new Float (gpsTrack.maxAlt))) + " m";
        g2.drawString (s, 2, 10);
        s = (Math.round (new Float (gpsTrack.minAlt))) + " m";
        g2.drawString (s, 2, imageHeight - 2);
        try {
            ImageIO.write (image, "png", new File (filePath));
            System.out.println ("  Profile " + filePath + " generated");
        } catch (IOException ex) {
            ex.printStackTrace ();
        }
    }
}
import java.util.ArrayList;
import java.util.Arrays;
public class Roadbook extends ArrayList <PlacePoint> {
    public Roadbook () {
    }
    public void addPlacePoint (String rawCoords, String name) {
        PlacePoint placePoint = new PlacePoint (rawCoords, name);
        this.add (placePoint);
    }
}
public class TrackPoint extends GeoPoint {
    public TrackPoint (String rawTrackPoint) {
        super(rawTrackPoint);
    }
}
</nowiki>

Aktuelle Version vom 23. März 2014, 13:27 Uhr

Beschreibung

Java jar-Datei zum Erstellen der Höhenprofile. Vor der Benutzung umbenennen in "HmProfil.jar.zip", entpacken und umbenennen in "HmProfil.jar".

Lizenz

Cc-by-nc-sa.png
  

Dieses Bild wurde unter der freien cc-by-nc-sa-Lizenz veröffentlicht.

Die bedeutet für eine Weiterverwendung folgendes:

  • der Bildautor muß genannt werden
  • es ist nur nicht-kommerzielle Weiternutzung gestattet
  • das Bild darf nur unter gleichen Bedingungen weiterverwendet werden

Sourcecode

import java.util.ArrayList;
import java.util.Arrays;

public class GeoPoint {

    String name = "";
    String rawTrackPoint;

    float lon;
    float lat;
    float alt;

    //distance to first point of track
    float dist;

    // coordinates on screen and in image
    int x;
    int y;

    public GeoPoint () {
    }

    public GeoPoint (double lat, double lon) {

        name = "";
        this.lat = (float) lat;
        this.lon = (float) lon;
    }

    public GeoPoint (String rawTrackPoint) {

        name = "";
        this.rawTrackPoint = rawTrackPoint;
        splitRawTrackPoint (rawTrackPoint);
    }

    public GeoPoint (String name, String rawTrackPoint) {

        this.name = name;
        this.rawTrackPoint = rawTrackPoint;
        splitRawTrackPoint (rawTrackPoint);
    }

    public GeoPoint (String rawTrackPoint, String name, String link) {

        this.name = name;
        this.rawTrackPoint = rawTrackPoint;
        splitRawTrackPoint (rawTrackPoint);
    }

    private void splitRawTrackPoint (String rawTrackPoint) {
        //System.out.println("rawTrackPoint: " + rawTrackPoint);

        ArrayList rawGeoData = new ArrayList (Arrays.asList (rawTrackPoint.split (",")));

        switch (rawGeoData.size ()) {
            case 2:
                lon = (new Float ((String) rawGeoData.get (0))).floatValue ();
                lat = (new Float ((String) rawGeoData.get (1))).floatValue ();
                alt = 0;
                break;

            case 3:
                lon = (new Float ((String) rawGeoData.get (0))).floatValue ();
                lat = (new Float ((String) rawGeoData.get (1))).floatValue ();
                alt = (new Float ((String) rawGeoData.get (2))).floatValue ();
                break;
            default:
                System.out.println ("Error: Trackpoint data is not valid: " + rawTrackPoint);
                System.exit (1);
        }
    }

    static double getDistance (TrackPoint tp1, TrackPoint tp2) {

        double lat1 = tp1.lat / 180 * Math.PI;
        double lon1 = tp1.lon / 180 * Math.PI;
        double lat2 = tp2.lat / 180 * Math.PI;
        double lon2 = tp2.lon / 180 * Math.PI;

        double dist = Math.acos (
                Math.sin (lat1) * Math.sin (lat2) +
                        Math.cos (lat1) * Math.cos (lat2) *
                                Math.cos (lon2 - lon1)
        ) * 6378.137; // radius of the equator

        if (Double.isNaN (dist)) dist = 0;

        return dist;
    }
}
import java.util.ArrayList;
import java.util.Arrays;

public class GPS_Track extends ArrayList <TrackPoint> {

    float minLon = +180;
    float maxLon = -180;
    float minLat =  +90;
    float maxLat =  -90;

    float minAlt = 10000;
    float maxAlt = -1000;

    double length;

    public GPS_Track () {}

    public void addPath (String rawPath) {

        TrackPoint tp;

        ArrayList rawTrackpoints = new ArrayList (Arrays.asList (rawPath.split (" ")));

        for (Object rawTrackpoint : rawTrackpoints) {

            tp = new TrackPoint ((String) rawTrackpoint);

            if (tp.lon < minLon) minLon = tp.lon;
            if (tp.lon > maxLon) maxLon = tp.lon;
            if (tp.lat < minLat) minLat = tp.lat;
            if (tp.lat > maxLat) maxLat = tp.lat;

            if (tp.alt < minAlt) minAlt = tp.alt;
            if (tp.alt > maxAlt) maxAlt = tp.alt;

            this.add (tp);
        }

        length = getPathLength (get (0), get (size () - 1));
    }

    public int getClosestPoint (GeoPoint placeMark) {

        double lat = placeMark.lat;
        double lon = placeMark.lon;
        double dist = 1000;

        TrackPoint tp;
        TrackPoint tpNear = null;

        for (Object o : this) {
            tp = (TrackPoint) o;
            if (tp.name.equals ("") || tp.name.equals ("TP")) {
                if (dist > Math.abs (lon - tp.lon) + Math.abs (lat - tp.lat)) {
                    dist = Math.abs (lon - tp.lon) + Math.abs (lat - tp.lat);
                    tpNear = tp;
                }
            }
        }

        return indexOf (tpNear);

        /* more exact but slower
        if (dist > TrackPoint.getDistance(tp, new TrackPoint(lat, lon))) {
            dist = TrackPoint.getDistance(tp, new TrackPoint(lat, lon));
            tpNear = tp;*/

    }

    public float getPathLength (TrackPoint tp0, TrackPoint tp1) {

        float dist = 0;

        int i0 = getClosestPoint (tp0);
        int i1 = getClosestPoint (tp1);

        for (int i = i0 + 1; i <= i1; i++) {
            dist += TrackPoint.getDistance (get (i - 1), get (i));
            //System.out.print(((TrackPoint)get(i)).rawTrackPoint);
            //System.out.println(" : " + dist);
        }

        return dist;
    }

    public void printTrackData () {

        for (Object o : this) {

            TrackPoint tp = (TrackPoint) o;

            System.out.println ("::" + tp.lon + "::" + tp.lat + "::" + tp.alt + "::");
        }
        System.out.println ();
    }
}import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;

public class HmProfil {

    final String KML_DIR_PATH = "../kml/";
    final String OUT_DIR_PATH = "../upload/";

    String    routeName;
    File      kmlFile;
    GPS_Track gps_track = new GPS_Track ();
    Roadbook  roadbook  = new Roadbook ();

    public HmProfil (String routeName) {

        this.routeName = routeName;

        System.out.println ("\nReading " + this.routeName + " ...\n");

        kmlFile = new File (KML_DIR_PATH + this.routeName + ".kml");

        try {

            DefaultHandler handler = new KML_Parser (gps_track, roadbook);

            SAXParser saxParser = SAXParserFactory.newInstance ().newSAXParser ();

            saxParser.parse (kmlFile, handler);

        } catch (ParserConfigurationException e) {
            e.printStackTrace ();
        } catch (SAXException e) {
            e.printStackTrace ();
        } catch (IOException e) {
            e.printStackTrace ();
        }

        System.out.format ("   trackpoints  : %d%n"     , gps_track.size ());
        System.out.format ("   track length : %.2f km%n", gps_track.length);

        System.out.println ("\nGenerating Profile and Thumbnail ...\n");

        Profil profil = new Profil (gps_track, roadbook);

        profil.drawImage (OUT_DIR_PATH + routeName + ".png");
        profil.drawThumb (OUT_DIR_PATH + routeName + "_s.png");
    }

    public static void main (String[] args) {

        String routeName = joinStrings (args);

        new HmProfil (routeName);

        System.exit (0);
    }

    private static String joinStrings (String[] args) {

        // Vorsicht: Es dürfen keine Kommas im input-String sein

        return (Arrays.toString(args).replace("[", "").replaceAll("[],,]", ""));
    }
}
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class KML_Parser extends DefaultHandler {

    private StringBuffer textBuffer  = null;
    private String       content     = null;
    private String       name        = null;
    private int          folderDepth = 0;
    private int          nameCount   = 0;
    private GPS_Track    gps_track;
    private Roadbook     roadbook;

    public KML_Parser (GPS_Track gps_track, Roadbook roadbook) {

        this.gps_track = gps_track;
        this.roadbook  = roadbook;
    }

    @Override
    public void startElement (
            String     namespaceURI,
            String     localName,
            String     qName,
            Attributes attrs) throws SAXException {

        String elementName = ("".equals (localName)) ? qName : localName;

        //System.out.println (folderDepth + " " + elementName);

        if (elementName.equals ("Folder")) folderDepth = 1;

        if (elementName.equals ("name")) nameCount ++;
    }

    @Override
    public void endElement (String namespaceURI,
                            String localName,
                            String qName) throws SAXException {

        if (textBuffer != null) content = textBuffer.toString ().trim ();

        textBuffer = null;

        String elementName = ("".equals (localName)) ? qName : localName;

        if ( (elementName.equals ("coordinates")) && (folderDepth == 0)) {

            //System.out.println (">" + content + "<");

            gps_track.addPath (content);
        }

        if ( (elementName.equals ("name")) && (nameCount > 3)) {

            name = content;
        }

        if ( (elementName.equals ("coordinates")) && (folderDepth == 1)) {

            roadbook.addPlacePoint (name, content);
        }
    }

    @Override
    public void characters (char[] buf, int offset, int len) throws SAXException {

        String s = new String (buf, offset, len);

        if (textBuffer == null) textBuffer = new StringBuffer (s);
        else                    textBuffer.append (s);
    }
}

public class PlacePoint extends GeoPoint {

    public PlacePoint (String rawTrackPoint, String name) {

        super(rawTrackPoint, name);
    }

}
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import javax.imageio.ImageIO;

public class Profil {

    GPS_Track gpsTrack;
    Roadbook  roadbook;

    BufferedImage image;

    int imageHeight;
    int imageWidth;

    float altStep = 20;   // 20 m Unterteilung
    int altHeight = 16;   // 16 Pixel pro 20 m
    float kmStep  =  5;   // 5 km Unterteilung
    int kmWidth   = 42;   // 42 Pixel pro 5 km

    float altCorr;
    float deltaAlt = 0;   // Differenz der max/min Höhenmeter
    int altAvg     = 6;   // Höhenglättungs-Faktor

    int xBorder   = 60;   // Linker und rechter Rand
    int yBorder   = 30;


    public Profil (GPS_Track gps_track, Roadbook roadbook) {

        this.gpsTrack = gps_track;
        this.roadbook = roadbook;

        TrackPoint trackPoint;

        deltaAlt = gps_track.maxAlt - gps_track.minAlt;

        // Korrektur für flache Profile, damit Ortsnamen noch passen
        if (deltaAlt < 150) {
            altCorr = 150;
            deltaAlt += altCorr;
        }

        Iterator i = gps_track.iterator ();

        int tpi = 0;

        while (i.hasNext ()) {

            trackPoint = (TrackPoint) i.next ();
            trackPoint.dist = gps_track.getPathLength (gps_track.get (0), trackPoint);

            if ( trackPoint.name.equals ("") ) tpi++;
        }

        // Glättung der Höhenwerte
        float avg;

        for (int k = 1; k <= altAvg; k++) {

            for (int j = 0; j < tpi; j++) {

                trackPoint = gps_track.get (j);

                if (j == 0) {

                    avg = (trackPoint.alt + (gps_track.get (1)).alt) / 2;
                    trackPoint.alt = avg;

                } else if (j == tpi - 1) {

                    avg = ((gps_track.get (j - 1)).alt + trackPoint.alt) / 2;
                    trackPoint.alt = avg;

                } else {

                    avg = ((gps_track.get (j - 1)).alt + trackPoint.alt + (gps_track.get (j + 1)).alt) / 3;
                    trackPoint.alt = avg;
                }
            }
        }
    }

    void drawImage (String filePath) {

        TrackPoint tp;

        imageWidth = (int) Math.round (gpsTrack.length / kmStep) * kmWidth + 2 * xBorder;
        imageHeight = Math.round (deltaAlt / altStep) * altHeight + 2 * yBorder;

        image = new BufferedImage (imageWidth, imageHeight, BufferedImage.TYPE_INT_RGB);

        Graphics2D g2 = (Graphics2D) image.getGraphics ();

        g2.setBackground (Color.WHITE);
        g2.clearRect (0, 0, imageWidth, imageHeight);

        g2.setColor (Color.LIGHT_GRAY);

        for (int i = -100; i < 3500; i += altStep) {

            if ((i >= gpsTrack.minAlt) && (i <= gpsTrack.maxAlt + altCorr)) {

                int y = Math.round (
                        (gpsTrack.maxAlt + altCorr - i) /
                                (gpsTrack.maxAlt + altCorr - gpsTrack.minAlt) *
                                (imageHeight - 2 * yBorder)
                ) + yBorder;

                g2.drawLine (xBorder / 2, y, imageWidth - xBorder / 2, y);

                String s = (new Integer (i)).toString ();
                g2.drawString (s, 3, y + 4);
                g2.drawString (s, imageWidth - 23, y + 4);
            }
        }

        for (int i = 0; i < gpsTrack.length + kmStep; i += kmStep) {

            String s = Integer.toString (i);
            int x = Math.round ((float) (i / gpsTrack.length) * (imageWidth - 2 * xBorder)) + xBorder;
            g2.drawString (s, x - 2, yBorder);
            g2.drawLine (x, yBorder + 4, x, imageHeight - yBorder / 2);
        }


        g2.setStroke (new BasicStroke (6, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
        g2.setColor (Color.ORANGE);

        for (int i = 0; i < gpsTrack.size (); i++) {

            tp = gpsTrack.get (i);

            if (tp.name.equals ("")) {

                float dist = tp.dist;

                int x = Math.round ((float) (dist / gpsTrack.length) * (imageWidth - 2 * xBorder)) + xBorder;
                int y = Math.round ((gpsTrack.maxAlt + altCorr - tp.alt) / (gpsTrack.maxAlt + altCorr - gpsTrack.minAlt) * (imageHeight - 2 * yBorder)) + yBorder;

                g2.drawLine (x, y, x, imageHeight - yBorder / 2);
            }
        }

        g2.setStroke (new BasicStroke (6, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
        g2.setColor (Color.RED);

        int xPrev = -1;
        int yPrev = -1;

        for (int i = 0; i < gpsTrack.size (); i++) {

            tp = gpsTrack.get (i);

            if (tp.name.equals ("")) {

                float dist = tp.dist;

                int x = Math.round ((float) (dist / gpsTrack.length) * (imageWidth - 2 * xBorder)) + xBorder;
                int y = Math.round ((gpsTrack.maxAlt + altCorr - tp.alt) / (gpsTrack.maxAlt + altCorr - gpsTrack.minAlt) * (imageHeight - 2 * yBorder)) + yBorder;

                if (i == 0) g2.drawLine (x, y, x, y);
                else g2.drawLine (xPrev, yPrev, x, y);

                xPrev = x;
                yPrev = y;
            }
        }

        g2.setColor (Color.BLACK);

        AffineTransform fontAT = new AffineTransform ();
        fontAT.rotate (Math.toRadians (270));
        Font font = new Font ("ARIAL", Font.PLAIN, 16);
        Font rotatedFont = font.deriveFont (fontAT);
        g2.setFont (rotatedFont);

        for (int i = 0; i < roadbook.size (); i++) {
            PlacePoint pp = roadbook.get (i);

            int j = gpsTrack.getClosestPoint (pp);
            double dist = gpsTrack.getPathLength (gpsTrack.get (0), gpsTrack.get (j));

            int x = Math.round ((float) (dist / gpsTrack.length) * (imageWidth - 2 * xBorder)) + xBorder;
            //g2.drawLine(x, 0, x, height);
            g2.drawString (pp.name, x + 4, imageHeight - yBorder / 2);
        }
        try {
            ImageIO.write (image, "png", new File (filePath));
            System.out.println ("   Profile " + filePath + " generated");
        } catch (IOException ex) {
            ex.printStackTrace ();
        }
    }

    void drawThumb (String filePath) {

        xBorder = 0;
        yBorder = 0;

        imageWidth = 196;
        imageHeight = 120;

        image = new BufferedImage (imageWidth, imageHeight, BufferedImage.TYPE_INT_RGB);

        TrackPoint tp;

        Graphics2D g2 = (Graphics2D) image.getGraphics ();

        g2.setBackground (Color.WHITE);
        g2.clearRect (0, 0, imageWidth, imageHeight);

        g2.setStroke (new BasicStroke (2, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
        g2.setColor (Color.ORANGE);

        for (int i = 0; i < gpsTrack.size (); i++) {
            tp = gpsTrack.get (i);
            if (tp.name.equals ("") || tp.name.equals ("TP")) {
                float dist = tp.dist;

                int x = Math.round ((float) (dist / gpsTrack.length) * (imageWidth - 2 * xBorder)) + xBorder;
                int y = Math.round ((gpsTrack.maxAlt + altCorr - tp.alt) / (gpsTrack.maxAlt + altCorr - gpsTrack.minAlt) * (imageHeight - 2 * yBorder)) + yBorder;

                g2.drawLine (x, y, x, imageHeight - yBorder / 2);
            }
        }

        g2.setStroke (new BasicStroke (2, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
        g2.setColor (Color.RED);

        int xPrev = -1;
        int yPrev = -1;

        for (int i = 0; i < gpsTrack.size (); i++) {
            tp = gpsTrack.get (i);
            if (tp.name.equals ("") || tp.name.equals ("TP")) {
                float dist = tp.dist;

                int x = Math.round ((float) (dist / gpsTrack.length) * (imageWidth - 2 * xBorder)) + xBorder;
                int y = Math.round ((gpsTrack.maxAlt + altCorr - tp.alt) / (gpsTrack.maxAlt + altCorr - gpsTrack.minAlt) * (imageHeight - 2 * yBorder)) + yBorder;

                if (i == 0) g2.drawLine (x, y, x, y);
                else g2.drawLine (xPrev, yPrev, x, y);

                xPrev = x;
                yPrev = y;
            }
        }

        g2.setColor (Color.BLACK);
        Font font = new Font ("ARIAL", Font.PLAIN, 11);
        g2.setFont (font);

        String s = (Math.round (new Float (gpsTrack.maxAlt))) + " m";
        g2.drawString (s, 2, 10);

        s = (Math.round (new Float (gpsTrack.minAlt))) + " m";
        g2.drawString (s, 2, imageHeight - 2);

        try {

            ImageIO.write (image, "png", new File (filePath));

            System.out.println ("   Profile " + filePath + " generated");

        } catch (IOException ex) {
            ex.printStackTrace ();
        }
    }
}
import java.util.ArrayList;
import java.util.Arrays;

public class Roadbook extends ArrayList <PlacePoint> {

    public Roadbook () {

    }

    public void addPlacePoint (String rawCoords, String name) {

        PlacePoint placePoint = new PlacePoint (rawCoords, name);

        this.add (placePoint);
    }

}


public class TrackPoint extends GeoPoint {

    public TrackPoint (String rawTrackPoint) {

        super(rawTrackPoint);
    }

}

Dateiversionen

Klicke auf einen Zeitpunkt, um diese Version zu laden.

Version vomMaßeBenutzerKommentar
aktuell13:24, 23. Mär. 2014 (11 KB)Jmages (Diskussion | Beiträge)Pfade angepasst
07:44, 5. Feb. 2014 (12 KB)Jmages (Diskussion | Beiträge)
06:12, 19. Apr. 2012 (55 KB)Jmages (Diskussion | Beiträge)

Die folgende Seite verwendet diese Datei: