From 9c4e04c4d672e02050294fa3e94f665f6cecea9d Mon Sep 17 00:00:00 2001 From: Hannes Janetzek Date: Tue, 1 Apr 2014 03:25:00 +0200 Subject: [PATCH] api: UrlTileSource - use replacement string for tilePath - move 'low-level' formatTilePath to LwHttp - implement LwHttpFactory --- .../source/geojson/GeoJsonTileSource.java | 18 +-- .../source/mapnik/MapnikVectorTileSource.java | 29 ++--- .../source/oscimap/OSciMap1TileSource.java | 7 +- .../source/oscimap2/OSciMap2TileSource.java | 7 +- .../org/oscim/tiling/source/HttpEngine.java | 5 +- vtm/src/org/oscim/tiling/source/LwHttp.java | 66 +++++++--- .../org/oscim/tiling/source/OkHttpEngine.java | 41 +++--- .../tiling/source/UrlTileDataSource.java | 2 +- .../oscim/tiling/source/UrlTileSource.java | 122 +++++++++--------- .../source/bitmap/BitmapTileSource.java | 11 +- .../tiling/source/bitmap/DefaultSources.java | 55 ++------ .../source/oscimap4/OSciMap4TileSource.java | 3 +- 12 files changed, 178 insertions(+), 188 deletions(-) diff --git a/vtm-extras/src/org/oscim/tiling/source/geojson/GeoJsonTileSource.java b/vtm-extras/src/org/oscim/tiling/source/geojson/GeoJsonTileSource.java index e381f6a1..eb83cdd2 100644 --- a/vtm-extras/src/org/oscim/tiling/source/geojson/GeoJsonTileSource.java +++ b/vtm-extras/src/org/oscim/tiling/source/geojson/GeoJsonTileSource.java @@ -22,27 +22,29 @@ import java.util.Map; import org.oscim.core.MapElement; import org.oscim.core.Tag; import org.oscim.tiling.ITileDataSource; -import org.oscim.tiling.source.LwHttp; import org.oscim.tiling.source.UrlTileDataSource; import org.oscim.tiling.source.UrlTileSource; public abstract class GeoJsonTileSource extends UrlTileSource { public GeoJsonTileSource(String url) { - super(url); - setExtension(".json"); + super(url, "/{Z}/{X}/{Y}.json"); + Map opt = new HashMap(); + opt.put("Accept-Encoding", "gzip"); + setHttpRequestHeaders(opt); } public GeoJsonTileSource(String url, int zoomMin, int zoomMax) { - super(url, zoomMin, zoomMax); - setExtension(".json"); + super(url, "/{Z}/{X}/{Y}.json", zoomMin, zoomMax); + Map opt = new HashMap(); + opt.put("Accept-Encoding", "gzip"); + setHttpRequestHeaders(opt); } @Override public ITileDataSource getDataSource() { - Map opt = new HashMap(); - opt.put("Accept-Encoding", "gzip"); - return new UrlTileDataSource(this, new GeoJsonTileDecoder(this), new LwHttp(getUrl(), opt)); + + return new UrlTileDataSource(this, new GeoJsonTileDecoder(this), getHttpEngine()); } public Tag getFeatureTag() { diff --git a/vtm-extras/src/org/oscim/tiling/source/mapnik/MapnikVectorTileSource.java b/vtm-extras/src/org/oscim/tiling/source/mapnik/MapnikVectorTileSource.java index abb551ad..60d1ee03 100644 --- a/vtm-extras/src/org/oscim/tiling/source/mapnik/MapnikVectorTileSource.java +++ b/vtm-extras/src/org/oscim/tiling/source/mapnik/MapnikVectorTileSource.java @@ -18,22 +18,21 @@ package org.oscim.tiling.source.mapnik; import org.oscim.core.Tile; import org.oscim.tiling.ITileDataSource; -import org.oscim.tiling.source.LwHttp; import org.oscim.tiling.source.UrlTileDataSource; import org.oscim.tiling.source.UrlTileSource; public class MapnikVectorTileSource extends UrlTileSource { public MapnikVectorTileSource() { - super("http://d1s11ojcu7opje.cloudfront.net/dev/764e0b8d"); + super("http://d1s11ojcu7opje.cloudfront.net/dev/764e0b8d", ""); } @Override public ITileDataSource getDataSource() { - return new UrlTileDataSource(this, new TileDecoder(), new LwHttp(getUrl())); + return new UrlTileDataSource(this, new TileDecoder(), getHttpEngine()); } - public int formatTilePath(Tile tile, byte[] path, int pos) { + public String formatTilePath(Tile tile) { // url formatter for mapbox streets byte[] hexTable = { '0', '1', '2', '3', @@ -41,17 +40,17 @@ public class MapnikVectorTileSource extends UrlTileSource { '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; + StringBuilder sb = new StringBuilder(); + sb.append('/'); + sb.append(hexTable[(tile.tileX) % 16]); + sb.append(hexTable[(tile.tileY) % 16]); + sb.append('/'); + sb.append(tile.zoomLevel); + sb.append('/'); + sb.append(tile.tileX); + sb.append('/'); + sb.append(tile.tileY); - path[pos++] = '/'; - path[pos++] = hexTable[(tile.tileX) % 16]; - path[pos++] = hexTable[(tile.tileY) % 16]; - path[pos++] = '/'; - pos = LwHttp.writeInt(tile.zoomLevel, pos, path); - path[pos++] = '/'; - pos = LwHttp.writeInt(tile.tileX, pos, path); - path[pos++] = '/'; - pos = LwHttp.writeInt(tile.tileY, pos, path); - - return pos; + return sb.toString(); } } diff --git a/vtm-extras/src/org/oscim/tiling/source/oscimap/OSciMap1TileSource.java b/vtm-extras/src/org/oscim/tiling/source/oscimap/OSciMap1TileSource.java index 50ae2b26..32626519 100644 --- a/vtm-extras/src/org/oscim/tiling/source/oscimap/OSciMap1TileSource.java +++ b/vtm-extras/src/org/oscim/tiling/source/oscimap/OSciMap1TileSource.java @@ -17,7 +17,6 @@ package org.oscim.tiling.source.oscimap; import org.oscim.tiling.ITileDataSource; -import org.oscim.tiling.source.LwHttp; import org.oscim.tiling.source.UrlTileDataSource; import org.oscim.tiling.source.UrlTileSource; @@ -28,13 +27,11 @@ import org.oscim.tiling.source.UrlTileSource; public class OSciMap1TileSource extends UrlTileSource { public OSciMap1TileSource(String url) { - super(url); - setExtension(".osmtile"); - setMimeType("application/osmtile"); + super(url, "/{Z}/{X}/{Y}.osmtile"); } @Override public ITileDataSource getDataSource() { - return new UrlTileDataSource(this, new TileDecoder(), new LwHttp(getUrl())); + return new UrlTileDataSource(this, new TileDecoder(), getHttpEngine()); } } diff --git a/vtm-extras/src/org/oscim/tiling/source/oscimap2/OSciMap2TileSource.java b/vtm-extras/src/org/oscim/tiling/source/oscimap2/OSciMap2TileSource.java index 77f881e2..54aa0bf9 100644 --- a/vtm-extras/src/org/oscim/tiling/source/oscimap2/OSciMap2TileSource.java +++ b/vtm-extras/src/org/oscim/tiling/source/oscimap2/OSciMap2TileSource.java @@ -27,7 +27,6 @@ import org.oscim.core.TagSet; import org.oscim.core.Tile; import org.oscim.tiling.ITileDataSink; import org.oscim.tiling.ITileDataSource; -import org.oscim.tiling.source.LwHttp; import org.oscim.tiling.source.PbfDecoder; import org.oscim.tiling.source.UrlTileDataSource; import org.oscim.tiling.source.UrlTileSource; @@ -37,14 +36,12 @@ import org.slf4j.LoggerFactory; public class OSciMap2TileSource extends UrlTileSource { public OSciMap2TileSource(String url) { - super(url); - setExtension(".osmtile"); - setMimeType("application/osmtile"); + super(url, "/{Z}/{X}/{Y}.osmtile"); } @Override public ITileDataSource getDataSource() { - return new UrlTileDataSource(this, new TileDecoder(), new LwHttp(getUrl())); + return new UrlTileDataSource(this, new TileDecoder(), getHttpEngine()); } static class TileDecoder extends PbfDecoder { diff --git a/vtm/src/org/oscim/tiling/source/HttpEngine.java b/vtm/src/org/oscim/tiling/source/HttpEngine.java index a843a1d6..63b29948 100644 --- a/vtm/src/org/oscim/tiling/source/HttpEngine.java +++ b/vtm/src/org/oscim/tiling/source/HttpEngine.java @@ -10,7 +10,7 @@ public interface HttpEngine { InputStream read() throws IOException; - boolean sendRequest(UrlTileSource tileSource, Tile tile) throws IOException; + boolean sendRequest(Tile tile) throws IOException; void close(); @@ -19,6 +19,7 @@ public interface HttpEngine { boolean requestCompleted(boolean success); public interface Factory { - public HttpEngine create(); + HttpEngine create(UrlTileSource tileSource); } + } diff --git a/vtm/src/org/oscim/tiling/source/LwHttp.java b/vtm/src/org/oscim/tiling/source/LwHttp.java index 8f3978ff..ac8abd80 100644 --- a/vtm/src/org/oscim/tiling/source/LwHttp.java +++ b/vtm/src/org/oscim/tiling/source/LwHttp.java @@ -24,7 +24,6 @@ import java.net.InetSocketAddress; import java.net.Socket; import java.net.SocketAddress; import java.net.URL; -import java.util.Map; import java.util.Map.Entry; import org.oscim.core.Tile; @@ -41,6 +40,8 @@ public class LwHttp implements HttpEngine { static final Logger log = LoggerFactory.getLogger(LwHttp.class); static final boolean dbg = false; + private final UrlTileSource mTileSource; + private final static byte[] HEADER_HTTP_OK = "200 OK".getBytes(); //private final static byte[] HEADER_CONTENT_TYPE = "Content-Type".getBytes(); private final static byte[] HEADER_CONTENT_LENGTH = "Content-Length".getBytes(); @@ -69,16 +70,9 @@ public class LwHttp implements HttpEngine { private final byte[] REQUEST_GET_END; private final byte[] mRequestBuffer; - /** - * @param url - * Base url for tiles - */ - public LwHttp(URL url) { - this(url, null); - } - - public LwHttp(URL url, Map header) { - + private LwHttp(UrlTileSource tileSource) { + mTileSource = tileSource; + URL url = tileSource.getUrl(); int port = url.getPort(); if (port < 0) port = 80; @@ -90,9 +84,9 @@ public class LwHttp implements HttpEngine { REQUEST_GET_START = ("GET " + path).getBytes(); String addRequest = ""; - if (header != null) { + if (tileSource.getRequestHeader() != null) { StringBuffer sb = new StringBuffer(); - for (Entry l : header.entrySet()) + for (Entry l : tileSource.getRequestHeader().entrySet()) sb.append('\n').append(l.getKey()).append(": ").append(l.getValue()); addRequest = sb.toString(); } @@ -330,7 +324,7 @@ public class LwHttp implements HttpEngine { } @Override - public boolean sendRequest(UrlTileSource tileSource, Tile tile) throws IOException { + public boolean sendRequest(Tile tile) throws IOException { if (mSocket != null) { if (mMaxReq-- <= 0) @@ -359,7 +353,7 @@ public class LwHttp implements HttpEngine { byte[] request = mRequestBuffer; int pos = REQUEST_GET_START.length; - pos = tileSource.formatTilePath(tile, request, pos); + pos = formatTilePath(mTileSource, tile, request, pos); int len = REQUEST_GET_END.length; System.arraycopy(REQUEST_GET_END, 0, request, pos, len); @@ -497,4 +491,46 @@ public class LwHttp implements HttpEngine { return true; } + + /** + * Write tile url - the low level, no-allocations method, + * + * override getTileUrl() for custom url formatting using + * Strings + * + * @param tile the Tile + * @param buf to write url string + * @param pos current position + * @return new position + */ + public int formatTilePath(UrlTileSource tileSource, Tile tile, byte[] buf, int pos) { + String p = tileSource.formatTilePath(tile); + log.debug("path {}", p); + //if (p != null) { + byte[] b = p.getBytes(); + System.arraycopy(b, 0, buf, pos, b.length); + return pos + b.length; + //} + // + // buf[pos++] = '/'; + // pos = LwHttp.writeInt(tile.zoomLevel, pos, buf); + // buf[pos++] = '/'; + // pos = LwHttp.writeInt(tile.tileX, pos, buf); + // buf[pos++] = '/'; + // pos = LwHttp.writeInt(tile.tileY, pos, buf); + // byte[] ext = tileSource.mExtBytes; + // if (ext == null) + // return pos; + // + // System.arraycopy(ext, 0, buf, pos, ext.length); + // return pos + ext.length; + } + + public static class LwHttpFactory implements HttpEngine.Factory { + + @Override + public HttpEngine create(UrlTileSource tileSource) { + return new LwHttp(tileSource); + } + } } diff --git a/vtm/src/org/oscim/tiling/source/OkHttpEngine.java b/vtm/src/org/oscim/tiling/source/OkHttpEngine.java index 2f4c7349..7e39ad73 100644 --- a/vtm/src/org/oscim/tiling/source/OkHttpEngine.java +++ b/vtm/src/org/oscim/tiling/source/OkHttpEngine.java @@ -4,6 +4,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.HttpURLConnection; +import java.net.MalformedURLException; import java.net.URL; import org.oscim.core.Tile; @@ -11,25 +12,27 @@ import org.oscim.core.Tile; import com.squareup.okhttp.OkHttpClient; public class OkHttpEngine implements HttpEngine { - private final OkHttpClient client; + private final OkHttpClient mClient; + private final UrlTileSource mTileSource; public static class OkHttpFactory implements HttpEngine.Factory { - private final OkHttpClient client; + private final OkHttpClient mClient; public OkHttpFactory() { - this.client = new OkHttpClient(); + mClient = new OkHttpClient(); } @Override - public HttpEngine create() { - return new OkHttpEngine(client); + public HttpEngine create(UrlTileSource tileSource) { + return new OkHttpEngine(mClient, tileSource); } } private InputStream inputStream; - public OkHttpEngine(OkHttpClient client) { - this.client = client; + public OkHttpEngine(OkHttpClient client, UrlTileSource tileSource) { + mClient = client; + mTileSource = tileSource; } @Override @@ -37,28 +40,20 @@ public class OkHttpEngine implements HttpEngine { return inputStream; } + HttpURLConnection openConnection(Tile tile) throws MalformedURLException { + return mClient.open(new URL(mTileSource.getUrl() + + mTileSource.formatTilePath(tile))); + } + @Override - public boolean sendRequest(UrlTileSource tileSource, Tile tile) throws IOException { + public boolean sendRequest(Tile tile) throws IOException { if (tile == null) { throw new IllegalArgumentException("Tile cannot be null."); } - final URL requestUrl = new URL(tileSource.getUrl() - + "/" - + Byte.toString(tile.zoomLevel) - + "/" - + tile.tileX - + "/" - + tile.tileY - + ".vtm"); + final HttpURLConnection connection = openConnection(tile); - final HttpURLConnection connection = client.open(requestUrl); - - try { - inputStream = connection.getInputStream(); - } catch (Exception e) { - e.printStackTrace(); - } + inputStream = connection.getInputStream(); return true; } diff --git a/vtm/src/org/oscim/tiling/source/UrlTileDataSource.java b/vtm/src/org/oscim/tiling/source/UrlTileDataSource.java index a97272c3..4cf814cf 100644 --- a/vtm/src/org/oscim/tiling/source/UrlTileDataSource.java +++ b/vtm/src/org/oscim/tiling/source/UrlTileDataSource.java @@ -75,7 +75,7 @@ public class UrlTileDataSource implements ITileDataSource { TileWriter cacheWriter = null; try { InputStream is; - if (!mConn.sendRequest(mTileSource, tile)) { + if (!mConn.sendRequest(tile)) { log.debug("{} Request failed", tile); } else if ((is = mConn.read()) == null) { log.debug("{} Network Error", tile); diff --git a/vtm/src/org/oscim/tiling/source/UrlTileSource.java b/vtm/src/org/oscim/tiling/source/UrlTileSource.java index 3d00bbd4..b7546ba3 100644 --- a/vtm/src/org/oscim/tiling/source/UrlTileSource.java +++ b/vtm/src/org/oscim/tiling/source/UrlTileSource.java @@ -18,30 +18,44 @@ package org.oscim.tiling.source; import java.net.MalformedURLException; import java.net.URL; +import java.util.Map; import org.oscim.core.Tile; import org.oscim.tiling.TileSource; +import org.oscim.tiling.source.LwHttp.LwHttpFactory; public abstract class UrlTileSource extends TileSource { private final URL mUrl; - private byte[] mExt; - private HttpEngine.Factory mHttpFactory; + private final String[] mTilePath; + + private HttpEngine.Factory mHttpFactory; + private Map mRequestHeaders; + + public UrlTileSource(String url, String tilePath, int zoomMin, int zoomMax) { + this(url, tilePath); + mZoomMin = zoomMin; + mZoomMax = zoomMax; + } + + /** + * @param urlString 'http://example.com/' + * @param tilePath replacement string for tile coordinates, + * e.g. '{Z}/{X}/{Y}.png' + */ + public UrlTileSource(String urlString, String tilePath) { + + if (tilePath == null) + throw new IllegalArgumentException("tilePath cannot be null."); - public UrlTileSource(String urlString) { URL url = null; try { url = new URL(urlString); } catch (MalformedURLException e) { - e.printStackTrace(); + throw new IllegalArgumentException(e); } mUrl = url; - } - - public UrlTileSource(String url, int zoomMin, int zoomMax) { - this(url); - mZoomMin = zoomMin; - mZoomMax = zoomMax; + mTilePath = tilePath.split("\\{|\\}"); } @Override @@ -54,70 +68,52 @@ public abstract class UrlTileSource extends TileSource { } - protected void setExtension(String ext) { - if (ext == null) { - mExt = null; - return; - } - mExt = ext.getBytes(); - } - - protected void setMimeType(String string) { - - } - - /** - * Create url path for tile - */ - protected String getTileUrl(Tile tile) { - return null; - } - - /** - * Write tile url - the low level, no-allocations method, - * - * override getTileUrl() for custom url formatting using - * Strings - * - * @param tile the Tile - * @param buf to write url string - * @param pos current position - * @return new position - */ - public int formatTilePath(Tile tile, byte[] buf, int pos) { - String p = getTileUrl(tile); - if (p != null) { - byte[] b = p.getBytes(); - System.arraycopy(b, 0, buf, pos, b.length); - return pos + b.length; - } - - buf[pos++] = '/'; - pos = LwHttp.writeInt(tile.zoomLevel, pos, buf); - buf[pos++] = '/'; - pos = LwHttp.writeInt(tile.tileX, pos, buf); - buf[pos++] = '/'; - pos = LwHttp.writeInt(tile.tileY, pos, buf); - if (mExt == null) - return pos; - - System.arraycopy(mExt, 0, buf, pos, mExt.length); - return pos + mExt.length; - } - public URL getUrl() { return mUrl; } + public String formatTilePath(Tile tile) { + // TODO only use the actual replacement positions. + + StringBuilder sb = new StringBuilder(); + for (String b : mTilePath) { + if (b.length() == 1) { + switch (b.charAt(0)) { + case 'X': + sb.append(tile.tileX); + continue; + case 'Y': + sb.append(tile.tileY); + continue; + case 'Z': + sb.append(tile.zoomLevel); + continue; + default: + break; + } + } + sb.append(b); + } + return sb.toString(); + } + public void setHttpEngine(HttpEngine.Factory httpFactory) { mHttpFactory = httpFactory; } + public void setHttpRequestHeaders(Map options) { + mRequestHeaders = options; + } + + protected Map getRequestHeader() { + return mRequestHeaders; + } + public HttpEngine getHttpEngine() { if (mHttpFactory == null) { - return new LwHttp(getUrl()); + mHttpFactory = new LwHttpFactory(); } - return mHttpFactory.create(); + return mHttpFactory.create(this); } } diff --git a/vtm/src/org/oscim/tiling/source/bitmap/BitmapTileSource.java b/vtm/src/org/oscim/tiling/source/bitmap/BitmapTileSource.java index 40197f63..3e2fc055 100644 --- a/vtm/src/org/oscim/tiling/source/bitmap/BitmapTileSource.java +++ b/vtm/src/org/oscim/tiling/source/bitmap/BitmapTileSource.java @@ -26,8 +26,15 @@ public class BitmapTileSource extends UrlTileSource { * implement getUrlString() for custom formatting. */ public BitmapTileSource(String url, int zoomMin, int zoomMax) { - super(url, zoomMin, zoomMax); - setExtension(".png"); + super(url, "/{Z}/{X}/{Y}.png", zoomMin, zoomMax); + } + + public BitmapTileSource(String url, int zoomMin, int zoomMax, String extension) { + super(url, "/{Z}/{X}/{Y}" + extension, zoomMin, zoomMax); + } + + public BitmapTileSource(String url, String tilePath, int zoomMin, int zoomMax) { + super(url, tilePath, zoomMin, zoomMax); } @Override diff --git a/vtm/src/org/oscim/tiling/source/bitmap/DefaultSources.java b/vtm/src/org/oscim/tiling/source/bitmap/DefaultSources.java index 92fea620..f74d5119 100644 --- a/vtm/src/org/oscim/tiling/source/bitmap/DefaultSources.java +++ b/vtm/src/org/oscim/tiling/source/bitmap/DefaultSources.java @@ -1,6 +1,5 @@ package org.oscim.tiling.source.bitmap; -import org.oscim.core.Tile; import org.oscim.layers.tile.bitmap.BitmapTileLayer.FadeStep; /** @@ -35,15 +34,13 @@ public class DefaultSources { public static class ImagicoLandcover extends BitmapTileSource { public ImagicoLandcover() { - super("http://www.imagico.de/map/tiles/landcover", 0, 6); - setExtension(".jpg"); + super("http://www.imagico.de/map/tiles/landcover", 0, 6, ".jpg"); } } public static class MapQuestAerial extends BitmapTileSource { public MapQuestAerial() { - super("http://otile1.mqcdn.com/tiles/1.0.0/sat", 0, 8); - setExtension(".jpg"); + super("http://otile1.mqcdn.com/tiles/1.0.0/sat", 0, 8, ".jpg"); } @Override @@ -64,38 +61,17 @@ public class DefaultSources { } public static class ArcGISWorldShaded extends BitmapTileSource { - private final StringBuilder sb = new StringBuilder(32); - public ArcGISWorldShaded() { - super("http://server.arcgisonline.com/ArcGIS/rest/services", 0, 13); - } - - @Override - public synchronized String getTileUrl(Tile tile) { - sb.setLength(0); - //sb.append("/World_Imagery/MapServer/tile/"); - sb.append("/World_Shaded_Relief/MapServer/tile/"); - sb.append(tile.zoomLevel); - sb.append('/').append(tile.tileY); - sb.append('/').append(tile.tileX); - return sb.toString(); + super("http://server.arcgisonline.com/ArcGIS/rest/services" + + "/World_Shaded_Relief/MapServer/tile/", + "{Z}/{Y}/{X}", 0, 13); } } public static class HillShadeHD extends BitmapTileSource { - private final StringBuilder sb = new StringBuilder(32); - public HillShadeHD() { - super("http://129.206.74.245:8004/tms_hs.ashx", 2, 16); - } - - @Override - public synchronized String getTileUrl(Tile tile) { - sb.setLength(0); - sb.append("?x=").append(tile.tileX); - sb.append("&y=").append(tile.tileY); - sb.append("&z=").append(tile.zoomLevel); - return sb.toString(); + super("http://129.206.74.245:8004/tms_hs.ashx", + "?x={X}&y={Y}&z={Z}", 2, 16); } } @@ -104,23 +80,8 @@ public class DefaultSources { * https://developers.google.com/maps/faq */ public static class GoogleMaps extends BitmapTileSource { - private final StringBuilder sb = new StringBuilder(60); - public GoogleMaps(String hostName) { - super(hostName, 1, 20); //jpeg for sat - } - - @Override - public synchronized String getTileUrl(Tile tile) { - sb.setLength(0); - sb.append("/vt/x="); //lyrs=y& - sb.append(tile.tileX); - sb.append("&y="); - sb.append(tile.tileY); - sb.append("&z="); - sb.append(tile.zoomLevel); - sb.append("&s=Galileo&scale=2"); - return sb.toString(); + super(hostName, "/vt/x={X}&y={Y}&z={Z}&s=Galileo&scale=2", 1, 20); //jpeg for sat } } diff --git a/vtm/src/org/oscim/tiling/source/oscimap4/OSciMap4TileSource.java b/vtm/src/org/oscim/tiling/source/oscimap4/OSciMap4TileSource.java index 3d2788a7..d98597cc 100644 --- a/vtm/src/org/oscim/tiling/source/oscimap4/OSciMap4TileSource.java +++ b/vtm/src/org/oscim/tiling/source/oscimap4/OSciMap4TileSource.java @@ -27,8 +27,7 @@ public class OSciMap4TileSource extends UrlTileSource { } public OSciMap4TileSource(String url) { - super(url); - setExtension(".vtm"); + super(url, "/{Z}/{X}/{Y}.vtm"); } @Override