mirror of
https://gitlab.com/wgp/dougal/software.git
synced 2025-12-06 13:37:07 +00:00
Assign (some) offline navdata to a survey.
There is no concept of ‘current survey’ in Dougal, and assigning navigation data to a particular survey is full of edge cases but sometimes it is necessary or at least convenient to do so. This commit implements once such strategy, which consists of checking the distance to the preplots of all active surveys (well, those that do have preplots anyway) and picking the nearest one. To reduce load, we only do this every once in a while as governed by the `offline_survey_detect_interval` option in the configuration. This strategy is only active if the configuration option `offline_survey_heuristics == "nearest_preplot"` for the corresponding navigation header.
This commit is contained in:
@@ -2,6 +2,8 @@
|
||||
|
||||
const { setSurvey, transaction, pool } = require('../connection');
|
||||
|
||||
let last_tstamp = 0;
|
||||
|
||||
async function getAllProjectConfigs () {
|
||||
const client = await pool.connect();
|
||||
|
||||
@@ -64,6 +66,50 @@ async function getNearestPreplot (candidates) {
|
||||
return res.rows[0] && res.rows[0].schema;
|
||||
}
|
||||
|
||||
async function getNearestOfflinePreplot (candidates) {
|
||||
|
||||
const queries = candidates.map( c=> {
|
||||
let text, values;
|
||||
if ("latitude" in candidates[0] && "longitude" in candidates[0]) {
|
||||
text = `
|
||||
SELECT
|
||||
'${c._schema}' AS _schema,
|
||||
ST_Distance(ST_Transform(ST_SetSRID(ST_MakePoint($1, $2), 4326), ST_SRID(geometry)), geometry) AS distance
|
||||
FROM ${c._schema}.preplot_points
|
||||
ORDER BY distance ASC
|
||||
LIMIT 1;
|
||||
`;
|
||||
values = [ candidates[0].longitude, candidates[0].latitude ];
|
||||
} else if ("easting" in candidates[0] && "northing" in candidates[0]) {
|
||||
text = `
|
||||
SELECT
|
||||
'${c._schema}' AS _schema,
|
||||
ST_Distance(ST_SetSRID(ST_MakePoint($1, $2), ST_SRID(geometry)), geometry) AS distance
|
||||
FROM ${c._schema}.preplot_points
|
||||
ORDER BY distance ASC
|
||||
LIMIT 1;
|
||||
`;
|
||||
values = [ candidates[0].easting, candidates[0].northing ];
|
||||
} else {
|
||||
// Missing a position, shouldn't happen at this point
|
||||
return {};
|
||||
}
|
||||
return {text, values};
|
||||
}).filter(i => i.text && i.values);
|
||||
|
||||
const client = await pool.connect();
|
||||
const results = [];
|
||||
for (const qry of queries) {
|
||||
const res = await client.query(qry.text, qry.values);
|
||||
if (res.rows[0] && res.rows[0]._schema) {
|
||||
results.push(res.rows[0]);
|
||||
}
|
||||
}
|
||||
client.release();
|
||||
const _schema = results.sort( (a, b) => a.distance - b.distance).shift()._schema;
|
||||
return candidates.find(c => c._schema == _schema);
|
||||
}
|
||||
|
||||
async function saveOnline (dataset, opts = {}) {
|
||||
|
||||
const client = await pool.connect();
|
||||
@@ -236,6 +282,23 @@ async function save (navData, opts = {}) {
|
||||
navData.payload._point = candidates[0].point;
|
||||
navData.payload._online = true;
|
||||
}
|
||||
} else {
|
||||
// We are offline. We only assign _schema once every save_interval seconds at most
|
||||
if (opts.offline_survey_heuristics == "nearest_preplot") {
|
||||
const now = Date.now();
|
||||
const do_save = !opts.offline_survey_detect_interval ||
|
||||
(now - last_tstamp) >= opts.offline_survey_detect_interval;
|
||||
|
||||
if (do_save) {
|
||||
const configs = await getAllProjectConfigs();
|
||||
const candidates = configs.map(c => Object.assign({}, navData, {_schema: c.schema}));
|
||||
const bestCandidate = await getNearestOfflinePreplot(candidates);
|
||||
if (bestCandidate) {
|
||||
navData.payload._schema = bestCandidate._schema;
|
||||
last_tstamp = now;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
await saveOffline(navData, opts);
|
||||
|
||||
Reference in New Issue
Block a user