fleetmap-reports 1.0.650 → 1.0.652

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fleetmap-reports",
3
- "version": "1.0.650",
3
+ "version": "1.0.652",
4
4
  "description": "",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
@@ -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 () => {
@@ -2,7 +2,6 @@ function devicesToProcess (userData) {
2
2
  const groupIds = userData.groups.map(g => g.id)
3
3
  const devices = userData.byGroup ? userData.devices.filter(d => !groupIds.includes(d.groupId)) : userData.devices
4
4
  devices.sort((a, b) => (a.name > b.name) ? 1 : -1)
5
-
6
5
  console.log('LOADING_MESSAGE:' + devices.map(d => d.name).join(', '))
7
6
  return devices
8
7
  }
@@ -27,12 +27,10 @@ async function createZoneReport (from, to, userData, traccar) {
27
27
  const url = `https://${process.env.SERVER_HOST}/reports/zone-report`
28
28
  return axios.post(url, { from, to, userData }, { withCredentials: true }).then(d => d.data)
29
29
  }
30
- console.log('Create ZoneReport')
31
30
  const reportData = []
32
31
  const types = ['geofenceEnter', 'geofenceExit']
33
32
 
34
33
  if (userData.byGroup) {
35
- console.log('ByGroup')
36
34
  for (const g of userData.groups) {
37
35
  const devices = userData.devices.filter(d => d.groupId === g.id)
38
36
  console.log(g.name + ' devices:' + devices.length)
@@ -42,12 +40,9 @@ async function createZoneReport (from, to, userData, traccar) {
42
40
  group: g,
43
41
  xpert: devices.filter(d => d.attributes.xpert).length > 0
44
42
  }
45
- console.log('LOADING_MESSAGE:' + 'Eventos...')
46
43
  const response = await traccar.reports.reportsEventsGet(from, to, null, [g.id], types)
47
44
  const data = response.data
48
45
 
49
- console.log('Geofence Enter/Exit Alerts:' + data.length)
50
-
51
46
  devices.sort((a, b) => (a.name > b.name) ? 1 : -1)
52
47
 
53
48
  if (data.length > 0) {
@@ -74,9 +69,7 @@ async function createZoneReport (from, to, userData, traccar) {
74
69
  deviceCount, devices.length, sliceSize, deviceChunk, undefined)
75
70
 
76
71
  const route = filterPositions(data.route)
77
-
78
72
  const alerts = getInAndOutEvents(slice, route, userData)
79
- console.log('Geofence Enter/Exit Alerts:' + alerts.length)
80
73
 
81
74
  if (alerts.length) {
82
75
  allData.devices.push(...await processDevices(from, to, devices, userData, { alerts, route }))
@@ -89,7 +82,7 @@ async function createZoneReport (from, to, userData, traccar) {
89
82
  return reportData
90
83
  }
91
84
 
92
- function getNextIn(outDate, alerts, geofenceId, deviceRoute) {
85
+ function getNextIn (outDate, alerts, geofenceId, deviceRoute) {
93
86
  return alerts
94
87
  .filter(a => a.type === 'geofenceEnter' && a.geofenceId === geofenceId)
95
88
  .find(a => new Date(a.position.fixTime).getTime() > outDate) ||
@@ -115,39 +108,37 @@ async function processDevices (from, to, devices, userData, data) {
115
108
  zoneInData[a.geofenceId] = a
116
109
  } else if (a.type === 'geofenceExit') {
117
110
  const geofence = userData.geofences.find(g => g.id === a.geofenceId)
111
+ if (!geofence) { return }
112
+ const outDate = new Date(a.position.fixTime).getTime()
113
+ const routeAfterOut = deviceRoute.filter(p =>
114
+ new Date(p.fixTime).getTime() >= outDate &&
115
+ new Date(p.fixTime).getTime() < getNextIn(outDate, alerts, a.geofenceId, deviceRoute)
116
+ )
118
117
  if (zoneInData[a.geofenceId]) {
119
118
  const totalInTime = moment(a.position.fixTime).diff(moment(zoneInData[a.geofenceId].position.fixTime), 'seconds')
120
119
  const inDate = new Date(zoneInData[a.geofenceId].position.fixTime).getTime()
121
- const outDate = new Date(a.position.fixTime).getTime()
122
120
  const routeIn = deviceRoute.filter(p =>
123
121
  new Date(p.fixTime).getTime() >= inDate &&
124
122
  new Date(p.fixTime).getTime() < outDate
125
123
  )
126
- const routeAfterOut = deviceRoute.filter(p =>
127
- new Date(p.fixTime).getTime() >= outDate &&
128
- new Date(p.fixTime).getTime() < getNextIn(outDate, alerts, a.geofenceId, deviceRoute)
129
- )
130
- if (geofence) {
131
- zoneInOutData.push({
132
- inTime: zoneInData[a.geofenceId].position,
133
- outTime: a.position,
134
- totalTime: totalInTime,
135
- distanceIn: calculateDistance(routeIn),
136
- distanceOut: calculateDistance(routeAfterOut),
137
- geofenceName: geofence.name,
138
- stopped: routeIn.filter(p => !p.attributes.ignition).length > 0,
139
- driverName: zoneInData[a.geofenceId].position.driverName
140
- })
141
- }
124
+ zoneInOutData.push({
125
+ inTime: zoneInData[a.geofenceId].position,
126
+ outTime: a.position,
127
+ totalTime: totalInTime,
128
+ distanceIn: calculateDistance(routeIn),
129
+ distanceOut: calculateDistance(routeAfterOut),
130
+ geofenceName: geofence.name,
131
+ stopped: routeIn.filter(p => !p.attributes.ignition).length > 0,
132
+ driverName: zoneInData[a.geofenceId].position.driverName
133
+ })
142
134
  zoneInData[a.geofenceId] = null
143
135
  } else {
144
- if (geofence) {
145
- zoneInOutData.push({
146
- outTime: a.position,
147
- geofenceName: geofence.name,
148
- driverName: ''
149
- })
150
- }
136
+ zoneInOutData.push({
137
+ outTime: a.position,
138
+ geofenceName: geofence.name,
139
+ driverName: '',
140
+ distanceOut: calculateDistance(routeAfterOut)
141
+ })
151
142
  }
152
143
  }
153
144
  }
@@ -182,66 +173,42 @@ async function processDevices (from, to, devices, userData, data) {
182
173
  return devicesResult
183
174
  }
184
175
 
176
+ function checkGeofenceEnter (p1, p2, g) {
177
+ switch (g.geometry.type) {
178
+ case 'Polygon':
179
+ return !booleanPointInPolygon.default(p1, g) && booleanPointInPolygon.default(p2, g)
180
+ case 'Point':
181
+ return distance.default(p1, g, { units: 'meters' }) >= g.properties.distance &&
182
+ distance.default(p2, g, { units: 'meters' }) < g.properties.distance
183
+ case 'LineString':
184
+ return pointToLineDistance.default(p1, g, { units: 'meters' }) > (g.properties.geofence.attributes.polylineDistance || 25) &&
185
+ pointToLineDistance.default(p2, g, { units: 'meters' }) <= (g.properties.geofence.attributes.polylineDistance || 25)
186
+ }
187
+ }
188
+
189
+ function checkGeofenceExit (p1, p2, g) {
190
+ return checkGeofenceEnter(p2, p1, g)
191
+ }
192
+
185
193
  function getInAndOutEvents (devices, route, userData) {
186
194
  const events = []
187
195
  devices.forEach(d => {
188
196
  const deviceRoute = route.filter(p => p.deviceId === d.id)
189
-
190
197
  const routePoints = deviceRoute.sort(sortPositions).map(p => convertPositionToFeature(p))
191
198
  const geofencesFeatures = userData.geofences.map(g => convertToFeature(g))
192
199
 
193
- const entryMap = []
194
- routePoints.forEach(p => {
195
- if (!p.properties.position.valid) {
196
- return
197
- }
198
- geofencesFeatures.forEach(g => {
199
- if (g.geometry.type === 'Polygon') {
200
- if (booleanPointInPolygon.default(p, g)) {
201
- if (!entryMap.includes(g)) {
202
- events.push(createEvent('geofenceEnter', d.id, p, g))
203
- entryMap.push(g)
204
- }
205
- } else {
206
- if (entryMap.includes(g)) {
207
- events.push(createEvent('geofenceExit', d.id, p, g))
208
- const index = entryMap.indexOf(g)
209
- entryMap.splice(index, 1)
210
- }
211
- }
212
- }
213
- if (g.geometry.type === 'Point') {
214
- if (distance.default(p, g, { units: 'meters' }) < g.properties.distance) {
215
- if (!entryMap.includes(g)) {
216
- events.push(createEvent('geofenceEnter', d.id, p, g))
217
- entryMap.push(g)
218
- }
219
- } else {
220
- if (entryMap.includes(g)) {
221
- events.push(createEvent('geofenceExit', d.id, p, g))
222
- const index = entryMap.indexOf(g)
223
- entryMap.splice(index, 1)
224
- }
225
- }
226
- }
227
- if (g.geometry.type === 'LineString') {
228
- if (pointToLineDistance.default(p, g, { units: 'meters' }) < (g.properties.geofence.attributes.polylineDistance || 25)) {
229
- if (!entryMap.includes(g)) {
230
- events.push(createEvent('geofenceEnter', d.id, p, g))
231
- entryMap.push(g)
232
- }
233
- } else {
234
- if (entryMap.includes(g)) {
235
- events.push(createEvent('geofenceExit', d.id, p, g))
236
- const index = entryMap.indexOf(g)
237
- entryMap.splice(index, 1)
238
- }
239
- }
200
+ routePoints.filter(p => p.properties.position.valid).forEach((p, i, array) => {
201
+ if (!i) { return }
202
+ const previous = array[i - 1]
203
+ for (const g of geofencesFeatures) {
204
+ if (checkGeofenceEnter(previous, p, g)) {
205
+ events.push(createEvent('geofenceEnter', d.id, p, g))
206
+ } else if (checkGeofenceExit(previous, p, g)) {
207
+ events.push(createEvent('geofenceExit', d.id, p, g))
240
208
  }
241
- })
209
+ }
242
210
  })
243
211
  })
244
-
245
212
  return events
246
213
  }
247
214