-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.js
163 lines (135 loc) · 5.01 KB
/
main.js
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
157
158
159
160
161
162
163
// ==================================================
// Is My House On Fire
// ==================================================
// get feed from inciweb, and do something with it
var http = require('http'),
xml2js = require('xml2js'),
pjson = require('./package.json');
// node-getopt to scrape command line
var opt = require('node-getopt').create([
[ 't' , 'threshold=ARG' , 'threshold distance from center to search. Defaults to 100km.' ],
[ 'l' , 'latitude=ARG' , 'latitude for center of search.' ],
[ 'n' , 'longitude=ARG' , 'longitude for center of search.' ],
[ 'h' , 'help' , 'display this help.' ],
[ 'v' , 'version' , 'show version.' ]
]) // create Getopt instance
.bindHelp() // bind option 'help' to default action
.parseSystem(); // parse command line
// if prompted for version, print and exit
if( opt.options.version ) {
console.log( pjson.name + " - version: " + pjson.version );
process.exit();
}
// otherwise, continue
// The url we want is: 'http://inciweb.nwcg.gov/feeds/rss/incidents/'
var options = {
host : 'inciweb.nwcg.gov',
path : '/feeds/rss/incidents/',
threshold : parseFloat( opt.options.threshold ) || 100, // 100 km
lat : parseFloat( opt.options.latitude ) || 37.735969, // yosemite valley
lon : parseFloat( opt.options.longitude ) || -119.601631
};
// optput greeting
console.log( '----------\n' );
console.log( 'calculating closest fires to you, up to ' + options.threshold + ' km away.' );
console.log( 'lat: ' + options.lat + ' lon: ' + options.lon );
// ==================================================
// Lat Long Functions
// ==================================================
/**
* Converts numeric degrees to radians
* http://www.movable-type.co.uk/scripts/latlong.html
*/
if (typeof(Number.prototype.toRadians) === "undefined") {
Number.prototype.toRadians = function() {
return this * Math.PI / 180;
};
}
/**
* Calculates distance between two points on the earth's surface
* output the distance in km
* http://www.movable-type.co.uk/scripts/latlong.html
*/
function calcDistance( lat1, lon1, lat2, lon2 ){
var R = 6371000 / 1000; // kilometers
var φ1 = lat1.toRadians();
var φ2 = lat2.toRadians();
var Δφ = (lat2-lat1).toRadians();
var Δλ = (lon2-lon1).toRadians();
var a = Math.sin(Δφ/2) * Math.sin(Δφ/2) +
Math.cos(φ1) * Math.cos(φ2) *
Math.sin(Δλ/2) * Math.sin(Δλ/2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
return R * c;
}
// ==================================================
// XML Parser
// ==================================================
var parser = new xml2js.Parser();
parser.addListener('end', function(result) {
var json = result;
var fires = json.rss.channel[0].item;
var pubDate = json.rss.channel[0].pubDate[0];
// print published date - with localized date formatting
// compare that to the time that we checked for update
console.log( 'published date: ' + ( new Date( pubDate ) ) );
console.log( 'last checked : ' + ( new Date() ) + '\n' );
for ( var i=0, j=0; i < fires.length; i++ ) {
var lat = parseFloat( fires[i]["geo:lat"][0] ),
lon = parseFloat( fires[i]["geo:long"][0] );
if( lat && lon ) {
var distance = calcDistance( lat, lon, options.lat, options.lon ),
size = fires[i].description ? fires[i].description[0].match( /([\d,]+ acres)/ ) : false,
direction = ( options.lat - lat > 0 ? 's' : 'n' ) + ( options.lon - lon > 0 ? 'w' : 'e' );
//
j++;
if( distance < options.threshold ) {
var output = [
'----------',
' ',
fires[i].title[0],
' ',
'distance : ' + distance.toPrecision(5) + 'km (' + ( distance * 0.621371 ).toPrecision(5) + ' miles)' ,
'direction : ' + direction ,
'fire size : ' + ( size ? size[1] : 'no info' ) ,
'info link : ' + fires[i].link[0] ,
' ' ,
fires[i].description[0] + '\n'
];
console.log( output.join('\n') );
}
}
}
//
console.log( '----------\n' + j + ' fires checked out of ' + i + ' total\n----------' );
});
// ==================================================
// HTTP GET
// ==================================================
function printConnectionError () {
console.log( '----------\nerror connecting to feed at ' + options.host + ' \n----------' );
process.exit();
}
callback = function(response) {
var str = '';
response.on('error', function(exception){
printConnectionError();
});
if ( response.statusCode > '400' ){
printConnectionError();
}
//another chunk of data has been recieved, so append it to `str`
response.on('data', function (chunk) {
str += chunk;
});
//the whole response has been recieved, so we just print it out here
response.on('end', function () {
parser.parseString( str );
});
};
http.request(options, callback)
.on('error', printConnectionError )
.end();
// ==================================================
// END
// ==================================================