File: OsmMapSource.java

package info (click to toggle)
gpsprune 17-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 3,984 kB
  • ctags: 5,218
  • sloc: java: 39,403; sh: 25; makefile: 17; python: 15
file content (199 lines) | stat: -rw-r--r-- 5,721 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
package tim.prune.gui.map;

import java.util.regex.Matcher;
import tim.prune.I18nManager;

/**
 * Class to provide a map source for all OSM-like sources
 * (eg mapnik, opencyclemap, openpistemap etc).
 * These can be single-layer or double-layer sources with tiles
 * in various formats (default png)
 */
public class OsmMapSource extends MapSource
{
	/** Name for this source */
	private String _name = null;
	/** Base urls */
	private String[] _baseUrls = null;
	/** Site names */
	private String[] _siteNames = null;
	/** Maximum zoom level */
	private int _maxZoom = 0;

	/**
	 * Constructor giving single name and url
	 * @param inName source name
	 * @param inUrl base url
	 */
	public OsmMapSource(String inName, String inUrl)
	{
		this(inName, inUrl, "png", null, null, 18);
	}

	/**
	 * Constructor giving name, two strings and maximum zoom
	 * @param inName source name
	 * @param inStr1 base layer url
	 * @param inStr2 either base layer extension or upper layer url
	 * @param inMaxZoom maximum zoom level
	 */
	public OsmMapSource(String inName, String inStr1, String inStr2, int inMaxZoom)
	{
		if (inStr2 != null && inStr2.length() == 3)
			init(inName, inStr1, inStr2, null, null, inMaxZoom);
		else
			init(inName, inStr1, "png", inStr2, "png", inMaxZoom);
	}

	/**
	 * Constructor giving name, urls, extensions and maximum zoom
	 * @param inName source name
	 * @param inUrl1 base layer url
	 * @param inExt1 extension for base layer
	 * @param inUrl2 upper layer url
	 * @param inExt2 extension for top layer
	 * @param inMaxZoom maximum zoom level
	 */
	public OsmMapSource(String inName, String inUrl1, String inExt1,
		String inUrl2, String inExt2, int inMaxZoom)
	{
		init(inName, inUrl1, inExt1, inUrl2, inExt2, inMaxZoom);
	}

	/**
	 * Initialisation giving name, urls, extensions and maximum zoom
	 * @param inName source name
	 * @param inUrl1 base layer url
	 * @param inExt1 extension for base layer
	 * @param inUrl2 upper layer url
	 * @param inExt2 extension for top layer
	 * @param inMaxZoom maximum zoom level
	 */
	private void init(String inName, String inUrl1, String inExt1,
		String inUrl2, String inExt2, int inMaxZoom)
	{
		_name = inName;
		if (_name == null || _name.trim().equals("")) {_name = I18nManager.getText("mapsource.unknown");}
		_baseUrls = new String[2];
		_baseUrls[0] = fixBaseUrl(inUrl1);
		_baseUrls[1] = fixBaseUrl(inUrl2);
		_extensions = new String[2];
		_extensions[0] = inExt1;
		_extensions[1] = inExt2;
		_siteNames = new String[2];
		_siteNames[0] = fixSiteName(_baseUrls[0]);
		_siteNames[1] = fixSiteName(_baseUrls[1]);
		// Swap layers if second layer given without first
		if (_baseUrls[0] == null && _baseUrls[1] != null)
		{
			_baseUrls[0] = _baseUrls[1];
			_siteNames[0] = _siteNames[1];
			_baseUrls[1] = _siteNames[1] = null;
		}
		_maxZoom = inMaxZoom;
	}

	/**
	 * Construct a new map source from its config string
	 * @param inConfigString string from Config, separated by semicolons
	 * @return new map source, or null if not parseable
	 */
	public static OsmMapSource fromConfig(String inConfigString)
	{
		OsmMapSource source = null;
		if (inConfigString.startsWith("o:"))
		{
			String[] items = inConfigString.substring(2).split(";");
			try {
				if (items.length == 3) { // single source url
					source = new OsmMapSource(items[0], items[1], null, Integer.parseInt(items[2]));
				}
				else if (items.length == 4) { // two urls or one url plus extension
					source = new OsmMapSource(items[0], items[1], items[2], Integer.parseInt(items[3]));
				}
				else if (items.length == 6) { // two urls and two extensions
					source = new OsmMapSource(items[0], items[1], items[2], items[3], items[4], Integer.parseInt(items[5]));
				}
			} catch (NumberFormatException nfe) {}
		}
		return source;
	}

	/**
	 * @return name
	 */
	public String getName() {
		return _name;
	}

	/** Number of layers */
	public int getNumLayers() {
		return _baseUrls[1] == null?1:2;
	}

	/** Base url for this source */
	public String getBaseUrl(int inLayerNum) {
		return _baseUrls[inLayerNum];
	}

	/** site name without protocol or www. */
	public String getSiteName(int inLayerNum) {
		return _siteNames[inLayerNum];
	}

	/**
	 * Make the URL to get the specified tile
	 */
	public String makeURL(int inLayerNum, int inZoom, int inX, int inY)
	{
		// Check if the base url has a [1234], if so replace at random
		return pickServerUrl(_baseUrls[inLayerNum])
			+ inZoom + "/" + inX + "/" + inY + "." + getFileExtension(inLayerNum);
	}

	/**
	 * @return maximum zoom level
	 */
	public final int getMaxZoomLevel()
	{
		return _maxZoom;
	}

	/**
	 * If the base url contains something like [1234], then pick a server
	 * @param inBaseUrl base url
	 * @return modified base url
	 */
	protected static final String pickServerUrl(String inBaseUrl)
	{
		if (inBaseUrl == null || inBaseUrl.indexOf('[') < 0) {
			return inBaseUrl;
		}
		// Check for [.*] (once only)
		// Only need to support one, make things a bit easier
		final Matcher matcher = WILD_PATTERN.matcher(inBaseUrl);
		// if not, return base url unchanged
		if (!matcher.matches()) {
			return inBaseUrl;
		}
		// if so, pick one at random and replace in the String
		final String match = matcher.group(2);
		final int numMatches = match.length();
		String server = null;
		if (numMatches > 0)
		{
			int matchNum = (int) Math.floor(Math.random() * numMatches);
			server = "" + match.charAt(matchNum);
		}
		final String result = matcher.group(1) + (server==null?"":server) + matcher.group(3);
		return result;
	}

	/**
	 * @return semicolon-separated list of all fields
	 */
	public String getConfigString()
	{
		return "o:" +  getName() + ";" + getSiteStrings() + getMaxZoomLevel();
	}
}