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

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

sonar - squid:S1126 - Return of boolean expressions should not be wrapped into an "if-then-else" statement

  • Property svn:eol-style set to native
File size: 5.7 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 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 return obj != null && getClass() == obj.getClass();
60 }
61 }
62
63 /**
64 * A static rotation
65 */
66 final class StaticRotationAngle implements RotationAngle {
67 private final double angle;
68
69 private StaticRotationAngle(double angle) {
70 this.angle = angle;
71 }
72
73 @Override
74 public double getRotationAngle(OsmPrimitive p) {
75 return angle;
76 }
77
78 @Override
79 public String toString() {
80 return angle + "rad";
81 }
82
83 @Override
84 public int hashCode() {
85 final int prime = 31;
86 int result = 1;
87 long temp = Double.doubleToLongBits(angle);
88 result = prime * result + (int) (temp ^ (temp >>> 32));
89 return result;
90 }
91
92 @Override
93 public boolean equals(Object obj) {
94 if (this == obj) {
95 return true;
96 }
97 if (obj == null || getClass() != obj.getClass()) {
98 return false;
99 }
100 StaticRotationAngle other = (StaticRotationAngle) obj;
101 return Double.doubleToLongBits(angle) == Double.doubleToLongBits(other.angle);
102 }
103 }
104
105 /**
106 * A no-rotation angle that always returns 0.
107 * @since 11726
108 */
109 RotationAngle NO_ROTATION = new StaticRotationAngle(0);
110
111 /**
112 * Calculates the rotation angle depending on the primitive to be displayed.
113 * @param p primitive
114 * @return rotation angle
115 */
116 double getRotationAngle(OsmPrimitive p);
117
118 /**
119 * Always returns the fixed {@code angle}.
120 * @param angle angle
121 * @return rotation angle
122 */
123 static RotationAngle buildStaticRotation(final double angle) {
124 return new StaticRotationAngle(angle);
125 }
126
127 /**
128 * Parses the rotation angle from the specified {@code string}.
129 * @param string angle as string
130 * @return rotation angle
131 */
132 static RotationAngle buildStaticRotation(final String string) {
133 try {
134 return buildStaticRotation(parseCardinalRotation(string));
135 } catch (IllegalArgumentException e) {
136 throw new IllegalArgumentException("Invalid string: " + string, e);
137 }
138 }
139
140 /**
141 * Converts an angle diven in cardinal directions to radians.
142 * The following values are supported: {@code n}, {@code north}, {@code ne}, {@code northeast},
143 * {@code e}, {@code east}, {@code se}, {@code southeast}, {@code s}, {@code south},
144 * {@code sw}, {@code southwest}, {@code w}, {@code west}, {@code nw}, {@code northwest}.
145 * @param cardinal the angle in cardinal directions
146 * @return the angle in radians
147 */
148 static double parseCardinalRotation(final String cardinal) {
149 switch (cardinal.toLowerCase(Locale.ENGLISH)) {
150 case "n":
151 case "north":
152 return 0; // 0 degree => 0 radian
153 case "ne":
154 case "northeast":
155 return Math.toRadians(45);
156 case "e":
157 case "east":
158 return Math.toRadians(90);
159 case "se":
160 case "southeast":
161 return Math.toRadians(135);
162 case "s":
163 case "south":
164 return Math.PI; // 180 degree
165 case "sw":
166 case "southwest":
167 return Math.toRadians(225);
168 case "w":
169 case "west":
170 return Math.toRadians(270);
171 case "nw":
172 case "northwest":
173 return Math.toRadians(315);
174 default:
175 throw new IllegalArgumentException("Unexpected cardinal direction " + cardinal);
176 }
177 }
178
179 /**
180 * Computes the angle depending on the referencing way segment, or {@code 0} if none exists.
181 * @return rotation angle
182 */
183 static RotationAngle buildWayDirectionRotation() {
184 return new WayDirectionRotationAngle();
185 }
186}
Note: See TracBrowser for help on using the repository browser.