fleetmap-reports 1.0.649 → 1.0.651
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/tests/index.test.js +4 -1
- package/src/zone-report.js +28 -67
package/package.json
CHANGED
package/src/tests/index.test.js
CHANGED
|
@@ -354,15 +354,18 @@ describe('Test_Reports', function () {
|
|
|
354
354
|
const userData = await report.getUserData()
|
|
355
355
|
const data = await report.zoneReport(new Date(2022, 3, 25, 0, 0, 0, 0),
|
|
356
356
|
new Date(2022, 3, 28, 23, 59, 59, 0),
|
|
357
|
-
userData)
|
|
357
|
+
{ ...userData, devices: userData.devices.filter(d => d.id === 22326) })
|
|
358
358
|
|
|
359
359
|
assert.equal(data.length, 1)
|
|
360
360
|
const device = data[0].devices.find(d => d.device.id === 22326)
|
|
361
361
|
assert.equal(device.geofences.length, 19)
|
|
362
|
+
console.log(device.geofences[0])
|
|
362
363
|
assert.equal(device.geofences[0].inTime.fixTime, '2022-04-25T23:47:58.000+0000')
|
|
363
364
|
assert.equal(device.geofences[0].outTime.fixTime, '2022-04-26T07:47:35.000+0000')
|
|
364
365
|
assert.equal(device.geofences[0].totalTime, '28777')
|
|
365
366
|
assert.equal(device.geofences[0].geofenceName, 'Casa João')
|
|
367
|
+
assert.equal(device.geofences[0].distanceIn, 0.38569639521207727)
|
|
368
|
+
// expect(device.geofences[0].distanceOut).toBeGreaterThan(0)
|
|
366
369
|
}, 990000)
|
|
367
370
|
// eslint-disable-next-line no-undef
|
|
368
371
|
it('Zone Report With Stops', async () => {
|
package/src/zone-report.js
CHANGED
|
@@ -32,7 +32,6 @@ async function createZoneReport (from, to, userData, traccar) {
|
|
|
32
32
|
const types = ['geofenceEnter', 'geofenceExit']
|
|
33
33
|
|
|
34
34
|
if (userData.byGroup) {
|
|
35
|
-
console.log('ByGroup')
|
|
36
35
|
for (const g of userData.groups) {
|
|
37
36
|
const devices = userData.devices.filter(d => d.groupId === g.id)
|
|
38
37
|
console.log(g.name + ' devices:' + devices.length)
|
|
@@ -42,12 +41,9 @@ async function createZoneReport (from, to, userData, traccar) {
|
|
|
42
41
|
group: g,
|
|
43
42
|
xpert: devices.filter(d => d.attributes.xpert).length > 0
|
|
44
43
|
}
|
|
45
|
-
console.log('LOADING_MESSAGE:' + 'Eventos...')
|
|
46
44
|
const response = await traccar.reports.reportsEventsGet(from, to, null, [g.id], types)
|
|
47
45
|
const data = response.data
|
|
48
46
|
|
|
49
|
-
console.log('Geofence Enter/Exit Alerts:' + data.length)
|
|
50
|
-
|
|
51
47
|
devices.sort((a, b) => (a.name > b.name) ? 1 : -1)
|
|
52
48
|
|
|
53
49
|
if (data.length > 0) {
|
|
@@ -74,9 +70,7 @@ async function createZoneReport (from, to, userData, traccar) {
|
|
|
74
70
|
deviceCount, devices.length, sliceSize, deviceChunk, undefined)
|
|
75
71
|
|
|
76
72
|
const route = filterPositions(data.route)
|
|
77
|
-
|
|
78
73
|
const alerts = getInAndOutEvents(slice, route, userData)
|
|
79
|
-
console.log('Geofence Enter/Exit Alerts:' + alerts.length)
|
|
80
74
|
|
|
81
75
|
if (alerts.length) {
|
|
82
76
|
allData.devices.push(...await processDevices(from, to, devices, userData, { alerts, route }))
|
|
@@ -88,14 +82,8 @@ async function createZoneReport (from, to, userData, traccar) {
|
|
|
88
82
|
|
|
89
83
|
return reportData
|
|
90
84
|
}
|
|
91
|
-
function getPreviousOut(inDate, alerts, geofenceId, deviceRoute) {
|
|
92
|
-
return alerts
|
|
93
|
-
.filter(a => a.type === 'geofenceExit' && a.geofenceId === geofenceId)
|
|
94
|
-
.find(a => new Date(a.position.fixTime).getTime() < inDate) ||
|
|
95
|
-
new Date(deviceRoute[0].fixTime).getTime()
|
|
96
|
-
}
|
|
97
85
|
|
|
98
|
-
function getNextIn(outDate, alerts, geofenceId, deviceRoute) {
|
|
86
|
+
function getNextIn (outDate, alerts, geofenceId, deviceRoute) {
|
|
99
87
|
return alerts
|
|
100
88
|
.filter(a => a.type === 'geofenceEnter' && a.geofenceId === geofenceId)
|
|
101
89
|
.find(a => new Date(a.position.fixTime).getTime() > outDate) ||
|
|
@@ -125,9 +113,6 @@ async function processDevices (from, to, devices, userData, data) {
|
|
|
125
113
|
const totalInTime = moment(a.position.fixTime).diff(moment(zoneInData[a.geofenceId].position.fixTime), 'seconds')
|
|
126
114
|
const inDate = new Date(zoneInData[a.geofenceId].position.fixTime).getTime()
|
|
127
115
|
const outDate = new Date(a.position.fixTime).getTime()
|
|
128
|
-
const routeBeforeIn = deviceRoute.filter(p =>
|
|
129
|
-
new Date(p.fixTime).getTime() >= getPreviousOut(inDate, alerts, a.geofenceId, deviceRoute) &&
|
|
130
|
-
new Date(p.fixTime).getTime() < inDate)
|
|
131
116
|
const routeIn = deviceRoute.filter(p =>
|
|
132
117
|
new Date(p.fixTime).getTime() >= inDate &&
|
|
133
118
|
new Date(p.fixTime).getTime() < outDate
|
|
@@ -142,7 +127,7 @@ async function processDevices (from, to, devices, userData, data) {
|
|
|
142
127
|
outTime: a.position,
|
|
143
128
|
totalTime: totalInTime,
|
|
144
129
|
distanceIn: calculateDistance(routeIn),
|
|
145
|
-
distanceOut: calculateDistance(
|
|
130
|
+
distanceOut: calculateDistance(routeAfterOut),
|
|
146
131
|
geofenceName: geofence.name,
|
|
147
132
|
stopped: routeIn.filter(p => !p.attributes.ignition).length > 0,
|
|
148
133
|
driverName: zoneInData[a.geofenceId].position.driverName
|
|
@@ -191,66 +176,42 @@ async function processDevices (from, to, devices, userData, data) {
|
|
|
191
176
|
return devicesResult
|
|
192
177
|
}
|
|
193
178
|
|
|
179
|
+
function checkGeofenceEnter (p1, p2, g) {
|
|
180
|
+
switch (g.geometry.type) {
|
|
181
|
+
case 'Polygon':
|
|
182
|
+
return !booleanPointInPolygon.default(p1, g) && booleanPointInPolygon.default(p2, g)
|
|
183
|
+
case 'Point':
|
|
184
|
+
return distance.default(p1, g, { units: 'meters' }) >= g.properties.distance &&
|
|
185
|
+
distance.default(p2, g, { units: 'meters' }) < g.properties.distance
|
|
186
|
+
case 'LineString':
|
|
187
|
+
return pointToLineDistance.default(p1, g, { units: 'meters' }) > (g.properties.geofence.attributes.polylineDistance || 25) &&
|
|
188
|
+
pointToLineDistance.default(p2, g, { units: 'meters' }) <= (g.properties.geofence.attributes.polylineDistance || 25)
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
function checkGeofenceExit (p1, p2, g) {
|
|
193
|
+
return checkGeofenceEnter(p2, p1, g)
|
|
194
|
+
}
|
|
195
|
+
|
|
194
196
|
function getInAndOutEvents (devices, route, userData) {
|
|
195
197
|
const events = []
|
|
196
198
|
devices.forEach(d => {
|
|
197
199
|
const deviceRoute = route.filter(p => p.deviceId === d.id)
|
|
198
|
-
|
|
199
200
|
const routePoints = deviceRoute.sort(sortPositions).map(p => convertPositionToFeature(p))
|
|
200
201
|
const geofencesFeatures = userData.geofences.map(g => convertToFeature(g))
|
|
201
202
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
if (
|
|
209
|
-
|
|
210
|
-
if (!entryMap.includes(g)) {
|
|
211
|
-
events.push(createEvent('geofenceEnter', d.id, p, g))
|
|
212
|
-
entryMap.push(g)
|
|
213
|
-
}
|
|
214
|
-
} else {
|
|
215
|
-
if (entryMap.includes(g)) {
|
|
216
|
-
events.push(createEvent('geofenceExit', d.id, p, g))
|
|
217
|
-
const index = entryMap.indexOf(g)
|
|
218
|
-
entryMap.splice(index, 1)
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
if (g.geometry.type === 'Point') {
|
|
223
|
-
if (distance.default(p, g, { units: 'meters' }) < g.properties.distance) {
|
|
224
|
-
if (!entryMap.includes(g)) {
|
|
225
|
-
events.push(createEvent('geofenceEnter', d.id, p, g))
|
|
226
|
-
entryMap.push(g)
|
|
227
|
-
}
|
|
228
|
-
} else {
|
|
229
|
-
if (entryMap.includes(g)) {
|
|
230
|
-
events.push(createEvent('geofenceExit', d.id, p, g))
|
|
231
|
-
const index = entryMap.indexOf(g)
|
|
232
|
-
entryMap.splice(index, 1)
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
if (g.geometry.type === 'LineString') {
|
|
237
|
-
if (pointToLineDistance.default(p, g, { units: 'meters' }) < (g.properties.geofence.attributes.polylineDistance || 25)) {
|
|
238
|
-
if (!entryMap.includes(g)) {
|
|
239
|
-
events.push(createEvent('geofenceEnter', d.id, p, g))
|
|
240
|
-
entryMap.push(g)
|
|
241
|
-
}
|
|
242
|
-
} else {
|
|
243
|
-
if (entryMap.includes(g)) {
|
|
244
|
-
events.push(createEvent('geofenceExit', d.id, p, g))
|
|
245
|
-
const index = entryMap.indexOf(g)
|
|
246
|
-
entryMap.splice(index, 1)
|
|
247
|
-
}
|
|
248
|
-
}
|
|
203
|
+
routePoints.filter(p => p.properties.position.valid).forEach((p, i, array) => {
|
|
204
|
+
if (!i) { return }
|
|
205
|
+
const previous = array[i - 1]
|
|
206
|
+
for (const g of geofencesFeatures) {
|
|
207
|
+
if (checkGeofenceEnter(previous, p, g)) {
|
|
208
|
+
events.push(createEvent('geofenceEnter', d.id, p, g))
|
|
209
|
+
} else if (checkGeofenceExit(previous, p, g)) {
|
|
210
|
+
events.push(createEvent('geofenceExit', d.id, p, g))
|
|
249
211
|
}
|
|
250
|
-
}
|
|
212
|
+
}
|
|
251
213
|
})
|
|
252
214
|
})
|
|
253
|
-
|
|
254
215
|
return events
|
|
255
216
|
}
|
|
256
217
|
|