From 2758f77fce63364de5c5e0689d09b273d4dd8a63 Mon Sep 17 00:00:00 2001 From: Jannis R Date: Sun, 25 Feb 2024 22:32:14 +0100 Subject: [PATCH] =?UTF-8?q?find=20max=20nr=20of=20radar()=20results:=20twe?= =?UTF-8?q?ak=20bbox=20algorithm=20=E2=9C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit follow-up of b06c567 follow-up of 98f042d related: #12 --- lib/find-max-radar-results.js | 34 ++++++++++++++++++++++++++++------ test.js | 25 +++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 6 deletions(-) diff --git a/lib/find-max-radar-results.js b/lib/find-max-radar-results.js index 2f0fbcb..fb9e7ce 100644 --- a/lib/find-max-radar-results.js +++ b/lib/find-max-radar-results.js @@ -1,6 +1,6 @@ 'use strict' -const debug = require('debug')('hafas-monitor-trips:find-max-radar-results') +const createDebug = require('debug') const distance = require('@turf/distance').default const dest = require('@turf/destination').default const {ok} = require('assert') @@ -18,7 +18,10 @@ const CACHE_TTL = 7 * 24 * 60 * 60 // 1 week // Therefore, we introduce a minimum to make this case less likely. const MIN_NR_OF_MOVEMENTS = 100 -const findMaxRadarResults = async (hafas, initialBbox, onReqTime, onMovement) => { +const debug = createDebug('hafas-monitor-trips:find-max-radar-results') +const debugBbox = createDebug('hafas-monitor-trips:find-max-radar-results:bbox') + +const expandingBoundingBoxes = function* (initialBbox) { // this is accurate enough for our use case const center = { type: 'Point', @@ -38,20 +41,37 @@ const findMaxRadarResults = async (hafas, initialBbox, onReqTime, onMovement) => debug('initial bbox', initialBbox) debug('center', center.coordinates, 'width', w, 'height', h) - let prevResults = -Infinity, prevPrevResults = -Infinity - for (let it = 0, distFactor = .1; it < MAX_ITERATIONS; it++, distFactor *= 2) { + // this creates wrong bounding boxes when "crossing" the antimeridian or the poles + // todo: find a way to deal with this, but allow *initial* legitimate bounding boxes across them? + for (let it = 0; it < MAX_ITERATIONS; it++) { + const distFactor = .1 * Math.pow(1.5, it) + debugBbox( + 'it', it, + 'distFactor', distFactor.toFixed(2), + 'width', (distFactor * w).toFixed(2), + 'height', (distFactor * h).toFixed(2), + ) + const _north = dest(center, distFactor * h / 2, 0).geometry.coordinates[1] const _west = dest(center, distFactor * w / 2, 270).geometry.coordinates[0] const _south = dest(center, distFactor * h / 2, 180).geometry.coordinates[1] const _east = dest(center, distFactor * w / 2, 90).geometry.coordinates[0] - const bbox = { + yield { north: Math.round(_north * 10000) / 10000, west: Math.round(_west * 10000) / 10000, south: Math.round(_south * 10000) / 10000, east: Math.round(_east * 10000) / 10000, } + } +} - debug('calling radar()', 'iteration', it, 'bbox', bbox) +const findMaxRadarResults = async (hafas, initialBbox, onReqTime, onMovement) => { + debug('initial bbox', initialBbox) + + let it = 0 + let prevResults = -Infinity, prevPrevResults = -Infinity + for (const bbox of expandingBoundingBoxes(initialBbox)) { + debug('calling radar()', 'iteration', it++, 'bbox', bbox) const t0 = Date.now() const movements = await hafas.radar(bbox, { results: ENOUGH_RESULTS, @@ -92,4 +112,6 @@ const cachedFindMaxRadarResults = async (hafas, bbox, redis, onReqTime, onMoveme return maxResults } +// todo [breaking]: export object +cachedFindMaxRadarResults.expandingBoundingBoxes = expandingBoundingBoxes module.exports = cachedFindMaxRadarResults diff --git a/test.js b/test.js index 27620dc..6040a28 100644 --- a/test.js +++ b/test.js @@ -4,8 +4,33 @@ const createHafas = require('vbb-hafas') const a = require('assert') const {Registry} = require('prom-client') const createMonitor = require('.') +const {expandingBoundingBoxes} = require('./lib/find-max-radar-results') const fetchTrips = require('./fetch-trips') +a.deepStrictEqual( + Array.from(expandingBoundingBoxes({ + north: 54.52, + west: 6.54, + south: 51.29, + east: 6.65, + })) + .map(({north, west, south, east}, i) => [north, west, south, east]), + [ + [53.0665,6.5895,52.7435,6.6005], + [53.1473,6.5868,52.6628,6.6032], + [53.2684,6.5826,52.5416,6.6074], + [53.4501,6.5764,52.3599,6.6136], + [53.7226,6.5672,52.0874,6.6228], + [54.1314,6.5532,51.6786,6.6368], + [54.7446,6.5324,51.0654,6.6576], + [55.6644,6.501, 50.1456,6.689 ], + [57.0441,6.454, 48.7659,6.736 ], + [59.1136,6.3836,46.6964,6.8064], + [62.2179,6.2778,43.5921,6.9122], + [66.8744,6.1193,38.9356,7.0707], + ], +) + const METRICS = [ 'hafas_reqs_total', 'hafas_errors_total',