forked from NatLabRockies/nodehaystack
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathHCoord.js
More file actions
156 lines (141 loc) · 3.73 KB
/
Copy pathHCoord.js
File metadata and controls
156 lines (141 loc) · 3.73 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
//
// Copyright (c) 2015, Shawn Jacobson
// Licensed under the Academic Free License version 3.0
//
// Ported from @see {@link https://bitbucket.org/brianfrank/haystack-java|Haystack Java Toolkit}
//
// History:
// 21 Mar 2015 Shawn Jacobson Creation
//
var HVal = require('./HVal');
/**
* HCoord models a geographic coordinate as latitude and longitude
* @see {@link http://project-haystack.org/doc/TagModel#tagKinds|Project Haystack}
*
* @constructor
* @extends {HVal}
* @param {float} ulat
* @param {float} ulng
*/
function HCoord(ulat, ulng) {
if (ulat < -90000000 || ulat > 90000000) throw new Error("Invalid lat > +/- 90");
if (ulng < -180000000 || ulng > 180000000) throw new Error("Invalid lng > +/- 180");
/** Latitude in micro-degrees */
this.ulat = ulat;
/** Longitude in micro-degrees */
this.ulng = ulng;
}
HCoord.prototype = Object.create(HVal.prototype);
module.exports = HCoord;
/**
* Latitude in decimal degrees
* @return {float}
*/
HCoord.prototype.lat = function() {
return this.ulat / 1000000.0;
};
/**
* Longitude in decimal degrees
* @return {float}
*/
HCoord.prototype.lng = function() {
return this.ulng / 1000000.0;
};
function uToStr(ud) {
var _ud = ud;
var s = "";
if (_ud < 0) {
s += "-";
_ud = -_ud;
}
if (_ud < 1000000.0) {
s += (_ud / 1000000.0).toFixed(6).toString();
// strip extra zeros
while (s.charAt(s.length - 2) !== '.' && s.charAt(s.length - 1) === '0')
s = s.substring(0, s.length - 1);
return s;
}
var x = _ud.toString();
var dot = x.length - 6;
var end = x.length;
var i;
while (end > dot + 1 && x.charAt(end - 1) === '0')
--end;
for (i = 0; i < dot; ++i)
s += x.charAt(i);
s += ".";
for (i = dot; i < end; ++i)
s += x.charAt(i);
return s;
}
/**
* Represented as "C(lat,lng)"
* @return {string}
*/
HCoord.prototype.toZinc = function() {
var s = "C(";
s += getLatLng(this);
s += ")";
return s;
};
/**
* Encode as "c:lat,lng"
* @returns string
*/
HCoord.prototype.toJSON = function() {
return "c:" + getLatLng(this);
};
function getLatLng(self) {
s = uToStr(self.ulat);
s += ",";
s += uToStr(self.ulng);
return s;
}
/**
* Equals is based on lat, lng
* @param {HCoord} that - object to be compared to
* @return {boolean}
*/
HCoord.prototype.equals = function(that) {
return that instanceof HCoord && this.ulat === that.ulat && this.ulng === that.ulng;
};
/**
* Parse from lat and long or string format "C(lat,lng)" or raise Error
* @static
* @param {string|float} lat - {string} Parse from string format "C(lat,lng)"<br/>
* {float} Construct from basic fields
* @param {float} lng
* @return {HCoord}
*/
HCoord.make = function(lat, lng) {
if (HVal.typeis(lat, 'string', String)) {
if (!HVal.startsWith(lat, "C(")) throw new Error("Parse Exception: Invalid start");
if (!HVal.endsWith(lat, ")")) throw new Error("Parse Exception: Invalid end");
var comma = lat.indexOf(',');
if (comma < 3) throw new Error("Parse Exception: Invalid format");
var plat = lat.substring(2, comma);
var plng = lat.substring(comma + 1, lat.length - 1);
if (isNaN(parseFloat(plat)) || isNaN(parseFloat(plng))) throw new Error("Parse Exception: NaN");
return HCoord.make(parseFloat(plat), parseFloat(plng));
} else {
return new HCoord(parseInt(lat * 1000000.0), parseInt(lng * 1000000.0));
}
};
/**
* Return if given latitude is legal value between -90.0 and +90.0
* @static
* @param {float} lat
* @return {boolean}
*/
HCoord.isLat = function(lat) {
return -90.0 <= lat && lat <= 90.0;
};
/**
* Return if given is longitude is legal value between -180.0 and +180.0
* @static
* @param {float} lng
* @return {boolean}
*/
HCoord.isLng = function(lng) {
return -180.0 <= lng && lng <= 180.0;
};