1 package tim.prune.gui.map;
3 import java.util.regex.Matcher;
4 import tim.prune.I18nManager;
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)
12 public class OsmMapSource extends MapSource
14 /** Name for this source */
15 private String _name = null;
17 private String[] _baseUrls = null;
19 private String[] _siteNames = null;
20 /** Maximum zoom level */
21 private int _maxZoom = 0;
24 * Constructor giving single name and url
25 * @param inName source name
26 * @param inUrl base url
28 public OsmMapSource(String inName, String inUrl)
30 this(inName, inUrl, "png", null, null, 18);
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
40 public OsmMapSource(String inName, String inStr1, String inStr2, int inMaxZoom)
42 if (inStr2 != null && inStr2.length() == 3)
43 init(inName, inStr1, inStr2, null, null, inMaxZoom);
45 init(inName, inStr1, "png", inStr2, "png", inMaxZoom);
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
57 public OsmMapSource(String inName, String inUrl1, String inExt1,
58 String inUrl2, String inExt2, int inMaxZoom)
60 init(inName, inUrl1, inExt1, inUrl2, inExt2, inMaxZoom);
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
72 private void init(String inName, String inUrl1, String inExt1,
73 String inUrl2, String inExt2, int inMaxZoom)
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)
89 _baseUrls[0] = _baseUrls[1];
90 _siteNames[0] = _siteNames[1];
91 _baseUrls[1] = _siteNames[1] = null;
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
101 public static OsmMapSource fromConfig(String inConfigString)
103 OsmMapSource source = null;
104 if (inConfigString.startsWith("o:"))
106 String[] items = inConfigString.substring(2).split(";");
108 if (items.length == 3) { // single source url
109 source = new OsmMapSource(items[0], items[1], null, Integer.parseInt(items[2]));
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]));
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]));
117 } catch (NumberFormatException nfe) {}
125 public String getName() {
129 /** Number of layers */
130 public int getNumLayers() {
131 return _baseUrls[1] == null?1:2;
134 /** Base url for this source */
135 public String getBaseUrl(int inLayerNum) {
136 return _baseUrls[inLayerNum];
139 /** site name without protocol or www. */
140 public String getSiteName(int inLayerNum) {
141 return _siteNames[inLayerNum];
145 * Make the URL to get the specified tile
147 public String makeURL(int inLayerNum, int inZoom, int inX, int inY)
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);
155 * @return maximum zoom level
157 public final int getMaxZoomLevel()
163 * If the base url contains something like [1234], then pick a server
164 * @param inBaseUrl base url
165 * @return modified base url
167 protected static final String pickServerUrl(String inBaseUrl)
169 if (inBaseUrl == null || inBaseUrl.indexOf('[') < 0) {
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()) {
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;
185 int matchNum = (int) Math.floor(Math.random() * numMatches);
186 server = "" + match.charAt(matchNum);
188 final String result = matcher.group(1) + (server==null?"":server) + matcher.group(3);
193 * @return semicolon-separated list of all fields
195 public String getConfigString()
197 return "o:" + getName() + ";" + getSiteStrings() + getMaxZoomLevel();