X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=org.simantics.district.maps%2Fsrc%2Forg%2Fsimantics%2Fmaps%2Fwms%2FWMSTileProvider.java;fp=org.simantics.district.maps%2Fsrc%2Forg%2Fsimantics%2Fmaps%2Fwms%2FWMSTileProvider.java;h=60e020679722e5c2483ba40db577100ab886bddb;hb=e9f74f09e0cedb603c0b4de9e542de8dd64a5ce3;hp=0000000000000000000000000000000000000000;hpb=16ee01dc5a40981c58fd5b478b89552e5814e8bb;p=simantics%2Fdistrict.git diff --git a/org.simantics.district.maps/src/org/simantics/maps/wms/WMSTileProvider.java b/org.simantics.district.maps/src/org/simantics/maps/wms/WMSTileProvider.java new file mode 100644 index 00000000..60e02067 --- /dev/null +++ b/org.simantics.district.maps/src/org/simantics/maps/wms/WMSTileProvider.java @@ -0,0 +1,184 @@ +/******************************************************************************* + * 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.wms; + +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; + +/** + * @author Tuukka Lehtonen + */ +public class WMSTileProvider implements ITileProvider { + + private WebService service; + + private int tileSize; + + private String[] layers; + + public WMSTileProvider(WebService service, int tileSize, String... layers) { + this.service = service; + this.tileSize = tileSize; + this.layers = layers; + } + + @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(); + + double minx = -180; + double miny = -90; + double w = 360; + double h = 180; + + double xdelta = w / xTiles; + double ydelta = h / yTiles; + double xx = x; + double yy = yTiles - y - 1; + + r.setFrame( + minx + xdelta*xx, + miny + ydelta*yy, + xdelta, + ydelta + ); + +// System.out.println("TileProvider: requesting " + key + ", bbox=" + r + ", size=" + tileSize); + BufferedImage img = getMap(service, tileSize, tileSize, r, "image/jpeg", 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, String... layers) throws MalformedURLException, IOException { + return getMap(service, rasterSize.width, rasterSize.height, bbox, format, layers); + } + + /** + * 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, String... layers) throws MalformedURLException, IOException { + if (rasterWidth == 0 || rasterHeight == 0) + return new BufferedImage(0, 0, BufferedImage.TYPE_INT_ARGB); + + // Create a method instance. + WMSGetMapQuery req = new WMSGetMapQuery(rasterWidth, rasterHeight, bbox, format, layers); +// req.setStyles("visual"); + +// String requestUrl = service.getRequestURL("", req.toString()); +// System.out.println("REQUEST: " + requestUrl); + + HttpURLConnection connection = null; + try { + connection = service.openConnection("", req.toString()); + // 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(); + 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. + connection.disconnect(); + } + } + +}