source: josm/trunk/src/org/openstreetmap/josm/gui/util/RotationAngle.java@ 11725

Last change on this file since 11725 was 11725, checked in by michael2402, 7 years ago

Add hashcode / equals to rotation angle.

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