0byt3m1n1
Path:
/
var
/
lib
/
vz
/
www
/
clients
/
client6
/
web11
/
web
/
wp-content
/
plugins
/
wp-google-maps
/
js
/
v8
/
[
Home
]
File: latlng.js
/** * @namespace WPGMZA * @module LatLng * @requires WPGMZA */ jQuery(function($) { /** * This class represents a latitude and longitude coordinate pair, and provides utilities to work with coordinates, parsing and conversion. * @class WPGMZA.LatLng * @constructor WPGMZA.LatLng * @memberof WPGMZA * @param {number|object} arg A latLng literal, or latitude * @param {number} [lng] 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) { // TODO: Support latlng string if(typeof arg == "string") { var m; if(!(m = arg.match(WPGMZA.LatLng.REGEXP))) throw new Error("Invalid LatLng string"); arg = { lat: m[1], lng: m[3] }; } 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; } } /** * A regular expression which matches latitude and longitude coordinate pairs from a string. Matches 1 and 3 correspond to latitude and longitude, respectively, * @constant {RegExp} * @memberof WPGMZA.LatLng */ WPGMZA.LatLng.REGEXP = /^(\-?\d+(\.\d+)?),\s*(\-?\d+(\.\d+)?)$/; /** * Returns true if the supplied object is a LatLng literal, also returns true for instances of WPGMZA.LatLng * @method * @static * @memberof WPGMZA.LatLng * @param {object} obj A LatLng literal, or an instance of WPGMZA.LatLng * @return {bool} True if this object is a valid LatLng literal or instance of WPGMZA.LatLng */ WPGMZA.LatLng.isValid = function(obj) { if(typeof obj != "object") return false; if(!("lat" in obj && "lng" in obj)) return false; return true; } /** * The latitude, guaranteed to be a number * @property lat * @memberof WPGMZA.LatLng */ 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 ); } }); /** * The longitude, guaranteed to be a number * @property lng * @memberof WPGMZA.LatLng */ 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 ); } }); /** * Returns this latitude and longitude as a string * @method * @memberof WPGMZA.LatLng * @return {string} This object represented as a string */ WPGMZA.LatLng.prototype.toString = function() { return this._lat + ", " + this._lng; } /** * Queries the users current location and passes it to a callback, you can pass * geocodeAddress through options if you would like to also receive the address * @method * @memberof WPGMZA.LatLng * @param {function} A callback to receive the WPGMZA.LatLng * @param {object} An object of options, only geocodeAddress is currently supported * @return void */ WPGMZA.LatLng.fromCurrentPosition = function(callback, options) { if(!options) options = {}; if(!callback) return; WPGMZA.getCurrentPosition(function(position) { var latLng = new WPGMZA.LatLng({ lat: position.coords.latitude, lng: position.coords.longitude }); if(options.geocodeAddress) { var geocoder = WPGMZA.Geocoder.createInstance(); geocoder.getAddressFromLatLng({ latLng: latLng }, function(results) { if(results.length) latLng.address = results[0]; callback(latLng); }); } else callback(latLng); }); } /** * Returns an instnace of WPGMZA.LatLng from an instance of google.maps.LatLng * @method * @static * @memberof WPGMZA.LatLng * @param {google.maps.LatLng} The google.maps.LatLng to convert * @return {WPGMZA.LatLng} An instance of WPGMZA.LatLng built from the supplied google.maps.LatLng */ WPGMZA.LatLng.fromGoogleLatLng = function(googleLatLng) { return new WPGMZA.LatLng( googleLatLng.lat(), googleLatLng.lng() ); } /** * Returns an instance of google.maps.LatLng with the same coordinates as this object * @method * @memberof WPGMZA.LatLng * @return {google.maps.LatLng} This object, expressed as a google.maps.LatLng */ WPGMZA.LatLng.prototype.toGoogleLatLng = function() { return new google.maps.LatLng({ lat: this.lat, lng: this.lng }); } WPGMZA.LatLng.prototype.toLatLngLiteral = function() { return { lat: this.lat, lng: this.lng }; } /** * Moves this latLng by the specified kilometers along the given heading. This function operates in place, as opposed to creating a new instance of WPGMZA.LatLng. With many thanks to Hu Kenneth - https://gis.stackexchange.com/questions/234473/get-a-lonlat-point-by-distance-or-between-2-lonlat-points * @method * @memberof WPGMZA.LatLng * @param {number} kilometers The number of kilometers to move this LatLng by * @param {number} heading The heading, in degrees, to move along, where zero is North * @return {void} */ 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; } /** * @function getGreatCircleDistance * @summary Uses the haversine formula to get the great circle distance between this and another LatLng / lat & lng pair * @param arg1 [WPGMZA.LatLng|Object|Number] Either a WPGMZA.LatLng, an object representing a lat/lng literal, or a latitude * @param arg2 (optional) If arg1 is a Number representing latitude, pass arg2 to represent the longitude * @return number The distance "as the crow files" between this point and the other */ WPGMZA.LatLng.prototype.getGreatCircleDistance = function(arg1, arg2) { var lat1 = this.lat; var lon1 = this.lng; var other; if(arguments.length == 1) other = new WPGMZA.LatLng(arg1); else if(arguments.length == 2) other = new WPGMZA.LatLng(arg1, arg2); else throw new Error("Invalid number of arguments"); var lat2 = other.lat; var lon2 = other.lng; var R = 6371; // Kilometers var phi1 = lat1.toRadians(); var phi2 = lat2.toRadians(); var deltaPhi = (lat2-lat1).toRadians(); var deltaLambda = (lon2-lon1).toRadians(); var a = Math.sin(deltaPhi/2) * Math.sin(deltaPhi/2) + Math.cos(phi1) * Math.cos(phi2) * Math.sin(deltaLambda/2) * Math.sin(deltaLambda/2); var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); var d = R * c; return d; } });