Datei:HmProfil.jar.kmz

Aus Radreise-Wiki
Version vom 23. März 2014, 13:27 Uhr von Jmages (Diskussion | Beiträge) (→‎Sourcecode: Pfade angepasst)
(Unterschied) ← Nächstältere Version | Aktuelle Version (Unterschied) | Nächstjüngere Version → (Unterschied)

HmProfil.jar.kmz(Dateigröße: 11 KB, MIME-Typ: application/zip)

Warnung! Diese Art von Datei kann böswilligen Programmcode enthalten. Durch das Herunterladen oder Öffnen der Datei kann der Computer beschädigt werden. Bereits das Anklicken des Links kann dazu führen dass der Browser die Datei öffnet und unbekannter Programmcode zur Ausführung kommt.

Die Betreiber dieses Wikis können keine Verantwortung für den Inhalte dieser Datei übernehmen. Sollte diese Datei tatsächlich böswilligen Programmcode enthalten, sollte umgehend ein Administrator informiert werden!

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: