-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathbuildLifeAst.js
144 lines (127 loc) · 4.38 KB
/
buildLifeAst.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
import { Map } from 'immutable'
import moment from 'moment'
import LIFEParser from './life.peg.js'
const sameMilitary = (a, b) => {
return a.minutes() === b.minutes() && a.hours() === b.hours()
}
const getPointForTime = (from, to, time) => {
const fromTime = from.get('time')
if (sameMilitary(fromTime, time)) {
return from
}
const toTime = to.get('time')
if (sameMilitary(toTime, time)) {
return to
}
const dlat = to.get('lat') - from.get('lat')
const dlon = to.get('lon') - from.get('lon')
const dt1 = fromTime.valueOf() - time.valueOf()
const dt2 = fromTime.valueOf() - toTime.valueOf()
const dtNorm = dt1 / dt2
const lat = from.get('lat') + dlat * dtNorm
const lon = from.get('lon') + dlon * dtNorm
return Map({
lat,
lon
})
}
const isGTE = (a, b) => {
if (a.hours() < b.hours()) {
return true
} else if (a.hours() === b.hours() && a.minutes() <= b.minutes()) {
return true
} else {
return false
}
}
const isBetween = (a, b, c) => {
return isGTE(a, b) && isGTE(b, c)
}
const findPointInSegments = (date, segments, reverse = false, untilLast = false) => {
let iter = segments.keySeq()
for (let segmentId of iter.toJS()) {
if (reverse) {
const segment = segments.get(segmentId)
const points = segment.get('points').reverse()
if (isBetween(points.get(-1).get('time'), date, points.get(0).get('time'))) {
const pCount = points.count()
let previous = null
for (let i = 0; i < pCount - 1; i++) {
if (isBetween(points.get(i + 1).get('time'), date, points.get(i).get('time'))) {
const point = getPointForTime(points.get(i), points.get(i + 1), date)
if (untilLast) {
previous = { segmentId, index: pCount - i, point }
} else {
return { segmentId, index: pCount - i, point }
}
} else if (previous) {
return previous
}
}
return previous
}
} else {
const segment = segments.get(segmentId)
const points = segment.get('points')
if (isBetween(points.get(0).get('time'), date, points.get(-1).get('time'))) {
console.log('untilLast?', untilLast)
let previous = null
for (let i = 1; i < points.count(); i++) {
console.log(i - 1, i)
if (isBetween(points.get(i - 1).get('time'), date, points.get(i).get('time'))) {
const point = getPointForTime(points.get(i - 1), points.get(i), date)
if (untilLast) {
previous = { segmentId, index: i - 1, point }
} else {
console.log('original')
return { segmentId, index: i - 1, point }
}
} else if (previous) {
console.log('last')
return previous
}
}
return previous
}
}
}
return null
}
const timeToMoment = (day, time) => {
return moment(day + ' ' + time.slice(0, 2) + ':' + time.slice(2))
}
export default (text, segments) => {
try {
const fragments = LIFEParser.parse(text)
const { year, month, day } = fragments.day.value
const currentDay = year + '-' + month + '-' + day
let timezoneChange = 0
let defaultTimezone = 1
for (let block of fragments.blocks) {
if (block.type === 'Timezone') {
timezoneChange = block.value - defaultTimezone
}
if (block.type === 'Trip' || block.type === 'Stay') {
const { timespan } = block
timespan.timezone = timezoneChange
const fromTime = timeToMoment(currentDay, timespan.start.value)
const toTime = timeToMoment(currentDay, timespan.finish.value)
const fromPoint = findPointInSegments(fromTime, segments, false, false)
const toPoint = findPointInSegments(toTime, segments, !!fromPoint, false)
block.references = { to: toPoint, from: fromPoint }
if (block.type === 'Trip' && block.tmodes) {
block.tmodes.forEach((tmode) => {
const tmFromPoint = findPointInSegments(timeToMoment(currentDay, tmode.timespan.start.value), segments)
const tmToPoint = findPointInSegments(timeToMoment(currentDay, tmode.timespan.finish.value), segments, true)
tmode.references = { to: tmToPoint, from: tmFromPoint }
tmode.timespan.timezone = timezoneChange
})
}
}
}
return fragments
} catch (e) {
console.log(e)
throw e
}
}