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
|
package tim.prune.gui.map;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Class to represent any map source, whether an OsmMapSource
* or one of the more complicated ones.
* Map sources may contain just one or several layers, and may
* build their URLs in different ways depending on the source
*/
public abstract class MapSource
{
/** File extensions */
protected String[] _extensions = null;
/** Regular expression for catching server wildcards */
protected static final Pattern WILD_PATTERN = Pattern.compile("^(.*)\\[(.*)\\](.*)$");
/**
* @return the number of layers used in this source
*/
public abstract int getNumLayers();
/**
* @return the name of the source
*/
public abstract String getName();
/**
* @return the base url for the specified layer
*/
public abstract String getBaseUrl(int inLayerNum);
/**
* @return the site name for the specified layer
*/
public abstract String getSiteName(int inLayerNum);
/**
* @return the file extension for the specified layer
*/
public final String getFileExtension(int inLayerNum) {
return _extensions[inLayerNum];
}
/**
* Make the URL to get the specified tile
* @param inLayerNum number of layer, from 0 (base) to getNumLayers-1 (top)
* @param inZoom zoom level
* @param inX x coordinate of tile
* @param inY y coordinate of tile
* @return URL as string
*/
public abstract String makeURL(int inLayerNum, int inZoom, int inX, int inY);
/**
* @return the maximum zoom level for this source
*/
public abstract int getMaxZoomLevel();
/**
* Make a relative file path from the base directory including site name
* @param inLayerNum layer number
* @param inZoom zoom level
* @param inX x coordinate
* @param inY y coordinate
* @return relative file path as String
*/
public String makeFilePath(int inLayerNum, int inZoom, int inX, int inY)
{
return getSiteName(inLayerNum) + inZoom + "/" + inX + "/" + inY + "." + getFileExtension(inLayerNum);
}
/**
* Checks the given url for having the right prefix and trailing slash
* @param inUrl url to check
* @return validated url with correct prefix and trailing slash, or null
*/
public static String fixBaseUrl(String inUrl)
{
if (inUrl == null || inUrl.equals("")) {return null;}
String urlstr = inUrl;
// check prefix
try {
new URL(urlstr.replace('[', 'w').replace(']', 'w'));
// There's a warning that this URL object isn't used, but it's enough to know the parse
// was successful without an exception being thrown.
}
catch (MalformedURLException e)
{
// fail if protocol specified
if (urlstr.indexOf("://") >= 0) {return null;}
// add the http protocol
urlstr = "http://" + urlstr;
}
// check trailing /
if (!urlstr.endsWith("/")) {
urlstr = urlstr + "/";
}
// Validate current url, return null if not ok
try {
URL url = new URL(urlstr.replace('[', 'w').replace(']', 'w'));
// url host must contain a dot
if (url.getHost().indexOf('.') < 0) {return null;}
}
catch (MalformedURLException e) {
urlstr = null;
}
return urlstr;
}
/**
* Fix the site name by stripping off protocol and www.
* This is used to create the file path for disk caching
* @param inUrl url to strip
* @return stripped url
*/
protected static String fixSiteName(String inUrl)
{
if (inUrl == null || inUrl.equals("")) {return null;}
String url = inUrl.toLowerCase();
int idx = url.indexOf("://");
if (idx >= 0) {url = url.substring(idx + 3);}
if (url.startsWith("www.")) {url = url.substring(4);}
// Strip out any "[.*]" as well
if (url.indexOf('[') >= 0)
{
Matcher matcher = WILD_PATTERN.matcher(url);
if (matcher.matches()) {
url = matcher.group(1) + matcher.group(3);
if (url.length() > 1 && url.charAt(0) == '.') {
url = url.substring(1);
}
}
}
return url;
}
/**
* @return string which can be written to the Config
*/
public abstract String getConfigString();
/**
* @return semicolon-separated list of base urls and extensions in order
*/
public String getSiteStrings()
{
StringBuilder sb = new StringBuilder();
for (int i=0; i<getNumLayers(); i++)
{
String url = getBaseUrl(i);
if (url != null)
{
sb.append(url);
sb.append(';');
sb.append(getFileExtension(i));
sb.append(';');
}
}
return sb.toString();
}
}
|