1 package au.gov.amsa.geo.model;
2
3 import java.io.Serializable;
4
5 import au.gov.amsa.risky.format.HasPosition;
6
7 import com.google.common.base.Optional;
8
9
10
11
12
13
14
15 public class Cell implements Serializable {
16
17 private static final long serialVersionUID = 5489135874617545438L;
18 private static final double radiusEarthKm = 6371.01;
19 private static final double KM_PER_NM = 1.852;
20
21 private final long latIndex;
22 private final long lonIndex;
23 private final int hashCode;
24
25
26
27
28
29
30
31 Cell(long latIndex, long lonIndex) {
32 this.latIndex = latIndex;
33 this.lonIndex = lonIndex;
34 hashCode = calculateHashCode();
35 }
36
37 public static Optional<Cell> cellAt(HasPosition p, Options options) {
38 return cellAt(p.lat(), p.lon(), options);
39 }
40
41 public static Optional<Cell> cellAt(double lat, double lon, Options options) {
42 return options.getGrid().cellAt(lat, lon);
43 }
44
45 public double leftEdgeLongitude(Options options) {
46 return options.getGrid().leftEdgeLongitude(this);
47 }
48
49 public double rightEdgeLongitude(Options options) {
50 return options.getGrid().rightEdgeLongitude(this);
51 }
52
53 public double topEdgeLatitude(Options options) {
54 return options.getGrid().topEdgeLatitude(this);
55 }
56
57 public double bottomEdgeLatitude(Options options) {
58 return options.getGrid().bottomEdgeLatitude(this);
59 }
60
61 public long getLatIndex() {
62 return latIndex;
63 }
64
65 public long getLonIndex() {
66 return lonIndex;
67 }
68
69 public double getCentreLon(Options options) {
70 return options.getGrid().centreLon(lonIndex);
71 }
72
73 public double getCentreLat(Options options) {
74 return options.getGrid().centreLat(latIndex);
75 }
76
77
78
79
80
81
82
83 public double areaNauticalMiles(Options options) {
84 double topLatRads = Math.toRadians(topEdgeLatitude(options));
85 double bottomLatRads = Math.toRadians(bottomEdgeLatitude(options));
86
87 return Math.PI / 180 * radiusEarthKm * radiusEarthKm
88 * Math.abs(Math.sin(topLatRads) - Math.sin(bottomLatRads))
89 * options.getCellSizeDegreesAsDouble() / (KM_PER_NM * KM_PER_NM);
90 }
91
92 @Override
93 public int hashCode() {
94 return hashCode;
95 }
96
97 private int calculateHashCode() {
98 final int prime = 31;
99 int result = 1;
100 result = prime * result + (int) (latIndex ^ (latIndex >>> 32));
101 result = prime * result + (int) (lonIndex ^ (lonIndex >>> 32));
102 return result;
103 }
104
105 @Override
106 public boolean equals(Object obj) {
107 if (this == obj)
108 return true;
109 if (obj == null)
110 return false;
111 if (getClass() != obj.getClass())
112 return false;
113 Cell other = (Cell) obj;
114 if (latIndex != other.latIndex)
115 return false;
116 if (lonIndex != other.lonIndex)
117 return false;
118 return true;
119 }
120
121 @Override
122 public String toString() {
123 return "Cell [latIndex=" + latIndex + ", lonIndex=" + lonIndex + "]";
124 }
125
126 }