/******************************************************************************* * 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; import java.awt.geom.Point2D; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import mobac.exceptions.MapCreationException; import mobac.program.annotations.AtlasCreatorName; import mobac.program.annotations.SupportedParameters; import mobac.program.atlascreators.impl.MapTileBuilder; import mobac.program.atlascreators.impl.MapTileWriter; import mobac.program.atlascreators.tileprovider.CacheTileProvider; import mobac.program.atlascreators.tileprovider.TileProvider; import mobac.program.interfaces.MapInterface; import mobac.program.interfaces.MapSpace; import mobac.program.model.TileImageParameters.Name; import mobac.utilities.Utilities; @AtlasCreatorName("CacheWolf (WFL)") @SupportedParameters(names = { Name.format, Name.height, Name.width }) public class CacheWolf extends Ozi { @Override public void initializeMap(MapInterface map, TileProvider mapTileProvider) { super.initializeMap(map, mapTileProvider); } @Override public void createMap() throws MapCreationException, InterruptedException { try { Utilities.mkDirs(layerDir); } catch (IOException e1) { throw new MapCreationException(map, e1); } if (parameters == null) { // One image per map super.createTiles(); writeWflFile(); } else // Use automatic tiling as specified in the parameters createTiles(); } @Override protected void createTiles() throws InterruptedException, MapCreationException { MapTileWriter mapTileWriter; CacheTileProvider ctp = new CacheTileProvider(mapDlTileProvider); try { mapDlTileProvider = ctp; mapTileWriter = new CWFileTileWriter(); MapTileBuilder mapTileBuilder = new MapTileBuilder(this, mapTileWriter, true); atlasProgress.initMapCreation(mapTileBuilder.getCustomTileCount()); mapTileBuilder.createTiles(); } catch (IOException e) { throw new MapCreationException(map, e); } finally { ctp.cleanup(); } } private void writeWflFile() throws MapCreationException { int width = (xMax - xMin + 1) * tileSize; int height = (yMax - yMin + 1) * tileSize; try { writeWflFile(mapName, 0, 0, width, height); } catch (IOException e) { throw new MapCreationException("Error writing wfl file: " + e.getMessage(), map, e); } } private void writeWflFile(String filename, int tilex, int tiley, int width, int height) throws IOException { FileOutputStream fout = null; try { fout = new FileOutputStream(new File(layerDir, filename + ".wfl")); OutputStreamWriter mapWriter = new OutputStreamWriter(fout, TEXT_FILE_CHARSET); MapSpace mapSpace = mapSource.getMapSpace(); int xStart = xMin * tileSize; int yStart = yMin * tileSize; if (parameters != null) { xStart += tilex * parameters.getWidth(); yStart += tiley * parameters.getHeight(); } //double topLeftLon = mapSpace.cXToLon(xStart, zoom); //double topLeftLat = mapSpace.cYToLat(yStart, zoom); Point2D.Double p = mapSpace.cXYToLonLat(xStart, yStart, zoom); double topLeftLon = p.x; double topLeftLat = p.y; //double bottomRightLon = mapSpace.cXToLon(xStart + width, zoom); //double bottomRightLat = mapSpace.cYToLat(yStart + height, zoom); p = mapSpace.cXYToLonLat(xStart + width, yStart + height, zoom); double bottomRightLon = p.x; double bottomRightLat = p.y; double[] affine = { 0, 0, 0, 0 }; // Mobile Atlas Creator does only output maps with north at top // (no rotation). Therefore we should be able to simplify the affine // calculation process: affine[1] = (bottomRightLon - topLeftLon) / width; affine[2] = (bottomRightLat - topLeftLat) / height; for (double d : affine) mapWriter.write(Double.toString(d) + "\n"); mapWriter.write(Double.toString(topLeftLat) + "\n"); mapWriter.write(Double.toString(topLeftLon) + "\n"); mapWriter.write(Double.toString(bottomRightLat) + "\n"); mapWriter.write(Double.toString(bottomRightLon) + "\n"); mapWriter.flush(); mapWriter.close(); } finally { Utilities.closeStream(fout); } } public class CWFileTileWriter implements MapTileWriter { public CWFileTileWriter() throws IOException { super(); log.debug("Writing tiles to set folder: " + layerDir); } public void writeTile(int tilex, int tiley, String imageFormat, byte[] tileData) throws IOException { String tileFileName = String.format("%s_%dx%d", mapName, tilex, tiley); File f = new File(layerDir, tileFileName + '.' + imageFormat); FileOutputStream out = new FileOutputStream(f); try { out.write(tileData); } finally { Utilities.closeStream(out); } writeWflFile(tileFileName, tilex, tiley, parameters.getWidth(), parameters.getHeight()); } public void finalizeMap() { } } }