]> gerrit.simantics Code Review - simantics/district.git/blob - org.simantics.district.maps/src/org/simantics/maps/sg/MapLocationInfoNode.java
Optimization of district scene graph node rendering
[simantics/district.git] / org.simantics.district.maps / src / org / simantics / maps / sg / MapLocationInfoNode.java
1 package org.simantics.maps.sg;
2
3 import java.awt.Color;
4 import java.awt.Composite;
5 import java.awt.Font;
6 import java.awt.FontMetrics;
7 import java.awt.Graphics2D;
8 import java.awt.geom.AffineTransform;
9 import java.awt.geom.Point2D;
10 import java.awt.geom.Rectangle2D;
11
12 import org.simantics.g2d.participant.MouseUtil;
13 import org.simantics.g2d.participant.MouseUtil.MouseInfo;
14 import org.simantics.maps.elevation.server.SingletonTiffTileInterface;
15 import org.simantics.maps.sg.Formatting.FormatMode;
16
17 public class MapLocationInfoNode extends MapInfoNode {
18
19     private static final long serialVersionUID = 7994492218791569147L;
20
21     private static final transient int    MAX_DIGITS = 7;
22     private static final transient int    MAX_Z_DECIMALS = 2;
23     private static final transient double TRIM_THRESHOLD_MAX_VALUE = Math.pow(10, 4);
24     private static final transient double TEXT_RIGHT_MARGIN = 20;
25
26     private MouseUtil mouse;
27
28     @Override
29     public void render(Graphics2D g2d) {
30         if (!enabled || mouse == null)
31             return;
32
33         AffineTransform ot = g2d.getTransform();
34         g2d.setTransform(new AffineTransform());
35
36         Rectangle2D bounds = g2d.getClipBounds();
37         if (bounds == null)
38             return; // FIXME
39
40         MouseInfo mouseInfo = mouse.getMouseInfo(0);
41
42         double startLat;
43         double startLon;
44         if (mouseInfo != null && mouseInfo.canvasPosition != null) {
45             Point2D canvasPosition = mouseInfo.canvasPosition;
46             double cx = canvasPosition.getX();
47             double cy = canvasPosition.getY();
48             startLat = yToLatitude(-cy / transform.getScaleY());
49             startLon = xToLongitude(cx / transform.getScaleX());
50         } else {
51             startLat = 0;
52             startLon = 0;
53         }
54
55         Number z = SingletonTiffTileInterface.lookup(startLat, startLon);
56
57         String str = "X: " + Formatting.formatValue(startLon, MAX_DIGITS, false, FormatMode.LIMIT_DIGITS, TRIM_THRESHOLD_MAX_VALUE) +
58                 "   Y: " + Formatting.formatValue(startLat, MAX_DIGITS, false, FormatMode.LIMIT_DIGITS, TRIM_THRESHOLD_MAX_VALUE) +
59                 "   Z: " + Formatting.formatValue(z.doubleValue(), MAX_Z_DECIMALS, false, FormatMode.LIMIT_DECIMALS, TRIM_THRESHOLD_MAX_VALUE);
60
61         Font font = MapInfoConstants.getInfoFont();
62         g2d.setFont(font);
63         FontMetrics fm = g2d.getFontMetrics();
64
65         Rectangle2D r = fm.getStringBounds(str, g2d);
66
67         double yOffsetFromBottom = getMapInfoNextY(g2d);
68         double frameMaxY = bounds.getMaxY() - yOffsetFromBottom;
69         double frameMinY = frameMaxY - font.getSize() - 2 * MapInfoConstants.TEXT_VERTICAL_MARGIN;
70         double frameWidth = r.getWidth() + MapInfoConstants.TEXT_HORIZONTAL_MARGIN * 2;
71         double frameMaxX = bounds.getMaxX() - TEXT_RIGHT_MARGIN;
72         double frameMinX = frameMaxX - frameWidth;
73         double textY = frameMinY + MapInfoConstants.TEXT_VERTICAL_MARGIN + fm.getMaxAscent();
74
75         Composite oc = g2d.getComposite();
76         g2d.setComposite(MapInfoConstants.INFO_COMPOSITE);
77         g2d.setStroke(MapInfoConstants.INFO_STROKE);
78
79         g2d.setColor(MapInfoConstants.TEXT_BG_COLOR);
80         rect.setFrame(frameMinX, frameMinY, frameWidth, frameMaxY - frameMinY);
81         g2d.fill(rect);
82
83         g2d.setColor(Color.BLACK);
84         g2d.drawString(str, (int) frameMinX + MapInfoConstants.TEXT_HORIZONTAL_MARGIN, (int) textY);
85
86         g2d.setComposite(oc);
87         g2d.setTransform(ot);
88
89         setMapInfoNextY(g2d, yOffsetFromBottom + rect.getHeight() + MapInfoConstants.INFO_ROW_SPACING);
90     }
91
92     public void setMouseUtil(MouseUtil util) {
93         this.mouse = util;
94     }
95
96     // TODO: these only work with Spherical Mercator
97     private static double xToLongitude(double x) {
98         return x;
99     }
100
101     private static double yToLatitude(double y) {
102         double rad = Math.toRadians(y);
103         double sinh = Math.sinh(rad);
104         double atan = Math.atan(sinh);
105         double finald = Math.toDegrees(atan);
106         return finald;
107     }
108
109 }