--- /dev/null
+/*******************************************************************************
+ * 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.tile;
+
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.Image;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.imageio.ImageIO;
+
+import org.simantics.maps.ProvisionException;
+
+/**
+ * @author Tuukka Lehtonen
+ * @deprecated this is a demo hack, do not use
+ */
+public class Shp2ImgTileProvider implements ITileProvider {
+
+ private static final String SHP2IMG_EXECUTABLE = "c:\\ms4w\\tools\\mapserv\\shp2img.exe";
+
+ private static final String SCHEME = "shp2img";
+
+ final URI source;
+
+ final File mapDirectory;
+
+ final String mapName;
+
+ final int tilePixelSize;
+
+ final String tileSizeString;
+
+ Rectangle2D extentDegrees;
+
+ Rectangle2D extentMeters;
+
+ double deWidthRecip;
+
+ double deHeightRecip;
+
+ String[] ENVP = null;
+
+ BufferedImage outOfBoundsImage;
+
+ public Shp2ImgTileProvider(String mapDirectory, String mapName, int tilePixelSize, Rectangle2D extentDegrees, Rectangle2D extentMeters) {
+ this.mapDirectory = new File(mapDirectory);
+ this.mapName = mapName;
+ this.tilePixelSize = tilePixelSize;
+ this.tileSizeString = String.valueOf(tilePixelSize);
+ this.extentDegrees = extentDegrees;
+ this.extentMeters = extentMeters;
+
+ this.deWidthRecip = 1.0 / extentDegrees.getWidth();
+ this.deHeightRecip = 1.0 / extentDegrees.getHeight();
+
+ if (!this.mapDirectory.exists()) {
+ throw new IllegalArgumentException("Map directory '" + mapDirectory + "' does not exist");
+ }
+
+ StringBuilder host = new StringBuilder();
+ boolean first = true;
+ String[] segments = mapDirectory.split(File.pathSeparator);
+ for (String seg : segments) {
+ if (!first)
+ host.append('.');
+ first = false;
+ host.append(seg);
+ }
+ host.append('.');
+ host.append(mapName);
+
+ try {
+ source = new URI(SCHEME, host.toString(), null, null);
+ } catch (URISyntaxException e) {
+ throw new RuntimeException("Shp2ImgTileProvider: Problem in URI generation with mapDirectory="
+ + mapDirectory + ", mapName= " + mapName, e);
+ }
+
+ List<String> envp = new ArrayList<String>();
+ envp.add("GDAL_DATA=c:\\ms4w\\gdaldata");
+ envp.add("GDAL_DRIVER_PATH=c:\\ms4w\\gdalplugins");
+ envp.add("PROJ_LIB=c:\\ms4w\\proj\\nad");
+ envp.add("PATH=c:\\ms4w\\Apache\\cgi-bin;c:\\ms4w\\tools\\gdal-ogr;c:\\ms4w\\tools\\mapserv;c:\\ms4w\\tools\\shapelib;c:\\ms4w\\proj\\bin;c:\\ms4w\\tools\\shp2tile;c:\\ms4w\\tools\\shpdiff;c:\\ms4w\\tools\\avce00;c:\\ms4w\\tools\\demtools;");
+ ENVP = envp.toArray(new String[0]);
+
+// Iterator<ImageReader> readers = ImageIO.getImageReadersByFormatName("png");
+// ImageReader reader = readers.next();
+ }
+
+ @Override
+ public URI getSource() {
+ return source;
+ }
+
+ @Override
+ public Rectangle2D getExtent() {
+ // FIXME: should return a clone
+ return extentDegrees;
+ }
+
+ @Override
+ public Image get(TileKey key) throws ProvisionException {
+ // TODO: make this code a utility and externalize the remaining logic as a strategy
+ // This very same code is the same in all ITileProvider implementations.
+
+ 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 +")");
+
+ 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
+ );
+
+ if (r.intersects(extentDegrees)) {
+ Rectangle2D meters = transformDegreesToMeters(r);
+// System.out.println("getImage: " + meters.getMinX() + ", " + meters.getMaxX() + ", " + meters.getWidth() + " ... " + meters.getMinY() + ", " + meters.getMaxY() + ", " + meters.getHeight());
+ try {
+ return getImage(meters);
+ } catch (IOException e) {
+ throw new ProvisionException(e);
+ }
+ }
+
+ return getOutOfBoundsImage();
+ }
+
+ private Image getOutOfBoundsImage() {
+ if (outOfBoundsImage != null)
+ return outOfBoundsImage;
+
+ final int outOfBoundsImageSize = 1;
+ BufferedImage image = new BufferedImage(outOfBoundsImageSize, outOfBoundsImageSize, BufferedImage.TYPE_3BYTE_BGR);
+ Graphics2D g = image.createGraphics();
+ try {
+ g.setColor(Color.PINK);
+ g.fillRect(0, 0, outOfBoundsImageSize, outOfBoundsImageSize);
+ outOfBoundsImage = image;
+ return image;
+ } finally {
+ g.dispose();
+ }
+ }
+
+ private Rectangle2D transformDegreesToMeters(Rectangle2D r) {
+ double nx1 = (r.getMinX() - extentDegrees.getMinX()) * deWidthRecip;
+ double ny1 = (r.getMinY() - extentDegrees.getMinY()) * deHeightRecip;
+ double nx2 = (r.getMaxX() - extentDegrees.getMinX()) * deWidthRecip;
+ double ny2 = (r.getMaxY() - extentDegrees.getMinY()) * deHeightRecip;
+ double dw = extentMeters.getWidth();
+ double dh = extentMeters.getHeight();
+ Rectangle2D result = new Rectangle2D.Double();
+ result.setFrameFromDiagonal(
+ extentMeters.getMinX() + nx1 * dw,
+ extentMeters.getMinY() + ny1 * dh,
+ extentMeters.getMinX() + nx2 * dw,
+ extentMeters.getMinY() + ny2 * dh
+ );
+ return result;
+ }
+
+ private BufferedImage getImage(Rectangle2D r) throws IOException {
+ double w = r.getWidth();
+ double h = r.getHeight();
+ String tileSizeStringX;
+ String tileSizeStringY;
+ if (w > h) {
+ tileSizeStringX = tileSizeString;
+ tileSizeStringY = "" + (int) Math.round(((double)tilePixelSize) * (h/w));
+ } else {
+ tileSizeStringX = "" + (int) Math.round(((double)tilePixelSize) * (w/h));
+ tileSizeStringY = tileSizeString;
+ }
+
+ File tempFile = File.createTempFile("map", ".png");
+ String[] cmd = new String[] {
+ SHP2IMG_EXECUTABLE,
+// "-all_debug",
+// "5",
+ "-m",
+ mapName,
+ "-o",
+ tempFile.getAbsolutePath(),
+ "-s",
+ tileSizeStringX,
+ tileSizeStringY,
+ "-e",
+ String.valueOf(r.getMinX()),
+ String.valueOf(r.getMinY()),
+ String.valueOf(r.getMaxX()),
+ String.valueOf(r.getMaxY())
+ };
+ try {
+ try {
+// System.out.println(System.currentTimeMillis() + " TEMP FILE: " + tempFile);
+// System.out.println(System.currentTimeMillis() + " EXEC: " + Arrays.toString(cmd));
+// System.out.println(System.currentTimeMillis() + " EXEC: " + Arrays.toString(ENVP));
+// System.out.println(System.currentTimeMillis() + " EXEC: " + mapDirectory);
+ Process p = Runtime.getRuntime().exec(cmd, ENVP, mapDirectory);
+ int result = p.waitFor();
+// System.out.println(System.currentTimeMillis() + " PROCESS EXITED: " + result);
+ if (result != 0)
+ throw new ProvisionException(SHP2IMG_EXECUTABLE + " returned error code: " + result);
+ //Thread.sleep(500);
+ BufferedImage img = ImageIO.read(tempFile);
+ //System.out.println("img = " + img);
+ if (img == null)
+ throw new ProvisionException("Failed to provide image for rectangle: " + r);
+
+ if (BufferedImage.TYPE_4BYTE_ABGR != img.getType()) {
+ BufferedImage img2 = new BufferedImage(img.getWidth(), img.getHeight(), BufferedImage.TYPE_4BYTE_ABGR);
+ img.copyData(img2.getRaster());
+ return img2;
+ }
+ return img;
+ } finally {
+ if (tempFile.exists()) {
+// System.out.println("DELETING TEMP FILE: " + tempFile);
+ tempFile.delete();
+ }
+ }
+ } catch (IOException e) {
+ throw new ProvisionException(e);
+ } catch (InterruptedException e) {
+ throw new ProvisionException(e);
+ }
+ }
+
+ public static void main(String[] args) {
+ try {
+ Rectangle2D degreeExtent = new Rectangle2D.Double();
+ Rectangle2D meterExtent = new Rectangle2D.Double();
+ degreeExtent.setFrameFromDiagonal(24.8, 60.175, 24.84, 60.195);
+ meterExtent.setFrameFromDiagonal(2544800, 6674000, 2546842.4, 6676000);
+
+ Shp2ImgTileProvider p = new Shp2ImgTileProvider("d:/TerrasolidOtaniemiMalli/ortho", "global.map", 512, degreeExtent, meterExtent);
+
+ BufferedImage buf = p.getImage(meterExtent);
+ ImageIO.write(buf, "png", new File("d:\\temp\\test.png"));
+ } catch (Throwable e) {
+ e.printStackTrace();
+ }
+ }
+
+}