]> gerrit.simantics Code Review - simantics/district.git/blob - org.simantics.district.maps/src/org/simantics/maps/osm/OSMTileProvider.java
Share some projects for Simantics District
[simantics/district.git] / org.simantics.district.maps / src / org / simantics / maps / osm / OSMTileProvider.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.osm;
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 import org.simantics.maps.wms.ServiceException;
32
33 /**
34  * @author Tuukka Lehtonen
35  * @see OSMGetMapQuery
36  */
37 public class OSMTileProvider implements ITileProvider {
38
39     private WebService  service;
40
41     private int      tileSize;
42
43     public OSMTileProvider(WebService service, int tileSize) {
44         this.service = service;
45         this.tileSize = tileSize;
46     }
47
48     @Override
49     public URI getSource() {
50         return service.getURI();
51     }
52
53     @Override
54     public Rectangle2D getExtent() {
55         return new Rectangle2D.Double(-180, -90, 360, 180);
56     }
57
58     @Override
59     public Image get(TileKey key) throws ProvisionException {
60         int level = key.getLevel();
61         int x = key.getX();
62         int y = key.getY();
63
64         double xTiles = Math.pow(2, level + 1);
65         double yTiles = Math.pow(2, level);
66
67         if (level < 0)
68             throw new IllegalArgumentException("invalid tile level " + level + " (tile=" + key +")");
69         if (x < 0 || x >= (int) xTiles)
70             throw new IllegalArgumentException("tile x out of bounds " + x + " (tile=" + key +")");
71         if (y < 0 || y >= (int) yTiles)
72             throw new IllegalArgumentException("tile y out of bounds " + y + " (tile=" + key +")");
73
74         try {
75             Rectangle2D r = new Rectangle2D.Double(x, y, 10, 10);
76
77 //            System.out.println("TileProvider: requesting " + key + ", bbox=" + r + ", size=" + tileSize);
78             BufferedImage img = getMap(service, tileSize, tileSize, r, "image/png", level);//layers);
79 //            System.out.println("TileProvider: response: " + img);
80             return img;
81         } catch (MalformedURLException e) {
82             throw new ProvisionException(e);
83         } catch (IOException e) {
84             throw new ProvisionException(e);
85         }
86     }
87
88     
89     /**
90      * Get a bufferedimage of the map data for the geographical coordinates.
91      * 
92      * @param x
93      * @param y
94      * @param z
95      * @return
96      * @throws MalformedURLException 
97      */
98     public static BufferedImage getMap(WebService service, Dimension rasterSize, Rectangle2D bbox, String format, int level) throws MalformedURLException, IOException {
99         return getMap(service, rasterSize.width, rasterSize.height, bbox, format, level);
100     }
101
102     /**
103      * Get a bufferedimage of the map data for the geographical coordinates.
104      * 
105      * @param x
106      * @param y
107      * @param z
108      * @return
109      * @throws MalformedURLException 
110      */
111     public static BufferedImage getMap(WebService service, int rasterWidth, int rasterHeight, Rectangle2D bbox, String format, int level) throws MalformedURLException, IOException {
112         if (rasterWidth == 0 || rasterHeight == 0)
113             return new BufferedImage(0, 0, BufferedImage.TYPE_INT_ARGB);
114
115         HttpURLConnection connection = null;
116         try {
117             connection = service.openConnection(("" + level + "/" + Math.round(bbox.getMinX()) + "/" + Math.round(bbox.getMinY())+".png"), null);
118
119             // Execute the method.
120             int statusCode = connection.getResponseCode();
121
122             if (statusCode != HttpURLConnection.HTTP_OK) {
123                 System.err.println("Method failed: " + connection.getResponseMessage());
124             }
125
126 //            for (Header h : method.getResponseHeaders()) {
127 //                System.out.println("HDR: " + h.getName() + ": " + h.getValue());
128 //            }
129
130             String contentType = connection.getHeaderField("Content-Type");
131             if (contentType != null) {
132 //                System.out.println("Content-Type: " + contentType);
133                 if (contentType.equals(format)) {
134                     InputStream response = connection.getInputStream();
135                     BufferedImage img = ImageIO.read(response);
136                     if (img == null) {
137                         throw new IIOException("ImageIO returned null, unable to decode stream as image data.");
138                     }
139                     return img;
140                 }
141             }
142
143             // Request failed,  produce as much debug information as possible.
144             StringBuilder sb = new StringBuilder();
145             sb.append("Response headers:\n");
146             for (String h : connection.getHeaderFields().keySet()) {
147                 sb.append(h);
148                 sb.append(": ");
149                 sb.append(connection.getHeaderField(h));
150                 sb.append("\n");
151             }
152             String response = connection.getContent().toString();
153             sb.append("Response body:\n");
154             sb.append(response);
155             throw new ServiceException("WMS GetMap request failed: " + connection.getURL().toString() + "\n" + sb.toString());
156         } finally {
157             // Release the connection.
158             if (connection != null)
159                 connection.disconnect();
160         }
161     }
162
163 }