Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
package org.etsi.geodesic;
import java.util.ArrayList;
/**
* @desc
* @see To validate GPS location: http://www.gps-coordinates.net
*/
public class Positioning implements IPositioning {
public static double TWOPI = 2 * Math.PI;
/**
* Unique reference to this object
*/
private static IPositioning Instance;
/**
* Singleton pattern implementation
*/
public static IPositioning getInstance() {
if (Instance == null) {
Instance = new Positioning();
}
return Instance;
}
/**
* Private constructor required for Singleton pattern implementation
*/
private Positioning() {
}
@Override
public boolean isLocationInsideEllipticArea(final WGS84 p_location, final ArrayList<WGS84> p_ellipticArea) {
// System.out.println(">>> Positioning.isLocationInsideEllipticArea: " + p_location);
// TODO: implement it
// Do not forget aboout passing throw 0 meridian
return false;
}
@Override
public boolean isLocationInsidePolygonalArea(final WGS84 p_location, final ArrayList<WGS84> p_polygonalArea) {
// System.out.println(">>> Positioning.isLocationInsidePolygonalArea: " + p_location + ", " + p_polygonalArea);
// TODO: Check passing throw 0 meridian and Equador
double angle = 0;
int poleNum = p_polygonalArea.size();
for (int index = 0; index < poleNum; index++) {
WGS84 delta1 = new WGS84(
p_polygonalArea.get(index).getLatitude() - p_location.getLatitude(),
p_polygonalArea.get(index).getLongitude() - p_location.getLongitude(),
0
);
WGS84 delta2 = new WGS84(
p_polygonalArea.get((index + 1) % poleNum).getLatitude() - p_location.getLatitude(),
p_polygonalArea.get((index + 1) % poleNum).getLongitude() - p_location.getLongitude(),
0
);
angle += calcAngle(delta1, delta2);
} // End of 'for' statement
// System.out.println("<<< Positioning.isLocationInsidePolygonalArea: " + (boolean)((Math.abs(angle) < Math.PI) ? false : true));
return (boolean)((Math.abs(angle) < Math.PI) ? false : true);
}
@Override
public boolean isLocationInsidePolygonalAreas(final WGS84 p_location, final ArrayList< ArrayList<WGS84> > p_polygonalAreas) {
// System.out.println(">>> Positioning.isLocationInsidePolygonalAreas: " + p_location);
for (int index = 0; index < p_polygonalAreas.size(); index++) {
if (isLocationInsidePolygonalArea(p_location, p_polygonalAreas.get(index))) {
return true;
}
} // End of 'for' statement
return false; // Not found
}
@Override
public boolean isLocationInsideCircularArea(final WGS84 p_location, final WGS84 p_center, final int p_radius) {
// System.out.println(">>> Positioning.isLocationInsideCircularArea: " + p_location + ", " + p_center + ", " + p_radius);
// TODO: Check passing throw 0 meridian and Equador
double theta = p_center.getLongitude() - p_location.getLongitude();
double distance =
Math.sin(dd2rad(p_center.getLatitude())) * Math.sin(dd2rad(p_location.getLatitude())) +
Math.cos(dd2rad(p_center.getLatitude())) * Math.cos(dd2rad(p_location.getLatitude())) * Math.cos(dd2rad(theta));
distance = rad2dd(Math.acos(distance));
distance *= 60 * 1.1515 * 1.609344 /*Kilometers*/;
// System.out.println("Positioning.isLocationInsideCircularArea: distance=" + distance);
// System.out.println("<<< Positioning.isLocationInsideCircularArea: " + (boolean)(distance <= (p_radius / 1000.0)));
return (boolean)(distance <= (p_radius / 1000.0));
}
@Override
public boolean isValidPolygonArea(final ArrayList<WGS84> p_polygonalArea) {
// System.out.println(">>> Positioning.isValidPolygonArea");
// Check if polygon coordinates are valid
for (int i = 0; i < p_polygonalArea.size(); i++) {
if (!p_polygonalArea.get(i).isValidPosition()) {
return false;
}
}
return true;
}
@Override
public boolean isLocationInsideIdentifiedRegion(final int p_regionDictionary, final int p_regionId, final long p_localRegion, final WGS84 p_location) {
// System.out.println(">>> Positioning.isLocationInsideIdentifiedRegion: " + p_regionDictionary + ", " + p_regionId + ", " + p_localRegion + ", " + p_location);
return CountriesAreas.getInstance().isLocationInsideIdentifiedRegion(p_regionDictionary, p_regionId, p_localRegion, p_location);
}
@Override
public boolean isPolygonalRegionInside(final ArrayList<WGS84> p_parentArea, final ArrayList<WGS84> p_regionArea) {
// System.out.println(">>> Positioning.isPolygonalRegionInside: " + p_parentArea + ", " + p_regionArea);
for (int i = 0; i < p_regionArea.size(); i++) {
if (!isLocationInsidePolygonalArea(p_regionArea.get(i), p_parentArea)) {
return false;
}
} // End of 'for' statement
return true;
}
private double calcAngle(final WGS84 p_origin, final WGS84 p_end) {
// System.out.println(">>> calcAngle: " + p_origin.getLatitude() + " - " + p_origin.getLongitude() + " - " + p_end.getLatitude() + " - " + p_end.getLongitude());
double theta1 = Math.atan2(p_origin.getLatitude(), p_origin.getLongitude());
// System.out.println("Angle2D: theta1=" + theta1);
double theta2 = Math.atan2(p_end.getLatitude(), p_end.getLongitude());
// System.out.println("Angle2D: theta2=" + theta2);
double dtheta = theta2 - theta1;
// System.out.println("calcAngle: dtheta" + dtheta);
while (dtheta > Math.PI) {
dtheta -= TWOPI;
} // End of 'while' statement
while (dtheta < -Math.PI) {
dtheta += TWOPI;
} // End of 'while' statement
// System.out.println("<<< calcAngle: " + dtheta);
return dtheta;
}
/**
* @desc Convert a decimal degrees value into a decimal radian
* @param p_decimalDegrees The value to convert
* @return The converted value in radians
*/
private double dd2rad(final double p_decimalDegrees) {
return p_decimalDegrees * Math.PI / 180;
}
/**
* @desc Convert a decimal radians value into a decimal degrees
* @param p_decimalRadians The value to convert
* @return The converted value in degrees
*/
private double rad2dd(final double p_decimalRadians) {
return p_decimalRadians * 180.0 / Math.PI;
}
} // End of class Positioning