package org.simantics.maps.sg; import java.awt.Color; import java.awt.Composite; import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics2D; import java.awt.geom.AffineTransform; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import org.simantics.g2d.participant.MouseUtil; import org.simantics.g2d.participant.MouseUtil.MouseInfo; import org.simantics.maps.elevation.server.SingletonTiffTileInterface; import org.simantics.maps.sg.Formatting.FormatMode; public class MapLocationInfoNode extends MapInfoNode { private static final long serialVersionUID = 7994492218791569147L; private static final transient int MAX_DIGITS = 7; private static final transient int MAX_Z_DECIMALS = 2; private static final transient double TRIM_THRESHOLD_MAX_VALUE = Math.pow(10, 4); private static final transient double TEXT_RIGHT_MARGIN = 20; private MouseUtil mouse; @Override public void render(Graphics2D g2d) { if (!enabled || mouse == null) return; AffineTransform ot = g2d.getTransform(); g2d.setTransform(new AffineTransform()); Rectangle2D bounds = g2d.getClipBounds(); if (bounds == null) return; // FIXME MouseInfo mouseInfo = mouse.getMouseInfo(0); double startLat; double startLon; if (mouseInfo != null && mouseInfo.canvasPosition != null) { Point2D canvasPosition = mouseInfo.canvasPosition; double cx = canvasPosition.getX(); double cy = canvasPosition.getY(); startLat = yToLatitude(-cy / transform.getScaleY()); startLon = xToLongitude(cx / transform.getScaleX()); } else { startLat = 0; startLon = 0; } Number z = SingletonTiffTileInterface.lookup(startLat, startLon); String str = "X: " + Formatting.formatValue(startLon, MAX_DIGITS, false, FormatMode.LIMIT_DIGITS, TRIM_THRESHOLD_MAX_VALUE) + " Y: " + Formatting.formatValue(startLat, MAX_DIGITS, false, FormatMode.LIMIT_DIGITS, TRIM_THRESHOLD_MAX_VALUE) + " Z: " + Formatting.formatValue(z.doubleValue(), MAX_Z_DECIMALS, false, FormatMode.LIMIT_DECIMALS, TRIM_THRESHOLD_MAX_VALUE); Font font = MapInfoConstants.getInfoFont(); g2d.setFont(font); FontMetrics fm = g2d.getFontMetrics(); Rectangle2D r = fm.getStringBounds(str, g2d); double yOffsetFromBottom = getMapInfoNextY(g2d); double frameMaxY = bounds.getMaxY() - yOffsetFromBottom; double frameMinY = frameMaxY - font.getSize() - 2 * MapInfoConstants.TEXT_VERTICAL_MARGIN; double frameWidth = r.getWidth() + MapInfoConstants.TEXT_HORIZONTAL_MARGIN * 2; double frameMaxX = bounds.getMaxX() - TEXT_RIGHT_MARGIN; double frameMinX = frameMaxX - frameWidth; double textY = frameMinY + MapInfoConstants.TEXT_VERTICAL_MARGIN + fm.getMaxAscent(); Composite oc = g2d.getComposite(); g2d.setComposite(MapInfoConstants.INFO_COMPOSITE); g2d.setStroke(MapInfoConstants.INFO_STROKE); g2d.setColor(MapInfoConstants.TEXT_BG_COLOR); rect.setFrame(frameMinX, frameMinY, frameWidth, frameMaxY - frameMinY); g2d.fill(rect); g2d.setColor(Color.BLACK); g2d.drawString(str, (int) frameMinX + MapInfoConstants.TEXT_HORIZONTAL_MARGIN, (int) textY); g2d.setComposite(oc); g2d.setTransform(ot); setMapInfoNextY(g2d, yOffsetFromBottom + rect.getHeight() + MapInfoConstants.INFO_ROW_SPACING); } public void setMouseUtil(MouseUtil util) { this.mouse = util; } // TODO: these only work with Spherical Mercator private static double xToLongitude(double x) { return x; } private static double yToLatitude(double y) { double rad = Math.toRadians(y); double sinh = Math.sinh(rad); double atan = Math.atan(sinh); double finald = Math.toDegrees(atan); return finald; } }