agmission/Development/server/controllers/geoutil.js

126 lines
4.2 KiB
JavaScript

'use strict';
const debug = require('debug')('agm:geoutil'),
lineUtil = require('../helpers/gridline_util'),
utils = require('../helpers/utils'),
ObjectId = require('mongodb').ObjectId,
Job = require('../model/job'),
AreaLine = require('../model/areas_lines'),
{ AppParamError } = require('../helpers/app_error');
async function generateLines_post(req, res) {
if (!req.body)
return res.end();
const params = req.body;
let lineResult = [], regenIds;
if (!params.jobId || !params.swath) AppParamError.throw();
// var hrstart = process.hrtime();
// Build the aggregation pipeline to get job info and sprayAreas with generated and stored lines
const pipeline = [
{
"$match": { _id: params.jobId }
},
{ $unwind: "$sprayAreas" },
{
$lookup: {
from: "area_lines",
localField: "sprayAreas._id",
foreignField: "areaId",
as: "area_lines"
}
},
{ $unwind: { "path": "$area_lines", "preserveNullAndEmptyArrays": true } },
{
$project: {
"_id": "$_id", "measureUnit": 1, "swathWidth": 1, "excludedAreas": 1, "bufs": 1,
"sprayAreas": {
"_id": "$sprayAreas._id", "geometry": "$sprayAreas.geometry", "properties": "$sprayAreas.properties",
"mems": { // list of areas Ids within the group
$cond: { if: '$area_lines.mems', then: "$area_lines.mems", else: [] }
},
"lines": {
$cond: { if: '$area_lines.lines', then: "$area_lines.lines", else: [] }
},
"heading": {
$cond: { if: '$area_lines.heading', then: "$area_lines.heading", else: 0 }
},
}
}
},
{
"$group": {
"_id": "$_id", "measureUnit": { $first: "$measureUnit" }, "swathWidth": { $first: "$swathWidth" }, "bufs": { $first: "$bufs" },
"excludedAreas": { $first: "$excludedAreas" }, "sprayAreas": { $push: "$sprayAreas" }
}
}
];
let _job;
const jobLines = await Job.aggregate(pipeline);
if (jobLines.length)
_job = jobLines[0];
if (_job && !utils.isEmptyArray(_job.sprayAreas)) {
if (!params.generate) {
for (let i = 0; i < _job.sprayAreas.length; i++) {
if (!utils.isEmptyArray(_job.sprayAreas[i].lines)) {
lineResult.push({
isNew: false, areaId: _job.sprayAreas[i]._id.toHexString(), lines: _job.sprayAreas[i].lines, heading: _job.sprayAreas[i].heading,
mems: _job.sprayAreas[i].mems
});
}
}
}
else {
const linesRes = await lineUtil.getLinesLatLng(_job, params.items, params.offset, undefined, undefined, params.heading, params.ab,
{ useGroup: true, regenerate: utils.isEmptyArray(params.items) });
if (linesRes) {
lineResult = linesRes.lines;
regenIds = linesRes.regenIds;
// Remove lines for areas which have just re-generated lines
if (!utils.isEmptyArray(regenIds)) {
await AreaLine.deleteMany({ areaId: { $in: regenIds } });
}
}
// Update generated or regenerated lines to db
if (!utils.isEmptyArray(lineResult)) {
const areaLines = utils.arrayToObject(lineResult, "areaId");
if (areaLines) {
let bulkLinesOps = [], line;
for (let i = 0; i < _job.sprayAreas.length; i++) {
line = areaLines[_job.sprayAreas[i]._id.toHexString()];
if (line && line.isNew) {
const doc = { areaId: line.areaId, lines: line.lines, heading: line.heading, latlngHeading: line.latlngHeading, masterPoint: line.masterPoint };
if (!utils.isEmptyArray(line.mems)) doc["mems"] = line.mems;
line.areaId = ObjectId(line.areaId)
let lineUpsertDoc = {
'updateOne': {
'filter': { 'areaId': line.areaId },
'update': doc,
'upsert': true
}
};
bulkLinesOps.push(lineUpsertDoc);
}
}
if (bulkLinesOps.length)
await AreaLine.bulkWrite(bulkLinesOps);
}
}
}
}
// var end = process.hrtime(hrstart);
// debug(`Generate Lines time: ${(end[0] + (end[1] * 1e-9)).toFixed(3)} secs`);
res.json(lineResult || []);
}
module.exports = {
generateLines_post
}