/* global Counter */ /* eslint-disable import/no-absolute-path */ /* eslint-disable prefer-arrow-callback */ import { Meteor } from 'meteor/meteor'; import { check, Match } from 'meteor/check'; import { localize } from '/imports/startup/server/IPGeocoder'; import ActiveFires from '../ActiveFires'; const counter = new Counter('countActiveFires', ActiveFires.find({})); Meteor.publish('activefirestotal', function total() { return counter; }); const validZoom = Match.Where((zoom) => { // http://wiki.openstreetmap.org/wiki/Zoom_levels check(zoom, Number); return zoom >= 0 && zoom <= 19; }); // https://github.com/3stack-software/meteor-match-library function NumberBetween(min, max) { return Match.Where((x) => { check(x, Number); return min <= x && x <= max; }); } function NullOr(type) { return Match.Where((x) => { if (x === null) { return true; } check(x, type); return true; }); } // http://wiki.openstreetmap.org/wiki/Zoom_levels // http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames#Resolution_and_Scale // http://cwestblog.com/2012/11/12/javascript-degree-and-radian-conversion/ Math.radians = (degrees) => { const rad = (degrees * Math.PI) / 180; return rad; }; const activefires = (zoom, lat, lng, height, width) => { // latitude -90 and 90 and the longitude between -180 and 180 check(lat, NumberBetween(-90, 90)); check(lng, NumberBetween(-180, 180)); // console.log("Zoom: " + zoom + " lat: " + lat + " lng: " + lng); const resolution = (156543.03 * Math.cos(Math.radians(lat))) / (2 ** zoom); const distUnt = resolution * Math.max(height, width); const distance = Math.trunc(distUnt); // console.log(`so ${height}x${width} gives ${Math.trunc(resolution*height/1000)} x ${Math.trunc(resolution*width/1000)} km, so looking in ${distance}`); // console.log(`So ${height}x${width} gives ${Math.trunc(resolution)} of resolution, so looking in ${Math.trunc(distance / 1000)}km`); const fires = ActiveFires.find({ ourid: { $near: { $geometry: { type: 'Point', coordinates: [lng, lat] }, $minDistance: 0, $maxDistance: distance } } }, { fields: { lat: 1, lon: 1, scan: 1 } }); // console.log(`Fires total: ${fires.count()}`); return fires; }; Meteor.publish('allActiveFires', function allActive() { // latitude -90 and 90 and the longitude between -180 and 180 const { latitude, longitude } = localize().location; // console.log(`${latitude}, ${longitude}`); check(latitude, NumberBetween(-90, 90)); check(longitude, NumberBetween(-180, 180)); // https://docs.meteor.com/api/collections.html#Mongo-Collection-find return ActiveFires.find({ ourid: { $near: { $geometry: { type: 'Point', coordinates: [longitude, latitude] }, $minDistance: 0, $maxDistance: 1000 // 156412000 } } }, { fields: { _id: 0, lat: 1, lon: 1, scan: 1 }, maxTimeMs: 30000 }); }); Meteor.publish('activefiresmyloc', function activeInMyLoc(zoom, lat, lng, height, width) { check(zoom, validZoom); check(lat, NullOr(Number)); check(lng, NullOr(Number)); check(height, NullOr(Number)); check(width, NullOr(Number)); // console.log(`Check active fires in ${lat},${lng} with zoom ${zoom} pixels in ${height}x${width} map`); if (lat && lng) { return activefires(zoom, lat, lng, height, width); } const geo = localize(); // console.log(`${location.latitude}, ${location.longitude}`); return activefires(zoom, geo.location.latitude, geo.location.longitude, height, width); });