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 */
34 MAP_SOURCE_INLINESKATE, /* Inlinemap.net */
35 MAP_SOURCE_GRAPHHOPPER /* Routing with GraphHopper */
39 * Generate a URL for the given source and track info
40 * @param inSource source to use, from the enum in UrlGenerator
41 * @param inTrackInfo track info
44 public static String generateUrl(WebService inSource, TrackInfo inTrackInfo)
48 case MAP_SOURCE_GOOGLE:
49 return generateGoogleUrl(inTrackInfo);
50 case MAP_SOURCE_MAPQUEST:
51 return generateMapquestUrl(inTrackInfo);
52 case MAP_SOURCE_YAHOO:
53 return generateYahooUrl(inTrackInfo);
55 return generateBingUrl(inTrackInfo);
56 case MAP_SOURCE_PEAKFINDER:
57 case MAP_SOURCE_GEOHACK:
58 case MAP_SOURCE_INLINESKATE:
59 return generateUrlForPoint(inSource, inTrackInfo);
60 case MAP_SOURCE_GRAPHHOPPER:
61 return generateGraphHopperUrl(inTrackInfo);
64 return generateOpenStreetMapUrl(inTrackInfo);
69 * Generate a url for Google maps
70 * @param inTrackInfo track information
73 private static String generateGoogleUrl(TrackInfo inTrackInfo)
75 // Check if any data to display
76 if (inTrackInfo == null || inTrackInfo.getTrack() == null || inTrackInfo.getTrack().getNumPoints() < 1)
80 double medianLat = getMedianValue(inTrackInfo.getTrack().getLatRange());
81 double medianLon = getMedianValue(inTrackInfo.getTrack().getLonRange());
82 double latSpan = getSpan(inTrackInfo.getTrack().getLatRange());
83 double lonSpan = getSpan(inTrackInfo.getTrack().getLonRange());
84 // Build basic url with centre position and span
85 String url = "http://" + I18nManager.getText("url.googlemaps")
86 + "/?ll=" + FIVE_DP.format(medianLat) + "," + FIVE_DP.format(medianLon)
87 + "&spn=" + FIVE_DP.format(latSpan) + "," + FIVE_DP.format(lonSpan);
88 DataPoint currPoint = inTrackInfo.getCurrentPoint();
89 // Add selected point, if any
90 if (currPoint != null) {
91 url = url + "&q=" + FIVE_DP.format(currPoint.getLatitude().getDouble()) + ","
92 + FIVE_DP.format(currPoint.getLongitude().getDouble());
93 if (currPoint.getWaypointName() != null) {
94 url = url + "(" + currPoint.getWaypointName() + ")";
101 * Generate a url for Mapquest maps
102 * @param inTrackInfo track information
105 private static String generateMapquestUrl(TrackInfo inTrackInfo)
107 // Check if any data to display
108 if (inTrackInfo == null || inTrackInfo.getTrack() == null || inTrackInfo.getTrack().getNumPoints() < 1)
112 double medianLat = getMedianValue(inTrackInfo.getTrack().getLatRange());
113 double medianLon = getMedianValue(inTrackInfo.getTrack().getLonRange());
114 // Build basic url with centre position
115 String url = "http://atlas.mapquest.com/maps/map.adp?latlongtype=decimal&latitude="
116 + FIVE_DP.format(medianLat) + "&longitude=" + FIVE_DP.format(medianLon);
122 * Generate a url for Yahoo maps
123 * @param inTrackInfo track information
126 private static String generateYahooUrl(TrackInfo inTrackInfo)
128 // Check if any data to display
129 if (inTrackInfo == null || inTrackInfo.getTrack() == null || inTrackInfo.getTrack().getNumPoints() < 1)
133 double medianLat = getMedianValue(inTrackInfo.getTrack().getLatRange());
134 double medianLon = getMedianValue(inTrackInfo.getTrack().getLonRange());
135 // Build basic url with centre position
136 String url = "http://maps.yahoo.com/#lat=" + FIVE_DP.format(medianLat)
137 + "&lon=" + FIVE_DP.format(medianLon) + "&zoom=13";
142 * Generate a url for Bing maps
143 * @param inTrackInfo track information
146 private static String generateBingUrl(TrackInfo inTrackInfo)
148 // Check if any data to display
149 if (inTrackInfo == null || inTrackInfo.getTrack() == null || inTrackInfo.getTrack().getNumPoints() < 1)
153 double medianLat = getMedianValue(inTrackInfo.getTrack().getLatRange());
154 double medianLon = getMedianValue(inTrackInfo.getTrack().getLonRange());
155 // Build basic url with centre position
156 String latStr = FIVE_DP.format(medianLat);
157 String lonStr = FIVE_DP.format(medianLon);
158 String url = "http://bing.com/maps/default.aspx?cp=" + latStr + "~" + lonStr
159 + "&where1=" + latStr + "%2C%20" + lonStr;
164 * Generate a url for routing with GraphHopper
165 * @param inTrackInfo track information
168 private static String generateGraphHopperUrl(TrackInfo inTrackInfo)
170 // Check if any data to display
171 if (inTrackInfo != null && inTrackInfo.getTrack() != null && inTrackInfo.getTrack().getNumPoints() >= 2)
173 if (inTrackInfo.getTrack().getNumPoints() == 2)
175 // Use first and last point of track
176 return generateGraphHopperUrl(inTrackInfo.getTrack().getPoint(0),
177 inTrackInfo.getTrack().getPoint(1));
179 else if (inTrackInfo.getSelection().hasRangeSelected())
181 // Use first and last point of selection
182 final int startIndex = inTrackInfo.getSelection().getStart();
183 final int endIndex = inTrackInfo.getSelection().getEnd();
184 return generateGraphHopperUrl(inTrackInfo.getTrack().getPoint(startIndex),
185 inTrackInfo.getTrack().getPoint(endIndex));
192 * Generate a url for routing with GraphHopper
193 * @param inStartPoint start point of routing
194 * @param inEndPoint end point of routing
197 private static String generateGraphHopperUrl(DataPoint inStartPoint, DataPoint inEndPoint)
199 final String url = "https://graphhopper.com/maps/"
200 + "?point=" + FIVE_DP.format(inStartPoint.getLatitude().getDouble())
201 + "%2C" + FIVE_DP.format(inStartPoint.getLongitude().getDouble())
202 + "&point=" + FIVE_DP.format(inEndPoint.getLatitude().getDouble())
203 + "%2C" + FIVE_DP.format(inEndPoint.getLongitude().getDouble())
204 + "&locale=" + I18nManager.getText("wikipedia.lang")
205 + "&elevation=true&weighting=fastest";
210 * Generate a url for Open Street Map
211 * @param inTrackInfo track information
214 private static String generateOpenStreetMapUrl(TrackInfo inTrackInfo)
216 // Check if any data to display
217 if (inTrackInfo == null || inTrackInfo.getTrack() == null || inTrackInfo.getTrack().getNumPoints() < 1)
221 DoubleRange latRange = inTrackInfo.getTrack().getLatRange();
222 DoubleRange lonRange = inTrackInfo.getTrack().getLonRange();
223 // Build basic url using min and max lat and long
224 String url = "http://openstreetmap.org/?minlat=" + FIVE_DP.format(latRange.getMinimum())
225 + "&maxlat=" + FIVE_DP.format(latRange.getMaximum())
226 + "&minlon=" + FIVE_DP.format(lonRange.getMinimum()) + "&maxlon=" + FIVE_DP.format(lonRange.getMaximum());
227 DataPoint currPoint = inTrackInfo.getCurrentPoint();
228 // Add selected point, if any (no way to add point name?)
229 if (currPoint != null) {
230 url = url + "&mlat=" + FIVE_DP.format(currPoint.getLatitude().getDouble())
231 + "&mlon=" + FIVE_DP.format(currPoint.getLongitude().getDouble());
237 * Generate a URL which only needs the current point
238 * This is just a helper method to simplify the calls to the service-specific methods
239 * @param inSource service to call
240 * @param inTrackInfo track info
241 * @return URL if available, or null
243 private static String generateUrlForPoint(WebService inService, TrackInfo inTrackInfo)
245 if (inTrackInfo == null || inTrackInfo.getTrack() == null || inTrackInfo.getTrack().getNumPoints() < 1)
249 // Need a current point
250 DataPoint currPoint = inTrackInfo.getCurrentPoint();
251 if (currPoint == null)
257 case MAP_SOURCE_PEAKFINDER:
258 return generatePeakfinderUrl(currPoint);
259 case MAP_SOURCE_GEOHACK:
260 return generateGeohackUrl(currPoint);
261 case MAP_SOURCE_INLINESKATE:
262 return generateInlinemapUrl(currPoint);
270 * Generate a url for PeakFinder
271 * @param inPoint current point, not null
274 private static String generatePeakfinderUrl(DataPoint inPoint)
276 return "https://www.peakfinder.org/?lat=" + FIVE_DP.format(inPoint.getLatitude().getDouble())
277 + "&lng=" + FIVE_DP.format(inPoint.getLongitude().getDouble());
281 * Generate a url for Geohack
282 * @param inPoint current point, not null
285 private static String generateGeohackUrl(DataPoint inPoint)
287 return "https://tools.wmflabs.org/geohack/geohack.php?params=" + FIVE_DP.format(inPoint.getLatitude().getDouble())
288 + "_N_" + FIVE_DP.format(inPoint.getLongitude().getDouble()) + "_E";
289 // Note: Could use absolute values and S, W but this seems to work
293 * Generate a url for Inlinemap.net
294 * @param inPoint current point, not null
297 private static String generateInlinemapUrl(DataPoint inPoint)
299 return "http://www.inlinemap.net/en/?tab=new#/z14/" + FIVE_DP.format(inPoint.getLatitude().getDouble())
300 + "," + FIVE_DP.format(inPoint.getLongitude().getDouble()) + "/terrain";
304 * Get the median value from the given lat/long range
305 * @param inRange range of values
306 * @return median value
308 private static double getMedianValue(DoubleRange inRange)
310 return (inRange.getMaximum() + inRange.getMinimum()) / 2.0;
314 * Get the span of the given lat/long range
315 * @param inRange range of values
318 private static double getSpan(DoubleRange inRange)
320 return inRange.getMaximum() - inRange.getMinimum();