Dienstag, 10. Juli 2012

Java long-time formatting

public static String formatTime(long milliseconds){
    int seconds = (int) (milliseconds / 1000) % 60 ;
    int minutes = (int) ((milliseconds / (1000*60)) % 60);
    int hours   = (int) ((milliseconds / (1000*60*60)) % 24);
    return String.format("%02d:%02d:%02d", hours, minutes, seconds);
}
This method converts a given time (as long) to a readable time string of the format hh:mm:ss. Sometimes pretty useful for performance measures (System.currentTimeMillis()) and easy formatting of java.util.Date.
Inline Version
public static String formatTime(long m){
    return String.format("%02d:%02d:%02d", (m/1E3)%60, ((m/(6*1E4))%60, (m/(3.6*1E6))%24);
}

Montag, 9. Juli 2012

Java Google Maps Route Information

static String getGoogleMapsRoute(float startLat, float startLng, float endLat, float endLng)
throws Exception {
    // build a search query for google maps:
    String query = "http://maps.googleapis.com/maps/api/directions/xml?origin="
        + startLat + "," + startLng + "&destination="
        + endLat + "," + endLng + "&sensor=false";
    XPath xPath = XPathFactory.newInstance().newXPath();
    org.xml.sax.InputSource source = new org.xml.sax.InputSource(new URL(url).openStream());
    // parse the received reply (XML) for the information we want:
    org.w3c.dom.Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(source);
    String length = xPath.evaluate("/DirectionsResponse/route/leg/distance/text", doc);
    String duration = xPath.evaluate("/DirectionsResponse/route/leg/duration/text", doc);
    String start = xPath.evaluate("/DirectionsResponse/route/leg/start_address", doc);
    String end = xPath.evaluate("/DirectionsResponse/route/leg/end_address", doc);
    return "(length = " + length + ", duration = " + duration + ") Start: " + start + ", End: " + end;
}
This nice java method retrieves information of a GoogleMaps route from the given start location to the end/target location (latitude + longitude). It is possible to write addresses or names of important places to the 'origin' and 'destination' parameters.
For this method one have to import some stuff from javax.xml.

Java Time Formatter

String formatTime(long nanotime) {
    String ret = "";
    DecimalFormat df = new DecimalFormat("#.###");
    long time = nanotime;
    ret = time > 1E3 ? df.format(time / 1E3) + "µs" : df.format(time) + " ns";
    ret = time > 1E6 ? df.format(time / 1E6) + "ms" : ret;
    ret = time > 1E9 ? df.format(time / 1E9) + "s" : ret;
    ret = time > 60 * 1E9 ? df.format(time / (1E9 * 60)) + "min" : ret;
    return ret;
}
Returns the string representation of the given time (nanoseconds) in the right format (s, ms, µs, min). You can use it for standard time formatting, and performance debugging.

Euclidean Distance 2D

float euclideanDistance2D(float start_x, float start_y, float end_x, float end_y) {
    float dx = Math.abs(start_x - end_x);
    float dy = Math.abs(start_y - end_y);
    return Math.sqrt(dx * dx + dy * dy);
}
This function calculates the euclidean/direct distance between two points (start, end) in the 2D plane.

Value Scaling Function

float scale(float value, float minA, float maxA, float minB, float maxB)
{
    // compute scaling factor:
    float rangeA = maxA - minA;            // dx
    float rangeB = maxB - minB;            // dy
    float slope = rangeB / rangeA;         // m
    float intercept = minB - slope * minA; // b

    // compute value in new range:
    float result = value * slope + intercept; // f(x)=m*x+b

    // cut the new value if it is out of bounds:
    if(result > maxB) result = maxB;
    if(result < minB) result = minB;

    return result;
}
This rather simple function linearly scales a value within range [minA, maxA] to a new range [minB, maxB].

Application Example
Let's say you want to have sensor readings within range [0°, 180°] of a laser scanner, but you want to store the data within the range [-1,1] because you let the laser scan a 180° field and 90° means straight ahead; you want that direction to be at 0. So you just call
scale(value, 0, 180, -1, 1) for an incomming sensor reading value and get the scaled one.
Inline Version

float scale(float value, float minA, float maxA, float minB, float maxB)
{
    // compute value in new range and cut if out of bounds:
    float slope = (maxB - minB) / (maxA - minA);
    float v = value * slope + minB - slope * minA;
    return v > maxB ? maxB : (v < minB ? minB : v);
}