Datei:HmProfil.jar.kmz: Unterschied zwischen den Versionen
Aus Radreise-Wiki
Jmages (Diskussion | Beiträge) |
Jmages (Diskussion | Beiträge) (→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
|
Dieses Bild wurde unter der freien cc-by-nc-sa-Lizenz veröffentlicht. Die bedeutet für eine Weiterverwendung folgendes:
|
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 vom | Maße | Benutzer | Kommentar | |
|---|---|---|---|---|
| aktuell | 13: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) |
Du kannst diese Datei nicht überschreiben.
Dateiverwendung
Die folgende Seite verwendet diese Datei:
