'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 }