]> gitweb.fperrin.net Git - GpsPrune.git/blob - tim/prune/gui/map/OsmMapSource.java
Version 14, October 2012
[GpsPrune.git] / tim / prune / gui / map / OsmMapSource.java
1 package tim.prune.gui.map;
2
3 import java.util.regex.Matcher;
4 import tim.prune.I18nManager;
5
6 /**
7  * Class to provide a map source for all OSM-like sources
8  * (eg mapnik, opencyclemap, openpistemap etc).
9  * These can be single-layer or double-layer sources with tiles
10  * in various formats (default png)
11  */
12 public class OsmMapSource extends MapSource
13 {
14         /** Name for this source */
15         private String _name = null;
16         /** Base urls */
17         private String[] _baseUrls = null;
18         /** Site names */
19         private String[] _siteNames = null;
20         /** Maximum zoom level */
21         private int _maxZoom = 0;
22
23         /**
24          * Constructor giving single name and url
25          * @param inName source name
26          * @param inUrl base url
27          */
28         public OsmMapSource(String inName, String inUrl)
29         {
30                 this(inName, inUrl, "png", null, null, 18);
31         }
32
33         /**
34          * Constructor giving name, two strings and maximum zoom
35          * @param inName source name
36          * @param inStr1 base layer url
37          * @param inStr2 either base layer extension or upper layer url
38          * @param inMaxZoom maximum zoom level
39          */
40         public OsmMapSource(String inName, String inStr1, String inStr2, int inMaxZoom)
41         {
42                 if (inStr2 != null && inStr2.length() == 3)
43                         init(inName, inStr1, inStr2, null, null, 18);
44                 else
45                         init(inName, inStr1, "png", inStr2, "png", 18);
46         }
47
48         /**
49          * Constructor giving name, urls, extensions and maximum zoom
50          * @param inName source name
51          * @param inUrl1 base layer url
52          * @param inExt1 extension for base layer
53          * @param inUrl2 upper layer url
54          * @param inExt2 extension for top layer
55          * @param inMaxZoom maximum zoom level
56          */
57         public OsmMapSource(String inName, String inUrl1, String inExt1,
58                 String inUrl2, String inExt2, int inMaxZoom)
59         {
60                 init(inName, inUrl1, inExt1, inUrl2, inExt2, inMaxZoom);
61         }
62
63         /**
64          * Initialisation giving name, urls, extensions and maximum zoom
65          * @param inName source name
66          * @param inUrl1 base layer url
67          * @param inExt1 extension for base layer
68          * @param inUrl2 upper layer url
69          * @param inExt2 extension for top layer
70          * @param inMaxZoom maximum zoom level
71          */
72         private void init(String inName, String inUrl1, String inExt1,
73                 String inUrl2, String inExt2, int inMaxZoom)
74         {
75                 _name = inName;
76                 if (_name == null || _name.trim().equals("")) {_name = I18nManager.getText("mapsource.unknown");}
77                 _baseUrls = new String[2];
78                 _baseUrls[0] = fixBaseUrl(inUrl1);
79                 _baseUrls[1] = fixBaseUrl(inUrl2);
80                 _extensions = new String[2];
81                 _extensions[0] = inExt1;
82                 _extensions[1] = inExt2;
83                 _siteNames = new String[2];
84                 _siteNames[0] = fixSiteName(_baseUrls[0]);
85                 _siteNames[1] = fixSiteName(_baseUrls[1]);
86                 // Swap layers if second layer given without first
87                 if (_baseUrls[0] == null && _baseUrls[1] != null)
88                 {
89                         _baseUrls[0] = _baseUrls[1];
90                         _siteNames[0] = _siteNames[1];
91                         _baseUrls[1] = _siteNames[1] = null;
92                 }
93                 _maxZoom = inMaxZoom;
94         }
95
96         /**
97          * Construct a new map source from its config string
98          * @param inConfigString string from Config, separated by semicolons
99          * @return new map source, or null if not parseable
100          */
101         public static OsmMapSource fromConfig(String inConfigString)
102         {
103                 OsmMapSource source = null;
104                 if (inConfigString.startsWith("o:"))
105                 {
106                         String[] items = inConfigString.substring(2).split(";");
107                         try {
108                                 if (items.length == 3) { // single source url
109                                         source = new OsmMapSource(items[0], items[1], null, Integer.parseInt(items[2]));
110                                 }
111                                 else if (items.length == 4) { // two urls or one url plus extension
112                                         source = new OsmMapSource(items[0], items[1], items[2], Integer.parseInt(items[3]));
113                                 }
114                                 else if (items.length == 6) { // two urls and two extensions
115                                         source = new OsmMapSource(items[0], items[1], items[2], items[3], items[4], Integer.parseInt(items[5]));
116                                 }
117                         } catch (NumberFormatException nfe) {}
118                 }
119                 return source;
120         }
121
122         /**
123          * @return name
124          */
125         public String getName() {
126                 return _name;
127         }
128
129         /** Number of layers */
130         public int getNumLayers() {
131                 return _baseUrls[1] == null?1:2;
132         }
133
134         /** Base url for this source */
135         public String getBaseUrl(int inLayerNum) {
136                 return _baseUrls[inLayerNum];
137         }
138
139         /** site name without protocol or www. */
140         public String getSiteName(int inLayerNum) {
141                 return _siteNames[inLayerNum];
142         }
143
144         /**
145          * Make the URL to get the specified tile
146          */
147         public String makeURL(int inLayerNum, int inZoom, int inX, int inY)
148         {
149                 // Check if the base url has a [1234], if so replace at random
150                 return pickServerUrl(_baseUrls[inLayerNum])
151                         + inZoom + "/" + inX + "/" + inY + "." + getFileExtension(inLayerNum);
152         }
153
154         /**
155          * @return maximum zoom level
156          */
157         public final int getMaxZoomLevel()
158         {
159                 return _maxZoom;
160         }
161
162         /**
163          * If the base url contains something like [1234], then pick a server
164          * @param inBaseUrl base url
165          * @return modified base url
166          */
167         protected static final String pickServerUrl(String inBaseUrl)
168         {
169                 if (inBaseUrl == null || inBaseUrl.indexOf('[') < 0) {
170                         return inBaseUrl;
171                 }
172                 // Check for [.*] (once only)
173                 // Only need to support one, make things a bit easier
174                 final Matcher matcher = WILD_PATTERN.matcher(inBaseUrl);
175                 // if not, return base url unchanged
176                 if (!matcher.matches()) {
177                         return inBaseUrl;
178                 }
179                 // if so, pick one at random and replace in the String
180                 final String match = matcher.group(2);
181                 final int numMatches = match.length();
182                 String server = null;
183                 if (numMatches > 0)
184                 {
185                         int matchNum = (int) Math.floor(Math.random() * numMatches);
186                         server = "" + match.charAt(matchNum);
187                 }
188                 final String result = matcher.group(1) + (server==null?"":server) + matcher.group(3);
189                 return result;
190         }
191
192         /**
193          * @return semicolon-separated list of all fields
194          */
195         public String getConfigString()
196         {
197                 return "o:" +  getName() + ";" + getSiteStrings() + getMaxZoomLevel();
198         }
199 }