/* * This is part of Geomajas, a GIS framework, http://www.geomajas.org/. * * Copyright 2008-2015 Geosparc nv, http://www.geosparc.com/, Belgium. * * The program is available in open source according to the GNU Affero * General Public License. All contributions in this program are covered * by the Geomajas Contributors License Agreement. For full licensing * details, see LICENSE.txt in the project root. */ package org.geomajas.gwt2.plugin.tilebasedlayer.client.layer; import org.geomajas.annotation.Api; import org.geomajas.gwt2.client.map.render.TileCode; import org.geomajas.gwt2.client.map.render.TileRenderer; import java.util.ArrayList; import java.util.List; /** * TileRenderer implementation that builds URLs for tile based layers. By default the * renderer uses Round-Robin to determine the next URL to fetch tiles from and by default the * Y-coordinates are not inverted. * <p/> * All URLs for the renderer should have placeholders in the form of {x}, {y} and {z} for the x-coordinate, * y-coordinate and tile level respectively. To invert the Y-coordinate {-y} instead of {y} can be supplied. * * @author Youri Flement * @since 2.1.0 */ @Api(allMethods = true) public class DefaultTileRenderer implements TileRenderer { private List<String> urls; private int currentIndex; /** * Create a new default tile renderer with an URL to a tile service. * * @param url The URL to the tile service. */ public DefaultTileRenderer(String url) { this(new ArrayList<String>()); urls.add(url); } /** * Create a new default tile renderer with URLs to various tile services. * * @param urls The URLs to the tile services. */ public DefaultTileRenderer(List<String> urls) { this.urls = urls; currentIndex = 0; } /** * Get the URL that points to the image representing the given tile code. * * @param tileCode The tile code to fetch an image for. * @return The image URL. */ @Override public String getUrl(TileCode tileCode) { int y = isYAxisInverted() ? invertedY(tileCode) : tileCode.getY(); return fillPlaceHolders(getNextUrl(), tileCode.getX(), y, tileCode.getTileLevel()); } /** * Add an URL to a tile service. * <p/> * The URL should have placeholders for the x- and y-coordinate and tile level in the form of {x}, {y}, {z}. * The Y-coordinate can be inverted by specifying {-y} instead of {y}. * The file extension of the tiles should be part of the URL. * * @param url The URL to the tile service. */ public void addUrl(String url) { urls.add(url); } /** * Remove an URL to a tile service. * * @param url The URL to the tile service. * @return <code>true</code> if the URL was found and removed and <code>false</code> otherwise. */ public boolean removeUrl(String url) { return urls.remove(url); } /** * Check whether the Y-coordinates in this renderer are inverted or not. * Returns <code>false</code> if there were no URLs configured. * * @return <code>true</code> if the Y-coordinates are inverted and <code>false</code> otherwise. */ public boolean isYAxisInverted() { if (urls.isEmpty()) { return false; } return urls.get(0).contains("{-y}"); } /** * Fill in the {x}, {y} and {z} placeholders in the URL. * * @param url The URL with placeholders. * @param x The x-coordinate to the tile. * @param y The y-coordinate to the tile. * @param z The tile level. * @return The URL with filled placeholders. */ protected String fillPlaceHolders(String url, int x, int y, int z) { url = url.replace("{x}", Integer.toString(x)); url = url.replace("{y}", Integer.toString(y)); url = url.replace("{-y}", Integer.toString(y)); return url.replace("{z}", Integer.toString(z)); } /** * We use Round-Robin to determine the next URL to fetch tiles from. * * @return The URL to fetch tiles from. */ protected String getNextUrl() { String url = urls.get(currentIndex); currentIndex = (currentIndex + 1) % urls.size(); return url; } /** * Invert the TMS Y-ordinate. * * @param code The tilecode of the tile. * @return The inverted Y-ordinate. */ protected int invertedY(TileCode code) { return (int) Math.pow(2, code.getTileLevel()) - code.getY() - 1; } }