package com.aerodynelabs.habtk.prediction; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.net.URL; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Scanner; import com.aerodynelabs.map.MapPath; import com.aerodynelabs.map.MapPoint; // http://developer.mapquest.com/web/products/open/elevation-service public class ElevationService { private static final String baseUrl = "http://open.mapquestapi.com/elevation/v1/getElevationProfile?"; private static final int SPLIT = 25; public static MapPath getElevationProfile(MapPath in) { MapPath out = new MapPath("Elevation"); int i = 0; while(i < in.getPath().size() - SPLIT) { LinkedList<MapPoint> sub = getSubProfile(in.getPath().subList(i, i + SPLIT)); if(sub != null) { out.addAll(sub); } else { return null; } i += SPLIT; } LinkedList<MapPoint> sub = getSubProfile(in.getPath().subList(i, in.getPath().size())); if(sub != null) { out.addAll(sub); } else { return null; } return out; } public static double getElevation(double lat, double lon) { Double elev = Double.NaN; String query = "shapeFormat=raw&outShapeFormat=none&latLngCollection=" + lat + "," + lon; URL url; BufferedReader reader; String line; String result = ""; try { url = new URL(baseUrl + query); InputStream stream = url.openStream(); reader = new BufferedReader(new InputStreamReader(stream)); while((line = reader.readLine()) != null) { result += line; } reader.close(); Scanner scanner = new Scanner(result); String field = scanner.findInLine("\"height\":[0-9.]+"); scanner.close(); scanner = new Scanner(field); String alt = scanner.findInLine("[0-9.]+"); scanner.close(); elev = Double.parseDouble(alt); } catch(Exception e) { e.printStackTrace(); } return elev; } public static String encodePath(List<MapPoint> in) { String encoded = ""; int pLat = 0, pLon = 0; Iterator<MapPoint> itr = in.iterator(); while(itr.hasNext()) { MapPoint p = itr.next(); int lat = floor5(p.getLatitude()); int lon = floor5(p.getLongitude()); encoded += encodeSignedNumber(lat - pLat); encoded += encodeSignedNumber(lon - pLon); pLat = lat; pLon = lon; } return encoded; } private static LinkedList<MapPoint> getSubProfile(List<MapPoint> in) { LinkedList<MapPoint> out = null; String query = "shapeFormat=raw&outShapeFormat=none&latLngCollection="; // String query = "shapeFormat=cmp&outShapeFormat=none&latLngCollection="; Iterator<MapPoint> itr = in.iterator(); while(itr.hasNext()) { MapPoint p = itr.next(); query += p.getLatitude() + ","; query += p.getLongitude(); if(itr.hasNext()) query += ","; } // query += encodePath(in); // System.out.println(baseUrl + query); URL url; BufferedReader reader; String line; String result = ""; try { url = new URL(baseUrl + query); InputStream stream = url.openStream(); reader = new BufferedReader(new InputStreamReader(stream)); while((line = reader.readLine()) != null) { result += line; } reader.close(); } catch(Exception e) { e.printStackTrace(); } try(Scanner scanner = new Scanner(result)) { out = new LinkedList<MapPoint>(); itr = in.iterator(); while(itr.hasNext()) { MapPoint p = itr.next(); double elev; String field = scanner.findInLine("\"height\":[0-9.]+"); Scanner s = new Scanner(field); String alt = s.findInLine("[0-9.]+"); s.close(); elev = Double.parseDouble(alt); out.add(new MapPoint(p.getLatitude(), p.getLongitude(), elev, p.getTime())); } } catch(Exception e) { e.printStackTrace(); return null; } return out; } private static String encodeNumber(int x) { StringBuffer encoded = new StringBuffer(); while(x > 0x20) { encoded.append( (char)((0x20 | (x & 0x1f)) + 63) ); x >>= 5; } encoded.append( (char)(x + 63) ); return encoded.toString(); } private static String encodeSignedNumber(int x) { int y = x << 1; if(x < 0) y = ~y; return encodeNumber(y); } private static int floor5(double x) { return (int) Math.round(x * 1e5); } }