1 package tim.prune.function.browser;
3 import java.text.DecimalFormat;
4 import java.text.NumberFormat;
5 import java.util.Locale;
7 import tim.prune.I18nManager;
8 import tim.prune.data.DataPoint;
9 import tim.prune.data.DoubleRange;
10 import tim.prune.data.TrackInfo;
13 * Class to manage the generation of map urls
14 * for display in an external browser
16 public abstract class UrlGenerator
18 /** Number formatter for five dp */
19 private static final NumberFormat FIVE_DP = NumberFormat.getNumberInstance(Locale.UK);
20 // Select the UK locale for this formatter so that decimal point is always used (not comma)
22 if (FIVE_DP instanceof DecimalFormat) ((DecimalFormat) FIVE_DP).applyPattern("0.00000");
25 public enum WebService
27 MAP_SOURCE_GOOGLE, /* Google maps */
28 MAP_SOURCE_OSM, /* OpenStreetMap */
29 MAP_SOURCE_MAPQUEST, /* Mapquest */
30 MAP_SOURCE_YAHOO, /* Yahoo */
31 MAP_SOURCE_BING, /* Bing */
32 MAP_SOURCE_PEAKFINDER, /* PeakFinder */
33 MAP_SOURCE_GEOHACK, /* Geohack */
37 * Generate a URL for the given source and track info
38 * @param inSource source to use, from the enum in UrlGenerator
39 * @param inTrackInfo track info
42 public static String generateUrl(WebService inSource, TrackInfo inTrackInfo)
46 case MAP_SOURCE_GOOGLE:
47 return generateGoogleUrl(inTrackInfo);
48 case MAP_SOURCE_MAPQUEST:
49 return generateMapquestUrl(inTrackInfo);
50 case MAP_SOURCE_YAHOO:
51 return generateYahooUrl(inTrackInfo);
53 return generateBingUrl(inTrackInfo);
54 case MAP_SOURCE_PEAKFINDER:
55 case MAP_SOURCE_GEOHACK:
56 return generateUrlForPoint(inSource, inTrackInfo);
59 return generateOpenStreetMapUrl(inTrackInfo);
64 * Generate a url for Google maps
65 * @param inTrackInfo track information
68 private static String generateGoogleUrl(TrackInfo inTrackInfo)
70 // Check if any data to display
71 if (inTrackInfo == null || inTrackInfo.getTrack() == null || inTrackInfo.getTrack().getNumPoints() < 1)
75 double medianLat = getMedianValue(inTrackInfo.getTrack().getLatRange());
76 double medianLon = getMedianValue(inTrackInfo.getTrack().getLonRange());
77 double latSpan = getSpan(inTrackInfo.getTrack().getLatRange());
78 double lonSpan = getSpan(inTrackInfo.getTrack().getLonRange());
79 // Build basic url with centre position and span
80 String url = "http://" + I18nManager.getText("url.googlemaps")
81 + "/?ll=" + FIVE_DP.format(medianLat) + "," + FIVE_DP.format(medianLon)
82 + "&spn=" + FIVE_DP.format(latSpan) + "," + FIVE_DP.format(lonSpan);
83 DataPoint currPoint = inTrackInfo.getCurrentPoint();
84 // Add selected point, if any
85 if (currPoint != null) {
86 url = url + "&q=" + FIVE_DP.format(currPoint.getLatitude().getDouble()) + ","
87 + FIVE_DP.format(currPoint.getLongitude().getDouble());
88 if (currPoint.getWaypointName() != null) {
89 url = url + "(" + currPoint.getWaypointName() + ")";
96 * Generate a url for Mapquest maps
97 * @param inTrackInfo track information
100 private static String generateMapquestUrl(TrackInfo inTrackInfo)
102 // Check if any data to display
103 if (inTrackInfo == null || inTrackInfo.getTrack() == null || inTrackInfo.getTrack().getNumPoints() < 1)
107 double medianLat = getMedianValue(inTrackInfo.getTrack().getLatRange());
108 double medianLon = getMedianValue(inTrackInfo.getTrack().getLonRange());
109 // Build basic url with centre position
110 String url = "http://atlas.mapquest.com/maps/map.adp?latlongtype=decimal&latitude="
111 + FIVE_DP.format(medianLat) + "&longitude=" + FIVE_DP.format(medianLon);
117 * Generate a url for Yahoo maps
118 * @param inTrackInfo track information
121 private static String generateYahooUrl(TrackInfo inTrackInfo)
123 // Check if any data to display
124 if (inTrackInfo == null || inTrackInfo.getTrack() == null || inTrackInfo.getTrack().getNumPoints() < 1)
128 double medianLat = getMedianValue(inTrackInfo.getTrack().getLatRange());
129 double medianLon = getMedianValue(inTrackInfo.getTrack().getLonRange());
130 // Build basic url with centre position
131 String url = "http://maps.yahoo.com/#lat=" + FIVE_DP.format(medianLat)
132 + "&lon=" + FIVE_DP.format(medianLon) + "&zoom=13";
137 * Generate a url for Bing maps
138 * @param inTrackInfo track information
141 private static String generateBingUrl(TrackInfo inTrackInfo)
143 // Check if any data to display
144 if (inTrackInfo == null || inTrackInfo.getTrack() == null || inTrackInfo.getTrack().getNumPoints() < 1)
148 double medianLat = getMedianValue(inTrackInfo.getTrack().getLatRange());
149 double medianLon = getMedianValue(inTrackInfo.getTrack().getLonRange());
150 // Build basic url with centre position
151 String latStr = FIVE_DP.format(medianLat);
152 String lonStr = FIVE_DP.format(medianLon);
153 String url = "http://bing.com/maps/default.aspx?cp=" + latStr + "~" + lonStr
154 + "&where1=" + latStr + "%2C%20" + lonStr;
159 * Generate a url for Open Street Map
160 * @param inTrackInfo track information
163 private static String generateOpenStreetMapUrl(TrackInfo inTrackInfo)
165 // Check if any data to display
166 if (inTrackInfo == null || inTrackInfo.getTrack() == null || inTrackInfo.getTrack().getNumPoints() < 1)
170 DoubleRange latRange = inTrackInfo.getTrack().getLatRange();
171 DoubleRange lonRange = inTrackInfo.getTrack().getLonRange();
172 // Build basic url using min and max lat and long
173 String url = "http://openstreetmap.org/?minlat=" + FIVE_DP.format(latRange.getMinimum())
174 + "&maxlat=" + FIVE_DP.format(latRange.getMaximum())
175 + "&minlon=" + FIVE_DP.format(lonRange.getMinimum()) + "&maxlon=" + FIVE_DP.format(lonRange.getMaximum());
176 DataPoint currPoint = inTrackInfo.getCurrentPoint();
177 // Add selected point, if any (no way to add point name?)
178 if (currPoint != null) {
179 url = url + "&mlat=" + FIVE_DP.format(currPoint.getLatitude().getDouble())
180 + "&mlon=" + FIVE_DP.format(currPoint.getLongitude().getDouble());
186 * Generate a URL which only needs the current point
187 * This is just a helper method to simplify the calls to the service-specific methods
188 * @param inSource service to call
189 * @param inTrackInfo track info
190 * @return URL if available, or null
192 private static String generateUrlForPoint(WebService inService, TrackInfo inTrackInfo)
194 if (inTrackInfo == null || inTrackInfo.getTrack() == null || inTrackInfo.getTrack().getNumPoints() < 1)
198 // Need a current point
199 DataPoint currPoint = inTrackInfo.getCurrentPoint();
200 if (currPoint == null)
206 case MAP_SOURCE_PEAKFINDER:
207 return generatePeakfinderUrl(currPoint);
208 case MAP_SOURCE_GEOHACK:
209 return generateGeohackUrl(currPoint);
217 * Generate a url for PeakFinder
218 * @param inPoint current point, not null
221 private static String generatePeakfinderUrl(DataPoint inPoint)
223 return "http://peakfinder.org/?lat=" + FIVE_DP.format(inPoint.getLatitude().getDouble())
224 + "&lng=" + FIVE_DP.format(inPoint.getLongitude().getDouble());
228 * Generate a url for Geohack
229 * @param inPoint current point, not null
232 private static String generateGeohackUrl(DataPoint inPoint)
234 return "https://tools.wmflabs.org/geohack/geohack.php?params=" + FIVE_DP.format(inPoint.getLatitude().getDouble())
235 + "_N_" + FIVE_DP.format(inPoint.getLongitude().getDouble()) + "_E";
236 // TODO: Could use absolute values and S, W but this seems to work
241 * Get the median value from the given lat/long range
242 * @param inRange range of values
243 * @return median value
245 private static double getMedianValue(DoubleRange inRange)
247 return (inRange.getMaximum() + inRange.getMinimum()) / 2.0;
251 * Get the span of the given lat/long range
252 * @param inRange range of values
255 private static double getSpan(DoubleRange inRange)
257 return inRange.getMaximum() - inRange.getMinimum();