]> gerrit.simantics Code Review - simantics/district.git/blobdiff - 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
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 (file)
index 0000000..60e0206
--- /dev/null
@@ -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();
+        }
+    }
+
+}