source: josm/trunk/src/org/openstreetmap/josm/data/osm/BBox.java@ 10378

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

Checkstyle 6.19: enable SingleSpaceSeparator and fix violations

  • Property svn:eol-style set to native
File size: 7.4 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.data.osm;
3
4import java.awt.geom.Rectangle2D;
5import java.util.Arrays;
6import java.util.Objects;
7
8import org.openstreetmap.josm.data.coor.LatLon;
9import org.openstreetmap.josm.data.coor.QuadTiling;
10import org.openstreetmap.josm.tools.Utils;
11
12public class BBox {
13
14 private double xmin = Double.POSITIVE_INFINITY;
15 private double xmax = Double.NEGATIVE_INFINITY;
16 private double ymin = Double.POSITIVE_INFINITY;
17 private double ymax = Double.NEGATIVE_INFINITY;
18
19 /**
20 * Constructs a new {@code BBox} defined by a single point.
21 *
22 * @param x X coordinate
23 * @param y Y coordinate
24 * @since 6203
25 */
26 public BBox(final double x, final double y) {
27 xmax = xmin = x;
28 ymax = ymin = y;
29 sanity();
30 }
31
32 /**
33 * Constructs a new {@code BBox} defined by points <code>a</code> and <code>b</code>.
34 * Result is minimal BBox containing both points.
35 *
36 * @param a first point
37 * @param b second point
38 */
39 public BBox(LatLon a, LatLon b) {
40 this(a.lon(), a.lat(), b.lon(), b.lat());
41 }
42
43 /**
44 * Constructs a new {@code BBox} from another one.
45 *
46 * @param copy the BBox to copy
47 */
48 public BBox(BBox copy) {
49 this.xmin = copy.xmin;
50 this.xmax = copy.xmax;
51 this.ymin = copy.ymin;
52 this.ymax = copy.ymax;
53 }
54
55 public BBox(double ax, double ay, double bx, double by) {
56
57 if (ax > bx) {
58 xmax = ax;
59 xmin = bx;
60 } else {
61 xmax = bx;
62 xmin = ax;
63 }
64
65 if (ay > by) {
66 ymax = ay;
67 ymin = by;
68 } else {
69 ymax = by;
70 ymin = ay;
71 }
72
73 sanity();
74 }
75
76 public BBox(Way w) {
77 for (Node n : w.getNodes()) {
78 LatLon coor = n.getCoor();
79 if (coor == null) {
80 continue;
81 }
82 add(coor);
83 }
84 }
85
86 public BBox(Node n) {
87 LatLon coor = n.getCoor();
88 if (coor == null) {
89 xmin = xmax = ymin = ymax = 0;
90 } else {
91 xmin = xmax = coor.lon();
92 ymin = ymax = coor.lat();
93 }
94 }
95
96 private void sanity() {
97 if (xmin < -180.0) {
98 xmin = -180.0;
99 }
100 if (xmax > 180.0) {
101 xmax = 180.0;
102 }
103 if (ymin < -90.0) {
104 ymin = -90.0;
105 }
106 if (ymax > 90.0) {
107 ymax = 90.0;
108 }
109 }
110
111 public final void add(LatLon c) {
112 add(c.lon(), c.lat());
113 }
114
115 /**
116 * Extends this bbox to include the point (x, y)
117 * @param x X coordinate
118 * @param y Y coordinate
119 */
120 public final void add(double x, double y) {
121 xmin = Math.min(xmin, x);
122 xmax = Math.max(xmax, x);
123 ymin = Math.min(ymin, y);
124 ymax = Math.max(ymax, y);
125 sanity();
126 }
127
128 public final void add(BBox box) {
129 xmin = Math.min(xmin, box.xmin);
130 xmax = Math.max(xmax, box.xmax);
131 ymin = Math.min(ymin, box.ymin);
132 ymax = Math.max(ymax, box.ymax);
133 sanity();
134 }
135
136 public void addPrimitive(OsmPrimitive primitive, double extraSpace) {
137 BBox primBbox = primitive.getBBox();
138 add(primBbox.xmin - extraSpace, primBbox.ymin - extraSpace);
139 add(primBbox.xmax + extraSpace, primBbox.ymax + extraSpace);
140 }
141
142 public double height() {
143 return ymax-ymin;
144 }
145
146 public double width() {
147 return xmax-xmin;
148 }
149
150 /**
151 * Tests, whether the bbox {@code b} lies completely inside this bbox.
152 * @param b bounding box
153 * @return {@code true} if {@code b} lies completely inside this bbox
154 */
155 public boolean bounds(BBox b) {
156 return xmin <= b.xmin && xmax >= b.xmax
157 && ymin <= b.ymin && ymax >= b.ymax;
158 }
159
160 /**
161 * Tests, whether the Point {@code c} lies within the bbox.
162 * @param c point
163 * @return {@code true} if {@code c} lies within the bbox
164 */
165 public boolean bounds(LatLon c) {
166 return xmin <= c.lon() && xmax >= c.lon()
167 && ymin <= c.lat() && ymax >= c.lat();
168 }
169
170 /**
171 * Tests, whether two BBoxes intersect as an area.
172 * I.e. whether there exists a point that lies in both of them.
173 * @param b other bounding box
174 * @return {@code true} if this bbox intersects with the other
175 */
176 public boolean intersects(BBox b) {
177 if (xmin > b.xmax)
178 return false;
179 if (xmax < b.xmin)
180 return false;
181 if (ymin > b.ymax)
182 return false;
183 if (ymax < b.ymin)
184 return false;
185 return true;
186 }
187
188 /**
189 * Returns the top-left point.
190 * @return The top-left point
191 */
192 public LatLon getTopLeft() {
193 return new LatLon(ymax, xmin);
194 }
195
196 /**
197 * Returns the latitude of top-left point.
198 * @return The latitude of top-left point
199 * @since 6203
200 */
201 public double getTopLeftLat() {
202 return ymax;
203 }
204
205 /**
206 * Returns the longitude of top-left point.
207 * @return The longitude of top-left point
208 * @since 6203
209 */
210 public double getTopLeftLon() {
211 return xmin;
212 }
213
214 /**
215 * Returns the bottom-right point.
216 * @return The bottom-right point
217 */
218 public LatLon getBottomRight() {
219 return new LatLon(ymin, xmax);
220 }
221
222 /**
223 * Returns the latitude of bottom-right point.
224 * @return The latitude of bottom-right point
225 * @since 6203
226 */
227 public double getBottomRightLat() {
228 return ymin;
229 }
230
231 /**
232 * Returns the longitude of bottom-right point.
233 * @return The longitude of bottom-right point
234 * @since 6203
235 */
236 public double getBottomRightLon() {
237 return xmax;
238 }
239
240 public LatLon getCenter() {
241 return new LatLon(ymin + (ymax-ymin)/2.0, xmin + (xmax-xmin)/2.0);
242 }
243
244 int getIndex(final int level) {
245
246 int idx1 = QuadTiling.index(ymin, xmin, level);
247
248 final int idx2 = QuadTiling.index(ymin, xmax, level);
249 if (idx1 == -1) idx1 = idx2;
250 else if (idx1 != idx2) return -1;
251
252 final int idx3 = QuadTiling.index(ymax, xmin, level);
253 if (idx1 == -1) idx1 = idx3;
254 else if (idx1 != idx3) return -1;
255
256 final int idx4 = QuadTiling.index(ymax, xmax, level);
257 if (idx1 == -1) idx1 = idx4;
258 else if (idx1 != idx4) return -1;
259
260 return idx1;
261 }
262
263 public Rectangle2D toRectangle() {
264 return new Rectangle2D.Double(xmin, ymin, xmax - xmin, ymax - ymin);
265 }
266
267 @Override
268 public int hashCode() {
269 return Objects.hash(xmin, xmax, ymin, ymax);
270 }
271
272 @Override
273 public boolean equals(Object o) {
274 if (this == o) return true;
275 if (o == null || getClass() != o.getClass()) return false;
276 BBox b = (BBox) o;
277 return Double.compare(b.xmax, xmax) == 0 && Double.compare(b.ymax, ymax) == 0
278 && Double.compare(b.xmin, xmin) == 0 && Double.compare(b.ymin, ymin) == 0;
279 }
280
281 @Override
282 public String toString() {
283 return "[ x: " + xmin + " -> " + xmax + ", y: " + ymin + " -> " + ymax + " ]";
284 }
285
286 public String toStringCSV(String separator) {
287 return Utils.join(separator, Arrays.asList(
288 LatLon.cDdFormatter.format(xmin),
289 LatLon.cDdFormatter.format(ymin),
290 LatLon.cDdFormatter.format(xmax),
291 LatLon.cDdFormatter.format(ymax)));
292 }
293}
Note: See TracBrowser for help on using the repository browser.