/* * This is part of Geomajas, a GIS framework, http://www.geomajas.org/. * * Copyright 2008-2015 Geosparc nv, http://www.geosparc.com/, Belgium. * * The program is available in open source according to the GNU Affero * General Public License. All contributions in this program are covered * by the Geomajas Contributors License Agreement. For full licensing * details, see LICENSE.txt in the project root. */ package org.geomajas.gwt2.plugin.print.tilebasedlayer.server.layer; import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import org.geomajas.configuration.client.ClientLayerInfo; import org.geomajas.global.GeomajasException; import org.geomajas.gwt2.plugin.print.tilebasedlayer.server.dto.TilebasedClientLayerInfo; import org.geomajas.layer.RasterLayer; import org.geomajas.layer.common.proxy.LayerHttpService; import org.geomajas.layer.tile.RasterTile; import org.geomajas.plugin.rasterizing.api.LayerFactory; import org.geomajas.plugin.rasterizing.command.dto.RasterLayerRasterizingInfo; import org.geomajas.plugin.rasterizing.layer.RasterDirectLayer; import org.geomajas.plugin.rasterizing.layer.RasterDirectLayer.UrlDownLoader; import org.geomajas.service.ConfigurationService; import org.geomajas.service.DispatcherUrlService; import org.geotools.map.Layer; import org.geotools.map.MapContext; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; /** * This factory creates a GeoTools layer that is capable of rendering tile-based layers. * * @author Jan De Moerloose */ @Component public class TileBasedClientLayerFactory implements LayerFactory { @Autowired private ConfigurationService configurationService; @Autowired private DispatcherUrlService dispatcherUrlService; @Autowired private LayerHttpService httpService; private ExecutorService imageThreadPool; private int threadsPerCore = 30; public int getThreadsPerCore() { return threadsPerCore; } public void setThreadsPerCore(int threadsPerCore) { this.threadsPerCore = threadsPerCore; } public boolean canCreateLayer(MapContext mapContext, ClientLayerInfo clientLayerInfo) { return clientLayerInfo instanceof TilebasedClientLayerInfo; } public Layer createLayer(MapContext mapContext, ClientLayerInfo clientLayerInfo) throws GeomajasException { if (!(clientLayerInfo instanceof TilebasedClientLayerInfo)) { throw new IllegalArgumentException( "TileBasedClientLayerFactory.createLayer() should only be called with TilebasedClientLayerInfo"); } TilebasedClientLayerInfo rasterInfo = (TilebasedClientLayerInfo) clientLayerInfo; RasterLayerRasterizingInfo extraInfo = (RasterLayerRasterizingInfo) rasterInfo .getWidgetInfo(RasterLayerRasterizingInfo.WIDGET_KEY); List<RasterTile> tiles = rasterInfo.getTiles(); for (RasterTile rasterTile : tiles) { if (null != rasterTile.getUrl() && !rasterTile.getUrl().isEmpty()) { rasterTile.setUrl(calculateUrl(rasterTile.getUrl())); } } final RasterLayer layer = configurationService.getRasterLayer(clientLayerInfo.getServerLayerId()); RasterDirectLayer rasterLayer = new RasterDirectLayer(imageThreadPool, getHttpDownloader(layer), tiles, rasterInfo.getTileHeight(), rasterInfo.getTileWidth(), rasterInfo.getScale(), extraInfo.getCssStyle()); rasterLayer.setTitle(clientLayerInfo.getLabel()); rasterLayer.getUserData().put(USERDATA_KEY_LAYER_ID, rasterInfo.getId()); rasterLayer.getUserData().put(USERDATA_KEY_SHOWING, extraInfo.isShowing()); return rasterLayer; } public Map<String, Object> getLayerUserData(MapContext mapContext, ClientLayerInfo clientLayerInfo) { Map<String, Object> userData = new HashMap<String, Object>(); RasterLayerRasterizingInfo extraInfo = (RasterLayerRasterizingInfo) clientLayerInfo .getWidgetInfo(RasterLayerRasterizingInfo.WIDGET_KEY); userData.put(USERDATA_KEY_SHOWING, extraInfo.isShowing()); return userData; } @PostConstruct public void postConstruct() { int cpus = Runtime.getRuntime().availableProcessors(); imageThreadPool = Executors.newFixedThreadPool(cpus * threadsPerCore); } @PreDestroy public void preDestroy() { imageThreadPool.shutdown(); } private UrlDownLoader getHttpDownloader(final RasterLayer layer) { return new UrlDownLoader() { @Override public InputStream getStream(String url) throws IOException { return httpService.getStream(url, layer); } }; } private String calculateUrl(String urlAsString) { URL absoluteUrl = null; if (!urlAsString.startsWith("http:") && !urlAsString.startsWith("https:")) { try { String baseUrlAsString = dispatcherUrlService.getLocalDispatcherUrl(); URL baseUrl = new URL(baseUrlAsString); absoluteUrl = new URL(baseUrl, "../" + urlAsString); } catch (MalformedURLException e) { // Should never happen... // log.error("Error converting URL " + legendImageServiceUrlAsString + " to absolute URL", e); e.printStackTrace(); } } else { try { absoluteUrl = new URL(urlAsString); } catch (MalformedURLException e) { // Should never happen... // log.error("Error converting URL " + legendImageServiceUrlAsString + " to absolute URL", e); e.printStackTrace(); } } return absoluteUrl.toExternalForm(); } }