/******************************************************************************* * Copyright (c) MOBAC developers * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * This program 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 for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. ******************************************************************************/ package mobac.program.atlascreators.impl.rmp; import java.awt.Color; import java.awt.Graphics2D; import java.awt.Point; import java.awt.image.BufferedImage; import mobac.exceptions.MapCreationException; import mobac.program.atlascreators.tileprovider.TileProvider; import mobac.program.interfaces.MapInterface; import mobac.program.interfaces.MapSource; import mobac.program.interfaces.MapSpace; import mobac.utilities.collections.SoftHashMap; import org.apache.log4j.Logger; /** * CalibratedImage that gets its data from a set of other CalibratedImage2 * */ public class MultiImage { private static final Logger log = Logger.getLogger(MultiImage.class); private final MapInterface map; private final MapSource mapSource; private final int zoom; private final TileProvider tileProvider; private SoftHashMap<TileKey, MobacTile> cache; public MultiImage(MapSource mapSource, TileProvider tileProvider, MapInterface map) { this.mapSource = mapSource; this.tileProvider = tileProvider; this.zoom = map.getZoom(); this.map = map; cache = new SoftHashMap<TileKey, MobacTile>(400); } public BufferedImage getSubImage(BoundingRect area, int width, int height) throws MapCreationException { if (log.isTraceEnabled()) log.trace(String.format("getSubImage %d %d %s", width, height, area)); MapSpace mapSpace = mapSource.getMapSpace(); int tilesize = mapSpace.getTileSize(); //int xMax = mapSource.getMapSpace().cLonToX(area.getEast(), zoom) / tilesize; //int xMin = mapSource.getMapSpace().cLonToX(area.getWest(), zoom) / tilesize; //int yMax = mapSource.getMapSpace().cLatToY(-area.getSouth(), zoom) / tilesize; //int yMin = mapSource.getMapSpace().cLatToY(-area.getNorth(), zoom) / tilesize; Point p1 = mapSpace.cLonLatToXY(area.getWest(), -area.getNorth(), zoom); Point p2 = mapSpace.cLonLatToXY(area.getEast(), -area.getSouth(), zoom); int xMax = p2.x / tilesize; int xMin = p1.x / tilesize; int yMax = p2.y / tilesize; int yMin = p1.y / tilesize; BufferedImage result = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics2D graph = result.createGraphics(); try { graph.setColor(Color.WHITE); graph.fillRect(0, 0, width, height); for (int x = xMin; x <= xMax; x++) { for (int y = yMin; y <= yMax; y++) { TileKey key = new TileKey(x, y); MobacTile image = cache.get(key); if (image == null) { image = new MobacTile(tileProvider, mapSpace, x, y, zoom); cache.put(key, image); } image.drawSubImage(area, result); } } } catch (Throwable t) { throw new MapCreationException(map, t); } finally { graph.dispose(); } return result; } protected static class TileKey { int x; int y; public TileKey(int x, int y) { this.x = x; this.y = y; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + x; result = prime * result + y; return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; TileKey other = (TileKey) obj; if (x != other.x) return false; if (y != other.y) return false; return true; } } }