From d89d417b7070c6bebe9a1ad5d1a6b104255b3ea0 Mon Sep 17 00:00:00 2001 From: Andrea Bisacchi Date: Tue, 29 Dec 2020 17:56:22 +0100 Subject: [PATCH 1/4] Change broadcast events from only IT to radius with Italy in the center --- lib/bot.js | 27 ++++++++++++++++++++++++--- lib/config/example.config.json | 3 ++- 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/lib/bot.js b/lib/bot.js index 4626eb6..d2c911e 100644 --- a/lib/bot.js +++ b/lib/bot.js @@ -12,6 +12,7 @@ const Card = require('./maps').Card; const social = require('./social'); const BROADCAST_THRESHOLD = config('ingv').broadcastThreshold; +const BROADCAST_RADIUS = config('ingv').broadcastRadius; const SOCIAL_THRESHOLD = config('social').threshold; const SOCIAL_ENABLED = config('social').enabled; @@ -77,11 +78,11 @@ poller.on('earthquakes', (earthquakes) => { } if (magnitude >= BROADCAST_THRESHOLD && - // broadcast only if we're sure that the country is Italy - result && result['country'] == 'IT') { + // broadcast only if the earthquake is in a radius from the "center of Italy" + _distanceFromCenter(lat, lon) <= BROADCAST_RADIUS) { notifications.broadcast(ev, callback); } - else { + else { // FIXME: this "else" means no notifications will be sent if someone is not interested in broadcast but that earthquake is near in his radius. Eg: There's an earthquake of magnitude 9 in Milan, if I'm interested in earthquakes near Milan but not in "big earthquake events" I will not be signaled notifications.send(ev, callback); } @@ -95,3 +96,23 @@ poller.on('earthquakes', (earthquakes) => { logger.info('Done'); }); }); + +function __distanceFromCenter(lat, lon) { + let lat1 = 41.2909725; // "Center" of + let lon1 = 12.572917; // Italy + let lat2 = lat; + let lon2 = lon; + + let R = 6371e3; + let p1 = lat1 * Math.PI/180; // φ, λ in radians + let p2 = lat2 * Math.PI/180; + let dp = (lat2-lat1) * Math.PI/180; + let dl = (lon2-lon1) * Math.PI/180; + + let a = Math.sin(dp/2) * Math.sin(dp/2) + + Math.cos(p1) * Math.cos(p2) * + Math.sin(dl/2) * Math.sin(dl/2); + let c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); + + return R * c / 1000; // in km +} diff --git a/lib/config/example.config.json b/lib/config/example.config.json index a9a741e..57674db 100644 --- a/lib/config/example.config.json +++ b/lib/config/example.config.json @@ -8,7 +8,8 @@ }, "ingv": { "pollingInterval": 60000, - "broadcastThreshold": 5 + "broadcastThreshold": 5, + "broadcastRadius" : 1000 }, "social": { "enabled": false, From e39d71526bf74e64d74b2d3f43c3f2865af2ab13 Mon Sep 17 00:00:00 2001 From: Andrea Bisacchi Date: Tue, 29 Dec 2020 18:00:00 +0100 Subject: [PATCH 2/4] Add broadcast always functionality --- lib/bot.js | 5 +++-- lib/config/example.config.json | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/bot.js b/lib/bot.js index d2c911e..5bdf6fd 100644 --- a/lib/bot.js +++ b/lib/bot.js @@ -11,6 +11,7 @@ const geocoding = require('./maps').geocoding; const Card = require('./maps').Card; const social = require('./social'); +const BROADCAST_ALWAYS = config('ingv').broadcastAlways; const BROADCAST_THRESHOLD = config('ingv').broadcastThreshold; const BROADCAST_RADIUS = config('ingv').broadcastRadius; const SOCIAL_THRESHOLD = config('social').threshold; @@ -78,8 +79,8 @@ poller.on('earthquakes', (earthquakes) => { } if (magnitude >= BROADCAST_THRESHOLD && - // broadcast only if the earthquake is in a radius from the "center of Italy" - _distanceFromCenter(lat, lon) <= BROADCAST_RADIUS) { + // broadcast only if the earthquake is >= BROADCAST_ALWAYS or is in a radius from the "center of Italy" + magnitude >= BROADCAST_ALWAYS || _distanceFromCenter(lat, lon) <= BROADCAST_RADIUS) { notifications.broadcast(ev, callback); } else { // FIXME: this "else" means no notifications will be sent if someone is not interested in broadcast but that earthquake is near in his radius. Eg: There's an earthquake of magnitude 9 in Milan, if I'm interested in earthquakes near Milan but not in "big earthquake events" I will not be signaled diff --git a/lib/config/example.config.json b/lib/config/example.config.json index 57674db..7061e69 100644 --- a/lib/config/example.config.json +++ b/lib/config/example.config.json @@ -8,6 +8,7 @@ }, "ingv": { "pollingInterval": 60000, + "broadcastAlways": 9, "broadcastThreshold": 5, "broadcastRadius" : 1000 }, From 3b773d3c2e087c5a53f358336134b17a37a276a4 Mon Sep 17 00:00:00 2001 From: Andrea Bisacchi Date: Tue, 29 Dec 2020 18:06:25 +0100 Subject: [PATCH 3/4] Bugfix --- lib/bot.js | 59 +++++++++++++++++++++++++++--------------------------- 1 file changed, 30 insertions(+), 29 deletions(-) diff --git a/lib/bot.js b/lib/bot.js index 5bdf6fd..ae6508c 100644 --- a/lib/bot.js +++ b/lib/bot.js @@ -17,6 +17,26 @@ const BROADCAST_RADIUS = config('ingv').broadcastRadius; const SOCIAL_THRESHOLD = config('social').threshold; const SOCIAL_ENABLED = config('social').enabled; +function _distanceFromCenter(lat, lon) { + let lat1 = 41.2909725; // "Center" of + let lon1 = 12.572917; // Italy + let lat2 = lat; + let lon2 = lon; + + let R = 6371e3; + let p1 = lat1 * Math.PI/180; // φ, λ in radians + let p2 = lat2 * Math.PI/180; + let dp = (lat2-lat1) * Math.PI/180; + let dl = (lon2-lon1) * Math.PI/180; + + let a = Math.sin(dp/2) * Math.sin(dp/2) + + Math.cos(p1) * Math.cos(p2) * + Math.sin(dl/2) * Math.sin(dl/2); + let c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); + + return R * c / 1000; // in km +} + // Create the HTTP server for handling tg messages let serverPort = config('telegram').serverPort; let server = new TelegramServer({ port: serverPort }); @@ -45,20 +65,20 @@ let poller = new IngvPoller(options); // That must be notified poller.on('earthquakes', (earthquakes) => { logger.info(`Notifying ${earthquakes.length} events`); - + // Loop through them async.eachSeries(earthquakes, (ev, callback) => { logger.info('New event', ev); - + let { lat, lon } = ev['origin']; let magnitude = ev['magnitude']['value']; - + logger.info(`Reverse geocoding for event <${ev.id}>`); - + // Convert the geographical coordinates to a city name (reverse geocoding) geocoding.reverse(lat, lon, (err, result) => { if (err) ; // TODO: do something, please - + let city; if (result) { city = result['name']; @@ -66,11 +86,11 @@ poller.on('earthquakes', (earthquakes) => { else { city = ev['zone']; } - + ev['city'] = city; // Update the db representation of the event db.history.setCity(ev['id'], city); - + // Generate the image card let card = new Card(ev); card.generate((err, filePath) => { @@ -79,14 +99,14 @@ poller.on('earthquakes', (earthquakes) => { } if (magnitude >= BROADCAST_THRESHOLD && - // broadcast only if the earthquake is >= BROADCAST_ALWAYS or is in a radius from the "center of Italy" - magnitude >= BROADCAST_ALWAYS || _distanceFromCenter(lat, lon) <= BROADCAST_RADIUS) { + // broadcast only if the earthquake is >= BROADCAST_ALWAYS or is in a radius with Italy in the center + (magnitude >= BROADCAST_ALWAYS || _distanceFromCenter(lat, lon) <= BROADCAST_RADIUS) ) { notifications.broadcast(ev, callback); } else { // FIXME: this "else" means no notifications will be sent if someone is not interested in broadcast but that earthquake is near in his radius. Eg: There's an earthquake of magnitude 9 in Milan, if I'm interested in earthquakes near Milan but not in "big earthquake events" I will not be signaled notifications.send(ev, callback); } - + // Post to social networks if (SOCIAL_ENABLED && magnitude >= SOCIAL_THRESHOLD) { social.publish(ev); @@ -98,22 +118,3 @@ poller.on('earthquakes', (earthquakes) => { }); }); -function __distanceFromCenter(lat, lon) { - let lat1 = 41.2909725; // "Center" of - let lon1 = 12.572917; // Italy - let lat2 = lat; - let lon2 = lon; - - let R = 6371e3; - let p1 = lat1 * Math.PI/180; // φ, λ in radians - let p2 = lat2 * Math.PI/180; - let dp = (lat2-lat1) * Math.PI/180; - let dl = (lon2-lon1) * Math.PI/180; - - let a = Math.sin(dp/2) * Math.sin(dp/2) + - Math.cos(p1) * Math.cos(p2) * - Math.sin(dl/2) * Math.sin(dl/2); - let c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); - - return R * c / 1000; // in km -} From b9e32bad32f7fdf035b3bbab3243be636cc0a3c8 Mon Sep 17 00:00:00 2001 From: Andrea Bisacchi Date: Tue, 29 Dec 2020 18:09:23 +0100 Subject: [PATCH 4/4] Not it is more redable --- lib/bot.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/bot.js b/lib/bot.js index ae6508c..4e835fb 100644 --- a/lib/bot.js +++ b/lib/bot.js @@ -98,9 +98,9 @@ poller.on('earthquakes', (earthquakes) => { ev['cardPath'] = filePath; } - if (magnitude >= BROADCAST_THRESHOLD && - // broadcast only if the earthquake is >= BROADCAST_ALWAYS or is in a radius with Italy in the center - (magnitude >= BROADCAST_ALWAYS || _distanceFromCenter(lat, lon) <= BROADCAST_RADIUS) ) { + if (magnitude >= BROADCAST_ALWAYS || + // broadcast only if the earthquake is >= BROADCAST_THRESHOLD and it is in a radius with Italy in the center + (magnitude >= BROADCAST_THRESHOLD && _distanceFromCenter(lat, lon) <= BROADCAST_RADIUS) ) { notifications.broadcast(ev, callback); } else { // FIXME: this "else" means no notifications will be sent if someone is not interested in broadcast but that earthquake is near in his radius. Eg: There's an earthquake of magnitude 9 in Milan, if I'm interested in earthquakes near Milan but not in "big earthquake events" I will not be signaled