source: josm/trunk/src/org/openstreetmap/josm/tools/RotationAngle.java@ 13463

Last change on this file since 13463 was 12756, checked in by Don-vip, 7 years ago

see #15229 - see #15182 - move RotationAngle from gui.util to tools

  • Property svn:eol-style set to native
File size: 5.6 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.tools;
3
4import java.util.Locale;
5
6import org.openstreetmap.josm.data.osm.Node;
7import org.openstreetmap.josm.data.osm.OsmPrimitive;
8import org.openstreetmap.josm.data.osm.Way;
9
10/**
11 * Determines how an icon is to be rotated depending on the primitive to be displayed.
12 * @since 8199 (creation)
13 * @since 10599 (functional interface)
14 * @since 12756 (moved from {@code gui.util} package)
15 */
16@FunctionalInterface
17public interface RotationAngle {
18
19 /**
20 * The rotation along a way.
21 */
22 final class WayDirectionRotationAngle implements RotationAngle {
23 @Override
24 public double getRotationAngle(OsmPrimitive p) {
25 if (!(p instanceof Node)) {
26 return 0;
27 }
28 final Node n = (Node) p;
29 final SubclassFilteredCollection<OsmPrimitive, Way> ways = Utils.filteredCollection(n.getReferrers(), Way.class);
30 if (ways.isEmpty()) {
31 return 0;
32 }
33 final Way w = ways.iterator().next();
34 final int idx = w.getNodes().indexOf(n);
35 if (idx == 0) {
36 return -Geometry.getSegmentAngle(n.getEastNorth(), w.getNode(idx + 1).getEastNorth());
37 } else {
38 return -Geometry.getSegmentAngle(w.getNode(idx - 1).getEastNorth(), n.getEastNorth());
39 }
40 }
41
42 @Override
43 public String toString() {
44 return "way-direction";
45 }
46
47 @Override
48 public int hashCode() {
49 return 1;
50 }
51
52 @Override
53 public boolean equals(Object obj) {
54 if (this == obj) {
55 return true;
56 }
57 return obj != null && getClass() == obj.getClass();
58 }
59 }
60
61 /**
62 * A static rotation
63 */
64 final class StaticRotationAngle implements RotationAngle {
65 private final double angle;
66
67 private StaticRotationAngle(double angle) {
68 this.angle = angle;
69 }
70
71 @Override
72 public double getRotationAngle(OsmPrimitive p) {
73 return angle;
74 }
75
76 @Override
77 public String toString() {
78 return angle + "rad";
79 }
80
81 @Override
82 public int hashCode() {
83 final int prime = 31;
84 int result = 1;
85 long temp = Double.doubleToLongBits(angle);
86 result = prime * result + (int) (temp ^ (temp >>> 32));
87 return result;
88 }
89
90 @Override
91 public boolean equals(Object obj) {
92 if (this == obj) {
93 return true;
94 }
95 if (obj == null || getClass() != obj.getClass()) {
96 return false;
97 }
98 StaticRotationAngle other = (StaticRotationAngle) obj;
99 return Double.doubleToLongBits(angle) == Double.doubleToLongBits(other.angle);
100 }
101 }
102
103 /**
104 * A no-rotation angle that always returns 0.
105 * @since 11726
106 */
107 RotationAngle NO_ROTATION = new StaticRotationAngle(0);
108
109 /**
110 * Calculates the rotation angle depending on the primitive to be displayed.
111 * @param p primitive
112 * @return rotation angle
113 */
114 double getRotationAngle(OsmPrimitive p);
115
116 /**
117 * Always returns the fixed {@code angle}.
118 * @param angle angle
119 * @return rotation angle
120 */
121 static RotationAngle buildStaticRotation(final double angle) {
122 return new StaticRotationAngle(angle);
123 }
124
125 /**
126 * Parses the rotation angle from the specified {@code string}.
127 * @param string angle as string
128 * @return rotation angle
129 */
130 static RotationAngle buildStaticRotation(final String string) {
131 try {
132 return buildStaticRotation(parseCardinalRotation(string));
133 } catch (IllegalArgumentException e) {
134 throw new IllegalArgumentException("Invalid string: " + string, e);
135 }
136 }
137
138 /**
139 * Converts an angle diven in cardinal directions to radians.
140 * The following values are supported: {@code n}, {@code north}, {@code ne}, {@code northeast},
141 * {@code e}, {@code east}, {@code se}, {@code southeast}, {@code s}, {@code south},
142 * {@code sw}, {@code southwest}, {@code w}, {@code west}, {@code nw}, {@code northwest}.
143 * @param cardinal the angle in cardinal directions
144 * @return the angle in radians
145 */
146 static double parseCardinalRotation(final String cardinal) {
147 switch (cardinal.toLowerCase(Locale.ENGLISH)) {
148 case "n":
149 case "north":
150 return 0; // 0 degree => 0 radian
151 case "ne":
152 case "northeast":
153 return Utils.toRadians(45);
154 case "e":
155 case "east":
156 return Utils.toRadians(90);
157 case "se":
158 case "southeast":
159 return Utils.toRadians(135);
160 case "s":
161 case "south":
162 return Math.PI; // 180 degree
163 case "sw":
164 case "southwest":
165 return Utils.toRadians(225);
166 case "w":
167 case "west":
168 return Utils.toRadians(270);
169 case "nw":
170 case "northwest":
171 return Utils.toRadians(315);
172 default:
173 throw new IllegalArgumentException("Unexpected cardinal direction " + cardinal);
174 }
175 }
176
177 /**
178 * Computes the angle depending on the referencing way segment, or {@code 0} if none exists.
179 * @return rotation angle
180 */
181 static RotationAngle buildWayDirectionRotation() {
182 return new WayDirectionRotationAngle();
183 }
184}
Note: See TracBrowser for help on using the repository browser.