source: other-projects/tipple-android/tipple-ar/tipple-standalone-hpg/src/org/greenstone/android/tipple/base/TipLocation.java@ 26528

Last change on this file since 26528 was 26528, checked in by davidb, 11 years ago

Code developed by the Tipple-AR Smoke and Mirrors team, based on the main tipple trunk

File size: 6.6 KB
Line 
1package org.greenstone.android.tipple.base;
2
3import java.util.List;
4import java.util.HashMap;
5
6import android.graphics.Bitmap;
7import android.graphics.Color;
8import android.graphics.drawable.Drawable;
9import android.location.Location;
10
11public class TipLocation {
12
13 // Text and/or Audio associated with (Latitude,Longitude) location with radius
14 // with the ability to project onto a screen
15
16 static final float SCREEN_Z = -700; // the distance of the screen from the camera
17 static final float EARTH_RADIUS = 6371000;
18 static final float INVISIBLE_SCALE = -1;
19
20 private double latitude_;
21 private double longitude_;
22 private double altitude_;
23
24 private double radiusInKM_;
25 // private double avgRadLatLong_;
26
27 private float distance_; // the distance in meters from the camera
28
29 private float screen_x_; // the x position on the screen in pixels
30 private float screen_y_; // the y position on the screen in pixels
31 private float screen_scale_; // the scale of the marker to draw on the screen (1/distance)
32
33 float marker_hit_x_; // the centre of the marker in screen coordinates
34 float marker_hit_y_;
35 float marker_hit_radius_; // the radius of the marker (approximated by a circle)
36
37 private String title_;
38 private String text_;
39 private String tts_text_;
40 private String title_tts_;
41
42 private Bitmap marker_bitmap_;
43 private Drawable marker_drawable_;
44
45 private int colour_fill_;
46 private int colour_outline_;
47
48 private String audioFilename_;
49 private List<String> audioPaths_;
50
51 protected String id_;
52
53 public TipLocation(HashMap<String, String> hashmap) {
54 latitude_ = Double.parseDouble(hashmap.get("latitude"));
55 longitude_ = Double.parseDouble(hashmap.get("longitude"));
56 altitude_ = hashmap.containsKey("altitude") ? Double.parseDouble(hashmap.get("altitude"))
57 : 0;
58 radiusInKM_ = Double.parseDouble(hashmap.get("radius"));
59
60 title_ = hashmap.get("title");
61 text_ = hashmap.get("text");
62 tts_text_ = (hashmap.containsKey("tts")) ? hashmap.get("tts") : null;
63 title_tts_ = (hashmap.containsKey("tts_title")) ? hashmap.get("tts_title") : null;
64
65 marker_bitmap_ = Global.getBitmap(hashmap.get("marker_type"));
66 marker_drawable_ = Global.getDrawable(hashmap.get("marker_type"));
67
68 try {
69 colour_fill_ = Color.parseColor(hashmap.get("colour_fill"));
70 } catch (Exception ex) {
71 colour_fill_ = Color.BLUE;
72 }
73 try {
74 colour_outline_ = Color.parseColor(hashmap.get("colour_outline"));
75 } catch (Exception ex) {
76 colour_outline_ = Color.BLUE;
77 }
78
79 audioFilename_ = hashmap.get("audio");
80
81 // Consolidate whitespace
82 title_ = title_.replaceAll("^\\s+", "");
83 title_ = title_.replaceAll("\\s+$", "");
84 title_ = title_.replaceAll("\\s+", " ");
85
86 if (text_ != null) {
87 text_ = text_.replaceAll("^\\s+", "");
88 text_ = text_.replaceAll("\\s+$", "");
89 text_ = text_.replaceAll("\\s+", " ");
90 }
91
92 id_ = title_.replaceAll("/\\s+/", "-");
93 }
94
95 public void setAltitude(double x) {
96 altitude_ = x;
97 }
98
99 public void setTitle(String x) {
100 title_ = x;
101 }
102
103 public int getColourFill() {
104 return colour_fill_;
105 }
106
107 public int getColourOutline() {
108 return colour_outline_;
109 }
110
111 public boolean isVisible() {
112 return screen_scale_ != INVISIBLE_SCALE;
113 }
114
115 public double getLatitude() {
116 return latitude_;
117 }
118
119 public double getLongitude() {
120 return longitude_;
121 }
122
123 public double getAltitude() {
124 return altitude_;
125 }
126
127 public float getDistance() {
128 return distance_;
129 }
130
131 public float getScreenX() {
132 return screen_x_;
133 }
134
135 public float getScreenY() {
136 return screen_y_;
137 }
138
139 /**
140 * The scale factor of the location's marker. When the location is 1 metre from the camera the
141 * scale factor is 1.
142 */
143 public float getScreenScale() {
144 return screen_scale_;
145 }
146
147 public void setHitCircle(float x, float y, float r) {
148 marker_hit_x_ = x;
149 marker_hit_y_ = y;
150 marker_hit_radius_ = r;
151 }
152
153 public boolean hits(float x, float y) {
154 float dX = marker_hit_x_ - x;
155 float dY = marker_hit_y_ - y;
156 float distSquared = dX * dX + dY * dY;
157
158 float radSquared = marker_hit_radius_ * marker_hit_radius_;
159
160 return distSquared <= radSquared;
161 }
162
163 public double getRadiusKM() {
164 return radiusInKM_;
165 }
166
167 public String getText() {
168 return text_;
169 }
170
171 public String getTTSText() {
172 return (tts_text_ != null) ? tts_text_ : text_;
173 }
174
175 public String getTitle() {
176 return title_;
177 }
178
179 public String getTitleTTS() {
180 return (title_tts_ != null) ? title_tts_ : title_;
181 }
182
183 public String getID() {
184 return id_;
185 }
186
187 public List<String> getAudio() {
188 return audioPaths_;
189 }
190
191 public String getAudioFilename() {
192 return audioFilename_;
193 }
194
195 public Bitmap getMarkerBitmap() {
196 return marker_bitmap_;
197 }
198
199 public Drawable getMarkerDrawable() {
200 return marker_drawable_;
201 }
202
203 public void projectToScreen(Location cameraLocation, float[] rotationMatrix) {
204 float[] onWorldAxes = new float[4];
205 float[] onPhoneAxes;
206
207 calcDifference(cameraLocation, onWorldAxes);
208
209 onPhoneAxes = SensorFusion.getInstance().worldToPhone(onWorldAxes);
210
211 distance_ = (float) Math.sqrt(onPhoneAxes[0] * onPhoneAxes[0] + onPhoneAxes[1]
212 * onPhoneAxes[1] + onPhoneAxes[2] * onPhoneAxes[2]);
213
214 float scalingFactor = SCREEN_Z / onPhoneAxes[2];
215 float projectedX = onPhoneAxes[0] * scalingFactor;
216 float projectedY = onPhoneAxes[1] * scalingFactor;
217
218 screen_x_ = 400 - projectedY;
219 screen_y_ = 240 - projectedX;
220 if (onPhoneAxes[2] < 0) {
221 // in front of camera
222 screen_scale_ = 1 / distance_;
223 } else {
224 // behind camera, so use invisible radius
225 screen_scale_ = INVISIBLE_SCALE;
226 }
227 }
228
229 private void calcDifference(Location origin, float[] result) {
230 // Uses trigonometry to calculate the location of the given point in
231 // terms of the XYZ axes centred at the origin.
232 // A = longitude, B = latitude, O = origin, P = point, D = difference
233 double sinDA = Math.sin(Math.toRadians(longitude_ - origin.getLongitude()));
234 double cosDA = Math.cos(Math.toRadians(longitude_ - origin.getLongitude()));
235 double sinPB = Math.sin(Math.toRadians(latitude_));
236 double cosPB = Math.cos(Math.toRadians(latitude_));
237 double sinOB = Math.sin(Math.toRadians(origin.getLatitude()));
238 double cosOB = Math.cos(Math.toRadians(origin.getLatitude()));
239 double r = EARTH_RADIUS + origin.getAltitude() + altitude_;
240
241 double x = r * cosPB * sinDA;
242 double y = r * (sinPB * cosOB - cosDA * cosPB * sinOB);
243 double z = r * (cosDA * cosPB * cosOB + sinPB * sinOB);
244
245 result[0] = (float) x;
246 result[1] = (float) y;
247 result[2] = (float) (z - (EARTH_RADIUS + origin.getAltitude()));
248 result[3] = 1;
249 }
250}
Note: See TracBrowser for help on using the repository browser.