1 package com.github.davidmoten.rtree.geometry;
2
3 import com.github.davidmoten.guavamini.annotations.VisibleForTesting;
4 import com.github.davidmoten.rtree.geometry.internal.CircleDouble;
5 import com.github.davidmoten.rtree.geometry.internal.CircleFloat;
6 import com.github.davidmoten.rtree.geometry.internal.LineDouble;
7 import com.github.davidmoten.rtree.geometry.internal.LineFloat;
8 import com.github.davidmoten.rtree.geometry.internal.PointDouble;
9 import com.github.davidmoten.rtree.geometry.internal.PointFloat;
10 import com.github.davidmoten.rtree.geometry.internal.RectangleDouble;
11 import com.github.davidmoten.rtree.geometry.internal.RectangleFloat;
12
13 public final class Geometries {
14
15 private Geometries() {
16
17 }
18
19 public static Point point(double x, double y) {
20 return PointDouble.create(x, y);
21 }
22
23 public static Point point(float x, float y) {
24 return PointFloat.create(x, y);
25 }
26
27 public static Point pointGeographic(double lon, double lat) {
28 return point(normalizeLongitudeDouble(lon), lat);
29 }
30
31 public static Point pointGeographic(float lon, float lat) {
32 return point(normalizeLongitude(lon), lat);
33 }
34
35 public static Rectangle rectangle(double x1, double y1, double x2, double y2) {
36 return rectangleDouble(x1, y1, x2, y2);
37 }
38
39 public static Rectangle rectangle(float x1, float y1, float x2, float y2) {
40 return RectangleFloat.create(x1, y1, x2, y2);
41 }
42
43 public static Rectangle rectangleGeographic(double lon1, double lat1, double lon2,
44 double lat2) {
45 return rectangleGeographic((float) lon1, (float) lat1, (float) lon2, (float) lat2);
46 }
47
48 public static Rectangle rectangleGeographic(float lon1, float lat1, float lon2, float lat2) {
49 float x1 = normalizeLongitude(lon1);
50 float x2 = normalizeLongitude(lon2);
51 if (x2 < x1) {
52 x2 += 360;
53 }
54 return rectangle(x1, lat1, x2, lat2);
55 }
56
57 private static Rectangle rectangleDouble(double x1, double y1, double x2, double y2) {
58 return RectangleDouble.create(x1, y1, x2, y2);
59 }
60
61 public static Circle circle(double x, double y, double radius) {
62 return CircleDouble.create(x, y, radius);
63 }
64
65 public static Circle circle(float x, float y, float radius) {
66 return CircleFloat.create(x, y, radius);
67 }
68
69 public static Line line(double x1, double y1, double x2, double y2) {
70 return LineDouble.create(x1, y1, x2, y2);
71 }
72
73 public static Line line(float x1, float y1, float x2, float y2) {
74 return LineFloat.create(x1, y1, x2, y2);
75 }
76
77 @VisibleForTesting
78 static double normalizeLongitude(double d) {
79 return normalizeLongitude((float) d);
80 }
81
82 private static float normalizeLongitude(float d) {
83 if (d == -180.0f)
84 return -180.0f;
85 else {
86 float sign = Math.signum(d);
87 float x = Math.abs(d) / 360;
88 float x2 = (x - (float) Math.floor(x)) * 360;
89 if (x2 >= 180)
90 x2 -= 360;
91 return x2 * sign;
92 }
93 }
94
95 private static double normalizeLongitudeDouble(double d) {
96 if (d == -180.0f)
97 return -180.0d;
98 else {
99 double sign = Math.signum(d);
100 double x = Math.abs(d) / 360;
101 double x2 = (x - (float) Math.floor(x)) * 360;
102 if (x2 >= 180)
103 x2 -= 360;
104 return x2 * sign;
105 }
106 }
107
108 }