--- /dev/null
+/*******************************************************************************
+ * 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();
+ }
+ }
+
+}