1 /*******************************************************************************
2 * Copyright (c) 2012 Association for Decentralized Information Management
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * VTT Technical Research Centre of Finland - initial API and implementation
11 *******************************************************************************/
12 package org.simantics.maps.wms;
14 import java.awt.Dimension;
15 import java.awt.Image;
16 import java.awt.geom.Rectangle2D;
17 import java.awt.image.BufferedImage;
18 import java.io.IOException;
19 import java.io.InputStream;
20 import java.net.HttpURLConnection;
21 import java.net.MalformedURLException;
24 import javax.imageio.IIOException;
25 import javax.imageio.ImageIO;
27 import org.simantics.maps.ProvisionException;
28 import org.simantics.maps.WebService;
29 import org.simantics.maps.internal.ImageUtil;
30 import org.simantics.maps.tile.ITileProvider;
31 import org.simantics.maps.tile.TileKey;
34 * @author Tuukka Lehtonen
36 public class WMSTileProvider implements ITileProvider {
38 private WebService service;
42 private String[] layers;
44 public WMSTileProvider(WebService service, int tileSize, String... layers) {
45 this.service = service;
46 this.tileSize = tileSize;
51 public URI getSource() {
52 return service.getURI();
56 public Rectangle2D getExtent() {
57 return new Rectangle2D.Double(-180, -90, 360, 180);
61 public Image get(TileKey key) throws ProvisionException {
62 int level = key.getLevel();
66 double xTiles = Math.pow(2, level + 1);
67 double yTiles = Math.pow(2, level);
70 throw new IllegalArgumentException("invalid tile level " + level + " (tile=" + key +")");
71 if (x < 0 || x >= (int) xTiles)
72 throw new IllegalArgumentException("tile x out of bounds " + x + " (tile=" + key +")");
73 if (y < 0 || y >= (int) yTiles)
74 throw new IllegalArgumentException("tile y out of bounds " + y + " (tile=" + key +")");
77 Rectangle2D r = new Rectangle2D.Double();
84 double xdelta = w / xTiles;
85 double ydelta = h / yTiles;
87 double yy = yTiles - y - 1;
96 // System.out.println("TileProvider: requesting " + key + ", bbox=" + r + ", size=" + tileSize);
97 BufferedImage img = getMap(service, tileSize, tileSize, r, "image/jpeg", layers);
98 // System.out.println("TileProvider: response: " + img);
100 } catch (MalformedURLException e) {
101 throw new ProvisionException(e);
102 } catch (IOException e) {
103 throw new ProvisionException(e);
108 * Get a bufferedimage of the map data for the geographical coordinates.
114 * @throws MalformedURLException
116 public static BufferedImage getMap(WebService service, Dimension rasterSize, Rectangle2D bbox, String format, String... layers) throws MalformedURLException, IOException {
117 return getMap(service, rasterSize.width, rasterSize.height, bbox, format, layers);
121 * Get a bufferedimage of the map data for the geographical coordinates.
127 * @throws MalformedURLException
129 public static BufferedImage getMap(WebService service, int rasterWidth, int rasterHeight, Rectangle2D bbox, String format, String... layers) throws MalformedURLException, IOException {
130 if (rasterWidth == 0 || rasterHeight == 0)
131 return new BufferedImage(0, 0, BufferedImage.TYPE_INT_ARGB);
133 // Create a method instance.
134 WMSGetMapQuery req = new WMSGetMapQuery(rasterWidth, rasterHeight, bbox, format, layers);
135 // req.setStyles("visual");
137 // String requestUrl = service.getRequestURL("", req.toString());
138 // System.out.println("REQUEST: " + requestUrl);
140 HttpURLConnection connection = null;
142 connection = service.openConnection("", req.toString());
143 // Execute the method.
144 int statusCode = connection.getResponseCode();
146 if (statusCode != HttpURLConnection.HTTP_OK) {
147 System.err.println("Method failed: " + connection.getResponseMessage());
150 // for (Header h : method.getResponseHeaders()) {
151 // System.out.println("HDR: " + h.getName() + ": " + h.getValue());
154 String contentType = connection.getHeaderField("Content-Type");
155 if (contentType != null) {
156 // System.out.println("Content-Type: " + contentType);
157 if (contentType.equals(format)) {
158 InputStream response = connection.getInputStream();
159 BufferedImage img = ImageIO.read(response);
161 throw new IIOException("ImageIO returned null, unable to decode stream as image data.");
163 return ImageUtil.toScreenCompatibleImage(img);
167 // Request failed, produce as much debug information as possible.
168 StringBuilder sb = new StringBuilder();
169 for (String h : connection.getHeaderFields().keySet()) {
172 sb.append(connection.getHeaderField(h));
175 String response = connection.getContent().toString();
176 sb.append("Response body:\n");
178 throw new ServiceException("WMS GetMap request failed: " + connection.getURL().toString() + "\n" + sb.toString());
180 // Release the connection.
181 connection.disconnect();