1 /* 2 * Compass.java 18 mars 2010 3 * 4 * Sweet Home 3D, Copyright (c) 2006 Emmanuel PUYBARET / eTeks <info@eteks.com> 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 */ 20 package com.eteks.sweethome3d.model; 21 22 import java.awt.geom.AffineTransform; 23 import java.awt.geom.Ellipse2D; 24 import java.awt.geom.PathIterator; 25 import java.awt.geom.Rectangle2D; 26 import java.lang.ref.WeakReference; 27 import java.util.Calendar; 28 import java.util.GregorianCalendar; 29 import java.util.HashMap; 30 import java.util.Map; 31 import java.util.TimeZone; 32 33 /** 34 * A compass used to locate where a home is located and how it's oriented towards North. 35 * @since 3.0 36 * @author Emmanuel Puybaret 37 * @author Fr�d�ric Mantegazza (Sun location algorithm) 38 */ 39 public class Compass extends HomeObject implements Selectable { 40 /** 41 * The properties of a compass that may change. <code>PropertyChangeListener</code>s added 42 * to a wall will be notified under a property name equal to the string value of one these properties. 43 */ 44 public enum Property {X, Y, DIAMETER, VISIBLE, NORTH_DIRECTION, LATITUDE, LONGITUDE, TIME_ZONE} 45 46 private static final long serialVersionUID = 1L; 47 48 private float x; 49 private float y; 50 private float diameter; 51 private boolean visible; 52 private float northDirection; 53 private float latitude; 54 private float longitude; 55 private TimeZone timeZone; 56 57 private transient float [][] pointsCache; 58 private transient Calendar dateCache; 59 private transient float sunElevationCache; 60 private transient float sunAzimuthCache; 61 62 63 private static WeakReference<Map<String, GeographicPoint>> timeZoneGeographicPointsReference; 64 65 /** 66 * Creates a compass drawn at the given point. 67 * North direction is set to zero, time zone to default 68 * and the latitude and the longitude of this new compass is equal 69 * to the geographic point matching the default time zone. 70 */ Compass(float x, float y, float diameter)71 public Compass(float x, float y, float diameter) { 72 this(createId("compass"), x, y, diameter); 73 } 74 75 /** 76 * Creates a compass drawn at the given point. 77 * North direction is set to zero, time zone to default 78 * and the latitude and the longitude of this new compass is equal 79 * to the geographic point matching the default time zone. 80 * @since 6.4 81 */ Compass(String id, float x, float y, float diameter)82 public Compass(String id, float x, float y, float diameter) { 83 super(id); 84 this.x = x; 85 this.y = y; 86 this.diameter = diameter; 87 this.visible = true; 88 this.timeZone = TimeZone.getDefault(); 89 initGeographicPoint(); 90 } 91 92 /** 93 * Returns the abscissa of the center of this compass. 94 */ getX()95 public float getX() { 96 return this.x; 97 } 98 99 /** 100 * Sets the abscissa of the center of this compass. Once this compass is updated, 101 * listeners added to this compass will receive a change notification. 102 */ setX(float x)103 public void setX(float x) { 104 if (x != this.x) { 105 float oldX = this.x; 106 this.x = x; 107 this.pointsCache = null; 108 firePropertyChange(Property.X.name(), oldX, x); 109 } 110 } 111 112 /** 113 * Returns the ordinate of the center of this compass. 114 */ getY()115 public float getY() { 116 return this.y; 117 } 118 119 /** 120 * Sets the ordinate of the center of this compass. Once this compass is updated, 121 * listeners added to this compass will receive a change notification. 122 */ setY(float y)123 public void setY(float y) { 124 if (y != this.y) { 125 float oldY = this.y; 126 this.y = y; 127 this.pointsCache = null; 128 firePropertyChange(Property.Y.name(), oldY, y); 129 } 130 } 131 132 /** 133 * Returns the diameter of this compass. 134 */ getDiameter()135 public float getDiameter() { 136 return this.diameter; 137 } 138 139 /** 140 * Sets the diameter of this compass. Once this compass is updated, 141 * listeners added to this compass will receive a change notification. 142 */ setDiameter(float diameter)143 public void setDiameter(float diameter) { 144 if (diameter != this.diameter) { 145 float oldDiameter = this.diameter; 146 this.diameter = diameter; 147 this.pointsCache = null; 148 firePropertyChange(Property.DIAMETER.name(), oldDiameter, diameter); 149 } 150 } 151 152 /** 153 * Returns <code>true</code> if this compass is visible. 154 */ isVisible()155 public boolean isVisible() { 156 return this.visible; 157 } 158 159 /** 160 * Sets whether this compass is visible or not. Once this compass is updated, 161 * listeners added to this piece will receive a change notification. 162 */ setVisible(boolean visible)163 public void setVisible(boolean visible) { 164 if (visible != this.visible) { 165 this.visible = visible; 166 firePropertyChange(Property.VISIBLE.name(), !visible, visible); 167 } 168 } 169 170 /** 171 * Returns the North direction angle of this compass in radians. 172 */ getNorthDirection()173 public float getNorthDirection() { 174 return this.northDirection; 175 } 176 177 /** 178 * Sets the North direction angle of this compass. Once this compass is updated, 179 * listeners added to this compass will receive a change notification. 180 */ setNorthDirection(float northDirection)181 public void setNorthDirection(float northDirection) { 182 if (northDirection != this.northDirection) { 183 float oldNorthDirection = this.northDirection; 184 this.northDirection = northDirection; 185 this.pointsCache = null; 186 firePropertyChange(Property.NORTH_DIRECTION.name(), oldNorthDirection, northDirection); 187 } 188 } 189 190 /** 191 * Returns the latitude of this compass in radians. 192 */ getLatitude()193 public final float getLatitude() { 194 return this.latitude; 195 } 196 197 /** 198 * Sets the latitude of this compass. Once this compass is updated, 199 * listeners added to this compass will receive a change notification. 200 */ setLatitude(float latitude)201 public void setLatitude(float latitude) { 202 if (latitude != this.latitude) { 203 float oldLatitude = this.latitude; 204 this.latitude = latitude; 205 this.dateCache = null; 206 firePropertyChange(Property.LATITUDE.name(), oldLatitude, latitude); 207 } 208 } 209 210 /** 211 * Returns the longitude of this compass in radians. 212 */ getLongitude()213 public final float getLongitude() { 214 return this.longitude; 215 } 216 217 /** 218 * Sets the longitude of the center of this compass. Once this compass is updated, 219 * listeners added to this compass will receive a change notification. 220 */ setLongitude(float longitude)221 public void setLongitude(float longitude) { 222 if (longitude != this.longitude) { 223 float oldLongitude = this.longitude; 224 this.longitude = longitude; 225 this.dateCache = null; 226 firePropertyChange(Property.LONGITUDE.name(), oldLongitude, longitude); 227 } 228 } 229 230 /** 231 * Returns the time zone identifier of this compass. 232 * @see java.util.TimeZone 233 */ getTimeZone()234 public String getTimeZone() { 235 return this.timeZone.getID(); 236 } 237 238 /** 239 * Sets the time zone identifier of this compass. Once this compass is updated, 240 * listeners added to this compass will receive a change notification. 241 * @throws IllegalArgumentException if <code>timeZone</code> is <code>null</code> or contains an unknown identifier. 242 * @see java.util.TimeZone 243 */ setTimeZone(String timeZone)244 public void setTimeZone(String timeZone) { 245 if (!this.timeZone.getID().equals(timeZone)) { 246 if (timeZone == null) { 247 throw new IllegalArgumentException("Time zone ID can't be null"); 248 } 249 String oldTimeZone = this.timeZone.getID(); 250 this.timeZone = TimeZone.getTimeZone(timeZone); 251 this.dateCache = null; 252 firePropertyChange(Property.TIME_ZONE.name(), oldTimeZone, timeZone); 253 } 254 } 255 256 /** 257 * Returns the corner points of the square that contains compass disc. 258 */ getPoints()259 public float [][] getPoints() { 260 if (this.pointsCache == null) { 261 // Create the rectangle that matches piece bounds 262 Rectangle2D pieceRectangle = new Rectangle2D.Float( 263 getX() - getDiameter() / 2, 264 getY() - getDiameter() / 2, 265 getDiameter(), getDiameter()); 266 // Apply rotation to the rectangle 267 AffineTransform rotation = AffineTransform.getRotateInstance(getNorthDirection(), getX(), getY()); 268 this.pointsCache = new float[4][2]; 269 PathIterator it = pieceRectangle.getPathIterator(rotation); 270 for (int i = 0; i < this.pointsCache.length; i++) { 271 it.currentSegment(this.pointsCache [i]); 272 it.next(); 273 } 274 } 275 return new float [][] {this.pointsCache [0].clone(), this.pointsCache [1].clone(), 276 this.pointsCache [2].clone(), this.pointsCache [3].clone()}; 277 } 278 279 /** 280 * Returns <code>true</code> if the disc of this compass intersects 281 * with the horizontal rectangle which opposite corners are at points 282 * (<code>x0</code>, <code>y0</code>) and (<code>x1</code>, <code>y1</code>). 283 */ intersectsRectangle(float x0, float y0, float x1, float y1)284 public boolean intersectsRectangle(float x0, float y0, 285 float x1, float y1) { 286 Rectangle2D rectangle = new Rectangle2D.Float(x0, y0, 0, 0); 287 rectangle.add(x1, y1); 288 return new Ellipse2D.Float(getX() - getDiameter() / 2, getY() - getDiameter() / 2, getDiameter(), getDiameter()).intersects(rectangle); 289 } 290 291 /** 292 * Returns <code>true</code> if the disc of this compass contains 293 * the point at (<code>x</code>, <code>y</code>) 294 * with a given <code>margin</code>. 295 */ containsPoint(float x, float y, float margin)296 public boolean containsPoint(float x, float y, float margin) { 297 Ellipse2D shape = new Ellipse2D.Float(getX() - getDiameter() / 2, getY() - getDiameter() / 2, getDiameter(), getDiameter()); 298 if (margin == 0) { 299 return shape.contains(x, y); 300 } else { 301 return shape.intersects(x - margin, y - margin, 2 * margin, 2 * margin); 302 } 303 } 304 305 /** 306 * Moves this compass of (<code>dx</code>, <code>dy</code>) units. 307 */ move(float dx, float dy)308 public void move(float dx, float dy) { 309 setX(getX() + dx); 310 setY(getY() + dy); 311 } 312 313 /** 314 * Returns a clone of this compass. 315 */ 316 @Override clone()317 public Compass clone() { 318 return (Compass)super.clone(); 319 } 320 321 /** 322 * Returns the elevation angle of the Sun in the sky in radians at a given 323 * <code>date</code> in milliseconds since the Epoch. 324 * See <a href="http://en.wikipedia.org/wiki/Horizontal_coordinate_system">Sun 325 * azimuth and elevation angles</a> for more information. 326 */ getSunElevation(long date)327 public float getSunElevation(long date) { 328 updateSunLocation(date); 329 return this.sunElevationCache; 330 } 331 332 /** 333 * Returns the azimuth angle of the Sun in the sky in radians at a given 334 * <code>date</code> in milliseconds since the Epoch. 335 * See <a href="http://en.wikipedia.org/wiki/Horizontal_coordinate_system">Sun 336 * azimuth and elevation angles</a> for more information. 337 */ getSunAzimuth(long date)338 public float getSunAzimuth(long date) { 339 updateSunLocation(date); 340 return this.sunAzimuthCache; 341 } 342 343 /** 344 * Computes the Sun's location in the sky at a given <code>date</code>. 345 */ updateSunLocation(long date)346 private void updateSunLocation(long date) { 347 if (this.dateCache == null 348 || this.dateCache.getTimeInMillis() != date) { 349 this.dateCache = new GregorianCalendar(this.timeZone); 350 this.dateCache.setTimeInMillis(date); 351 352 int year = this.dateCache.get(Calendar.YEAR); 353 int month = this.dateCache.get(Calendar.MONTH) + 1; // Based on 1 for January 354 int day = this.dateCache.get(Calendar.DAY_OF_MONTH); 355 int hour = this.dateCache.get(Calendar.HOUR_OF_DAY); 356 int minute = this.dateCache.get(Calendar.MINUTE); 357 int second = this.dateCache.get(Calendar.SECOND); 358 int timeZone = this.dateCache.getTimeZone().getRawOffset() / 3600000; 359 int savingTime = this.dateCache.get(Calendar.DST_OFFSET) / 3600000; 360 361 double julianDay = computeJulianDay(year, month, day, hour, minute, second, timeZone, savingTime); 362 double siderealTime = toSiderealTime(julianDay); 363 double angleH = 360. * siderealTime / 23.9344; 364 double angleT = (hour - (timeZone + savingTime) - 12. + minute / 60. + second / 3600.) * 360. / 23.9344; 365 double angle = angleH + angleT; 366 367 // Compute equatorial coordinates 368 double g = 357.529 + 0.98560028 * julianDay; 369 double q = 280.459 + 0.98564736 * julianDay; 370 double l = q + 1.915 * Math.sin(Math.toRadians(g)) + 0.020 * Math.sin(Math.toRadians(2 * g)); 371 double e = 23.439 - 0.00000036 * julianDay; 372 double rightAscension = Math.toDegrees(Math.atan(Math.cos(Math.toRadians(e)) * Math.sin(Math.toRadians(l)) / Math.cos(Math.toRadians(l)))) / 15.; 373 if (Math.cos(Math.toRadians(l)) < 0.) { 374 rightAscension += 12.; 375 } 376 if ((Math.cos(Math.toRadians(l)) > 0.) && (Math.sin(Math.toRadians(l)) < 0.)) { 377 rightAscension += 24.; 378 } 379 double declination = Math.asin(Math.sin(Math.toRadians(e)) * Math.sin(Math.toRadians(l))); 380 381 double hourAngle = Math.toRadians(angle - rightAscension * 15. + Math.toDegrees(this.longitude)); 382 double elevation = Math.asin(Math.sin(declination) * Math.sin(this.latitude) - Math.cos(declination) * Math.cos(this.latitude) * Math.cos(hourAngle)); 383 double azimuth = Math.acos((Math.sin(declination) - Math.sin(this.latitude) * Math.sin(elevation)) / (Math.cos(this.latitude) * Math.cos(elevation))); 384 double sinAzimuth = (Math.cos(declination) * Math.sin(hourAngle)) / Math.cos(elevation); 385 if (sinAzimuth < 0.) { 386 azimuth = Math.PI * 2 - azimuth; 387 } 388 389 this.sunElevationCache = (float)elevation; 390 this.sunAzimuthCache = (float)azimuth; 391 } 392 } 393 computeJulianDay(int year, int month, int day, int hour, int minute, int second, int timeZone, int savingTime)394 private double computeJulianDay(int year, int month, int day, int hour, int minute, int second, int timeZone, int savingTime) { 395 double dayPart = day + hour / 24. + minute / 1440. + second / 86400.; 396 if (month == 1 || month == 2) { 397 year -= 1; 398 month += 12; 399 } 400 int a = year / 100; 401 int b = 2 - a + a / 4; 402 403 double julianDay = (int)(365.25 * (year + 4716.)) + (int)((30.6001 * (month + 1))) + dayPart + b - 1524.5; 404 julianDay -= (timeZone + savingTime) / 24.; 405 julianDay -= 2451545.; 406 return julianDay; 407 } 408 toSiderealTime(double julianDay)409 private double toSiderealTime(double julianDay) { 410 double centuries = julianDay / 36525.; 411 double siderealTime = (24110.54841 + (8640184.812866 * centuries) + (0.093104 * Math.pow(centuries, 2.)) - (0.0000062 * Math.pow(centuries, 3.))) / 3600.; 412 return ((siderealTime / 24.) - (int)(siderealTime / 24.)) * 24.; 413 } 414 415 /** 416 * Inits the latitudeInDegrees and longitudeInDegrees where this compass is located from the id of the default time zone. 417 */ initGeographicPoint()418 private void initGeographicPoint() { 419 Map<String, GeographicPoint> timeZoneGeographicPoints; 420 if (timeZoneGeographicPointsReference != null) { 421 timeZoneGeographicPoints = timeZoneGeographicPointsReference.get(); 422 } else { 423 timeZoneGeographicPoints = null; 424 } 425 426 if (timeZoneGeographicPoints == null) { 427 timeZoneGeographicPoints = new HashMap<String, GeographicPoint>(); 428 // Default geographic points for Java 6 time zone ids 429 // from free data provided by MaxMind WorldCities and Postal Code Databases 430 // at http://www.maxmind.com/app/worldcities and from Wikipedia 431 GeographicPoint apia = new GeographicPoint(-13.8333333f, -171.7333333f); 432 timeZoneGeographicPoints.put("Etc/GMT+11", apia); // Apia 433 timeZoneGeographicPoints.put("Pacific/Apia", apia); 434 timeZoneGeographicPoints.put("Pacific/Midway", new GeographicPoint(28.2f, -177.35f)); 435 timeZoneGeographicPoints.put("Pacific/Niue", new GeographicPoint(-19.055f, -169.92f)); // Alofi 436 timeZoneGeographicPoints.put("Pacific/Pago_Pago", new GeographicPoint(-14.2780556f, -170.7025000f)); 437 timeZoneGeographicPoints.put("Pacific/Samoa", apia); 438 timeZoneGeographicPoints.put("US/Samoa", apia); 439 timeZoneGeographicPoints.put("America/Adak", new GeographicPoint(51.8800000f, -176.6580556f)); 440 timeZoneGeographicPoints.put("America/Atka", new GeographicPoint(52.1961111f, -174.2005556f)); 441 GeographicPoint honolulu = new GeographicPoint(21.3069444f, -157.8583333f); 442 timeZoneGeographicPoints.put("Etc/GMT+10", honolulu); // Honolulu 443 timeZoneGeographicPoints.put("Pacific/Fakaofo", new GeographicPoint(-9.3653f, -171.215f)); 444 timeZoneGeographicPoints.put("Pacific/Honolulu", honolulu); 445 timeZoneGeographicPoints.put("Pacific/Johnston", new GeographicPoint(16.75f, -169.517f)); 446 timeZoneGeographicPoints.put("Pacific/Rarotonga", new GeographicPoint(-21.233f, -159.783f)); 447 timeZoneGeographicPoints.put("Pacific/Tahiti", new GeographicPoint(-17.5333333f, -149.5666667f)); // Papeete 448 timeZoneGeographicPoints.put("SystemV/HST10", honolulu); // Honolulu 449 timeZoneGeographicPoints.put("US/Aleutian", new GeographicPoint(54.817f, 164.033f)); 450 timeZoneGeographicPoints.put("US/Hawaii", honolulu); // Honolulu 451 timeZoneGeographicPoints.put("Pacific/Marquesas", new GeographicPoint(-9.45f, -139.38f)); 452 GeographicPoint anchorage = new GeographicPoint(61.2180556f, -149.9002778f); 453 timeZoneGeographicPoints.put("America/Anchorage", anchorage); 454 timeZoneGeographicPoints.put("America/Juneau", new GeographicPoint(58.3019444f, -134.4197222f)); 455 timeZoneGeographicPoints.put("America/Nome", new GeographicPoint(64.5011111f, -165.4063889f)); 456 timeZoneGeographicPoints.put("America/Yakutat", new GeographicPoint(59.5469444f, -139.7272222f)); 457 timeZoneGeographicPoints.put("Etc/GMT+9", anchorage); // Anchorage 458 timeZoneGeographicPoints.put("Pacific/Gambier", new GeographicPoint(-23.1178f, -134.97f)); 459 timeZoneGeographicPoints.put("SystemV/YST9", anchorage); // Anchorage 460 timeZoneGeographicPoints.put("SystemV/YST9YDT", anchorage); // Anchorage 461 timeZoneGeographicPoints.put("US/Alaska", anchorage); // Anchorage 462 timeZoneGeographicPoints.put("America/Dawson", new GeographicPoint(64.066667f, -139.416667f)); 463 timeZoneGeographicPoints.put("America/Ensenada", new GeographicPoint(31.866667f, -116.616667f)); 464 GeographicPoint losAngeles = new GeographicPoint(34.0522222f, -118.2427778f); 465 timeZoneGeographicPoints.put("America/Los_Angeles", losAngeles); 466 timeZoneGeographicPoints.put("America/Santa_Isabel", new GeographicPoint(28.383333f, -113.35f)); 467 timeZoneGeographicPoints.put("America/Tijuana", new GeographicPoint(32.533333f, -117.016667f)); 468 timeZoneGeographicPoints.put("America/Vancouver", new GeographicPoint(49.25f, -123.133333f)); 469 timeZoneGeographicPoints.put("America/Whitehorse", new GeographicPoint(60.716667f, -135.05f)); 470 timeZoneGeographicPoints.put("Canada/Pacific", new GeographicPoint(49.25f, -123.133333f)); // Vancouver 471 timeZoneGeographicPoints.put("Canada/Yukon", new GeographicPoint(60.716667f, -135.05f)); // Whitehorse 472 timeZoneGeographicPoints.put("Etc/GMT+8", losAngeles); // Los Angeles 473 timeZoneGeographicPoints.put("Mexico/BajaNorte", new GeographicPoint(32.533333f, -117.016667f)); // Tijuana 474 timeZoneGeographicPoints.put("Pacific/Pitcairn", new GeographicPoint(-25.0667f, -130.1f)); // Adamstown 475 timeZoneGeographicPoints.put("SystemV/PST8", losAngeles); // Los Angeles 476 timeZoneGeographicPoints.put("SystemV/PST8PDT", losAngeles); // Los Angeles 477 timeZoneGeographicPoints.put("US/Pacific", losAngeles); // Los Angeles 478 timeZoneGeographicPoints.put("US/Pacific-New", losAngeles); // Los Angeles 479 timeZoneGeographicPoints.put("America/Boise", new GeographicPoint(43.6136111f, -116.2025000f)); 480 timeZoneGeographicPoints.put("America/Cambridge_Bay", new GeographicPoint(69.116667f, -105.033333f)); 481 timeZoneGeographicPoints.put("America/Chihuahua", new GeographicPoint(28.633333f, -106.083333f)); 482 timeZoneGeographicPoints.put("America/Dawson_Creek", new GeographicPoint(55.766667f, -120.233333f)); 483 GeographicPoint denver = new GeographicPoint(39.7391667f, -104.9841667f); 484 timeZoneGeographicPoints.put("America/Denver", denver); 485 timeZoneGeographicPoints.put("America/Edmonton", new GeographicPoint(53.55f, -113.5f)); 486 timeZoneGeographicPoints.put("America/Hermosillo", new GeographicPoint(29.066667f, -110.966667f)); 487 timeZoneGeographicPoints.put("America/Inuvik", new GeographicPoint(68.35f, -133.7f)); 488 timeZoneGeographicPoints.put("America/Mazatlan", new GeographicPoint(23.216667f, -106.416667f)); 489 timeZoneGeographicPoints.put("America/Ojinaga", new GeographicPoint(29.566667f, -104.416667f)); 490 timeZoneGeographicPoints.put("America/Phoenix", new GeographicPoint(33.4483333f, -112.0733333f)); 491 timeZoneGeographicPoints.put("America/Shiprock", new GeographicPoint(36.7855556f, -108.6863889f)); 492 timeZoneGeographicPoints.put("America/Yellowknife", new GeographicPoint(62.45f, -114.35f)); 493 timeZoneGeographicPoints.put("Canada/Mountain", new GeographicPoint(53.55f, -113.5f)); // Edmonton 494 timeZoneGeographicPoints.put("Etc/GMT+7", denver); // Denver 495 timeZoneGeographicPoints.put("Mexico/BajaSur", new GeographicPoint(32.567f, -116.633f)); // Tecate 496 timeZoneGeographicPoints.put("SystemV/MST7", denver); // Denver 497 timeZoneGeographicPoints.put("SystemV/MST7MDT", denver); // Denver 498 timeZoneGeographicPoints.put("US/Arizona", new GeographicPoint(33.4483333f, -112.0733333f)); // Phoenix 499 timeZoneGeographicPoints.put("US/Mountain", denver); // Denver 500 timeZoneGeographicPoints.put("America/Belize", new GeographicPoint(17.4833333f, -88.1833333f)); 501 timeZoneGeographicPoints.put("America/Cancun", new GeographicPoint(21.166667f, -86.833333f)); 502 GeographicPoint chicago = new GeographicPoint(41.8500000f, -87.6500000f); 503 timeZoneGeographicPoints.put("America/Chicago", chicago); 504 timeZoneGeographicPoints.put("America/Costa_Rica", new GeographicPoint(9.9333333f, -84.0833333f)); // San Jose 505 timeZoneGeographicPoints.put("America/El_Salvador", new GeographicPoint(13.7086111f, -89.2030556f)); // San Salvador 506 timeZoneGeographicPoints.put("America/Guatemala", new GeographicPoint(14.6211111f, -90.5269444f)); 507 timeZoneGeographicPoints.put("America/Knox_IN", new GeographicPoint(41.2958333f, -86.6250000f)); // Knox 508 timeZoneGeographicPoints.put("America/Managua", new GeographicPoint(12.1508333f, -86.2683333f)); 509 timeZoneGeographicPoints.put("America/Matamoros", new GeographicPoint(25.883333f, -97.5f)); 510 timeZoneGeographicPoints.put("America/Menominee", new GeographicPoint(45.1077778f, -87.6141667f)); 511 timeZoneGeographicPoints.put("America/Merida", new GeographicPoint(20.966667f, -89.616667f)); 512 timeZoneGeographicPoints.put("America/Mexico_City", new GeographicPoint(19.434167f, -99.138611f)); 513 timeZoneGeographicPoints.put("America/Monterrey", new GeographicPoint(25.666667f, -100.316667f)); 514 timeZoneGeographicPoints.put("America/Rainy_River", new GeographicPoint(48.716667f, -94.566667f)); 515 timeZoneGeographicPoints.put("America/Rankin_Inlet", new GeographicPoint(62.816667f, -92.083333f)); 516 timeZoneGeographicPoints.put("America/Regina", new GeographicPoint(50.45f, -104.616667f)); 517 timeZoneGeographicPoints.put("America/Swift_Current", new GeographicPoint(50.283333f, -107.766667f)); 518 timeZoneGeographicPoints.put("America/Tegucigalpa", new GeographicPoint(14.1f, -87.2166667f)); 519 timeZoneGeographicPoints.put("America/Winnipeg", new GeographicPoint(49.883333f, -97.166667f)); 520 timeZoneGeographicPoints.put("Canada/Central", new GeographicPoint(50.45f, -104.616667f)); // Regina 521 timeZoneGeographicPoints.put("Canada/East-Saskatchewan", new GeographicPoint(51.216667f, -102.466667f)); // Yorkton 522 timeZoneGeographicPoints.put("Canada/Saskatchewan", new GeographicPoint(50.45f, -104.616667f)); // Regina 523 timeZoneGeographicPoints.put("Chile/EasterIsland", new GeographicPoint(-27.15f, -109.425f)); 524 timeZoneGeographicPoints.put("Etc/GMT+6", chicago); // Chicago 525 timeZoneGeographicPoints.put("Mexico/General", new GeographicPoint(19.434167f, -99.138611f)); // Mexico City 526 timeZoneGeographicPoints.put("Pacific/Easter", new GeographicPoint(-27.15f, -109.425f)); // Easter Island 527 timeZoneGeographicPoints.put("Pacific/Galapagos", new GeographicPoint(-0.667f, -90.55f)); 528 timeZoneGeographicPoints.put("SystemV/CST6", chicago); // Chicago 529 timeZoneGeographicPoints.put("SystemV/CST6CDT", chicago); // Chicago 530 timeZoneGeographicPoints.put("US/Central", chicago); // Chicago 531 timeZoneGeographicPoints.put("US/Indiana-Starke", new GeographicPoint(41.2958333f, -86.6250000f)); // Knox 532 timeZoneGeographicPoints.put("America/Atikokan", new GeographicPoint(48.75f, -91.616667f)); 533 timeZoneGeographicPoints.put("America/Bogota", new GeographicPoint(4.6f, -74.0833333f)); 534 timeZoneGeographicPoints.put("America/Cayman", new GeographicPoint(19.3f, -81.3833333f)); // George Town 535 timeZoneGeographicPoints.put("America/Coral_Harbour", new GeographicPoint(64.133333f, -83.166667f)); 536 timeZoneGeographicPoints.put("America/Detroit", new GeographicPoint(42.3313889f, -83.0458333f)); 537 timeZoneGeographicPoints.put("America/Fort_Wayne", new GeographicPoint(41.1305556f, -85.1288889f)); 538 timeZoneGeographicPoints.put("America/Grand_Turk", new GeographicPoint(21.4666667f, -71.1333333f)); 539 timeZoneGeographicPoints.put("America/Guayaquil", new GeographicPoint(-2.1666667f, -79.9f)); 540 timeZoneGeographicPoints.put("America/Havana", new GeographicPoint(23.1319444f, -82.3641667f)); 541 timeZoneGeographicPoints.put("America/Indianapolis", new GeographicPoint(39.7683333f, -86.1580556f)); 542 timeZoneGeographicPoints.put("America/Iqaluit", new GeographicPoint(63.733333f, -68.5f)); 543 timeZoneGeographicPoints.put("America/Jamaica", new GeographicPoint(18.0f, -76.8f)); // Kingston 544 timeZoneGeographicPoints.put("America/Lima", new GeographicPoint(-12.05f, -77.05f)); 545 timeZoneGeographicPoints.put("America/Louisville", new GeographicPoint(38.2541667f, -85.7594444f)); 546 timeZoneGeographicPoints.put("America/Montreal", new GeographicPoint(45.5f, -73.583333f)); 547 timeZoneGeographicPoints.put("America/Nassau", new GeographicPoint(25.0833333f, -77.35f)); 548 GeographicPoint newYork = new GeographicPoint(40.7141667f, -74.0063889f); 549 timeZoneGeographicPoints.put("America/New_York", newYork); 550 timeZoneGeographicPoints.put("America/Nipigon", new GeographicPoint(49.016667f, -88.25f)); 551 timeZoneGeographicPoints.put("America/Panama", new GeographicPoint(8.9666667f, -79.5333333f)); 552 timeZoneGeographicPoints.put("America/Pangnirtung", new GeographicPoint(66.133333f, -65.75f)); 553 timeZoneGeographicPoints.put("America/Port-au-Prince", new GeographicPoint(18.5391667f, -72.335f)); 554 timeZoneGeographicPoints.put("America/Resolute", new GeographicPoint(74.683333f, -94.9f)); 555 timeZoneGeographicPoints.put("America/Thunder_Bay", new GeographicPoint(48.4f, -89.233333f)); 556 timeZoneGeographicPoints.put("America/Toronto", new GeographicPoint(43.666667f, -79.416667f)); 557 timeZoneGeographicPoints.put("Canada/Eastern", new GeographicPoint(43.666667f, -79.416667f)); // Toronto 558 timeZoneGeographicPoints.put("Etc/GMT+5", newYork); // New York 559 timeZoneGeographicPoints.put("SystemV/EST5", newYork); // New York 560 timeZoneGeographicPoints.put("SystemV/EST5EDT", newYork); // New York 561 timeZoneGeographicPoints.put("US/East-Indiana", new GeographicPoint(36.8381f, -84.85f)); // Monticello 562 timeZoneGeographicPoints.put("US/Eastern", newYork); // New York 563 timeZoneGeographicPoints.put("US/Michigan", new GeographicPoint(42.3313889f, -83.0458333f)); // Detroit 564 timeZoneGeographicPoints.put("America/Caracas", new GeographicPoint(10.5f, -66.9166667f)); 565 timeZoneGeographicPoints.put("America/Anguilla", new GeographicPoint(18.2166667f, -63.05f)); // The Valley 566 timeZoneGeographicPoints.put("America/Antigua", new GeographicPoint(17.1166667f, -61.85f)); // Saint John's 567 timeZoneGeographicPoints.put("America/Aruba", new GeographicPoint(10.5411111f, -72.9175f)); 568 timeZoneGeographicPoints.put("America/Asuncion", new GeographicPoint(-25.2666667f, -57.6666667f)); 569 timeZoneGeographicPoints.put("America/Barbados", new GeographicPoint(13.1f, -59.6166667f)); // Bridgetown 570 timeZoneGeographicPoints.put("America/Blanc-Sablon", new GeographicPoint(51.433333f, -57.116667f)); 571 timeZoneGeographicPoints.put("America/Boa_Vista", new GeographicPoint(2.8166667f, -60.6666667f)); 572 timeZoneGeographicPoints.put("America/Campo_Grande", new GeographicPoint(-20.45f, -54.6166667f)); 573 timeZoneGeographicPoints.put("America/Cuiaba", new GeographicPoint(-15.5833333f, -56.0833333f)); 574 timeZoneGeographicPoints.put("America/Curacao", new GeographicPoint(12.1167f, -68.933f)); // Willemstad 575 timeZoneGeographicPoints.put("America/Dominica", new GeographicPoint(15.3f, -61.4f)); // Roseau 576 timeZoneGeographicPoints.put("America/Eirunepe", new GeographicPoint(-6.6666667f, -69.8666667f)); 577 timeZoneGeographicPoints.put("America/Glace_Bay", new GeographicPoint(46.2f, -59.966667f)); 578 timeZoneGeographicPoints.put("America/Goose_Bay", new GeographicPoint(53.333333f, -60.416667f)); 579 timeZoneGeographicPoints.put("America/Grenada", new GeographicPoint(12.05f, -61.75f)); // Saint George 580 timeZoneGeographicPoints.put("America/Guadeloupe", new GeographicPoint(16.2333333f, -61.5166667f)); // Pointe-a-Pitre 581 timeZoneGeographicPoints.put("America/Guyana", new GeographicPoint(6.8f, -58.1666667f)); // Georgetown 582 timeZoneGeographicPoints.put("America/Halifax", new GeographicPoint(44.65f, -63.6f)); 583 timeZoneGeographicPoints.put("America/La_Paz", new GeographicPoint(-16.5f, -68.15f)); 584 timeZoneGeographicPoints.put("America/Manaus", new GeographicPoint(-3.1133333f, -60.0252778f)); 585 timeZoneGeographicPoints.put("America/Marigot", new GeographicPoint(18.073f, 63.0844f)); // St Martin Island 586 timeZoneGeographicPoints.put("America/Martinique", new GeographicPoint(14.6f, -61.0833333f)); // Fort-de-France 587 timeZoneGeographicPoints.put("America/Moncton", new GeographicPoint(46.083333f, -64.766667f)); 588 timeZoneGeographicPoints.put("America/Montserrat", new GeographicPoint(16.7f, -62.2166667f)); // Plymouth 589 timeZoneGeographicPoints.put("America/Port_of_Spain", new GeographicPoint(10.65f, -61.5166667f)); 590 timeZoneGeographicPoints.put("America/Porto_Acre", new GeographicPoint(-9.5877778f, -67.5355556f)); 591 timeZoneGeographicPoints.put("America/Porto_Velho", new GeographicPoint(-8.7666667f, -63.9f)); 592 timeZoneGeographicPoints.put("America/Puerto_Rico", new GeographicPoint(18.467f, 66.117f)); // San Juan 593 timeZoneGeographicPoints.put("America/Rio_Branco", new GeographicPoint(-9.9666667f, -67.8f)); 594 GeographicPoint santiago = new GeographicPoint(-33.45f, -70.6666667f); 595 timeZoneGeographicPoints.put("America/Santiago", santiago); 596 timeZoneGeographicPoints.put("America/Santo_Domingo", new GeographicPoint(18.4666667f, -69.9f)); 597 timeZoneGeographicPoints.put("America/St_Barthelemy", new GeographicPoint(17.8978f, -62.851f)); // Gustavia 598 timeZoneGeographicPoints.put("America/St_Kitts", new GeographicPoint(17.3f, -62.733f)); // Basseterre 599 timeZoneGeographicPoints.put("America/St_Lucia", new GeographicPoint(14.0167f, -60.9833f)); // Castries 600 timeZoneGeographicPoints.put("America/St_Thomas", new GeographicPoint(18.3333f, -64.9167f)); 601 timeZoneGeographicPoints.put("America/St_Vincent", new GeographicPoint(13.1667f, -61.2333f)); // Kingstown 602 timeZoneGeographicPoints.put("America/Thule", new GeographicPoint(-54.2766667f, -36.5116667f)); // Grytviken 603 timeZoneGeographicPoints.put("America/Tortola", new GeographicPoint(18.4166667f, -64.6166667f)); // Road Town 604 timeZoneGeographicPoints.put("America/Virgin", new GeographicPoint(18.3438889f, -64.9311111f)); // Charlotte Amalie 605 timeZoneGeographicPoints.put("Antarctica/Palmer", new GeographicPoint(-64.25f, -62.833f)); 606 timeZoneGeographicPoints.put("Atlantic/Bermuda", new GeographicPoint(32.2941667f, -64.7838889f)); // Hamilton 607 timeZoneGeographicPoints.put("Atlantic/Stanley", new GeographicPoint(-51.7f, -57.85f)); 608 timeZoneGeographicPoints.put("Brazil/Acre", new GeographicPoint(-10.8833333f, -45.0833333f)); 609 timeZoneGeographicPoints.put("Brazil/West", new GeographicPoint(-10.8833333f, -45.0833333f)); // Acre 610 timeZoneGeographicPoints.put("Canada/Atlantic", new GeographicPoint(44.65f, -63.6f)); // Halifax 611 timeZoneGeographicPoints.put("Chile/Continental", santiago); // Santiago 612 timeZoneGeographicPoints.put("Etc/GMT+4", santiago); // Santiago 613 timeZoneGeographicPoints.put("SystemV/AST4", new GeographicPoint(44.65f, -63.6f)); // Halifax 614 timeZoneGeographicPoints.put("SystemV/AST4ADT", new GeographicPoint(44.65f, -63.6f)); // Halifax 615 timeZoneGeographicPoints.put("America/St_Johns", new GeographicPoint(47.5675f, -52.7072f)); 616 timeZoneGeographicPoints.put("Canada/Newfoundland", new GeographicPoint(47.5675f, -52.7072f)); // St John's 617 timeZoneGeographicPoints.put("America/Araguaina", new GeographicPoint(-7.16f, -48.0575f)); 618 timeZoneGeographicPoints.put("America/Bahia", new GeographicPoint(-12.9833333f, -38.5166667f)); // Salvador 619 timeZoneGeographicPoints.put("America/Belem", new GeographicPoint(-1.45f, -48.4833333f)); 620 timeZoneGeographicPoints.put("America/Buenos_Aires", new GeographicPoint(-34.5875f, -58.6725f)); 621 timeZoneGeographicPoints.put("America/Catamarca", new GeographicPoint(-28.4666667f, -65.7833333f)); 622 timeZoneGeographicPoints.put("America/Cayenne", new GeographicPoint(4.9333333f, -52.3333333f)); 623 timeZoneGeographicPoints.put("America/Cordoba", new GeographicPoint(-31.4f, -64.1833333f)); 624 timeZoneGeographicPoints.put("America/Fortaleza", new GeographicPoint(-3.7166667f, -38.5f)); 625 timeZoneGeographicPoints.put("America/Godthab", new GeographicPoint(64.1833333f, -51.75f)); 626 timeZoneGeographicPoints.put("America/Jujuy", new GeographicPoint(-24.1833333f, -65.3f)); 627 timeZoneGeographicPoints.put("America/Maceio", new GeographicPoint(-9.6666667f, -35.7166667f)); 628 timeZoneGeographicPoints.put("America/Mendoza", new GeographicPoint(-32.8833333f, -68.8166667f)); 629 timeZoneGeographicPoints.put("America/Miquelon", new GeographicPoint(47.0975f, -56.3813889f)); 630 timeZoneGeographicPoints.put("America/Montevideo", new GeographicPoint(-34.8580556f, -56.1708333f)); 631 timeZoneGeographicPoints.put("America/Paramaribo", new GeographicPoint(5.8333333f, -55.1666667f)); 632 timeZoneGeographicPoints.put("America/Recife", new GeographicPoint(-8.05f, -34.9f)); 633 timeZoneGeographicPoints.put("America/Rosario", new GeographicPoint(-32.9511111f, -60.6663889f)); 634 timeZoneGeographicPoints.put("America/Santarem", new GeographicPoint(-2.4333333f, -54.7f)); 635 GeographicPoint saoPaulo = new GeographicPoint(-23.5333333f, -46.6166667f); 636 timeZoneGeographicPoints.put("America/Sao_Paulo", saoPaulo); 637 timeZoneGeographicPoints.put("Antarctica/Rothera", new GeographicPoint(67.567f, 68.133f)); 638 timeZoneGeographicPoints.put("Brazil/East", saoPaulo); // Sao Paulo 639 timeZoneGeographicPoints.put("Etc/GMT+3", saoPaulo); // Sao Paulo 640 timeZoneGeographicPoints.put("America/Noronha", new GeographicPoint(3.85f, 25.417f)); 641 GeographicPoint southGeorgia = new GeographicPoint(54.25f, 36.75f); 642 timeZoneGeographicPoints.put("Atlantic/South_Georgia", southGeorgia); 643 timeZoneGeographicPoints.put("Brazil/DeNoronha", new GeographicPoint(3.85f, 25.417f)); 644 timeZoneGeographicPoints.put("Etc/GMT+2", southGeorgia); // South Georgia 645 timeZoneGeographicPoints.put("America/Scoresbysund", new GeographicPoint(70.4833333f, -21.9666667f)); 646 GeographicPoint azores = new GeographicPoint(37.4833333f, -2.5666667f); 647 timeZoneGeographicPoints.put("Atlantic/Azores", azores); 648 timeZoneGeographicPoints.put("Atlantic/Cape_Verde", new GeographicPoint(14.9166667f, -23.5166667f)); // Praia 649 timeZoneGeographicPoints.put("Etc/GMT+1", azores); // Azores 650 timeZoneGeographicPoints.put("Africa/Abidjan", new GeographicPoint(5.341111f, -4.028056f)); 651 timeZoneGeographicPoints.put("Africa/Accra", new GeographicPoint(5.55f, -0.2166667f)); 652 timeZoneGeographicPoints.put("Africa/Bamako", new GeographicPoint(12.65f, -8.0f)); 653 timeZoneGeographicPoints.put("Africa/Banjul", new GeographicPoint(13.4530556f, -16.5775f)); 654 timeZoneGeographicPoints.put("Africa/Bissau", new GeographicPoint(11.85f, -15.5833333f)); 655 timeZoneGeographicPoints.put("Africa/Casablanca", new GeographicPoint(33.5930556f, -7.6163889f)); 656 timeZoneGeographicPoints.put("Africa/Conakry", new GeographicPoint(9.5091667f, -13.7122222f)); 657 timeZoneGeographicPoints.put("Africa/Dakar", new GeographicPoint(14.6708333f, -17.4380556f)); 658 timeZoneGeographicPoints.put("Africa/El_Aaiun", new GeographicPoint(27.1536111f, -13.2033333f)); 659 timeZoneGeographicPoints.put("Africa/Freetown", new GeographicPoint(8.49f, -13.2341667f)); 660 timeZoneGeographicPoints.put("Africa/Lome", new GeographicPoint(6.1319444f, 1.2227778f)); 661 timeZoneGeographicPoints.put("Africa/Monrovia", new GeographicPoint(6.3105556f, -10.8047222f)); 662 timeZoneGeographicPoints.put("Africa/Nouakchott", new GeographicPoint(18.0863889f, -15.9752778f)); 663 timeZoneGeographicPoints.put("Africa/Ouagadougou", new GeographicPoint(12.3702778f, -1.5247222f)); 664 timeZoneGeographicPoints.put("Africa/Sao_Tome", new GeographicPoint(0.3333333f, 6.7333333f)); 665 timeZoneGeographicPoints.put("Africa/Timbuktu", new GeographicPoint(16.7666667f, -3.0166667f)); 666 timeZoneGeographicPoints.put("America/Danmarkshavn", new GeographicPoint(76.767f, 18.667f)); 667 timeZoneGeographicPoints.put("Atlantic/Canary", new GeographicPoint(28.45f, -16.2333333f)); // Santa Cruz de Tenerife 668 timeZoneGeographicPoints.put("Atlantic/Faeroe", new GeographicPoint(62.0166667f, -6.7666667f)); // Thorshavn 669 timeZoneGeographicPoints.put("Atlantic/Faroe", new GeographicPoint(62.0166667f, -6.7666667f)); // Thorshavn 670 timeZoneGeographicPoints.put("Atlantic/Madeira", new GeographicPoint(32.6333333f, -16.9f)); // Funchal 671 timeZoneGeographicPoints.put("Atlantic/Reykjavik", new GeographicPoint(64.15f, -21.95f)); 672 timeZoneGeographicPoints.put("Atlantic/St_Helena", new GeographicPoint(-15.9333333f, -5.7166667f)); // Jamestown 673 GeographicPoint greenwich = new GeographicPoint(51.466667f, 0f); 674 timeZoneGeographicPoints.put("Etc/GMT", greenwich); // Greenwich 675 timeZoneGeographicPoints.put("Etc/GMT+0", greenwich); // Greenwich 676 timeZoneGeographicPoints.put("Etc/GMT-0", greenwich); // Greenwich 677 timeZoneGeographicPoints.put("Etc/GMT0", greenwich); // Greenwich 678 timeZoneGeographicPoints.put("Etc/Greenwich", greenwich); 679 timeZoneGeographicPoints.put("Etc/UCT", greenwich); // Greenwich 680 timeZoneGeographicPoints.put("Etc/UTC", greenwich); // Greenwich 681 timeZoneGeographicPoints.put("Etc/Universal", greenwich); // Greenwich 682 timeZoneGeographicPoints.put("Etc/Zulu", greenwich); // Greenwich 683 timeZoneGeographicPoints.put("Europe/Belfast", new GeographicPoint(54.583333f, -5.933333f)); 684 timeZoneGeographicPoints.put("Europe/Dublin", new GeographicPoint(53.3330556f, -6.2488889f)); 685 timeZoneGeographicPoints.put("Europe/Guernsey", new GeographicPoint(49.45f, -2.533f)); // Saint-Pierre-Port 686 timeZoneGeographicPoints.put("Europe/Isle_of_Man", new GeographicPoint(54.14521f, -4.48172f)); // Douglas 687 timeZoneGeographicPoints.put("Europe/Jersey", new GeographicPoint(49.2f, -2.117f)); // Saint-Helier 688 timeZoneGeographicPoints.put("Europe/Lisbon", new GeographicPoint(38.7166667f, -9.1333333f)); 689 timeZoneGeographicPoints.put("Europe/London", new GeographicPoint(51.5f, -.116667f)); 690 timeZoneGeographicPoints.put("Africa/Algiers", new GeographicPoint(36.7630556f, 3.0505556f)); 691 timeZoneGeographicPoints.put("Africa/Bangui", new GeographicPoint(4.3666667f, 18.5833333f)); 692 timeZoneGeographicPoints.put("Africa/Brazzaville", new GeographicPoint(-4.2591667f, 15.2847222f)); 693 timeZoneGeographicPoints.put("Africa/Ceuta", new GeographicPoint(35.8902778f, -5.3075f)); 694 timeZoneGeographicPoints.put("Africa/Douala", new GeographicPoint(4.0502778f, 9.7f)); 695 timeZoneGeographicPoints.put("Africa/Kinshasa", new GeographicPoint(-4.3f, 15.3f)); 696 timeZoneGeographicPoints.put("Africa/Lagos", new GeographicPoint(6.4530556f, 3.3958333f)); 697 timeZoneGeographicPoints.put("Africa/Libreville", new GeographicPoint(0.3833333f, 9.45f)); 698 timeZoneGeographicPoints.put("Africa/Luanda", new GeographicPoint(-8.8383333f, 13.2344444f)); 699 timeZoneGeographicPoints.put("Africa/Malabo", new GeographicPoint(3.75f, 8.7833333f)); 700 timeZoneGeographicPoints.put("Africa/Ndjamena", new GeographicPoint(12.1130556f, 15.0491667f)); 701 timeZoneGeographicPoints.put("Africa/Niamey", new GeographicPoint(13.5166667f, 2.1166667f)); 702 timeZoneGeographicPoints.put("Africa/Porto-Novo", new GeographicPoint(6.4833333f, 2.6166667f)); 703 timeZoneGeographicPoints.put("Africa/Tunis", new GeographicPoint(36.8027778f, 10.1797222f)); 704 timeZoneGeographicPoints.put("Africa/Windhoek", new GeographicPoint(-22.57f, 17.0836111f)); 705 timeZoneGeographicPoints.put("Arctic/Longyearbyen", new GeographicPoint(78.2166667f, 15.6333333f)); 706 timeZoneGeographicPoints.put("Atlantic/Jan_Mayen", new GeographicPoint(71f, -8.333f)); 707 GeographicPoint paris = new GeographicPoint(48.866667f, 2.333333f); 708 timeZoneGeographicPoints.put("Etc/GMT-1", paris); // Paris 709 timeZoneGeographicPoints.put("Europe/Amsterdam", new GeographicPoint(52.35f, 4.9166667f)); 710 timeZoneGeographicPoints.put("Europe/Andorra", new GeographicPoint(42.5f, 1.5166667f)); 711 timeZoneGeographicPoints.put("Europe/Belgrade", new GeographicPoint(44.818611f, 20.468056f)); 712 timeZoneGeographicPoints.put("Europe/Berlin", new GeographicPoint(52.5166667f, 13.4f)); 713 timeZoneGeographicPoints.put("Europe/Bratislava", new GeographicPoint(48.15f, 17.1166667f)); 714 timeZoneGeographicPoints.put("Europe/Brussels", new GeographicPoint(50.833333f, 4.333333f)); 715 timeZoneGeographicPoints.put("Europe/Budapest", new GeographicPoint(47.5f, 19.0833333f)); 716 timeZoneGeographicPoints.put("Europe/Copenhagen", new GeographicPoint(55.6666667f, 12.5833333f)); 717 timeZoneGeographicPoints.put("Europe/Gibraltar", new GeographicPoint(36.1333333f, -5.35f)); 718 timeZoneGeographicPoints.put("Europe/Ljubljana", new GeographicPoint(46.0552778f, 14.5144444f)); 719 timeZoneGeographicPoints.put("Europe/Luxembourg", new GeographicPoint(49.6116667f, 6.13f)); 720 timeZoneGeographicPoints.put("Europe/Madrid", new GeographicPoint(40.4f, -3.6833333f)); 721 timeZoneGeographicPoints.put("Europe/Malta", new GeographicPoint(35.8997222f, 14.5147222f)); // La Valette 722 timeZoneGeographicPoints.put("Europe/Monaco", new GeographicPoint(43.7333333f, 7.4166667f)); 723 timeZoneGeographicPoints.put("Europe/Oslo", new GeographicPoint(59.916667f, 10.75f)); 724 timeZoneGeographicPoints.put("Europe/Paris", paris); 725 timeZoneGeographicPoints.put("Europe/Podgorica", new GeographicPoint(42.441111f, 19.263611f)); 726 timeZoneGeographicPoints.put("Europe/Prague", new GeographicPoint(50.0833333f, 14.4666667f)); 727 timeZoneGeographicPoints.put("Europe/Rome", new GeographicPoint(41.9f, 12.4833333f)); 728 timeZoneGeographicPoints.put("Europe/San_Marino", new GeographicPoint(43.9333333f, 12.45f)); 729 timeZoneGeographicPoints.put("Europe/Sarajevo", new GeographicPoint(43.85f, 18.3833333f)); 730 timeZoneGeographicPoints.put("Europe/Skopje", new GeographicPoint(42.0f, 21.4333333f)); 731 timeZoneGeographicPoints.put("Europe/Stockholm", new GeographicPoint(59.3333333f, 18.05f)); 732 timeZoneGeographicPoints.put("Europe/Tirane", new GeographicPoint(41.3275f, 19.8188889f)); 733 timeZoneGeographicPoints.put("Europe/Vaduz", new GeographicPoint(47.1333333f, 9.5166667f)); 734 timeZoneGeographicPoints.put("Europe/Vatican", new GeographicPoint(41.9f, 12.45f)); 735 timeZoneGeographicPoints.put("Europe/Vienna", new GeographicPoint(48.2f, 16.3666667f)); 736 timeZoneGeographicPoints.put("Europe/Warsaw", new GeographicPoint(52.25f, 21.0f)); 737 timeZoneGeographicPoints.put("Europe/Zagreb", new GeographicPoint(45.8f, 16.0f)); 738 timeZoneGeographicPoints.put("Europe/Zurich", new GeographicPoint(47.3666667f, 8.55f)); 739 timeZoneGeographicPoints.put("Africa/Blantyre", new GeographicPoint(-15.7833333f, 35.0f)); 740 timeZoneGeographicPoints.put("Africa/Bujumbura", new GeographicPoint(-3.3761111f, 29.36f)); 741 timeZoneGeographicPoints.put("Africa/Cairo", new GeographicPoint(30.05f, 31.25f)); 742 timeZoneGeographicPoints.put("Africa/Gaborone", new GeographicPoint(-24.6463889f, 25.9119444f)); 743 timeZoneGeographicPoints.put("Africa/Harare", new GeographicPoint(-17.8177778f, 31.0447222f)); 744 timeZoneGeographicPoints.put("Africa/Johannesburg", new GeographicPoint(-26.2f, 28.0833333f)); 745 timeZoneGeographicPoints.put("Africa/Kigali", new GeographicPoint(-1.9536111f, 30.0605556f)); 746 timeZoneGeographicPoints.put("Africa/Lubumbashi", new GeographicPoint(-11.666667f, 27.466667f)); 747 timeZoneGeographicPoints.put("Africa/Lusaka", new GeographicPoint(-15.4166667f, 28.2833333f)); 748 timeZoneGeographicPoints.put("Africa/Maputo", new GeographicPoint(-25.9652778f, 32.5891667f)); 749 timeZoneGeographicPoints.put("Africa/Maseru", new GeographicPoint(-29.3166667f, 27.4833333f)); 750 timeZoneGeographicPoints.put("Africa/Mbabane", new GeographicPoint(-26.3166667f, 31.1333333f)); 751 timeZoneGeographicPoints.put("Africa/Tripoli", new GeographicPoint(32.8925f, 13.18f)); 752 timeZoneGeographicPoints.put("Asia/Amman", new GeographicPoint(31.95f, 35.9333333f)); 753 timeZoneGeographicPoints.put("Asia/Beirut", new GeographicPoint(33.8719444f, 35.5097222f)); 754 timeZoneGeographicPoints.put("Asia/Damascus", new GeographicPoint(33.5f, 36.3f)); 755 timeZoneGeographicPoints.put("Asia/Gaza", new GeographicPoint(31.5f, 34.466667f)); 756 timeZoneGeographicPoints.put("Asia/Istanbul", new GeographicPoint(41.0186111f, 28.9647222f)); 757 timeZoneGeographicPoints.put("Asia/Jerusalem", new GeographicPoint(31.78f, 35.23f)); 758 timeZoneGeographicPoints.put("Asia/Nicosia", new GeographicPoint(35.1666667f, 33.3666667f)); 759 timeZoneGeographicPoints.put("Asia/Tel_Aviv", new GeographicPoint(32.0666667f, 34.7666667f)); 760 GeographicPoint athens = new GeographicPoint(37.9833333f, 23.7333333f); 761 timeZoneGeographicPoints.put("Etc/GMT-2", athens); // Athens 762 timeZoneGeographicPoints.put("Europe/Athens", new GeographicPoint(37.9833333f, 23.7333333f)); 763 timeZoneGeographicPoints.put("Europe/Bucharest", new GeographicPoint(44.4333333f, 26.1f)); 764 timeZoneGeographicPoints.put("Europe/Chisinau", new GeographicPoint(47.0055556f, 28.8575f)); 765 timeZoneGeographicPoints.put("Europe/Helsinki", new GeographicPoint(60.1755556f, 24.9341667f)); 766 timeZoneGeographicPoints.put("Europe/Istanbul", new GeographicPoint(41.0186111f, 28.9647222f)); 767 timeZoneGeographicPoints.put("Europe/Kaliningrad", new GeographicPoint(54.71f, 20.5f)); 768 timeZoneGeographicPoints.put("Europe/Kiev", new GeographicPoint(50.4333333f, 30.5166667f)); 769 timeZoneGeographicPoints.put("Europe/Mariehamn", new GeographicPoint(60.1f, 19.95f)); 770 timeZoneGeographicPoints.put("Europe/Minsk", new GeographicPoint(53.9f, 27.5666667f)); 771 timeZoneGeographicPoints.put("Europe/Nicosia", new GeographicPoint(35.1666667f, 33.3666667f)); 772 timeZoneGeographicPoints.put("Europe/Riga", new GeographicPoint(56.95f, 24.1f)); 773 timeZoneGeographicPoints.put("Europe/Simferopol", new GeographicPoint(44.95f, 34.1f)); 774 timeZoneGeographicPoints.put("Europe/Sofia", new GeographicPoint(42.6833333f, 23.3166667f)); 775 timeZoneGeographicPoints.put("Europe/Tallinn", new GeographicPoint(59.4338889f, 24.7280556f)); 776 timeZoneGeographicPoints.put("Europe/Tiraspol", new GeographicPoint(46.8402778f, 29.6433333f)); 777 timeZoneGeographicPoints.put("Europe/Uzhgorod", new GeographicPoint(48.6166667f, 22.3f)); 778 timeZoneGeographicPoints.put("Europe/Vilnius", new GeographicPoint(54.6833333f, 25.3166667f)); 779 timeZoneGeographicPoints.put("Europe/Zaporozhye", new GeographicPoint(47.833f, 35.1667f)); 780 timeZoneGeographicPoints.put("Africa/Addis_Ababa", new GeographicPoint(9.0333333f, 38.7f)); 781 timeZoneGeographicPoints.put("Africa/Asmara", new GeographicPoint(15.3333333f, 38.9333333f)); 782 timeZoneGeographicPoints.put("Africa/Asmera", new GeographicPoint(15.3333333f, 38.9333333f)); 783 timeZoneGeographicPoints.put("Africa/Dar_es_Salaam", new GeographicPoint(-6.8f, 39.2833333f)); 784 timeZoneGeographicPoints.put("Africa/Djibouti", new GeographicPoint(11.595f, 43.1480556f)); 785 timeZoneGeographicPoints.put("Africa/Kampala", new GeographicPoint(0.3155556f, 32.5655556f)); 786 timeZoneGeographicPoints.put("Africa/Khartoum", new GeographicPoint(15.5880556f, 32.5341667f)); 787 timeZoneGeographicPoints.put("Africa/Mogadishu", new GeographicPoint(2.0666667f, 45.3666667f)); 788 timeZoneGeographicPoints.put("Africa/Nairobi", new GeographicPoint(-1.2833333f, 36.8166667f)); 789 timeZoneGeographicPoints.put("Antarctica/Syowa", new GeographicPoint(-69f, 39.5833f)); 790 timeZoneGeographicPoints.put("Asia/Aden", new GeographicPoint(12.7794444f, 45.0366667f)); 791 timeZoneGeographicPoints.put("Asia/Baghdad", new GeographicPoint(33.3386111f, 44.3938889f)); 792 timeZoneGeographicPoints.put("Asia/Bahrain", new GeographicPoint(26.2361111f, 50.5830556f)); // Manama 793 timeZoneGeographicPoints.put("Asia/Kuwait", new GeographicPoint(29.3697222f, 47.9783333f)); 794 timeZoneGeographicPoints.put("Asia/Qatar", new GeographicPoint(25.2866667f, 51.5333333f)); // Doha 795 timeZoneGeographicPoints.put("Asia/Riyadh", new GeographicPoint(24.6408333f, 46.7727778f)); 796 GeographicPoint moscow = new GeographicPoint(55.7522222f, 37.6155556f); 797 timeZoneGeographicPoints.put("Etc/GMT-3", moscow); // Moscow 798 timeZoneGeographicPoints.put("Europe/Moscow", moscow); 799 timeZoneGeographicPoints.put("Europe/Volgograd", new GeographicPoint(48.8047222f, 44.5858333f)); 800 timeZoneGeographicPoints.put("Indian/Antananarivo", new GeographicPoint(-18.9166667f, 47.5166667f)); 801 timeZoneGeographicPoints.put("Indian/Comoro", new GeographicPoint(-11.7041667f, 43.2402778f)); // Moroni 802 timeZoneGeographicPoints.put("Indian/Mayotte", new GeographicPoint(-12.7794444f, 45.2272222f)); // Mamoudzou 803 timeZoneGeographicPoints.put("Asia/Riyadh87", new GeographicPoint(24.6408333f, 46.7727778f)); 804 timeZoneGeographicPoints.put("Asia/Riyadh88", new GeographicPoint(24.6408333f, 46.7727778f)); 805 timeZoneGeographicPoints.put("Asia/Riyadh89", new GeographicPoint(24.6408333f, 46.7727778f)); 806 timeZoneGeographicPoints.put("Mideast/Riyadh87", new GeographicPoint(24.6408333f, 46.7727778f)); 807 timeZoneGeographicPoints.put("Mideast/Riyadh88", new GeographicPoint(24.6408333f, 46.7727778f)); 808 timeZoneGeographicPoints.put("Mideast/Riyadh89", new GeographicPoint(24.6408333f, 46.7727778f)); 809 timeZoneGeographicPoints.put("Asia/Tehran", new GeographicPoint(35.6719444f, 51.4244444f)); 810 timeZoneGeographicPoints.put("Asia/Baku", new GeographicPoint(40.3952778f, 49.8822222f)); 811 GeographicPoint dubai = new GeographicPoint(25.2522222f, 55.28f); 812 timeZoneGeographicPoints.put("Asia/Dubai", dubai); 813 timeZoneGeographicPoints.put("Asia/Muscat", new GeographicPoint(23.6133333f, 58.5933333f)); 814 timeZoneGeographicPoints.put("Asia/Tbilisi", new GeographicPoint(41.725f, 44.7908333f)); 815 timeZoneGeographicPoints.put("Asia/Yerevan", new GeographicPoint(40.1811111f, 44.5136111f)); 816 timeZoneGeographicPoints.put("Etc/GMT-4", dubai); // Dubai 817 timeZoneGeographicPoints.put("Europe/Samara", new GeographicPoint(53.2f, 50.15f)); 818 timeZoneGeographicPoints.put("Indian/Mahe", new GeographicPoint(-4.6166667f, 55.45f)); 819 timeZoneGeographicPoints.put("Indian/Mauritius", new GeographicPoint(-20.1619444f, 57.4988889f)); // Port Louis 820 timeZoneGeographicPoints.put("Indian/Reunion", new GeographicPoint(-20.8666667f, 55.4666667f)); // Saint Denis 821 timeZoneGeographicPoints.put("Asia/Kabul", new GeographicPoint(34.5166667f, 69.1833333f)); 822 timeZoneGeographicPoints.put("Antarctica/Davis", new GeographicPoint(-68.5764f, 77.9689f)); 823 timeZoneGeographicPoints.put("Antarctica/Mawson", new GeographicPoint(-53.104f, 73.514f)); 824 timeZoneGeographicPoints.put("Asia/Aqtau", new GeographicPoint(43.65f, 51.2f)); 825 timeZoneGeographicPoints.put("Asia/Aqtobe", new GeographicPoint(50.2980556f, 57.1813889f)); 826 timeZoneGeographicPoints.put("Asia/Ashgabat", new GeographicPoint(37.95f, 58.3833333f)); 827 timeZoneGeographicPoints.put("Asia/Ashkhabad", new GeographicPoint(37.95f, 58.3833333f)); 828 timeZoneGeographicPoints.put("Asia/Dushanbe", new GeographicPoint(38.56f, 68.7738889f)); 829 timeZoneGeographicPoints.put("Asia/Karachi", new GeographicPoint(24.8666667f, 67.05f)); 830 timeZoneGeographicPoints.put("Asia/Oral", new GeographicPoint(51.2333333f, 51.3666667f)); 831 timeZoneGeographicPoints.put("Asia/Samarkand", new GeographicPoint(39.6541667f, 66.9597222f)); 832 timeZoneGeographicPoints.put("Asia/Tashkent", new GeographicPoint(41.3166667f, 69.25f)); 833 timeZoneGeographicPoints.put("Asia/Yekaterinburg", new GeographicPoint(56.85f, 60.6f)); 834 GeographicPoint calcutta = new GeographicPoint(22.569722f, 88.369722f); 835 timeZoneGeographicPoints.put("Etc/GMT-5", calcutta); // Calcutta 836 timeZoneGeographicPoints.put("Indian/Kerguelen", new GeographicPoint(-49.25f, 69.583f)); // Port-aux-Francais 837 timeZoneGeographicPoints.put("Indian/Maldives", new GeographicPoint(4.1666667f, 73.5f)); // Male 838 timeZoneGeographicPoints.put("Asia/Calcutta", calcutta); 839 timeZoneGeographicPoints.put("Asia/Colombo", new GeographicPoint(6.9319444f, 79.8477778f)); 840 timeZoneGeographicPoints.put("Asia/Kolkata", calcutta); 841 timeZoneGeographicPoints.put("Asia/Kathmandu", new GeographicPoint(27.7166667f, 85.3166667f)); 842 timeZoneGeographicPoints.put("Asia/Katmandu", new GeographicPoint(27.7166667f, 85.3166667f)); 843 timeZoneGeographicPoints.put("Antarctica/Vostok", new GeographicPoint(-78.4644f, 106.8372f)); 844 timeZoneGeographicPoints.put("Asia/Almaty", new GeographicPoint(43.25f, 76.95f)); 845 timeZoneGeographicPoints.put("Asia/Bishkek", new GeographicPoint(42.8730556f, 74.6002778f)); 846 GeographicPoint dacca = new GeographicPoint(23.7230556f, 90.4086111f); 847 timeZoneGeographicPoints.put("Asia/Dacca", dacca); 848 timeZoneGeographicPoints.put("Asia/Dhaka", dacca); 849 timeZoneGeographicPoints.put("Asia/Novokuznetsk", new GeographicPoint(53.75f, 87.1f)); 850 timeZoneGeographicPoints.put("Asia/Novosibirsk", new GeographicPoint(55.0411111f, 82.9344444f)); 851 timeZoneGeographicPoints.put("Asia/Omsk", new GeographicPoint(55.0f, 73.4f)); 852 timeZoneGeographicPoints.put("Asia/Qyzylorda", new GeographicPoint(44.8527778f, 65.5091667f)); 853 timeZoneGeographicPoints.put("Asia/Thimbu", new GeographicPoint(27.4833333f, 89.6f)); 854 timeZoneGeographicPoints.put("Asia/Thimphu", new GeographicPoint(27.4833333f, 89.6f)); 855 timeZoneGeographicPoints.put("Etc/GMT-6", dacca); // Dacca 856 timeZoneGeographicPoints.put("Indian/Chagos", new GeographicPoint(-6f, 71.5f)); 857 timeZoneGeographicPoints.put("Asia/Rangoon", new GeographicPoint(16.7833333f, 96.1666667f)); 858 timeZoneGeographicPoints.put("Indian/Cocos", new GeographicPoint(-12.1167f, 96.9f)); 859 GeographicPoint bangkok = new GeographicPoint(13.75f, 100.516667f); 860 timeZoneGeographicPoints.put("Asia/Bangkok", bangkok); 861 timeZoneGeographicPoints.put("Asia/Ho_Chi_Minh", new GeographicPoint(10.75f, 106.6666667f)); 862 timeZoneGeographicPoints.put("Asia/Hovd", new GeographicPoint(48.0166667f, 91.6333333f)); 863 timeZoneGeographicPoints.put("Asia/Jakarta", new GeographicPoint(-6.1744444f, 106.8294444f)); 864 timeZoneGeographicPoints.put("Asia/Krasnoyarsk", new GeographicPoint(56.0097222f, 92.7916667f)); 865 timeZoneGeographicPoints.put("Asia/Phnom_Penh", new GeographicPoint(11.55f, 104.9166667f)); 866 timeZoneGeographicPoints.put("Asia/Pontianak", new GeographicPoint(-0.0333333f, 109.3333333f)); 867 timeZoneGeographicPoints.put("Asia/Saigon", new GeographicPoint(10.75f, 106.6666667f)); 868 timeZoneGeographicPoints.put("Asia/Vientiane", new GeographicPoint(17.966667f, 102.6f)); 869 timeZoneGeographicPoints.put("Etc/GMT-7", bangkok); // Bangkok 870 timeZoneGeographicPoints.put("Indian/Christmas", new GeographicPoint(-10.4166667f, 105.7166667f)); // Flying Fish Cove 871 timeZoneGeographicPoints.put("Asia/Brunei", new GeographicPoint(4.8833333f, 114.9333333f)); 872 timeZoneGeographicPoints.put("Asia/Choibalsan", new GeographicPoint(48.0666667f, 114.5f)); 873 timeZoneGeographicPoints.put("Asia/Chongqing", new GeographicPoint(29.5627778f, 106.5527778f)); 874 timeZoneGeographicPoints.put("Asia/Chungking", new GeographicPoint(29.5627778f, 106.5527778f)); 875 timeZoneGeographicPoints.put("Asia/Harbin", new GeographicPoint(45.75f, 126.65f)); 876 timeZoneGeographicPoints.put("Asia/Hong_Kong", new GeographicPoint(22.2833333f, 114.15f)); 877 timeZoneGeographicPoints.put("Asia/Irkutsk", new GeographicPoint(52.2666667f, 104.3333333f)); 878 timeZoneGeographicPoints.put("Asia/Kashgar", new GeographicPoint(39.3913889f, 76.04f)); 879 timeZoneGeographicPoints.put("Asia/Kuala_Lumpur", new GeographicPoint(3.1666667f, 101.7f)); 880 timeZoneGeographicPoints.put("Asia/Kuching", new GeographicPoint(1.55f, 110.3333333f)); 881 timeZoneGeographicPoints.put("Asia/Macao", new GeographicPoint(22.2f, 113.55f)); 882 timeZoneGeographicPoints.put("Asia/Macau", new GeographicPoint(22.2f, 113.55f)); 883 timeZoneGeographicPoints.put("Asia/Makassar", new GeographicPoint(2.45f, 99.7833333f)); 884 timeZoneGeographicPoints.put("Asia/Manila", new GeographicPoint(14.6041667f, 120.9822222f)); 885 GeographicPoint shanghai = new GeographicPoint(31.005f, 121.4086111f); 886 timeZoneGeographicPoints.put("Asia/Shanghai", shanghai); 887 timeZoneGeographicPoints.put("Asia/Singapore", new GeographicPoint(1.2930556f, 103.8558333f)); 888 timeZoneGeographicPoints.put("Asia/Taipei", new GeographicPoint(25.0391667f, 121.525f)); 889 timeZoneGeographicPoints.put("Asia/Ujung_Pandang", new GeographicPoint(-5.1305556f, 119.4069444f)); 890 timeZoneGeographicPoints.put("Asia/Ulaanbaatar", new GeographicPoint(47.9166667f, 106.9166667f)); 891 timeZoneGeographicPoints.put("Asia/Ulan_Bator", new GeographicPoint(47.9166667f, 106.9166667f)); 892 timeZoneGeographicPoints.put("Asia/Urumqi", new GeographicPoint(43.8f, 87.5833333f)); 893 timeZoneGeographicPoints.put("Australia/Perth", new GeographicPoint(-31.933333f, 115.833333f)); 894 timeZoneGeographicPoints.put("Australia/West", new GeographicPoint(-31.933333f, 115.833333f)); // Perth 895 timeZoneGeographicPoints.put("Etc/GMT-8", shanghai); // Shanghai 896 timeZoneGeographicPoints.put("Australia/Eucla", new GeographicPoint(-31.716667f, 128.866667f)); 897 timeZoneGeographicPoints.put("Asia/Dili", new GeographicPoint(-8.55f, 125.5833f)); 898 timeZoneGeographicPoints.put("Asia/Jayapura", new GeographicPoint(-2.5333333f, 140.7f)); 899 timeZoneGeographicPoints.put("Asia/Pyongyang", new GeographicPoint(39.0194444f, 125.7547222f)); 900 timeZoneGeographicPoints.put("Asia/Seoul", new GeographicPoint(37.5663889f, 126.9997222f)); 901 GeographicPoint tokyo = new GeographicPoint(35.685f, 139.7513889f); 902 timeZoneGeographicPoints.put("Asia/Tokyo", tokyo); 903 timeZoneGeographicPoints.put("Asia/Yakutsk", new GeographicPoint(62.0338889f, 129.7330556f)); 904 timeZoneGeographicPoints.put("Etc/GMT-9", tokyo); // Tokyo 905 timeZoneGeographicPoints.put("Pacific/Palau", new GeographicPoint(7.5f, 134.6241f)); // Ngerulmud 906 timeZoneGeographicPoints.put("Australia/Adelaide", new GeographicPoint(-34.933333f, 138.6f)); 907 timeZoneGeographicPoints.put("Australia/Broken_Hill", new GeographicPoint(-31.95f, 141.433333f)); 908 timeZoneGeographicPoints.put("Australia/Darwin", new GeographicPoint(-12.466667f, 130.833333f)); 909 timeZoneGeographicPoints.put("Australia/North", new GeographicPoint(-12.466667f, 130.833333f)); // Darwin 910 timeZoneGeographicPoints.put("Australia/South", new GeographicPoint(-34.933333f, 138.6f)); // Adelaide 911 timeZoneGeographicPoints.put("Australia/Yancowinna", new GeographicPoint(-31.7581f, 141.7178f)); 912 timeZoneGeographicPoints.put("Antarctica/DumontDUrville", new GeographicPoint(-66.66277f, 140.0014f)); 913 timeZoneGeographicPoints.put("Asia/Sakhalin", new GeographicPoint(51f, 143f)); 914 timeZoneGeographicPoints.put("Asia/Vladivostok", new GeographicPoint(43.1333333f, 131.9f)); 915 timeZoneGeographicPoints.put("Australia/ACT", new GeographicPoint(-35.283333f, 149.216667f)); // Canberra 916 timeZoneGeographicPoints.put("Australia/Brisbane", new GeographicPoint(-27.5f, 153.016667f)); 917 timeZoneGeographicPoints.put("Australia/Canberra", new GeographicPoint(-35.283333f, 149.216667f)); 918 timeZoneGeographicPoints.put("Australia/Currie", new GeographicPoint(-39.933333f, 143.866667f)); 919 timeZoneGeographicPoints.put("Australia/Hobart", new GeographicPoint(-42.916667f, 147.333333f)); 920 timeZoneGeographicPoints.put("Australia/Lindeman", new GeographicPoint(-20.45f, 149.0333f)); 921 timeZoneGeographicPoints.put("Australia/Melbourne", new GeographicPoint(-37.816667f, 144.966667f)); 922 GeographicPoint sydney = new GeographicPoint(-33.883333f, 151.216667f); 923 timeZoneGeographicPoints.put("Australia/NSW", sydney); // Sydney 924 timeZoneGeographicPoints.put("Australia/Queensland", new GeographicPoint(-27.5f, 153.016667f)); // Brisbane 925 timeZoneGeographicPoints.put("Australia/Sydney", sydney); 926 timeZoneGeographicPoints.put("Australia/Tasmania", new GeographicPoint(-42.916667f, 147.333333f)); // Hobart 927 timeZoneGeographicPoints.put("Australia/Victoria", new GeographicPoint(-37.816667f, 144.966667f)); // Melbourne 928 timeZoneGeographicPoints.put("Etc/GMT-10", sydney); // Sydney 929 timeZoneGeographicPoints.put("Pacific/Guam", new GeographicPoint(13.467f, 144.75f)); // Hagatna 930 timeZoneGeographicPoints.put("Pacific/Port_Moresby", new GeographicPoint(-9.4647222f, 147.1925f)); 931 timeZoneGeographicPoints.put("Pacific/Saipan", new GeographicPoint(15.1833f, 145.75f)); 932 timeZoneGeographicPoints.put("Pacific/Truk", new GeographicPoint(7.4167f, 151.7833f)); 933 timeZoneGeographicPoints.put("Pacific/Yap", new GeographicPoint(9.5144444f, 138.1291667f)); 934 timeZoneGeographicPoints.put("Australia/LHI", new GeographicPoint(-31.55f, 159.083f)); 935 timeZoneGeographicPoints.put("Australia/Lord_Howe", new GeographicPoint(-31.55f, 159.083f)); 936 timeZoneGeographicPoints.put("Antarctica/Casey", new GeographicPoint(-66.2833f, 110.5333f)); 937 timeZoneGeographicPoints.put("Asia/Magadan", new GeographicPoint(59.5666667f, 150.8f)); 938 GeographicPoint noumea = new GeographicPoint(-22.2666667f, 166.45f); 939 timeZoneGeographicPoints.put("Etc/GMT-11", noumea); // Noumea 940 timeZoneGeographicPoints.put("Pacific/Efate", new GeographicPoint(-17.667f, 168.417f)); 941 timeZoneGeographicPoints.put("Pacific/Guadalcanal", new GeographicPoint(-9.617f, 160.183f)); 942 timeZoneGeographicPoints.put("Pacific/Kosrae", new GeographicPoint(5.317f, 162.983f)); 943 timeZoneGeographicPoints.put("Pacific/Noumea", noumea); 944 timeZoneGeographicPoints.put("Pacific/Ponape", new GeographicPoint(6.9638889f, 158.2083333f)); 945 timeZoneGeographicPoints.put("Pacific/Norfolk", new GeographicPoint(-29.05f, 167.95f)); // Kingston 946 timeZoneGeographicPoints.put("Antarctica/McMurdo", new GeographicPoint(-77.85f, 166.667f)); 947 timeZoneGeographicPoints.put("Antarctica/South_Pole", new GeographicPoint(-90f, 0f)); 948 timeZoneGeographicPoints.put("Asia/Anadyr", new GeographicPoint(64.75f, 177.4833333f)); 949 timeZoneGeographicPoints.put("Asia/Kamchatka", new GeographicPoint(57f, 160f)); 950 GeographicPoint auckland = new GeographicPoint(-36.866667f, 174.766667f); 951 timeZoneGeographicPoints.put("Etc/GMT-12", auckland); // Auckland 952 timeZoneGeographicPoints.put("Pacific/Auckland", auckland); 953 timeZoneGeographicPoints.put("Pacific/Fiji", new GeographicPoint(-18.1333333f, 178.4166667f)); // Suva 954 timeZoneGeographicPoints.put("Pacific/Funafuti", new GeographicPoint(-8.5166667f, 179.2166667f)); 955 timeZoneGeographicPoints.put("Pacific/Kwajalein", new GeographicPoint(9.1939f, 167.4597f)); 956 timeZoneGeographicPoints.put("Pacific/Majuro", new GeographicPoint(7.1f, 171.3833333f)); 957 timeZoneGeographicPoints.put("Pacific/Nauru", new GeographicPoint(-0.5322f, 166.9328f)); 958 timeZoneGeographicPoints.put("Pacific/Tarawa", new GeographicPoint(1.4167f, 173.0333f)); 959 timeZoneGeographicPoints.put("Pacific/Wake", new GeographicPoint(19.2833f, 166.6f)); 960 timeZoneGeographicPoints.put("Pacific/Wallis", new GeographicPoint(-13.273f, -176.205f)); 961 timeZoneGeographicPoints.put("Pacific/Chatham", new GeographicPoint(-43.883f, -176.517f)); 962 GeographicPoint enderbury = new GeographicPoint(-3.133f, -171.0833f); 963 timeZoneGeographicPoints.put("Etc/GMT-13", enderbury); // Enderbury 964 timeZoneGeographicPoints.put("Pacific/Enderbury", enderbury); 965 timeZoneGeographicPoints.put("Pacific/Tongatapu", new GeographicPoint(-21.2114f, -175.153f)); 966 GeographicPoint kiritimati = new GeographicPoint(1.883f, -157.4f); 967 timeZoneGeographicPoints.put("Etc/GMT-14", kiritimati); // Kiritimati 968 timeZoneGeographicPoints.put("Pacific/Kiritimati", kiritimati); 969 970 timeZoneGeographicPoints.put("MIT", apia); // Apia 971 timeZoneGeographicPoints.put("HST", honolulu); // Honolulu 972 timeZoneGeographicPoints.put("PST", losAngeles); // Los Angeles 973 timeZoneGeographicPoints.put("PST8PDT", losAngeles); // Los Angeles 974 timeZoneGeographicPoints.put("MST", denver); // Denver 975 timeZoneGeographicPoints.put("MST7MDT", denver); // Denver 976 timeZoneGeographicPoints.put("Navajo", new GeographicPoint(35.6728f, -109.0622f)); // Window Rock 977 timeZoneGeographicPoints.put("PNT", new GeographicPoint(33.4483333f, -112.0733333f)); // Phoenix 978 timeZoneGeographicPoints.put("America/Indiana/Knox", new GeographicPoint(41.2958333f, -86.6250000f)); 979 timeZoneGeographicPoints.put("America/Indiana/Tell_City", new GeographicPoint(37.953f, -86.7614f)); 980 timeZoneGeographicPoints.put("America/North_Dakota/Center", new GeographicPoint(47.115f, -101.3003f)); 981 timeZoneGeographicPoints.put("America/North_Dakota/New_Salem", new GeographicPoint(46.843f, 101.4119f)); 982 timeZoneGeographicPoints.put("CST", chicago); // Chicago 983 timeZoneGeographicPoints.put("CST6CDT", chicago); // Chicago 984 timeZoneGeographicPoints.put("America/Indiana/Indianapolis", new GeographicPoint(39.7683333f, -86.1580556f)); 985 timeZoneGeographicPoints.put("America/Indiana/Marengo", new GeographicPoint(36.3706f, -86.3433f)); 986 timeZoneGeographicPoints.put("America/Indiana/Petersburg", new GeographicPoint(38.4917f, -87.2803f)); 987 timeZoneGeographicPoints.put("America/Indiana/Vevay", new GeographicPoint(38.7458f, -85.0711f)); 988 timeZoneGeographicPoints.put("America/Indiana/Vincennes", new GeographicPoint(38.6783f, -87.5164f)); 989 timeZoneGeographicPoints.put("America/Indiana/Winamac", new GeographicPoint(41.0525f, -86.6044f)); 990 timeZoneGeographicPoints.put("America/Kentucky/Louisville", new GeographicPoint(38.2542f, -85.7603f)); 991 timeZoneGeographicPoints.put("America/Kentucky/Monticello", new GeographicPoint(36.8381f, -84.85f)); 992 timeZoneGeographicPoints.put("Cuba", new GeographicPoint(23.1319444f, -82.3641667f)); // Havana 993 timeZoneGeographicPoints.put("EST", newYork); // New York 994 timeZoneGeographicPoints.put("EST5EDT", newYork); // New York 995 timeZoneGeographicPoints.put("IET", newYork); // New York 996 timeZoneGeographicPoints.put("AST", new GeographicPoint(44.65f, -63.6f)); // Halifax 997 timeZoneGeographicPoints.put("Jamaica", new GeographicPoint(18.0f, -76.8f)); // Kingston 998 timeZoneGeographicPoints.put("America/Argentina/San_Luis", new GeographicPoint(-33.3f, -66.333f)); 999 timeZoneGeographicPoints.put("PRT", new GeographicPoint(18.467f, 66.117f)); // San Juan 1000 timeZoneGeographicPoints.put("CNT", new GeographicPoint(47.5675f, -52.7072f)); // St John's 1001 timeZoneGeographicPoints.put("AGT", new GeographicPoint(-34.5875f, -58.6725f)); // Buenos Aires 1002 timeZoneGeographicPoints.put("America/Argentina/Buenos_Aires", new GeographicPoint(-34.5875f, -58.6725f)); 1003 timeZoneGeographicPoints.put("America/Argentina/Catamarca", new GeographicPoint(-28.4666667f, -65.7833333f)); 1004 timeZoneGeographicPoints.put("America/Argentina/ComodRivadavia", new GeographicPoint(-42.7578f, -65.0297f)); 1005 timeZoneGeographicPoints.put("America/Argentina/Cordoba", new GeographicPoint(-31.4f, -64.1833333f)); 1006 timeZoneGeographicPoints.put("America/Argentina/Jujuy", new GeographicPoint(-24.1833333f, -65.3f)); 1007 timeZoneGeographicPoints.put("America/Argentina/La_Rioja", new GeographicPoint(-29.4144f, -66.8552f)); 1008 timeZoneGeographicPoints.put("America/Argentina/Mendoza", new GeographicPoint(-32.8833333f, -68.8166667f)); 1009 timeZoneGeographicPoints.put("America/Argentina/Rio_Gallegos", new GeographicPoint(-51.625f, -69.2286f)); 1010 timeZoneGeographicPoints.put("America/Argentina/Salta", new GeographicPoint(-24.7833333f, -65.4166667f)); 1011 timeZoneGeographicPoints.put("America/Argentina/San_Juan", new GeographicPoint(-31.5333f, -68.5167f)); 1012 timeZoneGeographicPoints.put("America/Argentina/Tucuman", new GeographicPoint(-26.8167f, 65.2167f)); 1013 timeZoneGeographicPoints.put("America/Argentina/Ushuaia", new GeographicPoint(-54.6f, -68.3f)); 1014 timeZoneGeographicPoints.put("BET", saoPaulo); // Sao Paulo 1015 timeZoneGeographicPoints.put("Eire", new GeographicPoint(53.3330556f, -6.2488889f)); // Dublin 1016 timeZoneGeographicPoints.put("GB", greenwich); // Greenwich 1017 timeZoneGeographicPoints.put("GB-Eire", new GeographicPoint(53.3330556f, -6.2488889f)); // Dublin 1018 timeZoneGeographicPoints.put("GMT", greenwich); // Greenwich 1019 timeZoneGeographicPoints.put("GMT0", greenwich); // Greenwich 1020 timeZoneGeographicPoints.put("Greenwich", greenwich); // Greenwich 1021 timeZoneGeographicPoints.put("Iceland", new GeographicPoint(64.1333f, -21.9333f)); // Reykjav�k 1022 timeZoneGeographicPoints.put("Portugal", new GeographicPoint(38.7166667f, -9.1333333f)); // Lisbon 1023 timeZoneGeographicPoints.put("UCT", greenwich); // Greenwich 1024 timeZoneGeographicPoints.put("UTC", greenwich); // Greenwich 1025 timeZoneGeographicPoints.put("Universal", greenwich); // Greenwich 1026 timeZoneGeographicPoints.put("WET", greenwich); // Greenwich 1027 timeZoneGeographicPoints.put("Zulu", greenwich); // Greenwich 1028 timeZoneGeographicPoints.put("CET", paris); // Paris 1029 timeZoneGeographicPoints.put("ECT", paris); // Paris 1030 timeZoneGeographicPoints.put("MET", new GeographicPoint(35.6719444f, 51.4244444f)); // Tehran 1031 timeZoneGeographicPoints.put("Poland", new GeographicPoint(52.25f, 21.0f)); // Warsaw 1032 timeZoneGeographicPoints.put("ART", new GeographicPoint(-34.5875f, -58.6725f)); // Buenos Aires 1033 timeZoneGeographicPoints.put("CAT", new GeographicPoint(-1.9536111f, 30.0605556f)); // Kigali 1034 timeZoneGeographicPoints.put("EET", new GeographicPoint(37.9833333f, 23.7333333f)); // Athens 1035 timeZoneGeographicPoints.put("Egypt", new GeographicPoint(30.05f, 31.25f)); // Cairo 1036 timeZoneGeographicPoints.put("Israel", new GeographicPoint(32.0666667f, 34.7666667f)); // Tel Aviv 1037 timeZoneGeographicPoints.put("Libya", new GeographicPoint(32.8925f, 13.18f)); // Tripoli 1038 timeZoneGeographicPoints.put("Turkey", new GeographicPoint(41.0186111f, 28.9647222f)); // Istanbul 1039 timeZoneGeographicPoints.put("EAT", new GeographicPoint(-1.2833333f, 36.8166667f)); // Nairobi 1040 timeZoneGeographicPoints.put("W-SU", moscow); // Moscow 1041 timeZoneGeographicPoints.put("Iran", new GeographicPoint(35.6719444f, 51.4244444f)); // Tehran 1042 timeZoneGeographicPoints.put("NET", new GeographicPoint(40.1811111f, 44.5136111f)); // Yerevan 1043 timeZoneGeographicPoints.put("PLT", new GeographicPoint(24.8666667f, 67.05f)); // Karachi 1044 timeZoneGeographicPoints.put("IST", calcutta); // Calcutta 1045 timeZoneGeographicPoints.put("BST", dacca); // Dacca 1046 timeZoneGeographicPoints.put("VST", bangkok); // Bangkok 1047 timeZoneGeographicPoints.put("CTT", shanghai); // Shanghai 1048 timeZoneGeographicPoints.put("Hongkong", new GeographicPoint(22.2833333f, 114.15f)); 1049 timeZoneGeographicPoints.put("PRC", shanghai); // Shanghai 1050 timeZoneGeographicPoints.put("Singapore", new GeographicPoint(1.2930556f, 103.8558333f)); 1051 timeZoneGeographicPoints.put("JST", tokyo); // Tokyo 1052 timeZoneGeographicPoints.put("Japan", tokyo); // Tokyo 1053 timeZoneGeographicPoints.put("ROK", new GeographicPoint(37.5663889f, 126.9997222f)); // Seoul 1054 timeZoneGeographicPoints.put("ACT", new GeographicPoint(-35.283333f, 149.216667f)); // Canberra 1055 timeZoneGeographicPoints.put("AET", sydney); // Sydney 1056 timeZoneGeographicPoints.put("SST", new GeographicPoint(-28.4667f, 159.8167f)); // Honiara 1057 timeZoneGeographicPoints.put("Kwajalein", new GeographicPoint(9.1939f, 167.4597f)); 1058 timeZoneGeographicPoints.put("NST", auckland); // Auckland 1059 timeZoneGeographicPoints.put("NZ", auckland); // Auckland 1060 timeZoneGeographicPoints.put("NZ-CHAT", new GeographicPoint(-43.883f, -176.517f)); // Chatham 1061 1062 // Store geographic points in a weak reference because it should be used only to init a new compass 1063 timeZoneGeographicPointsReference = new WeakReference<Map<String,GeographicPoint>>(timeZoneGeographicPoints); 1064 } 1065 1066 GeographicPoint point = timeZoneGeographicPoints.get(TimeZone.getDefault().getID()); 1067 if (point == null) { 1068 point = timeZoneGeographicPoints.get("Etc/GMT"); 1069 } 1070 this.latitude = (float)Math.toRadians(point.getLatitudeInDegrees()); 1071 this.longitude = (float)Math.toRadians(point.getLongitudeInDegrees()); 1072 } 1073 1074 /** 1075 * A geographic point used to store known points. 1076 */ 1077 private static class GeographicPoint { 1078 private final float latitudeInDegrees; 1079 private final float longitudeInDegrees; 1080 GeographicPoint(float latitudeInDegrees, float longitudeInDegrees)1081 public GeographicPoint(float latitudeInDegrees, float longitudeInDegrees) { 1082 this.latitudeInDegrees = latitudeInDegrees; 1083 this.longitudeInDegrees = longitudeInDegrees; 1084 } 1085 getLatitudeInDegrees()1086 public float getLatitudeInDegrees() { 1087 return this.latitudeInDegrees; 1088 } 1089 getLongitudeInDegrees()1090 public float getLongitudeInDegrees() { 1091 return this.longitudeInDegrees; 1092 } 1093 } 1094 } 1095