// License: GPL. For details, see LICENSE file.
package org.openstreetmap.josm.plugins.elevation.grid;
import static org.openstreetmap.josm.tools.I18n.tr;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.concurrent.BlockingDeque;
import java.util.concurrent.LinkedBlockingDeque;
import org.openstreetmap.gui.jmapviewer.Tile;
import org.openstreetmap.gui.jmapviewer.interfaces.TileCache;
import org.openstreetmap.gui.jmapviewer.interfaces.TileSource;
import org.openstreetmap.josm.data.Bounds;
import org.openstreetmap.josm.data.coor.LatLon;
import org.openstreetmap.josm.gui.MapView;
import org.openstreetmap.josm.plugins.elevation.ElevationHelper;
import org.openstreetmap.josm.plugins.elevation.IVertexRenderer;
import org.openstreetmap.josm.plugins.elevation.gui.Triangle;
public class ElevationGridTile extends Tile {
private final BlockingDeque<EleVertex> toDo = new LinkedBlockingDeque<>();
private final BlockingDeque<EleVertex> vertices = new LinkedBlockingDeque<>();
private Bounds box;
public ElevationGridTile(TileSource source, int xtile, int ytile, int zoom) {
super(source, xtile, ytile, zoom);
box = tile2Bounds(xtile, ytile, zoom);
initQueue();
}
public ElevationGridTile(TileSource source, int xtile, int ytile, int zoom,
BufferedImage image) {
super(source, xtile, ytile, zoom, image);
}
@Override
public void loadPlaceholderFromCache(TileCache cache) {
// TODO Auto-generated method stub
super.loadPlaceholderFromCache(cache);
//System.out.println("loadPlaceholderFromCache");
}
@Override
public String getUrl() throws IOException {
// TODO Auto-generated method stub
return super.getUrl();
}
/**
* Use {@link ElevationGridTile#paintTile(Graphics2D, MapView, IVertexRenderer)} to render the tile as grid.
* This method just issues a debug text.
*/
@Override
public void paint(Graphics g, int x, int y) {
super.paint(g, x, y);
//g.drawString(String.format("EGT %d/%d ", getXtile(), getYtile()), x, y);
g.drawString(getStatus(), x, y);
}
/**
* Paints the vertices of this tile.
*
* @param g the graphics context
* @param mv the map view
* @param vertexRenderer the vertex renderer
*/
public void paintTile(Graphics2D g, MapView mv, IVertexRenderer vertexRenderer) {
BlockingDeque<EleVertex> list = getVertices();
for (EleVertex eleVertex : list) {
Point p0 = mv.getPoint(eleVertex.get(0));
Point p1 = mv.getPoint(eleVertex.get(1));
Point p2 = mv.getPoint(eleVertex.get(2));
Triangle shape = new Triangle(p0, p1, p2);
// obtain vertex color
g.setColor(vertexRenderer.getElevationColor(eleVertex));
// TODO: Move to renderer
g.fill(shape);
}
}
@Override
public void loadImage(InputStream input) throws IOException {
if (isLoaded()) return;
// TODO: Save
// We abuse the loadImage method to render the vertices...
//
while (toDo.size() > 0) {
EleVertex vertex = toDo.poll();
if (vertex.isFinished()) {
vertices.add(vertex);
} else {
List<EleVertex> newV = vertex.divide();
for (EleVertex eleVertex : newV) {
toDo.add(eleVertex);
}
}
}
setLoaded(true);
}
public BlockingDeque<EleVertex> getVertices() {
return vertices;
}
/**
* See also <a href="http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames#Tile_bounding_box">OSM Wiki</a>
* @param x the x
* @param y the y
* @param zoom the zoom
* @return the bounds
*/
private Bounds tile2Bounds(final int x, final int y, final int zoom) {
return new Bounds(
new LatLon(source.tileXYToLatLon(x, y, zoom)),
new LatLon(source.tileXYToLatLon(x + 1, y + 1, zoom)));
}
/**
* Inits the 'todo' queue with the initial vertices.
*/
private void initQueue() {
LatLon min = box.getMin();
LatLon max = box.getMax();
// compute missing coordinates
LatLon h1 = new LatLon(min.lat(), max.lon());
LatLon h2 = new LatLon(max.lat(), min.lon());
double eleMin = ElevationHelper.getSrtmElevation(min);
double eleMax = ElevationHelper.getSrtmElevation(max);
// SRTM files present?
if (!ElevationHelper.isValidElevation(eleMax) || !ElevationHelper.isValidElevation(eleMin)) {
setError(tr("No SRTM data"));
return;
}
// compute elevation coords
EleCoordinate p0 = new EleCoordinate(min, eleMin);
EleCoordinate p1 = new EleCoordinate(h1, ElevationHelper.getSrtmElevation(h1));
EleCoordinate p2 = new EleCoordinate(max, eleMax);
EleCoordinate p3 = new EleCoordinate(h2, ElevationHelper.getSrtmElevation(h2));
// compute initial vertices
EleVertex v1 = new EleVertex(p0, p1, p2);
EleVertex v2 = new EleVertex(p2, p3, p0);
// enqueue vertices
toDo.add(v1);
toDo.add(v2);
}
@Override
public String toString() {
return "ElevationGridTile [box=" + box + ", xtile=" + xtile
+ ", ytile=" + ytile + "]";
}
}