/*************************************************** * * cismet GmbH, Saarbruecken, Germany * * ... and it just works. * ****************************************************/ /* * To change this template, choose Tools | Templates * and open the template in the editor. */ package de.cismet.cismap.commons.raster.wms.googlemaps; import edu.umd.cs.piccolo.PNode; import java.math.BigDecimal; import de.cismet.cismap.commons.RetrievalServiceLayer; import de.cismet.cismap.commons.raster.wms.AbstractWMS; import de.cismet.cismap.commons.rasterservice.ImageRetrieval; import de.cismet.cismap.commons.rasterservice.RasterMapService; /** * DOCUMENT ME! * * @author hell * @version $Revision$, $Date$ */ public class GMService extends AbstractWMS implements RasterMapService, RetrievalServiceLayer { //~ Static fields/initializers --------------------------------------------- private static long TWO_TO_THIRTYTWO = 0x100000000L; private static double LONG_DEGREES_PER_PIXEL = 1.0759E-05D; private static double LAT_DEGREES_PER_PIXEL = 5.2499999999999997E-06D; private static double[] ZOOM_LEVELS = { 0.0D, 2D, 4D, 8D, 16D, 32D, 64D, 128D, 300D, 1000D }; //~ Instance fields -------------------------------------------------------- private final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(this.getClass()); private ImageRetrieval ir; private boolean enabled = true; private PNode pNode = new PNode(); //~ Methods ---------------------------------------------------------------- @Override public void retrieve(final boolean forced) { if (log.isDebugEnabled()) { log.debug("retrieve()"); // NOI18N } final GMBoundingBox real = new GMBoundingBox(); final String url = generateURL(new GMBoundingBox( new GMGISPosition(bb.getY1(), bb.getX1()), new GMGISPosition(bb.getY2(), bb.getX2())), width, height, real); if ((ir != null) && ir.isAlive() && ir.getUrl().equals(url.toString()) && !forced) { if (log.isDebugEnabled()) { // mach nix // mehrfachaufruf mit der gleichen url = unsinn log.debug("multiple invocations with the same url = humbug"); // NOI18N } } else { if ((ir != null) && ir.isAlive()) { ir.youngerWMSCall(); ir.interrupt(); // retrievalAborted(new RetrievalEvent()); // try { // ir.join(); // } // catch (InterruptedException iex){ // log.warn("ir.join() wurde unterbrochen",iex); // } } ir = new ImageRetrieval(this); ir.setUrl(url); if (log.isDebugEnabled()) { log.debug("ir.start();"); // NOI18N } ir.setPriority(Thread.NORM_PRIORITY); ir.start(); } } @Override public Object clone() { return new GMService(); } @Override public PNode getPNode() { return pNode; } @Override public void setPNode(final PNode pNode) { this.pNode = pNode; } @Override public boolean isEnabled() { return enabled; } @Override public void setEnabled(final boolean enabled) { this.enabled = enabled; ; } @Override public boolean canBeDisabled() { return true; } @Override public int getLayerPosition() { return -1; } @Override public void setLayerPosition(final int layerPosition) { } @Override public float getTranslucency() { return 0.5f; } @Override public void setTranslucency(final float t) { } @Override public String getName() { return "GM"; // NOI18N } @Override public void setName(final String name) { } /** * DOCUMENT ME! * * @param box DOCUMENT ME! * @param image_width DOCUMENT ME! * @param image_height DOCUMENT ME! * @param result DOCUMENT ME! * * @return DOCUMENT ME! */ public static String generateURL(final GMBoundingBox box, final int image_width, final int image_height, final GMBoundingBox result) { final GMGISPosition position = box.middle(); final double width = box.width(); String URL = null; int ZoomLevel = 1; double Magnification = 0.0D; double longtitude = (new BigDecimal(position.getLongitude())).setScale(6, 5).doubleValue(); double latitude = (new BigDecimal(position.getLatitude())).setScale(6, 5).doubleValue(); final double pixelwidth = (double)image_width * LONG_DEGREES_PER_PIXEL; if (width < pixelwidth) { Magnification = ZOOM_LEVELS[0]; } else if (width < (pixelwidth * ZOOM_LEVELS[1])) { Magnification = ZOOM_LEVELS[1]; } else if (width < (pixelwidth * ZOOM_LEVELS[2])) { Magnification = ZOOM_LEVELS[2]; } else if (width < (pixelwidth * ZOOM_LEVELS[3])) { Magnification = ZOOM_LEVELS[3]; } else if (width < (pixelwidth * ZOOM_LEVELS[4])) { Magnification = ZOOM_LEVELS[4]; } else if (width < (pixelwidth * ZOOM_LEVELS[5])) { Magnification = ZOOM_LEVELS[5]; } else if (width < (pixelwidth * ZOOM_LEVELS[6])) { Magnification = ZOOM_LEVELS[6]; } else if (width < (pixelwidth * ZOOM_LEVELS[7])) { Magnification = ZOOM_LEVELS[7]; } else if (width < (pixelwidth * ZOOM_LEVELS[8])) { Magnification = ZOOM_LEVELS[8]; } else { Magnification = ZOOM_LEVELS[9]; } ZoomLevel = (new Double((double)image_width * (1.0D + Magnification))).intValue(); longtitude *= 1000000D; latitude *= 1000000D; if (longtitude < 0.0D) { longtitude += TWO_TO_THIRTYTWO; } if (latitude < 0.0D) { latitude += TWO_TO_THIRTYTWO; } URL = "http://maps.google.com/mapdata?latitude_e6=" + (new BigDecimal(latitude)).setScale(0, 5) + "&longitude_e6=" + (new BigDecimal(longtitude)).setScale(0, 5) + "&zm=" + ZoomLevel + "&cc=us&min_priority=2&w=" + image_width + "&h=" + image_height; // NOI18N if (Magnification == 0.0D) { Magnification = 1.0D; } final double long_half = (double)(image_width / 2) * (LONG_DEGREES_PER_PIXEL * Magnification); final double dpp = 1.075E-05D * Math.cos((position.latitude * 3.1415926535897931D) / 180D); final double lat_half = (double)(image_height / 2) * (dpp * Magnification); final GMGISPosition topLeft = new GMGISPosition(position.latitude - lat_half, position.longitude - long_half); final GMGISPosition bottomRight = new GMGISPosition(position.latitude + lat_half, position.longitude + long_half); result.setBottomRight(bottomRight); result.setTopLeft(topLeft); return URL; } } /** * DOCUMENT ME! * * @version $Revision$, $Date$ */ class GMGISPosition { //~ Instance fields -------------------------------------------------------- double longitude; double latitude; double elevation; long timestamp; //~ Constructors ----------------------------------------------------------- /** * Creates a new GMGISPosition object. * * @param latitude DOCUMENT ME! * @param longitude DOCUMENT ME! */ public GMGISPosition(final double latitude, final double longitude) { this.longitude = longitude; this.latitude = latitude; } /** * Creates a new GMGISPosition object. * * @param latitude DOCUMENT ME! * @param longitude DOCUMENT ME! * @param elevation DOCUMENT ME! * @param timestamp DOCUMENT ME! */ public GMGISPosition(final double latitude, final double longitude, final double elevation, final long timestamp) { this.longitude = longitude; this.latitude = latitude; this.elevation = elevation; this.timestamp = timestamp; } //~ Methods ---------------------------------------------------------------- /** * DOCUMENT ME! * * @return DOCUMENT ME! */ public double getElevation() { return elevation; } /** * DOCUMENT ME! * * @param elevation DOCUMENT ME! */ public void setElevation(final double elevation) { this.elevation = elevation; } /** * DOCUMENT ME! * * @return DOCUMENT ME! */ public double getLatitude() { return latitude; } /** * DOCUMENT ME! * * @param latitude DOCUMENT ME! */ public void setLatitude(final double latitude) { this.latitude = latitude; } /** * DOCUMENT ME! * * @return DOCUMENT ME! */ public double getLongitude() { return longitude; } /** * DOCUMENT ME! * * @param longitude DOCUMENT ME! */ public void setLongitude(final double longitude) { this.longitude = longitude; } /** * DOCUMENT ME! * * @return DOCUMENT ME! */ public long getTimestamp() { return timestamp; } /** * DOCUMENT ME! * * @param timestamp DOCUMENT ME! */ public void setTimestamp(final long timestamp) { this.timestamp = timestamp; } } /** * DOCUMENT ME! * * @version $Revision$, $Date$ */ class GMBoundingBox { //~ Instance fields -------------------------------------------------------- private GMGISPosition topLeft; private GMGISPosition bottomRight; //~ Constructors ----------------------------------------------------------- /** * Creates a new GMBoundingBox object. */ public GMBoundingBox() { topLeft = null; bottomRight = null; } /** * Creates a new GMBoundingBox object. * * @param top DOCUMENT ME! * @param bottom DOCUMENT ME! */ public GMBoundingBox(final GMGISPosition top, final GMGISPosition bottom) { topLeft = null; bottomRight = null; topLeft = top; bottomRight = bottom; } //~ Methods ---------------------------------------------------------------- /** * DOCUMENT ME! * * @return DOCUMENT ME! */ public GMGISPosition getBottomRight() { return bottomRight; } /** * DOCUMENT ME! * * @param bottomRight DOCUMENT ME! */ public void setBottomRight(final GMGISPosition bottomRight) { this.bottomRight = bottomRight; } /** * DOCUMENT ME! * * @return DOCUMENT ME! */ public GMGISPosition getTopLeft() { return topLeft; } /** * DOCUMENT ME! * * @param topLeft DOCUMENT ME! */ public void setTopLeft(final GMGISPosition topLeft) { this.topLeft = topLeft; } /** * DOCUMENT ME! * * @return DOCUMENT ME! */ public GMGISPosition middle() { return middle(this); } /** * DOCUMENT ME! * * @param box DOCUMENT ME! * * @return DOCUMENT ME! */ public static GMGISPosition middle(final GMBoundingBox box) { final double west = box.getTopLeft().longitude; final double north = box.getTopLeft().latitude; final double east = box.getBottomRight().longitude; final double south = box.getBottomRight().latitude; double middlelat = -1D; double middlelong = -1D; if (north > south) { middlelat = north + ((south - north) / 2D); } else { middlelat = north + ((north - south) / 2D); } if (east > west) { middlelong = west + ((east - west) / 2D); } else { middlelong = west + ((west - east) / 2D); } return new GMGISPosition(middlelat, middlelong); } /** * DOCUMENT ME! * * @return DOCUMENT ME! */ public double width() { return width(this); } /** * DOCUMENT ME! * * @param box DOCUMENT ME! * * @return DOCUMENT ME! */ public static double width(final GMBoundingBox box) { final double west = box.getTopLeft().longitude; final double east = box.getBottomRight().longitude; double width = -1D; if (east > west) { width = east - west; } else { width = west - east; } return width; } /** * DOCUMENT ME! * * @return DOCUMENT ME! */ public double height() { return height(this); } /** * DOCUMENT ME! * * @param box DOCUMENT ME! * * @return DOCUMENT ME! */ public static double height(final GMBoundingBox box) { final double north = box.getTopLeft().latitude; final double south = box.getBottomRight().latitude; double height = -1D; if (north > south) { height = north - south; } else { height = south - north; } return height; } }