]> gitweb.fperrin.net Git - GpsPrune.git/blob - tim/prune/function/browser/UrlGenerator.java
Version 19.1, August 2018
[GpsPrune.git] / tim / prune / function / browser / UrlGenerator.java
1 package tim.prune.function.browser;
2
3 import java.text.DecimalFormat;
4 import java.text.NumberFormat;
5 import java.util.Locale;
6
7 import tim.prune.I18nManager;
8 import tim.prune.data.DataPoint;
9 import tim.prune.data.DoubleRange;
10 import tim.prune.data.TrackInfo;
11
12 /**
13  * Class to manage the generation of map urls
14  * for display in an external browser
15  */
16 public abstract class UrlGenerator
17 {
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)
21         static {
22                 if (FIVE_DP instanceof DecimalFormat) ((DecimalFormat) FIVE_DP).applyPattern("0.00000");
23         }
24
25         public enum WebService
26         {
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 */
36         }
37
38         /**
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
42          * @return url for map
43          */
44         public static String generateUrl(WebService inSource, TrackInfo inTrackInfo)
45         {
46                 switch (inSource)
47                 {
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);
54                         case MAP_SOURCE_BING:
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);
62                         case MAP_SOURCE_OSM:
63                         default:
64                                 return generateOpenStreetMapUrl(inTrackInfo);
65                 }
66         }
67
68         /**
69          * Generate a url for Google maps
70          * @param inTrackInfo track information
71          * @return URL
72          */
73         private static String generateGoogleUrl(TrackInfo inTrackInfo)
74         {
75                 // Check if any data to display
76                 if (inTrackInfo == null || inTrackInfo.getTrack() == null || inTrackInfo.getTrack().getNumPoints() < 1)
77                 {
78                         return null;
79                 }
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() + ")";
95                         }
96                 }
97                 return url;
98         }
99
100         /**
101          * Generate a url for Mapquest maps
102          * @param inTrackInfo track information
103          * @return URL
104          */
105         private static String generateMapquestUrl(TrackInfo inTrackInfo)
106         {
107                 // Check if any data to display
108                 if (inTrackInfo == null || inTrackInfo.getTrack() == null || inTrackInfo.getTrack().getNumPoints() < 1)
109                 {
110                         return null;
111                 }
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);
117                 return url;
118         }
119
120
121         /**
122          * Generate a url for Yahoo maps
123          * @param inTrackInfo track information
124          * @return URL
125          */
126         private static String generateYahooUrl(TrackInfo inTrackInfo)
127         {
128                 // Check if any data to display
129                 if (inTrackInfo == null || inTrackInfo.getTrack() == null || inTrackInfo.getTrack().getNumPoints() < 1)
130                 {
131                         return null;
132                 }
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";
138                 return url;
139         }
140
141         /**
142          * Generate a url for Bing maps
143          * @param inTrackInfo track information
144          * @return URL
145          */
146         private static String generateBingUrl(TrackInfo inTrackInfo)
147         {
148                 // Check if any data to display
149                 if (inTrackInfo == null || inTrackInfo.getTrack() == null || inTrackInfo.getTrack().getNumPoints() < 1)
150                 {
151                         return null;
152                 }
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;
160                 return url;
161         }
162
163         /**
164          * Generate a url for routing with GraphHopper
165          * @param inTrackInfo track information
166          * @return URL
167          */
168         private static String generateGraphHopperUrl(TrackInfo inTrackInfo)
169         {
170                 // Check if any data to display
171                 if (inTrackInfo != null && inTrackInfo.getTrack() != null && inTrackInfo.getTrack().getNumPoints() >= 2)
172                 {
173                         if (inTrackInfo.getTrack().getNumPoints() == 2)
174                         {
175                                 // Use first and last point of track
176                                 return generateGraphHopperUrl(inTrackInfo.getTrack().getPoint(0),
177                                         inTrackInfo.getTrack().getPoint(1));
178                         }
179                         else if (inTrackInfo.getSelection().hasRangeSelected())
180                         {
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));
186                         }
187                 }
188                 return null;
189         }
190
191         /**
192          * Generate a url for routing with GraphHopper
193          * @param inStartPoint start point of routing
194          * @param inEndPoint end point of routing
195          * @return URL
196          */
197         private static String generateGraphHopperUrl(DataPoint inStartPoint, DataPoint inEndPoint)
198         {
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";
206                 return url;
207         }
208
209         /**
210          * Generate a url for Open Street Map
211          * @param inTrackInfo track information
212          * @return URL
213          */
214         private static String generateOpenStreetMapUrl(TrackInfo inTrackInfo)
215         {
216                 // Check if any data to display
217                 if (inTrackInfo == null || inTrackInfo.getTrack() == null || inTrackInfo.getTrack().getNumPoints() < 1)
218                 {
219                         return null;
220                 }
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());
232                 }
233                 return url;
234         }
235
236         /**
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
242          */
243         private static String generateUrlForPoint(WebService inService, TrackInfo inTrackInfo)
244         {
245                 if (inTrackInfo == null || inTrackInfo.getTrack() == null || inTrackInfo.getTrack().getNumPoints() < 1)
246                 {
247                         return null;
248                 }
249                 // Need a current point
250                 DataPoint currPoint = inTrackInfo.getCurrentPoint();
251                 if (currPoint == null)
252                 {
253                         return null;
254                 }
255                 switch (inService)
256                 {
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);
263                         default:
264                                 return null;
265                 }
266         }
267
268
269         /**
270          * Generate a url for PeakFinder
271          * @param inPoint current point, not null
272          * @return URL
273          */
274         private static String generatePeakfinderUrl(DataPoint inPoint)
275         {
276                 return "https://www.peakfinder.org/?lat=" + FIVE_DP.format(inPoint.getLatitude().getDouble())
277                         + "&lng=" + FIVE_DP.format(inPoint.getLongitude().getDouble());
278         }
279
280         /**
281          * Generate a url for Geohack
282          * @param inPoint current point, not null
283          * @return URL
284          */
285         private static String generateGeohackUrl(DataPoint inPoint)
286         {
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
290         }
291
292         /**
293          * Generate a url for Inlinemap.net
294          * @param inPoint current point, not null
295          * @return URL
296          */
297         private static String generateInlinemapUrl(DataPoint inPoint)
298         {
299                 return "http://www.inlinemap.net/en/?tab=new#/z14/" + FIVE_DP.format(inPoint.getLatitude().getDouble())
300                         + "," + FIVE_DP.format(inPoint.getLongitude().getDouble()) + "/terrain";
301         }
302
303         /**
304          * Get the median value from the given lat/long range
305          * @param inRange range of values
306          * @return median value
307          */
308         private static double getMedianValue(DoubleRange inRange)
309         {
310                 return (inRange.getMaximum() + inRange.getMinimum()) / 2.0;
311         }
312
313         /**
314          * Get the span of the given lat/long range
315          * @param inRange range of values
316          * @return span
317          */
318         private static double getSpan(DoubleRange inRange)
319         {
320                 return inRange.getMaximum() - inRange.getMinimum();
321         }
322 }