/* * Copyright (c) 2010, 2011 Itiner.pl. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Itiner designates this * particular file as subject to the "Classpath" exception as provided * by Itiner in the LICENSE.txt file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. */ package com.codename1.maps.providers; import com.codename1.ui.geom.Dimension; import com.codename1.maps.BoundingBox; import com.codename1.maps.Coord; import com.codename1.ui.geom.Point; import com.codename1.maps.Projection; import com.codename1.maps.ProxyHttpTile; import com.codename1.maps.Tile; /** * This is a tiled map provider * * @author Roman Kamyk <roman.kamyk@itiner.pl> */ public abstract class TiledProvider extends MapProvider { protected final String _url; // Very ugly cacheing private Point _tileNo; protected int _zoomLevel; /** * Creates a new Tiled provider * * @param url the url of the provider * @param projection the Projection system of the Provider * @param tileSize the tiles size(usually 256x256) */ public TiledProvider(String url, Projection projection, Dimension tileSize) { super(projection, tileSize); _url = url; } /** * build a url request for a tile * * @param zoomLevel the zoom level * @param xTile x position of the tile * @param yTile y position of the tile * @return the image url of the tile */ protected String url(int zoomLevel, int xTile, int yTile) { StringBuilder sb = new StringBuilder(_url); sb.append("/"); sb.append(zoomLevel); sb.append("/"); sb.append(xTile); sb.append("/"); sb.append(yTile); sb.append(".png"); return sb.toString(); } private int tileNo(double pos, double pos0, double scale) { return (int) ((pos - pos0) / scale); } private double tileCoord(int tileNo, double pos0, double scale) { return tileNo * scale + pos0; } /** * Scale to the zoom level * @param zoomLevel to scale to * * @return a scaled coordinate. */ public Coord scale(int zoomLevel) { int divider = (1 << zoomLevel); double longitude = (1.0 * projection().extent().longitudeDifference()) / divider / tileSize().getWidth(); double latitude = (1.0 * projection().extent().latitudeDifference()) / divider / tileSize().getHeight(); return new Coord(latitude, longitude, false); } private Point tileNo(Coord position, Coord boundary, Coord scale) { return new Point(tileNo(position.getLongitude(), boundary.getLongitude(), scale.getLongitude()), tileNo(position.getLatitude(), boundary.getLatitude(), scale.getLatitude())); } private Coord tileCoord(Point tileNo, Coord boundary, Coord scale) { return new Coord(tileCoord(tileNo.getY(), boundary.getLatitude(), scale.getLatitude()), tileCoord(tileNo.getX(), boundary.getLongitude(), scale.getLongitude()), true); } /** * {@inheritDoc} */ public BoundingBox bboxFor(Coord position, int zoomLevel) { _zoomLevel = zoomLevel; Coord scale = scale(zoomLevel); Dimension tileSize = tileSize(); double x = scale.getLongitude() * tileSize.getWidth(); double y = scale.getLatitude() * tileSize.getHeight(); Coord tileScale = new Coord(y, x, false); _tileNo = tileNo(position, projection().extent().getSouthWest(), tileScale); Coord start = tileCoord(_tileNo, projection().extent().getSouthWest(), tileScale); Coord end = start.translate(tileScale.getLatitude(), tileScale.getLongitude()); return new BoundingBox(start, end); } /** * {@inheritDoc} */ public Tile tileFor(BoundingBox bbox) { String url = url(_zoomLevel, _tileNo.getX(), (1 << _zoomLevel) - _tileNo.getY() - 1); return new ProxyHttpTile(tileSize(), bbox, url); } }