View Javadoc
1   package au.gov.amsa.geo.model;
2   
3   import au.gov.amsa.risky.format.HasFix;
4   import au.gov.amsa.util.navigation.Position;
5   
6   /**
7    * Geographic bounds using a latitude, longitude rectangle.
8    */
9   public class Bounds {
10  
11      private final double topLeftLat, topLeftLon, bottomRightLat, bottomRightLon;
12  
13      public Bounds(double topLeftLat, double topLeftLon, double bottomRightLat, double bottomRightLon) {
14          this.topLeftLat = topLeftLat;
15          this.topLeftLon = Position.to180(topLeftLon);
16          this.bottomRightLat = bottomRightLat;
17          this.bottomRightLon = Position.to180(bottomRightLon);
18      }
19  
20      public double getTopLeftLat() {
21          return topLeftLat;
22      }
23  
24      public double getTopLeftLon() {
25          return topLeftLon;
26      }
27  
28      public double getBottomRightLat() {
29          return bottomRightLat;
30      }
31  
32      public double getBottomRightLon() {
33          return bottomRightLon;
34      }
35  
36      public double getWidthDegrees() {
37          if (bottomRightLon < topLeftLon)
38              return bottomRightLon + 360 - topLeftLon;
39          else
40              return bottomRightLon - topLeftLon;
41      }
42  
43      public double getHeightDegrees() {
44          return topLeftLat - bottomRightLat;
45      }
46  
47      public boolean contains(HasFix p) {
48          return contains(p.fix().lat(), p.fix().lon());
49      }
50  
51      public boolean contains(double lat, double lon) {
52          return topLeftLat >= lat && bottomRightLat <= lat
53                  && betweenLongitudes(topLeftLon, bottomRightLon, Position.to180(lon));
54      }
55  
56      /**
57       * Returns true if and only if lon is between the longitudes topLeftLon and
58       * bottomRightLon.
59       * 
60       * @param topLeftLon
61       *            must be between -180 and 180
62       * @param bottomRightLon
63       *            must be between -180 and 180
64       * @param lon
65       *            must be between -180 and 180
66       * @return
67       */
68      private static boolean betweenLongitudes(double topLeftLon, double bottomRightLon, double lon) {
69          if (topLeftLon <= bottomRightLon)
70              return lon >= topLeftLon && lon <= bottomRightLon;
71          else
72              return lon >= topLeftLon || lon <= bottomRightLon;
73      }
74  
75      @Override
76      public String toString() {
77          StringBuilder builder = new StringBuilder();
78          builder.append("Bounds [topLeftLat=");
79          builder.append(topLeftLat);
80          builder.append(", topLeftLon=");
81          builder.append(topLeftLon);
82          builder.append(", bottomRightLat=");
83          builder.append(bottomRightLat);
84          builder.append(", bottomRightLon=");
85          builder.append(bottomRightLon);
86          builder.append("]");
87          return builder.toString();
88      }
89  
90      public Bounds expand(double latExpansionDegrees, double lonExpansionDegrees) {
91          return new Bounds(Math.min(90, topLeftLat + latExpansionDegrees), topLeftLon
92                  - lonExpansionDegrees, Math.max(-90, bottomRightLat - latExpansionDegrees),
93                  bottomRightLon + lonExpansionDegrees);
94      }
95  
96  }