/* * This file is part of JGrasstools (http://www.jgrasstools.org) * (C) HydroloGIS - www.hydrologis.com * * JGrasstools 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 3 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 org.jgrasstools.nww.layers.defaults.raster; import java.awt.image.BufferedImage; import java.io.File; import java.net.MalformedURLException; import java.net.URL; import javax.imageio.ImageIO; import org.geotools.geometry.jts.JTS; import org.geotools.referencing.CRS; import org.geotools.referencing.crs.DefaultGeographicCRS; import org.jgrasstools.dbs.spatialite.RasterCoverage; import org.jgrasstools.gears.spatialite.RL2CoverageHandler; import org.jgrasstools.gears.utils.CrsUtilities; import org.jgrasstools.gears.utils.geometry.GeometryUtilities; import org.jgrasstools.nww.layers.defaults.NwwLayer; import org.jgrasstools.nww.utils.NwwUtilities; import org.jgrasstools.nww.utils.cache.CacheUtils; import org.opengis.referencing.crs.CoordinateReferenceSystem; import org.opengis.referencing.operation.MathTransform; import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Polygon; import gov.nasa.worldwind.avlist.AVKey; import gov.nasa.worldwind.avlist.AVList; import gov.nasa.worldwind.avlist.AVListImpl; import gov.nasa.worldwind.geom.Angle; import gov.nasa.worldwind.geom.LatLon; import gov.nasa.worldwind.geom.Sector; import gov.nasa.worldwind.layers.mercator.MercatorSector; import gov.nasa.worldwind.util.LevelSet; import gov.nasa.worldwind.util.Tile; import gov.nasa.worldwind.util.TileUrlBuilder; /** * Procedural layer for rasterlite2 files * * @author Andrea Antonello (www.hydrologis.com) */ public class RL2NwwLayer extends BasicMercatorTiledImageLayer implements NwwLayer { private String layerName = "unknown layer"; private static final int TILESIZE = 512; private Coordinate centerCoordinateLL; public RL2NwwLayer( RL2CoverageHandler rl2Handler, Integer tileSize ) throws Exception { super(makeLevels(rl2Handler, tileSize)); RasterCoverage rasterCoverage = rl2Handler.getRasterCoverage(); this.layerName = rasterCoverage.coverage_name; double w = rasterCoverage.extent_minx; double s = rasterCoverage.extent_miny; double e = rasterCoverage.extent_maxx; double n = rasterCoverage.extent_maxy; double centerX = w + (e - w) / 2.0; double centerY = s + (n - s) / 2.0; Coordinate centerCoordinate = new Coordinate(centerX, centerY); CoordinateReferenceSystem targetCRS = DefaultGeographicCRS.WGS84; CoordinateReferenceSystem sourceCRS = CrsUtilities.getCrsFromSrid(rasterCoverage.srid); MathTransform transform = CRS.findMathTransform(sourceCRS, targetCRS); centerCoordinateLL = JTS.transform(centerCoordinate, null, transform); this.setUseTransparentTextures(true); } private static LevelSet makeLevels( RL2CoverageHandler rl2Handler, Integer tileSize ) throws MalformedURLException { AVList params = new AVListImpl(); if (tileSize == null || tileSize < 256) { tileSize = TILESIZE; } int finalTileSize = tileSize; String databasePath = rl2Handler.getDatabasePath(); File databaseFile = new File(databasePath); String tilesPart = "-tiles" + File.separator + rl2Handler.getRasterCoverage().coverage_name; String cacheRelativePath = "rl2/" + databaseFile.getName() + tilesPart; String urlString = databaseFile.toURI().toURL().toExternalForm(); params.setValue(AVKey.URL, urlString); params.setValue(AVKey.TILE_WIDTH, finalTileSize); params.setValue(AVKey.TILE_HEIGHT, finalTileSize); params.setValue(AVKey.DATA_CACHE_NAME, cacheRelativePath); params.setValue(AVKey.SERVICE, "*"); params.setValue(AVKey.DATASET_NAME, "*"); String imageFormat = null; try { String compression = rl2Handler.getRasterCoverage().compression; if (compression.equals("JPEG")) { imageFormat = "jpg"; } } catch (Exception e1) { e1.printStackTrace(); } if (imageFormat == null) { imageFormat = "png"; } final String _imageFormat = imageFormat; params.setValue(AVKey.FORMAT_SUFFIX, "." + imageFormat); params.setValue(AVKey.NUM_LEVELS, 22); params.setValue(AVKey.NUM_EMPTY_LEVELS, 0); params.setValue(AVKey.LEVEL_ZERO_TILE_DELTA, new LatLon(Angle.fromDegrees(22.5d), Angle.fromDegrees(45d))); params.setValue(AVKey.SECTOR, new MercatorSector(-1.0, 1.0, Angle.NEG180, Angle.POS180)); File cacheRoot = CacheUtils.getCacheRoot(); final File cacheFolder = new File(cacheRoot, cacheRelativePath); if (!cacheFolder.exists()) { cacheFolder.mkdirs(); } params.setValue(AVKey.TILE_URL_BUILDER, new TileUrlBuilder(){ public URL getURL( Tile tile, String altImageFormat ) throws MalformedURLException { int zoom = tile.getLevelNumber() + 3; Sector sector = tile.getSector(); double n = sector.getMaxLatitude().degrees; double s = sector.getMinLatitude().degrees; double e = sector.getMaxLongitude().degrees; double w = sector.getMinLongitude().degrees; double centerX = w + (e - w) / 2.0; double centerY = s + (n - s) / 2.0; int[] tileNumber = NwwUtilities.getTileNumber(centerY, centerX, zoom); int x = tileNumber[0]; int y = tileNumber[1]; // int zoom = tile.getLevelNumber() + 3; // int x = tile.getColumn(); // int y = (1 << (tile.getLevelNumber()) + 3) - 1 - tile.getRow(); // // double n = MBTilesHelper.tile2lat(y, zoom); // double s = MBTilesHelper.tile2lat(y + 1, zoom); // double w = MBTilesHelper.tile2lon(x, zoom); // double e = MBTilesHelper.tile2lon(x + 1, zoom); Coordinate ll = new Coordinate(w, s); Coordinate ur = new Coordinate(e, n); Polygon polygon = GeometryUtilities.createPolygonFromEnvelope(new com.vividsolutions.jts.geom.Envelope(ll, ur)); try { File imgFile; synchronized (rl2Handler) { StringBuilder sb = new StringBuilder(); sb.append(zoom); sb.append(File.separator); sb.append(x); File tileImageFolderFile = new File(cacheFolder, sb.toString()); if (!tileImageFolderFile.exists()) { tileImageFolderFile.mkdirs(); } sb = new StringBuilder(); sb.append(y); sb.append("."); sb.append(_imageFormat); imgFile = new File(tileImageFolderFile, sb.toString()); if (!imgFile.exists()) { BufferedImage bImg = rl2Handler.getRL2Image(polygon, "" + CrsUtilities.WGS84_SRID, finalTileSize, finalTileSize); if (bImg != null) { ImageIO.write(bImg, _imageFormat, imgFile); } else { return null; } } } return imgFile.toURI().toURL(); } catch (Exception ez) { ez.printStackTrace(); return null; } } }); return new LevelSet(params); } public String toString() { return layerName; } @Override public Coordinate getCenter() { return centerCoordinateLL; } }