]> gerrit.simantics Code Review - simantics/district.git/blob - org.simantics.district.maps/src/org/simantics/maps/wms/WMSTileProvider.java
Share some projects for Simantics District
[simantics/district.git] / org.simantics.district.maps / src / org / simantics / maps / wms / WMSTileProvider.java
1 /*******************************************************************************
2  * Copyright (c) 2012 Association for Decentralized Information Management
3  * in Industry THTH ry.
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
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.maps.wms;
13
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;
22 import java.net.URI;
23
24 import javax.imageio.IIOException;
25 import javax.imageio.ImageIO;
26
27 import org.simantics.maps.ProvisionException;
28 import org.simantics.maps.WebService;
29 import org.simantics.maps.tile.ITileProvider;
30 import org.simantics.maps.tile.TileKey;
31
32 /**
33  * @author Tuukka Lehtonen
34  */
35 public class WMSTileProvider implements ITileProvider {
36
37     private WebService  service;
38
39     private int      tileSize;
40
41     private String[] layers;
42
43     public WMSTileProvider(WebService service, int tileSize, String... layers) {
44         this.service = service;
45         this.tileSize = tileSize;
46         this.layers = layers;
47     }
48
49     @Override
50     public URI getSource() {
51         return service.getURI();
52     }
53
54     @Override
55     public Rectangle2D getExtent() {
56         return new Rectangle2D.Double(-180, -90, 360, 180);
57     }
58
59     @Override
60     public Image get(TileKey key) throws ProvisionException {
61         int level = key.getLevel();
62         int x = key.getX();
63         int y = key.getY();
64
65         double xTiles = Math.pow(2, level + 1);
66         double yTiles = Math.pow(2, level);
67
68         if (level < 0)
69             throw new IllegalArgumentException("invalid tile level " + level + " (tile=" + key +")");
70         if (x < 0 || x >= (int) xTiles)
71             throw new IllegalArgumentException("tile x out of bounds " + x + " (tile=" + key +")");
72         if (y < 0 || y >= (int) yTiles)
73             throw new IllegalArgumentException("tile y out of bounds " + y + " (tile=" + key +")");
74
75         try {
76             Rectangle2D r = new Rectangle2D.Double();
77
78             double minx = -180;
79             double miny = -90;
80             double w = 360;
81             double h = 180;
82
83             double xdelta = w / xTiles;
84             double ydelta = h / yTiles;
85             double xx = x;
86             double yy = yTiles - y - 1;
87
88             r.setFrame(
89                     minx + xdelta*xx,
90                     miny + ydelta*yy,
91                     xdelta,
92                     ydelta
93             );
94
95 //            System.out.println("TileProvider: requesting " + key + ", bbox=" + r + ", size=" + tileSize);
96             BufferedImage img = getMap(service, tileSize, tileSize, r, "image/jpeg", layers);
97 //            System.out.println("TileProvider: response: " + img);
98             return img;
99         } catch (MalformedURLException e) {
100             throw new ProvisionException(e);
101         } catch (IOException e) {
102             throw new ProvisionException(e);
103         }
104     }
105     
106     /**
107      * Get a bufferedimage of the map data for the geographical coordinates.
108      * 
109      * @param x
110      * @param y
111      * @param z
112      * @return
113      * @throws MalformedURLException 
114      */
115     public static BufferedImage getMap(WebService service, Dimension rasterSize, Rectangle2D bbox, String format, String... layers) throws MalformedURLException, IOException {
116         return getMap(service, rasterSize.width, rasterSize.height, bbox, format, layers);
117     }
118
119     /**
120      * Get a bufferedimage of the map data for the geographical coordinates.
121      * 
122      * @param x
123      * @param y
124      * @param z
125      * @return
126      * @throws MalformedURLException 
127      */
128     public static BufferedImage getMap(WebService service, int rasterWidth, int rasterHeight, Rectangle2D bbox, String format, String... layers) throws MalformedURLException, IOException {
129         if (rasterWidth == 0 || rasterHeight == 0)
130             return new BufferedImage(0, 0, BufferedImage.TYPE_INT_ARGB);
131
132         // Create a method instance.
133         WMSGetMapQuery req = new WMSGetMapQuery(rasterWidth, rasterHeight, bbox, format, layers);
134 //        req.setStyles("visual");
135
136 //        String requestUrl = service.getRequestURL("", req.toString());
137 //        System.out.println("REQUEST: " + requestUrl);
138
139         HttpURLConnection connection = null;
140         try {
141                 connection = service.openConnection("", req.toString());
142             // Execute the method.
143             int statusCode = connection.getResponseCode();
144
145             if (statusCode != HttpURLConnection.HTTP_OK) {
146                 System.err.println("Method failed: " + connection.getResponseMessage());
147             }
148
149 //            for (Header h : method.getResponseHeaders()) {
150 //                System.out.println("HDR: " + h.getName() + ": " + h.getValue());
151 //            }
152
153             String contentType = connection.getHeaderField("Content-Type");
154             if (contentType != null) {
155 //                System.out.println("Content-Type: " + contentType);
156                 if (contentType.equals(format)) {
157                     InputStream response = connection.getInputStream();
158                     BufferedImage img = ImageIO.read(response);
159                     if (img == null) {
160                         throw new IIOException("ImageIO returned null, unable to decode stream as image data.");
161                     }
162                     return img;
163                 }
164             }
165
166             // Request failed,  produce as much debug information as possible.
167             StringBuilder sb = new StringBuilder();
168             for (String h : connection.getHeaderFields().keySet()) {
169                 sb.append(h);
170                 sb.append(": ");
171                 sb.append(connection.getHeaderField(h));
172                 sb.append("\n");
173             }
174             String response = connection.getContent().toString();
175             sb.append("Response body:\n");
176             sb.append(response);
177             throw new ServiceException("WMS GetMap request failed: " + connection.getURL().toString() + "\n" + sb.toString());
178         } finally {
179             // Release the connection.
180             connection.disconnect();
181         }
182     }
183
184 }