/**
* @namespace WPGMZA
* @module LatLng
* @requires WPGMZA
*/
(function($) {
/**
* Constructor
* @param mixed A latLng literal, or latitude
* @param mixed The latitude, where arg is a longitude
*/
WPGMZA.LatLng = function(arg, lng)
{
this._lat = 0;
this._lng = 0;
if(arguments.length == 0)
return;
if(arguments.length == 1)
{
if(typeof arg != "object" || !("lat" in arg && "lng" in arg))
throw new Error("Argument must be a LatLng literal");
this.lat = arg.lat;
this.lng = arg.lng;
}
else
{
this.lat = arg;
this.lng = lng;
}
}
WPGMZA.LatLng.isValid = function(obj)
{
if(typeof obj != "object")
return false;
if(!("lat" in obj && "lng" in obj))
return false;
return true;
}
Object.defineProperty(WPGMZA.LatLng.prototype, "lat", {
get: function() {
return this._lat;
},
set: function(val) {
if(!$.isNumeric(val))
throw new Error("Latitude must be numeric");
this._lat = parseFloat( val );
}
});
Object.defineProperty(WPGMZA.LatLng.prototype, "lng", {
get: function() {
return this._lng;
},
set: function(val) {
if(!$.isNumeric(val))
throw new Error("Longitude must be numeric");
this._lng = parseFloat( val );
}
});
WPGMZA.LatLng.prototype.toString = function()
{
return this._lat + ", " + this._lng;
}
WPGMZA.LatLng.prototype.toGoogleLatLng = function()
{
return new google.maps.LatLng({
lat: this.lat,
lng: this.lng
});
}
/**
* @function moveByDistance
* @summary Moves this latLng by the specified kilometers along the given heading
* @return void
* With many thanks to Hu Kenneth - https://gis.stackexchange.com/questions/234473/get-a-lonlat-point-by-distance-or-between-2-lonlat-points
*/
WPGMZA.LatLng.prototype.moveByDistance = function(kilometers, heading)
{
var radius = 6371;
var delta = parseFloat(kilometers) / radius;
var theta = parseFloat(heading) / 180 * Math.PI;
var phi1 = this.lat / 180 * Math.PI;
var lambda1 = this.lng / 180 * Math.PI;
var sinPhi1 = Math.sin(phi1), cosPhi1 = Math.cos(phi1);
var sinDelta = Math.sin(delta), cosDelta = Math.cos(delta);
var sinTheta = Math.sin(theta), cosTheta = Math.cos(theta);
var sinPhi2 = sinPhi1 * cosDelta + cosPhi1 * sinDelta * cosTheta;
var phi2 = Math.asin(sinPhi2);
var y = sinTheta * sinDelta * cosPhi1;
var x = cosDelta - sinPhi1 * sinPhi2;
var lambda2 = lambda1 + Math.atan2(y, x);
this.lat = phi2 * 180 / Math.PI;
this.lng = lambda2 * 180 / Math.PI;
}
})(jQuery);