"use strict"; import haversine from 'haversine-distance'; import shuffle_fisher_yates from '../Helpers/FisherYates.mjs'; import { normalise_lat, normalise_lng, normalise_rssi, normalise_gateway_distance, } from '../../common/Normalisers.mjs'; class DatasetFetcher { constructor({ settings, log, GatewayRepo, RSSIRepo, ReadingRepo }) { this.settings = settings; this.l = log; this.repo_gateway = GatewayRepo; this.repo_rssi = RSSIRepo; this.repo_reading = ReadingRepo; } fetch_all(gateway_id) { let gateway_location = this.repo_gateway.get_by_id(gateway_id); let result = []; for(let rssi of this.repo_rssi.iterate_gateway(gateway_id)) { result.push({ input: { latitude: rssi.latitude, longitude: rssi.longitude, distance: haversine(gateway_location, rssi) }, output: [ rssi.rssi ] }); } for(let reading of this.repo_reading.iterate_unreceived()) { result.push({ input: { latitude: reading.latitude, longitude: reading.longitude, distance: haversine(gateway_location, reading) }, output: [ -150 ] }); } shuffle_fisher_yates(result); if(this.settings.ai.do_zap_false_negatives) { let zap_count = this.zap_false_negatives(result, this.settings.ai.false_negative_zap_radius); this.l.log(`[DatasetFetcher] Zapped ${zap_count} false negatives with a radius of ${this.settings.ai.false_negative_zap_radius}m.`); } for(let item of result) { item.input.latitude = normalise_lat(item.input.latitude); item.input.longitude = normalise_lng(item.input.longitude); item.input.distance = normalise_gateway_distance(item.input.distance); item.output[0] = normalise_rssi(item.output[0]); } return result; } zap_false_negatives(readings_raw, max_distance_metres) { let items_zapped = 0; for(let next_item of readings_raw) { // Only zap for readings where we got a signal if(next_item.output[0] <= -150) // -150: codename for no signal continue; // console.log(next_item); // Store a list of items to zap, because changing the length of the // array while we're iterating it is a recipe for disaster let items_to_zap = []; for(let comp_item of readings_raw) { // Avoid zapping readings where we got a signal if(comp_item.output[0] > -150) continue; let distance = haversine( next_item.input, comp_item.input ); if(isNaN(distance)) throw new Error(`Error: Got NaN when checking zapping distance.`); if(distance < max_distance_metres) { // console.log(`Zap! (${distance})`); items_to_zap.push(comp_item); } } items_zapped += items_to_zap.length; for(let next_item of items_to_zap) { readings_raw.splice(readings_raw.indexOf(next_item), 1); } } return items_zapped; } } export default DatasetFetcher;