/******************************************************************************* * Copyright (c) 2012 Association for Decentralized Information Management * in Industry THTH ry. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * VTT Technical Research Centre of Finland - initial API and implementation *******************************************************************************/ package org.simantics.maps.osm; import java.awt.Dimension; import java.awt.Image; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URI; import javax.imageio.IIOException; import javax.imageio.ImageIO; import org.simantics.maps.ProvisionException; import org.simantics.maps.WebService; import org.simantics.maps.tile.ITileProvider; import org.simantics.maps.tile.TileKey; import org.simantics.maps.wms.ServiceException; /** * @author Tuukka Lehtonen * @see OSMGetMapQuery */ public class OSMTileProvider implements ITileProvider { private WebService service; private int tileSize; public OSMTileProvider(WebService service, int tileSize) { this.service = service; this.tileSize = tileSize; } @Override public URI getSource() { return service.getURI(); } @Override public Rectangle2D getExtent() { return new Rectangle2D.Double(-180, -90, 360, 180); } @Override public Image get(TileKey key) throws ProvisionException { int level = key.getLevel(); int x = key.getX(); int y = key.getY(); double xTiles = Math.pow(2, level + 1); double yTiles = Math.pow(2, level); if (level < 0) throw new IllegalArgumentException("invalid tile level " + level + " (tile=" + key +")"); if (x < 0 || x >= (int) xTiles) throw new IllegalArgumentException("tile x out of bounds " + x + " (tile=" + key +")"); if (y < 0 || y >= (int) yTiles) throw new IllegalArgumentException("tile y out of bounds " + y + " (tile=" + key +")"); try { Rectangle2D r = new Rectangle2D.Double(x, y, 10, 10); // System.out.println("TileProvider: requesting " + key + ", bbox=" + r + ", size=" + tileSize); BufferedImage img = getMap(service, tileSize, tileSize, r, "image/png", level);//layers); // System.out.println("TileProvider: response: " + img); return img; } catch (MalformedURLException e) { throw new ProvisionException(e); } catch (IOException e) { throw new ProvisionException(e); } } /** * Get a bufferedimage of the map data for the geographical coordinates. * * @param x * @param y * @param z * @return * @throws MalformedURLException */ public static BufferedImage getMap(WebService service, Dimension rasterSize, Rectangle2D bbox, String format, int level) throws MalformedURLException, IOException { return getMap(service, rasterSize.width, rasterSize.height, bbox, format, level); } /** * Get a bufferedimage of the map data for the geographical coordinates. * * @param x * @param y * @param z * @return * @throws MalformedURLException */ public static BufferedImage getMap(WebService service, int rasterWidth, int rasterHeight, Rectangle2D bbox, String format, int level) throws MalformedURLException, IOException { if (rasterWidth == 0 || rasterHeight == 0) return new BufferedImage(0, 0, BufferedImage.TYPE_INT_ARGB); HttpURLConnection connection = null; try { connection = service.openConnection(("" + level + "/" + Math.round(bbox.getMinX()) + "/" + Math.round(bbox.getMinY())+".png"), null); // Execute the method. int statusCode = connection.getResponseCode(); if (statusCode != HttpURLConnection.HTTP_OK) { System.err.println("Method failed: " + connection.getResponseMessage()); } // for (Header h : method.getResponseHeaders()) { // System.out.println("HDR: " + h.getName() + ": " + h.getValue()); // } String contentType = connection.getHeaderField("Content-Type"); if (contentType != null) { // System.out.println("Content-Type: " + contentType); if (contentType.equals(format)) { InputStream response = connection.getInputStream(); BufferedImage img = ImageIO.read(response); if (img == null) { throw new IIOException("ImageIO returned null, unable to decode stream as image data."); } return img; } } // Request failed, produce as much debug information as possible. StringBuilder sb = new StringBuilder(); sb.append("Response headers:\n"); for (String h : connection.getHeaderFields().keySet()) { sb.append(h); sb.append(": "); sb.append(connection.getHeaderField(h)); sb.append("\n"); } String response = connection.getContent().toString(); sb.append("Response body:\n"); sb.append(response); throw new ServiceException("WMS GetMap request failed: " + connection.getURL().toString() + "\n" + sb.toString()); } finally { // Release the connection. if (connection != null) connection.disconnect(); } } }