UNPKG

leancloud-storage

Version:
190 lines (159 loc) 5.8 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault"); var _promise = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/promise")); var _ = require('underscore'); /*global navigator: false */ module.exports = function (AV) { /** * Creates a new GeoPoint with any of the following forms:<br> * @example * new GeoPoint(otherGeoPoint) * new GeoPoint(30, 30) * new GeoPoint([30, 30]) * new GeoPoint({latitude: 30, longitude: 30}) * new GeoPoint() // defaults to (0, 0) * @class * * <p>Represents a latitude / longitude point that may be associated * with a key in a AVObject or used as a reference point for geo queries. * This allows proximity-based queries on the key.</p> * * <p>Only one key in a class may contain a GeoPoint.</p> * * <p>Example:<pre> * var point = new AV.GeoPoint(30.0, -20.0); * var object = new AV.Object("PlaceObject"); * object.set("location", point); * object.save();</pre></p> */ AV.GeoPoint = function (arg1, arg2) { if (_.isArray(arg1)) { AV.GeoPoint._validate(arg1[0], arg1[1]); this.latitude = arg1[0]; this.longitude = arg1[1]; } else if (_.isObject(arg1)) { AV.GeoPoint._validate(arg1.latitude, arg1.longitude); this.latitude = arg1.latitude; this.longitude = arg1.longitude; } else if (_.isNumber(arg1) && _.isNumber(arg2)) { AV.GeoPoint._validate(arg1, arg2); this.latitude = arg1; this.longitude = arg2; } else { this.latitude = 0; this.longitude = 0; } // Add properties so that anyone using Webkit or Mozilla will get an error // if they try to set values that are out of bounds. var self = this; if (this.__defineGetter__ && this.__defineSetter__) { // Use _latitude and _longitude to actually store the values, and add // getters and setters for latitude and longitude. this._latitude = this.latitude; this._longitude = this.longitude; this.__defineGetter__('latitude', function () { return self._latitude; }); this.__defineGetter__('longitude', function () { return self._longitude; }); this.__defineSetter__('latitude', function (val) { AV.GeoPoint._validate(val, self.longitude); self._latitude = val; }); this.__defineSetter__('longitude', function (val) { AV.GeoPoint._validate(self.latitude, val); self._longitude = val; }); } }; /** * @lends AV.GeoPoint.prototype * @property {float} latitude North-south portion of the coordinate, in range * [-90, 90]. Throws an exception if set out of range in a modern browser. * @property {float} longitude East-west portion of the coordinate, in range * [-180, 180]. Throws if set out of range in a modern browser. */ /** * Throws an exception if the given lat-long is out of bounds. * @private */ AV.GeoPoint._validate = function (latitude, longitude) { if (latitude < -90.0) { throw new Error('AV.GeoPoint latitude ' + latitude + ' < -90.0.'); } if (latitude > 90.0) { throw new Error('AV.GeoPoint latitude ' + latitude + ' > 90.0.'); } if (longitude < -180.0) { throw new Error('AV.GeoPoint longitude ' + longitude + ' < -180.0.'); } if (longitude > 180.0) { throw new Error('AV.GeoPoint longitude ' + longitude + ' > 180.0.'); } }; /** * Creates a GeoPoint with the user's current location, if available. * @return {Promise.<AV.GeoPoint>} */ AV.GeoPoint.current = function () { return new _promise.default(function (resolve, reject) { navigator.geolocation.getCurrentPosition(function (location) { resolve(new AV.GeoPoint({ latitude: location.coords.latitude, longitude: location.coords.longitude })); }, reject); }); }; _.extend(AV.GeoPoint.prototype, /** @lends AV.GeoPoint.prototype */ { /** * Returns a JSON representation of the GeoPoint, suitable for AV. * @return {Object} */ toJSON: function toJSON() { AV.GeoPoint._validate(this.latitude, this.longitude); return { __type: 'GeoPoint', latitude: this.latitude, longitude: this.longitude }; }, /** * Returns the distance from this GeoPoint to another in radians. * @param {AV.GeoPoint} point the other AV.GeoPoint. * @return {Number} */ radiansTo: function radiansTo(point) { var d2r = Math.PI / 180.0; var lat1rad = this.latitude * d2r; var long1rad = this.longitude * d2r; var lat2rad = point.latitude * d2r; var long2rad = point.longitude * d2r; var deltaLat = lat1rad - lat2rad; var deltaLong = long1rad - long2rad; var sinDeltaLatDiv2 = Math.sin(deltaLat / 2); var sinDeltaLongDiv2 = Math.sin(deltaLong / 2); // Square of half the straight line chord distance between both points. var a = sinDeltaLatDiv2 * sinDeltaLatDiv2 + Math.cos(lat1rad) * Math.cos(lat2rad) * sinDeltaLongDiv2 * sinDeltaLongDiv2; a = Math.min(1.0, a); return 2 * Math.asin(Math.sqrt(a)); }, /** * Returns the distance from this GeoPoint to another in kilometers. * @param {AV.GeoPoint} point the other AV.GeoPoint. * @return {Number} */ kilometersTo: function kilometersTo(point) { return this.radiansTo(point) * 6371.0; }, /** * Returns the distance from this GeoPoint to another in miles. * @param {AV.GeoPoint} point the other AV.GeoPoint. * @return {Number} */ milesTo: function milesTo(point) { return this.radiansTo(point) * 3958.8; } }); };