193 строки
7.3 KiB
TypeScript
193 строки
7.3 KiB
TypeScript
///<reference path='refs.ts'/>
|
|
module TDev.RT {
|
|
//? A geo coordinate (latitude, longitude, ...)
|
|
//@ stem("loc") immutable ctx(general,indexkey,cloudfield,json) serializable
|
|
export class Location_
|
|
extends RTValue
|
|
{
|
|
public _latitude : number = undefined;
|
|
public _longitude : number = undefined;
|
|
public _altitude : number = undefined;
|
|
public _hor_accuracy : number = undefined;
|
|
public _vert_accuracy : number = undefined;
|
|
public _speed : number = undefined;
|
|
public _course : number = undefined;
|
|
|
|
constructor() {
|
|
super()
|
|
}
|
|
|
|
static mkShort(lat: number, lon: number): Location_
|
|
{
|
|
return Location_.mk(lat, lon, undefined, undefined, undefined, undefined, undefined);
|
|
}
|
|
|
|
static mk(lat : number, lon : number, alt : number, horacc : number, veracc : number, cou : number, spe : number) : Location_
|
|
{
|
|
var l = new Location_();
|
|
l._latitude = lat;
|
|
l._longitude = lon;
|
|
l._altitude = alt;
|
|
l._hor_accuracy = horacc;
|
|
l._vert_accuracy = veracc;
|
|
l._course = cou;
|
|
l._speed = spe;
|
|
return l;
|
|
}
|
|
|
|
static mkFromString(s: string):Location_ {
|
|
var pos = s.indexOf(",");
|
|
var l = new Location_();
|
|
l._latitude = Number(s.slice(0, pos));
|
|
l._longitude = Number(s.slice(pos + 1));
|
|
return l;
|
|
}
|
|
|
|
//? Converts to a string lat,long
|
|
public to_string() : string { return this._latitude + ',' + this._longitude; }
|
|
|
|
|
|
//ctx is ignored
|
|
public exportJson(ctx: JsonExportCtx): any {
|
|
return {
|
|
latitude: this._latitude,
|
|
longitude: this._longitude,
|
|
altitude: this._altitude,
|
|
hor_accuracy: this._hor_accuracy,
|
|
vert_accuracy: this._vert_accuracy,
|
|
course: this._course,
|
|
speed: this._speed
|
|
};
|
|
}
|
|
public importJson(ctx: JsonImportCtx, json: any): RT.RTValue {
|
|
Util.oops("should not call immutable instance for importing");
|
|
return undefined;
|
|
}
|
|
static mkFromJson(ctx: JsonImportCtx, json: any): RT.Location_ {
|
|
if (typeof json != "object")
|
|
return undefined;
|
|
var loc = new Location_();
|
|
loc._latitude = ctx.importNumber(json, "latitude");
|
|
loc._longitude = ctx.importNumber(json, "longitude");
|
|
loc._altitude = ctx.importNumber(json, "altitude");
|
|
loc._hor_accuracy = ctx.importNumber(json, "hor_accuracy");
|
|
loc._vert_accuracy = ctx.importNumber(json, "vert_accuracy");
|
|
loc._course = ctx.importNumber(json, "course");
|
|
loc._speed = ctx.importNumber(json, "speed");
|
|
return loc;
|
|
}
|
|
|
|
public isSerializable() { return true; }
|
|
|
|
public toJsonKey()
|
|
{
|
|
return [this._latitude, this._longitude, this._altitude,
|
|
this._hor_accuracy, this._vert_accuracy,
|
|
this._speed, this._course];
|
|
}
|
|
|
|
public keyCompareTo(o:any):number
|
|
{
|
|
var other:Location_ = o;
|
|
var diff = this._latitude - other._latitude;
|
|
if (diff) return diff;
|
|
diff = this._longitude - other._longitude;
|
|
if (diff) return diff;
|
|
diff = this._altitude - other._altitude;
|
|
if (diff) return diff;
|
|
diff = this._hor_accuracy - other._hor_accuracy;
|
|
if (diff) return diff;
|
|
diff = this._vert_accuracy - other._vert_accuracy;
|
|
if (diff) return diff;
|
|
diff = this._speed - other._speed;
|
|
if (diff) return diff;
|
|
diff = this._course - other._course;
|
|
return diff;
|
|
}
|
|
|
|
|
|
//? Gets the latitude of the coordinate
|
|
public latitude() : number { return this._latitude; }
|
|
|
|
//? Gets the longitude of the coordinate
|
|
public longitude() : number { return this._longitude; }
|
|
|
|
//? Gets the altitude of the coordinate
|
|
public altitude() : number { return this._altitude; }
|
|
|
|
//? Gets the horizontal accuracy of the coordinate
|
|
public hor_accuracy() : number { return this._hor_accuracy; }
|
|
|
|
//? Gets the vertical accuracy of the coordinate
|
|
public vert_accuracy() : number { return this._vert_accuracy; }
|
|
|
|
//? Gets the speed of the coordinate
|
|
public speed() : number { return this._speed; }
|
|
|
|
//? Gets the course of the coordinate
|
|
public course() : number { return this._course; }
|
|
|
|
public toString(): string {
|
|
return "(" + this._latitude + "," + this._longitude + ")";
|
|
}
|
|
|
|
//? Indicates if this instance is equal to the other
|
|
public equals(other:Location_) : boolean {
|
|
return (
|
|
this._latitude === other._latitude &&
|
|
this._longitude === other._longitude &&
|
|
this._altitude === other._altitude &&
|
|
this._hor_accuracy === other._hor_accuracy &&
|
|
this._vert_accuracy === other._vert_accuracy &&
|
|
this._speed === other._speed &&
|
|
this._course === other._course);
|
|
}
|
|
|
|
//? Shares the location (email, sms, social or '' to pick from a list)
|
|
//@ flow(SinkSharing) uiAsync
|
|
//@ [network].defl("social") [network].deflStrings("", "email", "sms", "social") [message].defl("Sent from TouchDevelop")
|
|
public share(network: string, message: string, r : ResumeCtx): void {
|
|
var lnk = Link.mk(Maps.mapUrl(this), LinkKind.hyperlink);
|
|
lnk.set_title(this.to_string());
|
|
lnk.set_description(message);
|
|
HTML.showProgressNotification(lf("sharing location..."));
|
|
ShareManager.shareLinkAsync(lnk, network).done(() => r.resume());
|
|
}
|
|
|
|
//? Calculates the distance in meters
|
|
public distance(other: Location_): number
|
|
{
|
|
return Location_.computeDistance(this.latitude(), this.longitude(), other.latitude(), other.longitude());
|
|
}
|
|
|
|
static computeDistance(lat1 : number, lng1 : number, lat2 : number, lng2 : number) : number
|
|
{
|
|
var radius = 6367.0; // earth radius in kilometers
|
|
return radius * 2 * Math.asin(
|
|
Math.min(
|
|
1,
|
|
Math.sqrt(
|
|
Math.pow(Math.sin(((Math_.deg_to_rad(lat2 - lat1))) / 2.0), 2.0)
|
|
+ Math.cos(Math_.deg_to_rad(lat1))
|
|
* Math.cos(Math_.deg_to_rad(lat2))
|
|
* Math.pow(Math.sin(((Math_.deg_to_rad(lng2 - lng1))) / 2.0), 2.0)
|
|
)
|
|
)
|
|
);
|
|
}
|
|
|
|
// Displays the location in a map using Bing.
|
|
public getViewCore(s: IStackFrame, b: BoxBase): HTMLElement
|
|
{
|
|
var map = Maps.create_map();
|
|
map.set_center(this);
|
|
map.add_text(this, this.latitude().toFixed(3) + ', ' + this.longitude().toFixed(3), Colors.background(s), Colors.foreground(s));
|
|
return map.getViewCore(s, b);
|
|
}
|
|
|
|
//? Displays the location in a map using Bing.
|
|
//@ cap(maps) flow(SinkSafe)
|
|
public post_to_wall(s:IStackFrame) : void { super.post_to_wall(s) }
|
|
}
|
|
}
|