1 /*
2  * Copyright (c) 2016 Vivid Solutions.
3  *
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License 2.0
6  * and Eclipse Distribution License v. 1.0 which accompanies this distribution.
7  * The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v20.html
8  * and the Eclipse Distribution License is available at
9  *
10  * http://www.eclipse.org/org/documents/edl-v10.php.
11  */
12 
13 package org.locationtech.jtstest.testbuilder.ui.style;
14 
15 import java.awt.Color;
16 import java.awt.Font;
17 import java.awt.Graphics2D;
18 import java.awt.geom.Point2D;
19 
20 import org.locationtech.jts.awt.FontGlyphReader;
21 import org.locationtech.jts.geom.Coordinate;
22 import org.locationtech.jts.geom.Geometry;
23 import org.locationtech.jts.geom.LineSegment;
24 import org.locationtech.jts.geom.LineString;
25 import org.locationtech.jts.geom.Polygon;
26 import org.locationtech.jtstest.testbuilder.geom.ConstrainedInteriorPoint;
27 import org.locationtech.jtstest.testbuilder.ui.GraphicsUtil;
28 import org.locationtech.jtstest.testbuilder.ui.Viewport;
29 
30 
31 public class DataLabelStyle implements Style
32 {
33   private Color color;
34   private int size = 12;
35   private Font font = new Font(FontGlyphReader.FONT_SANSSERIF, Font.BOLD, 12);
36 
DataLabelStyle(Color color)37   public DataLabelStyle(Color color) {
38     this.color = color;
39   }
40 
DataLabelStyle()41   public DataLabelStyle() {
42   }
43 
getColor()44   public Color getColor() {
45     return color;
46   }
setColor(Color color)47   public void setColor(Color color) {
48     this.color = color;
49   }
getSize()50   public int getSize() {
51     return size;
52   }
53 
setSize(int size)54   public void setSize(int size) {
55     this.size = size;
56     font = new Font(FontGlyphReader.FONT_SANSSERIF, Font.BOLD, size);
57   }
58 
paint(Geometry geom, Viewport viewport, Graphics2D g2d)59   public void paint(Geometry geom, Viewport viewport, Graphics2D g2d)
60   {
61     if (geom.getUserData() == null) return;
62     g2d.setColor(color);
63     g2d.setFont(font);
64 
65     String label = geom.getUserData().toString();
66 
67     if (geom instanceof Polygon) {
68       paintLabelPolygon(label, geom, viewport, g2d);
69     }
70     else if (geom instanceof LineString) {
71       paintLabelLine(label, geom, viewport, g2d);
72     }
73     else {
74       paintLabel(label, geom, viewport, g2d);
75     }
76   }
77 
paintLabelPolygon(String label, Geometry geom, Viewport viewport, Graphics2D g2d)78   private void paintLabelPolygon(String label, Geometry geom, Viewport viewport, Graphics2D g2d) {
79     Coordinate origin = ConstrainedInteriorPoint.getCoordinate((Polygon) geom, viewport.getModelEnv());
80     Point2D vp = viewport.toView(new Point2D.Double(origin.x, origin.y));
81     GraphicsUtil.drawStringAlignCenter(g2d, label, (int) vp.getX(), (int) vp.getY());
82   }
83 
paintLabel(String label, Geometry geom, Viewport viewport, Graphics2D g2d)84   private void paintLabel(String label, Geometry geom, Viewport viewport, Graphics2D g2d) {
85     Coordinate origin = geom.getInteriorPoint().getCoordinate();
86     Point2D vp = viewport.toView(new Point2D.Double(origin.x, origin.y));
87     GraphicsUtil.drawStringAlignCenter(g2d, label, (int) vp.getX(), (int) vp.getY());
88   }
89 
paintLabelLine(String label, Geometry line, Viewport viewport, Graphics2D g2d)90   private void paintLabelLine(String label, Geometry line, Viewport viewport, Graphics2D g2d) {
91     LineSegment baseline = LineLabelBaseline.getBaseline((LineString) line, viewport.getModelEnv());
92     if (baseline == null) return;
93 
94     Coordinate origin = baseline.p0;
95     Point2D vpOrigin = viewport.toView(new Point2D.Double(origin.x, origin.y));
96 
97     Coordinate dirPt = baseline.p1;
98     Point2D vpDir = viewport.toView(new Point2D.Double(dirPt.x, dirPt.y));
99 
100     double dx = vpDir.getX() - vpOrigin.getX();
101     double dy = vpDir.getY() - vpOrigin.getY();
102 
103     double offsetLen = 15;
104     double nudgeX = 5;
105 
106     double dirVecLen = Math.sqrt(dx*dx + dy*dy);
107 
108     double offsetX = offsetLen * dx / dirVecLen;
109     double offsetY = offsetLen * dy / dirVecLen;
110     offsetX += dx > 0 ? nudgeX : -nudgeX;
111 
112     float alignX = offsetX < 0 ? 1 : 0;
113     float alignY = offsetY < 0 ? 0 : 1;
114 
115     Point2D vp = new Point2D.Double(vpOrigin.getX() + offsetX, vpOrigin.getY() + offsetY);
116 
117     GraphicsUtil.drawStringAlign(g2d, label, (int) vp.getX(), (int) vp.getY(), alignX, alignY);
118 
119   }
120 
121 }
122