/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2015, Open Source Geospatial Foundation (OSGeo) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library 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 * Lesser General Public License for more details. */ package org.geotools.tile.util; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import java.util.Collection; import java.util.concurrent.CountDownLatch; import org.geotools.geometry.jts.ReferencedEnvelope; import org.geotools.tile.Tile; import org.geotools.tile.TileService; import org.opengis.referencing.FactoryException; import org.opengis.referencing.operation.TransformException; /** * This Layer is an attempt to speed rendering by using a CountDownLatch and * threads to render each tile. The performance improvement is minimal, though. * * @author Ugo Taddei * @since 12 * @source $URL: * http://svn.osgeo.org/geotools/trunk/modules/unsupported/tile-client * /src/main/java/org/geotools/tile/util/AsyncTileLayer.java $ */ public class AsyncTileLayer extends TileLayer { private CountDownLatch countDownLatch; public AsyncTileLayer(TileService service) { super(service); } @Override protected void renderTiles(Collection<Tile> tiles, Graphics2D g2d, ReferencedEnvelope viewportExtent, AffineTransform worldToImageTransform) { long t = System.currentTimeMillis(); this.countDownLatch = new CountDownLatch(tiles.size()); // g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, // (float) 0.5)); localRenderTiles(tiles, g2d, viewportExtent, worldToImageTransform); try { this.countDownLatch.await(); } catch (InterruptedException ie) { ie.printStackTrace(); } this.countDownLatch = null; // System.out.println("Async: " + (System.currentTimeMillis() - t)); } protected void renderTile(final Tile tile, final Graphics2D g2d, final double[] points) { Runnable r = new Runnable() { @Override public void run() { BufferedImage img = getTileImage(tile); g2d.drawImage(img, (int) points[0], (int) points[1], (int) Math.ceil(points[2] - points[0]), (int) Math.ceil(points[3] - points[1]), null); AsyncTileLayer.this.countDownLatch.countDown(); } }; new Thread(r).start(); } protected void localRenderTiles(Collection<Tile> tiles, Graphics2D g2d, ReferencedEnvelope viewportExtent, AffineTransform worldToImageTransform) { g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); // double[] points = new double[4]; for (Tile tile : tiles) { ReferencedEnvelope nativeTileEnvelope = tile.getExtent(); ReferencedEnvelope tileEnvViewport; try { tileEnvViewport = nativeTileEnvelope.transform( viewportExtent.getCoordinateReferenceSystem(), true); } catch (TransformException | FactoryException e) { throw new RuntimeException(e); } double[] points = new double[4]; points[0] = tileEnvViewport.getMinX(); points[3] = tileEnvViewport.getMinY(); points[2] = tileEnvViewport.getMaxX(); points[1] = tileEnvViewport.getMaxY(); worldToImageTransform.transform(points, 0, points, 0, 2); renderTile(tile, g2d, points); // BufferedImage img = getTileImage(tile); // // g2d.drawImage(img, (int) points[0], (int) points[1], // (int) Math.ceil(points[2] - points[0]), // (int) Math.ceil(points[3] - points[1]), null); } } }